blob: 5a7af9d97cc32e9010f7bc03d45e00f27c42b821 [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) {
Alexey Bataev37e594c2016-03-04 07:21:16 +00002044 VisitOMPClauseWithPreInit(C);
Alexey Bataev005248a2016-02-25 05:25:57 +00002045 Visitor->AddStmt(C->getPostUpdateExpr());
2046}
2047
Alexey Bataevaadd52e2014-02-13 05:29:23 +00002048void OMPClauseEnqueue::VisitOMPIfClause(const OMPIfClause *C) {
2049 Visitor->AddStmt(C->getCondition());
2050}
2051
Alexey Bataev3778b602014-07-17 07:32:53 +00002052void OMPClauseEnqueue::VisitOMPFinalClause(const OMPFinalClause *C) {
2053 Visitor->AddStmt(C->getCondition());
2054}
2055
Alexey Bataev568a8332014-03-06 06:15:19 +00002056void OMPClauseEnqueue::VisitOMPNumThreadsClause(const OMPNumThreadsClause *C) {
2057 Visitor->AddStmt(C->getNumThreads());
2058}
2059
Alexey Bataev62c87d22014-03-21 04:51:18 +00002060void OMPClauseEnqueue::VisitOMPSafelenClause(const OMPSafelenClause *C) {
2061 Visitor->AddStmt(C->getSafelen());
2062}
2063
Alexey Bataev66b15b52015-08-21 11:14:16 +00002064void OMPClauseEnqueue::VisitOMPSimdlenClause(const OMPSimdlenClause *C) {
2065 Visitor->AddStmt(C->getSimdlen());
2066}
2067
Alexander Musman8bd31e62014-05-27 15:12:19 +00002068void OMPClauseEnqueue::VisitOMPCollapseClause(const OMPCollapseClause *C) {
2069 Visitor->AddStmt(C->getNumForLoops());
2070}
2071
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002072void OMPClauseEnqueue::VisitOMPDefaultClause(const OMPDefaultClause *C) { }
Alexey Bataev756c1962013-09-24 03:17:45 +00002073
Alexey Bataevbcbadb62014-05-06 06:04:14 +00002074void OMPClauseEnqueue::VisitOMPProcBindClause(const OMPProcBindClause *C) { }
2075
Alexey Bataev56dafe82014-06-20 07:16:17 +00002076void OMPClauseEnqueue::VisitOMPScheduleClause(const OMPScheduleClause *C) {
Alexey Bataev3392d762016-02-16 11:18:12 +00002077 VisitOMPClauseWithPreInit(C);
Alexey Bataev56dafe82014-06-20 07:16:17 +00002078 Visitor->AddStmt(C->getChunkSize());
2079}
2080
Alexey Bataev10e775f2015-07-30 11:36:16 +00002081void OMPClauseEnqueue::VisitOMPOrderedClause(const OMPOrderedClause *C) {
2082 Visitor->AddStmt(C->getNumForLoops());
2083}
Alexey Bataev142e1fc2014-06-20 09:44:06 +00002084
Alexey Bataev236070f2014-06-20 11:19:47 +00002085void OMPClauseEnqueue::VisitOMPNowaitClause(const OMPNowaitClause *) {}
2086
Alexey Bataev7aea99a2014-07-17 12:19:31 +00002087void OMPClauseEnqueue::VisitOMPUntiedClause(const OMPUntiedClause *) {}
2088
Alexey Bataev74ba3a52014-07-17 12:47:03 +00002089void OMPClauseEnqueue::VisitOMPMergeableClause(const OMPMergeableClause *) {}
2090
Alexey Bataevf98b00c2014-07-23 02:27:21 +00002091void OMPClauseEnqueue::VisitOMPReadClause(const OMPReadClause *) {}
2092
Alexey Bataevdea47612014-07-23 07:46:59 +00002093void OMPClauseEnqueue::VisitOMPWriteClause(const OMPWriteClause *) {}
2094
Alexey Bataev67a4f222014-07-23 10:25:33 +00002095void OMPClauseEnqueue::VisitOMPUpdateClause(const OMPUpdateClause *) {}
2096
Alexey Bataev459dec02014-07-24 06:46:57 +00002097void OMPClauseEnqueue::VisitOMPCaptureClause(const OMPCaptureClause *) {}
2098
Alexey Bataev82bad8b2014-07-24 08:55:34 +00002099void OMPClauseEnqueue::VisitOMPSeqCstClause(const OMPSeqCstClause *) {}
2100
Alexey Bataev346265e2015-09-25 10:37:12 +00002101void OMPClauseEnqueue::VisitOMPThreadsClause(const OMPThreadsClause *) {}
2102
Alexey Bataevd14d1e62015-09-28 06:39:35 +00002103void OMPClauseEnqueue::VisitOMPSIMDClause(const OMPSIMDClause *) {}
2104
Alexey Bataevb825de12015-12-07 10:51:44 +00002105void OMPClauseEnqueue::VisitOMPNogroupClause(const OMPNogroupClause *) {}
2106
Michael Wonge710d542015-08-07 16:16:36 +00002107void OMPClauseEnqueue::VisitOMPDeviceClause(const OMPDeviceClause *C) {
2108 Visitor->AddStmt(C->getDevice());
2109}
2110
Kelvin Li099bb8c2015-11-24 20:50:12 +00002111void OMPClauseEnqueue::VisitOMPNumTeamsClause(const OMPNumTeamsClause *C) {
2112 Visitor->AddStmt(C->getNumTeams());
2113}
2114
Kelvin Lia15fb1a2015-11-27 18:47:36 +00002115void OMPClauseEnqueue::VisitOMPThreadLimitClause(const OMPThreadLimitClause *C) {
2116 Visitor->AddStmt(C->getThreadLimit());
2117}
2118
Alexey Bataeva0569352015-12-01 10:17:31 +00002119void OMPClauseEnqueue::VisitOMPPriorityClause(const OMPPriorityClause *C) {
2120 Visitor->AddStmt(C->getPriority());
2121}
2122
Alexey Bataev1fd4aed2015-12-07 12:52:51 +00002123void OMPClauseEnqueue::VisitOMPGrainsizeClause(const OMPGrainsizeClause *C) {
2124 Visitor->AddStmt(C->getGrainsize());
2125}
2126
Alexey Bataev382967a2015-12-08 12:06:20 +00002127void OMPClauseEnqueue::VisitOMPNumTasksClause(const OMPNumTasksClause *C) {
2128 Visitor->AddStmt(C->getNumTasks());
2129}
2130
Alexey Bataev28c75412015-12-15 08:19:24 +00002131void OMPClauseEnqueue::VisitOMPHintClause(const OMPHintClause *C) {
2132 Visitor->AddStmt(C->getHint());
2133}
2134
Alexey Bataev756c1962013-09-24 03:17:45 +00002135template<typename T>
2136void OMPClauseEnqueue::VisitOMPClauseList(T *Node) {
Alexey Bataev03b340a2014-10-21 03:16:40 +00002137 for (const auto *I : Node->varlists()) {
Aaron Ballman2205d2a2014-03-14 15:55:35 +00002138 Visitor->AddStmt(I);
Alexey Bataev03b340a2014-10-21 03:16:40 +00002139 }
Alexey Bataev756c1962013-09-24 03:17:45 +00002140}
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002141
2142void OMPClauseEnqueue::VisitOMPPrivateClause(const OMPPrivateClause *C) {
Alexey Bataev756c1962013-09-24 03:17:45 +00002143 VisitOMPClauseList(C);
Alexey Bataev03b340a2014-10-21 03:16:40 +00002144 for (const auto *E : C->private_copies()) {
2145 Visitor->AddStmt(E);
2146 }
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002147}
Alexey Bataevd5af8e42013-10-01 05:32:34 +00002148void OMPClauseEnqueue::VisitOMPFirstprivateClause(
2149 const OMPFirstprivateClause *C) {
2150 VisitOMPClauseList(C);
Alexey Bataev417089f2016-02-17 13:19:37 +00002151 VisitOMPClauseWithPreInit(C);
2152 for (const auto *E : C->private_copies()) {
2153 Visitor->AddStmt(E);
2154 }
2155 for (const auto *E : C->inits()) {
2156 Visitor->AddStmt(E);
2157 }
Alexey Bataevd5af8e42013-10-01 05:32:34 +00002158}
Alexander Musman1bb328c2014-06-04 13:06:39 +00002159void OMPClauseEnqueue::VisitOMPLastprivateClause(
2160 const OMPLastprivateClause *C) {
2161 VisitOMPClauseList(C);
Alexey Bataev005248a2016-02-25 05:25:57 +00002162 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 Bataev61205072016-03-02 04:57:40 +00002181 VisitOMPClauseWithPostUpdate(C);
Alexey Bataevf24e7b12015-10-08 09:10:53 +00002182 for (auto *E : C->privates()) {
2183 Visitor->AddStmt(E);
2184 }
Alexey Bataev794ba0d2015-04-10 10:43:45 +00002185 for (auto *E : C->lhs_exprs()) {
2186 Visitor->AddStmt(E);
2187 }
2188 for (auto *E : C->rhs_exprs()) {
2189 Visitor->AddStmt(E);
2190 }
2191 for (auto *E : C->reduction_ops()) {
2192 Visitor->AddStmt(E);
2193 }
Alexey Bataevc5e02582014-06-16 07:08:35 +00002194}
Alexander Musman8dba6642014-04-22 13:09:42 +00002195void OMPClauseEnqueue::VisitOMPLinearClause(const OMPLinearClause *C) {
2196 VisitOMPClauseList(C);
Alexey Bataevbd9fec12015-08-18 06:47:21 +00002197 for (const auto *E : C->privates()) {
2198 Visitor->AddStmt(E);
2199 }
Alexander Musman3276a272015-03-21 10:12:56 +00002200 for (const auto *E : C->inits()) {
2201 Visitor->AddStmt(E);
2202 }
2203 for (const auto *E : C->updates()) {
2204 Visitor->AddStmt(E);
2205 }
2206 for (const auto *E : C->finals()) {
2207 Visitor->AddStmt(E);
2208 }
Alexander Musman8dba6642014-04-22 13:09:42 +00002209 Visitor->AddStmt(C->getStep());
Alexander Musman3276a272015-03-21 10:12:56 +00002210 Visitor->AddStmt(C->getCalcStep());
Alexander Musman8dba6642014-04-22 13:09:42 +00002211}
Alexander Musmanf0d76e72014-05-29 14:36:25 +00002212void OMPClauseEnqueue::VisitOMPAlignedClause(const OMPAlignedClause *C) {
2213 VisitOMPClauseList(C);
2214 Visitor->AddStmt(C->getAlignment());
2215}
Alexey Bataevd48bcd82014-03-31 03:36:38 +00002216void OMPClauseEnqueue::VisitOMPCopyinClause(const OMPCopyinClause *C) {
2217 VisitOMPClauseList(C);
Alexey Bataevf56f98c2015-04-16 05:39:01 +00002218 for (auto *E : C->source_exprs()) {
2219 Visitor->AddStmt(E);
2220 }
2221 for (auto *E : C->destination_exprs()) {
2222 Visitor->AddStmt(E);
2223 }
2224 for (auto *E : C->assignment_ops()) {
2225 Visitor->AddStmt(E);
2226 }
Alexey Bataevd48bcd82014-03-31 03:36:38 +00002227}
Alexey Bataevbae9a792014-06-27 10:37:06 +00002228void
2229OMPClauseEnqueue::VisitOMPCopyprivateClause(const OMPCopyprivateClause *C) {
2230 VisitOMPClauseList(C);
Alexey Bataeva63048e2015-03-23 06:18:07 +00002231 for (auto *E : C->source_exprs()) {
2232 Visitor->AddStmt(E);
2233 }
2234 for (auto *E : C->destination_exprs()) {
2235 Visitor->AddStmt(E);
2236 }
2237 for (auto *E : C->assignment_ops()) {
2238 Visitor->AddStmt(E);
2239 }
Alexey Bataevbae9a792014-06-27 10:37:06 +00002240}
Alexey Bataev6125da92014-07-21 11:26:11 +00002241void OMPClauseEnqueue::VisitOMPFlushClause(const OMPFlushClause *C) {
2242 VisitOMPClauseList(C);
2243}
Alexey Bataev1c2cfbc2015-06-23 14:25:19 +00002244void OMPClauseEnqueue::VisitOMPDependClause(const OMPDependClause *C) {
2245 VisitOMPClauseList(C);
2246}
Kelvin Li0bff7af2015-11-23 05:32:03 +00002247void OMPClauseEnqueue::VisitOMPMapClause(const OMPMapClause *C) {
2248 VisitOMPClauseList(C);
2249}
Carlo Bertollib4adf552016-01-15 18:50:31 +00002250void OMPClauseEnqueue::VisitOMPDistScheduleClause(
2251 const OMPDistScheduleClause *C) {
Alexey Bataev3392d762016-02-16 11:18:12 +00002252 VisitOMPClauseWithPreInit(C);
Carlo Bertollib4adf552016-01-15 18:50:31 +00002253 Visitor->AddStmt(C->getChunkSize());
Carlo Bertollib4adf552016-01-15 18:50:31 +00002254}
Alexey Bataev3392d762016-02-16 11:18:12 +00002255void OMPClauseEnqueue::VisitOMPDefaultmapClause(
2256 const OMPDefaultmapClause * /*C*/) {}
Alexander Kornienkoab9db512015-06-22 23:07:51 +00002257}
Alexey Bataev756c1962013-09-24 03:17:45 +00002258
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002259void EnqueueVisitor::EnqueueChildren(const OMPClause *S) {
2260 unsigned size = WL.size();
2261 OMPClauseEnqueue Visitor(this);
2262 Visitor.Visit(S);
2263 if (size == WL.size())
2264 return;
2265 // Now reverse the entries we just added. This will match the DFS
2266 // ordering performed by the worklist.
2267 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
2268 std::reverse(I, E);
2269}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002270void EnqueueVisitor::VisitAddrLabelExpr(const AddrLabelExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002271 WL.push_back(LabelRefVisit(E->getLabel(), E->getLabelLoc(), Parent));
2272}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002273void EnqueueVisitor::VisitBlockExpr(const BlockExpr *B) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002274 AddDecl(B->getBlockDecl());
2275}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002276void EnqueueVisitor::VisitCompoundLiteralExpr(const CompoundLiteralExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002277 EnqueueChildren(E);
2278 AddTypeLoc(E->getTypeSourceInfo());
2279}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002280void EnqueueVisitor::VisitCompoundStmt(const CompoundStmt *S) {
Pete Cooper57d3f142015-07-30 17:22:52 +00002281 for (auto &I : llvm::reverse(S->body()))
2282 AddStmt(I);
Guy Benyei11169dd2012-12-18 14:30:41 +00002283}
2284void EnqueueVisitor::
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002285VisitMSDependentExistsStmt(const MSDependentExistsStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002286 AddStmt(S->getSubStmt());
2287 AddDeclarationNameInfo(S);
2288 if (NestedNameSpecifierLoc QualifierLoc = S->getQualifierLoc())
2289 AddNestedNameSpecifierLoc(QualifierLoc);
2290}
2291
2292void EnqueueVisitor::
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002293VisitCXXDependentScopeMemberExpr(const CXXDependentScopeMemberExpr *E) {
James Y Knight04ec5bf2015-12-24 02:59:37 +00002294 if (E->hasExplicitTemplateArgs())
2295 AddExplicitTemplateArgs(E->getTemplateArgs(), E->getNumTemplateArgs());
Guy Benyei11169dd2012-12-18 14:30:41 +00002296 AddDeclarationNameInfo(E);
2297 if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
2298 AddNestedNameSpecifierLoc(QualifierLoc);
2299 if (!E->isImplicitAccess())
2300 AddStmt(E->getBase());
2301}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002302void EnqueueVisitor::VisitCXXNewExpr(const CXXNewExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002303 // Enqueue the initializer , if any.
2304 AddStmt(E->getInitializer());
2305 // Enqueue the array size, if any.
2306 AddStmt(E->getArraySize());
2307 // Enqueue the allocated type.
2308 AddTypeLoc(E->getAllocatedTypeSourceInfo());
2309 // Enqueue the placement arguments.
2310 for (unsigned I = E->getNumPlacementArgs(); I > 0; --I)
2311 AddStmt(E->getPlacementArg(I-1));
2312}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002313void EnqueueVisitor::VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *CE) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002314 for (unsigned I = CE->getNumArgs(); I > 1 /* Yes, this is 1 */; --I)
2315 AddStmt(CE->getArg(I-1));
2316 AddStmt(CE->getCallee());
2317 AddStmt(CE->getArg(0));
2318}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002319void EnqueueVisitor::VisitCXXPseudoDestructorExpr(
2320 const CXXPseudoDestructorExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002321 // Visit the name of the type being destroyed.
2322 AddTypeLoc(E->getDestroyedTypeInfo());
2323 // Visit the scope type that looks disturbingly like the nested-name-specifier
2324 // but isn't.
2325 AddTypeLoc(E->getScopeTypeInfo());
2326 // Visit the nested-name-specifier.
2327 if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
2328 AddNestedNameSpecifierLoc(QualifierLoc);
2329 // Visit base expression.
2330 AddStmt(E->getBase());
2331}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002332void EnqueueVisitor::VisitCXXScalarValueInitExpr(
2333 const CXXScalarValueInitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002334 AddTypeLoc(E->getTypeSourceInfo());
2335}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002336void EnqueueVisitor::VisitCXXTemporaryObjectExpr(
2337 const CXXTemporaryObjectExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002338 EnqueueChildren(E);
2339 AddTypeLoc(E->getTypeSourceInfo());
2340}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002341void EnqueueVisitor::VisitCXXTypeidExpr(const CXXTypeidExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002342 EnqueueChildren(E);
2343 if (E->isTypeOperand())
2344 AddTypeLoc(E->getTypeOperandSourceInfo());
2345}
2346
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002347void EnqueueVisitor::VisitCXXUnresolvedConstructExpr(
2348 const CXXUnresolvedConstructExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002349 EnqueueChildren(E);
2350 AddTypeLoc(E->getTypeSourceInfo());
2351}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002352void EnqueueVisitor::VisitCXXUuidofExpr(const CXXUuidofExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002353 EnqueueChildren(E);
2354 if (E->isTypeOperand())
2355 AddTypeLoc(E->getTypeOperandSourceInfo());
2356}
2357
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002358void EnqueueVisitor::VisitCXXCatchStmt(const CXXCatchStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002359 EnqueueChildren(S);
2360 AddDecl(S->getExceptionDecl());
2361}
2362
Argyrios Kyrtzidis99891242014-11-13 09:03:21 +00002363void EnqueueVisitor::VisitCXXForRangeStmt(const CXXForRangeStmt *S) {
Argyrios Kyrtzidiscde70692014-11-13 09:50:19 +00002364 AddStmt(S->getBody());
Argyrios Kyrtzidis99891242014-11-13 09:03:21 +00002365 AddStmt(S->getRangeInit());
Argyrios Kyrtzidiscde70692014-11-13 09:50:19 +00002366 AddDecl(S->getLoopVariable());
Argyrios Kyrtzidis99891242014-11-13 09:03:21 +00002367}
2368
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002369void EnqueueVisitor::VisitDeclRefExpr(const DeclRefExpr *DR) {
James Y Knight04ec5bf2015-12-24 02:59:37 +00002370 if (DR->hasExplicitTemplateArgs())
2371 AddExplicitTemplateArgs(DR->getTemplateArgs(), DR->getNumTemplateArgs());
Guy Benyei11169dd2012-12-18 14:30:41 +00002372 WL.push_back(DeclRefExprParts(DR, Parent));
2373}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002374void EnqueueVisitor::VisitDependentScopeDeclRefExpr(
2375 const DependentScopeDeclRefExpr *E) {
James Y Knight04ec5bf2015-12-24 02:59:37 +00002376 if (E->hasExplicitTemplateArgs())
2377 AddExplicitTemplateArgs(E->getTemplateArgs(), E->getNumTemplateArgs());
Guy Benyei11169dd2012-12-18 14:30:41 +00002378 AddDeclarationNameInfo(E);
2379 AddNestedNameSpecifierLoc(E->getQualifierLoc());
2380}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002381void EnqueueVisitor::VisitDeclStmt(const DeclStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002382 unsigned size = WL.size();
2383 bool isFirst = true;
Aaron Ballman535bbcc2014-03-14 17:01:24 +00002384 for (const auto *D : S->decls()) {
2385 AddDecl(D, isFirst);
Guy Benyei11169dd2012-12-18 14:30:41 +00002386 isFirst = false;
2387 }
2388 if (size == WL.size())
2389 return;
2390 // Now reverse the entries we just added. This will match the DFS
2391 // ordering performed by the worklist.
2392 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
2393 std::reverse(I, E);
2394}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002395void EnqueueVisitor::VisitDesignatedInitExpr(const DesignatedInitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002396 AddStmt(E->getInit());
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002397 for (DesignatedInitExpr::const_reverse_designators_iterator
Guy Benyei11169dd2012-12-18 14:30:41 +00002398 D = E->designators_rbegin(), DEnd = E->designators_rend();
2399 D != DEnd; ++D) {
2400 if (D->isFieldDesignator()) {
2401 if (FieldDecl *Field = D->getField())
2402 AddMemberRef(Field, D->getFieldLoc());
2403 continue;
2404 }
2405 if (D->isArrayDesignator()) {
2406 AddStmt(E->getArrayIndex(*D));
2407 continue;
2408 }
2409 assert(D->isArrayRangeDesignator() && "Unknown designator kind");
2410 AddStmt(E->getArrayRangeEnd(*D));
2411 AddStmt(E->getArrayRangeStart(*D));
2412 }
2413}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002414void EnqueueVisitor::VisitExplicitCastExpr(const ExplicitCastExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002415 EnqueueChildren(E);
2416 AddTypeLoc(E->getTypeInfoAsWritten());
2417}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002418void EnqueueVisitor::VisitForStmt(const ForStmt *FS) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002419 AddStmt(FS->getBody());
2420 AddStmt(FS->getInc());
2421 AddStmt(FS->getCond());
2422 AddDecl(FS->getConditionVariable());
2423 AddStmt(FS->getInit());
2424}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002425void EnqueueVisitor::VisitGotoStmt(const GotoStmt *GS) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002426 WL.push_back(LabelRefVisit(GS->getLabel(), GS->getLabelLoc(), Parent));
2427}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002428void EnqueueVisitor::VisitIfStmt(const IfStmt *If) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002429 AddStmt(If->getElse());
2430 AddStmt(If->getThen());
2431 AddStmt(If->getCond());
2432 AddDecl(If->getConditionVariable());
2433}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002434void EnqueueVisitor::VisitInitListExpr(const InitListExpr *IE) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002435 // We care about the syntactic form of the initializer list, only.
2436 if (InitListExpr *Syntactic = IE->getSyntacticForm())
2437 IE = Syntactic;
2438 EnqueueChildren(IE);
2439}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002440void EnqueueVisitor::VisitMemberExpr(const MemberExpr *M) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002441 WL.push_back(MemberExprParts(M, Parent));
2442
2443 // If the base of the member access expression is an implicit 'this', don't
2444 // visit it.
2445 // FIXME: If we ever want to show these implicit accesses, this will be
2446 // unfortunate. However, clang_getCursor() relies on this behavior.
Argyrios Kyrtzidis58d0e7a2015-03-13 04:40:07 +00002447 if (M->isImplicitAccess())
2448 return;
2449
2450 // Ignore base anonymous struct/union fields, otherwise they will shadow the
2451 // real field that that we are interested in.
2452 if (auto *SubME = dyn_cast<MemberExpr>(M->getBase())) {
2453 if (auto *FD = dyn_cast_or_null<FieldDecl>(SubME->getMemberDecl())) {
2454 if (FD->isAnonymousStructOrUnion()) {
2455 AddStmt(SubME->getBase());
2456 return;
2457 }
2458 }
2459 }
2460
2461 AddStmt(M->getBase());
Guy Benyei11169dd2012-12-18 14:30:41 +00002462}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002463void EnqueueVisitor::VisitObjCEncodeExpr(const ObjCEncodeExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002464 AddTypeLoc(E->getEncodedTypeSourceInfo());
2465}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002466void EnqueueVisitor::VisitObjCMessageExpr(const ObjCMessageExpr *M) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002467 EnqueueChildren(M);
2468 AddTypeLoc(M->getClassReceiverTypeInfo());
2469}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002470void EnqueueVisitor::VisitOffsetOfExpr(const OffsetOfExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002471 // Visit the components of the offsetof expression.
2472 for (unsigned N = E->getNumComponents(), I = N; I > 0; --I) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002473 const OffsetOfNode &Node = E->getComponent(I-1);
2474 switch (Node.getKind()) {
2475 case OffsetOfNode::Array:
2476 AddStmt(E->getIndexExpr(Node.getArrayExprIndex()));
2477 break;
2478 case OffsetOfNode::Field:
2479 AddMemberRef(Node.getField(), Node.getSourceRange().getEnd());
2480 break;
2481 case OffsetOfNode::Identifier:
2482 case OffsetOfNode::Base:
2483 continue;
2484 }
2485 }
2486 // Visit the type into which we're computing the offset.
2487 AddTypeLoc(E->getTypeSourceInfo());
2488}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002489void EnqueueVisitor::VisitOverloadExpr(const OverloadExpr *E) {
James Y Knight04ec5bf2015-12-24 02:59:37 +00002490 if (E->hasExplicitTemplateArgs())
2491 AddExplicitTemplateArgs(E->getTemplateArgs(), E->getNumTemplateArgs());
Guy Benyei11169dd2012-12-18 14:30:41 +00002492 WL.push_back(OverloadExprParts(E, Parent));
2493}
2494void EnqueueVisitor::VisitUnaryExprOrTypeTraitExpr(
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002495 const UnaryExprOrTypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002496 EnqueueChildren(E);
2497 if (E->isArgumentType())
2498 AddTypeLoc(E->getArgumentTypeInfo());
2499}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002500void EnqueueVisitor::VisitStmt(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002501 EnqueueChildren(S);
2502}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002503void EnqueueVisitor::VisitSwitchStmt(const SwitchStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002504 AddStmt(S->getBody());
2505 AddStmt(S->getCond());
2506 AddDecl(S->getConditionVariable());
2507}
2508
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002509void EnqueueVisitor::VisitWhileStmt(const WhileStmt *W) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002510 AddStmt(W->getBody());
2511 AddStmt(W->getCond());
2512 AddDecl(W->getConditionVariable());
2513}
2514
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002515void EnqueueVisitor::VisitTypeTraitExpr(const TypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002516 for (unsigned I = E->getNumArgs(); I > 0; --I)
2517 AddTypeLoc(E->getArg(I-1));
2518}
2519
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002520void EnqueueVisitor::VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002521 AddTypeLoc(E->getQueriedTypeSourceInfo());
2522}
2523
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002524void EnqueueVisitor::VisitExpressionTraitExpr(const ExpressionTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002525 EnqueueChildren(E);
2526}
2527
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002528void EnqueueVisitor::VisitUnresolvedMemberExpr(const UnresolvedMemberExpr *U) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002529 VisitOverloadExpr(U);
2530 if (!U->isImplicitAccess())
2531 AddStmt(U->getBase());
2532}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002533void EnqueueVisitor::VisitVAArgExpr(const VAArgExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002534 AddStmt(E->getSubExpr());
2535 AddTypeLoc(E->getWrittenTypeInfo());
2536}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002537void EnqueueVisitor::VisitSizeOfPackExpr(const SizeOfPackExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002538 WL.push_back(SizeOfPackExprParts(E, Parent));
2539}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002540void EnqueueVisitor::VisitOpaqueValueExpr(const OpaqueValueExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002541 // If the opaque value has a source expression, just transparently
2542 // visit that. This is useful for (e.g.) pseudo-object expressions.
2543 if (Expr *SourceExpr = E->getSourceExpr())
2544 return Visit(SourceExpr);
2545}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002546void EnqueueVisitor::VisitLambdaExpr(const LambdaExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002547 AddStmt(E->getBody());
2548 WL.push_back(LambdaExprParts(E, Parent));
2549}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002550void EnqueueVisitor::VisitPseudoObjectExpr(const PseudoObjectExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002551 // Treat the expression like its syntactic form.
2552 Visit(E->getSyntacticForm());
2553}
2554
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002555void EnqueueVisitor::VisitOMPExecutableDirective(
2556 const OMPExecutableDirective *D) {
2557 EnqueueChildren(D);
2558 for (ArrayRef<OMPClause *>::iterator I = D->clauses().begin(),
2559 E = D->clauses().end();
2560 I != E; ++I)
2561 EnqueueChildren(*I);
2562}
2563
Alexander Musman3aaab662014-08-19 11:27:13 +00002564void EnqueueVisitor::VisitOMPLoopDirective(const OMPLoopDirective *D) {
2565 VisitOMPExecutableDirective(D);
2566}
2567
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002568void EnqueueVisitor::VisitOMPParallelDirective(const OMPParallelDirective *D) {
2569 VisitOMPExecutableDirective(D);
2570}
2571
Alexey Bataev1b59ab52014-02-27 08:29:12 +00002572void EnqueueVisitor::VisitOMPSimdDirective(const OMPSimdDirective *D) {
Alexander Musman3aaab662014-08-19 11:27:13 +00002573 VisitOMPLoopDirective(D);
Alexey Bataev1b59ab52014-02-27 08:29:12 +00002574}
2575
Alexey Bataevf29276e2014-06-18 04:14:57 +00002576void EnqueueVisitor::VisitOMPForDirective(const OMPForDirective *D) {
Alexander Musman3aaab662014-08-19 11:27:13 +00002577 VisitOMPLoopDirective(D);
Alexey Bataevf29276e2014-06-18 04:14:57 +00002578}
2579
Alexander Musmanf82886e2014-09-18 05:12:34 +00002580void EnqueueVisitor::VisitOMPForSimdDirective(const OMPForSimdDirective *D) {
2581 VisitOMPLoopDirective(D);
2582}
2583
Alexey Bataevd3f8dd22014-06-25 11:44:49 +00002584void EnqueueVisitor::VisitOMPSectionsDirective(const OMPSectionsDirective *D) {
2585 VisitOMPExecutableDirective(D);
2586}
2587
Alexey Bataev1e0498a2014-06-26 08:21:58 +00002588void EnqueueVisitor::VisitOMPSectionDirective(const OMPSectionDirective *D) {
2589 VisitOMPExecutableDirective(D);
2590}
2591
Alexey Bataevd1e40fb2014-06-26 12:05:45 +00002592void EnqueueVisitor::VisitOMPSingleDirective(const OMPSingleDirective *D) {
2593 VisitOMPExecutableDirective(D);
2594}
2595
Alexander Musman80c22892014-07-17 08:54:58 +00002596void EnqueueVisitor::VisitOMPMasterDirective(const OMPMasterDirective *D) {
2597 VisitOMPExecutableDirective(D);
2598}
2599
Alexander Musmand9ed09f2014-07-21 09:42:05 +00002600void EnqueueVisitor::VisitOMPCriticalDirective(const OMPCriticalDirective *D) {
2601 VisitOMPExecutableDirective(D);
2602 AddDeclarationNameInfo(D);
2603}
2604
Alexey Bataev4acb8592014-07-07 13:01:15 +00002605void
2606EnqueueVisitor::VisitOMPParallelForDirective(const OMPParallelForDirective *D) {
Alexander Musman3aaab662014-08-19 11:27:13 +00002607 VisitOMPLoopDirective(D);
Alexey Bataev4acb8592014-07-07 13:01:15 +00002608}
2609
Alexander Musmane4e893b2014-09-23 09:33:00 +00002610void EnqueueVisitor::VisitOMPParallelForSimdDirective(
2611 const OMPParallelForSimdDirective *D) {
2612 VisitOMPLoopDirective(D);
2613}
2614
Alexey Bataev84d0b3e2014-07-08 08:12:03 +00002615void EnqueueVisitor::VisitOMPParallelSectionsDirective(
2616 const OMPParallelSectionsDirective *D) {
2617 VisitOMPExecutableDirective(D);
2618}
2619
Alexey Bataev9c2e8ee2014-07-11 11:25:16 +00002620void EnqueueVisitor::VisitOMPTaskDirective(const OMPTaskDirective *D) {
2621 VisitOMPExecutableDirective(D);
2622}
2623
Alexey Bataev68446b72014-07-18 07:47:19 +00002624void
2625EnqueueVisitor::VisitOMPTaskyieldDirective(const OMPTaskyieldDirective *D) {
2626 VisitOMPExecutableDirective(D);
2627}
2628
Alexey Bataev4d1dfea2014-07-18 09:11:51 +00002629void EnqueueVisitor::VisitOMPBarrierDirective(const OMPBarrierDirective *D) {
2630 VisitOMPExecutableDirective(D);
2631}
2632
Alexey Bataev2df347a2014-07-18 10:17:07 +00002633void EnqueueVisitor::VisitOMPTaskwaitDirective(const OMPTaskwaitDirective *D) {
2634 VisitOMPExecutableDirective(D);
2635}
2636
Alexey Bataevc30dd2d2015-06-18 12:14:09 +00002637void EnqueueVisitor::VisitOMPTaskgroupDirective(
2638 const OMPTaskgroupDirective *D) {
2639 VisitOMPExecutableDirective(D);
2640}
2641
Alexey Bataev6125da92014-07-21 11:26:11 +00002642void EnqueueVisitor::VisitOMPFlushDirective(const OMPFlushDirective *D) {
2643 VisitOMPExecutableDirective(D);
2644}
2645
Alexey Bataev9fb6e642014-07-22 06:45:04 +00002646void EnqueueVisitor::VisitOMPOrderedDirective(const OMPOrderedDirective *D) {
2647 VisitOMPExecutableDirective(D);
2648}
2649
Alexey Bataev0162e452014-07-22 10:10:35 +00002650void EnqueueVisitor::VisitOMPAtomicDirective(const OMPAtomicDirective *D) {
2651 VisitOMPExecutableDirective(D);
2652}
2653
Alexey Bataev0bd520b2014-09-19 08:19:49 +00002654void EnqueueVisitor::VisitOMPTargetDirective(const OMPTargetDirective *D) {
2655 VisitOMPExecutableDirective(D);
2656}
2657
Michael Wong65f367f2015-07-21 13:44:28 +00002658void EnqueueVisitor::VisitOMPTargetDataDirective(const
2659 OMPTargetDataDirective *D) {
2660 VisitOMPExecutableDirective(D);
2661}
2662
Samuel Antaodf67fc42016-01-19 19:15:56 +00002663void EnqueueVisitor::VisitOMPTargetEnterDataDirective(
2664 const OMPTargetEnterDataDirective *D) {
2665 VisitOMPExecutableDirective(D);
2666}
2667
Samuel Antao72590762016-01-19 20:04:50 +00002668void EnqueueVisitor::VisitOMPTargetExitDataDirective(
2669 const OMPTargetExitDataDirective *D) {
2670 VisitOMPExecutableDirective(D);
2671}
2672
Arpith Chacko Jacobe955b3d2016-01-26 18:48:41 +00002673void EnqueueVisitor::VisitOMPTargetParallelDirective(
2674 const OMPTargetParallelDirective *D) {
2675 VisitOMPExecutableDirective(D);
2676}
2677
Arpith Chacko Jacob05bebb52016-02-03 15:46:42 +00002678void EnqueueVisitor::VisitOMPTargetParallelForDirective(
2679 const OMPTargetParallelForDirective *D) {
2680 VisitOMPLoopDirective(D);
2681}
2682
Alexey Bataev13314bf2014-10-09 04:18:56 +00002683void EnqueueVisitor::VisitOMPTeamsDirective(const OMPTeamsDirective *D) {
2684 VisitOMPExecutableDirective(D);
2685}
2686
Alexey Bataev6d4ed052015-07-01 06:57:41 +00002687void EnqueueVisitor::VisitOMPCancellationPointDirective(
2688 const OMPCancellationPointDirective *D) {
2689 VisitOMPExecutableDirective(D);
2690}
2691
Alexey Bataev80909872015-07-02 11:25:17 +00002692void EnqueueVisitor::VisitOMPCancelDirective(const OMPCancelDirective *D) {
2693 VisitOMPExecutableDirective(D);
2694}
2695
Alexey Bataev49f6e782015-12-01 04:18:41 +00002696void EnqueueVisitor::VisitOMPTaskLoopDirective(const OMPTaskLoopDirective *D) {
2697 VisitOMPLoopDirective(D);
2698}
2699
Alexey Bataev0a6ed842015-12-03 09:40:15 +00002700void EnqueueVisitor::VisitOMPTaskLoopSimdDirective(
2701 const OMPTaskLoopSimdDirective *D) {
2702 VisitOMPLoopDirective(D);
2703}
2704
Carlo Bertolli6200a3d2015-12-14 14:51:25 +00002705void EnqueueVisitor::VisitOMPDistributeDirective(
2706 const OMPDistributeDirective *D) {
2707 VisitOMPLoopDirective(D);
2708}
2709
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002710void CursorVisitor::EnqueueWorkList(VisitorWorkList &WL, const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002711 EnqueueVisitor(WL, MakeCXCursor(S, StmtParent, TU,RegionOfInterest)).Visit(S);
2712}
2713
2714bool CursorVisitor::IsInRegionOfInterest(CXCursor C) {
2715 if (RegionOfInterest.isValid()) {
2716 SourceRange Range = getRawCursorExtent(C);
2717 if (Range.isInvalid() || CompareRegionOfInterest(Range))
2718 return false;
2719 }
2720 return true;
2721}
2722
2723bool CursorVisitor::RunVisitorWorkList(VisitorWorkList &WL) {
2724 while (!WL.empty()) {
2725 // Dequeue the worklist item.
Robert Wilhelm25284cc2013-08-23 16:11:15 +00002726 VisitorJob LI = WL.pop_back_val();
Guy Benyei11169dd2012-12-18 14:30:41 +00002727
2728 // Set the Parent field, then back to its old value once we're done.
2729 SetParentRAII SetParent(Parent, StmtParent, LI.getParent());
2730
2731 switch (LI.getKind()) {
2732 case VisitorJob::DeclVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002733 const Decl *D = cast<DeclVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002734 if (!D)
2735 continue;
2736
2737 // For now, perform default visitation for Decls.
2738 if (Visit(MakeCXCursor(D, TU, RegionOfInterest,
2739 cast<DeclVisit>(&LI)->isFirst())))
2740 return true;
2741
2742 continue;
2743 }
2744 case VisitorJob::ExplicitTemplateArgsVisitKind: {
James Y Knight04ec5bf2015-12-24 02:59:37 +00002745 for (const TemplateArgumentLoc &Arg :
2746 *cast<ExplicitTemplateArgsVisit>(&LI)) {
2747 if (VisitTemplateArgumentLoc(Arg))
Guy Benyei11169dd2012-12-18 14:30:41 +00002748 return true;
2749 }
2750 continue;
2751 }
2752 case VisitorJob::TypeLocVisitKind: {
2753 // Perform default visitation for TypeLocs.
2754 if (Visit(cast<TypeLocVisit>(&LI)->get()))
2755 return true;
2756 continue;
2757 }
2758 case VisitorJob::LabelRefVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002759 const LabelDecl *LS = cast<LabelRefVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002760 if (LabelStmt *stmt = LS->getStmt()) {
2761 if (Visit(MakeCursorLabelRef(stmt, cast<LabelRefVisit>(&LI)->getLoc(),
2762 TU))) {
2763 return true;
2764 }
2765 }
2766 continue;
2767 }
2768
2769 case VisitorJob::NestedNameSpecifierLocVisitKind: {
2770 NestedNameSpecifierLocVisit *V = cast<NestedNameSpecifierLocVisit>(&LI);
2771 if (VisitNestedNameSpecifierLoc(V->get()))
2772 return true;
2773 continue;
2774 }
2775
2776 case VisitorJob::DeclarationNameInfoVisitKind: {
2777 if (VisitDeclarationNameInfo(cast<DeclarationNameInfoVisit>(&LI)
2778 ->get()))
2779 return true;
2780 continue;
2781 }
2782 case VisitorJob::MemberRefVisitKind: {
2783 MemberRefVisit *V = cast<MemberRefVisit>(&LI);
2784 if (Visit(MakeCursorMemberRef(V->get(), V->getLoc(), TU)))
2785 return true;
2786 continue;
2787 }
2788 case VisitorJob::StmtVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002789 const Stmt *S = cast<StmtVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002790 if (!S)
2791 continue;
2792
2793 // Update the current cursor.
2794 CXCursor Cursor = MakeCXCursor(S, StmtParent, TU, RegionOfInterest);
2795 if (!IsInRegionOfInterest(Cursor))
2796 continue;
2797 switch (Visitor(Cursor, Parent, ClientData)) {
2798 case CXChildVisit_Break: return true;
2799 case CXChildVisit_Continue: break;
2800 case CXChildVisit_Recurse:
2801 if (PostChildrenVisitor)
Craig Topper69186e72014-06-08 08:38:04 +00002802 WL.push_back(PostChildrenVisit(nullptr, Cursor));
Guy Benyei11169dd2012-12-18 14:30:41 +00002803 EnqueueWorkList(WL, S);
2804 break;
2805 }
2806 continue;
2807 }
2808 case VisitorJob::MemberExprPartsKind: {
2809 // Handle the other pieces in the MemberExpr besides the base.
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002810 const MemberExpr *M = cast<MemberExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002811
2812 // Visit the nested-name-specifier
2813 if (NestedNameSpecifierLoc QualifierLoc = M->getQualifierLoc())
2814 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2815 return true;
2816
2817 // Visit the declaration name.
2818 if (VisitDeclarationNameInfo(M->getMemberNameInfo()))
2819 return true;
2820
2821 // Visit the explicitly-specified template arguments, if any.
2822 if (M->hasExplicitTemplateArgs()) {
2823 for (const TemplateArgumentLoc *Arg = M->getTemplateArgs(),
2824 *ArgEnd = Arg + M->getNumTemplateArgs();
2825 Arg != ArgEnd; ++Arg) {
2826 if (VisitTemplateArgumentLoc(*Arg))
2827 return true;
2828 }
2829 }
2830 continue;
2831 }
2832 case VisitorJob::DeclRefExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002833 const DeclRefExpr *DR = cast<DeclRefExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002834 // Visit nested-name-specifier, if present.
2835 if (NestedNameSpecifierLoc QualifierLoc = DR->getQualifierLoc())
2836 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2837 return true;
2838 // Visit declaration name.
2839 if (VisitDeclarationNameInfo(DR->getNameInfo()))
2840 return true;
2841 continue;
2842 }
2843 case VisitorJob::OverloadExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002844 const OverloadExpr *O = cast<OverloadExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002845 // Visit the nested-name-specifier.
2846 if (NestedNameSpecifierLoc QualifierLoc = O->getQualifierLoc())
2847 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2848 return true;
2849 // Visit the declaration name.
2850 if (VisitDeclarationNameInfo(O->getNameInfo()))
2851 return true;
2852 // Visit the overloaded declaration reference.
2853 if (Visit(MakeCursorOverloadedDeclRef(O, TU)))
2854 return true;
2855 continue;
2856 }
2857 case VisitorJob::SizeOfPackExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002858 const SizeOfPackExpr *E = cast<SizeOfPackExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002859 NamedDecl *Pack = E->getPack();
2860 if (isa<TemplateTypeParmDecl>(Pack)) {
2861 if (Visit(MakeCursorTypeRef(cast<TemplateTypeParmDecl>(Pack),
2862 E->getPackLoc(), TU)))
2863 return true;
2864
2865 continue;
2866 }
2867
2868 if (isa<TemplateTemplateParmDecl>(Pack)) {
2869 if (Visit(MakeCursorTemplateRef(cast<TemplateTemplateParmDecl>(Pack),
2870 E->getPackLoc(), TU)))
2871 return true;
2872
2873 continue;
2874 }
2875
2876 // Non-type template parameter packs and function parameter packs are
2877 // treated like DeclRefExpr cursors.
2878 continue;
2879 }
2880
2881 case VisitorJob::LambdaExprPartsKind: {
2882 // Visit captures.
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002883 const LambdaExpr *E = cast<LambdaExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002884 for (LambdaExpr::capture_iterator C = E->explicit_capture_begin(),
2885 CEnd = E->explicit_capture_end();
2886 C != CEnd; ++C) {
Richard Smithba71c082013-05-16 06:20:58 +00002887 // FIXME: Lambda init-captures.
2888 if (!C->capturesVariable())
Guy Benyei11169dd2012-12-18 14:30:41 +00002889 continue;
Richard Smithba71c082013-05-16 06:20:58 +00002890
Guy Benyei11169dd2012-12-18 14:30:41 +00002891 if (Visit(MakeCursorVariableRef(C->getCapturedVar(),
2892 C->getLocation(),
2893 TU)))
2894 return true;
2895 }
2896
2897 // Visit parameters and return type, if present.
2898 if (E->hasExplicitParameters() || E->hasExplicitResultType()) {
2899 TypeLoc TL = E->getCallOperator()->getTypeSourceInfo()->getTypeLoc();
2900 if (E->hasExplicitParameters() && E->hasExplicitResultType()) {
2901 // Visit the whole type.
2902 if (Visit(TL))
2903 return true;
David Blaikie6adc78e2013-02-18 22:06:02 +00002904 } else if (FunctionProtoTypeLoc Proto =
2905 TL.getAs<FunctionProtoTypeLoc>()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002906 if (E->hasExplicitParameters()) {
2907 // Visit parameters.
Alp Tokerb3fd5cf2014-01-21 00:32:38 +00002908 for (unsigned I = 0, N = Proto.getNumParams(); I != N; ++I)
2909 if (Visit(MakeCXCursor(Proto.getParam(I), TU)))
Guy Benyei11169dd2012-12-18 14:30:41 +00002910 return true;
2911 } else {
2912 // Visit result type.
Alp Toker42a16a62014-01-25 23:51:36 +00002913 if (Visit(Proto.getReturnLoc()))
Guy Benyei11169dd2012-12-18 14:30:41 +00002914 return true;
2915 }
2916 }
2917 }
2918 break;
2919 }
2920
2921 case VisitorJob::PostChildrenVisitKind:
2922 if (PostChildrenVisitor(Parent, ClientData))
2923 return true;
2924 break;
2925 }
2926 }
2927 return false;
2928}
2929
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002930bool CursorVisitor::Visit(const Stmt *S) {
Craig Topper69186e72014-06-08 08:38:04 +00002931 VisitorWorkList *WL = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00002932 if (!WorkListFreeList.empty()) {
2933 WL = WorkListFreeList.back();
2934 WL->clear();
2935 WorkListFreeList.pop_back();
2936 }
2937 else {
2938 WL = new VisitorWorkList();
2939 WorkListCache.push_back(WL);
2940 }
2941 EnqueueWorkList(*WL, S);
2942 bool result = RunVisitorWorkList(*WL);
2943 WorkListFreeList.push_back(WL);
2944 return result;
2945}
2946
2947namespace {
Dmitri Gribenkof8579502013-01-12 19:30:44 +00002948typedef SmallVector<SourceRange, 4> RefNamePieces;
James Y Knight04ec5bf2015-12-24 02:59:37 +00002949RefNamePieces buildPieces(unsigned NameFlags, bool IsMemberRefExpr,
2950 const DeclarationNameInfo &NI, SourceRange QLoc,
2951 const SourceRange *TemplateArgsLoc = nullptr) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002952 const bool WantQualifier = NameFlags & CXNameRange_WantQualifier;
2953 const bool WantTemplateArgs = NameFlags & CXNameRange_WantTemplateArgs;
2954 const bool WantSinglePiece = NameFlags & CXNameRange_WantSinglePiece;
2955
2956 const DeclarationName::NameKind Kind = NI.getName().getNameKind();
2957
2958 RefNamePieces Pieces;
2959
2960 if (WantQualifier && QLoc.isValid())
2961 Pieces.push_back(QLoc);
2962
2963 if (Kind != DeclarationName::CXXOperatorName || IsMemberRefExpr)
2964 Pieces.push_back(NI.getLoc());
James Y Knight04ec5bf2015-12-24 02:59:37 +00002965
2966 if (WantTemplateArgs && TemplateArgsLoc && TemplateArgsLoc->isValid())
2967 Pieces.push_back(*TemplateArgsLoc);
2968
Guy Benyei11169dd2012-12-18 14:30:41 +00002969 if (Kind == DeclarationName::CXXOperatorName) {
2970 Pieces.push_back(SourceLocation::getFromRawEncoding(
2971 NI.getInfo().CXXOperatorName.BeginOpNameLoc));
2972 Pieces.push_back(SourceLocation::getFromRawEncoding(
2973 NI.getInfo().CXXOperatorName.EndOpNameLoc));
2974 }
2975
2976 if (WantSinglePiece) {
2977 SourceRange R(Pieces.front().getBegin(), Pieces.back().getEnd());
2978 Pieces.clear();
2979 Pieces.push_back(R);
2980 }
2981
2982 return Pieces;
2983}
Alexander Kornienkoab9db512015-06-22 23:07:51 +00002984}
Guy Benyei11169dd2012-12-18 14:30:41 +00002985
2986//===----------------------------------------------------------------------===//
2987// Misc. API hooks.
2988//===----------------------------------------------------------------------===//
2989
Chad Rosier05c71aa2013-03-27 18:28:23 +00002990static void fatal_error_handler(void *user_data, const std::string& reason,
2991 bool gen_crash_diag) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002992 // Write the result out to stderr avoiding errs() because raw_ostreams can
2993 // call report_fatal_error.
2994 fprintf(stderr, "LIBCLANG FATAL ERROR: %s\n", reason.c_str());
2995 ::abort();
2996}
2997
Chandler Carruth66660742014-06-27 16:37:27 +00002998namespace {
2999struct RegisterFatalErrorHandler {
3000 RegisterFatalErrorHandler() {
3001 llvm::install_fatal_error_handler(fatal_error_handler, nullptr);
3002 }
3003};
3004}
3005
3006static llvm::ManagedStatic<RegisterFatalErrorHandler> RegisterFatalErrorHandlerOnce;
3007
Guy Benyei11169dd2012-12-18 14:30:41 +00003008extern "C" {
3009CXIndex clang_createIndex(int excludeDeclarationsFromPCH,
3010 int displayDiagnostics) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003011 // We use crash recovery to make some of our APIs more reliable, implicitly
3012 // enable it.
Argyrios Kyrtzidis3701f542013-11-27 08:58:09 +00003013 if (!getenv("LIBCLANG_DISABLE_CRASH_RECOVERY"))
3014 llvm::CrashRecoveryContext::Enable();
Guy Benyei11169dd2012-12-18 14:30:41 +00003015
Chandler Carruth66660742014-06-27 16:37:27 +00003016 // Look through the managed static to trigger construction of the managed
3017 // static which registers our fatal error handler. This ensures it is only
3018 // registered once.
3019 (void)*RegisterFatalErrorHandlerOnce;
Guy Benyei11169dd2012-12-18 14:30:41 +00003020
Adrian Prantlbc068582015-07-08 01:00:30 +00003021 // Initialize targets for clang module support.
3022 llvm::InitializeAllTargets();
3023 llvm::InitializeAllTargetMCs();
3024 llvm::InitializeAllAsmPrinters();
3025 llvm::InitializeAllAsmParsers();
3026
Adrian Prantlfb2398d2015-07-17 01:19:54 +00003027 CIndexer *CIdxr = new CIndexer();
3028
Guy Benyei11169dd2012-12-18 14:30:41 +00003029 if (excludeDeclarationsFromPCH)
3030 CIdxr->setOnlyLocalDecls();
3031 if (displayDiagnostics)
3032 CIdxr->setDisplayDiagnostics();
3033
3034 if (getenv("LIBCLANG_BGPRIO_INDEX"))
3035 CIdxr->setCXGlobalOptFlags(CIdxr->getCXGlobalOptFlags() |
3036 CXGlobalOpt_ThreadBackgroundPriorityForIndexing);
3037 if (getenv("LIBCLANG_BGPRIO_EDIT"))
3038 CIdxr->setCXGlobalOptFlags(CIdxr->getCXGlobalOptFlags() |
3039 CXGlobalOpt_ThreadBackgroundPriorityForEditing);
3040
3041 return CIdxr;
3042}
3043
3044void clang_disposeIndex(CXIndex CIdx) {
3045 if (CIdx)
3046 delete static_cast<CIndexer *>(CIdx);
3047}
3048
3049void clang_CXIndex_setGlobalOptions(CXIndex CIdx, unsigned options) {
3050 if (CIdx)
3051 static_cast<CIndexer *>(CIdx)->setCXGlobalOptFlags(options);
3052}
3053
3054unsigned clang_CXIndex_getGlobalOptions(CXIndex CIdx) {
3055 if (CIdx)
3056 return static_cast<CIndexer *>(CIdx)->getCXGlobalOptFlags();
3057 return 0;
3058}
3059
3060void clang_toggleCrashRecovery(unsigned isEnabled) {
3061 if (isEnabled)
3062 llvm::CrashRecoveryContext::Enable();
3063 else
3064 llvm::CrashRecoveryContext::Disable();
3065}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003066
Guy Benyei11169dd2012-12-18 14:30:41 +00003067CXTranslationUnit clang_createTranslationUnit(CXIndex CIdx,
3068 const char *ast_filename) {
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00003069 CXTranslationUnit TU;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003070 enum CXErrorCode Result =
3071 clang_createTranslationUnit2(CIdx, ast_filename, &TU);
Reid Klecknerfd48fc62014-02-12 23:56:20 +00003072 (void)Result;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003073 assert((TU && Result == CXError_Success) ||
3074 (!TU && Result != CXError_Success));
3075 return TU;
3076}
3077
3078enum CXErrorCode clang_createTranslationUnit2(CXIndex CIdx,
3079 const char *ast_filename,
3080 CXTranslationUnit *out_TU) {
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00003081 if (out_TU)
Craig Topper69186e72014-06-08 08:38:04 +00003082 *out_TU = nullptr;
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00003083
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003084 if (!CIdx || !ast_filename || !out_TU)
3085 return CXError_InvalidArguments;
Guy Benyei11169dd2012-12-18 14:30:41 +00003086
Argyrios Kyrtzidis27021012013-05-24 22:24:07 +00003087 LOG_FUNC_SECTION {
3088 *Log << ast_filename;
3089 }
3090
Guy Benyei11169dd2012-12-18 14:30:41 +00003091 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
3092 FileSystemOptions FileSystemOpts;
3093
Justin Bognerd512c1e2014-10-15 00:33:06 +00003094 IntrusiveRefCntPtr<DiagnosticsEngine> Diags =
3095 CompilerInstance::createDiagnostics(new DiagnosticOptions());
David Blaikie6f7382d2014-08-10 19:08:04 +00003096 std::unique_ptr<ASTUnit> AU = ASTUnit::LoadFromASTFile(
Adrian Prantlfb2398d2015-07-17 01:19:54 +00003097 ast_filename, CXXIdx->getPCHContainerOperations()->getRawReader(), Diags,
Adrian Prantl6b21ab22015-08-27 19:46:20 +00003098 FileSystemOpts, /*UseDebugInfo=*/false,
3099 CXXIdx->getOnlyLocalDecls(), None,
David Blaikie6f7382d2014-08-10 19:08:04 +00003100 /*CaptureDiagnostics=*/true,
3101 /*AllowPCHWithCompilerErrors=*/true,
3102 /*UserFilesAreVolatile=*/true);
3103 *out_TU = MakeCXTranslationUnit(CXXIdx, AU.release());
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003104 return *out_TU ? CXError_Success : CXError_Failure;
Guy Benyei11169dd2012-12-18 14:30:41 +00003105}
3106
3107unsigned clang_defaultEditingTranslationUnitOptions() {
3108 return CXTranslationUnit_PrecompiledPreamble |
3109 CXTranslationUnit_CacheCompletionResults;
3110}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003111
Guy Benyei11169dd2012-12-18 14:30:41 +00003112CXTranslationUnit
3113clang_createTranslationUnitFromSourceFile(CXIndex CIdx,
3114 const char *source_filename,
3115 int num_command_line_args,
3116 const char * const *command_line_args,
3117 unsigned num_unsaved_files,
3118 struct CXUnsavedFile *unsaved_files) {
3119 unsigned Options = CXTranslationUnit_DetailedPreprocessingRecord;
3120 return clang_parseTranslationUnit(CIdx, source_filename,
3121 command_line_args, num_command_line_args,
3122 unsaved_files, num_unsaved_files,
3123 Options);
3124}
3125
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003126static CXErrorCode
3127clang_parseTranslationUnit_Impl(CXIndex CIdx, const char *source_filename,
3128 const char *const *command_line_args,
3129 int num_command_line_args,
3130 ArrayRef<CXUnsavedFile> unsaved_files,
3131 unsigned options, CXTranslationUnit *out_TU) {
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00003132 // Set up the initial return values.
3133 if (out_TU)
Craig Topper69186e72014-06-08 08:38:04 +00003134 *out_TU = nullptr;
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00003135
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003136 // Check arguments.
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003137 if (!CIdx || !out_TU)
3138 return CXError_InvalidArguments;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003139
Guy Benyei11169dd2012-12-18 14:30:41 +00003140 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
3141
3142 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
3143 setThreadBackgroundPriority();
3144
3145 bool PrecompilePreamble = options & CXTranslationUnit_PrecompiledPreamble;
Benjamin Kramer5c248d82015-12-15 09:30:31 +00003146 bool CreatePreambleOnFirstParse =
3147 options & CXTranslationUnit_CreatePreambleOnFirstParse;
Guy Benyei11169dd2012-12-18 14:30:41 +00003148 // FIXME: Add a flag for modules.
3149 TranslationUnitKind TUKind
3150 = (options & CXTranslationUnit_Incomplete)? TU_Prefix : TU_Complete;
Alp Toker8c8a8752013-12-03 06:53:35 +00003151 bool CacheCodeCompletionResults
Guy Benyei11169dd2012-12-18 14:30:41 +00003152 = options & CXTranslationUnit_CacheCompletionResults;
3153 bool IncludeBriefCommentsInCodeCompletion
3154 = options & CXTranslationUnit_IncludeBriefCommentsInCodeCompletion;
3155 bool SkipFunctionBodies = options & CXTranslationUnit_SkipFunctionBodies;
3156 bool ForSerialization = options & CXTranslationUnit_ForSerialization;
3157
3158 // Configure the diagnostics.
3159 IntrusiveRefCntPtr<DiagnosticsEngine>
Sean Silvaf1b49e22013-01-20 01:58:28 +00003160 Diags(CompilerInstance::createDiagnostics(new DiagnosticOptions));
Guy Benyei11169dd2012-12-18 14:30:41 +00003161
Manuel Klimek016c0242016-03-01 10:56:19 +00003162 if (options & CXTranslationUnit_KeepGoing)
3163 Diags->setFatalsAsError(true);
3164
Guy Benyei11169dd2012-12-18 14:30:41 +00003165 // Recover resources if we crash before exiting this function.
3166 llvm::CrashRecoveryContextCleanupRegistrar<DiagnosticsEngine,
3167 llvm::CrashRecoveryContextReleaseRefCleanup<DiagnosticsEngine> >
Alp Tokerf994cef2014-07-05 03:08:06 +00003168 DiagCleanup(Diags.get());
Guy Benyei11169dd2012-12-18 14:30:41 +00003169
Ahmed Charlesb8984322014-03-07 20:03:18 +00003170 std::unique_ptr<std::vector<ASTUnit::RemappedFile>> RemappedFiles(
3171 new std::vector<ASTUnit::RemappedFile>());
Guy Benyei11169dd2012-12-18 14:30:41 +00003172
3173 // Recover resources if we crash before exiting this function.
3174 llvm::CrashRecoveryContextCleanupRegistrar<
3175 std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
3176
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003177 for (auto &UF : unsaved_files) {
Rafael Espindolad87f8d72014-08-27 20:03:29 +00003178 std::unique_ptr<llvm::MemoryBuffer> MB =
Alp Toker9d85b182014-07-07 01:23:14 +00003179 llvm::MemoryBuffer::getMemBufferCopy(getContents(UF), UF.Filename);
Rafael Espindolad87f8d72014-08-27 20:03:29 +00003180 RemappedFiles->push_back(std::make_pair(UF.Filename, MB.release()));
Guy Benyei11169dd2012-12-18 14:30:41 +00003181 }
3182
Ahmed Charlesb8984322014-03-07 20:03:18 +00003183 std::unique_ptr<std::vector<const char *>> Args(
3184 new std::vector<const char *>());
Guy Benyei11169dd2012-12-18 14:30:41 +00003185
3186 // Recover resources if we crash before exiting this method.
3187 llvm::CrashRecoveryContextCleanupRegistrar<std::vector<const char*> >
3188 ArgsCleanup(Args.get());
3189
3190 // Since the Clang C library is primarily used by batch tools dealing with
3191 // (often very broken) source code, where spell-checking can have a
3192 // significant negative impact on performance (particularly when
3193 // precompiled headers are involved), we disable it by default.
3194 // Only do this if we haven't found a spell-checking-related argument.
3195 bool FoundSpellCheckingArgument = false;
3196 for (int I = 0; I != num_command_line_args; ++I) {
3197 if (strcmp(command_line_args[I], "-fno-spell-checking") == 0 ||
3198 strcmp(command_line_args[I], "-fspell-checking") == 0) {
3199 FoundSpellCheckingArgument = true;
3200 break;
3201 }
3202 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003203 Args->insert(Args->end(), command_line_args,
3204 command_line_args + num_command_line_args);
3205
Benjamin Kramerc02670e2015-11-18 16:14:27 +00003206 if (!FoundSpellCheckingArgument)
3207 Args->insert(Args->begin() + 1, "-fno-spell-checking");
3208
Guy Benyei11169dd2012-12-18 14:30:41 +00003209 // The 'source_filename' argument is optional. If the caller does not
3210 // specify it then it is assumed that the source file is specified
3211 // in the actual argument list.
3212 // Put the source file after command_line_args otherwise if '-x' flag is
3213 // present it will be unused.
3214 if (source_filename)
3215 Args->push_back(source_filename);
3216
3217 // Do we need the detailed preprocessing record?
3218 if (options & CXTranslationUnit_DetailedPreprocessingRecord) {
3219 Args->push_back("-Xclang");
3220 Args->push_back("-detailed-preprocessing-record");
3221 }
3222
3223 unsigned NumErrors = Diags->getClient()->getNumErrors();
Ahmed Charlesb8984322014-03-07 20:03:18 +00003224 std::unique_ptr<ASTUnit> ErrUnit;
Benjamin Kramer5c248d82015-12-15 09:30:31 +00003225 // Unless the user specified that they want the preamble on the first parse
3226 // set it up to be created on the first reparse. This makes the first parse
3227 // faster, trading for a slower (first) reparse.
3228 unsigned PrecompilePreambleAfterNParses =
3229 !PrecompilePreamble ? 0 : 2 - CreatePreambleOnFirstParse;
Ahmed Charlesb8984322014-03-07 20:03:18 +00003230 std::unique_ptr<ASTUnit> Unit(ASTUnit::LoadFromCommandLine(
Adrian Prantlbb165fb2015-06-20 18:53:08 +00003231 Args->data(), Args->data() + Args->size(),
3232 CXXIdx->getPCHContainerOperations(), Diags,
Ahmed Charlesb8984322014-03-07 20:03:18 +00003233 CXXIdx->getClangResourcesPath(), CXXIdx->getOnlyLocalDecls(),
3234 /*CaptureDiagnostics=*/true, *RemappedFiles.get(),
Benjamin Kramer5c248d82015-12-15 09:30:31 +00003235 /*RemappedFilesKeepOriginalName=*/true, PrecompilePreambleAfterNParses,
3236 TUKind, CacheCodeCompletionResults, IncludeBriefCommentsInCodeCompletion,
Ahmed Charlesb8984322014-03-07 20:03:18 +00003237 /*AllowPCHWithCompilerErrors=*/true, SkipFunctionBodies,
Argyrios Kyrtzidisa3e2ff12015-11-20 03:36:21 +00003238 /*UserFilesAreVolatile=*/true, ForSerialization,
3239 CXXIdx->getPCHContainerOperations()->getRawReader().getFormat(),
3240 &ErrUnit));
Guy Benyei11169dd2012-12-18 14:30:41 +00003241
Artem Belevich0ff05cd2015-07-13 23:27:56 +00003242 // Early failures in LoadFromCommandLine may return with ErrUnit unset.
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003243 if (!Unit && !ErrUnit)
3244 return CXError_ASTReadError;
Artem Belevich0ff05cd2015-07-13 23:27:56 +00003245
Guy Benyei11169dd2012-12-18 14:30:41 +00003246 if (NumErrors != Diags->getClient()->getNumErrors()) {
3247 // Make sure to check that 'Unit' is non-NULL.
3248 if (CXXIdx->getDisplayDiagnostics())
3249 printDiagsToStderr(Unit ? Unit.get() : ErrUnit.get());
3250 }
3251
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003252 if (isASTReadError(Unit ? Unit.get() : ErrUnit.get()))
3253 return CXError_ASTReadError;
3254
3255 *out_TU = MakeCXTranslationUnit(CXXIdx, Unit.release());
3256 return *out_TU ? CXError_Success : CXError_Failure;
Guy Benyei11169dd2012-12-18 14:30:41 +00003257}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003258
3259CXTranslationUnit
3260clang_parseTranslationUnit(CXIndex CIdx,
3261 const char *source_filename,
3262 const char *const *command_line_args,
3263 int num_command_line_args,
3264 struct CXUnsavedFile *unsaved_files,
3265 unsigned num_unsaved_files,
3266 unsigned options) {
3267 CXTranslationUnit TU;
3268 enum CXErrorCode Result = clang_parseTranslationUnit2(
3269 CIdx, source_filename, command_line_args, num_command_line_args,
3270 unsaved_files, num_unsaved_files, options, &TU);
Reid Kleckner6eaf05a2014-02-13 01:19:59 +00003271 (void)Result;
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00003272 assert((TU && Result == CXError_Success) ||
3273 (!TU && Result != CXError_Success));
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003274 return TU;
3275}
3276
3277enum CXErrorCode clang_parseTranslationUnit2(
Benjamin Kramerc02670e2015-11-18 16:14:27 +00003278 CXIndex CIdx, const char *source_filename,
3279 const char *const *command_line_args, int num_command_line_args,
3280 struct CXUnsavedFile *unsaved_files, unsigned num_unsaved_files,
3281 unsigned options, CXTranslationUnit *out_TU) {
3282 SmallVector<const char *, 4> Args;
3283 Args.push_back("clang");
3284 Args.append(command_line_args, command_line_args + num_command_line_args);
3285 return clang_parseTranslationUnit2FullArgv(
3286 CIdx, source_filename, Args.data(), Args.size(), unsaved_files,
3287 num_unsaved_files, options, out_TU);
3288}
3289
3290enum CXErrorCode clang_parseTranslationUnit2FullArgv(
3291 CXIndex CIdx, const char *source_filename,
3292 const char *const *command_line_args, int num_command_line_args,
3293 struct CXUnsavedFile *unsaved_files, unsigned num_unsaved_files,
3294 unsigned options, CXTranslationUnit *out_TU) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00003295 LOG_FUNC_SECTION {
3296 *Log << source_filename << ": ";
3297 for (int i = 0; i != num_command_line_args; ++i)
3298 *Log << command_line_args[i] << " ";
3299 }
3300
Alp Toker9d85b182014-07-07 01:23:14 +00003301 if (num_unsaved_files && !unsaved_files)
3302 return CXError_InvalidArguments;
3303
Alp Toker5c532982014-07-07 22:42:03 +00003304 CXErrorCode result = CXError_Failure;
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003305 auto ParseTranslationUnitImpl = [=, &result] {
3306 result = clang_parseTranslationUnit_Impl(
3307 CIdx, source_filename, command_line_args, num_command_line_args,
3308 llvm::makeArrayRef(unsaved_files, num_unsaved_files), options, out_TU);
3309 };
Guy Benyei11169dd2012-12-18 14:30:41 +00003310 llvm::CrashRecoveryContext CRC;
3311
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003312 if (!RunSafely(CRC, ParseTranslationUnitImpl)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003313 fprintf(stderr, "libclang: crash detected during parsing: {\n");
3314 fprintf(stderr, " 'source_filename' : '%s'\n", source_filename);
3315 fprintf(stderr, " 'command_line_args' : [");
3316 for (int i = 0; i != num_command_line_args; ++i) {
3317 if (i)
3318 fprintf(stderr, ", ");
3319 fprintf(stderr, "'%s'", command_line_args[i]);
3320 }
3321 fprintf(stderr, "],\n");
3322 fprintf(stderr, " 'unsaved_files' : [");
3323 for (unsigned i = 0; i != num_unsaved_files; ++i) {
3324 if (i)
3325 fprintf(stderr, ", ");
3326 fprintf(stderr, "('%s', '...', %ld)", unsaved_files[i].Filename,
3327 unsaved_files[i].Length);
3328 }
3329 fprintf(stderr, "],\n");
3330 fprintf(stderr, " 'options' : %d,\n", options);
3331 fprintf(stderr, "}\n");
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003332
3333 return CXError_Crashed;
Guy Benyei11169dd2012-12-18 14:30:41 +00003334 } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003335 if (CXTranslationUnit *TU = out_TU)
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003336 PrintLibclangResourceUsage(*TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003337 }
Alp Toker5c532982014-07-07 22:42:03 +00003338
3339 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003340}
3341
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003342CXString clang_Type_getObjCEncoding(CXType CT) {
3343 CXTranslationUnit tu = static_cast<CXTranslationUnit>(CT.data[1]);
3344 ASTContext &Ctx = getASTUnit(tu)->getASTContext();
3345 std::string encoding;
3346 Ctx.getObjCEncodingForType(QualType::getFromOpaquePtr(CT.data[0]),
3347 encoding);
3348
3349 return cxstring::createDup(encoding);
3350}
3351
3352static const IdentifierInfo *getMacroIdentifier(CXCursor C) {
3353 if (C.kind == CXCursor_MacroDefinition) {
3354 if (const MacroDefinitionRecord *MDR = getCursorMacroDefinition(C))
3355 return MDR->getName();
3356 } else if (C.kind == CXCursor_MacroExpansion) {
3357 MacroExpansionCursor ME = getCursorMacroExpansion(C);
3358 return ME.getName();
3359 }
3360 return nullptr;
3361}
3362
3363unsigned clang_Cursor_isMacroFunctionLike(CXCursor C) {
3364 const IdentifierInfo *II = getMacroIdentifier(C);
3365 if (!II) {
3366 return false;
3367 }
3368 ASTUnit *ASTU = getCursorASTUnit(C);
3369 Preprocessor &PP = ASTU->getPreprocessor();
3370 if (const MacroInfo *MI = PP.getMacroInfo(II))
3371 return MI->isFunctionLike();
3372 return false;
3373}
3374
3375unsigned clang_Cursor_isMacroBuiltin(CXCursor C) {
3376 const IdentifierInfo *II = getMacroIdentifier(C);
3377 if (!II) {
3378 return false;
3379 }
3380 ASTUnit *ASTU = getCursorASTUnit(C);
3381 Preprocessor &PP = ASTU->getPreprocessor();
3382 if (const MacroInfo *MI = PP.getMacroInfo(II))
3383 return MI->isBuiltinMacro();
3384 return false;
3385}
3386
3387unsigned clang_Cursor_isFunctionInlined(CXCursor C) {
3388 const Decl *D = getCursorDecl(C);
3389 const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(D);
3390 if (!FD) {
3391 return false;
3392 }
3393 return FD->isInlined();
3394}
3395
3396static StringLiteral* getCFSTR_value(CallExpr *callExpr) {
3397 if (callExpr->getNumArgs() != 1) {
3398 return nullptr;
3399 }
3400
3401 StringLiteral *S = nullptr;
3402 auto *arg = callExpr->getArg(0);
3403 if (arg->getStmtClass() == Stmt::ImplicitCastExprClass) {
3404 ImplicitCastExpr *I = static_cast<ImplicitCastExpr *>(arg);
3405 auto *subExpr = I->getSubExprAsWritten();
3406
3407 if(subExpr->getStmtClass() != Stmt::StringLiteralClass){
3408 return nullptr;
3409 }
3410
3411 S = static_cast<StringLiteral *>(I->getSubExprAsWritten());
3412 } else if (arg->getStmtClass() == Stmt::StringLiteralClass) {
3413 S = static_cast<StringLiteral *>(callExpr->getArg(0));
3414 } else {
3415 return nullptr;
3416 }
3417 return S;
3418}
3419
3420typedef struct {
3421 CXEvalResultKind EvalType;
3422 union {
3423 int intVal;
3424 double floatVal;
3425 char *stringVal;
3426 } EvalData;
3427} ExprEvalResult;
3428
3429void clang_EvalResult_dispose(CXEvalResult E) {
3430 ExprEvalResult *ER = (ExprEvalResult *)E;
3431 if (ER) {
3432 CXEvalResultKind evalType = ER->EvalType;
3433
3434 if (evalType != CXEval_UnExposed && evalType != CXEval_Float &&
3435 evalType != CXEval_Int && ER->EvalData.stringVal) {
3436 free((void *) ER->EvalData.stringVal);
3437 }
3438 free((void *)ER);
3439 }
3440}
3441
3442CXEvalResultKind clang_EvalResult_getKind(CXEvalResult E) {
3443 if (!E) {
3444 return CXEval_UnExposed;
3445 }
3446 return ((ExprEvalResult *)E)->EvalType;
3447}
3448
3449int clang_EvalResult_getAsInt(CXEvalResult E) {
3450 if (!E) {
3451 return 0;
3452 }
3453 return ((ExprEvalResult *)E)->EvalData.intVal;
3454}
3455
3456double clang_EvalResult_getAsDouble(CXEvalResult E) {
3457 if (!E) {
3458 return 0;
3459 }
3460 return ((ExprEvalResult *)E)->EvalData.floatVal;
3461}
3462
3463const char* clang_EvalResult_getAsStr(CXEvalResult E) {
3464 if (!E) {
3465 return nullptr;
3466 }
3467 return ((ExprEvalResult *)E)->EvalData.stringVal;
3468}
3469
3470static const ExprEvalResult* evaluateExpr(Expr *expr, CXCursor C) {
3471 Expr::EvalResult ER;
3472 ASTContext &ctx = getCursorContext(C);
3473 if (!expr) {
3474 return nullptr;
3475 }
3476 expr = expr->IgnoreParens();
3477 bool res = expr->EvaluateAsRValue(ER, ctx);
3478 QualType rettype;
3479 CallExpr *callExpr;
3480 ExprEvalResult *result = (ExprEvalResult *) malloc(sizeof(ExprEvalResult));
3481 if (!result) {
3482 return nullptr;
3483 }
3484 result->EvalType = CXEval_UnExposed;
3485
3486 if (res) {
3487
3488 if (ER.Val.isInt()) {
3489 result->EvalType = CXEval_Int;
3490 result->EvalData.intVal = ER.Val.getInt().getExtValue();
3491 return result;
3492 } else if (ER.Val.isFloat()) {
3493
3494 llvm::SmallVector<char, 100> Buffer;
3495 ER.Val.getFloat().toString(Buffer);
3496 std::string floatStr(Buffer.data(), Buffer.size());
3497 result->EvalType = CXEval_Float;
3498 bool ignored;
3499 llvm::APFloat apFloat = ER.Val.getFloat();
3500 apFloat.convert(llvm::APFloat::IEEEdouble,
3501 llvm::APFloat::rmNearestTiesToEven, &ignored);
3502 result->EvalData.floatVal = apFloat.convertToDouble();
3503 return result;
3504
3505 } else if (expr->getStmtClass() == Stmt::ImplicitCastExprClass) {
3506
3507 const ImplicitCastExpr *I = dyn_cast<ImplicitCastExpr>(expr);
3508 auto *subExpr = I->getSubExprAsWritten();
3509 if (subExpr->getStmtClass() == Stmt::StringLiteralClass ||
3510 subExpr->getStmtClass() == Stmt::ObjCStringLiteralClass) {
3511
3512 const StringLiteral *StrE = nullptr;
3513 const ObjCStringLiteral *ObjCExpr;
3514 ObjCExpr = dyn_cast<ObjCStringLiteral>(subExpr);
3515
3516 if (ObjCExpr) {
3517 StrE = ObjCExpr->getString();
3518 result->EvalType = CXEval_ObjCStrLiteral;
3519 } else {
3520 StrE = cast<StringLiteral>(I->getSubExprAsWritten());
3521 result->EvalType = CXEval_StrLiteral;
3522 }
3523
3524 std::string strRef(StrE->getString().str());
3525 result->EvalData.stringVal = (char *)malloc(strRef.size()+1);
3526 strncpy((char*)result->EvalData.stringVal, strRef.c_str(),
3527 strRef.size());
3528 result->EvalData.stringVal[strRef.size()] = '\0';
3529 return result;
3530 }
3531
3532 } else if (expr->getStmtClass() == Stmt::ObjCStringLiteralClass ||
3533 expr->getStmtClass() == Stmt::StringLiteralClass) {
3534
3535 const StringLiteral *StrE = nullptr;
3536 const ObjCStringLiteral *ObjCExpr;
3537 ObjCExpr = dyn_cast<ObjCStringLiteral>(expr);
3538
3539 if (ObjCExpr) {
3540 StrE = ObjCExpr->getString();
3541 result->EvalType = CXEval_ObjCStrLiteral;
3542 } else {
3543 StrE = cast<StringLiteral>(expr);
3544 result->EvalType = CXEval_StrLiteral;
3545 }
3546
3547 std::string strRef(StrE->getString().str());
3548 result->EvalData.stringVal = (char *)malloc(strRef.size()+1);
3549 strncpy((char*)result->EvalData.stringVal, strRef.c_str(),
3550 strRef.size());
3551 result->EvalData.stringVal[strRef.size()] = '\0';
3552 return result;
3553
3554 } else if (expr->getStmtClass() == Stmt::CStyleCastExprClass) {
3555
3556 CStyleCastExpr *CC = static_cast<CStyleCastExpr *>(expr);
3557
3558 rettype = CC->getType();
3559 if (rettype.getAsString() == "CFStringRef" &&
3560 CC->getSubExpr()->getStmtClass() == Stmt::CallExprClass) {
3561
3562 callExpr = static_cast<CallExpr *>(CC->getSubExpr());
3563 StringLiteral* S = getCFSTR_value(callExpr);
3564 if (S) {
3565 std::string strLiteral(S->getString().str());
3566 result->EvalType = CXEval_CFStr;
3567
3568 result->EvalData.stringVal = (char *)malloc(strLiteral.size()+1);
3569 strncpy((char*)result->EvalData.stringVal, strLiteral.c_str(),
3570 strLiteral.size());
3571 result->EvalData.stringVal[strLiteral.size()] = '\0';
3572 return result;
3573 }
3574 }
3575
3576 } else if (expr->getStmtClass() == Stmt::CallExprClass) {
3577
3578 callExpr = static_cast<CallExpr *>(expr);
3579 rettype = callExpr->getCallReturnType(ctx);
3580
3581 if (rettype->isVectorType() || callExpr->getNumArgs() > 1) {
3582 return nullptr;
3583 }
3584 if (rettype->isIntegralType(ctx) || rettype->isRealFloatingType()) {
3585 if(callExpr->getNumArgs() == 1 &&
3586 !callExpr->getArg(0)->getType()->isIntegralType(ctx)){
3587
3588 return nullptr;
3589 }
3590 } else if(rettype.getAsString() == "CFStringRef") {
3591
3592 StringLiteral* S = getCFSTR_value(callExpr);
3593 if (S) {
3594 std::string strLiteral(S->getString().str());
3595 result->EvalType = CXEval_CFStr;
3596 result->EvalData.stringVal = (char *)malloc(strLiteral.size()+1);
3597 strncpy((char*)result->EvalData.stringVal, strLiteral.c_str(),
3598 strLiteral.size());
3599 result->EvalData.stringVal[strLiteral.size()] = '\0';
3600 return result;
3601 }
3602 }
3603
3604 } else if (expr->getStmtClass() == Stmt::DeclRefExprClass) {
3605
3606 DeclRefExpr *D = static_cast<DeclRefExpr *>(expr);
3607 ValueDecl *V = D->getDecl();
3608 if (V->getKind() == Decl::Function) {
3609 std::string strName(V->getNameAsString());
3610 result->EvalType = CXEval_Other;
3611 result->EvalData.stringVal = (char *)malloc(strName.size()+1);
3612 strncpy((char*)result->EvalData.stringVal, strName.c_str(),
3613 strName.size());
3614 result->EvalData.stringVal[strName.size()] = '\0';
3615 return result;
3616 }
3617 }
3618
3619 }
3620
3621 clang_EvalResult_dispose((CXEvalResult *)result);
3622 return nullptr;
3623}
3624
3625CXEvalResult clang_Cursor_Evaluate(CXCursor C) {
3626 const Decl *D = getCursorDecl(C);
3627 if (D) {
3628 const Expr *expr = nullptr;
3629 if (auto *Var = dyn_cast<VarDecl>(D)) {
3630 expr = Var->getInit();
3631 } else if (auto *Field = dyn_cast<FieldDecl>(D)) {
3632 expr = Field->getInClassInitializer();
3633 }
3634 if (expr)
Aaron Ballman01dc1572016-01-20 15:25:30 +00003635 return const_cast<CXEvalResult>(reinterpret_cast<const void *>(
3636 evaluateExpr(const_cast<Expr *>(expr), C)));
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003637 return nullptr;
3638 }
3639
3640 const CompoundStmt *compoundStmt = dyn_cast_or_null<CompoundStmt>(getCursorStmt(C));
3641 if (compoundStmt) {
3642 Expr *expr = nullptr;
3643 for (auto *bodyIterator : compoundStmt->body()) {
3644 if ((expr = dyn_cast<Expr>(bodyIterator))) {
3645 break;
3646 }
3647 }
3648 if (expr)
Aaron Ballman01dc1572016-01-20 15:25:30 +00003649 return const_cast<CXEvalResult>(
3650 reinterpret_cast<const void *>(evaluateExpr(expr, C)));
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003651 }
3652 return nullptr;
3653}
3654
3655unsigned clang_Cursor_hasAttrs(CXCursor C) {
3656 const Decl *D = getCursorDecl(C);
3657 if (!D) {
3658 return 0;
3659 }
3660
3661 if (D->hasAttrs()) {
3662 return 1;
3663 }
3664
3665 return 0;
3666}
Guy Benyei11169dd2012-12-18 14:30:41 +00003667unsigned clang_defaultSaveOptions(CXTranslationUnit TU) {
3668 return CXSaveTranslationUnit_None;
3669}
3670
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003671static CXSaveError clang_saveTranslationUnit_Impl(CXTranslationUnit TU,
3672 const char *FileName,
3673 unsigned options) {
3674 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00003675 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
3676 setThreadBackgroundPriority();
3677
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003678 bool hadError = cxtu::getASTUnit(TU)->Save(FileName);
3679 return hadError ? CXSaveError_Unknown : CXSaveError_None;
Guy Benyei11169dd2012-12-18 14:30:41 +00003680}
3681
3682int clang_saveTranslationUnit(CXTranslationUnit TU, const char *FileName,
3683 unsigned options) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00003684 LOG_FUNC_SECTION {
3685 *Log << TU << ' ' << FileName;
3686 }
3687
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003688 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003689 LOG_BAD_TU(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003690 return CXSaveError_InvalidTU;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003691 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003692
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003693 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003694 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
3695 if (!CXXUnit->hasSema())
3696 return CXSaveError_InvalidTU;
3697
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003698 CXSaveError result;
3699 auto SaveTranslationUnitImpl = [=, &result]() {
3700 result = clang_saveTranslationUnit_Impl(TU, FileName, options);
3701 };
Guy Benyei11169dd2012-12-18 14:30:41 +00003702
3703 if (!CXXUnit->getDiagnostics().hasUnrecoverableErrorOccurred() ||
3704 getenv("LIBCLANG_NOTHREADS")) {
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003705 SaveTranslationUnitImpl();
Guy Benyei11169dd2012-12-18 14:30:41 +00003706
3707 if (getenv("LIBCLANG_RESOURCE_USAGE"))
3708 PrintLibclangResourceUsage(TU);
3709
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003710 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003711 }
3712
3713 // We have an AST that has invalid nodes due to compiler errors.
3714 // Use a crash recovery thread for protection.
3715
3716 llvm::CrashRecoveryContext CRC;
3717
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003718 if (!RunSafely(CRC, SaveTranslationUnitImpl)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003719 fprintf(stderr, "libclang: crash detected during AST saving: {\n");
3720 fprintf(stderr, " 'filename' : '%s'\n", FileName);
3721 fprintf(stderr, " 'options' : %d,\n", options);
3722 fprintf(stderr, "}\n");
3723
3724 return CXSaveError_Unknown;
3725
3726 } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
3727 PrintLibclangResourceUsage(TU);
3728 }
3729
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003730 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003731}
3732
3733void clang_disposeTranslationUnit(CXTranslationUnit CTUnit) {
3734 if (CTUnit) {
3735 // If the translation unit has been marked as unsafe to free, just discard
3736 // it.
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003737 ASTUnit *Unit = cxtu::getASTUnit(CTUnit);
3738 if (Unit && Unit->isUnsafeToFree())
Guy Benyei11169dd2012-12-18 14:30:41 +00003739 return;
3740
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003741 delete cxtu::getASTUnit(CTUnit);
Dmitri Gribenkob95b3f12013-01-26 22:44:19 +00003742 delete CTUnit->StringPool;
Guy Benyei11169dd2012-12-18 14:30:41 +00003743 delete static_cast<CXDiagnosticSetImpl *>(CTUnit->Diagnostics);
3744 disposeOverridenCXCursorsPool(CTUnit->OverridenCursorsPool);
Dmitri Gribenko9e605112013-11-13 22:16:51 +00003745 delete CTUnit->CommentToXML;
Guy Benyei11169dd2012-12-18 14:30:41 +00003746 delete CTUnit;
3747 }
3748}
3749
3750unsigned clang_defaultReparseOptions(CXTranslationUnit TU) {
3751 return CXReparse_None;
3752}
3753
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003754static CXErrorCode
3755clang_reparseTranslationUnit_Impl(CXTranslationUnit TU,
3756 ArrayRef<CXUnsavedFile> unsaved_files,
3757 unsigned options) {
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003758 // Check arguments.
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003759 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003760 LOG_BAD_TU(TU);
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003761 return CXError_InvalidArguments;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003762 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003763
3764 // Reset the associated diagnostics.
3765 delete static_cast<CXDiagnosticSetImpl*>(TU->Diagnostics);
Craig Topper69186e72014-06-08 08:38:04 +00003766 TU->Diagnostics = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00003767
Dmitri Gribenko183436e2013-01-26 21:49:50 +00003768 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00003769 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
3770 setThreadBackgroundPriority();
3771
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003772 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003773 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
Ahmed Charlesb8984322014-03-07 20:03:18 +00003774
3775 std::unique_ptr<std::vector<ASTUnit::RemappedFile>> RemappedFiles(
3776 new std::vector<ASTUnit::RemappedFile>());
3777
Guy Benyei11169dd2012-12-18 14:30:41 +00003778 // Recover resources if we crash before exiting this function.
3779 llvm::CrashRecoveryContextCleanupRegistrar<
3780 std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
Alp Toker9d85b182014-07-07 01:23:14 +00003781
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003782 for (auto &UF : unsaved_files) {
Rafael Espindolad87f8d72014-08-27 20:03:29 +00003783 std::unique_ptr<llvm::MemoryBuffer> MB =
Alp Toker9d85b182014-07-07 01:23:14 +00003784 llvm::MemoryBuffer::getMemBufferCopy(getContents(UF), UF.Filename);
Rafael Espindolad87f8d72014-08-27 20:03:29 +00003785 RemappedFiles->push_back(std::make_pair(UF.Filename, MB.release()));
Guy Benyei11169dd2012-12-18 14:30:41 +00003786 }
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003787
Adrian Prantlbb165fb2015-06-20 18:53:08 +00003788 if (!CXXUnit->Reparse(CXXIdx->getPCHContainerOperations(),
3789 *RemappedFiles.get()))
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003790 return CXError_Success;
3791 if (isASTReadError(CXXUnit))
3792 return CXError_ASTReadError;
3793 return CXError_Failure;
Guy Benyei11169dd2012-12-18 14:30:41 +00003794}
3795
3796int clang_reparseTranslationUnit(CXTranslationUnit TU,
3797 unsigned num_unsaved_files,
3798 struct CXUnsavedFile *unsaved_files,
3799 unsigned options) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00003800 LOG_FUNC_SECTION {
3801 *Log << TU;
3802 }
3803
Alp Toker9d85b182014-07-07 01:23:14 +00003804 if (num_unsaved_files && !unsaved_files)
3805 return CXError_InvalidArguments;
3806
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003807 CXErrorCode result;
3808 auto ReparseTranslationUnitImpl = [=, &result]() {
3809 result = clang_reparseTranslationUnit_Impl(
3810 TU, llvm::makeArrayRef(unsaved_files, num_unsaved_files), options);
3811 };
Guy Benyei11169dd2012-12-18 14:30:41 +00003812
3813 if (getenv("LIBCLANG_NOTHREADS")) {
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003814 ReparseTranslationUnitImpl();
Alp Toker5c532982014-07-07 22:42:03 +00003815 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003816 }
3817
3818 llvm::CrashRecoveryContext CRC;
3819
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003820 if (!RunSafely(CRC, ReparseTranslationUnitImpl)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003821 fprintf(stderr, "libclang: crash detected during reparsing\n");
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003822 cxtu::getASTUnit(TU)->setUnsafeToFree(true);
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003823 return CXError_Crashed;
Guy Benyei11169dd2012-12-18 14:30:41 +00003824 } else if (getenv("LIBCLANG_RESOURCE_USAGE"))
3825 PrintLibclangResourceUsage(TU);
3826
Alp Toker5c532982014-07-07 22:42:03 +00003827 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003828}
3829
3830
3831CXString clang_getTranslationUnitSpelling(CXTranslationUnit CTUnit) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003832 if (isNotUsableTU(CTUnit)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003833 LOG_BAD_TU(CTUnit);
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003834 return cxstring::createEmpty();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003835 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003836
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003837 ASTUnit *CXXUnit = cxtu::getASTUnit(CTUnit);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003838 return cxstring::createDup(CXXUnit->getOriginalSourceFileName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003839}
3840
3841CXCursor clang_getTranslationUnitCursor(CXTranslationUnit TU) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003842 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003843 LOG_BAD_TU(TU);
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00003844 return clang_getNullCursor();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003845 }
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00003846
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003847 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003848 return MakeCXCursor(CXXUnit->getASTContext().getTranslationUnitDecl(), TU);
3849}
3850
3851} // end: extern "C"
3852
3853//===----------------------------------------------------------------------===//
3854// CXFile Operations.
3855//===----------------------------------------------------------------------===//
3856
3857extern "C" {
3858CXString clang_getFileName(CXFile SFile) {
3859 if (!SFile)
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00003860 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00003861
3862 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003863 return cxstring::createRef(FEnt->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003864}
3865
3866time_t clang_getFileTime(CXFile SFile) {
3867 if (!SFile)
3868 return 0;
3869
3870 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
3871 return FEnt->getModificationTime();
3872}
3873
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003874CXFile clang_getFile(CXTranslationUnit TU, const char *file_name) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003875 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003876 LOG_BAD_TU(TU);
Craig Topper69186e72014-06-08 08:38:04 +00003877 return nullptr;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003878 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003879
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003880 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003881
3882 FileManager &FMgr = CXXUnit->getFileManager();
3883 return const_cast<FileEntry *>(FMgr.getFile(file_name));
3884}
3885
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003886unsigned clang_isFileMultipleIncludeGuarded(CXTranslationUnit TU,
3887 CXFile file) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003888 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003889 LOG_BAD_TU(TU);
3890 return 0;
3891 }
3892
3893 if (!file)
Guy Benyei11169dd2012-12-18 14:30:41 +00003894 return 0;
3895
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003896 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003897 FileEntry *FEnt = static_cast<FileEntry *>(file);
3898 return CXXUnit->getPreprocessor().getHeaderSearchInfo()
3899 .isFileMultipleIncludeGuarded(FEnt);
3900}
3901
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003902int clang_getFileUniqueID(CXFile file, CXFileUniqueID *outID) {
3903 if (!file || !outID)
3904 return 1;
3905
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003906 FileEntry *FEnt = static_cast<FileEntry *>(file);
Rafael Espindolaf8f91b82013-08-01 21:42:11 +00003907 const llvm::sys::fs::UniqueID &ID = FEnt->getUniqueID();
3908 outID->data[0] = ID.getDevice();
3909 outID->data[1] = ID.getFile();
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003910 outID->data[2] = FEnt->getModificationTime();
3911 return 0;
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003912}
3913
Argyrios Kyrtzidisac3997e2014-08-16 00:26:19 +00003914int clang_File_isEqual(CXFile file1, CXFile file2) {
3915 if (file1 == file2)
3916 return true;
3917
3918 if (!file1 || !file2)
3919 return false;
3920
3921 FileEntry *FEnt1 = static_cast<FileEntry *>(file1);
3922 FileEntry *FEnt2 = static_cast<FileEntry *>(file2);
3923 return FEnt1->getUniqueID() == FEnt2->getUniqueID();
3924}
3925
Guy Benyei11169dd2012-12-18 14:30:41 +00003926} // end: extern "C"
3927
3928//===----------------------------------------------------------------------===//
3929// CXCursor Operations.
3930//===----------------------------------------------------------------------===//
3931
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003932static const Decl *getDeclFromExpr(const Stmt *E) {
3933 if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003934 return getDeclFromExpr(CE->getSubExpr());
3935
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003936 if (const DeclRefExpr *RefExpr = dyn_cast<DeclRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003937 return RefExpr->getDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003938 if (const MemberExpr *ME = dyn_cast<MemberExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003939 return ME->getMemberDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003940 if (const ObjCIvarRefExpr *RE = dyn_cast<ObjCIvarRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003941 return RE->getDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003942 if (const ObjCPropertyRefExpr *PRE = dyn_cast<ObjCPropertyRefExpr>(E)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003943 if (PRE->isExplicitProperty())
3944 return PRE->getExplicitProperty();
3945 // It could be messaging both getter and setter as in:
3946 // ++myobj.myprop;
3947 // in which case prefer to associate the setter since it is less obvious
3948 // from inspecting the source that the setter is going to get called.
3949 if (PRE->isMessagingSetter())
3950 return PRE->getImplicitPropertySetter();
3951 return PRE->getImplicitPropertyGetter();
3952 }
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003953 if (const PseudoObjectExpr *POE = dyn_cast<PseudoObjectExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003954 return getDeclFromExpr(POE->getSyntacticForm());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003955 if (const OpaqueValueExpr *OVE = dyn_cast<OpaqueValueExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003956 if (Expr *Src = OVE->getSourceExpr())
3957 return getDeclFromExpr(Src);
3958
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003959 if (const CallExpr *CE = dyn_cast<CallExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003960 return getDeclFromExpr(CE->getCallee());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003961 if (const CXXConstructExpr *CE = dyn_cast<CXXConstructExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003962 if (!CE->isElidable())
3963 return CE->getConstructor();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003964 if (const ObjCMessageExpr *OME = dyn_cast<ObjCMessageExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003965 return OME->getMethodDecl();
3966
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003967 if (const ObjCProtocolExpr *PE = dyn_cast<ObjCProtocolExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003968 return PE->getProtocol();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003969 if (const SubstNonTypeTemplateParmPackExpr *NTTP
Guy Benyei11169dd2012-12-18 14:30:41 +00003970 = dyn_cast<SubstNonTypeTemplateParmPackExpr>(E))
3971 return NTTP->getParameterPack();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003972 if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003973 if (isa<NonTypeTemplateParmDecl>(SizeOfPack->getPack()) ||
3974 isa<ParmVarDecl>(SizeOfPack->getPack()))
3975 return SizeOfPack->getPack();
Craig Topper69186e72014-06-08 08:38:04 +00003976
3977 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00003978}
3979
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003980static SourceLocation getLocationFromExpr(const Expr *E) {
3981 if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003982 return getLocationFromExpr(CE->getSubExpr());
3983
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003984 if (const ObjCMessageExpr *Msg = dyn_cast<ObjCMessageExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003985 return /*FIXME:*/Msg->getLeftLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003986 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003987 return DRE->getLocation();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003988 if (const MemberExpr *Member = dyn_cast<MemberExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003989 return Member->getMemberLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003990 if (const ObjCIvarRefExpr *Ivar = dyn_cast<ObjCIvarRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003991 return Ivar->getLocation();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003992 if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003993 return SizeOfPack->getPackLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003994 if (const ObjCPropertyRefExpr *PropRef = dyn_cast<ObjCPropertyRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003995 return PropRef->getLocation();
3996
3997 return E->getLocStart();
3998}
3999
4000extern "C" {
4001
4002unsigned clang_visitChildren(CXCursor parent,
4003 CXCursorVisitor visitor,
4004 CXClientData client_data) {
4005 CursorVisitor CursorVis(getCursorTU(parent), visitor, client_data,
4006 /*VisitPreprocessorLast=*/false);
4007 return CursorVis.VisitChildren(parent);
4008}
4009
4010#ifndef __has_feature
4011#define __has_feature(x) 0
4012#endif
4013#if __has_feature(blocks)
4014typedef enum CXChildVisitResult
4015 (^CXCursorVisitorBlock)(CXCursor cursor, CXCursor parent);
4016
4017static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
4018 CXClientData client_data) {
4019 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
4020 return block(cursor, parent);
4021}
4022#else
4023// If we are compiled with a compiler that doesn't have native blocks support,
4024// define and call the block manually, so the
4025typedef struct _CXChildVisitResult
4026{
4027 void *isa;
4028 int flags;
4029 int reserved;
4030 enum CXChildVisitResult(*invoke)(struct _CXChildVisitResult*, CXCursor,
4031 CXCursor);
4032} *CXCursorVisitorBlock;
4033
4034static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
4035 CXClientData client_data) {
4036 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
4037 return block->invoke(block, cursor, parent);
4038}
4039#endif
4040
4041
4042unsigned clang_visitChildrenWithBlock(CXCursor parent,
4043 CXCursorVisitorBlock block) {
4044 return clang_visitChildren(parent, visitWithBlock, block);
4045}
4046
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004047static CXString getDeclSpelling(const Decl *D) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004048 if (!D)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00004049 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00004050
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004051 const NamedDecl *ND = dyn_cast<NamedDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00004052 if (!ND) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004053 if (const ObjCPropertyImplDecl *PropImpl =
4054 dyn_cast<ObjCPropertyImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004055 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004056 return cxstring::createDup(Property->getIdentifier()->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00004057
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004058 if (const ImportDecl *ImportD = dyn_cast<ImportDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004059 if (Module *Mod = ImportD->getImportedModule())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004060 return cxstring::createDup(Mod->getFullModuleName());
Guy Benyei11169dd2012-12-18 14:30:41 +00004061
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00004062 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00004063 }
4064
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004065 if (const ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(ND))
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004066 return cxstring::createDup(OMD->getSelector().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00004067
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004068 if (const ObjCCategoryImplDecl *CIMP = dyn_cast<ObjCCategoryImplDecl>(ND))
Guy Benyei11169dd2012-12-18 14:30:41 +00004069 // No, this isn't the same as the code below. getIdentifier() is non-virtual
4070 // and returns different names. NamedDecl returns the class name and
4071 // ObjCCategoryImplDecl returns the category name.
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004072 return cxstring::createRef(CIMP->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00004073
4074 if (isa<UsingDirectiveDecl>(D))
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00004075 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00004076
4077 SmallString<1024> S;
4078 llvm::raw_svector_ostream os(S);
4079 ND->printName(os);
4080
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004081 return cxstring::createDup(os.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00004082}
4083
4084CXString clang_getCursorSpelling(CXCursor C) {
4085 if (clang_isTranslationUnit(C.kind))
Dmitri Gribenko2c173b42013-01-11 19:28:44 +00004086 return clang_getTranslationUnitSpelling(getCursorTU(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00004087
4088 if (clang_isReference(C.kind)) {
4089 switch (C.kind) {
4090 case CXCursor_ObjCSuperClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004091 const ObjCInterfaceDecl *Super = getCursorObjCSuperClassRef(C).first;
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004092 return cxstring::createRef(Super->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00004093 }
4094 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004095 const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004096 return cxstring::createRef(Class->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00004097 }
4098 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004099 const ObjCProtocolDecl *OID = getCursorObjCProtocolRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00004100 assert(OID && "getCursorSpelling(): Missing protocol decl");
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004101 return cxstring::createRef(OID->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00004102 }
4103 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004104 const CXXBaseSpecifier *B = getCursorCXXBaseSpecifier(C);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004105 return cxstring::createDup(B->getType().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00004106 }
4107 case CXCursor_TypeRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004108 const TypeDecl *Type = getCursorTypeRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00004109 assert(Type && "Missing type decl");
4110
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004111 return cxstring::createDup(getCursorContext(C).getTypeDeclType(Type).
Guy Benyei11169dd2012-12-18 14:30:41 +00004112 getAsString());
4113 }
4114 case CXCursor_TemplateRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004115 const TemplateDecl *Template = getCursorTemplateRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00004116 assert(Template && "Missing template decl");
4117
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004118 return cxstring::createDup(Template->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00004119 }
4120
4121 case CXCursor_NamespaceRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004122 const NamedDecl *NS = getCursorNamespaceRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00004123 assert(NS && "Missing namespace decl");
4124
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004125 return cxstring::createDup(NS->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00004126 }
4127
4128 case CXCursor_MemberRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004129 const FieldDecl *Field = getCursorMemberRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00004130 assert(Field && "Missing member decl");
4131
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004132 return cxstring::createDup(Field->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00004133 }
4134
4135 case CXCursor_LabelRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004136 const LabelStmt *Label = getCursorLabelRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00004137 assert(Label && "Missing label");
4138
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004139 return cxstring::createRef(Label->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00004140 }
4141
4142 case CXCursor_OverloadedDeclRef: {
4143 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004144 if (const Decl *D = Storage.dyn_cast<const Decl *>()) {
4145 if (const NamedDecl *ND = dyn_cast<NamedDecl>(D))
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004146 return cxstring::createDup(ND->getNameAsString());
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00004147 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00004148 }
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004149 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004150 return cxstring::createDup(E->getName().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00004151 OverloadedTemplateStorage *Ovl
4152 = Storage.get<OverloadedTemplateStorage*>();
4153 if (Ovl->size() == 0)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00004154 return cxstring::createEmpty();
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004155 return cxstring::createDup((*Ovl->begin())->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00004156 }
4157
4158 case CXCursor_VariableRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004159 const VarDecl *Var = getCursorVariableRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00004160 assert(Var && "Missing variable decl");
4161
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004162 return cxstring::createDup(Var->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00004163 }
4164
4165 default:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004166 return cxstring::createRef("<not implemented>");
Guy Benyei11169dd2012-12-18 14:30:41 +00004167 }
4168 }
4169
4170 if (clang_isExpression(C.kind)) {
Argyrios Kyrtzidis3227d862014-03-03 19:40:52 +00004171 const Expr *E = getCursorExpr(C);
4172
4173 if (C.kind == CXCursor_ObjCStringLiteral ||
4174 C.kind == CXCursor_StringLiteral) {
4175 const StringLiteral *SLit;
4176 if (const ObjCStringLiteral *OSL = dyn_cast<ObjCStringLiteral>(E)) {
4177 SLit = OSL->getString();
4178 } else {
4179 SLit = cast<StringLiteral>(E);
4180 }
4181 SmallString<256> Buf;
4182 llvm::raw_svector_ostream OS(Buf);
4183 SLit->outputString(OS);
4184 return cxstring::createDup(OS.str());
4185 }
4186
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004187 const Decl *D = getDeclFromExpr(getCursorExpr(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00004188 if (D)
4189 return getDeclSpelling(D);
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00004190 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00004191 }
4192
4193 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004194 const Stmt *S = getCursorStmt(C);
4195 if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S))
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004196 return cxstring::createRef(Label->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00004197
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00004198 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00004199 }
4200
4201 if (C.kind == CXCursor_MacroExpansion)
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004202 return cxstring::createRef(getCursorMacroExpansion(C).getName()
Guy Benyei11169dd2012-12-18 14:30:41 +00004203 ->getNameStart());
4204
4205 if (C.kind == CXCursor_MacroDefinition)
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004206 return cxstring::createRef(getCursorMacroDefinition(C)->getName()
Guy Benyei11169dd2012-12-18 14:30:41 +00004207 ->getNameStart());
4208
4209 if (C.kind == CXCursor_InclusionDirective)
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004210 return cxstring::createDup(getCursorInclusionDirective(C)->getFileName());
Guy Benyei11169dd2012-12-18 14:30:41 +00004211
4212 if (clang_isDeclaration(C.kind))
4213 return getDeclSpelling(getCursorDecl(C));
4214
4215 if (C.kind == CXCursor_AnnotateAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00004216 const AnnotateAttr *AA = cast<AnnotateAttr>(cxcursor::getCursorAttr(C));
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004217 return cxstring::createDup(AA->getAnnotation());
Guy Benyei11169dd2012-12-18 14:30:41 +00004218 }
4219
4220 if (C.kind == CXCursor_AsmLabelAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00004221 const AsmLabelAttr *AA = cast<AsmLabelAttr>(cxcursor::getCursorAttr(C));
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004222 return cxstring::createDup(AA->getLabel());
Guy Benyei11169dd2012-12-18 14:30:41 +00004223 }
4224
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00004225 if (C.kind == CXCursor_PackedAttr) {
4226 return cxstring::createRef("packed");
4227 }
4228
Saleem Abdulrasool79c69712015-09-05 18:53:43 +00004229 if (C.kind == CXCursor_VisibilityAttr) {
4230 const VisibilityAttr *AA = cast<VisibilityAttr>(cxcursor::getCursorAttr(C));
4231 switch (AA->getVisibility()) {
4232 case VisibilityAttr::VisibilityType::Default:
4233 return cxstring::createRef("default");
4234 case VisibilityAttr::VisibilityType::Hidden:
4235 return cxstring::createRef("hidden");
4236 case VisibilityAttr::VisibilityType::Protected:
4237 return cxstring::createRef("protected");
4238 }
4239 llvm_unreachable("unknown visibility type");
4240 }
4241
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00004242 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00004243}
4244
4245CXSourceRange clang_Cursor_getSpellingNameRange(CXCursor C,
4246 unsigned pieceIndex,
4247 unsigned options) {
4248 if (clang_Cursor_isNull(C))
4249 return clang_getNullRange();
4250
4251 ASTContext &Ctx = getCursorContext(C);
4252
4253 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004254 const Stmt *S = getCursorStmt(C);
4255 if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004256 if (pieceIndex > 0)
4257 return clang_getNullRange();
4258 return cxloc::translateSourceRange(Ctx, Label->getIdentLoc());
4259 }
4260
4261 return clang_getNullRange();
4262 }
4263
4264 if (C.kind == CXCursor_ObjCMessageExpr) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004265 if (const ObjCMessageExpr *
Guy Benyei11169dd2012-12-18 14:30:41 +00004266 ME = dyn_cast_or_null<ObjCMessageExpr>(getCursorExpr(C))) {
4267 if (pieceIndex >= ME->getNumSelectorLocs())
4268 return clang_getNullRange();
4269 return cxloc::translateSourceRange(Ctx, ME->getSelectorLoc(pieceIndex));
4270 }
4271 }
4272
4273 if (C.kind == CXCursor_ObjCInstanceMethodDecl ||
4274 C.kind == CXCursor_ObjCClassMethodDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004275 if (const ObjCMethodDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00004276 MD = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(C))) {
4277 if (pieceIndex >= MD->getNumSelectorLocs())
4278 return clang_getNullRange();
4279 return cxloc::translateSourceRange(Ctx, MD->getSelectorLoc(pieceIndex));
4280 }
4281 }
4282
4283 if (C.kind == CXCursor_ObjCCategoryDecl ||
4284 C.kind == CXCursor_ObjCCategoryImplDecl) {
4285 if (pieceIndex > 0)
4286 return clang_getNullRange();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004287 if (const ObjCCategoryDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00004288 CD = dyn_cast_or_null<ObjCCategoryDecl>(getCursorDecl(C)))
4289 return cxloc::translateSourceRange(Ctx, CD->getCategoryNameLoc());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004290 if (const ObjCCategoryImplDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00004291 CID = dyn_cast_or_null<ObjCCategoryImplDecl>(getCursorDecl(C)))
4292 return cxloc::translateSourceRange(Ctx, CID->getCategoryNameLoc());
4293 }
4294
4295 if (C.kind == CXCursor_ModuleImportDecl) {
4296 if (pieceIndex > 0)
4297 return clang_getNullRange();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004298 if (const ImportDecl *ImportD =
4299 dyn_cast_or_null<ImportDecl>(getCursorDecl(C))) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004300 ArrayRef<SourceLocation> Locs = ImportD->getIdentifierLocs();
4301 if (!Locs.empty())
4302 return cxloc::translateSourceRange(Ctx,
4303 SourceRange(Locs.front(), Locs.back()));
4304 }
4305 return clang_getNullRange();
4306 }
4307
Argyrios Kyrtzidisa2a1e532014-08-26 20:23:26 +00004308 if (C.kind == CXCursor_CXXMethod || C.kind == CXCursor_Destructor ||
4309 C.kind == CXCursor_ConversionFunction) {
4310 if (pieceIndex > 0)
4311 return clang_getNullRange();
4312 if (const FunctionDecl *FD =
4313 dyn_cast_or_null<FunctionDecl>(getCursorDecl(C))) {
4314 DeclarationNameInfo FunctionName = FD->getNameInfo();
4315 return cxloc::translateSourceRange(Ctx, FunctionName.getSourceRange());
4316 }
4317 return clang_getNullRange();
4318 }
4319
Guy Benyei11169dd2012-12-18 14:30:41 +00004320 // FIXME: A CXCursor_InclusionDirective should give the location of the
4321 // filename, but we don't keep track of this.
4322
4323 // FIXME: A CXCursor_AnnotateAttr should give the location of the annotation
4324 // but we don't keep track of this.
4325
4326 // FIXME: A CXCursor_AsmLabelAttr should give the location of the label
4327 // but we don't keep track of this.
4328
4329 // Default handling, give the location of the cursor.
4330
4331 if (pieceIndex > 0)
4332 return clang_getNullRange();
4333
4334 CXSourceLocation CXLoc = clang_getCursorLocation(C);
4335 SourceLocation Loc = cxloc::translateSourceLocation(CXLoc);
4336 return cxloc::translateSourceRange(Ctx, Loc);
4337}
4338
Eli Bendersky44a206f2014-07-31 18:04:56 +00004339CXString clang_Cursor_getMangling(CXCursor C) {
4340 if (clang_isInvalid(C.kind) || !clang_isDeclaration(C.kind))
4341 return cxstring::createEmpty();
4342
Eli Bendersky44a206f2014-07-31 18:04:56 +00004343 // Mangling only works for functions and variables.
Eli Bendersky79759592014-08-01 15:01:10 +00004344 const Decl *D = getCursorDecl(C);
Eli Bendersky44a206f2014-07-31 18:04:56 +00004345 if (!D || !(isa<FunctionDecl>(D) || isa<VarDecl>(D)))
4346 return cxstring::createEmpty();
4347
Argyrios Kyrtzidisca741ce2016-02-14 22:30:14 +00004348 ASTContext &Ctx = D->getASTContext();
4349 index::CodegenNameGenerator CGNameGen(Ctx);
4350 return cxstring::createDup(CGNameGen.getName(D));
Eli Bendersky44a206f2014-07-31 18:04:56 +00004351}
4352
Saleem Abdulrasool60034432015-11-12 03:57:22 +00004353CXStringSet *clang_Cursor_getCXXManglings(CXCursor C) {
4354 if (clang_isInvalid(C.kind) || !clang_isDeclaration(C.kind))
4355 return nullptr;
4356
4357 const Decl *D = getCursorDecl(C);
4358 if (!(isa<CXXRecordDecl>(D) || isa<CXXMethodDecl>(D)))
4359 return nullptr;
4360
Argyrios Kyrtzidisca741ce2016-02-14 22:30:14 +00004361 ASTContext &Ctx = D->getASTContext();
4362 index::CodegenNameGenerator CGNameGen(Ctx);
4363 std::vector<std::string> Manglings = CGNameGen.getAllManglings(D);
Saleem Abdulrasool60034432015-11-12 03:57:22 +00004364 return cxstring::createSet(Manglings);
4365}
4366
Guy Benyei11169dd2012-12-18 14:30:41 +00004367CXString clang_getCursorDisplayName(CXCursor C) {
4368 if (!clang_isDeclaration(C.kind))
4369 return clang_getCursorSpelling(C);
4370
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004371 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004372 if (!D)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00004373 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00004374
4375 PrintingPolicy Policy = getCursorContext(C).getPrintingPolicy();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004376 if (const FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004377 D = FunTmpl->getTemplatedDecl();
4378
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004379 if (const FunctionDecl *Function = dyn_cast<FunctionDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004380 SmallString<64> Str;
4381 llvm::raw_svector_ostream OS(Str);
4382 OS << *Function;
4383 if (Function->getPrimaryTemplate())
4384 OS << "<>";
4385 OS << "(";
4386 for (unsigned I = 0, N = Function->getNumParams(); I != N; ++I) {
4387 if (I)
4388 OS << ", ";
4389 OS << Function->getParamDecl(I)->getType().getAsString(Policy);
4390 }
4391
4392 if (Function->isVariadic()) {
4393 if (Function->getNumParams())
4394 OS << ", ";
4395 OS << "...";
4396 }
4397 OS << ")";
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004398 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00004399 }
4400
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004401 if (const ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004402 SmallString<64> Str;
4403 llvm::raw_svector_ostream OS(Str);
4404 OS << *ClassTemplate;
4405 OS << "<";
4406 TemplateParameterList *Params = ClassTemplate->getTemplateParameters();
4407 for (unsigned I = 0, N = Params->size(); I != N; ++I) {
4408 if (I)
4409 OS << ", ";
4410
4411 NamedDecl *Param = Params->getParam(I);
4412 if (Param->getIdentifier()) {
4413 OS << Param->getIdentifier()->getName();
4414 continue;
4415 }
4416
4417 // There is no parameter name, which makes this tricky. Try to come up
4418 // with something useful that isn't too long.
4419 if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(Param))
4420 OS << (TTP->wasDeclaredWithTypename()? "typename" : "class");
4421 else if (NonTypeTemplateParmDecl *NTTP
4422 = dyn_cast<NonTypeTemplateParmDecl>(Param))
4423 OS << NTTP->getType().getAsString(Policy);
4424 else
4425 OS << "template<...> class";
4426 }
4427
4428 OS << ">";
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004429 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00004430 }
4431
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004432 if (const ClassTemplateSpecializationDecl *ClassSpec
Guy Benyei11169dd2012-12-18 14:30:41 +00004433 = dyn_cast<ClassTemplateSpecializationDecl>(D)) {
4434 // If the type was explicitly written, use that.
4435 if (TypeSourceInfo *TSInfo = ClassSpec->getTypeAsWritten())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004436 return cxstring::createDup(TSInfo->getType().getAsString(Policy));
Guy Benyei11169dd2012-12-18 14:30:41 +00004437
Benjamin Kramer9170e912013-02-22 15:46:01 +00004438 SmallString<128> Str;
Guy Benyei11169dd2012-12-18 14:30:41 +00004439 llvm::raw_svector_ostream OS(Str);
4440 OS << *ClassSpec;
Benjamin Kramer9170e912013-02-22 15:46:01 +00004441 TemplateSpecializationType::PrintTemplateArgumentList(OS,
Guy Benyei11169dd2012-12-18 14:30:41 +00004442 ClassSpec->getTemplateArgs().data(),
4443 ClassSpec->getTemplateArgs().size(),
4444 Policy);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004445 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00004446 }
4447
4448 return clang_getCursorSpelling(C);
4449}
4450
4451CXString clang_getCursorKindSpelling(enum CXCursorKind Kind) {
4452 switch (Kind) {
4453 case CXCursor_FunctionDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004454 return cxstring::createRef("FunctionDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004455 case CXCursor_TypedefDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004456 return cxstring::createRef("TypedefDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004457 case CXCursor_EnumDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004458 return cxstring::createRef("EnumDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004459 case CXCursor_EnumConstantDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004460 return cxstring::createRef("EnumConstantDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004461 case CXCursor_StructDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004462 return cxstring::createRef("StructDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004463 case CXCursor_UnionDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004464 return cxstring::createRef("UnionDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004465 case CXCursor_ClassDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004466 return cxstring::createRef("ClassDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004467 case CXCursor_FieldDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004468 return cxstring::createRef("FieldDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004469 case CXCursor_VarDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004470 return cxstring::createRef("VarDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004471 case CXCursor_ParmDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004472 return cxstring::createRef("ParmDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004473 case CXCursor_ObjCInterfaceDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004474 return cxstring::createRef("ObjCInterfaceDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004475 case CXCursor_ObjCCategoryDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004476 return cxstring::createRef("ObjCCategoryDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004477 case CXCursor_ObjCProtocolDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004478 return cxstring::createRef("ObjCProtocolDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004479 case CXCursor_ObjCPropertyDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004480 return cxstring::createRef("ObjCPropertyDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004481 case CXCursor_ObjCIvarDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004482 return cxstring::createRef("ObjCIvarDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004483 case CXCursor_ObjCInstanceMethodDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004484 return cxstring::createRef("ObjCInstanceMethodDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004485 case CXCursor_ObjCClassMethodDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004486 return cxstring::createRef("ObjCClassMethodDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004487 case CXCursor_ObjCImplementationDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004488 return cxstring::createRef("ObjCImplementationDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004489 case CXCursor_ObjCCategoryImplDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004490 return cxstring::createRef("ObjCCategoryImplDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004491 case CXCursor_CXXMethod:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004492 return cxstring::createRef("CXXMethod");
Guy Benyei11169dd2012-12-18 14:30:41 +00004493 case CXCursor_UnexposedDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004494 return cxstring::createRef("UnexposedDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004495 case CXCursor_ObjCSuperClassRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004496 return cxstring::createRef("ObjCSuperClassRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004497 case CXCursor_ObjCProtocolRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004498 return cxstring::createRef("ObjCProtocolRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004499 case CXCursor_ObjCClassRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004500 return cxstring::createRef("ObjCClassRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004501 case CXCursor_TypeRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004502 return cxstring::createRef("TypeRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004503 case CXCursor_TemplateRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004504 return cxstring::createRef("TemplateRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004505 case CXCursor_NamespaceRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004506 return cxstring::createRef("NamespaceRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004507 case CXCursor_MemberRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004508 return cxstring::createRef("MemberRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004509 case CXCursor_LabelRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004510 return cxstring::createRef("LabelRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004511 case CXCursor_OverloadedDeclRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004512 return cxstring::createRef("OverloadedDeclRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004513 case CXCursor_VariableRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004514 return cxstring::createRef("VariableRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004515 case CXCursor_IntegerLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004516 return cxstring::createRef("IntegerLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00004517 case CXCursor_FloatingLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004518 return cxstring::createRef("FloatingLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00004519 case CXCursor_ImaginaryLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004520 return cxstring::createRef("ImaginaryLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00004521 case CXCursor_StringLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004522 return cxstring::createRef("StringLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00004523 case CXCursor_CharacterLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004524 return cxstring::createRef("CharacterLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00004525 case CXCursor_ParenExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004526 return cxstring::createRef("ParenExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004527 case CXCursor_UnaryOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004528 return cxstring::createRef("UnaryOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00004529 case CXCursor_ArraySubscriptExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004530 return cxstring::createRef("ArraySubscriptExpr");
Alexey Bataev1a3320e2015-08-25 14:24:04 +00004531 case CXCursor_OMPArraySectionExpr:
4532 return cxstring::createRef("OMPArraySectionExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004533 case CXCursor_BinaryOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004534 return cxstring::createRef("BinaryOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00004535 case CXCursor_CompoundAssignOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004536 return cxstring::createRef("CompoundAssignOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00004537 case CXCursor_ConditionalOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004538 return cxstring::createRef("ConditionalOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00004539 case CXCursor_CStyleCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004540 return cxstring::createRef("CStyleCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004541 case CXCursor_CompoundLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004542 return cxstring::createRef("CompoundLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004543 case CXCursor_InitListExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004544 return cxstring::createRef("InitListExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004545 case CXCursor_AddrLabelExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004546 return cxstring::createRef("AddrLabelExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004547 case CXCursor_StmtExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004548 return cxstring::createRef("StmtExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004549 case CXCursor_GenericSelectionExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004550 return cxstring::createRef("GenericSelectionExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004551 case CXCursor_GNUNullExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004552 return cxstring::createRef("GNUNullExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004553 case CXCursor_CXXStaticCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004554 return cxstring::createRef("CXXStaticCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004555 case CXCursor_CXXDynamicCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004556 return cxstring::createRef("CXXDynamicCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004557 case CXCursor_CXXReinterpretCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004558 return cxstring::createRef("CXXReinterpretCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004559 case CXCursor_CXXConstCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004560 return cxstring::createRef("CXXConstCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004561 case CXCursor_CXXFunctionalCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004562 return cxstring::createRef("CXXFunctionalCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004563 case CXCursor_CXXTypeidExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004564 return cxstring::createRef("CXXTypeidExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004565 case CXCursor_CXXBoolLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004566 return cxstring::createRef("CXXBoolLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004567 case CXCursor_CXXNullPtrLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004568 return cxstring::createRef("CXXNullPtrLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004569 case CXCursor_CXXThisExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004570 return cxstring::createRef("CXXThisExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004571 case CXCursor_CXXThrowExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004572 return cxstring::createRef("CXXThrowExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004573 case CXCursor_CXXNewExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004574 return cxstring::createRef("CXXNewExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004575 case CXCursor_CXXDeleteExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004576 return cxstring::createRef("CXXDeleteExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004577 case CXCursor_UnaryExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004578 return cxstring::createRef("UnaryExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004579 case CXCursor_ObjCStringLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004580 return cxstring::createRef("ObjCStringLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00004581 case CXCursor_ObjCBoolLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004582 return cxstring::createRef("ObjCBoolLiteralExpr");
Argyrios Kyrtzidisc2233be2013-04-23 17:57:17 +00004583 case CXCursor_ObjCSelfExpr:
4584 return cxstring::createRef("ObjCSelfExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004585 case CXCursor_ObjCEncodeExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004586 return cxstring::createRef("ObjCEncodeExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004587 case CXCursor_ObjCSelectorExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004588 return cxstring::createRef("ObjCSelectorExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004589 case CXCursor_ObjCProtocolExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004590 return cxstring::createRef("ObjCProtocolExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004591 case CXCursor_ObjCBridgedCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004592 return cxstring::createRef("ObjCBridgedCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004593 case CXCursor_BlockExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004594 return cxstring::createRef("BlockExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004595 case CXCursor_PackExpansionExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004596 return cxstring::createRef("PackExpansionExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004597 case CXCursor_SizeOfPackExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004598 return cxstring::createRef("SizeOfPackExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004599 case CXCursor_LambdaExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004600 return cxstring::createRef("LambdaExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004601 case CXCursor_UnexposedExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004602 return cxstring::createRef("UnexposedExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004603 case CXCursor_DeclRefExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004604 return cxstring::createRef("DeclRefExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004605 case CXCursor_MemberRefExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004606 return cxstring::createRef("MemberRefExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004607 case CXCursor_CallExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004608 return cxstring::createRef("CallExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004609 case CXCursor_ObjCMessageExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004610 return cxstring::createRef("ObjCMessageExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004611 case CXCursor_UnexposedStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004612 return cxstring::createRef("UnexposedStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004613 case CXCursor_DeclStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004614 return cxstring::createRef("DeclStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004615 case CXCursor_LabelStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004616 return cxstring::createRef("LabelStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004617 case CXCursor_CompoundStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004618 return cxstring::createRef("CompoundStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004619 case CXCursor_CaseStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004620 return cxstring::createRef("CaseStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004621 case CXCursor_DefaultStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004622 return cxstring::createRef("DefaultStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004623 case CXCursor_IfStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004624 return cxstring::createRef("IfStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004625 case CXCursor_SwitchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004626 return cxstring::createRef("SwitchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004627 case CXCursor_WhileStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004628 return cxstring::createRef("WhileStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004629 case CXCursor_DoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004630 return cxstring::createRef("DoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004631 case CXCursor_ForStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004632 return cxstring::createRef("ForStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004633 case CXCursor_GotoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004634 return cxstring::createRef("GotoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004635 case CXCursor_IndirectGotoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004636 return cxstring::createRef("IndirectGotoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004637 case CXCursor_ContinueStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004638 return cxstring::createRef("ContinueStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004639 case CXCursor_BreakStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004640 return cxstring::createRef("BreakStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004641 case CXCursor_ReturnStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004642 return cxstring::createRef("ReturnStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004643 case CXCursor_GCCAsmStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004644 return cxstring::createRef("GCCAsmStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004645 case CXCursor_MSAsmStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004646 return cxstring::createRef("MSAsmStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004647 case CXCursor_ObjCAtTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004648 return cxstring::createRef("ObjCAtTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004649 case CXCursor_ObjCAtCatchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004650 return cxstring::createRef("ObjCAtCatchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004651 case CXCursor_ObjCAtFinallyStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004652 return cxstring::createRef("ObjCAtFinallyStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004653 case CXCursor_ObjCAtThrowStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004654 return cxstring::createRef("ObjCAtThrowStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004655 case CXCursor_ObjCAtSynchronizedStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004656 return cxstring::createRef("ObjCAtSynchronizedStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004657 case CXCursor_ObjCAutoreleasePoolStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004658 return cxstring::createRef("ObjCAutoreleasePoolStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004659 case CXCursor_ObjCForCollectionStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004660 return cxstring::createRef("ObjCForCollectionStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004661 case CXCursor_CXXCatchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004662 return cxstring::createRef("CXXCatchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004663 case CXCursor_CXXTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004664 return cxstring::createRef("CXXTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004665 case CXCursor_CXXForRangeStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004666 return cxstring::createRef("CXXForRangeStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004667 case CXCursor_SEHTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004668 return cxstring::createRef("SEHTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004669 case CXCursor_SEHExceptStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004670 return cxstring::createRef("SEHExceptStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004671 case CXCursor_SEHFinallyStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004672 return cxstring::createRef("SEHFinallyStmt");
Nico Weber9b982072014-07-07 00:12:30 +00004673 case CXCursor_SEHLeaveStmt:
4674 return cxstring::createRef("SEHLeaveStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004675 case CXCursor_NullStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004676 return cxstring::createRef("NullStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004677 case CXCursor_InvalidFile:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004678 return cxstring::createRef("InvalidFile");
Guy Benyei11169dd2012-12-18 14:30:41 +00004679 case CXCursor_InvalidCode:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004680 return cxstring::createRef("InvalidCode");
Guy Benyei11169dd2012-12-18 14:30:41 +00004681 case CXCursor_NoDeclFound:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004682 return cxstring::createRef("NoDeclFound");
Guy Benyei11169dd2012-12-18 14:30:41 +00004683 case CXCursor_NotImplemented:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004684 return cxstring::createRef("NotImplemented");
Guy Benyei11169dd2012-12-18 14:30:41 +00004685 case CXCursor_TranslationUnit:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004686 return cxstring::createRef("TranslationUnit");
Guy Benyei11169dd2012-12-18 14:30:41 +00004687 case CXCursor_UnexposedAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004688 return cxstring::createRef("UnexposedAttr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004689 case CXCursor_IBActionAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004690 return cxstring::createRef("attribute(ibaction)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004691 case CXCursor_IBOutletAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004692 return cxstring::createRef("attribute(iboutlet)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004693 case CXCursor_IBOutletCollectionAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004694 return cxstring::createRef("attribute(iboutletcollection)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004695 case CXCursor_CXXFinalAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004696 return cxstring::createRef("attribute(final)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004697 case CXCursor_CXXOverrideAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004698 return cxstring::createRef("attribute(override)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004699 case CXCursor_AnnotateAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004700 return cxstring::createRef("attribute(annotate)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004701 case CXCursor_AsmLabelAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004702 return cxstring::createRef("asm label");
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00004703 case CXCursor_PackedAttr:
4704 return cxstring::createRef("attribute(packed)");
Joey Gouly81228382014-05-01 15:41:58 +00004705 case CXCursor_PureAttr:
4706 return cxstring::createRef("attribute(pure)");
4707 case CXCursor_ConstAttr:
4708 return cxstring::createRef("attribute(const)");
4709 case CXCursor_NoDuplicateAttr:
4710 return cxstring::createRef("attribute(noduplicate)");
Eli Bendersky2581e662014-05-28 19:29:58 +00004711 case CXCursor_CUDAConstantAttr:
4712 return cxstring::createRef("attribute(constant)");
4713 case CXCursor_CUDADeviceAttr:
4714 return cxstring::createRef("attribute(device)");
4715 case CXCursor_CUDAGlobalAttr:
4716 return cxstring::createRef("attribute(global)");
4717 case CXCursor_CUDAHostAttr:
4718 return cxstring::createRef("attribute(host)");
Eli Bendersky9b071472014-08-08 14:59:00 +00004719 case CXCursor_CUDASharedAttr:
4720 return cxstring::createRef("attribute(shared)");
Saleem Abdulrasool79c69712015-09-05 18:53:43 +00004721 case CXCursor_VisibilityAttr:
4722 return cxstring::createRef("attribute(visibility)");
Saleem Abdulrasool8aa0b802015-12-10 18:45:18 +00004723 case CXCursor_DLLExport:
4724 return cxstring::createRef("attribute(dllexport)");
4725 case CXCursor_DLLImport:
4726 return cxstring::createRef("attribute(dllimport)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004727 case CXCursor_PreprocessingDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004728 return cxstring::createRef("preprocessing directive");
Guy Benyei11169dd2012-12-18 14:30:41 +00004729 case CXCursor_MacroDefinition:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004730 return cxstring::createRef("macro definition");
Guy Benyei11169dd2012-12-18 14:30:41 +00004731 case CXCursor_MacroExpansion:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004732 return cxstring::createRef("macro expansion");
Guy Benyei11169dd2012-12-18 14:30:41 +00004733 case CXCursor_InclusionDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004734 return cxstring::createRef("inclusion directive");
Guy Benyei11169dd2012-12-18 14:30:41 +00004735 case CXCursor_Namespace:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004736 return cxstring::createRef("Namespace");
Guy Benyei11169dd2012-12-18 14:30:41 +00004737 case CXCursor_LinkageSpec:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004738 return cxstring::createRef("LinkageSpec");
Guy Benyei11169dd2012-12-18 14:30:41 +00004739 case CXCursor_CXXBaseSpecifier:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004740 return cxstring::createRef("C++ base class specifier");
Guy Benyei11169dd2012-12-18 14:30:41 +00004741 case CXCursor_Constructor:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004742 return cxstring::createRef("CXXConstructor");
Guy Benyei11169dd2012-12-18 14:30:41 +00004743 case CXCursor_Destructor:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004744 return cxstring::createRef("CXXDestructor");
Guy Benyei11169dd2012-12-18 14:30:41 +00004745 case CXCursor_ConversionFunction:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004746 return cxstring::createRef("CXXConversion");
Guy Benyei11169dd2012-12-18 14:30:41 +00004747 case CXCursor_TemplateTypeParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004748 return cxstring::createRef("TemplateTypeParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00004749 case CXCursor_NonTypeTemplateParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004750 return cxstring::createRef("NonTypeTemplateParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00004751 case CXCursor_TemplateTemplateParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004752 return cxstring::createRef("TemplateTemplateParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00004753 case CXCursor_FunctionTemplate:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004754 return cxstring::createRef("FunctionTemplate");
Guy Benyei11169dd2012-12-18 14:30:41 +00004755 case CXCursor_ClassTemplate:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004756 return cxstring::createRef("ClassTemplate");
Guy Benyei11169dd2012-12-18 14:30:41 +00004757 case CXCursor_ClassTemplatePartialSpecialization:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004758 return cxstring::createRef("ClassTemplatePartialSpecialization");
Guy Benyei11169dd2012-12-18 14:30:41 +00004759 case CXCursor_NamespaceAlias:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004760 return cxstring::createRef("NamespaceAlias");
Guy Benyei11169dd2012-12-18 14:30:41 +00004761 case CXCursor_UsingDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004762 return cxstring::createRef("UsingDirective");
Guy Benyei11169dd2012-12-18 14:30:41 +00004763 case CXCursor_UsingDeclaration:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004764 return cxstring::createRef("UsingDeclaration");
Guy Benyei11169dd2012-12-18 14:30:41 +00004765 case CXCursor_TypeAliasDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004766 return cxstring::createRef("TypeAliasDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004767 case CXCursor_ObjCSynthesizeDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004768 return cxstring::createRef("ObjCSynthesizeDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004769 case CXCursor_ObjCDynamicDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004770 return cxstring::createRef("ObjCDynamicDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004771 case CXCursor_CXXAccessSpecifier:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004772 return cxstring::createRef("CXXAccessSpecifier");
Guy Benyei11169dd2012-12-18 14:30:41 +00004773 case CXCursor_ModuleImportDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004774 return cxstring::createRef("ModuleImport");
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00004775 case CXCursor_OMPParallelDirective:
Alexey Bataev1b59ab52014-02-27 08:29:12 +00004776 return cxstring::createRef("OMPParallelDirective");
4777 case CXCursor_OMPSimdDirective:
4778 return cxstring::createRef("OMPSimdDirective");
Alexey Bataevf29276e2014-06-18 04:14:57 +00004779 case CXCursor_OMPForDirective:
4780 return cxstring::createRef("OMPForDirective");
Alexander Musmanf82886e2014-09-18 05:12:34 +00004781 case CXCursor_OMPForSimdDirective:
4782 return cxstring::createRef("OMPForSimdDirective");
Alexey Bataevd3f8dd22014-06-25 11:44:49 +00004783 case CXCursor_OMPSectionsDirective:
4784 return cxstring::createRef("OMPSectionsDirective");
Alexey Bataev1e0498a2014-06-26 08:21:58 +00004785 case CXCursor_OMPSectionDirective:
4786 return cxstring::createRef("OMPSectionDirective");
Alexey Bataevd1e40fb2014-06-26 12:05:45 +00004787 case CXCursor_OMPSingleDirective:
4788 return cxstring::createRef("OMPSingleDirective");
Alexander Musman80c22892014-07-17 08:54:58 +00004789 case CXCursor_OMPMasterDirective:
4790 return cxstring::createRef("OMPMasterDirective");
Alexander Musmand9ed09f2014-07-21 09:42:05 +00004791 case CXCursor_OMPCriticalDirective:
4792 return cxstring::createRef("OMPCriticalDirective");
Alexey Bataev4acb8592014-07-07 13:01:15 +00004793 case CXCursor_OMPParallelForDirective:
4794 return cxstring::createRef("OMPParallelForDirective");
Alexander Musmane4e893b2014-09-23 09:33:00 +00004795 case CXCursor_OMPParallelForSimdDirective:
4796 return cxstring::createRef("OMPParallelForSimdDirective");
Alexey Bataev84d0b3e2014-07-08 08:12:03 +00004797 case CXCursor_OMPParallelSectionsDirective:
4798 return cxstring::createRef("OMPParallelSectionsDirective");
Alexey Bataev9c2e8ee2014-07-11 11:25:16 +00004799 case CXCursor_OMPTaskDirective:
4800 return cxstring::createRef("OMPTaskDirective");
Alexey Bataev68446b72014-07-18 07:47:19 +00004801 case CXCursor_OMPTaskyieldDirective:
4802 return cxstring::createRef("OMPTaskyieldDirective");
Alexey Bataev4d1dfea2014-07-18 09:11:51 +00004803 case CXCursor_OMPBarrierDirective:
4804 return cxstring::createRef("OMPBarrierDirective");
Alexey Bataev2df347a2014-07-18 10:17:07 +00004805 case CXCursor_OMPTaskwaitDirective:
4806 return cxstring::createRef("OMPTaskwaitDirective");
Alexey Bataevc30dd2d2015-06-18 12:14:09 +00004807 case CXCursor_OMPTaskgroupDirective:
4808 return cxstring::createRef("OMPTaskgroupDirective");
Alexey Bataev6125da92014-07-21 11:26:11 +00004809 case CXCursor_OMPFlushDirective:
4810 return cxstring::createRef("OMPFlushDirective");
Alexey Bataev9fb6e642014-07-22 06:45:04 +00004811 case CXCursor_OMPOrderedDirective:
4812 return cxstring::createRef("OMPOrderedDirective");
Alexey Bataev0162e452014-07-22 10:10:35 +00004813 case CXCursor_OMPAtomicDirective:
4814 return cxstring::createRef("OMPAtomicDirective");
Alexey Bataev0bd520b2014-09-19 08:19:49 +00004815 case CXCursor_OMPTargetDirective:
4816 return cxstring::createRef("OMPTargetDirective");
Michael Wong65f367f2015-07-21 13:44:28 +00004817 case CXCursor_OMPTargetDataDirective:
4818 return cxstring::createRef("OMPTargetDataDirective");
Samuel Antaodf67fc42016-01-19 19:15:56 +00004819 case CXCursor_OMPTargetEnterDataDirective:
4820 return cxstring::createRef("OMPTargetEnterDataDirective");
Samuel Antao72590762016-01-19 20:04:50 +00004821 case CXCursor_OMPTargetExitDataDirective:
4822 return cxstring::createRef("OMPTargetExitDataDirective");
Arpith Chacko Jacobe955b3d2016-01-26 18:48:41 +00004823 case CXCursor_OMPTargetParallelDirective:
4824 return cxstring::createRef("OMPTargetParallelDirective");
Arpith Chacko Jacob05bebb52016-02-03 15:46:42 +00004825 case CXCursor_OMPTargetParallelForDirective:
4826 return cxstring::createRef("OMPTargetParallelForDirective");
Alexey Bataev13314bf2014-10-09 04:18:56 +00004827 case CXCursor_OMPTeamsDirective:
4828 return cxstring::createRef("OMPTeamsDirective");
Alexey Bataev6d4ed052015-07-01 06:57:41 +00004829 case CXCursor_OMPCancellationPointDirective:
4830 return cxstring::createRef("OMPCancellationPointDirective");
Alexey Bataev80909872015-07-02 11:25:17 +00004831 case CXCursor_OMPCancelDirective:
4832 return cxstring::createRef("OMPCancelDirective");
Alexey Bataev49f6e782015-12-01 04:18:41 +00004833 case CXCursor_OMPTaskLoopDirective:
4834 return cxstring::createRef("OMPTaskLoopDirective");
Alexey Bataev0a6ed842015-12-03 09:40:15 +00004835 case CXCursor_OMPTaskLoopSimdDirective:
4836 return cxstring::createRef("OMPTaskLoopSimdDirective");
Carlo Bertolli6200a3d2015-12-14 14:51:25 +00004837 case CXCursor_OMPDistributeDirective:
4838 return cxstring::createRef("OMPDistributeDirective");
Francisco Lopes da Silva975a9f62015-01-21 16:24:11 +00004839 case CXCursor_OverloadCandidate:
4840 return cxstring::createRef("OverloadCandidate");
Sergey Kalinichev8f3b1872015-11-15 13:48:32 +00004841 case CXCursor_TypeAliasTemplateDecl:
4842 return cxstring::createRef("TypeAliasTemplateDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004843 }
4844
4845 llvm_unreachable("Unhandled CXCursorKind");
4846}
4847
4848struct GetCursorData {
4849 SourceLocation TokenBeginLoc;
4850 bool PointsAtMacroArgExpansion;
4851 bool VisitedObjCPropertyImplDecl;
4852 SourceLocation VisitedDeclaratorDeclStartLoc;
4853 CXCursor &BestCursor;
4854
4855 GetCursorData(SourceManager &SM,
4856 SourceLocation tokenBegin, CXCursor &outputCursor)
4857 : TokenBeginLoc(tokenBegin), BestCursor(outputCursor) {
4858 PointsAtMacroArgExpansion = SM.isMacroArgExpansion(tokenBegin);
4859 VisitedObjCPropertyImplDecl = false;
4860 }
4861};
4862
4863static enum CXChildVisitResult GetCursorVisitor(CXCursor cursor,
4864 CXCursor parent,
4865 CXClientData client_data) {
4866 GetCursorData *Data = static_cast<GetCursorData *>(client_data);
4867 CXCursor *BestCursor = &Data->BestCursor;
4868
4869 // If we point inside a macro argument we should provide info of what the
4870 // token is so use the actual cursor, don't replace it with a macro expansion
4871 // cursor.
4872 if (cursor.kind == CXCursor_MacroExpansion && Data->PointsAtMacroArgExpansion)
4873 return CXChildVisit_Recurse;
4874
4875 if (clang_isDeclaration(cursor.kind)) {
4876 // Avoid having the implicit methods override the property decls.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004877 if (const ObjCMethodDecl *MD
Guy Benyei11169dd2012-12-18 14:30:41 +00004878 = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
4879 if (MD->isImplicit())
4880 return CXChildVisit_Break;
4881
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004882 } else if (const ObjCInterfaceDecl *ID
Guy Benyei11169dd2012-12-18 14:30:41 +00004883 = dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(cursor))) {
4884 // Check that when we have multiple @class references in the same line,
4885 // that later ones do not override the previous ones.
4886 // If we have:
4887 // @class Foo, Bar;
4888 // source ranges for both start at '@', so 'Bar' will end up overriding
4889 // 'Foo' even though the cursor location was at 'Foo'.
4890 if (BestCursor->kind == CXCursor_ObjCInterfaceDecl ||
4891 BestCursor->kind == CXCursor_ObjCClassRef)
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004892 if (const ObjCInterfaceDecl *PrevID
Guy Benyei11169dd2012-12-18 14:30:41 +00004893 = dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(*BestCursor))){
4894 if (PrevID != ID &&
4895 !PrevID->isThisDeclarationADefinition() &&
4896 !ID->isThisDeclarationADefinition())
4897 return CXChildVisit_Break;
4898 }
4899
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004900 } else if (const DeclaratorDecl *DD
Guy Benyei11169dd2012-12-18 14:30:41 +00004901 = dyn_cast_or_null<DeclaratorDecl>(getCursorDecl(cursor))) {
4902 SourceLocation StartLoc = DD->getSourceRange().getBegin();
4903 // Check that when we have multiple declarators in the same line,
4904 // that later ones do not override the previous ones.
4905 // If we have:
4906 // int Foo, Bar;
4907 // source ranges for both start at 'int', so 'Bar' will end up overriding
4908 // 'Foo' even though the cursor location was at 'Foo'.
4909 if (Data->VisitedDeclaratorDeclStartLoc == StartLoc)
4910 return CXChildVisit_Break;
4911 Data->VisitedDeclaratorDeclStartLoc = StartLoc;
4912
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004913 } else if (const ObjCPropertyImplDecl *PropImp
Guy Benyei11169dd2012-12-18 14:30:41 +00004914 = dyn_cast_or_null<ObjCPropertyImplDecl>(getCursorDecl(cursor))) {
4915 (void)PropImp;
4916 // Check that when we have multiple @synthesize in the same line,
4917 // that later ones do not override the previous ones.
4918 // If we have:
4919 // @synthesize Foo, Bar;
4920 // source ranges for both start at '@', so 'Bar' will end up overriding
4921 // 'Foo' even though the cursor location was at 'Foo'.
4922 if (Data->VisitedObjCPropertyImplDecl)
4923 return CXChildVisit_Break;
4924 Data->VisitedObjCPropertyImplDecl = true;
4925 }
4926 }
4927
4928 if (clang_isExpression(cursor.kind) &&
4929 clang_isDeclaration(BestCursor->kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004930 if (const Decl *D = getCursorDecl(*BestCursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004931 // Avoid having the cursor of an expression replace the declaration cursor
4932 // when the expression source range overlaps the declaration range.
4933 // This can happen for C++ constructor expressions whose range generally
4934 // include the variable declaration, e.g.:
4935 // MyCXXClass foo; // Make sure pointing at 'foo' returns a VarDecl cursor.
4936 if (D->getLocation().isValid() && Data->TokenBeginLoc.isValid() &&
4937 D->getLocation() == Data->TokenBeginLoc)
4938 return CXChildVisit_Break;
4939 }
4940 }
4941
4942 // If our current best cursor is the construction of a temporary object,
4943 // don't replace that cursor with a type reference, because we want
4944 // clang_getCursor() to point at the constructor.
4945 if (clang_isExpression(BestCursor->kind) &&
4946 isa<CXXTemporaryObjectExpr>(getCursorExpr(*BestCursor)) &&
4947 cursor.kind == CXCursor_TypeRef) {
4948 // Keep the cursor pointing at CXXTemporaryObjectExpr but also mark it
4949 // as having the actual point on the type reference.
4950 *BestCursor = getTypeRefedCallExprCursor(*BestCursor);
4951 return CXChildVisit_Recurse;
4952 }
Douglas Gregore9d95f12015-07-07 03:57:35 +00004953
4954 // If we already have an Objective-C superclass reference, don't
4955 // update it further.
4956 if (BestCursor->kind == CXCursor_ObjCSuperClassRef)
4957 return CXChildVisit_Break;
4958
Guy Benyei11169dd2012-12-18 14:30:41 +00004959 *BestCursor = cursor;
4960 return CXChildVisit_Recurse;
4961}
4962
4963CXCursor clang_getCursor(CXTranslationUnit TU, CXSourceLocation Loc) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00004964 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004965 LOG_BAD_TU(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004966 return clang_getNullCursor();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004967 }
Guy Benyei11169dd2012-12-18 14:30:41 +00004968
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004969 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004970 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
4971
4972 SourceLocation SLoc = cxloc::translateSourceLocation(Loc);
4973 CXCursor Result = cxcursor::getCursor(TU, SLoc);
4974
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004975 LOG_FUNC_SECTION {
Guy Benyei11169dd2012-12-18 14:30:41 +00004976 CXFile SearchFile;
4977 unsigned SearchLine, SearchColumn;
4978 CXFile ResultFile;
4979 unsigned ResultLine, ResultColumn;
4980 CXString SearchFileName, ResultFileName, KindSpelling, USR;
4981 const char *IsDef = clang_isCursorDefinition(Result)? " (Definition)" : "";
4982 CXSourceLocation ResultLoc = clang_getCursorLocation(Result);
Craig Topper69186e72014-06-08 08:38:04 +00004983
4984 clang_getFileLocation(Loc, &SearchFile, &SearchLine, &SearchColumn,
4985 nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004986 clang_getFileLocation(ResultLoc, &ResultFile, &ResultLine,
Craig Topper69186e72014-06-08 08:38:04 +00004987 &ResultColumn, nullptr);
Guy Benyei11169dd2012-12-18 14:30:41 +00004988 SearchFileName = clang_getFileName(SearchFile);
4989 ResultFileName = clang_getFileName(ResultFile);
4990 KindSpelling = clang_getCursorKindSpelling(Result.kind);
4991 USR = clang_getCursorUSR(Result);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004992 *Log << llvm::format("(%s:%d:%d) = %s",
4993 clang_getCString(SearchFileName), SearchLine, SearchColumn,
4994 clang_getCString(KindSpelling))
4995 << llvm::format("(%s:%d:%d):%s%s",
4996 clang_getCString(ResultFileName), ResultLine, ResultColumn,
4997 clang_getCString(USR), IsDef);
Guy Benyei11169dd2012-12-18 14:30:41 +00004998 clang_disposeString(SearchFileName);
4999 clang_disposeString(ResultFileName);
5000 clang_disposeString(KindSpelling);
5001 clang_disposeString(USR);
5002
5003 CXCursor Definition = clang_getCursorDefinition(Result);
5004 if (!clang_equalCursors(Definition, clang_getNullCursor())) {
5005 CXSourceLocation DefinitionLoc = clang_getCursorLocation(Definition);
5006 CXString DefinitionKindSpelling
5007 = clang_getCursorKindSpelling(Definition.kind);
5008 CXFile DefinitionFile;
5009 unsigned DefinitionLine, DefinitionColumn;
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00005010 clang_getFileLocation(DefinitionLoc, &DefinitionFile,
Craig Topper69186e72014-06-08 08:38:04 +00005011 &DefinitionLine, &DefinitionColumn, nullptr);
Guy Benyei11169dd2012-12-18 14:30:41 +00005012 CXString DefinitionFileName = clang_getFileName(DefinitionFile);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00005013 *Log << llvm::format(" -> %s(%s:%d:%d)",
5014 clang_getCString(DefinitionKindSpelling),
5015 clang_getCString(DefinitionFileName),
5016 DefinitionLine, DefinitionColumn);
Guy Benyei11169dd2012-12-18 14:30:41 +00005017 clang_disposeString(DefinitionFileName);
5018 clang_disposeString(DefinitionKindSpelling);
5019 }
5020 }
5021
5022 return Result;
5023}
5024
5025CXCursor clang_getNullCursor(void) {
5026 return MakeCXCursorInvalid(CXCursor_InvalidFile);
5027}
5028
5029unsigned clang_equalCursors(CXCursor X, CXCursor Y) {
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00005030 // Clear out the "FirstInDeclGroup" part in a declaration cursor, since we
5031 // can't set consistently. For example, when visiting a DeclStmt we will set
5032 // it but we don't set it on the result of clang_getCursorDefinition for
5033 // a reference of the same declaration.
5034 // FIXME: Setting "FirstInDeclGroup" in CXCursors is a hack that only works
5035 // when visiting a DeclStmt currently, the AST should be enhanced to be able
5036 // to provide that kind of info.
5037 if (clang_isDeclaration(X.kind))
Craig Topper69186e72014-06-08 08:38:04 +00005038 X.data[1] = nullptr;
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00005039 if (clang_isDeclaration(Y.kind))
Craig Topper69186e72014-06-08 08:38:04 +00005040 Y.data[1] = nullptr;
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00005041
Guy Benyei11169dd2012-12-18 14:30:41 +00005042 return X == Y;
5043}
5044
5045unsigned clang_hashCursor(CXCursor C) {
5046 unsigned Index = 0;
5047 if (clang_isExpression(C.kind) || clang_isStatement(C.kind))
5048 Index = 1;
5049
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005050 return llvm::DenseMapInfo<std::pair<unsigned, const void*> >::getHashValue(
Guy Benyei11169dd2012-12-18 14:30:41 +00005051 std::make_pair(C.kind, C.data[Index]));
5052}
5053
5054unsigned clang_isInvalid(enum CXCursorKind K) {
5055 return K >= CXCursor_FirstInvalid && K <= CXCursor_LastInvalid;
5056}
5057
5058unsigned clang_isDeclaration(enum CXCursorKind K) {
5059 return (K >= CXCursor_FirstDecl && K <= CXCursor_LastDecl) ||
5060 (K >= CXCursor_FirstExtraDecl && K <= CXCursor_LastExtraDecl);
5061}
5062
5063unsigned clang_isReference(enum CXCursorKind K) {
5064 return K >= CXCursor_FirstRef && K <= CXCursor_LastRef;
5065}
5066
5067unsigned clang_isExpression(enum CXCursorKind K) {
5068 return K >= CXCursor_FirstExpr && K <= CXCursor_LastExpr;
5069}
5070
5071unsigned clang_isStatement(enum CXCursorKind K) {
5072 return K >= CXCursor_FirstStmt && K <= CXCursor_LastStmt;
5073}
5074
5075unsigned clang_isAttribute(enum CXCursorKind K) {
5076 return K >= CXCursor_FirstAttr && K <= CXCursor_LastAttr;
5077}
5078
5079unsigned clang_isTranslationUnit(enum CXCursorKind K) {
5080 return K == CXCursor_TranslationUnit;
5081}
5082
5083unsigned clang_isPreprocessing(enum CXCursorKind K) {
5084 return K >= CXCursor_FirstPreprocessing && K <= CXCursor_LastPreprocessing;
5085}
5086
5087unsigned clang_isUnexposed(enum CXCursorKind K) {
5088 switch (K) {
5089 case CXCursor_UnexposedDecl:
5090 case CXCursor_UnexposedExpr:
5091 case CXCursor_UnexposedStmt:
5092 case CXCursor_UnexposedAttr:
5093 return true;
5094 default:
5095 return false;
5096 }
5097}
5098
5099CXCursorKind clang_getCursorKind(CXCursor C) {
5100 return C.kind;
5101}
5102
5103CXSourceLocation clang_getCursorLocation(CXCursor C) {
5104 if (clang_isReference(C.kind)) {
5105 switch (C.kind) {
5106 case CXCursor_ObjCSuperClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005107 std::pair<const ObjCInterfaceDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00005108 = getCursorObjCSuperClassRef(C);
5109 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
5110 }
5111
5112 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005113 std::pair<const ObjCProtocolDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00005114 = getCursorObjCProtocolRef(C);
5115 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
5116 }
5117
5118 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005119 std::pair<const ObjCInterfaceDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00005120 = getCursorObjCClassRef(C);
5121 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
5122 }
5123
5124 case CXCursor_TypeRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005125 std::pair<const TypeDecl *, SourceLocation> P = getCursorTypeRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005126 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
5127 }
5128
5129 case CXCursor_TemplateRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005130 std::pair<const TemplateDecl *, SourceLocation> P =
5131 getCursorTemplateRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005132 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
5133 }
5134
5135 case CXCursor_NamespaceRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005136 std::pair<const NamedDecl *, SourceLocation> P = getCursorNamespaceRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005137 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
5138 }
5139
5140 case CXCursor_MemberRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005141 std::pair<const FieldDecl *, SourceLocation> P = getCursorMemberRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005142 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
5143 }
5144
5145 case CXCursor_VariableRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005146 std::pair<const VarDecl *, SourceLocation> P = getCursorVariableRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005147 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
5148 }
5149
5150 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005151 const CXXBaseSpecifier *BaseSpec = getCursorCXXBaseSpecifier(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005152 if (!BaseSpec)
5153 return clang_getNullLocation();
5154
5155 if (TypeSourceInfo *TSInfo = BaseSpec->getTypeSourceInfo())
5156 return cxloc::translateSourceLocation(getCursorContext(C),
5157 TSInfo->getTypeLoc().getBeginLoc());
5158
5159 return cxloc::translateSourceLocation(getCursorContext(C),
5160 BaseSpec->getLocStart());
5161 }
5162
5163 case CXCursor_LabelRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005164 std::pair<const LabelStmt *, SourceLocation> P = getCursorLabelRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005165 return cxloc::translateSourceLocation(getCursorContext(C), P.second);
5166 }
5167
5168 case CXCursor_OverloadedDeclRef:
5169 return cxloc::translateSourceLocation(getCursorContext(C),
5170 getCursorOverloadedDeclRef(C).second);
5171
5172 default:
5173 // FIXME: Need a way to enumerate all non-reference cases.
5174 llvm_unreachable("Missed a reference kind");
5175 }
5176 }
5177
5178 if (clang_isExpression(C.kind))
5179 return cxloc::translateSourceLocation(getCursorContext(C),
5180 getLocationFromExpr(getCursorExpr(C)));
5181
5182 if (clang_isStatement(C.kind))
5183 return cxloc::translateSourceLocation(getCursorContext(C),
5184 getCursorStmt(C)->getLocStart());
5185
5186 if (C.kind == CXCursor_PreprocessingDirective) {
5187 SourceLocation L = cxcursor::getCursorPreprocessingDirective(C).getBegin();
5188 return cxloc::translateSourceLocation(getCursorContext(C), L);
5189 }
5190
5191 if (C.kind == CXCursor_MacroExpansion) {
5192 SourceLocation L
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00005193 = cxcursor::getCursorMacroExpansion(C).getSourceRange().getBegin();
Guy Benyei11169dd2012-12-18 14:30:41 +00005194 return cxloc::translateSourceLocation(getCursorContext(C), L);
5195 }
5196
5197 if (C.kind == CXCursor_MacroDefinition) {
5198 SourceLocation L = cxcursor::getCursorMacroDefinition(C)->getLocation();
5199 return cxloc::translateSourceLocation(getCursorContext(C), L);
5200 }
5201
5202 if (C.kind == CXCursor_InclusionDirective) {
5203 SourceLocation L
5204 = cxcursor::getCursorInclusionDirective(C)->getSourceRange().getBegin();
5205 return cxloc::translateSourceLocation(getCursorContext(C), L);
5206 }
5207
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00005208 if (clang_isAttribute(C.kind)) {
5209 SourceLocation L
5210 = cxcursor::getCursorAttr(C)->getLocation();
5211 return cxloc::translateSourceLocation(getCursorContext(C), L);
5212 }
5213
Guy Benyei11169dd2012-12-18 14:30:41 +00005214 if (!clang_isDeclaration(C.kind))
5215 return clang_getNullLocation();
5216
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005217 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005218 if (!D)
5219 return clang_getNullLocation();
5220
5221 SourceLocation Loc = D->getLocation();
5222 // FIXME: Multiple variables declared in a single declaration
5223 // currently lack the information needed to correctly determine their
5224 // ranges when accounting for the type-specifier. We use context
5225 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
5226 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005227 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005228 if (!cxcursor::isFirstInDeclGroup(C))
5229 Loc = VD->getLocation();
5230 }
5231
5232 // For ObjC methods, give the start location of the method name.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005233 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00005234 Loc = MD->getSelectorStartLoc();
5235
5236 return cxloc::translateSourceLocation(getCursorContext(C), Loc);
5237}
5238
5239} // end extern "C"
5240
5241CXCursor cxcursor::getCursor(CXTranslationUnit TU, SourceLocation SLoc) {
5242 assert(TU);
5243
5244 // Guard against an invalid SourceLocation, or we may assert in one
5245 // of the following calls.
5246 if (SLoc.isInvalid())
5247 return clang_getNullCursor();
5248
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005249 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005250
5251 // Translate the given source location to make it point at the beginning of
5252 // the token under the cursor.
5253 SLoc = Lexer::GetBeginningOfToken(SLoc, CXXUnit->getSourceManager(),
5254 CXXUnit->getASTContext().getLangOpts());
5255
5256 CXCursor Result = MakeCXCursorInvalid(CXCursor_NoDeclFound);
5257 if (SLoc.isValid()) {
5258 GetCursorData ResultData(CXXUnit->getSourceManager(), SLoc, Result);
5259 CursorVisitor CursorVis(TU, GetCursorVisitor, &ResultData,
5260 /*VisitPreprocessorLast=*/true,
5261 /*VisitIncludedEntities=*/false,
5262 SourceLocation(SLoc));
5263 CursorVis.visitFileRegion();
5264 }
5265
5266 return Result;
5267}
5268
5269static SourceRange getRawCursorExtent(CXCursor C) {
5270 if (clang_isReference(C.kind)) {
5271 switch (C.kind) {
5272 case CXCursor_ObjCSuperClassRef:
5273 return getCursorObjCSuperClassRef(C).second;
5274
5275 case CXCursor_ObjCProtocolRef:
5276 return getCursorObjCProtocolRef(C).second;
5277
5278 case CXCursor_ObjCClassRef:
5279 return getCursorObjCClassRef(C).second;
5280
5281 case CXCursor_TypeRef:
5282 return getCursorTypeRef(C).second;
5283
5284 case CXCursor_TemplateRef:
5285 return getCursorTemplateRef(C).second;
5286
5287 case CXCursor_NamespaceRef:
5288 return getCursorNamespaceRef(C).second;
5289
5290 case CXCursor_MemberRef:
5291 return getCursorMemberRef(C).second;
5292
5293 case CXCursor_CXXBaseSpecifier:
5294 return getCursorCXXBaseSpecifier(C)->getSourceRange();
5295
5296 case CXCursor_LabelRef:
5297 return getCursorLabelRef(C).second;
5298
5299 case CXCursor_OverloadedDeclRef:
5300 return getCursorOverloadedDeclRef(C).second;
5301
5302 case CXCursor_VariableRef:
5303 return getCursorVariableRef(C).second;
5304
5305 default:
5306 // FIXME: Need a way to enumerate all non-reference cases.
5307 llvm_unreachable("Missed a reference kind");
5308 }
5309 }
5310
5311 if (clang_isExpression(C.kind))
5312 return getCursorExpr(C)->getSourceRange();
5313
5314 if (clang_isStatement(C.kind))
5315 return getCursorStmt(C)->getSourceRange();
5316
5317 if (clang_isAttribute(C.kind))
5318 return getCursorAttr(C)->getRange();
5319
5320 if (C.kind == CXCursor_PreprocessingDirective)
5321 return cxcursor::getCursorPreprocessingDirective(C);
5322
5323 if (C.kind == CXCursor_MacroExpansion) {
5324 ASTUnit *TU = getCursorASTUnit(C);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00005325 SourceRange Range = cxcursor::getCursorMacroExpansion(C).getSourceRange();
Guy Benyei11169dd2012-12-18 14:30:41 +00005326 return TU->mapRangeFromPreamble(Range);
5327 }
5328
5329 if (C.kind == CXCursor_MacroDefinition) {
5330 ASTUnit *TU = getCursorASTUnit(C);
5331 SourceRange Range = cxcursor::getCursorMacroDefinition(C)->getSourceRange();
5332 return TU->mapRangeFromPreamble(Range);
5333 }
5334
5335 if (C.kind == CXCursor_InclusionDirective) {
5336 ASTUnit *TU = getCursorASTUnit(C);
5337 SourceRange Range = cxcursor::getCursorInclusionDirective(C)->getSourceRange();
5338 return TU->mapRangeFromPreamble(Range);
5339 }
5340
5341 if (C.kind == CXCursor_TranslationUnit) {
5342 ASTUnit *TU = getCursorASTUnit(C);
5343 FileID MainID = TU->getSourceManager().getMainFileID();
5344 SourceLocation Start = TU->getSourceManager().getLocForStartOfFile(MainID);
5345 SourceLocation End = TU->getSourceManager().getLocForEndOfFile(MainID);
5346 return SourceRange(Start, End);
5347 }
5348
5349 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005350 const Decl *D = cxcursor::getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005351 if (!D)
5352 return SourceRange();
5353
5354 SourceRange R = D->getSourceRange();
5355 // FIXME: Multiple variables declared in a single declaration
5356 // currently lack the information needed to correctly determine their
5357 // ranges when accounting for the type-specifier. We use context
5358 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
5359 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005360 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005361 if (!cxcursor::isFirstInDeclGroup(C))
5362 R.setBegin(VD->getLocation());
5363 }
5364 return R;
5365 }
5366 return SourceRange();
5367}
5368
5369/// \brief Retrieves the "raw" cursor extent, which is then extended to include
5370/// the decl-specifier-seq for declarations.
5371static SourceRange getFullCursorExtent(CXCursor C, SourceManager &SrcMgr) {
5372 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005373 const Decl *D = cxcursor::getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005374 if (!D)
5375 return SourceRange();
5376
5377 SourceRange R = D->getSourceRange();
5378
5379 // Adjust the start of the location for declarations preceded by
5380 // declaration specifiers.
5381 SourceLocation StartLoc;
5382 if (const DeclaratorDecl *DD = dyn_cast<DeclaratorDecl>(D)) {
5383 if (TypeSourceInfo *TI = DD->getTypeSourceInfo())
5384 StartLoc = TI->getTypeLoc().getLocStart();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005385 } else if (const TypedefDecl *Typedef = dyn_cast<TypedefDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005386 if (TypeSourceInfo *TI = Typedef->getTypeSourceInfo())
5387 StartLoc = TI->getTypeLoc().getLocStart();
5388 }
5389
5390 if (StartLoc.isValid() && R.getBegin().isValid() &&
5391 SrcMgr.isBeforeInTranslationUnit(StartLoc, R.getBegin()))
5392 R.setBegin(StartLoc);
5393
5394 // FIXME: Multiple variables declared in a single declaration
5395 // currently lack the information needed to correctly determine their
5396 // ranges when accounting for the type-specifier. We use context
5397 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
5398 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005399 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005400 if (!cxcursor::isFirstInDeclGroup(C))
5401 R.setBegin(VD->getLocation());
5402 }
5403
5404 return R;
5405 }
5406
5407 return getRawCursorExtent(C);
5408}
5409
5410extern "C" {
5411
5412CXSourceRange clang_getCursorExtent(CXCursor C) {
5413 SourceRange R = getRawCursorExtent(C);
5414 if (R.isInvalid())
5415 return clang_getNullRange();
5416
5417 return cxloc::translateSourceRange(getCursorContext(C), R);
5418}
5419
5420CXCursor clang_getCursorReferenced(CXCursor C) {
5421 if (clang_isInvalid(C.kind))
5422 return clang_getNullCursor();
5423
5424 CXTranslationUnit tu = getCursorTU(C);
5425 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005426 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005427 if (!D)
5428 return clang_getNullCursor();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005429 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00005430 return MakeCursorOverloadedDeclRef(Using, D->getLocation(), tu);
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005431 if (const ObjCPropertyImplDecl *PropImpl =
5432 dyn_cast<ObjCPropertyImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00005433 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
5434 return MakeCXCursor(Property, tu);
5435
5436 return C;
5437 }
5438
5439 if (clang_isExpression(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005440 const Expr *E = getCursorExpr(C);
5441 const Decl *D = getDeclFromExpr(E);
Guy Benyei11169dd2012-12-18 14:30:41 +00005442 if (D) {
5443 CXCursor declCursor = MakeCXCursor(D, tu);
5444 declCursor = getSelectorIdentifierCursor(getSelectorIdentifierIndex(C),
5445 declCursor);
5446 return declCursor;
5447 }
5448
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005449 if (const OverloadExpr *Ovl = dyn_cast_or_null<OverloadExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00005450 return MakeCursorOverloadedDeclRef(Ovl, tu);
5451
5452 return clang_getNullCursor();
5453 }
5454
5455 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005456 const Stmt *S = getCursorStmt(C);
5457 if (const GotoStmt *Goto = dyn_cast_or_null<GotoStmt>(S))
Guy Benyei11169dd2012-12-18 14:30:41 +00005458 if (LabelDecl *label = Goto->getLabel())
5459 if (LabelStmt *labelS = label->getStmt())
5460 return MakeCXCursor(labelS, getCursorDecl(C), tu);
5461
5462 return clang_getNullCursor();
5463 }
Richard Smith66a81862015-05-04 02:25:31 +00005464
Guy Benyei11169dd2012-12-18 14:30:41 +00005465 if (C.kind == CXCursor_MacroExpansion) {
Richard Smith66a81862015-05-04 02:25:31 +00005466 if (const MacroDefinitionRecord *Def =
5467 getCursorMacroExpansion(C).getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005468 return MakeMacroDefinitionCursor(Def, tu);
5469 }
5470
5471 if (!clang_isReference(C.kind))
5472 return clang_getNullCursor();
5473
5474 switch (C.kind) {
5475 case CXCursor_ObjCSuperClassRef:
5476 return MakeCXCursor(getCursorObjCSuperClassRef(C).first, tu);
5477
5478 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005479 const ObjCProtocolDecl *Prot = getCursorObjCProtocolRef(C).first;
5480 if (const ObjCProtocolDecl *Def = Prot->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005481 return MakeCXCursor(Def, tu);
5482
5483 return MakeCXCursor(Prot, tu);
5484 }
5485
5486 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005487 const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
5488 if (const ObjCInterfaceDecl *Def = Class->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005489 return MakeCXCursor(Def, tu);
5490
5491 return MakeCXCursor(Class, tu);
5492 }
5493
5494 case CXCursor_TypeRef:
5495 return MakeCXCursor(getCursorTypeRef(C).first, tu );
5496
5497 case CXCursor_TemplateRef:
5498 return MakeCXCursor(getCursorTemplateRef(C).first, tu );
5499
5500 case CXCursor_NamespaceRef:
5501 return MakeCXCursor(getCursorNamespaceRef(C).first, tu );
5502
5503 case CXCursor_MemberRef:
5504 return MakeCXCursor(getCursorMemberRef(C).first, tu );
5505
5506 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005507 const CXXBaseSpecifier *B = cxcursor::getCursorCXXBaseSpecifier(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005508 return clang_getTypeDeclaration(cxtype::MakeCXType(B->getType(),
5509 tu ));
5510 }
5511
5512 case CXCursor_LabelRef:
5513 // FIXME: We end up faking the "parent" declaration here because we
5514 // don't want to make CXCursor larger.
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005515 return MakeCXCursor(getCursorLabelRef(C).first,
5516 cxtu::getASTUnit(tu)->getASTContext()
5517 .getTranslationUnitDecl(),
Guy Benyei11169dd2012-12-18 14:30:41 +00005518 tu);
5519
5520 case CXCursor_OverloadedDeclRef:
5521 return C;
5522
5523 case CXCursor_VariableRef:
5524 return MakeCXCursor(getCursorVariableRef(C).first, tu);
5525
5526 default:
5527 // We would prefer to enumerate all non-reference cursor kinds here.
5528 llvm_unreachable("Unhandled reference cursor kind");
5529 }
5530}
5531
5532CXCursor clang_getCursorDefinition(CXCursor C) {
5533 if (clang_isInvalid(C.kind))
5534 return clang_getNullCursor();
5535
5536 CXTranslationUnit TU = getCursorTU(C);
5537
5538 bool WasReference = false;
5539 if (clang_isReference(C.kind) || clang_isExpression(C.kind)) {
5540 C = clang_getCursorReferenced(C);
5541 WasReference = true;
5542 }
5543
5544 if (C.kind == CXCursor_MacroExpansion)
5545 return clang_getCursorReferenced(C);
5546
5547 if (!clang_isDeclaration(C.kind))
5548 return clang_getNullCursor();
5549
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005550 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005551 if (!D)
5552 return clang_getNullCursor();
5553
5554 switch (D->getKind()) {
5555 // Declaration kinds that don't really separate the notions of
5556 // declaration and definition.
5557 case Decl::Namespace:
5558 case Decl::Typedef:
5559 case Decl::TypeAlias:
5560 case Decl::TypeAliasTemplate:
5561 case Decl::TemplateTypeParm:
5562 case Decl::EnumConstant:
5563 case Decl::Field:
John McCall5e77d762013-04-16 07:28:30 +00005564 case Decl::MSProperty:
Guy Benyei11169dd2012-12-18 14:30:41 +00005565 case Decl::IndirectField:
5566 case Decl::ObjCIvar:
5567 case Decl::ObjCAtDefsField:
5568 case Decl::ImplicitParam:
5569 case Decl::ParmVar:
5570 case Decl::NonTypeTemplateParm:
5571 case Decl::TemplateTemplateParm:
5572 case Decl::ObjCCategoryImpl:
5573 case Decl::ObjCImplementation:
5574 case Decl::AccessSpec:
5575 case Decl::LinkageSpec:
5576 case Decl::ObjCPropertyImpl:
5577 case Decl::FileScopeAsm:
5578 case Decl::StaticAssert:
5579 case Decl::Block:
Tareq A. Siraj6dfa25a2013-04-16 19:37:38 +00005580 case Decl::Captured:
Alexey Bataev4244be22016-02-11 05:35:55 +00005581 case Decl::OMPCapturedExpr:
Guy Benyei11169dd2012-12-18 14:30:41 +00005582 case Decl::Label: // FIXME: Is this right??
5583 case Decl::ClassScopeFunctionSpecialization:
5584 case Decl::Import:
Alexey Bataeva769e072013-03-22 06:34:35 +00005585 case Decl::OMPThreadPrivate:
Alexey Bataev94a4f0c2016-03-03 05:21:39 +00005586 case Decl::OMPDeclareReduction:
Douglas Gregor85f3f952015-07-07 03:57:15 +00005587 case Decl::ObjCTypeParam:
David Majnemerd9b1a4f2015-11-04 03:40:30 +00005588 case Decl::BuiltinTemplate:
Nico Weber66220292016-03-02 17:28:48 +00005589 case Decl::PragmaComment:
Nico Webercbbaeb12016-03-02 19:28:54 +00005590 case Decl::PragmaDetectMismatch:
Guy Benyei11169dd2012-12-18 14:30:41 +00005591 return C;
5592
5593 // Declaration kinds that don't make any sense here, but are
5594 // nonetheless harmless.
David Blaikief005d3c2013-02-22 17:44:58 +00005595 case Decl::Empty:
Guy Benyei11169dd2012-12-18 14:30:41 +00005596 case Decl::TranslationUnit:
Richard Smithf19e1272015-03-07 00:04:49 +00005597 case Decl::ExternCContext:
Guy Benyei11169dd2012-12-18 14:30:41 +00005598 break;
5599
5600 // Declaration kinds for which the definition is not resolvable.
5601 case Decl::UnresolvedUsingTypename:
5602 case Decl::UnresolvedUsingValue:
5603 break;
5604
5605 case Decl::UsingDirective:
5606 return MakeCXCursor(cast<UsingDirectiveDecl>(D)->getNominatedNamespace(),
5607 TU);
5608
5609 case Decl::NamespaceAlias:
5610 return MakeCXCursor(cast<NamespaceAliasDecl>(D)->getNamespace(), TU);
5611
5612 case Decl::Enum:
5613 case Decl::Record:
5614 case Decl::CXXRecord:
5615 case Decl::ClassTemplateSpecialization:
5616 case Decl::ClassTemplatePartialSpecialization:
5617 if (TagDecl *Def = cast<TagDecl>(D)->getDefinition())
5618 return MakeCXCursor(Def, TU);
5619 return clang_getNullCursor();
5620
5621 case Decl::Function:
5622 case Decl::CXXMethod:
5623 case Decl::CXXConstructor:
5624 case Decl::CXXDestructor:
5625 case Decl::CXXConversion: {
Craig Topper69186e72014-06-08 08:38:04 +00005626 const FunctionDecl *Def = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005627 if (cast<FunctionDecl>(D)->getBody(Def))
Dmitri Gribenko9c256e32013-01-14 00:46:27 +00005628 return MakeCXCursor(Def, TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005629 return clang_getNullCursor();
5630 }
5631
Larisse Voufo39a1e502013-08-06 01:03:05 +00005632 case Decl::Var:
5633 case Decl::VarTemplateSpecialization:
5634 case Decl::VarTemplatePartialSpecialization: {
Guy Benyei11169dd2012-12-18 14:30:41 +00005635 // Ask the variable if it has a definition.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005636 if (const VarDecl *Def = cast<VarDecl>(D)->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005637 return MakeCXCursor(Def, TU);
5638 return clang_getNullCursor();
5639 }
5640
5641 case Decl::FunctionTemplate: {
Craig Topper69186e72014-06-08 08:38:04 +00005642 const FunctionDecl *Def = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005643 if (cast<FunctionTemplateDecl>(D)->getTemplatedDecl()->getBody(Def))
5644 return MakeCXCursor(Def->getDescribedFunctionTemplate(), TU);
5645 return clang_getNullCursor();
5646 }
5647
5648 case Decl::ClassTemplate: {
5649 if (RecordDecl *Def = cast<ClassTemplateDecl>(D)->getTemplatedDecl()
5650 ->getDefinition())
5651 return MakeCXCursor(cast<CXXRecordDecl>(Def)->getDescribedClassTemplate(),
5652 TU);
5653 return clang_getNullCursor();
5654 }
5655
Larisse Voufo39a1e502013-08-06 01:03:05 +00005656 case Decl::VarTemplate: {
5657 if (VarDecl *Def =
5658 cast<VarTemplateDecl>(D)->getTemplatedDecl()->getDefinition())
5659 return MakeCXCursor(cast<VarDecl>(Def)->getDescribedVarTemplate(), TU);
5660 return clang_getNullCursor();
5661 }
5662
Guy Benyei11169dd2012-12-18 14:30:41 +00005663 case Decl::Using:
5664 return MakeCursorOverloadedDeclRef(cast<UsingDecl>(D),
5665 D->getLocation(), TU);
5666
5667 case Decl::UsingShadow:
5668 return clang_getCursorDefinition(
5669 MakeCXCursor(cast<UsingShadowDecl>(D)->getTargetDecl(),
5670 TU));
5671
5672 case Decl::ObjCMethod: {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005673 const ObjCMethodDecl *Method = cast<ObjCMethodDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00005674 if (Method->isThisDeclarationADefinition())
5675 return C;
5676
5677 // Dig out the method definition in the associated
5678 // @implementation, if we have it.
5679 // FIXME: The ASTs should make finding the definition easier.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005680 if (const ObjCInterfaceDecl *Class
Guy Benyei11169dd2012-12-18 14:30:41 +00005681 = dyn_cast<ObjCInterfaceDecl>(Method->getDeclContext()))
5682 if (ObjCImplementationDecl *ClassImpl = Class->getImplementation())
5683 if (ObjCMethodDecl *Def = ClassImpl->getMethod(Method->getSelector(),
5684 Method->isInstanceMethod()))
5685 if (Def->isThisDeclarationADefinition())
5686 return MakeCXCursor(Def, TU);
5687
5688 return clang_getNullCursor();
5689 }
5690
5691 case Decl::ObjCCategory:
5692 if (ObjCCategoryImplDecl *Impl
5693 = cast<ObjCCategoryDecl>(D)->getImplementation())
5694 return MakeCXCursor(Impl, TU);
5695 return clang_getNullCursor();
5696
5697 case Decl::ObjCProtocol:
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005698 if (const ObjCProtocolDecl *Def = cast<ObjCProtocolDecl>(D)->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005699 return MakeCXCursor(Def, TU);
5700 return clang_getNullCursor();
5701
5702 case Decl::ObjCInterface: {
5703 // There are two notions of a "definition" for an Objective-C
5704 // class: the interface and its implementation. When we resolved a
5705 // reference to an Objective-C class, produce the @interface as
5706 // the definition; when we were provided with the interface,
5707 // produce the @implementation as the definition.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005708 const ObjCInterfaceDecl *IFace = cast<ObjCInterfaceDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00005709 if (WasReference) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005710 if (const ObjCInterfaceDecl *Def = IFace->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005711 return MakeCXCursor(Def, TU);
5712 } else if (ObjCImplementationDecl *Impl = IFace->getImplementation())
5713 return MakeCXCursor(Impl, TU);
5714 return clang_getNullCursor();
5715 }
5716
5717 case Decl::ObjCProperty:
5718 // FIXME: We don't really know where to find the
5719 // ObjCPropertyImplDecls that implement this property.
5720 return clang_getNullCursor();
5721
5722 case Decl::ObjCCompatibleAlias:
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005723 if (const ObjCInterfaceDecl *Class
Guy Benyei11169dd2012-12-18 14:30:41 +00005724 = cast<ObjCCompatibleAliasDecl>(D)->getClassInterface())
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005725 if (const ObjCInterfaceDecl *Def = Class->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005726 return MakeCXCursor(Def, TU);
5727
5728 return clang_getNullCursor();
5729
5730 case Decl::Friend:
5731 if (NamedDecl *Friend = cast<FriendDecl>(D)->getFriendDecl())
5732 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
5733 return clang_getNullCursor();
5734
5735 case Decl::FriendTemplate:
5736 if (NamedDecl *Friend = cast<FriendTemplateDecl>(D)->getFriendDecl())
5737 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
5738 return clang_getNullCursor();
5739 }
5740
5741 return clang_getNullCursor();
5742}
5743
5744unsigned clang_isCursorDefinition(CXCursor C) {
5745 if (!clang_isDeclaration(C.kind))
5746 return 0;
5747
5748 return clang_getCursorDefinition(C) == C;
5749}
5750
5751CXCursor clang_getCanonicalCursor(CXCursor C) {
5752 if (!clang_isDeclaration(C.kind))
5753 return C;
5754
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005755 if (const Decl *D = getCursorDecl(C)) {
5756 if (const ObjCCategoryImplDecl *CatImplD = dyn_cast<ObjCCategoryImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00005757 if (ObjCCategoryDecl *CatD = CatImplD->getCategoryDecl())
5758 return MakeCXCursor(CatD, getCursorTU(C));
5759
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005760 if (const ObjCImplDecl *ImplD = dyn_cast<ObjCImplDecl>(D))
5761 if (const ObjCInterfaceDecl *IFD = ImplD->getClassInterface())
Guy Benyei11169dd2012-12-18 14:30:41 +00005762 return MakeCXCursor(IFD, getCursorTU(C));
5763
5764 return MakeCXCursor(D->getCanonicalDecl(), getCursorTU(C));
5765 }
5766
5767 return C;
5768}
5769
5770int clang_Cursor_getObjCSelectorIndex(CXCursor cursor) {
5771 return cxcursor::getSelectorIdentifierIndexAndLoc(cursor).first;
5772}
5773
5774unsigned clang_getNumOverloadedDecls(CXCursor C) {
5775 if (C.kind != CXCursor_OverloadedDeclRef)
5776 return 0;
5777
5778 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005779 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Guy Benyei11169dd2012-12-18 14:30:41 +00005780 return E->getNumDecls();
5781
5782 if (OverloadedTemplateStorage *S
5783 = Storage.dyn_cast<OverloadedTemplateStorage*>())
5784 return S->size();
5785
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005786 const Decl *D = Storage.get<const Decl *>();
5787 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00005788 return Using->shadow_size();
5789
5790 return 0;
5791}
5792
5793CXCursor clang_getOverloadedDecl(CXCursor cursor, unsigned index) {
5794 if (cursor.kind != CXCursor_OverloadedDeclRef)
5795 return clang_getNullCursor();
5796
5797 if (index >= clang_getNumOverloadedDecls(cursor))
5798 return clang_getNullCursor();
5799
5800 CXTranslationUnit TU = getCursorTU(cursor);
5801 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(cursor).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005802 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Guy Benyei11169dd2012-12-18 14:30:41 +00005803 return MakeCXCursor(E->decls_begin()[index], TU);
5804
5805 if (OverloadedTemplateStorage *S
5806 = Storage.dyn_cast<OverloadedTemplateStorage*>())
5807 return MakeCXCursor(S->begin()[index], TU);
5808
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005809 const Decl *D = Storage.get<const Decl *>();
5810 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005811 // FIXME: This is, unfortunately, linear time.
5812 UsingDecl::shadow_iterator Pos = Using->shadow_begin();
5813 std::advance(Pos, index);
5814 return MakeCXCursor(cast<UsingShadowDecl>(*Pos)->getTargetDecl(), TU);
5815 }
5816
5817 return clang_getNullCursor();
5818}
5819
5820void clang_getDefinitionSpellingAndExtent(CXCursor C,
5821 const char **startBuf,
5822 const char **endBuf,
5823 unsigned *startLine,
5824 unsigned *startColumn,
5825 unsigned *endLine,
5826 unsigned *endColumn) {
5827 assert(getCursorDecl(C) && "CXCursor has null decl");
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005828 const FunctionDecl *FD = dyn_cast<FunctionDecl>(getCursorDecl(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00005829 CompoundStmt *Body = dyn_cast<CompoundStmt>(FD->getBody());
5830
5831 SourceManager &SM = FD->getASTContext().getSourceManager();
5832 *startBuf = SM.getCharacterData(Body->getLBracLoc());
5833 *endBuf = SM.getCharacterData(Body->getRBracLoc());
5834 *startLine = SM.getSpellingLineNumber(Body->getLBracLoc());
5835 *startColumn = SM.getSpellingColumnNumber(Body->getLBracLoc());
5836 *endLine = SM.getSpellingLineNumber(Body->getRBracLoc());
5837 *endColumn = SM.getSpellingColumnNumber(Body->getRBracLoc());
5838}
5839
5840
5841CXSourceRange clang_getCursorReferenceNameRange(CXCursor C, unsigned NameFlags,
5842 unsigned PieceIndex) {
5843 RefNamePieces Pieces;
5844
5845 switch (C.kind) {
5846 case CXCursor_MemberRefExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005847 if (const MemberExpr *E = dyn_cast<MemberExpr>(getCursorExpr(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00005848 Pieces = buildPieces(NameFlags, true, E->getMemberNameInfo(),
5849 E->getQualifierLoc().getSourceRange());
5850 break;
5851
5852 case CXCursor_DeclRefExpr:
James Y Knight04ec5bf2015-12-24 02:59:37 +00005853 if (const DeclRefExpr *E = dyn_cast<DeclRefExpr>(getCursorExpr(C))) {
5854 SourceRange TemplateArgLoc(E->getLAngleLoc(), E->getRAngleLoc());
5855 Pieces =
5856 buildPieces(NameFlags, false, E->getNameInfo(),
5857 E->getQualifierLoc().getSourceRange(), &TemplateArgLoc);
5858 }
Guy Benyei11169dd2012-12-18 14:30:41 +00005859 break;
5860
5861 case CXCursor_CallExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005862 if (const CXXOperatorCallExpr *OCE =
Guy Benyei11169dd2012-12-18 14:30:41 +00005863 dyn_cast<CXXOperatorCallExpr>(getCursorExpr(C))) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005864 const Expr *Callee = OCE->getCallee();
5865 if (const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Callee))
Guy Benyei11169dd2012-12-18 14:30:41 +00005866 Callee = ICE->getSubExpr();
5867
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005868 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(Callee))
Guy Benyei11169dd2012-12-18 14:30:41 +00005869 Pieces = buildPieces(NameFlags, false, DRE->getNameInfo(),
5870 DRE->getQualifierLoc().getSourceRange());
5871 }
5872 break;
5873
5874 default:
5875 break;
5876 }
5877
5878 if (Pieces.empty()) {
5879 if (PieceIndex == 0)
5880 return clang_getCursorExtent(C);
5881 } else if (PieceIndex < Pieces.size()) {
5882 SourceRange R = Pieces[PieceIndex];
5883 if (R.isValid())
5884 return cxloc::translateSourceRange(getCursorContext(C), R);
5885 }
5886
5887 return clang_getNullRange();
5888}
5889
5890void clang_enableStackTraces(void) {
5891 llvm::sys::PrintStackTraceOnErrorSignal();
5892}
5893
5894void clang_executeOnThread(void (*fn)(void*), void *user_data,
5895 unsigned stack_size) {
5896 llvm::llvm_execute_on_thread(fn, user_data, stack_size);
5897}
5898
5899} // end: extern "C"
5900
5901//===----------------------------------------------------------------------===//
5902// Token-based Operations.
5903//===----------------------------------------------------------------------===//
5904
5905/* CXToken layout:
5906 * int_data[0]: a CXTokenKind
5907 * int_data[1]: starting token location
5908 * int_data[2]: token length
5909 * int_data[3]: reserved
5910 * ptr_data: for identifiers and keywords, an IdentifierInfo*.
5911 * otherwise unused.
5912 */
5913extern "C" {
5914
5915CXTokenKind clang_getTokenKind(CXToken CXTok) {
5916 return static_cast<CXTokenKind>(CXTok.int_data[0]);
5917}
5918
5919CXString clang_getTokenSpelling(CXTranslationUnit TU, CXToken CXTok) {
5920 switch (clang_getTokenKind(CXTok)) {
5921 case CXToken_Identifier:
5922 case CXToken_Keyword:
5923 // We know we have an IdentifierInfo*, so use that.
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005924 return cxstring::createRef(static_cast<IdentifierInfo *>(CXTok.ptr_data)
Guy Benyei11169dd2012-12-18 14:30:41 +00005925 ->getNameStart());
5926
5927 case CXToken_Literal: {
5928 // We have stashed the starting pointer in the ptr_data field. Use it.
5929 const char *Text = static_cast<const char *>(CXTok.ptr_data);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00005930 return cxstring::createDup(StringRef(Text, CXTok.int_data[2]));
Guy Benyei11169dd2012-12-18 14:30:41 +00005931 }
5932
5933 case CXToken_Punctuation:
5934 case CXToken_Comment:
5935 break;
5936 }
5937
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005938 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005939 LOG_BAD_TU(TU);
5940 return cxstring::createEmpty();
5941 }
5942
Guy Benyei11169dd2012-12-18 14:30:41 +00005943 // We have to find the starting buffer pointer the hard way, by
5944 // deconstructing the source location.
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005945 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005946 if (!CXXUnit)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00005947 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00005948
5949 SourceLocation Loc = SourceLocation::getFromRawEncoding(CXTok.int_data[1]);
5950 std::pair<FileID, unsigned> LocInfo
5951 = CXXUnit->getSourceManager().getDecomposedSpellingLoc(Loc);
5952 bool Invalid = false;
5953 StringRef Buffer
5954 = CXXUnit->getSourceManager().getBufferData(LocInfo.first, &Invalid);
5955 if (Invalid)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00005956 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00005957
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00005958 return cxstring::createDup(Buffer.substr(LocInfo.second, CXTok.int_data[2]));
Guy Benyei11169dd2012-12-18 14:30:41 +00005959}
5960
5961CXSourceLocation clang_getTokenLocation(CXTranslationUnit TU, CXToken CXTok) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005962 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005963 LOG_BAD_TU(TU);
5964 return clang_getNullLocation();
5965 }
5966
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005967 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005968 if (!CXXUnit)
5969 return clang_getNullLocation();
5970
5971 return cxloc::translateSourceLocation(CXXUnit->getASTContext(),
5972 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
5973}
5974
5975CXSourceRange clang_getTokenExtent(CXTranslationUnit TU, CXToken CXTok) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005976 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005977 LOG_BAD_TU(TU);
5978 return clang_getNullRange();
5979 }
5980
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005981 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005982 if (!CXXUnit)
5983 return clang_getNullRange();
5984
5985 return cxloc::translateSourceRange(CXXUnit->getASTContext(),
5986 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
5987}
5988
5989static void getTokens(ASTUnit *CXXUnit, SourceRange Range,
5990 SmallVectorImpl<CXToken> &CXTokens) {
5991 SourceManager &SourceMgr = CXXUnit->getSourceManager();
5992 std::pair<FileID, unsigned> BeginLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005993 = SourceMgr.getDecomposedSpellingLoc(Range.getBegin());
Guy Benyei11169dd2012-12-18 14:30:41 +00005994 std::pair<FileID, unsigned> EndLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005995 = SourceMgr.getDecomposedSpellingLoc(Range.getEnd());
Guy Benyei11169dd2012-12-18 14:30:41 +00005996
5997 // Cannot tokenize across files.
5998 if (BeginLocInfo.first != EndLocInfo.first)
5999 return;
6000
6001 // Create a lexer
6002 bool Invalid = false;
6003 StringRef Buffer
6004 = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
6005 if (Invalid)
6006 return;
6007
6008 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
6009 CXXUnit->getASTContext().getLangOpts(),
6010 Buffer.begin(), Buffer.data() + BeginLocInfo.second, Buffer.end());
6011 Lex.SetCommentRetentionState(true);
6012
6013 // Lex tokens until we hit the end of the range.
6014 const char *EffectiveBufferEnd = Buffer.data() + EndLocInfo.second;
6015 Token Tok;
6016 bool previousWasAt = false;
6017 do {
6018 // Lex the next token
6019 Lex.LexFromRawLexer(Tok);
6020 if (Tok.is(tok::eof))
6021 break;
6022
6023 // Initialize the CXToken.
6024 CXToken CXTok;
6025
6026 // - Common fields
6027 CXTok.int_data[1] = Tok.getLocation().getRawEncoding();
6028 CXTok.int_data[2] = Tok.getLength();
6029 CXTok.int_data[3] = 0;
6030
6031 // - Kind-specific fields
6032 if (Tok.isLiteral()) {
6033 CXTok.int_data[0] = CXToken_Literal;
Dmitri Gribenkof9304482013-01-23 15:56:07 +00006034 CXTok.ptr_data = const_cast<char *>(Tok.getLiteralData());
Guy Benyei11169dd2012-12-18 14:30:41 +00006035 } else if (Tok.is(tok::raw_identifier)) {
6036 // Lookup the identifier to determine whether we have a keyword.
6037 IdentifierInfo *II
6038 = CXXUnit->getPreprocessor().LookUpIdentifierInfo(Tok);
6039
6040 if ((II->getObjCKeywordID() != tok::objc_not_keyword) && previousWasAt) {
6041 CXTok.int_data[0] = CXToken_Keyword;
6042 }
6043 else {
6044 CXTok.int_data[0] = Tok.is(tok::identifier)
6045 ? CXToken_Identifier
6046 : CXToken_Keyword;
6047 }
6048 CXTok.ptr_data = II;
6049 } else if (Tok.is(tok::comment)) {
6050 CXTok.int_data[0] = CXToken_Comment;
Craig Topper69186e72014-06-08 08:38:04 +00006051 CXTok.ptr_data = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006052 } else {
6053 CXTok.int_data[0] = CXToken_Punctuation;
Craig Topper69186e72014-06-08 08:38:04 +00006054 CXTok.ptr_data = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006055 }
6056 CXTokens.push_back(CXTok);
6057 previousWasAt = Tok.is(tok::at);
6058 } while (Lex.getBufferLocation() <= EffectiveBufferEnd);
6059}
6060
6061void clang_tokenize(CXTranslationUnit TU, CXSourceRange Range,
6062 CXToken **Tokens, unsigned *NumTokens) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006063 LOG_FUNC_SECTION {
6064 *Log << TU << ' ' << Range;
6065 }
6066
Guy Benyei11169dd2012-12-18 14:30:41 +00006067 if (Tokens)
Craig Topper69186e72014-06-08 08:38:04 +00006068 *Tokens = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006069 if (NumTokens)
6070 *NumTokens = 0;
6071
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006072 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006073 LOG_BAD_TU(TU);
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00006074 return;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006075 }
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00006076
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006077 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00006078 if (!CXXUnit || !Tokens || !NumTokens)
6079 return;
6080
6081 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
6082
6083 SourceRange R = cxloc::translateCXSourceRange(Range);
6084 if (R.isInvalid())
6085 return;
6086
6087 SmallVector<CXToken, 32> CXTokens;
6088 getTokens(CXXUnit, R, CXTokens);
6089
6090 if (CXTokens.empty())
6091 return;
6092
6093 *Tokens = (CXToken *)malloc(sizeof(CXToken) * CXTokens.size());
6094 memmove(*Tokens, CXTokens.data(), sizeof(CXToken) * CXTokens.size());
6095 *NumTokens = CXTokens.size();
6096}
6097
6098void clang_disposeTokens(CXTranslationUnit TU,
6099 CXToken *Tokens, unsigned NumTokens) {
6100 free(Tokens);
6101}
6102
6103} // end: extern "C"
6104
6105//===----------------------------------------------------------------------===//
6106// Token annotation APIs.
6107//===----------------------------------------------------------------------===//
6108
Guy Benyei11169dd2012-12-18 14:30:41 +00006109static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
6110 CXCursor parent,
6111 CXClientData client_data);
6112static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
6113 CXClientData client_data);
6114
6115namespace {
6116class AnnotateTokensWorker {
Guy Benyei11169dd2012-12-18 14:30:41 +00006117 CXToken *Tokens;
6118 CXCursor *Cursors;
6119 unsigned NumTokens;
6120 unsigned TokIdx;
6121 unsigned PreprocessingTokIdx;
6122 CursorVisitor AnnotateVis;
6123 SourceManager &SrcMgr;
6124 bool HasContextSensitiveKeywords;
6125
6126 struct PostChildrenInfo {
6127 CXCursor Cursor;
6128 SourceRange CursorRange;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00006129 unsigned BeforeReachingCursorIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00006130 unsigned BeforeChildrenTokenIdx;
6131 };
Dmitri Gribenkof8579502013-01-12 19:30:44 +00006132 SmallVector<PostChildrenInfo, 8> PostChildrenInfos;
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00006133
6134 CXToken &getTok(unsigned Idx) {
6135 assert(Idx < NumTokens);
6136 return Tokens[Idx];
6137 }
6138 const CXToken &getTok(unsigned Idx) const {
6139 assert(Idx < NumTokens);
6140 return Tokens[Idx];
6141 }
Guy Benyei11169dd2012-12-18 14:30:41 +00006142 bool MoreTokens() const { return TokIdx < NumTokens; }
6143 unsigned NextToken() const { return TokIdx; }
6144 void AdvanceToken() { ++TokIdx; }
6145 SourceLocation GetTokenLoc(unsigned tokI) {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00006146 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[1]);
Guy Benyei11169dd2012-12-18 14:30:41 +00006147 }
6148 bool isFunctionMacroToken(unsigned tokI) const {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00006149 return getTok(tokI).int_data[3] != 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00006150 }
6151 SourceLocation getFunctionMacroTokenLoc(unsigned tokI) const {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00006152 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[3]);
Guy Benyei11169dd2012-12-18 14:30:41 +00006153 }
6154
6155 void annotateAndAdvanceTokens(CXCursor, RangeComparisonResult, SourceRange);
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00006156 bool annotateAndAdvanceFunctionMacroTokens(CXCursor, RangeComparisonResult,
Guy Benyei11169dd2012-12-18 14:30:41 +00006157 SourceRange);
6158
6159public:
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006160 AnnotateTokensWorker(CXToken *tokens, CXCursor *cursors, unsigned numTokens,
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006161 CXTranslationUnit TU, SourceRange RegionOfInterest)
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006162 : Tokens(tokens), Cursors(cursors),
Guy Benyei11169dd2012-12-18 14:30:41 +00006163 NumTokens(numTokens), TokIdx(0), PreprocessingTokIdx(0),
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006164 AnnotateVis(TU,
Guy Benyei11169dd2012-12-18 14:30:41 +00006165 AnnotateTokensVisitor, this,
6166 /*VisitPreprocessorLast=*/true,
6167 /*VisitIncludedEntities=*/false,
6168 RegionOfInterest,
6169 /*VisitDeclsOnly=*/false,
6170 AnnotateTokensPostChildrenVisitor),
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006171 SrcMgr(cxtu::getASTUnit(TU)->getSourceManager()),
Guy Benyei11169dd2012-12-18 14:30:41 +00006172 HasContextSensitiveKeywords(false) { }
6173
6174 void VisitChildren(CXCursor C) { AnnotateVis.VisitChildren(C); }
6175 enum CXChildVisitResult Visit(CXCursor cursor, CXCursor parent);
6176 bool postVisitChildren(CXCursor cursor);
6177 void AnnotateTokens();
6178
6179 /// \brief Determine whether the annotator saw any cursors that have
6180 /// context-sensitive keywords.
6181 bool hasContextSensitiveKeywords() const {
6182 return HasContextSensitiveKeywords;
6183 }
6184
6185 ~AnnotateTokensWorker() {
6186 assert(PostChildrenInfos.empty());
6187 }
6188};
Alexander Kornienkoab9db512015-06-22 23:07:51 +00006189}
Guy Benyei11169dd2012-12-18 14:30:41 +00006190
6191void AnnotateTokensWorker::AnnotateTokens() {
6192 // Walk the AST within the region of interest, annotating tokens
6193 // along the way.
6194 AnnotateVis.visitFileRegion();
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006195}
Guy Benyei11169dd2012-12-18 14:30:41 +00006196
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006197static inline void updateCursorAnnotation(CXCursor &Cursor,
6198 const CXCursor &updateC) {
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00006199 if (clang_isInvalid(updateC.kind) || !clang_isInvalid(Cursor.kind))
Guy Benyei11169dd2012-12-18 14:30:41 +00006200 return;
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006201 Cursor = updateC;
Guy Benyei11169dd2012-12-18 14:30:41 +00006202}
6203
6204/// \brief It annotates and advances tokens with a cursor until the comparison
6205//// between the cursor location and the source range is the same as
6206/// \arg compResult.
6207///
6208/// Pass RangeBefore to annotate tokens with a cursor until a range is reached.
6209/// Pass RangeOverlap to annotate tokens inside a range.
6210void AnnotateTokensWorker::annotateAndAdvanceTokens(CXCursor updateC,
6211 RangeComparisonResult compResult,
6212 SourceRange range) {
6213 while (MoreTokens()) {
6214 const unsigned I = NextToken();
6215 if (isFunctionMacroToken(I))
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00006216 if (!annotateAndAdvanceFunctionMacroTokens(updateC, compResult, range))
6217 return;
Guy Benyei11169dd2012-12-18 14:30:41 +00006218
6219 SourceLocation TokLoc = GetTokenLoc(I);
6220 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006221 updateCursorAnnotation(Cursors[I], updateC);
Guy Benyei11169dd2012-12-18 14:30:41 +00006222 AdvanceToken();
6223 continue;
6224 }
6225 break;
6226 }
6227}
6228
6229/// \brief Special annotation handling for macro argument tokens.
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00006230/// \returns true if it advanced beyond all macro tokens, false otherwise.
6231bool AnnotateTokensWorker::annotateAndAdvanceFunctionMacroTokens(
Guy Benyei11169dd2012-12-18 14:30:41 +00006232 CXCursor updateC,
6233 RangeComparisonResult compResult,
6234 SourceRange range) {
6235 assert(MoreTokens());
6236 assert(isFunctionMacroToken(NextToken()) &&
6237 "Should be called only for macro arg tokens");
6238
6239 // This works differently than annotateAndAdvanceTokens; because expanded
6240 // macro arguments can have arbitrary translation-unit source order, we do not
6241 // advance the token index one by one until a token fails the range test.
6242 // We only advance once past all of the macro arg tokens if all of them
6243 // pass the range test. If one of them fails we keep the token index pointing
6244 // at the start of the macro arg tokens so that the failing token will be
6245 // annotated by a subsequent annotation try.
6246
6247 bool atLeastOneCompFail = false;
6248
6249 unsigned I = NextToken();
6250 for (; I < NumTokens && isFunctionMacroToken(I); ++I) {
6251 SourceLocation TokLoc = getFunctionMacroTokenLoc(I);
6252 if (TokLoc.isFileID())
6253 continue; // not macro arg token, it's parens or comma.
6254 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
6255 if (clang_isInvalid(clang_getCursorKind(Cursors[I])))
6256 Cursors[I] = updateC;
6257 } else
6258 atLeastOneCompFail = true;
6259 }
6260
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00006261 if (atLeastOneCompFail)
6262 return false;
6263
6264 TokIdx = I; // All of the tokens were handled, advance beyond all of them.
6265 return true;
Guy Benyei11169dd2012-12-18 14:30:41 +00006266}
6267
6268enum CXChildVisitResult
6269AnnotateTokensWorker::Visit(CXCursor cursor, CXCursor parent) {
Guy Benyei11169dd2012-12-18 14:30:41 +00006270 SourceRange cursorRange = getRawCursorExtent(cursor);
6271 if (cursorRange.isInvalid())
6272 return CXChildVisit_Recurse;
6273
6274 if (!HasContextSensitiveKeywords) {
6275 // Objective-C properties can have context-sensitive keywords.
6276 if (cursor.kind == CXCursor_ObjCPropertyDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006277 if (const ObjCPropertyDecl *Property
Guy Benyei11169dd2012-12-18 14:30:41 +00006278 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(cursor)))
6279 HasContextSensitiveKeywords = Property->getPropertyAttributesAsWritten() != 0;
6280 }
6281 // Objective-C methods can have context-sensitive keywords.
6282 else if (cursor.kind == CXCursor_ObjCInstanceMethodDecl ||
6283 cursor.kind == CXCursor_ObjCClassMethodDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006284 if (const ObjCMethodDecl *Method
Guy Benyei11169dd2012-12-18 14:30:41 +00006285 = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
6286 if (Method->getObjCDeclQualifier())
6287 HasContextSensitiveKeywords = true;
6288 else {
Aaron Ballman43b68be2014-03-07 17:50:17 +00006289 for (const auto *P : Method->params()) {
6290 if (P->getObjCDeclQualifier()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00006291 HasContextSensitiveKeywords = true;
6292 break;
6293 }
6294 }
6295 }
6296 }
6297 }
6298 // C++ methods can have context-sensitive keywords.
6299 else if (cursor.kind == CXCursor_CXXMethod) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006300 if (const CXXMethodDecl *Method
Guy Benyei11169dd2012-12-18 14:30:41 +00006301 = dyn_cast_or_null<CXXMethodDecl>(getCursorDecl(cursor))) {
6302 if (Method->hasAttr<FinalAttr>() || Method->hasAttr<OverrideAttr>())
6303 HasContextSensitiveKeywords = true;
6304 }
6305 }
6306 // C++ classes can have context-sensitive keywords.
6307 else if (cursor.kind == CXCursor_StructDecl ||
6308 cursor.kind == CXCursor_ClassDecl ||
6309 cursor.kind == CXCursor_ClassTemplate ||
6310 cursor.kind == CXCursor_ClassTemplatePartialSpecialization) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006311 if (const Decl *D = getCursorDecl(cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +00006312 if (D->hasAttr<FinalAttr>())
6313 HasContextSensitiveKeywords = true;
6314 }
6315 }
Argyrios Kyrtzidis990b3862013-06-04 18:24:30 +00006316
6317 // Don't override a property annotation with its getter/setter method.
6318 if (cursor.kind == CXCursor_ObjCInstanceMethodDecl &&
6319 parent.kind == CXCursor_ObjCPropertyDecl)
6320 return CXChildVisit_Continue;
Guy Benyei11169dd2012-12-18 14:30:41 +00006321
6322 if (clang_isPreprocessing(cursor.kind)) {
6323 // Items in the preprocessing record are kept separate from items in
6324 // declarations, so we keep a separate token index.
6325 unsigned SavedTokIdx = TokIdx;
6326 TokIdx = PreprocessingTokIdx;
6327
6328 // Skip tokens up until we catch up to the beginning of the preprocessing
6329 // entry.
6330 while (MoreTokens()) {
6331 const unsigned I = NextToken();
6332 SourceLocation TokLoc = GetTokenLoc(I);
6333 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
6334 case RangeBefore:
6335 AdvanceToken();
6336 continue;
6337 case RangeAfter:
6338 case RangeOverlap:
6339 break;
6340 }
6341 break;
6342 }
6343
6344 // Look at all of the tokens within this range.
6345 while (MoreTokens()) {
6346 const unsigned I = NextToken();
6347 SourceLocation TokLoc = GetTokenLoc(I);
6348 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
6349 case RangeBefore:
6350 llvm_unreachable("Infeasible");
6351 case RangeAfter:
6352 break;
6353 case RangeOverlap:
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00006354 // For macro expansions, just note where the beginning of the macro
6355 // expansion occurs.
6356 if (cursor.kind == CXCursor_MacroExpansion) {
6357 if (TokLoc == cursorRange.getBegin())
6358 Cursors[I] = cursor;
6359 AdvanceToken();
6360 break;
6361 }
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006362 // We may have already annotated macro names inside macro definitions.
6363 if (Cursors[I].kind != CXCursor_MacroExpansion)
6364 Cursors[I] = cursor;
Guy Benyei11169dd2012-12-18 14:30:41 +00006365 AdvanceToken();
Guy Benyei11169dd2012-12-18 14:30:41 +00006366 continue;
6367 }
6368 break;
6369 }
6370
6371 // Save the preprocessing token index; restore the non-preprocessing
6372 // token index.
6373 PreprocessingTokIdx = TokIdx;
6374 TokIdx = SavedTokIdx;
6375 return CXChildVisit_Recurse;
6376 }
6377
6378 if (cursorRange.isInvalid())
6379 return CXChildVisit_Continue;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00006380
6381 unsigned BeforeReachingCursorIdx = NextToken();
Guy Benyei11169dd2012-12-18 14:30:41 +00006382 const enum CXCursorKind cursorK = clang_getCursorKind(cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00006383 const enum CXCursorKind K = clang_getCursorKind(parent);
6384 const CXCursor updateC =
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00006385 (clang_isInvalid(K) || K == CXCursor_TranslationUnit ||
6386 // Attributes are annotated out-of-order, skip tokens until we reach it.
6387 clang_isAttribute(cursor.kind))
Guy Benyei11169dd2012-12-18 14:30:41 +00006388 ? clang_getNullCursor() : parent;
6389
6390 annotateAndAdvanceTokens(updateC, RangeBefore, cursorRange);
6391
6392 // Avoid having the cursor of an expression "overwrite" the annotation of the
6393 // variable declaration that it belongs to.
6394 // This can happen for C++ constructor expressions whose range generally
6395 // include the variable declaration, e.g.:
6396 // MyCXXClass foo; // Make sure we don't annotate 'foo' as a CallExpr cursor.
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00006397 if (clang_isExpression(cursorK) && MoreTokens()) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00006398 const Expr *E = getCursorExpr(cursor);
Dmitri Gribenkoa1691182013-01-26 18:12:08 +00006399 if (const Decl *D = getCursorParentDecl(cursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00006400 const unsigned I = NextToken();
6401 if (E->getLocStart().isValid() && D->getLocation().isValid() &&
6402 E->getLocStart() == D->getLocation() &&
6403 E->getLocStart() == GetTokenLoc(I)) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006404 updateCursorAnnotation(Cursors[I], updateC);
Guy Benyei11169dd2012-12-18 14:30:41 +00006405 AdvanceToken();
6406 }
6407 }
6408 }
6409
6410 // Before recursing into the children keep some state that we are going
6411 // to use in the AnnotateTokensWorker::postVisitChildren callback to do some
6412 // extra work after the child nodes are visited.
6413 // Note that we don't call VisitChildren here to avoid traversing statements
6414 // code-recursively which can blow the stack.
6415
6416 PostChildrenInfo Info;
6417 Info.Cursor = cursor;
6418 Info.CursorRange = cursorRange;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00006419 Info.BeforeReachingCursorIdx = BeforeReachingCursorIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00006420 Info.BeforeChildrenTokenIdx = NextToken();
6421 PostChildrenInfos.push_back(Info);
6422
6423 return CXChildVisit_Recurse;
6424}
6425
6426bool AnnotateTokensWorker::postVisitChildren(CXCursor cursor) {
6427 if (PostChildrenInfos.empty())
6428 return false;
6429 const PostChildrenInfo &Info = PostChildrenInfos.back();
6430 if (!clang_equalCursors(Info.Cursor, cursor))
6431 return false;
6432
6433 const unsigned BeforeChildren = Info.BeforeChildrenTokenIdx;
6434 const unsigned AfterChildren = NextToken();
6435 SourceRange cursorRange = Info.CursorRange;
6436
6437 // Scan the tokens that are at the end of the cursor, but are not captured
6438 // but the child cursors.
6439 annotateAndAdvanceTokens(cursor, RangeOverlap, cursorRange);
6440
6441 // Scan the tokens that are at the beginning of the cursor, but are not
6442 // capture by the child cursors.
6443 for (unsigned I = BeforeChildren; I != AfterChildren; ++I) {
6444 if (!clang_isInvalid(clang_getCursorKind(Cursors[I])))
6445 break;
6446
6447 Cursors[I] = cursor;
6448 }
6449
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00006450 // Attributes are annotated out-of-order, rewind TokIdx to when we first
6451 // encountered the attribute cursor.
6452 if (clang_isAttribute(cursor.kind))
6453 TokIdx = Info.BeforeReachingCursorIdx;
6454
Guy Benyei11169dd2012-12-18 14:30:41 +00006455 PostChildrenInfos.pop_back();
6456 return false;
6457}
6458
6459static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
6460 CXCursor parent,
6461 CXClientData client_data) {
6462 return static_cast<AnnotateTokensWorker*>(client_data)->Visit(cursor, parent);
6463}
6464
6465static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
6466 CXClientData client_data) {
6467 return static_cast<AnnotateTokensWorker*>(client_data)->
6468 postVisitChildren(cursor);
6469}
6470
6471namespace {
6472
6473/// \brief Uses the macro expansions in the preprocessing record to find
6474/// and mark tokens that are macro arguments. This info is used by the
6475/// AnnotateTokensWorker.
6476class MarkMacroArgTokensVisitor {
6477 SourceManager &SM;
6478 CXToken *Tokens;
6479 unsigned NumTokens;
6480 unsigned CurIdx;
6481
6482public:
6483 MarkMacroArgTokensVisitor(SourceManager &SM,
6484 CXToken *tokens, unsigned numTokens)
6485 : SM(SM), Tokens(tokens), NumTokens(numTokens), CurIdx(0) { }
6486
6487 CXChildVisitResult visit(CXCursor cursor, CXCursor parent) {
6488 if (cursor.kind != CXCursor_MacroExpansion)
6489 return CXChildVisit_Continue;
6490
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006491 SourceRange macroRange = getCursorMacroExpansion(cursor).getSourceRange();
Guy Benyei11169dd2012-12-18 14:30:41 +00006492 if (macroRange.getBegin() == macroRange.getEnd())
6493 return CXChildVisit_Continue; // it's not a function macro.
6494
6495 for (; CurIdx < NumTokens; ++CurIdx) {
6496 if (!SM.isBeforeInTranslationUnit(getTokenLoc(CurIdx),
6497 macroRange.getBegin()))
6498 break;
6499 }
6500
6501 if (CurIdx == NumTokens)
6502 return CXChildVisit_Break;
6503
6504 for (; CurIdx < NumTokens; ++CurIdx) {
6505 SourceLocation tokLoc = getTokenLoc(CurIdx);
6506 if (!SM.isBeforeInTranslationUnit(tokLoc, macroRange.getEnd()))
6507 break;
6508
6509 setFunctionMacroTokenLoc(CurIdx, SM.getMacroArgExpandedLocation(tokLoc));
6510 }
6511
6512 if (CurIdx == NumTokens)
6513 return CXChildVisit_Break;
6514
6515 return CXChildVisit_Continue;
6516 }
6517
6518private:
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00006519 CXToken &getTok(unsigned Idx) {
6520 assert(Idx < NumTokens);
6521 return Tokens[Idx];
6522 }
6523 const CXToken &getTok(unsigned Idx) const {
6524 assert(Idx < NumTokens);
6525 return Tokens[Idx];
6526 }
6527
Guy Benyei11169dd2012-12-18 14:30:41 +00006528 SourceLocation getTokenLoc(unsigned tokI) {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00006529 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[1]);
Guy Benyei11169dd2012-12-18 14:30:41 +00006530 }
6531
6532 void setFunctionMacroTokenLoc(unsigned tokI, SourceLocation loc) {
6533 // The third field is reserved and currently not used. Use it here
6534 // to mark macro arg expanded tokens with their expanded locations.
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00006535 getTok(tokI).int_data[3] = loc.getRawEncoding();
Guy Benyei11169dd2012-12-18 14:30:41 +00006536 }
6537};
6538
6539} // end anonymous namespace
6540
6541static CXChildVisitResult
6542MarkMacroArgTokensVisitorDelegate(CXCursor cursor, CXCursor parent,
6543 CXClientData client_data) {
6544 return static_cast<MarkMacroArgTokensVisitor*>(client_data)->visit(cursor,
6545 parent);
6546}
6547
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006548/// \brief Used by \c annotatePreprocessorTokens.
6549/// \returns true if lexing was finished, false otherwise.
6550static bool lexNext(Lexer &Lex, Token &Tok,
6551 unsigned &NextIdx, unsigned NumTokens) {
6552 if (NextIdx >= NumTokens)
6553 return true;
6554
6555 ++NextIdx;
6556 Lex.LexFromRawLexer(Tok);
Alexander Kornienko1a9f1842015-12-28 15:24:08 +00006557 return Tok.is(tok::eof);
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006558}
6559
Guy Benyei11169dd2012-12-18 14:30:41 +00006560static void annotatePreprocessorTokens(CXTranslationUnit TU,
6561 SourceRange RegionOfInterest,
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006562 CXCursor *Cursors,
6563 CXToken *Tokens,
6564 unsigned NumTokens) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006565 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00006566
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006567 Preprocessor &PP = CXXUnit->getPreprocessor();
Guy Benyei11169dd2012-12-18 14:30:41 +00006568 SourceManager &SourceMgr = CXXUnit->getSourceManager();
6569 std::pair<FileID, unsigned> BeginLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00006570 = SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getBegin());
Guy Benyei11169dd2012-12-18 14:30:41 +00006571 std::pair<FileID, unsigned> EndLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00006572 = SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getEnd());
Guy Benyei11169dd2012-12-18 14:30:41 +00006573
6574 if (BeginLocInfo.first != EndLocInfo.first)
6575 return;
6576
6577 StringRef Buffer;
6578 bool Invalid = false;
6579 Buffer = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
6580 if (Buffer.empty() || Invalid)
6581 return;
6582
6583 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
6584 CXXUnit->getASTContext().getLangOpts(),
6585 Buffer.begin(), Buffer.data() + BeginLocInfo.second,
6586 Buffer.end());
6587 Lex.SetCommentRetentionState(true);
6588
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006589 unsigned NextIdx = 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00006590 // Lex tokens in raw mode until we hit the end of the range, to avoid
6591 // entering #includes or expanding macros.
6592 while (true) {
6593 Token Tok;
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006594 if (lexNext(Lex, Tok, NextIdx, NumTokens))
6595 break;
6596 unsigned TokIdx = NextIdx-1;
6597 assert(Tok.getLocation() ==
6598 SourceLocation::getFromRawEncoding(Tokens[TokIdx].int_data[1]));
Guy Benyei11169dd2012-12-18 14:30:41 +00006599
6600 reprocess:
6601 if (Tok.is(tok::hash) && Tok.isAtStartOfLine()) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006602 // We have found a preprocessing directive. Annotate the tokens
6603 // appropriately.
Guy Benyei11169dd2012-12-18 14:30:41 +00006604 //
6605 // FIXME: Some simple tests here could identify macro definitions and
6606 // #undefs, to provide specific cursor kinds for those.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006607
6608 SourceLocation BeginLoc = Tok.getLocation();
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006609 if (lexNext(Lex, Tok, NextIdx, NumTokens))
6610 break;
6611
Craig Topper69186e72014-06-08 08:38:04 +00006612 MacroInfo *MI = nullptr;
Alp Toker2d57cea2014-05-17 04:53:25 +00006613 if (Tok.is(tok::raw_identifier) && Tok.getRawIdentifier() == "define") {
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006614 if (lexNext(Lex, Tok, NextIdx, NumTokens))
6615 break;
6616
6617 if (Tok.is(tok::raw_identifier)) {
Alp Toker2d57cea2014-05-17 04:53:25 +00006618 IdentifierInfo &II =
6619 PP.getIdentifierTable().get(Tok.getRawIdentifier());
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006620 SourceLocation MappedTokLoc =
6621 CXXUnit->mapLocationToPreamble(Tok.getLocation());
6622 MI = getMacroInfo(II, MappedTokLoc, TU);
6623 }
6624 }
6625
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006626 bool finished = false;
Guy Benyei11169dd2012-12-18 14:30:41 +00006627 do {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006628 if (lexNext(Lex, Tok, NextIdx, NumTokens)) {
6629 finished = true;
6630 break;
6631 }
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006632 // If we are in a macro definition, check if the token was ever a
6633 // macro name and annotate it if that's the case.
6634 if (MI) {
6635 SourceLocation SaveLoc = Tok.getLocation();
6636 Tok.setLocation(CXXUnit->mapLocationToPreamble(SaveLoc));
Richard Smith66a81862015-05-04 02:25:31 +00006637 MacroDefinitionRecord *MacroDef =
6638 checkForMacroInMacroDefinition(MI, Tok, TU);
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006639 Tok.setLocation(SaveLoc);
6640 if (MacroDef)
Richard Smith66a81862015-05-04 02:25:31 +00006641 Cursors[NextIdx - 1] =
6642 MakeMacroExpansionCursor(MacroDef, Tok.getLocation(), TU);
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006643 }
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006644 } while (!Tok.isAtStartOfLine());
6645
6646 unsigned LastIdx = finished ? NextIdx-1 : NextIdx-2;
6647 assert(TokIdx <= LastIdx);
6648 SourceLocation EndLoc =
6649 SourceLocation::getFromRawEncoding(Tokens[LastIdx].int_data[1]);
6650 CXCursor Cursor =
6651 MakePreprocessingDirectiveCursor(SourceRange(BeginLoc, EndLoc), TU);
6652
6653 for (; TokIdx <= LastIdx; ++TokIdx)
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006654 updateCursorAnnotation(Cursors[TokIdx], Cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00006655
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006656 if (finished)
6657 break;
6658 goto reprocess;
Guy Benyei11169dd2012-12-18 14:30:41 +00006659 }
Guy Benyei11169dd2012-12-18 14:30:41 +00006660 }
6661}
6662
6663// This gets run a separate thread to avoid stack blowout.
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00006664static void clang_annotateTokensImpl(CXTranslationUnit TU, ASTUnit *CXXUnit,
6665 CXToken *Tokens, unsigned NumTokens,
6666 CXCursor *Cursors) {
Dmitri Gribenko183436e2013-01-26 21:49:50 +00006667 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00006668 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
6669 setThreadBackgroundPriority();
6670
6671 // Determine the region of interest, which contains all of the tokens.
6672 SourceRange RegionOfInterest;
6673 RegionOfInterest.setBegin(
6674 cxloc::translateSourceLocation(clang_getTokenLocation(TU, Tokens[0])));
6675 RegionOfInterest.setEnd(
6676 cxloc::translateSourceLocation(clang_getTokenLocation(TU,
6677 Tokens[NumTokens-1])));
6678
Guy Benyei11169dd2012-12-18 14:30:41 +00006679 // Relex the tokens within the source range to look for preprocessing
6680 // directives.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006681 annotatePreprocessorTokens(TU, RegionOfInterest, Cursors, Tokens, NumTokens);
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00006682
6683 // If begin location points inside a macro argument, set it to the expansion
6684 // location so we can have the full context when annotating semantically.
6685 {
6686 SourceManager &SM = CXXUnit->getSourceManager();
6687 SourceLocation Loc =
6688 SM.getMacroArgExpandedLocation(RegionOfInterest.getBegin());
6689 if (Loc.isMacroID())
6690 RegionOfInterest.setBegin(SM.getExpansionLoc(Loc));
6691 }
6692
Guy Benyei11169dd2012-12-18 14:30:41 +00006693 if (CXXUnit->getPreprocessor().getPreprocessingRecord()) {
6694 // Search and mark tokens that are macro argument expansions.
6695 MarkMacroArgTokensVisitor Visitor(CXXUnit->getSourceManager(),
6696 Tokens, NumTokens);
6697 CursorVisitor MacroArgMarker(TU,
6698 MarkMacroArgTokensVisitorDelegate, &Visitor,
6699 /*VisitPreprocessorLast=*/true,
6700 /*VisitIncludedEntities=*/false,
6701 RegionOfInterest);
6702 MacroArgMarker.visitPreprocessedEntitiesInRegion();
6703 }
6704
6705 // Annotate all of the source locations in the region of interest that map to
6706 // a specific cursor.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006707 AnnotateTokensWorker W(Tokens, Cursors, NumTokens, TU, RegionOfInterest);
Guy Benyei11169dd2012-12-18 14:30:41 +00006708
6709 // FIXME: We use a ridiculous stack size here because the data-recursion
6710 // algorithm uses a large stack frame than the non-data recursive version,
6711 // and AnnotationTokensWorker currently transforms the data-recursion
6712 // algorithm back into a traditional recursion by explicitly calling
6713 // VisitChildren(). We will need to remove this explicit recursive call.
6714 W.AnnotateTokens();
6715
6716 // If we ran into any entities that involve context-sensitive keywords,
6717 // take another pass through the tokens to mark them as such.
6718 if (W.hasContextSensitiveKeywords()) {
6719 for (unsigned I = 0; I != NumTokens; ++I) {
6720 if (clang_getTokenKind(Tokens[I]) != CXToken_Identifier)
6721 continue;
6722
6723 if (Cursors[I].kind == CXCursor_ObjCPropertyDecl) {
6724 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006725 if (const ObjCPropertyDecl *Property
Guy Benyei11169dd2012-12-18 14:30:41 +00006726 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(Cursors[I]))) {
6727 if (Property->getPropertyAttributesAsWritten() != 0 &&
6728 llvm::StringSwitch<bool>(II->getName())
6729 .Case("readonly", true)
6730 .Case("assign", true)
6731 .Case("unsafe_unretained", true)
6732 .Case("readwrite", true)
6733 .Case("retain", true)
6734 .Case("copy", true)
6735 .Case("nonatomic", true)
6736 .Case("atomic", true)
6737 .Case("getter", true)
6738 .Case("setter", true)
6739 .Case("strong", true)
6740 .Case("weak", true)
6741 .Default(false))
6742 Tokens[I].int_data[0] = CXToken_Keyword;
6743 }
6744 continue;
6745 }
6746
6747 if (Cursors[I].kind == CXCursor_ObjCInstanceMethodDecl ||
6748 Cursors[I].kind == CXCursor_ObjCClassMethodDecl) {
6749 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
6750 if (llvm::StringSwitch<bool>(II->getName())
6751 .Case("in", true)
6752 .Case("out", true)
6753 .Case("inout", true)
6754 .Case("oneway", true)
6755 .Case("bycopy", true)
6756 .Case("byref", true)
6757 .Default(false))
6758 Tokens[I].int_data[0] = CXToken_Keyword;
6759 continue;
6760 }
6761
6762 if (Cursors[I].kind == CXCursor_CXXFinalAttr ||
6763 Cursors[I].kind == CXCursor_CXXOverrideAttr) {
6764 Tokens[I].int_data[0] = CXToken_Keyword;
6765 continue;
6766 }
6767 }
6768 }
6769}
6770
6771extern "C" {
6772
6773void clang_annotateTokens(CXTranslationUnit TU,
6774 CXToken *Tokens, unsigned NumTokens,
6775 CXCursor *Cursors) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006776 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006777 LOG_BAD_TU(TU);
6778 return;
6779 }
6780 if (NumTokens == 0 || !Tokens || !Cursors) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006781 LOG_FUNC_SECTION { *Log << "<null input>"; }
Guy Benyei11169dd2012-12-18 14:30:41 +00006782 return;
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006783 }
6784
6785 LOG_FUNC_SECTION {
6786 *Log << TU << ' ';
6787 CXSourceLocation bloc = clang_getTokenLocation(TU, Tokens[0]);
6788 CXSourceLocation eloc = clang_getTokenLocation(TU, Tokens[NumTokens-1]);
6789 *Log << clang_getRange(bloc, eloc);
6790 }
Guy Benyei11169dd2012-12-18 14:30:41 +00006791
6792 // Any token we don't specifically annotate will have a NULL cursor.
6793 CXCursor C = clang_getNullCursor();
6794 for (unsigned I = 0; I != NumTokens; ++I)
6795 Cursors[I] = C;
6796
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006797 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00006798 if (!CXXUnit)
6799 return;
6800
6801 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00006802
6803 auto AnnotateTokensImpl = [=]() {
6804 clang_annotateTokensImpl(TU, CXXUnit, Tokens, NumTokens, Cursors);
6805 };
Guy Benyei11169dd2012-12-18 14:30:41 +00006806 llvm::CrashRecoveryContext CRC;
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00006807 if (!RunSafely(CRC, AnnotateTokensImpl, GetSafetyThreadStackSize() * 2)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00006808 fprintf(stderr, "libclang: crash detected while annotating tokens\n");
6809 }
6810}
6811
6812} // end: extern "C"
6813
6814//===----------------------------------------------------------------------===//
6815// Operations for querying linkage of a cursor.
6816//===----------------------------------------------------------------------===//
6817
6818extern "C" {
6819CXLinkageKind clang_getCursorLinkage(CXCursor cursor) {
6820 if (!clang_isDeclaration(cursor.kind))
6821 return CXLinkage_Invalid;
6822
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006823 const Decl *D = cxcursor::getCursorDecl(cursor);
6824 if (const NamedDecl *ND = dyn_cast_or_null<NamedDecl>(D))
Rafael Espindola3ae00052013-05-13 00:12:11 +00006825 switch (ND->getLinkageInternal()) {
Rafael Espindola50df3a02013-05-25 17:16:20 +00006826 case NoLinkage:
6827 case VisibleNoLinkage: return CXLinkage_NoLinkage;
Guy Benyei11169dd2012-12-18 14:30:41 +00006828 case InternalLinkage: return CXLinkage_Internal;
6829 case UniqueExternalLinkage: return CXLinkage_UniqueExternal;
6830 case ExternalLinkage: return CXLinkage_External;
6831 };
6832
6833 return CXLinkage_Invalid;
6834}
6835} // end: extern "C"
6836
6837//===----------------------------------------------------------------------===//
Ehsan Akhgari93697fa2015-11-23 19:56:46 +00006838// Operations for querying visibility of a cursor.
6839//===----------------------------------------------------------------------===//
6840
6841extern "C" {
6842CXVisibilityKind clang_getCursorVisibility(CXCursor cursor) {
6843 if (!clang_isDeclaration(cursor.kind))
6844 return CXVisibility_Invalid;
6845
6846 const Decl *D = cxcursor::getCursorDecl(cursor);
6847 if (const NamedDecl *ND = dyn_cast_or_null<NamedDecl>(D))
6848 switch (ND->getVisibility()) {
6849 case HiddenVisibility: return CXVisibility_Hidden;
6850 case ProtectedVisibility: return CXVisibility_Protected;
6851 case DefaultVisibility: return CXVisibility_Default;
6852 };
6853
6854 return CXVisibility_Invalid;
6855}
6856} // end: extern "C"
6857
6858//===----------------------------------------------------------------------===//
Guy Benyei11169dd2012-12-18 14:30:41 +00006859// Operations for querying language of a cursor.
6860//===----------------------------------------------------------------------===//
6861
6862static CXLanguageKind getDeclLanguage(const Decl *D) {
6863 if (!D)
6864 return CXLanguage_C;
6865
6866 switch (D->getKind()) {
6867 default:
6868 break;
6869 case Decl::ImplicitParam:
6870 case Decl::ObjCAtDefsField:
6871 case Decl::ObjCCategory:
6872 case Decl::ObjCCategoryImpl:
6873 case Decl::ObjCCompatibleAlias:
6874 case Decl::ObjCImplementation:
6875 case Decl::ObjCInterface:
6876 case Decl::ObjCIvar:
6877 case Decl::ObjCMethod:
6878 case Decl::ObjCProperty:
6879 case Decl::ObjCPropertyImpl:
6880 case Decl::ObjCProtocol:
Douglas Gregor85f3f952015-07-07 03:57:15 +00006881 case Decl::ObjCTypeParam:
Guy Benyei11169dd2012-12-18 14:30:41 +00006882 return CXLanguage_ObjC;
6883 case Decl::CXXConstructor:
6884 case Decl::CXXConversion:
6885 case Decl::CXXDestructor:
6886 case Decl::CXXMethod:
6887 case Decl::CXXRecord:
6888 case Decl::ClassTemplate:
6889 case Decl::ClassTemplatePartialSpecialization:
6890 case Decl::ClassTemplateSpecialization:
6891 case Decl::Friend:
6892 case Decl::FriendTemplate:
6893 case Decl::FunctionTemplate:
6894 case Decl::LinkageSpec:
6895 case Decl::Namespace:
6896 case Decl::NamespaceAlias:
6897 case Decl::NonTypeTemplateParm:
6898 case Decl::StaticAssert:
6899 case Decl::TemplateTemplateParm:
6900 case Decl::TemplateTypeParm:
6901 case Decl::UnresolvedUsingTypename:
6902 case Decl::UnresolvedUsingValue:
6903 case Decl::Using:
6904 case Decl::UsingDirective:
6905 case Decl::UsingShadow:
6906 return CXLanguage_CPlusPlus;
6907 }
6908
6909 return CXLanguage_C;
6910}
6911
6912extern "C" {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006913
6914static CXAvailabilityKind getCursorAvailabilityForDecl(const Decl *D) {
6915 if (isa<FunctionDecl>(D) && cast<FunctionDecl>(D)->isDeleted())
Manuel Klimek8e3a7ed2015-09-25 17:53:16 +00006916 return CXAvailability_NotAvailable;
Guy Benyei11169dd2012-12-18 14:30:41 +00006917
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006918 switch (D->getAvailability()) {
6919 case AR_Available:
6920 case AR_NotYetIntroduced:
6921 if (const EnumConstantDecl *EnumConst = dyn_cast<EnumConstantDecl>(D))
Benjamin Kramer656363d2013-10-15 18:53:18 +00006922 return getCursorAvailabilityForDecl(
6923 cast<Decl>(EnumConst->getDeclContext()));
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006924 return CXAvailability_Available;
6925
6926 case AR_Deprecated:
6927 return CXAvailability_Deprecated;
6928
6929 case AR_Unavailable:
6930 return CXAvailability_NotAvailable;
6931 }
Benjamin Kramer656363d2013-10-15 18:53:18 +00006932
6933 llvm_unreachable("Unknown availability kind!");
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006934}
6935
Guy Benyei11169dd2012-12-18 14:30:41 +00006936enum CXAvailabilityKind clang_getCursorAvailability(CXCursor cursor) {
6937 if (clang_isDeclaration(cursor.kind))
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006938 if (const Decl *D = cxcursor::getCursorDecl(cursor))
6939 return getCursorAvailabilityForDecl(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00006940
6941 return CXAvailability_Available;
6942}
6943
6944static CXVersion convertVersion(VersionTuple In) {
6945 CXVersion Out = { -1, -1, -1 };
6946 if (In.empty())
6947 return Out;
6948
6949 Out.Major = In.getMajor();
6950
NAKAMURA Takumic2b5d1f2013-02-21 02:32:34 +00006951 Optional<unsigned> Minor = In.getMinor();
6952 if (Minor.hasValue())
Guy Benyei11169dd2012-12-18 14:30:41 +00006953 Out.Minor = *Minor;
6954 else
6955 return Out;
6956
NAKAMURA Takumic2b5d1f2013-02-21 02:32:34 +00006957 Optional<unsigned> Subminor = In.getSubminor();
6958 if (Subminor.hasValue())
Guy Benyei11169dd2012-12-18 14:30:41 +00006959 Out.Subminor = *Subminor;
6960
6961 return Out;
6962}
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006963
6964static int getCursorPlatformAvailabilityForDecl(const Decl *D,
6965 int *always_deprecated,
6966 CXString *deprecated_message,
6967 int *always_unavailable,
6968 CXString *unavailable_message,
6969 CXPlatformAvailability *availability,
6970 int availability_size) {
6971 bool HadAvailAttr = false;
6972 int N = 0;
Aaron Ballmanb97112e2014-03-08 22:19:01 +00006973 for (auto A : D->attrs()) {
6974 if (DeprecatedAttr *Deprecated = dyn_cast<DeprecatedAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006975 HadAvailAttr = true;
6976 if (always_deprecated)
6977 *always_deprecated = 1;
Nico Weberaacf0312014-04-24 05:16:45 +00006978 if (deprecated_message) {
Argyrios Kyrtzidisedfe07f2014-04-24 06:05:40 +00006979 clang_disposeString(*deprecated_message);
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006980 *deprecated_message = cxstring::createDup(Deprecated->getMessage());
Nico Weberaacf0312014-04-24 05:16:45 +00006981 }
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006982 continue;
6983 }
6984
Aaron Ballmanb97112e2014-03-08 22:19:01 +00006985 if (UnavailableAttr *Unavailable = dyn_cast<UnavailableAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006986 HadAvailAttr = true;
6987 if (always_unavailable)
6988 *always_unavailable = 1;
6989 if (unavailable_message) {
Argyrios Kyrtzidisedfe07f2014-04-24 06:05:40 +00006990 clang_disposeString(*unavailable_message);
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006991 *unavailable_message = cxstring::createDup(Unavailable->getMessage());
6992 }
6993 continue;
6994 }
6995
Aaron Ballmanb97112e2014-03-08 22:19:01 +00006996 if (AvailabilityAttr *Avail = dyn_cast<AvailabilityAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006997 HadAvailAttr = true;
6998 if (N < availability_size) {
6999 availability[N].Platform
7000 = cxstring::createDup(Avail->getPlatform()->getName());
7001 availability[N].Introduced = convertVersion(Avail->getIntroduced());
7002 availability[N].Deprecated = convertVersion(Avail->getDeprecated());
7003 availability[N].Obsoleted = convertVersion(Avail->getObsoleted());
7004 availability[N].Unavailable = Avail->getUnavailable();
7005 availability[N].Message = cxstring::createDup(Avail->getMessage());
7006 }
7007 ++N;
7008 }
7009 }
7010
7011 if (!HadAvailAttr)
7012 if (const EnumConstantDecl *EnumConst = dyn_cast<EnumConstantDecl>(D))
7013 return getCursorPlatformAvailabilityForDecl(
7014 cast<Decl>(EnumConst->getDeclContext()),
7015 always_deprecated,
7016 deprecated_message,
7017 always_unavailable,
7018 unavailable_message,
7019 availability,
7020 availability_size);
Guy Benyei11169dd2012-12-18 14:30:41 +00007021
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00007022 return N;
7023}
7024
Guy Benyei11169dd2012-12-18 14:30:41 +00007025int clang_getCursorPlatformAvailability(CXCursor cursor,
7026 int *always_deprecated,
7027 CXString *deprecated_message,
7028 int *always_unavailable,
7029 CXString *unavailable_message,
7030 CXPlatformAvailability *availability,
7031 int availability_size) {
7032 if (always_deprecated)
7033 *always_deprecated = 0;
7034 if (deprecated_message)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00007035 *deprecated_message = cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00007036 if (always_unavailable)
7037 *always_unavailable = 0;
7038 if (unavailable_message)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00007039 *unavailable_message = cxstring::createEmpty();
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00007040
Guy Benyei11169dd2012-12-18 14:30:41 +00007041 if (!clang_isDeclaration(cursor.kind))
7042 return 0;
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00007043
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00007044 const Decl *D = cxcursor::getCursorDecl(cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00007045 if (!D)
7046 return 0;
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00007047
7048 return getCursorPlatformAvailabilityForDecl(D, always_deprecated,
7049 deprecated_message,
7050 always_unavailable,
7051 unavailable_message,
7052 availability,
7053 availability_size);
Guy Benyei11169dd2012-12-18 14:30:41 +00007054}
7055
7056void clang_disposeCXPlatformAvailability(CXPlatformAvailability *availability) {
7057 clang_disposeString(availability->Platform);
7058 clang_disposeString(availability->Message);
7059}
7060
7061CXLanguageKind clang_getCursorLanguage(CXCursor cursor) {
7062 if (clang_isDeclaration(cursor.kind))
7063 return getDeclLanguage(cxcursor::getCursorDecl(cursor));
7064
7065 return CXLanguage_Invalid;
7066}
7067
7068 /// \brief If the given cursor is the "templated" declaration
7069 /// descibing a class or function template, return the class or
7070 /// function template.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00007071static const Decl *maybeGetTemplateCursor(const Decl *D) {
Guy Benyei11169dd2012-12-18 14:30:41 +00007072 if (!D)
Craig Topper69186e72014-06-08 08:38:04 +00007073 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00007074
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00007075 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00007076 if (FunctionTemplateDecl *FunTmpl = FD->getDescribedFunctionTemplate())
7077 return FunTmpl;
7078
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00007079 if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00007080 if (ClassTemplateDecl *ClassTmpl = RD->getDescribedClassTemplate())
7081 return ClassTmpl;
7082
7083 return D;
7084}
7085
Argyrios Kyrtzidis4e0854f2014-10-15 17:05:31 +00007086
7087enum CX_StorageClass clang_Cursor_getStorageClass(CXCursor C) {
7088 StorageClass sc = SC_None;
7089 const Decl *D = getCursorDecl(C);
7090 if (D) {
7091 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
7092 sc = FD->getStorageClass();
7093 } else if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
7094 sc = VD->getStorageClass();
7095 } else {
7096 return CX_SC_Invalid;
7097 }
7098 } else {
7099 return CX_SC_Invalid;
7100 }
7101 switch (sc) {
7102 case SC_None:
7103 return CX_SC_None;
7104 case SC_Extern:
7105 return CX_SC_Extern;
7106 case SC_Static:
7107 return CX_SC_Static;
7108 case SC_PrivateExtern:
7109 return CX_SC_PrivateExtern;
Argyrios Kyrtzidis4e0854f2014-10-15 17:05:31 +00007110 case SC_Auto:
7111 return CX_SC_Auto;
7112 case SC_Register:
7113 return CX_SC_Register;
Argyrios Kyrtzidis4e0854f2014-10-15 17:05:31 +00007114 }
Kaelyn Takataab61e702014-10-15 18:03:26 +00007115 llvm_unreachable("Unhandled storage class!");
Argyrios Kyrtzidis4e0854f2014-10-15 17:05:31 +00007116}
7117
Guy Benyei11169dd2012-12-18 14:30:41 +00007118CXCursor clang_getCursorSemanticParent(CXCursor cursor) {
7119 if (clang_isDeclaration(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00007120 if (const Decl *D = getCursorDecl(cursor)) {
7121 const DeclContext *DC = D->getDeclContext();
Guy Benyei11169dd2012-12-18 14:30:41 +00007122 if (!DC)
7123 return clang_getNullCursor();
7124
7125 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
7126 getCursorTU(cursor));
7127 }
7128 }
7129
7130 if (clang_isStatement(cursor.kind) || clang_isExpression(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00007131 if (const Decl *D = getCursorDecl(cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +00007132 return MakeCXCursor(D, getCursorTU(cursor));
7133 }
7134
7135 return clang_getNullCursor();
7136}
7137
7138CXCursor clang_getCursorLexicalParent(CXCursor cursor) {
7139 if (clang_isDeclaration(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00007140 if (const Decl *D = getCursorDecl(cursor)) {
7141 const DeclContext *DC = D->getLexicalDeclContext();
Guy Benyei11169dd2012-12-18 14:30:41 +00007142 if (!DC)
7143 return clang_getNullCursor();
7144
7145 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
7146 getCursorTU(cursor));
7147 }
7148 }
7149
7150 // FIXME: Note that we can't easily compute the lexical context of a
7151 // statement or expression, so we return nothing.
7152 return clang_getNullCursor();
7153}
7154
7155CXFile clang_getIncludedFile(CXCursor cursor) {
7156 if (cursor.kind != CXCursor_InclusionDirective)
Craig Topper69186e72014-06-08 08:38:04 +00007157 return nullptr;
7158
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00007159 const InclusionDirective *ID = getCursorInclusionDirective(cursor);
Dmitri Gribenkof9304482013-01-23 15:56:07 +00007160 return const_cast<FileEntry *>(ID->getFile());
Guy Benyei11169dd2012-12-18 14:30:41 +00007161}
7162
Argyrios Kyrtzidis9adfd8a2013-04-18 22:15:49 +00007163unsigned clang_Cursor_getObjCPropertyAttributes(CXCursor C, unsigned reserved) {
7164 if (C.kind != CXCursor_ObjCPropertyDecl)
7165 return CXObjCPropertyAttr_noattr;
7166
7167 unsigned Result = CXObjCPropertyAttr_noattr;
7168 const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(getCursorDecl(C));
7169 ObjCPropertyDecl::PropertyAttributeKind Attr =
7170 PD->getPropertyAttributesAsWritten();
7171
7172#define SET_CXOBJCPROP_ATTR(A) \
7173 if (Attr & ObjCPropertyDecl::OBJC_PR_##A) \
7174 Result |= CXObjCPropertyAttr_##A
7175 SET_CXOBJCPROP_ATTR(readonly);
7176 SET_CXOBJCPROP_ATTR(getter);
7177 SET_CXOBJCPROP_ATTR(assign);
7178 SET_CXOBJCPROP_ATTR(readwrite);
7179 SET_CXOBJCPROP_ATTR(retain);
7180 SET_CXOBJCPROP_ATTR(copy);
7181 SET_CXOBJCPROP_ATTR(nonatomic);
7182 SET_CXOBJCPROP_ATTR(setter);
7183 SET_CXOBJCPROP_ATTR(atomic);
7184 SET_CXOBJCPROP_ATTR(weak);
7185 SET_CXOBJCPROP_ATTR(strong);
7186 SET_CXOBJCPROP_ATTR(unsafe_unretained);
7187#undef SET_CXOBJCPROP_ATTR
7188
7189 return Result;
7190}
7191
Argyrios Kyrtzidis9d9bc012013-04-18 23:29:12 +00007192unsigned clang_Cursor_getObjCDeclQualifiers(CXCursor C) {
7193 if (!clang_isDeclaration(C.kind))
7194 return CXObjCDeclQualifier_None;
7195
7196 Decl::ObjCDeclQualifier QT = Decl::OBJC_TQ_None;
7197 const Decl *D = getCursorDecl(C);
7198 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
7199 QT = MD->getObjCDeclQualifier();
7200 else if (const ParmVarDecl *PD = dyn_cast<ParmVarDecl>(D))
7201 QT = PD->getObjCDeclQualifier();
7202 if (QT == Decl::OBJC_TQ_None)
7203 return CXObjCDeclQualifier_None;
7204
7205 unsigned Result = CXObjCDeclQualifier_None;
7206 if (QT & Decl::OBJC_TQ_In) Result |= CXObjCDeclQualifier_In;
7207 if (QT & Decl::OBJC_TQ_Inout) Result |= CXObjCDeclQualifier_Inout;
7208 if (QT & Decl::OBJC_TQ_Out) Result |= CXObjCDeclQualifier_Out;
7209 if (QT & Decl::OBJC_TQ_Bycopy) Result |= CXObjCDeclQualifier_Bycopy;
7210 if (QT & Decl::OBJC_TQ_Byref) Result |= CXObjCDeclQualifier_Byref;
7211 if (QT & Decl::OBJC_TQ_Oneway) Result |= CXObjCDeclQualifier_Oneway;
7212
7213 return Result;
7214}
7215
Argyrios Kyrtzidis7b50fc52013-07-05 20:44:37 +00007216unsigned clang_Cursor_isObjCOptional(CXCursor C) {
7217 if (!clang_isDeclaration(C.kind))
7218 return 0;
7219
7220 const Decl *D = getCursorDecl(C);
7221 if (const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(D))
7222 return PD->getPropertyImplementation() == ObjCPropertyDecl::Optional;
7223 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
7224 return MD->getImplementationControl() == ObjCMethodDecl::Optional;
7225
7226 return 0;
7227}
7228
Argyrios Kyrtzidis23814e42013-04-18 23:53:05 +00007229unsigned clang_Cursor_isVariadic(CXCursor C) {
7230 if (!clang_isDeclaration(C.kind))
7231 return 0;
7232
7233 const Decl *D = getCursorDecl(C);
7234 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
7235 return FD->isVariadic();
7236 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
7237 return MD->isVariadic();
7238
7239 return 0;
7240}
7241
Guy Benyei11169dd2012-12-18 14:30:41 +00007242CXSourceRange clang_Cursor_getCommentRange(CXCursor C) {
7243 if (!clang_isDeclaration(C.kind))
7244 return clang_getNullRange();
7245
7246 const Decl *D = getCursorDecl(C);
7247 ASTContext &Context = getCursorContext(C);
7248 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
7249 if (!RC)
7250 return clang_getNullRange();
7251
7252 return cxloc::translateSourceRange(Context, RC->getSourceRange());
7253}
7254
7255CXString clang_Cursor_getRawCommentText(CXCursor C) {
7256 if (!clang_isDeclaration(C.kind))
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00007257 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00007258
7259 const Decl *D = getCursorDecl(C);
7260 ASTContext &Context = getCursorContext(C);
7261 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
7262 StringRef RawText = RC ? RC->getRawText(Context.getSourceManager()) :
7263 StringRef();
7264
7265 // Don't duplicate the string because RawText points directly into source
7266 // code.
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00007267 return cxstring::createRef(RawText);
Guy Benyei11169dd2012-12-18 14:30:41 +00007268}
7269
7270CXString clang_Cursor_getBriefCommentText(CXCursor C) {
7271 if (!clang_isDeclaration(C.kind))
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00007272 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00007273
7274 const Decl *D = getCursorDecl(C);
7275 const ASTContext &Context = getCursorContext(C);
7276 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
7277
7278 if (RC) {
7279 StringRef BriefText = RC->getBriefText(Context);
7280
7281 // Don't duplicate the string because RawComment ensures that this memory
7282 // will not go away.
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00007283 return cxstring::createRef(BriefText);
Guy Benyei11169dd2012-12-18 14:30:41 +00007284 }
7285
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00007286 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00007287}
7288
Guy Benyei11169dd2012-12-18 14:30:41 +00007289CXModule clang_Cursor_getModule(CXCursor C) {
7290 if (C.kind == CXCursor_ModuleImportDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00007291 if (const ImportDecl *ImportD =
7292 dyn_cast_or_null<ImportDecl>(getCursorDecl(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00007293 return ImportD->getImportedModule();
7294 }
7295
Craig Topper69186e72014-06-08 08:38:04 +00007296 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00007297}
7298
Argyrios Kyrtzidisf6d49c32014-05-14 23:14:37 +00007299CXModule clang_getModuleForFile(CXTranslationUnit TU, CXFile File) {
7300 if (isNotUsableTU(TU)) {
7301 LOG_BAD_TU(TU);
7302 return nullptr;
7303 }
7304 if (!File)
7305 return nullptr;
7306 FileEntry *FE = static_cast<FileEntry *>(File);
7307
7308 ASTUnit &Unit = *cxtu::getASTUnit(TU);
7309 HeaderSearch &HS = Unit.getPreprocessor().getHeaderSearchInfo();
7310 ModuleMap::KnownHeader Header = HS.findModuleForHeader(FE);
7311
Richard Smithfeb54b62014-10-23 02:01:19 +00007312 return Header.getModule();
Argyrios Kyrtzidisf6d49c32014-05-14 23:14:37 +00007313}
7314
Argyrios Kyrtzidis12fdb9e2013-04-26 22:47:49 +00007315CXFile clang_Module_getASTFile(CXModule CXMod) {
7316 if (!CXMod)
Craig Topper69186e72014-06-08 08:38:04 +00007317 return nullptr;
Argyrios Kyrtzidis12fdb9e2013-04-26 22:47:49 +00007318 Module *Mod = static_cast<Module*>(CXMod);
7319 return const_cast<FileEntry *>(Mod->getASTFile());
7320}
7321
Guy Benyei11169dd2012-12-18 14:30:41 +00007322CXModule clang_Module_getParent(CXModule CXMod) {
7323 if (!CXMod)
Craig Topper69186e72014-06-08 08:38:04 +00007324 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00007325 Module *Mod = static_cast<Module*>(CXMod);
7326 return Mod->Parent;
7327}
7328
7329CXString clang_Module_getName(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->Name);
Guy Benyei11169dd2012-12-18 14:30:41 +00007334}
7335
7336CXString clang_Module_getFullName(CXModule CXMod) {
7337 if (!CXMod)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00007338 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00007339 Module *Mod = static_cast<Module*>(CXMod);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00007340 return cxstring::createDup(Mod->getFullModuleName());
Guy Benyei11169dd2012-12-18 14:30:41 +00007341}
7342
Argyrios Kyrtzidis884337f2014-05-15 04:44:25 +00007343int clang_Module_isSystem(CXModule CXMod) {
7344 if (!CXMod)
7345 return 0;
7346 Module *Mod = static_cast<Module*>(CXMod);
7347 return Mod->IsSystem;
7348}
7349
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00007350unsigned clang_Module_getNumTopLevelHeaders(CXTranslationUnit TU,
7351 CXModule CXMod) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00007352 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00007353 LOG_BAD_TU(TU);
7354 return 0;
7355 }
7356 if (!CXMod)
Guy Benyei11169dd2012-12-18 14:30:41 +00007357 return 0;
7358 Module *Mod = static_cast<Module*>(CXMod);
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00007359 FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
7360 ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
7361 return TopHeaders.size();
Guy Benyei11169dd2012-12-18 14:30:41 +00007362}
7363
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00007364CXFile clang_Module_getTopLevelHeader(CXTranslationUnit TU,
7365 CXModule CXMod, unsigned Index) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00007366 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00007367 LOG_BAD_TU(TU);
Craig Topper69186e72014-06-08 08:38:04 +00007368 return nullptr;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00007369 }
7370 if (!CXMod)
Craig Topper69186e72014-06-08 08:38:04 +00007371 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00007372 Module *Mod = static_cast<Module*>(CXMod);
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00007373 FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
Guy Benyei11169dd2012-12-18 14:30:41 +00007374
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00007375 ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
7376 if (Index < TopHeaders.size())
7377 return const_cast<FileEntry *>(TopHeaders[Index]);
Guy Benyei11169dd2012-12-18 14:30:41 +00007378
Craig Topper69186e72014-06-08 08:38:04 +00007379 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00007380}
7381
7382} // end: extern "C"
7383
7384//===----------------------------------------------------------------------===//
7385// C++ AST instrospection.
7386//===----------------------------------------------------------------------===//
7387
7388extern "C" {
Saleem Abdulrasool6ea75db2015-10-27 15:50:22 +00007389unsigned clang_CXXField_isMutable(CXCursor C) {
7390 if (!clang_isDeclaration(C.kind))
7391 return 0;
7392
7393 if (const auto D = cxcursor::getCursorDecl(C))
7394 if (const auto FD = dyn_cast_or_null<FieldDecl>(D))
7395 return FD->isMutable() ? 1 : 0;
7396 return 0;
7397}
7398
Dmitri Gribenko62770be2013-05-17 18:38:35 +00007399unsigned clang_CXXMethod_isPureVirtual(CXCursor C) {
7400 if (!clang_isDeclaration(C.kind))
7401 return 0;
7402
Dmitri Gribenko62770be2013-05-17 18:38:35 +00007403 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00007404 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00007405 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Dmitri Gribenko62770be2013-05-17 18:38:35 +00007406 return (Method && Method->isVirtual() && Method->isPure()) ? 1 : 0;
7407}
7408
Dmitri Gribenkoe570ede2014-04-07 14:59:13 +00007409unsigned clang_CXXMethod_isConst(CXCursor C) {
7410 if (!clang_isDeclaration(C.kind))
7411 return 0;
7412
7413 const Decl *D = cxcursor::getCursorDecl(C);
7414 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00007415 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Dmitri Gribenkoe570ede2014-04-07 14:59:13 +00007416 return (Method && (Method->getTypeQualifiers() & Qualifiers::Const)) ? 1 : 0;
7417}
7418
Guy Benyei11169dd2012-12-18 14:30:41 +00007419unsigned clang_CXXMethod_isStatic(CXCursor C) {
7420 if (!clang_isDeclaration(C.kind))
7421 return 0;
7422
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00007423 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00007424 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00007425 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00007426 return (Method && Method->isStatic()) ? 1 : 0;
7427}
7428
7429unsigned clang_CXXMethod_isVirtual(CXCursor C) {
7430 if (!clang_isDeclaration(C.kind))
7431 return 0;
7432
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00007433 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00007434 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00007435 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00007436 return (Method && Method->isVirtual()) ? 1 : 0;
7437}
7438} // end: extern "C"
7439
7440//===----------------------------------------------------------------------===//
7441// Attribute introspection.
7442//===----------------------------------------------------------------------===//
7443
7444extern "C" {
7445CXType clang_getIBOutletCollectionType(CXCursor C) {
7446 if (C.kind != CXCursor_IBOutletCollectionAttr)
7447 return cxtype::MakeCXType(QualType(), cxcursor::getCursorTU(C));
7448
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00007449 const IBOutletCollectionAttr *A =
Guy Benyei11169dd2012-12-18 14:30:41 +00007450 cast<IBOutletCollectionAttr>(cxcursor::getCursorAttr(C));
7451
7452 return cxtype::MakeCXType(A->getInterface(), cxcursor::getCursorTU(C));
7453}
7454} // end: extern "C"
7455
7456//===----------------------------------------------------------------------===//
7457// Inspecting memory usage.
7458//===----------------------------------------------------------------------===//
7459
7460typedef std::vector<CXTUResourceUsageEntry> MemUsageEntries;
7461
7462static inline void createCXTUResourceUsageEntry(MemUsageEntries &entries,
7463 enum CXTUResourceUsageKind k,
7464 unsigned long amount) {
7465 CXTUResourceUsageEntry entry = { k, amount };
7466 entries.push_back(entry);
7467}
7468
7469extern "C" {
7470
7471const char *clang_getTUResourceUsageName(CXTUResourceUsageKind kind) {
7472 const char *str = "";
7473 switch (kind) {
7474 case CXTUResourceUsage_AST:
7475 str = "ASTContext: expressions, declarations, and types";
7476 break;
7477 case CXTUResourceUsage_Identifiers:
7478 str = "ASTContext: identifiers";
7479 break;
7480 case CXTUResourceUsage_Selectors:
7481 str = "ASTContext: selectors";
7482 break;
7483 case CXTUResourceUsage_GlobalCompletionResults:
7484 str = "Code completion: cached global results";
7485 break;
7486 case CXTUResourceUsage_SourceManagerContentCache:
7487 str = "SourceManager: content cache allocator";
7488 break;
7489 case CXTUResourceUsage_AST_SideTables:
7490 str = "ASTContext: side tables";
7491 break;
7492 case CXTUResourceUsage_SourceManager_Membuffer_Malloc:
7493 str = "SourceManager: malloc'ed memory buffers";
7494 break;
7495 case CXTUResourceUsage_SourceManager_Membuffer_MMap:
7496 str = "SourceManager: mmap'ed memory buffers";
7497 break;
7498 case CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc:
7499 str = "ExternalASTSource: malloc'ed memory buffers";
7500 break;
7501 case CXTUResourceUsage_ExternalASTSource_Membuffer_MMap:
7502 str = "ExternalASTSource: mmap'ed memory buffers";
7503 break;
7504 case CXTUResourceUsage_Preprocessor:
7505 str = "Preprocessor: malloc'ed memory";
7506 break;
7507 case CXTUResourceUsage_PreprocessingRecord:
7508 str = "Preprocessor: PreprocessingRecord";
7509 break;
7510 case CXTUResourceUsage_SourceManager_DataStructures:
7511 str = "SourceManager: data structures and tables";
7512 break;
7513 case CXTUResourceUsage_Preprocessor_HeaderSearch:
7514 str = "Preprocessor: header search tables";
7515 break;
7516 }
7517 return str;
7518}
7519
7520CXTUResourceUsage clang_getCXTUResourceUsage(CXTranslationUnit TU) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00007521 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00007522 LOG_BAD_TU(TU);
Craig Topper69186e72014-06-08 08:38:04 +00007523 CXTUResourceUsage usage = { (void*) nullptr, 0, nullptr };
Guy Benyei11169dd2012-12-18 14:30:41 +00007524 return usage;
7525 }
7526
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007527 ASTUnit *astUnit = cxtu::getASTUnit(TU);
Ahmed Charlesb8984322014-03-07 20:03:18 +00007528 std::unique_ptr<MemUsageEntries> entries(new MemUsageEntries());
Guy Benyei11169dd2012-12-18 14:30:41 +00007529 ASTContext &astContext = astUnit->getASTContext();
7530
7531 // How much memory is used by AST nodes and types?
7532 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST,
7533 (unsigned long) astContext.getASTAllocatedMemory());
7534
7535 // How much memory is used by identifiers?
7536 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Identifiers,
7537 (unsigned long) astContext.Idents.getAllocator().getTotalMemory());
7538
7539 // How much memory is used for selectors?
7540 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Selectors,
7541 (unsigned long) astContext.Selectors.getTotalMemory());
7542
7543 // How much memory is used by ASTContext's side tables?
7544 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST_SideTables,
7545 (unsigned long) astContext.getSideTableAllocatedMemory());
7546
7547 // How much memory is used for caching global code completion results?
7548 unsigned long completionBytes = 0;
7549 if (GlobalCodeCompletionAllocator *completionAllocator =
Alp Tokerf994cef2014-07-05 03:08:06 +00007550 astUnit->getCachedCompletionAllocator().get()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00007551 completionBytes = completionAllocator->getTotalMemory();
7552 }
7553 createCXTUResourceUsageEntry(*entries,
7554 CXTUResourceUsage_GlobalCompletionResults,
7555 completionBytes);
7556
7557 // How much memory is being used by SourceManager's content cache?
7558 createCXTUResourceUsageEntry(*entries,
7559 CXTUResourceUsage_SourceManagerContentCache,
7560 (unsigned long) astContext.getSourceManager().getContentCacheSize());
7561
7562 // How much memory is being used by the MemoryBuffer's in SourceManager?
7563 const SourceManager::MemoryBufferSizes &srcBufs =
7564 astUnit->getSourceManager().getMemoryBufferSizes();
7565
7566 createCXTUResourceUsageEntry(*entries,
7567 CXTUResourceUsage_SourceManager_Membuffer_Malloc,
7568 (unsigned long) srcBufs.malloc_bytes);
7569 createCXTUResourceUsageEntry(*entries,
7570 CXTUResourceUsage_SourceManager_Membuffer_MMap,
7571 (unsigned long) srcBufs.mmap_bytes);
7572 createCXTUResourceUsageEntry(*entries,
7573 CXTUResourceUsage_SourceManager_DataStructures,
7574 (unsigned long) astContext.getSourceManager()
7575 .getDataStructureSizes());
7576
7577 // How much memory is being used by the ExternalASTSource?
7578 if (ExternalASTSource *esrc = astContext.getExternalSource()) {
7579 const ExternalASTSource::MemoryBufferSizes &sizes =
7580 esrc->getMemoryBufferSizes();
7581
7582 createCXTUResourceUsageEntry(*entries,
7583 CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc,
7584 (unsigned long) sizes.malloc_bytes);
7585 createCXTUResourceUsageEntry(*entries,
7586 CXTUResourceUsage_ExternalASTSource_Membuffer_MMap,
7587 (unsigned long) sizes.mmap_bytes);
7588 }
7589
7590 // How much memory is being used by the Preprocessor?
7591 Preprocessor &pp = astUnit->getPreprocessor();
7592 createCXTUResourceUsageEntry(*entries,
7593 CXTUResourceUsage_Preprocessor,
7594 pp.getTotalMemory());
7595
7596 if (PreprocessingRecord *pRec = pp.getPreprocessingRecord()) {
7597 createCXTUResourceUsageEntry(*entries,
7598 CXTUResourceUsage_PreprocessingRecord,
7599 pRec->getTotalMemory());
7600 }
7601
7602 createCXTUResourceUsageEntry(*entries,
7603 CXTUResourceUsage_Preprocessor_HeaderSearch,
7604 pp.getHeaderSearchInfo().getTotalMemory());
Craig Topper69186e72014-06-08 08:38:04 +00007605
Guy Benyei11169dd2012-12-18 14:30:41 +00007606 CXTUResourceUsage usage = { (void*) entries.get(),
7607 (unsigned) entries->size(),
Alexander Kornienko6ee521c2015-01-23 15:36:10 +00007608 !entries->empty() ? &(*entries)[0] : nullptr };
Ahmed Charles9a16beb2014-03-07 19:33:25 +00007609 entries.release();
Guy Benyei11169dd2012-12-18 14:30:41 +00007610 return usage;
7611}
7612
7613void clang_disposeCXTUResourceUsage(CXTUResourceUsage usage) {
7614 if (usage.data)
7615 delete (MemUsageEntries*) usage.data;
7616}
7617
Argyrios Kyrtzidis0e282ef2013-12-06 18:55:45 +00007618CXSourceRangeList *clang_getSkippedRanges(CXTranslationUnit TU, CXFile file) {
7619 CXSourceRangeList *skipped = new CXSourceRangeList;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00007620 skipped->count = 0;
Craig Topper69186e72014-06-08 08:38:04 +00007621 skipped->ranges = nullptr;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00007622
Dmitri Gribenko852d6222014-02-11 15:02:48 +00007623 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00007624 LOG_BAD_TU(TU);
7625 return skipped;
7626 }
7627
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00007628 if (!file)
7629 return skipped;
7630
7631 ASTUnit *astUnit = cxtu::getASTUnit(TU);
7632 PreprocessingRecord *ppRec = astUnit->getPreprocessor().getPreprocessingRecord();
7633 if (!ppRec)
7634 return skipped;
7635
7636 ASTContext &Ctx = astUnit->getASTContext();
7637 SourceManager &sm = Ctx.getSourceManager();
7638 FileEntry *fileEntry = static_cast<FileEntry *>(file);
7639 FileID wantedFileID = sm.translateFile(fileEntry);
7640
7641 const std::vector<SourceRange> &SkippedRanges = ppRec->getSkippedRanges();
7642 std::vector<SourceRange> wantedRanges;
7643 for (std::vector<SourceRange>::const_iterator i = SkippedRanges.begin(), ei = SkippedRanges.end();
7644 i != ei; ++i) {
7645 if (sm.getFileID(i->getBegin()) == wantedFileID || sm.getFileID(i->getEnd()) == wantedFileID)
7646 wantedRanges.push_back(*i);
7647 }
7648
7649 skipped->count = wantedRanges.size();
7650 skipped->ranges = new CXSourceRange[skipped->count];
7651 for (unsigned i = 0, ei = skipped->count; i != ei; ++i)
7652 skipped->ranges[i] = cxloc::translateSourceRange(Ctx, wantedRanges[i]);
7653
7654 return skipped;
7655}
7656
Argyrios Kyrtzidis0e282ef2013-12-06 18:55:45 +00007657void clang_disposeSourceRangeList(CXSourceRangeList *ranges) {
7658 if (ranges) {
7659 delete[] ranges->ranges;
7660 delete ranges;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00007661 }
7662}
7663
Guy Benyei11169dd2012-12-18 14:30:41 +00007664} // end extern "C"
7665
7666void clang::PrintLibclangResourceUsage(CXTranslationUnit TU) {
7667 CXTUResourceUsage Usage = clang_getCXTUResourceUsage(TU);
7668 for (unsigned I = 0; I != Usage.numEntries; ++I)
7669 fprintf(stderr, " %s: %lu\n",
7670 clang_getTUResourceUsageName(Usage.entries[I].kind),
7671 Usage.entries[I].amount);
7672
7673 clang_disposeCXTUResourceUsage(Usage);
7674}
7675
7676//===----------------------------------------------------------------------===//
7677// Misc. utility functions.
7678//===----------------------------------------------------------------------===//
7679
7680/// Default to using an 8 MB stack size on "safety" threads.
7681static unsigned SafetyStackThreadSize = 8 << 20;
7682
7683namespace clang {
7684
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00007685bool RunSafely(llvm::CrashRecoveryContext &CRC, llvm::function_ref<void()> Fn,
Guy Benyei11169dd2012-12-18 14:30:41 +00007686 unsigned Size) {
7687 if (!Size)
7688 Size = GetSafetyThreadStackSize();
7689 if (Size)
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00007690 return CRC.RunSafelyOnThread(Fn, Size);
7691 return CRC.RunSafely(Fn);
Guy Benyei11169dd2012-12-18 14:30:41 +00007692}
7693
7694unsigned GetSafetyThreadStackSize() {
7695 return SafetyStackThreadSize;
7696}
7697
7698void SetSafetyThreadStackSize(unsigned Value) {
7699 SafetyStackThreadSize = Value;
7700}
7701
Alexander Kornienkoab9db512015-06-22 23:07:51 +00007702}
Guy Benyei11169dd2012-12-18 14:30:41 +00007703
7704void clang::setThreadBackgroundPriority() {
7705 if (getenv("LIBCLANG_BGPRIO_DISABLE"))
7706 return;
7707
Alp Toker1a86ad22014-07-06 06:24:00 +00007708#ifdef USE_DARWIN_THREADS
Guy Benyei11169dd2012-12-18 14:30:41 +00007709 setpriority(PRIO_DARWIN_THREAD, 0, PRIO_DARWIN_BG);
7710#endif
7711}
7712
7713void cxindex::printDiagsToStderr(ASTUnit *Unit) {
7714 if (!Unit)
7715 return;
7716
7717 for (ASTUnit::stored_diag_iterator D = Unit->stored_diag_begin(),
7718 DEnd = Unit->stored_diag_end();
7719 D != DEnd; ++D) {
Ben Langmuir749323f2014-04-22 17:40:12 +00007720 CXStoredDiagnostic Diag(*D, Unit->getLangOpts());
Guy Benyei11169dd2012-12-18 14:30:41 +00007721 CXString Msg = clang_formatDiagnostic(&Diag,
7722 clang_defaultDiagnosticDisplayOptions());
7723 fprintf(stderr, "%s\n", clang_getCString(Msg));
7724 clang_disposeString(Msg);
7725 }
7726#ifdef LLVM_ON_WIN32
7727 // On Windows, force a flush, since there may be multiple copies of
7728 // stderr and stdout in the file system, all with different buffers
7729 // but writing to the same device.
7730 fflush(stderr);
7731#endif
7732}
7733
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007734MacroInfo *cxindex::getMacroInfo(const IdentifierInfo &II,
7735 SourceLocation MacroDefLoc,
7736 CXTranslationUnit TU){
7737 if (MacroDefLoc.isInvalid() || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00007738 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007739 if (!II.hadMacroDefinition())
Craig Topper69186e72014-06-08 08:38:04 +00007740 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007741
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007742 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00007743 Preprocessor &PP = Unit->getPreprocessor();
Richard Smith20e883e2015-04-29 23:20:19 +00007744 MacroDirective *MD = PP.getLocalMacroDirectiveHistory(&II);
Argyrios Kyrtzidisb6210df2013-03-26 17:17:01 +00007745 if (MD) {
7746 for (MacroDirective::DefInfo
7747 Def = MD->getDefinition(); Def; Def = Def.getPreviousDefinition()) {
7748 if (MacroDefLoc == Def.getMacroInfo()->getDefinitionLoc())
7749 return Def.getMacroInfo();
7750 }
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007751 }
7752
Craig Topper69186e72014-06-08 08:38:04 +00007753 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007754}
7755
Richard Smith66a81862015-05-04 02:25:31 +00007756const MacroInfo *cxindex::getMacroInfo(const MacroDefinitionRecord *MacroDef,
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00007757 CXTranslationUnit TU) {
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007758 if (!MacroDef || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00007759 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007760 const IdentifierInfo *II = MacroDef->getName();
7761 if (!II)
Craig Topper69186e72014-06-08 08:38:04 +00007762 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007763
7764 return getMacroInfo(*II, MacroDef->getLocation(), TU);
7765}
7766
Richard Smith66a81862015-05-04 02:25:31 +00007767MacroDefinitionRecord *
7768cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI, const Token &Tok,
7769 CXTranslationUnit TU) {
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007770 if (!MI || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00007771 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007772 if (Tok.isNot(tok::raw_identifier))
Craig Topper69186e72014-06-08 08:38:04 +00007773 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007774
7775 if (MI->getNumTokens() == 0)
Craig Topper69186e72014-06-08 08:38:04 +00007776 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007777 SourceRange DefRange(MI->getReplacementToken(0).getLocation(),
7778 MI->getDefinitionEndLoc());
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007779 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007780
7781 // Check that the token is inside the definition and not its argument list.
7782 SourceManager &SM = Unit->getSourceManager();
7783 if (SM.isBeforeInTranslationUnit(Tok.getLocation(), DefRange.getBegin()))
Craig Topper69186e72014-06-08 08:38:04 +00007784 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007785 if (SM.isBeforeInTranslationUnit(DefRange.getEnd(), Tok.getLocation()))
Craig Topper69186e72014-06-08 08:38:04 +00007786 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007787
7788 Preprocessor &PP = Unit->getPreprocessor();
7789 PreprocessingRecord *PPRec = PP.getPreprocessingRecord();
7790 if (!PPRec)
Craig Topper69186e72014-06-08 08:38:04 +00007791 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007792
Alp Toker2d57cea2014-05-17 04:53:25 +00007793 IdentifierInfo &II = PP.getIdentifierTable().get(Tok.getRawIdentifier());
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007794 if (!II.hadMacroDefinition())
Craig Topper69186e72014-06-08 08:38:04 +00007795 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007796
7797 // Check that the identifier is not one of the macro arguments.
7798 if (std::find(MI->arg_begin(), MI->arg_end(), &II) != MI->arg_end())
Craig Topper69186e72014-06-08 08:38:04 +00007799 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007800
Richard Smith20e883e2015-04-29 23:20:19 +00007801 MacroDirective *InnerMD = PP.getLocalMacroDirectiveHistory(&II);
Argyrios Kyrtzidis09c9e812013-02-20 00:54:57 +00007802 if (!InnerMD)
Craig Topper69186e72014-06-08 08:38:04 +00007803 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007804
Argyrios Kyrtzidisb6210df2013-03-26 17:17:01 +00007805 return PPRec->findMacroDefinition(InnerMD->getMacroInfo());
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007806}
7807
Richard Smith66a81862015-05-04 02:25:31 +00007808MacroDefinitionRecord *
7809cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI, SourceLocation Loc,
7810 CXTranslationUnit TU) {
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007811 if (Loc.isInvalid() || !MI || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00007812 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007813
7814 if (MI->getNumTokens() == 0)
Craig Topper69186e72014-06-08 08:38:04 +00007815 return nullptr;
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007816 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007817 Preprocessor &PP = Unit->getPreprocessor();
7818 if (!PP.getPreprocessingRecord())
Craig Topper69186e72014-06-08 08:38:04 +00007819 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007820 Loc = Unit->getSourceManager().getSpellingLoc(Loc);
7821 Token Tok;
7822 if (PP.getRawToken(Loc, Tok))
Craig Topper69186e72014-06-08 08:38:04 +00007823 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007824
7825 return checkForMacroInMacroDefinition(MI, Tok, TU);
7826}
7827
Guy Benyei11169dd2012-12-18 14:30:41 +00007828extern "C" {
7829
7830CXString clang_getClangVersion() {
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00007831 return cxstring::createDup(getClangFullVersion());
Guy Benyei11169dd2012-12-18 14:30:41 +00007832}
7833
7834} // end: extern "C"
7835
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007836Logger &cxindex::Logger::operator<<(CXTranslationUnit TU) {
7837 if (TU) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007838 if (ASTUnit *Unit = cxtu::getASTUnit(TU)) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007839 LogOS << '<' << Unit->getMainFileName() << '>';
Argyrios Kyrtzidis37f2ab42013-03-05 20:21:14 +00007840 if (Unit->isMainFileAST())
7841 LogOS << " (" << Unit->getASTFileName() << ')';
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007842 return *this;
7843 }
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00007844 } else {
7845 LogOS << "<NULL TU>";
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007846 }
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007847 return *this;
7848}
7849
Argyrios Kyrtzidisba4b5f82013-03-08 02:32:26 +00007850Logger &cxindex::Logger::operator<<(const FileEntry *FE) {
7851 *this << FE->getName();
7852 return *this;
7853}
7854
7855Logger &cxindex::Logger::operator<<(CXCursor cursor) {
7856 CXString cursorName = clang_getCursorDisplayName(cursor);
7857 *this << cursorName << "@" << clang_getCursorLocation(cursor);
7858 clang_disposeString(cursorName);
7859 return *this;
7860}
7861
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007862Logger &cxindex::Logger::operator<<(CXSourceLocation Loc) {
7863 CXFile File;
7864 unsigned Line, Column;
Craig Topper69186e72014-06-08 08:38:04 +00007865 clang_getFileLocation(Loc, &File, &Line, &Column, nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007866 CXString FileName = clang_getFileName(File);
7867 *this << llvm::format("(%s:%d:%d)", clang_getCString(FileName), Line, Column);
7868 clang_disposeString(FileName);
7869 return *this;
7870}
7871
7872Logger &cxindex::Logger::operator<<(CXSourceRange range) {
7873 CXSourceLocation BLoc = clang_getRangeStart(range);
7874 CXSourceLocation ELoc = clang_getRangeEnd(range);
7875
7876 CXFile BFile;
7877 unsigned BLine, BColumn;
Craig Topper69186e72014-06-08 08:38:04 +00007878 clang_getFileLocation(BLoc, &BFile, &BLine, &BColumn, nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007879
7880 CXFile EFile;
7881 unsigned ELine, EColumn;
Craig Topper69186e72014-06-08 08:38:04 +00007882 clang_getFileLocation(ELoc, &EFile, &ELine, &EColumn, nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007883
7884 CXString BFileName = clang_getFileName(BFile);
7885 if (BFile == EFile) {
7886 *this << llvm::format("[%s %d:%d-%d:%d]", clang_getCString(BFileName),
7887 BLine, BColumn, ELine, EColumn);
7888 } else {
7889 CXString EFileName = clang_getFileName(EFile);
7890 *this << llvm::format("[%s:%d:%d - ", clang_getCString(BFileName),
7891 BLine, BColumn)
7892 << llvm::format("%s:%d:%d]", clang_getCString(EFileName),
7893 ELine, EColumn);
7894 clang_disposeString(EFileName);
7895 }
7896 clang_disposeString(BFileName);
7897 return *this;
7898}
7899
7900Logger &cxindex::Logger::operator<<(CXString Str) {
7901 *this << clang_getCString(Str);
7902 return *this;
7903}
7904
7905Logger &cxindex::Logger::operator<<(const llvm::format_object_base &Fmt) {
7906 LogOS << Fmt;
7907 return *this;
7908}
7909
Chandler Carruth37ad2582014-06-27 15:14:39 +00007910static llvm::ManagedStatic<llvm::sys::Mutex> LoggingMutex;
7911
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007912cxindex::Logger::~Logger() {
Chandler Carruth37ad2582014-06-27 15:14:39 +00007913 llvm::sys::ScopedLock L(*LoggingMutex);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007914
7915 static llvm::TimeRecord sBeginTR = llvm::TimeRecord::getCurrentTime();
7916
Dmitri Gribenkof8579502013-01-12 19:30:44 +00007917 raw_ostream &OS = llvm::errs();
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007918 OS << "[libclang:" << Name << ':';
7919
Alp Toker1a86ad22014-07-06 06:24:00 +00007920#ifdef USE_DARWIN_THREADS
7921 // TODO: Portability.
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007922 mach_port_t tid = pthread_mach_thread_np(pthread_self());
7923 OS << tid << ':';
7924#endif
7925
7926 llvm::TimeRecord TR = llvm::TimeRecord::getCurrentTime();
7927 OS << llvm::format("%7.4f] ", TR.getWallTime() - sBeginTR.getWallTime());
Yaron Keren09fb7c62015-03-10 07:33:23 +00007928 OS << Msg << '\n';
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007929
7930 if (Trace) {
Zachary Turner1fe2a8d2015-03-05 19:15:09 +00007931 llvm::sys::PrintStackTrace(OS);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007932 OS << "--------------------------------------------------\n";
7933 }
7934}
Benjamin Kramerc1ffdab2016-03-03 08:58:18 +00007935
7936#ifdef CLANG_TOOL_EXTRA_BUILD
7937// This anchor is used to force the linker to link the clang-tidy plugin.
7938extern volatile int ClangTidyPluginAnchorSource;
7939static int LLVM_ATTRIBUTE_UNUSED ClangTidyPluginAnchorDestination =
7940 ClangTidyPluginAnchorSource;
7941#endif