blob: f4fa07c7fa893c80d2305d9a543d12c23b003eff [file] [log] [blame]
Guy Benyei11169dd2012-12-18 14:30:41 +00001//===- CIndex.cpp - Clang-C Source Indexing Library -----------------------===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file implements the main API hooks in the Clang-C Source Indexing
11// library.
12//
13//===----------------------------------------------------------------------===//
14
15#include "CIndexer.h"
16#include "CIndexDiagnostic.h"
Chandler Carruth4b417452013-01-19 08:09:44 +000017#include "CLog.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000018#include "CXCursor.h"
19#include "CXSourceLocation.h"
20#include "CXString.h"
21#include "CXTranslationUnit.h"
22#include "CXType.h"
23#include "CursorVisitor.h"
David Blaikie0a4e61f2013-09-13 18:32:52 +000024#include "clang/AST/Attr.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000025#include "clang/AST/StmtVisitor.h"
26#include "clang/Basic/Diagnostic.h"
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +000027#include "clang/Basic/DiagnosticCategories.h"
28#include "clang/Basic/DiagnosticIDs.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000029#include "clang/Basic/Version.h"
30#include "clang/Frontend/ASTUnit.h"
31#include "clang/Frontend/CompilerInstance.h"
32#include "clang/Frontend/FrontendDiagnostic.h"
Argyrios Kyrtzidisca741ce2016-02-14 22:30:14 +000033#include "clang/Index/CodegenNameGenerator.h"
Dmitri Gribenko9e605112013-11-13 22:16:51 +000034#include "clang/Index/CommentToXML.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000035#include "clang/Lex/HeaderSearch.h"
36#include "clang/Lex/Lexer.h"
37#include "clang/Lex/PreprocessingRecord.h"
38#include "clang/Lex/Preprocessor.h"
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +000039#include "clang/Serialization/SerializationDiagnostic.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000040#include "llvm/ADT/Optional.h"
41#include "llvm/ADT/STLExtras.h"
42#include "llvm/ADT/StringSwitch.h"
Alp Toker1d257e12014-06-04 03:28:55 +000043#include "llvm/Config/llvm-config.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000044#include "llvm/Support/Compiler.h"
45#include "llvm/Support/CrashRecoveryContext.h"
Chandler Carruth4b417452013-01-19 08:09:44 +000046#include "llvm/Support/Format.h"
Chandler Carruth37ad2582014-06-27 15:14:39 +000047#include "llvm/Support/ManagedStatic.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000048#include "llvm/Support/MemoryBuffer.h"
49#include "llvm/Support/Mutex.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000050#include "llvm/Support/Program.h"
51#include "llvm/Support/SaveAndRestore.h"
52#include "llvm/Support/Signals.h"
Adrian Prantlbc068582015-07-08 01:00:30 +000053#include "llvm/Support/TargetSelect.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000054#include "llvm/Support/Threading.h"
55#include "llvm/Support/Timer.h"
56#include "llvm/Support/raw_ostream.h"
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +000057
Alp Toker1a86ad22014-07-06 06:24:00 +000058#if LLVM_ENABLE_THREADS != 0 && defined(__APPLE__)
59#define USE_DARWIN_THREADS
60#endif
61
62#ifdef USE_DARWIN_THREADS
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +000063#include <pthread.h>
64#endif
Guy Benyei11169dd2012-12-18 14:30:41 +000065
66using namespace clang;
67using namespace clang::cxcursor;
Guy Benyei11169dd2012-12-18 14:30:41 +000068using namespace clang::cxtu;
69using namespace clang::cxindex;
70
Dmitri Gribenkod36209e2013-01-26 21:32:42 +000071CXTranslationUnit cxtu::MakeCXTranslationUnit(CIndexer *CIdx, ASTUnit *AU) {
72 if (!AU)
Craig Topper69186e72014-06-08 08:38:04 +000073 return nullptr;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +000074 assert(CIdx);
Guy Benyei11169dd2012-12-18 14:30:41 +000075 CXTranslationUnit D = new CXTranslationUnitImpl();
76 D->CIdx = CIdx;
Dmitri Gribenkod36209e2013-01-26 21:32:42 +000077 D->TheASTUnit = AU;
Dmitri Gribenko74895212013-02-03 13:52:47 +000078 D->StringPool = new cxstring::CXStringPool();
Craig Topper69186e72014-06-08 08:38:04 +000079 D->Diagnostics = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +000080 D->OverridenCursorsPool = createOverridenCXCursorsPool();
Craig Topper69186e72014-06-08 08:38:04 +000081 D->CommentToXML = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +000082 return D;
83}
84
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +000085bool cxtu::isASTReadError(ASTUnit *AU) {
86 for (ASTUnit::stored_diag_iterator D = AU->stored_diag_begin(),
87 DEnd = AU->stored_diag_end();
88 D != DEnd; ++D) {
89 if (D->getLevel() >= DiagnosticsEngine::Error &&
90 DiagnosticIDs::getCategoryNumberForDiag(D->getID()) ==
91 diag::DiagCat_AST_Deserialization_Issue)
92 return true;
93 }
94 return false;
95}
96
Guy Benyei11169dd2012-12-18 14:30:41 +000097cxtu::CXTUOwner::~CXTUOwner() {
98 if (TU)
99 clang_disposeTranslationUnit(TU);
100}
101
102/// \brief Compare two source ranges to determine their relative position in
103/// the translation unit.
104static RangeComparisonResult RangeCompare(SourceManager &SM,
105 SourceRange R1,
106 SourceRange R2) {
107 assert(R1.isValid() && "First range is invalid?");
108 assert(R2.isValid() && "Second range is invalid?");
109 if (R1.getEnd() != R2.getBegin() &&
110 SM.isBeforeInTranslationUnit(R1.getEnd(), R2.getBegin()))
111 return RangeBefore;
112 if (R2.getEnd() != R1.getBegin() &&
113 SM.isBeforeInTranslationUnit(R2.getEnd(), R1.getBegin()))
114 return RangeAfter;
115 return RangeOverlap;
116}
117
118/// \brief Determine if a source location falls within, before, or after a
119/// a given source range.
120static RangeComparisonResult LocationCompare(SourceManager &SM,
121 SourceLocation L, SourceRange R) {
122 assert(R.isValid() && "First range is invalid?");
123 assert(L.isValid() && "Second range is invalid?");
124 if (L == R.getBegin() || L == R.getEnd())
125 return RangeOverlap;
126 if (SM.isBeforeInTranslationUnit(L, R.getBegin()))
127 return RangeBefore;
128 if (SM.isBeforeInTranslationUnit(R.getEnd(), L))
129 return RangeAfter;
130 return RangeOverlap;
131}
132
133/// \brief Translate a Clang source range into a CIndex source range.
134///
135/// Clang internally represents ranges where the end location points to the
136/// start of the token at the end. However, for external clients it is more
137/// useful to have a CXSourceRange be a proper half-open interval. This routine
138/// does the appropriate translation.
139CXSourceRange cxloc::translateSourceRange(const SourceManager &SM,
140 const LangOptions &LangOpts,
141 const CharSourceRange &R) {
142 // We want the last character in this location, so we will adjust the
143 // location accordingly.
144 SourceLocation EndLoc = R.getEnd();
145 if (EndLoc.isValid() && EndLoc.isMacroID() && !SM.isMacroArgExpansion(EndLoc))
146 EndLoc = SM.getExpansionRange(EndLoc).second;
Yaron Keren8b563662015-10-03 10:46:20 +0000147 if (R.isTokenRange() && EndLoc.isValid()) {
Guy Benyei11169dd2012-12-18 14:30:41 +0000148 unsigned Length = Lexer::MeasureTokenLength(SM.getSpellingLoc(EndLoc),
149 SM, LangOpts);
150 EndLoc = EndLoc.getLocWithOffset(Length);
151 }
152
Bill Wendlingeade3622013-01-23 08:25:41 +0000153 CXSourceRange Result = {
Dmitri Gribenkof9304482013-01-23 15:56:07 +0000154 { &SM, &LangOpts },
Bill Wendlingeade3622013-01-23 08:25:41 +0000155 R.getBegin().getRawEncoding(),
156 EndLoc.getRawEncoding()
157 };
Guy Benyei11169dd2012-12-18 14:30:41 +0000158 return Result;
159}
160
161//===----------------------------------------------------------------------===//
162// Cursor visitor.
163//===----------------------------------------------------------------------===//
164
165static SourceRange getRawCursorExtent(CXCursor C);
166static SourceRange getFullCursorExtent(CXCursor C, SourceManager &SrcMgr);
167
168
169RangeComparisonResult CursorVisitor::CompareRegionOfInterest(SourceRange R) {
170 return RangeCompare(AU->getSourceManager(), R, RegionOfInterest);
171}
172
173/// \brief Visit the given cursor and, if requested by the visitor,
174/// its children.
175///
176/// \param Cursor the cursor to visit.
177///
178/// \param CheckedRegionOfInterest if true, then the caller already checked
179/// that this cursor is within the region of interest.
180///
181/// \returns true if the visitation should be aborted, false if it
182/// should continue.
183bool CursorVisitor::Visit(CXCursor Cursor, bool CheckedRegionOfInterest) {
184 if (clang_isInvalid(Cursor.kind))
185 return false;
186
187 if (clang_isDeclaration(Cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +0000188 const Decl *D = getCursorDecl(Cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +0000189 if (!D) {
190 assert(0 && "Invalid declaration cursor");
191 return true; // abort.
192 }
193
194 // Ignore implicit declarations, unless it's an objc method because
195 // currently we should report implicit methods for properties when indexing.
196 if (D->isImplicit() && !isa<ObjCMethodDecl>(D))
197 return false;
198 }
199
200 // If we have a range of interest, and this cursor doesn't intersect with it,
201 // we're done.
202 if (RegionOfInterest.isValid() && !CheckedRegionOfInterest) {
203 SourceRange Range = getRawCursorExtent(Cursor);
204 if (Range.isInvalid() || CompareRegionOfInterest(Range))
205 return false;
206 }
207
208 switch (Visitor(Cursor, Parent, ClientData)) {
209 case CXChildVisit_Break:
210 return true;
211
212 case CXChildVisit_Continue:
213 return false;
214
215 case CXChildVisit_Recurse: {
216 bool ret = VisitChildren(Cursor);
217 if (PostChildrenVisitor)
218 if (PostChildrenVisitor(Cursor, ClientData))
219 return true;
220 return ret;
221 }
222 }
223
224 llvm_unreachable("Invalid CXChildVisitResult!");
225}
226
227static bool visitPreprocessedEntitiesInRange(SourceRange R,
228 PreprocessingRecord &PPRec,
229 CursorVisitor &Visitor) {
230 SourceManager &SM = Visitor.getASTUnit()->getSourceManager();
231 FileID FID;
232
233 if (!Visitor.shouldVisitIncludedEntities()) {
234 // If the begin/end of the range lie in the same FileID, do the optimization
235 // where we skip preprocessed entities that do not come from the same FileID.
236 FID = SM.getFileID(SM.getFileLoc(R.getBegin()));
237 if (FID != SM.getFileID(SM.getFileLoc(R.getEnd())))
238 FID = FileID();
239 }
240
Benjamin Kramerb4ef6682015-02-06 17:25:10 +0000241 const auto &Entities = PPRec.getPreprocessedEntitiesInRange(R);
242 return Visitor.visitPreprocessedEntities(Entities.begin(), Entities.end(),
Guy Benyei11169dd2012-12-18 14:30:41 +0000243 PPRec, FID);
244}
245
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000246bool CursorVisitor::visitFileRegion() {
Guy Benyei11169dd2012-12-18 14:30:41 +0000247 if (RegionOfInterest.isInvalid())
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000248 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000249
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +0000250 ASTUnit *Unit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +0000251 SourceManager &SM = Unit->getSourceManager();
252
253 std::pair<FileID, unsigned>
254 Begin = SM.getDecomposedLoc(SM.getFileLoc(RegionOfInterest.getBegin())),
255 End = SM.getDecomposedLoc(SM.getFileLoc(RegionOfInterest.getEnd()));
256
257 if (End.first != Begin.first) {
258 // If the end does not reside in the same file, try to recover by
259 // picking the end of the file of begin location.
260 End.first = Begin.first;
261 End.second = SM.getFileIDSize(Begin.first);
262 }
263
264 assert(Begin.first == End.first);
265 if (Begin.second > End.second)
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000266 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000267
268 FileID File = Begin.first;
269 unsigned Offset = Begin.second;
270 unsigned Length = End.second - Begin.second;
271
272 if (!VisitDeclsOnly && !VisitPreprocessorLast)
273 if (visitPreprocessedEntitiesInRegion())
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000274 return true; // visitation break.
Guy Benyei11169dd2012-12-18 14:30:41 +0000275
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000276 if (visitDeclsFromFileRegion(File, Offset, Length))
277 return true; // visitation break.
Guy Benyei11169dd2012-12-18 14:30:41 +0000278
279 if (!VisitDeclsOnly && VisitPreprocessorLast)
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000280 return visitPreprocessedEntitiesInRegion();
281
282 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000283}
284
285static bool isInLexicalContext(Decl *D, DeclContext *DC) {
286 if (!DC)
287 return false;
288
289 for (DeclContext *DeclDC = D->getLexicalDeclContext();
290 DeclDC; DeclDC = DeclDC->getLexicalParent()) {
291 if (DeclDC == DC)
292 return true;
293 }
294 return false;
295}
296
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000297bool CursorVisitor::visitDeclsFromFileRegion(FileID File,
Guy Benyei11169dd2012-12-18 14:30:41 +0000298 unsigned Offset, unsigned Length) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +0000299 ASTUnit *Unit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +0000300 SourceManager &SM = Unit->getSourceManager();
301 SourceRange Range = RegionOfInterest;
302
303 SmallVector<Decl *, 16> Decls;
304 Unit->findFileRegionDecls(File, Offset, Length, Decls);
305
306 // If we didn't find any file level decls for the file, try looking at the
307 // file that it was included from.
308 while (Decls.empty() || Decls.front()->isTopLevelDeclInObjCContainer()) {
309 bool Invalid = false;
310 const SrcMgr::SLocEntry &SLEntry = SM.getSLocEntry(File, &Invalid);
311 if (Invalid)
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000312 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000313
314 SourceLocation Outer;
315 if (SLEntry.isFile())
316 Outer = SLEntry.getFile().getIncludeLoc();
317 else
318 Outer = SLEntry.getExpansion().getExpansionLocStart();
319 if (Outer.isInvalid())
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000320 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000321
Benjamin Kramer867ea1d2014-03-02 13:01:17 +0000322 std::tie(File, Offset) = SM.getDecomposedExpansionLoc(Outer);
Guy Benyei11169dd2012-12-18 14:30:41 +0000323 Length = 0;
324 Unit->findFileRegionDecls(File, Offset, Length, Decls);
325 }
326
327 assert(!Decls.empty());
328
329 bool VisitedAtLeastOnce = false;
Craig Topper69186e72014-06-08 08:38:04 +0000330 DeclContext *CurDC = nullptr;
Craig Topper2341c0d2013-07-04 03:08:24 +0000331 SmallVectorImpl<Decl *>::iterator DIt = Decls.begin();
332 for (SmallVectorImpl<Decl *>::iterator DE = Decls.end(); DIt != DE; ++DIt) {
Guy Benyei11169dd2012-12-18 14:30:41 +0000333 Decl *D = *DIt;
334 if (D->getSourceRange().isInvalid())
335 continue;
336
337 if (isInLexicalContext(D, CurDC))
338 continue;
339
340 CurDC = dyn_cast<DeclContext>(D);
341
342 if (TagDecl *TD = dyn_cast<TagDecl>(D))
343 if (!TD->isFreeStanding())
344 continue;
345
346 RangeComparisonResult CompRes = RangeCompare(SM, D->getSourceRange(),Range);
347 if (CompRes == RangeBefore)
348 continue;
349 if (CompRes == RangeAfter)
350 break;
351
352 assert(CompRes == RangeOverlap);
353 VisitedAtLeastOnce = true;
354
355 if (isa<ObjCContainerDecl>(D)) {
356 FileDI_current = &DIt;
357 FileDE_current = DE;
358 } else {
Craig Topper69186e72014-06-08 08:38:04 +0000359 FileDI_current = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +0000360 }
361
362 if (Visit(MakeCXCursor(D, TU, Range), /*CheckedRegionOfInterest=*/true))
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000363 return true; // visitation break.
Guy Benyei11169dd2012-12-18 14:30:41 +0000364 }
365
366 if (VisitedAtLeastOnce)
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000367 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000368
369 // No Decls overlapped with the range. Move up the lexical context until there
370 // is a context that contains the range or we reach the translation unit
371 // level.
372 DeclContext *DC = DIt == Decls.begin() ? (*DIt)->getLexicalDeclContext()
373 : (*(DIt-1))->getLexicalDeclContext();
374
375 while (DC && !DC->isTranslationUnit()) {
376 Decl *D = cast<Decl>(DC);
377 SourceRange CurDeclRange = D->getSourceRange();
378 if (CurDeclRange.isInvalid())
379 break;
380
381 if (RangeCompare(SM, CurDeclRange, Range) == RangeOverlap) {
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000382 if (Visit(MakeCXCursor(D, TU, Range), /*CheckedRegionOfInterest=*/true))
383 return true; // visitation break.
Guy Benyei11169dd2012-12-18 14:30:41 +0000384 }
385
386 DC = D->getLexicalDeclContext();
387 }
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000388
389 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000390}
391
392bool CursorVisitor::visitPreprocessedEntitiesInRegion() {
393 if (!AU->getPreprocessor().getPreprocessingRecord())
394 return false;
395
396 PreprocessingRecord &PPRec
397 = *AU->getPreprocessor().getPreprocessingRecord();
398 SourceManager &SM = AU->getSourceManager();
399
400 if (RegionOfInterest.isValid()) {
401 SourceRange MappedRange = AU->mapRangeToPreamble(RegionOfInterest);
402 SourceLocation B = MappedRange.getBegin();
403 SourceLocation E = MappedRange.getEnd();
404
405 if (AU->isInPreambleFileID(B)) {
406 if (SM.isLoadedSourceLocation(E))
407 return visitPreprocessedEntitiesInRange(SourceRange(B, E),
408 PPRec, *this);
409
410 // Beginning of range lies in the preamble but it also extends beyond
411 // it into the main file. Split the range into 2 parts, one covering
412 // the preamble and another covering the main file. This allows subsequent
413 // calls to visitPreprocessedEntitiesInRange to accept a source range that
414 // lies in the same FileID, allowing it to skip preprocessed entities that
415 // do not come from the same FileID.
416 bool breaked =
417 visitPreprocessedEntitiesInRange(
418 SourceRange(B, AU->getEndOfPreambleFileID()),
419 PPRec, *this);
420 if (breaked) return true;
421 return visitPreprocessedEntitiesInRange(
422 SourceRange(AU->getStartOfMainFileID(), E),
423 PPRec, *this);
424 }
425
426 return visitPreprocessedEntitiesInRange(SourceRange(B, E), PPRec, *this);
427 }
428
429 bool OnlyLocalDecls
430 = !AU->isMainFileAST() && AU->getOnlyLocalDecls();
431
432 if (OnlyLocalDecls)
433 return visitPreprocessedEntities(PPRec.local_begin(), PPRec.local_end(),
434 PPRec);
435
436 return visitPreprocessedEntities(PPRec.begin(), PPRec.end(), PPRec);
437}
438
439template<typename InputIterator>
440bool CursorVisitor::visitPreprocessedEntities(InputIterator First,
441 InputIterator Last,
442 PreprocessingRecord &PPRec,
443 FileID FID) {
444 for (; First != Last; ++First) {
445 if (!FID.isInvalid() && !PPRec.isEntityInFileID(First, FID))
446 continue;
447
448 PreprocessedEntity *PPE = *First;
Argyrios Kyrtzidis1030f262013-05-07 20:37:17 +0000449 if (!PPE)
450 continue;
451
Guy Benyei11169dd2012-12-18 14:30:41 +0000452 if (MacroExpansion *ME = dyn_cast<MacroExpansion>(PPE)) {
453 if (Visit(MakeMacroExpansionCursor(ME, TU)))
454 return true;
Richard Smith66a81862015-05-04 02:25:31 +0000455
Guy Benyei11169dd2012-12-18 14:30:41 +0000456 continue;
457 }
Richard Smith66a81862015-05-04 02:25:31 +0000458
459 if (MacroDefinitionRecord *MD = dyn_cast<MacroDefinitionRecord>(PPE)) {
Guy Benyei11169dd2012-12-18 14:30:41 +0000460 if (Visit(MakeMacroDefinitionCursor(MD, TU)))
461 return true;
Richard Smith66a81862015-05-04 02:25:31 +0000462
Guy Benyei11169dd2012-12-18 14:30:41 +0000463 continue;
464 }
465
466 if (InclusionDirective *ID = dyn_cast<InclusionDirective>(PPE)) {
467 if (Visit(MakeInclusionDirectiveCursor(ID, TU)))
468 return true;
469
470 continue;
471 }
472 }
473
474 return false;
475}
476
477/// \brief Visit the children of the given cursor.
478///
479/// \returns true if the visitation should be aborted, false if it
480/// should continue.
481bool CursorVisitor::VisitChildren(CXCursor Cursor) {
482 if (clang_isReference(Cursor.kind) &&
483 Cursor.kind != CXCursor_CXXBaseSpecifier) {
484 // By definition, references have no children.
485 return false;
486 }
487
488 // Set the Parent field to Cursor, then back to its old value once we're
489 // done.
490 SetParentRAII SetParent(Parent, StmtParent, Cursor);
491
492 if (clang_isDeclaration(Cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +0000493 Decl *D = const_cast<Decl *>(getCursorDecl(Cursor));
Guy Benyei11169dd2012-12-18 14:30:41 +0000494 if (!D)
495 return false;
496
497 return VisitAttributes(D) || Visit(D);
498 }
499
500 if (clang_isStatement(Cursor.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +0000501 if (const Stmt *S = getCursorStmt(Cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +0000502 return Visit(S);
503
504 return false;
505 }
506
507 if (clang_isExpression(Cursor.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +0000508 if (const Expr *E = getCursorExpr(Cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +0000509 return Visit(E);
510
511 return false;
512 }
513
514 if (clang_isTranslationUnit(Cursor.kind)) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +0000515 CXTranslationUnit TU = getCursorTU(Cursor);
516 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +0000517
518 int VisitOrder[2] = { VisitPreprocessorLast, !VisitPreprocessorLast };
519 for (unsigned I = 0; I != 2; ++I) {
520 if (VisitOrder[I]) {
521 if (!CXXUnit->isMainFileAST() && CXXUnit->getOnlyLocalDecls() &&
522 RegionOfInterest.isInvalid()) {
523 for (ASTUnit::top_level_iterator TL = CXXUnit->top_level_begin(),
524 TLEnd = CXXUnit->top_level_end();
525 TL != TLEnd; ++TL) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +0000526 if (Visit(MakeCXCursor(*TL, TU, RegionOfInterest), true))
Guy Benyei11169dd2012-12-18 14:30:41 +0000527 return true;
528 }
529 } else if (VisitDeclContext(
530 CXXUnit->getASTContext().getTranslationUnitDecl()))
531 return true;
532 continue;
533 }
534
535 // Walk the preprocessing record.
536 if (CXXUnit->getPreprocessor().getPreprocessingRecord())
537 visitPreprocessedEntitiesInRegion();
538 }
539
540 return false;
541 }
542
543 if (Cursor.kind == CXCursor_CXXBaseSpecifier) {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +0000544 if (const CXXBaseSpecifier *Base = getCursorCXXBaseSpecifier(Cursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +0000545 if (TypeSourceInfo *BaseTSInfo = Base->getTypeSourceInfo()) {
546 return Visit(BaseTSInfo->getTypeLoc());
547 }
548 }
549 }
550
551 if (Cursor.kind == CXCursor_IBOutletCollectionAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +0000552 const IBOutletCollectionAttr *A =
Guy Benyei11169dd2012-12-18 14:30:41 +0000553 cast<IBOutletCollectionAttr>(cxcursor::getCursorAttr(Cursor));
Richard Smithb1f9a282013-10-31 01:56:18 +0000554 if (const ObjCObjectType *ObjT = A->getInterface()->getAs<ObjCObjectType>())
Richard Smithb87c4652013-10-31 21:23:20 +0000555 return Visit(cxcursor::MakeCursorObjCClassRef(
556 ObjT->getInterface(),
557 A->getInterfaceLoc()->getTypeLoc().getLocStart(), TU));
Guy Benyei11169dd2012-12-18 14:30:41 +0000558 }
559
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +0000560 // If pointing inside a macro definition, check if the token is an identifier
561 // that was ever defined as a macro. In such a case, create a "pseudo" macro
562 // expansion cursor for that token.
563 SourceLocation BeginLoc = RegionOfInterest.getBegin();
564 if (Cursor.kind == CXCursor_MacroDefinition &&
565 BeginLoc == RegionOfInterest.getEnd()) {
566 SourceLocation Loc = AU->mapLocationToPreamble(BeginLoc);
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +0000567 const MacroInfo *MI =
568 getMacroInfo(cxcursor::getCursorMacroDefinition(Cursor), TU);
Richard Smith66a81862015-05-04 02:25:31 +0000569 if (MacroDefinitionRecord *MacroDef =
570 checkForMacroInMacroDefinition(MI, Loc, TU))
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +0000571 return Visit(cxcursor::MakeMacroExpansionCursor(MacroDef, BeginLoc, TU));
572 }
573
Guy Benyei11169dd2012-12-18 14:30:41 +0000574 // Nothing to visit at the moment.
575 return false;
576}
577
578bool CursorVisitor::VisitBlockDecl(BlockDecl *B) {
579 if (TypeSourceInfo *TSInfo = B->getSignatureAsWritten())
580 if (Visit(TSInfo->getTypeLoc()))
581 return true;
582
583 if (Stmt *Body = B->getBody())
584 return Visit(MakeCXCursor(Body, StmtParent, TU, RegionOfInterest));
585
586 return false;
587}
588
Ted Kremenek03325582013-02-21 01:29:01 +0000589Optional<bool> CursorVisitor::shouldVisitCursor(CXCursor Cursor) {
Guy Benyei11169dd2012-12-18 14:30:41 +0000590 if (RegionOfInterest.isValid()) {
591 SourceRange Range = getFullCursorExtent(Cursor, AU->getSourceManager());
592 if (Range.isInvalid())
David Blaikie7a30dc52013-02-21 01:47:18 +0000593 return None;
Guy Benyei11169dd2012-12-18 14:30:41 +0000594
595 switch (CompareRegionOfInterest(Range)) {
596 case RangeBefore:
597 // This declaration comes before the region of interest; skip it.
David Blaikie7a30dc52013-02-21 01:47:18 +0000598 return None;
Guy Benyei11169dd2012-12-18 14:30:41 +0000599
600 case RangeAfter:
601 // This declaration comes after the region of interest; we're done.
602 return false;
603
604 case RangeOverlap:
605 // This declaration overlaps the region of interest; visit it.
606 break;
607 }
608 }
609 return true;
610}
611
612bool CursorVisitor::VisitDeclContext(DeclContext *DC) {
613 DeclContext::decl_iterator I = DC->decls_begin(), E = DC->decls_end();
614
615 // FIXME: Eventually remove. This part of a hack to support proper
616 // iteration over all Decls contained lexically within an ObjC container.
617 SaveAndRestore<DeclContext::decl_iterator*> DI_saved(DI_current, &I);
618 SaveAndRestore<DeclContext::decl_iterator> DE_saved(DE_current, E);
619
620 for ( ; I != E; ++I) {
621 Decl *D = *I;
622 if (D->getLexicalDeclContext() != DC)
623 continue;
624 CXCursor Cursor = MakeCXCursor(D, TU, RegionOfInterest);
625
626 // Ignore synthesized ivars here, otherwise if we have something like:
627 // @synthesize prop = _prop;
628 // and '_prop' is not declared, we will encounter a '_prop' ivar before
629 // encountering the 'prop' synthesize declaration and we will think that
630 // we passed the region-of-interest.
631 if (ObjCIvarDecl *ivarD = dyn_cast<ObjCIvarDecl>(D)) {
632 if (ivarD->getSynthesize())
633 continue;
634 }
635
636 // FIXME: ObjCClassRef/ObjCProtocolRef for forward class/protocol
637 // declarations is a mismatch with the compiler semantics.
638 if (Cursor.kind == CXCursor_ObjCInterfaceDecl) {
639 ObjCInterfaceDecl *ID = cast<ObjCInterfaceDecl>(D);
640 if (!ID->isThisDeclarationADefinition())
641 Cursor = MakeCursorObjCClassRef(ID, ID->getLocation(), TU);
642
643 } else if (Cursor.kind == CXCursor_ObjCProtocolDecl) {
644 ObjCProtocolDecl *PD = cast<ObjCProtocolDecl>(D);
645 if (!PD->isThisDeclarationADefinition())
646 Cursor = MakeCursorObjCProtocolRef(PD, PD->getLocation(), TU);
647 }
648
Ted Kremenek03325582013-02-21 01:29:01 +0000649 const Optional<bool> &V = shouldVisitCursor(Cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +0000650 if (!V.hasValue())
651 continue;
652 if (!V.getValue())
653 return false;
654 if (Visit(Cursor, true))
655 return true;
656 }
657 return false;
658}
659
660bool CursorVisitor::VisitTranslationUnitDecl(TranslationUnitDecl *D) {
661 llvm_unreachable("Translation units are visited directly by Visit()");
662}
663
Sergey Kalinichev8f3b1872015-11-15 13:48:32 +0000664bool CursorVisitor::VisitTypeAliasTemplateDecl(TypeAliasTemplateDecl *D) {
665 if (VisitTemplateParameters(D->getTemplateParameters()))
666 return true;
667
668 return Visit(MakeCXCursor(D->getTemplatedDecl(), TU, RegionOfInterest));
669}
670
Guy Benyei11169dd2012-12-18 14:30:41 +0000671bool CursorVisitor::VisitTypeAliasDecl(TypeAliasDecl *D) {
672 if (TypeSourceInfo *TSInfo = D->getTypeSourceInfo())
673 return Visit(TSInfo->getTypeLoc());
674
675 return false;
676}
677
678bool CursorVisitor::VisitTypedefDecl(TypedefDecl *D) {
679 if (TypeSourceInfo *TSInfo = D->getTypeSourceInfo())
680 return Visit(TSInfo->getTypeLoc());
681
682 return false;
683}
684
685bool CursorVisitor::VisitTagDecl(TagDecl *D) {
686 return VisitDeclContext(D);
687}
688
689bool CursorVisitor::VisitClassTemplateSpecializationDecl(
690 ClassTemplateSpecializationDecl *D) {
691 bool ShouldVisitBody = false;
692 switch (D->getSpecializationKind()) {
693 case TSK_Undeclared:
694 case TSK_ImplicitInstantiation:
695 // Nothing to visit
696 return false;
697
698 case TSK_ExplicitInstantiationDeclaration:
699 case TSK_ExplicitInstantiationDefinition:
700 break;
701
702 case TSK_ExplicitSpecialization:
703 ShouldVisitBody = true;
704 break;
705 }
706
707 // Visit the template arguments used in the specialization.
708 if (TypeSourceInfo *SpecType = D->getTypeAsWritten()) {
709 TypeLoc TL = SpecType->getTypeLoc();
David Blaikie6adc78e2013-02-18 22:06:02 +0000710 if (TemplateSpecializationTypeLoc TSTLoc =
711 TL.getAs<TemplateSpecializationTypeLoc>()) {
712 for (unsigned I = 0, N = TSTLoc.getNumArgs(); I != N; ++I)
713 if (VisitTemplateArgumentLoc(TSTLoc.getArgLoc(I)))
Guy Benyei11169dd2012-12-18 14:30:41 +0000714 return true;
715 }
716 }
Alexander Kornienko1a9f1842015-12-28 15:24:08 +0000717
718 return ShouldVisitBody && VisitCXXRecordDecl(D);
Guy Benyei11169dd2012-12-18 14:30:41 +0000719}
720
721bool CursorVisitor::VisitClassTemplatePartialSpecializationDecl(
722 ClassTemplatePartialSpecializationDecl *D) {
723 // FIXME: Visit the "outer" template parameter lists on the TagDecl
724 // before visiting these template parameters.
725 if (VisitTemplateParameters(D->getTemplateParameters()))
726 return true;
727
728 // Visit the partial specialization arguments.
Enea Zaffanella6dbe1872013-08-10 07:24:53 +0000729 const ASTTemplateArgumentListInfo *Info = D->getTemplateArgsAsWritten();
730 const TemplateArgumentLoc *TemplateArgs = Info->getTemplateArgs();
731 for (unsigned I = 0, N = Info->NumTemplateArgs; I != N; ++I)
Guy Benyei11169dd2012-12-18 14:30:41 +0000732 if (VisitTemplateArgumentLoc(TemplateArgs[I]))
733 return true;
734
735 return VisitCXXRecordDecl(D);
736}
737
738bool CursorVisitor::VisitTemplateTypeParmDecl(TemplateTypeParmDecl *D) {
739 // Visit the default argument.
740 if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited())
741 if (TypeSourceInfo *DefArg = D->getDefaultArgumentInfo())
742 if (Visit(DefArg->getTypeLoc()))
743 return true;
744
745 return false;
746}
747
748bool CursorVisitor::VisitEnumConstantDecl(EnumConstantDecl *D) {
749 if (Expr *Init = D->getInitExpr())
750 return Visit(MakeCXCursor(Init, StmtParent, TU, RegionOfInterest));
751 return false;
752}
753
754bool CursorVisitor::VisitDeclaratorDecl(DeclaratorDecl *DD) {
Argyrios Kyrtzidis2ec76742013-04-05 21:04:10 +0000755 unsigned NumParamList = DD->getNumTemplateParameterLists();
756 for (unsigned i = 0; i < NumParamList; i++) {
757 TemplateParameterList* Params = DD->getTemplateParameterList(i);
758 if (VisitTemplateParameters(Params))
759 return true;
760 }
761
Guy Benyei11169dd2012-12-18 14:30:41 +0000762 if (TypeSourceInfo *TSInfo = DD->getTypeSourceInfo())
763 if (Visit(TSInfo->getTypeLoc()))
764 return true;
765
766 // Visit the nested-name-specifier, if present.
767 if (NestedNameSpecifierLoc QualifierLoc = DD->getQualifierLoc())
768 if (VisitNestedNameSpecifierLoc(QualifierLoc))
769 return true;
770
771 return false;
772}
773
Benjamin Kramer4cadf292014-03-07 21:51:58 +0000774/// \brief Compare two base or member initializers based on their source order.
775static int CompareCXXCtorInitializers(CXXCtorInitializer *const *X,
776 CXXCtorInitializer *const *Y) {
777 return (*X)->getSourceOrder() - (*Y)->getSourceOrder();
778}
779
Guy Benyei11169dd2012-12-18 14:30:41 +0000780bool CursorVisitor::VisitFunctionDecl(FunctionDecl *ND) {
Argyrios Kyrtzidis2ec76742013-04-05 21:04:10 +0000781 unsigned NumParamList = ND->getNumTemplateParameterLists();
782 for (unsigned i = 0; i < NumParamList; i++) {
783 TemplateParameterList* Params = ND->getTemplateParameterList(i);
784 if (VisitTemplateParameters(Params))
785 return true;
786 }
787
Guy Benyei11169dd2012-12-18 14:30:41 +0000788 if (TypeSourceInfo *TSInfo = ND->getTypeSourceInfo()) {
789 // Visit the function declaration's syntactic components in the order
790 // written. This requires a bit of work.
791 TypeLoc TL = TSInfo->getTypeLoc().IgnoreParens();
David Blaikie6adc78e2013-02-18 22:06:02 +0000792 FunctionTypeLoc FTL = TL.getAs<FunctionTypeLoc>();
Guy Benyei11169dd2012-12-18 14:30:41 +0000793
794 // If we have a function declared directly (without the use of a typedef),
795 // visit just the return type. Otherwise, just visit the function's type
796 // now.
Alp Toker42a16a62014-01-25 23:51:36 +0000797 if ((FTL && !isa<CXXConversionDecl>(ND) && Visit(FTL.getReturnLoc())) ||
Guy Benyei11169dd2012-12-18 14:30:41 +0000798 (!FTL && Visit(TL)))
799 return true;
800
801 // Visit the nested-name-specifier, if present.
802 if (NestedNameSpecifierLoc QualifierLoc = ND->getQualifierLoc())
803 if (VisitNestedNameSpecifierLoc(QualifierLoc))
804 return true;
805
806 // Visit the declaration name.
Argyrios Kyrtzidis4a4d2b42014-02-09 08:13:47 +0000807 if (!isa<CXXDestructorDecl>(ND))
808 if (VisitDeclarationNameInfo(ND->getNameInfo()))
809 return true;
Guy Benyei11169dd2012-12-18 14:30:41 +0000810
811 // FIXME: Visit explicitly-specified template arguments!
812
813 // Visit the function parameters, if we have a function type.
David Blaikie6adc78e2013-02-18 22:06:02 +0000814 if (FTL && VisitFunctionTypeLoc(FTL, true))
Guy Benyei11169dd2012-12-18 14:30:41 +0000815 return true;
816
Bill Wendling44426052012-12-20 19:22:21 +0000817 // FIXME: Attributes?
Guy Benyei11169dd2012-12-18 14:30:41 +0000818 }
819
820 if (ND->doesThisDeclarationHaveABody() && !ND->isLateTemplateParsed()) {
821 if (CXXConstructorDecl *Constructor = dyn_cast<CXXConstructorDecl>(ND)) {
822 // Find the initializers that were written in the source.
823 SmallVector<CXXCtorInitializer *, 4> WrittenInits;
Aaron Ballman0ad78302014-03-13 17:34:31 +0000824 for (auto *I : Constructor->inits()) {
825 if (!I->isWritten())
Guy Benyei11169dd2012-12-18 14:30:41 +0000826 continue;
827
Aaron Ballman0ad78302014-03-13 17:34:31 +0000828 WrittenInits.push_back(I);
Guy Benyei11169dd2012-12-18 14:30:41 +0000829 }
830
831 // Sort the initializers in source order
Benjamin Kramer4cadf292014-03-07 21:51:58 +0000832 llvm::array_pod_sort(WrittenInits.begin(), WrittenInits.end(),
833 &CompareCXXCtorInitializers);
834
Guy Benyei11169dd2012-12-18 14:30:41 +0000835 // Visit the initializers in source order
836 for (unsigned I = 0, N = WrittenInits.size(); I != N; ++I) {
837 CXXCtorInitializer *Init = WrittenInits[I];
838 if (Init->isAnyMemberInitializer()) {
839 if (Visit(MakeCursorMemberRef(Init->getAnyMember(),
840 Init->getMemberLocation(), TU)))
841 return true;
842 } else if (TypeSourceInfo *TInfo = Init->getTypeSourceInfo()) {
843 if (Visit(TInfo->getTypeLoc()))
844 return true;
845 }
846
847 // Visit the initializer value.
848 if (Expr *Initializer = Init->getInit())
849 if (Visit(MakeCXCursor(Initializer, ND, TU, RegionOfInterest)))
850 return true;
851 }
852 }
853
854 if (Visit(MakeCXCursor(ND->getBody(), StmtParent, TU, RegionOfInterest)))
855 return true;
856 }
857
858 return false;
859}
860
861bool CursorVisitor::VisitFieldDecl(FieldDecl *D) {
862 if (VisitDeclaratorDecl(D))
863 return true;
864
865 if (Expr *BitWidth = D->getBitWidth())
866 return Visit(MakeCXCursor(BitWidth, StmtParent, TU, RegionOfInterest));
867
868 return false;
869}
870
871bool CursorVisitor::VisitVarDecl(VarDecl *D) {
872 if (VisitDeclaratorDecl(D))
873 return true;
874
875 if (Expr *Init = D->getInit())
876 return Visit(MakeCXCursor(Init, StmtParent, TU, RegionOfInterest));
877
878 return false;
879}
880
881bool CursorVisitor::VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl *D) {
882 if (VisitDeclaratorDecl(D))
883 return true;
884
885 if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited())
886 if (Expr *DefArg = D->getDefaultArgument())
887 return Visit(MakeCXCursor(DefArg, StmtParent, TU, RegionOfInterest));
888
889 return false;
890}
891
892bool CursorVisitor::VisitFunctionTemplateDecl(FunctionTemplateDecl *D) {
893 // FIXME: Visit the "outer" template parameter lists on the FunctionDecl
894 // before visiting these template parameters.
895 if (VisitTemplateParameters(D->getTemplateParameters()))
896 return true;
897
898 return VisitFunctionDecl(D->getTemplatedDecl());
899}
900
901bool CursorVisitor::VisitClassTemplateDecl(ClassTemplateDecl *D) {
902 // FIXME: Visit the "outer" template parameter lists on the TagDecl
903 // before visiting these template parameters.
904 if (VisitTemplateParameters(D->getTemplateParameters()))
905 return true;
906
907 return VisitCXXRecordDecl(D->getTemplatedDecl());
908}
909
910bool CursorVisitor::VisitTemplateTemplateParmDecl(TemplateTemplateParmDecl *D) {
911 if (VisitTemplateParameters(D->getTemplateParameters()))
912 return true;
913
914 if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited() &&
915 VisitTemplateArgumentLoc(D->getDefaultArgument()))
916 return true;
917
918 return false;
919}
920
Douglas Gregor9bda6cf2015-07-07 03:58:14 +0000921bool CursorVisitor::VisitObjCTypeParamDecl(ObjCTypeParamDecl *D) {
922 // Visit the bound, if it's explicit.
923 if (D->hasExplicitBound()) {
924 if (auto TInfo = D->getTypeSourceInfo()) {
925 if (Visit(TInfo->getTypeLoc()))
926 return true;
927 }
928 }
929
930 return false;
931}
932
Guy Benyei11169dd2012-12-18 14:30:41 +0000933bool CursorVisitor::VisitObjCMethodDecl(ObjCMethodDecl *ND) {
Alp Toker314cc812014-01-25 16:55:45 +0000934 if (TypeSourceInfo *TSInfo = ND->getReturnTypeSourceInfo())
Guy Benyei11169dd2012-12-18 14:30:41 +0000935 if (Visit(TSInfo->getTypeLoc()))
936 return true;
937
Aaron Ballman43b68be2014-03-07 17:50:17 +0000938 for (const auto *P : ND->params()) {
939 if (Visit(MakeCXCursor(P, TU, RegionOfInterest)))
Guy Benyei11169dd2012-12-18 14:30:41 +0000940 return true;
941 }
942
Alexander Kornienko1a9f1842015-12-28 15:24:08 +0000943 return ND->isThisDeclarationADefinition() &&
944 Visit(MakeCXCursor(ND->getBody(), StmtParent, TU, RegionOfInterest));
Guy Benyei11169dd2012-12-18 14:30:41 +0000945}
946
947template <typename DeclIt>
948static void addRangedDeclsInContainer(DeclIt *DI_current, DeclIt DE_current,
949 SourceManager &SM, SourceLocation EndLoc,
950 SmallVectorImpl<Decl *> &Decls) {
951 DeclIt next = *DI_current;
952 while (++next != DE_current) {
953 Decl *D_next = *next;
954 if (!D_next)
955 break;
956 SourceLocation L = D_next->getLocStart();
957 if (!L.isValid())
958 break;
959 if (SM.isBeforeInTranslationUnit(L, EndLoc)) {
960 *DI_current = next;
961 Decls.push_back(D_next);
962 continue;
963 }
964 break;
965 }
966}
967
Guy Benyei11169dd2012-12-18 14:30:41 +0000968bool CursorVisitor::VisitObjCContainerDecl(ObjCContainerDecl *D) {
969 // FIXME: Eventually convert back to just 'VisitDeclContext()'. Essentially
970 // an @implementation can lexically contain Decls that are not properly
971 // nested in the AST. When we identify such cases, we need to retrofit
972 // this nesting here.
973 if (!DI_current && !FileDI_current)
974 return VisitDeclContext(D);
975
976 // Scan the Decls that immediately come after the container
977 // in the current DeclContext. If any fall within the
978 // container's lexical region, stash them into a vector
979 // for later processing.
980 SmallVector<Decl *, 24> DeclsInContainer;
981 SourceLocation EndLoc = D->getSourceRange().getEnd();
982 SourceManager &SM = AU->getSourceManager();
983 if (EndLoc.isValid()) {
984 if (DI_current) {
985 addRangedDeclsInContainer(DI_current, DE_current, SM, EndLoc,
986 DeclsInContainer);
987 } else {
988 addRangedDeclsInContainer(FileDI_current, FileDE_current, SM, EndLoc,
989 DeclsInContainer);
990 }
991 }
992
993 // The common case.
994 if (DeclsInContainer.empty())
995 return VisitDeclContext(D);
996
997 // Get all the Decls in the DeclContext, and sort them with the
998 // additional ones we've collected. Then visit them.
Aaron Ballman629afae2014-03-07 19:56:05 +0000999 for (auto *SubDecl : D->decls()) {
1000 if (!SubDecl || SubDecl->getLexicalDeclContext() != D ||
1001 SubDecl->getLocStart().isInvalid())
Guy Benyei11169dd2012-12-18 14:30:41 +00001002 continue;
Aaron Ballman629afae2014-03-07 19:56:05 +00001003 DeclsInContainer.push_back(SubDecl);
Guy Benyei11169dd2012-12-18 14:30:41 +00001004 }
1005
1006 // Now sort the Decls so that they appear in lexical order.
1007 std::sort(DeclsInContainer.begin(), DeclsInContainer.end(),
Benjamin Kramerbbdd7642014-03-01 14:48:57 +00001008 [&SM](Decl *A, Decl *B) {
1009 SourceLocation L_A = A->getLocStart();
1010 SourceLocation L_B = B->getLocStart();
1011 assert(L_A.isValid() && L_B.isValid());
1012 return SM.isBeforeInTranslationUnit(L_A, L_B);
1013 });
Guy Benyei11169dd2012-12-18 14:30:41 +00001014
1015 // Now visit the decls.
1016 for (SmallVectorImpl<Decl*>::iterator I = DeclsInContainer.begin(),
1017 E = DeclsInContainer.end(); I != E; ++I) {
1018 CXCursor Cursor = MakeCXCursor(*I, TU, RegionOfInterest);
Ted Kremenek03325582013-02-21 01:29:01 +00001019 const Optional<bool> &V = shouldVisitCursor(Cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00001020 if (!V.hasValue())
1021 continue;
1022 if (!V.getValue())
1023 return false;
1024 if (Visit(Cursor, true))
1025 return true;
1026 }
1027 return false;
1028}
1029
1030bool CursorVisitor::VisitObjCCategoryDecl(ObjCCategoryDecl *ND) {
1031 if (Visit(MakeCursorObjCClassRef(ND->getClassInterface(), ND->getLocation(),
1032 TU)))
1033 return true;
1034
Douglas Gregore9d95f12015-07-07 03:57:35 +00001035 if (VisitObjCTypeParamList(ND->getTypeParamList()))
1036 return true;
1037
Guy Benyei11169dd2012-12-18 14:30:41 +00001038 ObjCCategoryDecl::protocol_loc_iterator PL = ND->protocol_loc_begin();
1039 for (ObjCCategoryDecl::protocol_iterator I = ND->protocol_begin(),
1040 E = ND->protocol_end(); I != E; ++I, ++PL)
1041 if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
1042 return true;
1043
1044 return VisitObjCContainerDecl(ND);
1045}
1046
1047bool CursorVisitor::VisitObjCProtocolDecl(ObjCProtocolDecl *PID) {
1048 if (!PID->isThisDeclarationADefinition())
1049 return Visit(MakeCursorObjCProtocolRef(PID, PID->getLocation(), TU));
1050
1051 ObjCProtocolDecl::protocol_loc_iterator PL = PID->protocol_loc_begin();
1052 for (ObjCProtocolDecl::protocol_iterator I = PID->protocol_begin(),
1053 E = PID->protocol_end(); I != E; ++I, ++PL)
1054 if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
1055 return true;
1056
1057 return VisitObjCContainerDecl(PID);
1058}
1059
1060bool CursorVisitor::VisitObjCPropertyDecl(ObjCPropertyDecl *PD) {
1061 if (PD->getTypeSourceInfo() && Visit(PD->getTypeSourceInfo()->getTypeLoc()))
1062 return true;
1063
1064 // FIXME: This implements a workaround with @property declarations also being
1065 // installed in the DeclContext for the @interface. Eventually this code
1066 // should be removed.
1067 ObjCCategoryDecl *CDecl = dyn_cast<ObjCCategoryDecl>(PD->getDeclContext());
1068 if (!CDecl || !CDecl->IsClassExtension())
1069 return false;
1070
1071 ObjCInterfaceDecl *ID = CDecl->getClassInterface();
1072 if (!ID)
1073 return false;
1074
1075 IdentifierInfo *PropertyId = PD->getIdentifier();
1076 ObjCPropertyDecl *prevDecl =
Manman Ren5b786402016-01-28 18:49:28 +00001077 ObjCPropertyDecl::findPropertyDecl(cast<DeclContext>(ID), PropertyId,
1078 PD->getQueryKind());
Guy Benyei11169dd2012-12-18 14:30:41 +00001079
1080 if (!prevDecl)
1081 return false;
1082
1083 // Visit synthesized methods since they will be skipped when visiting
1084 // the @interface.
1085 if (ObjCMethodDecl *MD = prevDecl->getGetterMethodDecl())
1086 if (MD->isPropertyAccessor() && MD->getLexicalDeclContext() == CDecl)
1087 if (Visit(MakeCXCursor(MD, TU, RegionOfInterest)))
1088 return true;
1089
1090 if (ObjCMethodDecl *MD = prevDecl->getSetterMethodDecl())
1091 if (MD->isPropertyAccessor() && MD->getLexicalDeclContext() == CDecl)
1092 if (Visit(MakeCXCursor(MD, TU, RegionOfInterest)))
1093 return true;
1094
1095 return false;
1096}
1097
Douglas Gregore9d95f12015-07-07 03:57:35 +00001098bool CursorVisitor::VisitObjCTypeParamList(ObjCTypeParamList *typeParamList) {
1099 if (!typeParamList)
1100 return false;
1101
1102 for (auto *typeParam : *typeParamList) {
1103 // Visit the type parameter.
1104 if (Visit(MakeCXCursor(typeParam, TU, RegionOfInterest)))
1105 return true;
Douglas Gregore9d95f12015-07-07 03:57:35 +00001106 }
1107
1108 return false;
1109}
1110
Guy Benyei11169dd2012-12-18 14:30:41 +00001111bool CursorVisitor::VisitObjCInterfaceDecl(ObjCInterfaceDecl *D) {
1112 if (!D->isThisDeclarationADefinition()) {
1113 // Forward declaration is treated like a reference.
1114 return Visit(MakeCursorObjCClassRef(D, D->getLocation(), TU));
1115 }
1116
Douglas Gregore9d95f12015-07-07 03:57:35 +00001117 // Objective-C type parameters.
1118 if (VisitObjCTypeParamList(D->getTypeParamListAsWritten()))
1119 return true;
1120
Guy Benyei11169dd2012-12-18 14:30:41 +00001121 // Issue callbacks for super class.
1122 if (D->getSuperClass() &&
1123 Visit(MakeCursorObjCSuperClassRef(D->getSuperClass(),
1124 D->getSuperClassLoc(),
1125 TU)))
1126 return true;
1127
Douglas Gregore9d95f12015-07-07 03:57:35 +00001128 if (TypeSourceInfo *SuperClassTInfo = D->getSuperClassTInfo())
1129 if (Visit(SuperClassTInfo->getTypeLoc()))
1130 return true;
1131
Guy Benyei11169dd2012-12-18 14:30:41 +00001132 ObjCInterfaceDecl::protocol_loc_iterator PL = D->protocol_loc_begin();
1133 for (ObjCInterfaceDecl::protocol_iterator I = D->protocol_begin(),
1134 E = D->protocol_end(); I != E; ++I, ++PL)
1135 if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
1136 return true;
1137
1138 return VisitObjCContainerDecl(D);
1139}
1140
1141bool CursorVisitor::VisitObjCImplDecl(ObjCImplDecl *D) {
1142 return VisitObjCContainerDecl(D);
1143}
1144
1145bool CursorVisitor::VisitObjCCategoryImplDecl(ObjCCategoryImplDecl *D) {
1146 // 'ID' could be null when dealing with invalid code.
1147 if (ObjCInterfaceDecl *ID = D->getClassInterface())
1148 if (Visit(MakeCursorObjCClassRef(ID, D->getLocation(), TU)))
1149 return true;
1150
1151 return VisitObjCImplDecl(D);
1152}
1153
1154bool CursorVisitor::VisitObjCImplementationDecl(ObjCImplementationDecl *D) {
1155#if 0
1156 // Issue callbacks for super class.
1157 // FIXME: No source location information!
1158 if (D->getSuperClass() &&
1159 Visit(MakeCursorObjCSuperClassRef(D->getSuperClass(),
1160 D->getSuperClassLoc(),
1161 TU)))
1162 return true;
1163#endif
1164
1165 return VisitObjCImplDecl(D);
1166}
1167
1168bool CursorVisitor::VisitObjCPropertyImplDecl(ObjCPropertyImplDecl *PD) {
1169 if (ObjCIvarDecl *Ivar = PD->getPropertyIvarDecl())
1170 if (PD->isIvarNameSpecified())
1171 return Visit(MakeCursorMemberRef(Ivar, PD->getPropertyIvarDeclLoc(), TU));
1172
1173 return false;
1174}
1175
1176bool CursorVisitor::VisitNamespaceDecl(NamespaceDecl *D) {
1177 return VisitDeclContext(D);
1178}
1179
1180bool CursorVisitor::VisitNamespaceAliasDecl(NamespaceAliasDecl *D) {
1181 // Visit nested-name-specifier.
1182 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1183 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1184 return true;
1185
1186 return Visit(MakeCursorNamespaceRef(D->getAliasedNamespace(),
1187 D->getTargetNameLoc(), TU));
1188}
1189
1190bool CursorVisitor::VisitUsingDecl(UsingDecl *D) {
1191 // Visit nested-name-specifier.
1192 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc()) {
1193 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1194 return true;
1195 }
1196
1197 if (Visit(MakeCursorOverloadedDeclRef(D, D->getLocation(), TU)))
1198 return true;
1199
1200 return VisitDeclarationNameInfo(D->getNameInfo());
1201}
1202
1203bool CursorVisitor::VisitUsingDirectiveDecl(UsingDirectiveDecl *D) {
1204 // Visit nested-name-specifier.
1205 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1206 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1207 return true;
1208
1209 return Visit(MakeCursorNamespaceRef(D->getNominatedNamespaceAsWritten(),
1210 D->getIdentLocation(), TU));
1211}
1212
1213bool CursorVisitor::VisitUnresolvedUsingValueDecl(UnresolvedUsingValueDecl *D) {
1214 // Visit nested-name-specifier.
1215 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc()) {
1216 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1217 return true;
1218 }
1219
1220 return VisitDeclarationNameInfo(D->getNameInfo());
1221}
1222
1223bool CursorVisitor::VisitUnresolvedUsingTypenameDecl(
1224 UnresolvedUsingTypenameDecl *D) {
1225 // Visit nested-name-specifier.
1226 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1227 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1228 return true;
1229
1230 return false;
1231}
1232
1233bool CursorVisitor::VisitDeclarationNameInfo(DeclarationNameInfo Name) {
1234 switch (Name.getName().getNameKind()) {
1235 case clang::DeclarationName::Identifier:
1236 case clang::DeclarationName::CXXLiteralOperatorName:
1237 case clang::DeclarationName::CXXOperatorName:
1238 case clang::DeclarationName::CXXUsingDirective:
1239 return false;
1240
1241 case clang::DeclarationName::CXXConstructorName:
1242 case clang::DeclarationName::CXXDestructorName:
1243 case clang::DeclarationName::CXXConversionFunctionName:
1244 if (TypeSourceInfo *TSInfo = Name.getNamedTypeInfo())
1245 return Visit(TSInfo->getTypeLoc());
1246 return false;
1247
1248 case clang::DeclarationName::ObjCZeroArgSelector:
1249 case clang::DeclarationName::ObjCOneArgSelector:
1250 case clang::DeclarationName::ObjCMultiArgSelector:
1251 // FIXME: Per-identifier location info?
1252 return false;
1253 }
1254
1255 llvm_unreachable("Invalid DeclarationName::Kind!");
1256}
1257
1258bool CursorVisitor::VisitNestedNameSpecifier(NestedNameSpecifier *NNS,
1259 SourceRange Range) {
1260 // FIXME: This whole routine is a hack to work around the lack of proper
1261 // source information in nested-name-specifiers (PR5791). Since we do have
1262 // a beginning source location, we can visit the first component of the
1263 // nested-name-specifier, if it's a single-token component.
1264 if (!NNS)
1265 return false;
1266
1267 // Get the first component in the nested-name-specifier.
1268 while (NestedNameSpecifier *Prefix = NNS->getPrefix())
1269 NNS = Prefix;
1270
1271 switch (NNS->getKind()) {
1272 case NestedNameSpecifier::Namespace:
1273 return Visit(MakeCursorNamespaceRef(NNS->getAsNamespace(), Range.getBegin(),
1274 TU));
1275
1276 case NestedNameSpecifier::NamespaceAlias:
1277 return Visit(MakeCursorNamespaceRef(NNS->getAsNamespaceAlias(),
1278 Range.getBegin(), TU));
1279
1280 case NestedNameSpecifier::TypeSpec: {
1281 // If the type has a form where we know that the beginning of the source
1282 // range matches up with a reference cursor. Visit the appropriate reference
1283 // cursor.
1284 const Type *T = NNS->getAsType();
1285 if (const TypedefType *Typedef = dyn_cast<TypedefType>(T))
1286 return Visit(MakeCursorTypeRef(Typedef->getDecl(), Range.getBegin(), TU));
1287 if (const TagType *Tag = dyn_cast<TagType>(T))
1288 return Visit(MakeCursorTypeRef(Tag->getDecl(), Range.getBegin(), TU));
1289 if (const TemplateSpecializationType *TST
1290 = dyn_cast<TemplateSpecializationType>(T))
1291 return VisitTemplateName(TST->getTemplateName(), Range.getBegin());
1292 break;
1293 }
1294
1295 case NestedNameSpecifier::TypeSpecWithTemplate:
1296 case NestedNameSpecifier::Global:
1297 case NestedNameSpecifier::Identifier:
Nikola Smiljanic67860242014-09-26 00:28:20 +00001298 case NestedNameSpecifier::Super:
Guy Benyei11169dd2012-12-18 14:30:41 +00001299 break;
1300 }
1301
1302 return false;
1303}
1304
1305bool
1306CursorVisitor::VisitNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier) {
1307 SmallVector<NestedNameSpecifierLoc, 4> Qualifiers;
1308 for (; Qualifier; Qualifier = Qualifier.getPrefix())
1309 Qualifiers.push_back(Qualifier);
1310
1311 while (!Qualifiers.empty()) {
1312 NestedNameSpecifierLoc Q = Qualifiers.pop_back_val();
1313 NestedNameSpecifier *NNS = Q.getNestedNameSpecifier();
1314 switch (NNS->getKind()) {
1315 case NestedNameSpecifier::Namespace:
1316 if (Visit(MakeCursorNamespaceRef(NNS->getAsNamespace(),
1317 Q.getLocalBeginLoc(),
1318 TU)))
1319 return true;
1320
1321 break;
1322
1323 case NestedNameSpecifier::NamespaceAlias:
1324 if (Visit(MakeCursorNamespaceRef(NNS->getAsNamespaceAlias(),
1325 Q.getLocalBeginLoc(),
1326 TU)))
1327 return true;
1328
1329 break;
1330
1331 case NestedNameSpecifier::TypeSpec:
1332 case NestedNameSpecifier::TypeSpecWithTemplate:
1333 if (Visit(Q.getTypeLoc()))
1334 return true;
1335
1336 break;
1337
1338 case NestedNameSpecifier::Global:
1339 case NestedNameSpecifier::Identifier:
Nikola Smiljanic67860242014-09-26 00:28:20 +00001340 case NestedNameSpecifier::Super:
Guy Benyei11169dd2012-12-18 14:30:41 +00001341 break;
1342 }
1343 }
1344
1345 return false;
1346}
1347
1348bool CursorVisitor::VisitTemplateParameters(
1349 const TemplateParameterList *Params) {
1350 if (!Params)
1351 return false;
1352
1353 for (TemplateParameterList::const_iterator P = Params->begin(),
1354 PEnd = Params->end();
1355 P != PEnd; ++P) {
1356 if (Visit(MakeCXCursor(*P, TU, RegionOfInterest)))
1357 return true;
1358 }
1359
1360 return false;
1361}
1362
1363bool CursorVisitor::VisitTemplateName(TemplateName Name, SourceLocation Loc) {
1364 switch (Name.getKind()) {
1365 case TemplateName::Template:
1366 return Visit(MakeCursorTemplateRef(Name.getAsTemplateDecl(), Loc, TU));
1367
1368 case TemplateName::OverloadedTemplate:
1369 // Visit the overloaded template set.
1370 if (Visit(MakeCursorOverloadedDeclRef(Name, Loc, TU)))
1371 return true;
1372
1373 return false;
1374
1375 case TemplateName::DependentTemplate:
1376 // FIXME: Visit nested-name-specifier.
1377 return false;
1378
1379 case TemplateName::QualifiedTemplate:
1380 // FIXME: Visit nested-name-specifier.
1381 return Visit(MakeCursorTemplateRef(
1382 Name.getAsQualifiedTemplateName()->getDecl(),
1383 Loc, TU));
1384
1385 case TemplateName::SubstTemplateTemplateParm:
1386 return Visit(MakeCursorTemplateRef(
1387 Name.getAsSubstTemplateTemplateParm()->getParameter(),
1388 Loc, TU));
1389
1390 case TemplateName::SubstTemplateTemplateParmPack:
1391 return Visit(MakeCursorTemplateRef(
1392 Name.getAsSubstTemplateTemplateParmPack()->getParameterPack(),
1393 Loc, TU));
1394 }
1395
1396 llvm_unreachable("Invalid TemplateName::Kind!");
1397}
1398
1399bool CursorVisitor::VisitTemplateArgumentLoc(const TemplateArgumentLoc &TAL) {
1400 switch (TAL.getArgument().getKind()) {
1401 case TemplateArgument::Null:
1402 case TemplateArgument::Integral:
1403 case TemplateArgument::Pack:
1404 return false;
1405
1406 case TemplateArgument::Type:
1407 if (TypeSourceInfo *TSInfo = TAL.getTypeSourceInfo())
1408 return Visit(TSInfo->getTypeLoc());
1409 return false;
1410
1411 case TemplateArgument::Declaration:
1412 if (Expr *E = TAL.getSourceDeclExpression())
1413 return Visit(MakeCXCursor(E, StmtParent, TU, RegionOfInterest));
1414 return false;
1415
1416 case TemplateArgument::NullPtr:
1417 if (Expr *E = TAL.getSourceNullPtrExpression())
1418 return Visit(MakeCXCursor(E, StmtParent, TU, RegionOfInterest));
1419 return false;
1420
1421 case TemplateArgument::Expression:
1422 if (Expr *E = TAL.getSourceExpression())
1423 return Visit(MakeCXCursor(E, StmtParent, TU, RegionOfInterest));
1424 return false;
1425
1426 case TemplateArgument::Template:
1427 case TemplateArgument::TemplateExpansion:
1428 if (VisitNestedNameSpecifierLoc(TAL.getTemplateQualifierLoc()))
1429 return true;
1430
1431 return VisitTemplateName(TAL.getArgument().getAsTemplateOrTemplatePattern(),
1432 TAL.getTemplateNameLoc());
1433 }
1434
1435 llvm_unreachable("Invalid TemplateArgument::Kind!");
1436}
1437
1438bool CursorVisitor::VisitLinkageSpecDecl(LinkageSpecDecl *D) {
1439 return VisitDeclContext(D);
1440}
1441
1442bool CursorVisitor::VisitQualifiedTypeLoc(QualifiedTypeLoc TL) {
1443 return Visit(TL.getUnqualifiedLoc());
1444}
1445
1446bool CursorVisitor::VisitBuiltinTypeLoc(BuiltinTypeLoc TL) {
1447 ASTContext &Context = AU->getASTContext();
1448
1449 // Some builtin types (such as Objective-C's "id", "sel", and
1450 // "Class") have associated declarations. Create cursors for those.
1451 QualType VisitType;
1452 switch (TL.getTypePtr()->getKind()) {
1453
1454 case BuiltinType::Void:
1455 case BuiltinType::NullPtr:
1456 case BuiltinType::Dependent:
Guy Benyeid8a08ea2012-12-18 14:38:23 +00001457 case BuiltinType::OCLImage1d:
1458 case BuiltinType::OCLImage1dArray:
1459 case BuiltinType::OCLImage1dBuffer:
1460 case BuiltinType::OCLImage2d:
1461 case BuiltinType::OCLImage2dArray:
Alexey Bader9c8453f2015-09-15 11:18:52 +00001462 case BuiltinType::OCLImage2dDepth:
1463 case BuiltinType::OCLImage2dArrayDepth:
1464 case BuiltinType::OCLImage2dMSAA:
1465 case BuiltinType::OCLImage2dArrayMSAA:
1466 case BuiltinType::OCLImage2dMSAADepth:
1467 case BuiltinType::OCLImage2dArrayMSAADepth:
Guy Benyeid8a08ea2012-12-18 14:38:23 +00001468 case BuiltinType::OCLImage3d:
NAKAMURA Takumi288c42e2013-02-07 12:47:42 +00001469 case BuiltinType::OCLSampler:
Guy Benyei1b4fb3e2013-01-20 12:31:11 +00001470 case BuiltinType::OCLEvent:
Alexey Bader9c8453f2015-09-15 11:18:52 +00001471 case BuiltinType::OCLClkEvent:
1472 case BuiltinType::OCLQueue:
1473 case BuiltinType::OCLNDRange:
1474 case BuiltinType::OCLReserveID:
Guy Benyei11169dd2012-12-18 14:30:41 +00001475#define BUILTIN_TYPE(Id, SingletonId)
1476#define SIGNED_TYPE(Id, SingletonId) case BuiltinType::Id:
1477#define UNSIGNED_TYPE(Id, SingletonId) case BuiltinType::Id:
1478#define FLOATING_TYPE(Id, SingletonId) case BuiltinType::Id:
1479#define PLACEHOLDER_TYPE(Id, SingletonId) case BuiltinType::Id:
1480#include "clang/AST/BuiltinTypes.def"
1481 break;
1482
1483 case BuiltinType::ObjCId:
1484 VisitType = Context.getObjCIdType();
1485 break;
1486
1487 case BuiltinType::ObjCClass:
1488 VisitType = Context.getObjCClassType();
1489 break;
1490
1491 case BuiltinType::ObjCSel:
1492 VisitType = Context.getObjCSelType();
1493 break;
1494 }
1495
1496 if (!VisitType.isNull()) {
1497 if (const TypedefType *Typedef = VisitType->getAs<TypedefType>())
1498 return Visit(MakeCursorTypeRef(Typedef->getDecl(), TL.getBuiltinLoc(),
1499 TU));
1500 }
1501
1502 return false;
1503}
1504
1505bool CursorVisitor::VisitTypedefTypeLoc(TypedefTypeLoc TL) {
1506 return Visit(MakeCursorTypeRef(TL.getTypedefNameDecl(), TL.getNameLoc(), TU));
1507}
1508
1509bool CursorVisitor::VisitUnresolvedUsingTypeLoc(UnresolvedUsingTypeLoc TL) {
1510 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1511}
1512
1513bool CursorVisitor::VisitTagTypeLoc(TagTypeLoc TL) {
1514 if (TL.isDefinition())
1515 return Visit(MakeCXCursor(TL.getDecl(), TU, RegionOfInterest));
1516
1517 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1518}
1519
1520bool CursorVisitor::VisitTemplateTypeParmTypeLoc(TemplateTypeParmTypeLoc TL) {
1521 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1522}
1523
1524bool CursorVisitor::VisitObjCInterfaceTypeLoc(ObjCInterfaceTypeLoc TL) {
Hans Wennborg59dbe862015-09-29 20:56:43 +00001525 return Visit(MakeCursorObjCClassRef(TL.getIFaceDecl(), TL.getNameLoc(), TU));
Guy Benyei11169dd2012-12-18 14:30:41 +00001526}
1527
1528bool CursorVisitor::VisitObjCObjectTypeLoc(ObjCObjectTypeLoc TL) {
1529 if (TL.hasBaseTypeAsWritten() && Visit(TL.getBaseLoc()))
1530 return true;
1531
Douglas Gregore9d95f12015-07-07 03:57:35 +00001532 for (unsigned I = 0, N = TL.getNumTypeArgs(); I != N; ++I) {
1533 if (Visit(TL.getTypeArgTInfo(I)->getTypeLoc()))
1534 return true;
1535 }
1536
Guy Benyei11169dd2012-12-18 14:30:41 +00001537 for (unsigned I = 0, N = TL.getNumProtocols(); I != N; ++I) {
1538 if (Visit(MakeCursorObjCProtocolRef(TL.getProtocol(I), TL.getProtocolLoc(I),
1539 TU)))
1540 return true;
1541 }
1542
1543 return false;
1544}
1545
1546bool CursorVisitor::VisitObjCObjectPointerTypeLoc(ObjCObjectPointerTypeLoc TL) {
1547 return Visit(TL.getPointeeLoc());
1548}
1549
1550bool CursorVisitor::VisitParenTypeLoc(ParenTypeLoc TL) {
1551 return Visit(TL.getInnerLoc());
1552}
1553
1554bool CursorVisitor::VisitPointerTypeLoc(PointerTypeLoc TL) {
1555 return Visit(TL.getPointeeLoc());
1556}
1557
1558bool CursorVisitor::VisitBlockPointerTypeLoc(BlockPointerTypeLoc TL) {
1559 return Visit(TL.getPointeeLoc());
1560}
1561
1562bool CursorVisitor::VisitMemberPointerTypeLoc(MemberPointerTypeLoc TL) {
1563 return Visit(TL.getPointeeLoc());
1564}
1565
1566bool CursorVisitor::VisitLValueReferenceTypeLoc(LValueReferenceTypeLoc TL) {
1567 return Visit(TL.getPointeeLoc());
1568}
1569
1570bool CursorVisitor::VisitRValueReferenceTypeLoc(RValueReferenceTypeLoc TL) {
1571 return Visit(TL.getPointeeLoc());
1572}
1573
1574bool CursorVisitor::VisitAttributedTypeLoc(AttributedTypeLoc TL) {
1575 return Visit(TL.getModifiedLoc());
1576}
1577
1578bool CursorVisitor::VisitFunctionTypeLoc(FunctionTypeLoc TL,
1579 bool SkipResultType) {
Alp Toker42a16a62014-01-25 23:51:36 +00001580 if (!SkipResultType && Visit(TL.getReturnLoc()))
Guy Benyei11169dd2012-12-18 14:30:41 +00001581 return true;
1582
Alp Tokerb3fd5cf2014-01-21 00:32:38 +00001583 for (unsigned I = 0, N = TL.getNumParams(); I != N; ++I)
1584 if (Decl *D = TL.getParam(I))
Guy Benyei11169dd2012-12-18 14:30:41 +00001585 if (Visit(MakeCXCursor(D, TU, RegionOfInterest)))
1586 return true;
1587
1588 return false;
1589}
1590
1591bool CursorVisitor::VisitArrayTypeLoc(ArrayTypeLoc TL) {
1592 if (Visit(TL.getElementLoc()))
1593 return true;
1594
1595 if (Expr *Size = TL.getSizeExpr())
1596 return Visit(MakeCXCursor(Size, StmtParent, TU, RegionOfInterest));
1597
1598 return false;
1599}
1600
Reid Kleckner8a365022013-06-24 17:51:48 +00001601bool CursorVisitor::VisitDecayedTypeLoc(DecayedTypeLoc TL) {
1602 return Visit(TL.getOriginalLoc());
1603}
1604
Reid Kleckner0503a872013-12-05 01:23:43 +00001605bool CursorVisitor::VisitAdjustedTypeLoc(AdjustedTypeLoc TL) {
1606 return Visit(TL.getOriginalLoc());
1607}
1608
Guy Benyei11169dd2012-12-18 14:30:41 +00001609bool CursorVisitor::VisitTemplateSpecializationTypeLoc(
1610 TemplateSpecializationTypeLoc TL) {
1611 // Visit the template name.
1612 if (VisitTemplateName(TL.getTypePtr()->getTemplateName(),
1613 TL.getTemplateNameLoc()))
1614 return true;
1615
1616 // Visit the template arguments.
1617 for (unsigned I = 0, N = TL.getNumArgs(); I != N; ++I)
1618 if (VisitTemplateArgumentLoc(TL.getArgLoc(I)))
1619 return true;
1620
1621 return false;
1622}
1623
1624bool CursorVisitor::VisitTypeOfExprTypeLoc(TypeOfExprTypeLoc TL) {
1625 return Visit(MakeCXCursor(TL.getUnderlyingExpr(), StmtParent, TU));
1626}
1627
1628bool CursorVisitor::VisitTypeOfTypeLoc(TypeOfTypeLoc TL) {
1629 if (TypeSourceInfo *TSInfo = TL.getUnderlyingTInfo())
1630 return Visit(TSInfo->getTypeLoc());
1631
1632 return false;
1633}
1634
1635bool CursorVisitor::VisitUnaryTransformTypeLoc(UnaryTransformTypeLoc TL) {
1636 if (TypeSourceInfo *TSInfo = TL.getUnderlyingTInfo())
1637 return Visit(TSInfo->getTypeLoc());
1638
1639 return false;
1640}
1641
1642bool CursorVisitor::VisitDependentNameTypeLoc(DependentNameTypeLoc TL) {
Hans Wennborg59dbe862015-09-29 20:56:43 +00001643 return VisitNestedNameSpecifierLoc(TL.getQualifierLoc());
Guy Benyei11169dd2012-12-18 14:30:41 +00001644}
1645
1646bool CursorVisitor::VisitDependentTemplateSpecializationTypeLoc(
1647 DependentTemplateSpecializationTypeLoc TL) {
1648 // Visit the nested-name-specifier, if there is one.
1649 if (TL.getQualifierLoc() &&
1650 VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
1651 return true;
1652
1653 // Visit the template arguments.
1654 for (unsigned I = 0, N = TL.getNumArgs(); I != N; ++I)
1655 if (VisitTemplateArgumentLoc(TL.getArgLoc(I)))
1656 return true;
1657
1658 return false;
1659}
1660
1661bool CursorVisitor::VisitElaboratedTypeLoc(ElaboratedTypeLoc TL) {
1662 if (VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
1663 return true;
1664
1665 return Visit(TL.getNamedTypeLoc());
1666}
1667
1668bool CursorVisitor::VisitPackExpansionTypeLoc(PackExpansionTypeLoc TL) {
1669 return Visit(TL.getPatternLoc());
1670}
1671
1672bool CursorVisitor::VisitDecltypeTypeLoc(DecltypeTypeLoc TL) {
1673 if (Expr *E = TL.getUnderlyingExpr())
1674 return Visit(MakeCXCursor(E, StmtParent, TU));
1675
1676 return false;
1677}
1678
1679bool CursorVisitor::VisitInjectedClassNameTypeLoc(InjectedClassNameTypeLoc TL) {
1680 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1681}
1682
1683bool CursorVisitor::VisitAtomicTypeLoc(AtomicTypeLoc TL) {
1684 return Visit(TL.getValueLoc());
1685}
1686
Xiuli Pan9c14e282016-01-09 12:53:17 +00001687bool CursorVisitor::VisitPipeTypeLoc(PipeTypeLoc TL) {
1688 return Visit(TL.getValueLoc());
1689}
1690
Guy Benyei11169dd2012-12-18 14:30:41 +00001691#define DEFAULT_TYPELOC_IMPL(CLASS, PARENT) \
1692bool CursorVisitor::Visit##CLASS##TypeLoc(CLASS##TypeLoc TL) { \
1693 return Visit##PARENT##Loc(TL); \
1694}
1695
1696DEFAULT_TYPELOC_IMPL(Complex, Type)
1697DEFAULT_TYPELOC_IMPL(ConstantArray, ArrayType)
1698DEFAULT_TYPELOC_IMPL(IncompleteArray, ArrayType)
1699DEFAULT_TYPELOC_IMPL(VariableArray, ArrayType)
1700DEFAULT_TYPELOC_IMPL(DependentSizedArray, ArrayType)
1701DEFAULT_TYPELOC_IMPL(DependentSizedExtVector, Type)
1702DEFAULT_TYPELOC_IMPL(Vector, Type)
1703DEFAULT_TYPELOC_IMPL(ExtVector, VectorType)
1704DEFAULT_TYPELOC_IMPL(FunctionProto, FunctionType)
1705DEFAULT_TYPELOC_IMPL(FunctionNoProto, FunctionType)
1706DEFAULT_TYPELOC_IMPL(Record, TagType)
1707DEFAULT_TYPELOC_IMPL(Enum, TagType)
1708DEFAULT_TYPELOC_IMPL(SubstTemplateTypeParm, Type)
1709DEFAULT_TYPELOC_IMPL(SubstTemplateTypeParmPack, Type)
1710DEFAULT_TYPELOC_IMPL(Auto, Type)
1711
1712bool CursorVisitor::VisitCXXRecordDecl(CXXRecordDecl *D) {
1713 // Visit the nested-name-specifier, if present.
1714 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1715 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1716 return true;
1717
1718 if (D->isCompleteDefinition()) {
Aaron Ballman574705e2014-03-13 15:41:46 +00001719 for (const auto &I : D->bases()) {
1720 if (Visit(cxcursor::MakeCursorCXXBaseSpecifier(&I, TU)))
Guy Benyei11169dd2012-12-18 14:30:41 +00001721 return true;
1722 }
1723 }
1724
1725 return VisitTagDecl(D);
1726}
1727
1728bool CursorVisitor::VisitAttributes(Decl *D) {
Aaron Ballmanb97112e2014-03-08 22:19:01 +00001729 for (const auto *I : D->attrs())
1730 if (Visit(MakeCXCursor(I, D, TU)))
Guy Benyei11169dd2012-12-18 14:30:41 +00001731 return true;
1732
1733 return false;
1734}
1735
1736//===----------------------------------------------------------------------===//
1737// Data-recursive visitor methods.
1738//===----------------------------------------------------------------------===//
1739
1740namespace {
1741#define DEF_JOB(NAME, DATA, KIND)\
1742class NAME : public VisitorJob {\
1743public:\
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001744 NAME(const DATA *d, CXCursor parent) : \
1745 VisitorJob(parent, VisitorJob::KIND, d) {} \
Guy Benyei11169dd2012-12-18 14:30:41 +00001746 static bool classof(const VisitorJob *VJ) { return VJ->getKind() == KIND; }\
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001747 const DATA *get() const { return static_cast<const DATA*>(data[0]); }\
Guy Benyei11169dd2012-12-18 14:30:41 +00001748};
1749
1750DEF_JOB(StmtVisit, Stmt, StmtVisitKind)
1751DEF_JOB(MemberExprParts, MemberExpr, MemberExprPartsKind)
1752DEF_JOB(DeclRefExprParts, DeclRefExpr, DeclRefExprPartsKind)
1753DEF_JOB(OverloadExprParts, OverloadExpr, OverloadExprPartsKind)
Guy Benyei11169dd2012-12-18 14:30:41 +00001754DEF_JOB(SizeOfPackExprParts, SizeOfPackExpr, SizeOfPackExprPartsKind)
1755DEF_JOB(LambdaExprParts, LambdaExpr, LambdaExprPartsKind)
1756DEF_JOB(PostChildrenVisit, void, PostChildrenVisitKind)
1757#undef DEF_JOB
1758
James Y Knight04ec5bf2015-12-24 02:59:37 +00001759class ExplicitTemplateArgsVisit : public VisitorJob {
1760public:
1761 ExplicitTemplateArgsVisit(const TemplateArgumentLoc *Begin,
1762 const TemplateArgumentLoc *End, CXCursor parent)
1763 : VisitorJob(parent, VisitorJob::ExplicitTemplateArgsVisitKind, Begin,
1764 End) {}
1765 static bool classof(const VisitorJob *VJ) {
1766 return VJ->getKind() == ExplicitTemplateArgsVisitKind;
1767 }
1768 const TemplateArgumentLoc *begin() const {
1769 return static_cast<const TemplateArgumentLoc *>(data[0]);
1770 }
1771 const TemplateArgumentLoc *end() {
1772 return static_cast<const TemplateArgumentLoc *>(data[1]);
1773 }
1774};
Guy Benyei11169dd2012-12-18 14:30:41 +00001775class DeclVisit : public VisitorJob {
1776public:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001777 DeclVisit(const Decl *D, CXCursor parent, bool isFirst) :
Guy Benyei11169dd2012-12-18 14:30:41 +00001778 VisitorJob(parent, VisitorJob::DeclVisitKind,
Craig Topper69186e72014-06-08 08:38:04 +00001779 D, isFirst ? (void*) 1 : (void*) nullptr) {}
Guy Benyei11169dd2012-12-18 14:30:41 +00001780 static bool classof(const VisitorJob *VJ) {
1781 return VJ->getKind() == DeclVisitKind;
1782 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001783 const Decl *get() const { return static_cast<const Decl *>(data[0]); }
Dmitri Gribenkoe5423a72015-03-23 19:23:50 +00001784 bool isFirst() const { return data[1] != nullptr; }
Guy Benyei11169dd2012-12-18 14:30:41 +00001785};
1786class TypeLocVisit : public VisitorJob {
1787public:
1788 TypeLocVisit(TypeLoc tl, CXCursor parent) :
1789 VisitorJob(parent, VisitorJob::TypeLocVisitKind,
1790 tl.getType().getAsOpaquePtr(), tl.getOpaqueData()) {}
1791
1792 static bool classof(const VisitorJob *VJ) {
1793 return VJ->getKind() == TypeLocVisitKind;
1794 }
1795
1796 TypeLoc get() const {
1797 QualType T = QualType::getFromOpaquePtr(data[0]);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001798 return TypeLoc(T, const_cast<void *>(data[1]));
Guy Benyei11169dd2012-12-18 14:30:41 +00001799 }
1800};
1801
1802class LabelRefVisit : public VisitorJob {
1803public:
1804 LabelRefVisit(LabelDecl *LD, SourceLocation labelLoc, CXCursor parent)
1805 : VisitorJob(parent, VisitorJob::LabelRefVisitKind, LD,
1806 labelLoc.getPtrEncoding()) {}
1807
1808 static bool classof(const VisitorJob *VJ) {
1809 return VJ->getKind() == VisitorJob::LabelRefVisitKind;
1810 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001811 const LabelDecl *get() const {
1812 return static_cast<const LabelDecl *>(data[0]);
1813 }
Guy Benyei11169dd2012-12-18 14:30:41 +00001814 SourceLocation getLoc() const {
1815 return SourceLocation::getFromPtrEncoding(data[1]); }
1816};
1817
1818class NestedNameSpecifierLocVisit : public VisitorJob {
1819public:
1820 NestedNameSpecifierLocVisit(NestedNameSpecifierLoc Qualifier, CXCursor parent)
1821 : VisitorJob(parent, VisitorJob::NestedNameSpecifierLocVisitKind,
1822 Qualifier.getNestedNameSpecifier(),
1823 Qualifier.getOpaqueData()) { }
1824
1825 static bool classof(const VisitorJob *VJ) {
1826 return VJ->getKind() == VisitorJob::NestedNameSpecifierLocVisitKind;
1827 }
1828
1829 NestedNameSpecifierLoc get() const {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001830 return NestedNameSpecifierLoc(
1831 const_cast<NestedNameSpecifier *>(
1832 static_cast<const NestedNameSpecifier *>(data[0])),
1833 const_cast<void *>(data[1]));
Guy Benyei11169dd2012-12-18 14:30:41 +00001834 }
1835};
1836
1837class DeclarationNameInfoVisit : public VisitorJob {
1838public:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001839 DeclarationNameInfoVisit(const Stmt *S, CXCursor parent)
Dmitri Gribenkodd7dacf2013-02-03 13:19:54 +00001840 : VisitorJob(parent, VisitorJob::DeclarationNameInfoVisitKind, S) {}
Guy Benyei11169dd2012-12-18 14:30:41 +00001841 static bool classof(const VisitorJob *VJ) {
1842 return VJ->getKind() == VisitorJob::DeclarationNameInfoVisitKind;
1843 }
1844 DeclarationNameInfo get() const {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001845 const Stmt *S = static_cast<const Stmt *>(data[0]);
Guy Benyei11169dd2012-12-18 14:30:41 +00001846 switch (S->getStmtClass()) {
1847 default:
1848 llvm_unreachable("Unhandled Stmt");
1849 case clang::Stmt::MSDependentExistsStmtClass:
1850 return cast<MSDependentExistsStmt>(S)->getNameInfo();
1851 case Stmt::CXXDependentScopeMemberExprClass:
1852 return cast<CXXDependentScopeMemberExpr>(S)->getMemberNameInfo();
1853 case Stmt::DependentScopeDeclRefExprClass:
1854 return cast<DependentScopeDeclRefExpr>(S)->getNameInfo();
Alexander Musmand9ed09f2014-07-21 09:42:05 +00001855 case Stmt::OMPCriticalDirectiveClass:
1856 return cast<OMPCriticalDirective>(S)->getDirectiveName();
Guy Benyei11169dd2012-12-18 14:30:41 +00001857 }
1858 }
1859};
1860class MemberRefVisit : public VisitorJob {
1861public:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001862 MemberRefVisit(const FieldDecl *D, SourceLocation L, CXCursor parent)
Guy Benyei11169dd2012-12-18 14:30:41 +00001863 : VisitorJob(parent, VisitorJob::MemberRefVisitKind, D,
1864 L.getPtrEncoding()) {}
1865 static bool classof(const VisitorJob *VJ) {
1866 return VJ->getKind() == VisitorJob::MemberRefVisitKind;
1867 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001868 const FieldDecl *get() const {
1869 return static_cast<const FieldDecl *>(data[0]);
Guy Benyei11169dd2012-12-18 14:30:41 +00001870 }
1871 SourceLocation getLoc() const {
1872 return SourceLocation::getFromRawEncoding((unsigned)(uintptr_t) data[1]);
1873 }
1874};
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001875class EnqueueVisitor : public ConstStmtVisitor<EnqueueVisitor, void> {
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001876 friend class OMPClauseEnqueue;
Guy Benyei11169dd2012-12-18 14:30:41 +00001877 VisitorWorkList &WL;
1878 CXCursor Parent;
1879public:
1880 EnqueueVisitor(VisitorWorkList &wl, CXCursor parent)
1881 : WL(wl), Parent(parent) {}
1882
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001883 void VisitAddrLabelExpr(const AddrLabelExpr *E);
1884 void VisitBlockExpr(const BlockExpr *B);
1885 void VisitCompoundLiteralExpr(const CompoundLiteralExpr *E);
1886 void VisitCompoundStmt(const CompoundStmt *S);
1887 void VisitCXXDefaultArgExpr(const CXXDefaultArgExpr *E) { /* Do nothing. */ }
1888 void VisitMSDependentExistsStmt(const MSDependentExistsStmt *S);
1889 void VisitCXXDependentScopeMemberExpr(const CXXDependentScopeMemberExpr *E);
1890 void VisitCXXNewExpr(const CXXNewExpr *E);
1891 void VisitCXXScalarValueInitExpr(const CXXScalarValueInitExpr *E);
1892 void VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *E);
1893 void VisitCXXPseudoDestructorExpr(const CXXPseudoDestructorExpr *E);
1894 void VisitCXXTemporaryObjectExpr(const CXXTemporaryObjectExpr *E);
1895 void VisitCXXTypeidExpr(const CXXTypeidExpr *E);
1896 void VisitCXXUnresolvedConstructExpr(const CXXUnresolvedConstructExpr *E);
1897 void VisitCXXUuidofExpr(const CXXUuidofExpr *E);
1898 void VisitCXXCatchStmt(const CXXCatchStmt *S);
Argyrios Kyrtzidis99891242014-11-13 09:03:21 +00001899 void VisitCXXForRangeStmt(const CXXForRangeStmt *S);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001900 void VisitDeclRefExpr(const DeclRefExpr *D);
1901 void VisitDeclStmt(const DeclStmt *S);
1902 void VisitDependentScopeDeclRefExpr(const DependentScopeDeclRefExpr *E);
1903 void VisitDesignatedInitExpr(const DesignatedInitExpr *E);
1904 void VisitExplicitCastExpr(const ExplicitCastExpr *E);
1905 void VisitForStmt(const ForStmt *FS);
1906 void VisitGotoStmt(const GotoStmt *GS);
1907 void VisitIfStmt(const IfStmt *If);
1908 void VisitInitListExpr(const InitListExpr *IE);
1909 void VisitMemberExpr(const MemberExpr *M);
1910 void VisitOffsetOfExpr(const OffsetOfExpr *E);
1911 void VisitObjCEncodeExpr(const ObjCEncodeExpr *E);
1912 void VisitObjCMessageExpr(const ObjCMessageExpr *M);
1913 void VisitOverloadExpr(const OverloadExpr *E);
1914 void VisitUnaryExprOrTypeTraitExpr(const UnaryExprOrTypeTraitExpr *E);
1915 void VisitStmt(const Stmt *S);
1916 void VisitSwitchStmt(const SwitchStmt *S);
1917 void VisitWhileStmt(const WhileStmt *W);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001918 void VisitTypeTraitExpr(const TypeTraitExpr *E);
1919 void VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *E);
1920 void VisitExpressionTraitExpr(const ExpressionTraitExpr *E);
1921 void VisitUnresolvedMemberExpr(const UnresolvedMemberExpr *U);
1922 void VisitVAArgExpr(const VAArgExpr *E);
1923 void VisitSizeOfPackExpr(const SizeOfPackExpr *E);
1924 void VisitPseudoObjectExpr(const PseudoObjectExpr *E);
1925 void VisitOpaqueValueExpr(const OpaqueValueExpr *E);
1926 void VisitLambdaExpr(const LambdaExpr *E);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001927 void VisitOMPExecutableDirective(const OMPExecutableDirective *D);
Alexander Musman3aaab662014-08-19 11:27:13 +00001928 void VisitOMPLoopDirective(const OMPLoopDirective *D);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001929 void VisitOMPParallelDirective(const OMPParallelDirective *D);
Alexey Bataev1b59ab52014-02-27 08:29:12 +00001930 void VisitOMPSimdDirective(const OMPSimdDirective *D);
Alexey Bataevf29276e2014-06-18 04:14:57 +00001931 void VisitOMPForDirective(const OMPForDirective *D);
Alexander Musmanf82886e2014-09-18 05:12:34 +00001932 void VisitOMPForSimdDirective(const OMPForSimdDirective *D);
Alexey Bataevd3f8dd22014-06-25 11:44:49 +00001933 void VisitOMPSectionsDirective(const OMPSectionsDirective *D);
Alexey Bataev1e0498a2014-06-26 08:21:58 +00001934 void VisitOMPSectionDirective(const OMPSectionDirective *D);
Alexey Bataevd1e40fb2014-06-26 12:05:45 +00001935 void VisitOMPSingleDirective(const OMPSingleDirective *D);
Alexander Musman80c22892014-07-17 08:54:58 +00001936 void VisitOMPMasterDirective(const OMPMasterDirective *D);
Alexander Musmand9ed09f2014-07-21 09:42:05 +00001937 void VisitOMPCriticalDirective(const OMPCriticalDirective *D);
Alexey Bataev4acb8592014-07-07 13:01:15 +00001938 void VisitOMPParallelForDirective(const OMPParallelForDirective *D);
Alexander Musmane4e893b2014-09-23 09:33:00 +00001939 void VisitOMPParallelForSimdDirective(const OMPParallelForSimdDirective *D);
Alexey Bataev84d0b3e2014-07-08 08:12:03 +00001940 void VisitOMPParallelSectionsDirective(const OMPParallelSectionsDirective *D);
Alexey Bataev9c2e8ee2014-07-11 11:25:16 +00001941 void VisitOMPTaskDirective(const OMPTaskDirective *D);
Alexey Bataev68446b72014-07-18 07:47:19 +00001942 void VisitOMPTaskyieldDirective(const OMPTaskyieldDirective *D);
Alexey Bataev4d1dfea2014-07-18 09:11:51 +00001943 void VisitOMPBarrierDirective(const OMPBarrierDirective *D);
Alexey Bataev2df347a2014-07-18 10:17:07 +00001944 void VisitOMPTaskwaitDirective(const OMPTaskwaitDirective *D);
Alexey Bataevc30dd2d2015-06-18 12:14:09 +00001945 void VisitOMPTaskgroupDirective(const OMPTaskgroupDirective *D);
Alexey Bataev6d4ed052015-07-01 06:57:41 +00001946 void
1947 VisitOMPCancellationPointDirective(const OMPCancellationPointDirective *D);
Alexey Bataev80909872015-07-02 11:25:17 +00001948 void VisitOMPCancelDirective(const OMPCancelDirective *D);
Alexey Bataev6125da92014-07-21 11:26:11 +00001949 void VisitOMPFlushDirective(const OMPFlushDirective *D);
Alexey Bataev9fb6e642014-07-22 06:45:04 +00001950 void VisitOMPOrderedDirective(const OMPOrderedDirective *D);
Alexey Bataev0162e452014-07-22 10:10:35 +00001951 void VisitOMPAtomicDirective(const OMPAtomicDirective *D);
Alexey Bataev0bd520b2014-09-19 08:19:49 +00001952 void VisitOMPTargetDirective(const OMPTargetDirective *D);
Michael Wong65f367f2015-07-21 13:44:28 +00001953 void VisitOMPTargetDataDirective(const OMPTargetDataDirective *D);
Samuel Antaodf67fc42016-01-19 19:15:56 +00001954 void VisitOMPTargetEnterDataDirective(const OMPTargetEnterDataDirective *D);
Samuel Antao72590762016-01-19 20:04:50 +00001955 void VisitOMPTargetExitDataDirective(const OMPTargetExitDataDirective *D);
Arpith Chacko Jacobe955b3d2016-01-26 18:48:41 +00001956 void VisitOMPTargetParallelDirective(const OMPTargetParallelDirective *D);
Arpith Chacko Jacob05bebb52016-02-03 15:46:42 +00001957 void
1958 VisitOMPTargetParallelForDirective(const OMPTargetParallelForDirective *D);
Alexey Bataev13314bf2014-10-09 04:18:56 +00001959 void VisitOMPTeamsDirective(const OMPTeamsDirective *D);
Alexey Bataev49f6e782015-12-01 04:18:41 +00001960 void VisitOMPTaskLoopDirective(const OMPTaskLoopDirective *D);
Alexey Bataev0a6ed842015-12-03 09:40:15 +00001961 void VisitOMPTaskLoopSimdDirective(const OMPTaskLoopSimdDirective *D);
Carlo Bertolli6200a3d2015-12-14 14:51:25 +00001962 void VisitOMPDistributeDirective(const OMPDistributeDirective *D);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001963
Guy Benyei11169dd2012-12-18 14:30:41 +00001964private:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001965 void AddDeclarationNameInfo(const Stmt *S);
Guy Benyei11169dd2012-12-18 14:30:41 +00001966 void AddNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier);
James Y Knight04ec5bf2015-12-24 02:59:37 +00001967 void AddExplicitTemplateArgs(const TemplateArgumentLoc *A,
1968 unsigned NumTemplateArgs);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001969 void AddMemberRef(const FieldDecl *D, SourceLocation L);
1970 void AddStmt(const Stmt *S);
1971 void AddDecl(const Decl *D, bool isFirst = true);
Guy Benyei11169dd2012-12-18 14:30:41 +00001972 void AddTypeLoc(TypeSourceInfo *TI);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001973 void EnqueueChildren(const Stmt *S);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001974 void EnqueueChildren(const OMPClause *S);
Guy Benyei11169dd2012-12-18 14:30:41 +00001975};
Alexander Kornienkoab9db512015-06-22 23:07:51 +00001976} // end anonyous namespace
Guy Benyei11169dd2012-12-18 14:30:41 +00001977
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001978void EnqueueVisitor::AddDeclarationNameInfo(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001979 // 'S' should always be non-null, since it comes from the
1980 // statement we are visiting.
1981 WL.push_back(DeclarationNameInfoVisit(S, Parent));
1982}
1983
1984void
1985EnqueueVisitor::AddNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier) {
1986 if (Qualifier)
1987 WL.push_back(NestedNameSpecifierLocVisit(Qualifier, Parent));
1988}
1989
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001990void EnqueueVisitor::AddStmt(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001991 if (S)
1992 WL.push_back(StmtVisit(S, Parent));
1993}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001994void EnqueueVisitor::AddDecl(const Decl *D, bool isFirst) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001995 if (D)
1996 WL.push_back(DeclVisit(D, Parent, isFirst));
1997}
James Y Knight04ec5bf2015-12-24 02:59:37 +00001998void EnqueueVisitor::AddExplicitTemplateArgs(const TemplateArgumentLoc *A,
1999 unsigned NumTemplateArgs) {
2000 WL.push_back(ExplicitTemplateArgsVisit(A, A + NumTemplateArgs, Parent));
Guy Benyei11169dd2012-12-18 14:30:41 +00002001}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002002void EnqueueVisitor::AddMemberRef(const FieldDecl *D, SourceLocation L) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002003 if (D)
2004 WL.push_back(MemberRefVisit(D, L, Parent));
2005}
2006void EnqueueVisitor::AddTypeLoc(TypeSourceInfo *TI) {
2007 if (TI)
2008 WL.push_back(TypeLocVisit(TI->getTypeLoc(), Parent));
2009 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002010void EnqueueVisitor::EnqueueChildren(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002011 unsigned size = WL.size();
Benjamin Kramer642f1732015-07-02 21:03:14 +00002012 for (const Stmt *SubStmt : S->children()) {
2013 AddStmt(SubStmt);
Guy Benyei11169dd2012-12-18 14:30:41 +00002014 }
2015 if (size == WL.size())
2016 return;
2017 // Now reverse the entries we just added. This will match the DFS
2018 // ordering performed by the worklist.
2019 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
2020 std::reverse(I, E);
2021}
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002022namespace {
2023class OMPClauseEnqueue : public ConstOMPClauseVisitor<OMPClauseEnqueue> {
2024 EnqueueVisitor *Visitor;
Alexey Bataev756c1962013-09-24 03:17:45 +00002025 /// \brief Process clauses with list of variables.
2026 template <typename T>
2027 void VisitOMPClauseList(T *Node);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002028public:
2029 OMPClauseEnqueue(EnqueueVisitor *Visitor) : Visitor(Visitor) { }
2030#define OPENMP_CLAUSE(Name, Class) \
2031 void Visit##Class(const Class *C);
2032#include "clang/Basic/OpenMPKinds.def"
Alexey Bataev3392d762016-02-16 11:18:12 +00002033 void VisitOMPClauseWithPreInit(const OMPClauseWithPreInit *C);
Alexey Bataev005248a2016-02-25 05:25:57 +00002034 void VisitOMPClauseWithPostUpdate(const OMPClauseWithPostUpdate *C);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002035};
2036
Alexey Bataev3392d762016-02-16 11:18:12 +00002037void OMPClauseEnqueue::VisitOMPClauseWithPreInit(
2038 const OMPClauseWithPreInit *C) {
2039 Visitor->AddStmt(C->getPreInitStmt());
2040}
2041
Alexey Bataev005248a2016-02-25 05:25:57 +00002042void OMPClauseEnqueue::VisitOMPClauseWithPostUpdate(
2043 const OMPClauseWithPostUpdate *C) {
2044 Visitor->AddStmt(C->getPostUpdateExpr());
2045}
2046
Alexey Bataevaadd52e2014-02-13 05:29:23 +00002047void OMPClauseEnqueue::VisitOMPIfClause(const OMPIfClause *C) {
2048 Visitor->AddStmt(C->getCondition());
2049}
2050
Alexey Bataev3778b602014-07-17 07:32:53 +00002051void OMPClauseEnqueue::VisitOMPFinalClause(const OMPFinalClause *C) {
2052 Visitor->AddStmt(C->getCondition());
2053}
2054
Alexey Bataev568a8332014-03-06 06:15:19 +00002055void OMPClauseEnqueue::VisitOMPNumThreadsClause(const OMPNumThreadsClause *C) {
2056 Visitor->AddStmt(C->getNumThreads());
2057}
2058
Alexey Bataev62c87d22014-03-21 04:51:18 +00002059void OMPClauseEnqueue::VisitOMPSafelenClause(const OMPSafelenClause *C) {
2060 Visitor->AddStmt(C->getSafelen());
2061}
2062
Alexey Bataev66b15b52015-08-21 11:14:16 +00002063void OMPClauseEnqueue::VisitOMPSimdlenClause(const OMPSimdlenClause *C) {
2064 Visitor->AddStmt(C->getSimdlen());
2065}
2066
Alexander Musman8bd31e62014-05-27 15:12:19 +00002067void OMPClauseEnqueue::VisitOMPCollapseClause(const OMPCollapseClause *C) {
2068 Visitor->AddStmt(C->getNumForLoops());
2069}
2070
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002071void OMPClauseEnqueue::VisitOMPDefaultClause(const OMPDefaultClause *C) { }
Alexey Bataev756c1962013-09-24 03:17:45 +00002072
Alexey Bataevbcbadb62014-05-06 06:04:14 +00002073void OMPClauseEnqueue::VisitOMPProcBindClause(const OMPProcBindClause *C) { }
2074
Alexey Bataev56dafe82014-06-20 07:16:17 +00002075void OMPClauseEnqueue::VisitOMPScheduleClause(const OMPScheduleClause *C) {
Alexey Bataev3392d762016-02-16 11:18:12 +00002076 VisitOMPClauseWithPreInit(C);
Alexey Bataev56dafe82014-06-20 07:16:17 +00002077 Visitor->AddStmt(C->getChunkSize());
2078}
2079
Alexey Bataev10e775f2015-07-30 11:36:16 +00002080void OMPClauseEnqueue::VisitOMPOrderedClause(const OMPOrderedClause *C) {
2081 Visitor->AddStmt(C->getNumForLoops());
2082}
Alexey Bataev142e1fc2014-06-20 09:44:06 +00002083
Alexey Bataev236070f2014-06-20 11:19:47 +00002084void OMPClauseEnqueue::VisitOMPNowaitClause(const OMPNowaitClause *) {}
2085
Alexey Bataev7aea99a2014-07-17 12:19:31 +00002086void OMPClauseEnqueue::VisitOMPUntiedClause(const OMPUntiedClause *) {}
2087
Alexey Bataev74ba3a52014-07-17 12:47:03 +00002088void OMPClauseEnqueue::VisitOMPMergeableClause(const OMPMergeableClause *) {}
2089
Alexey Bataevf98b00c2014-07-23 02:27:21 +00002090void OMPClauseEnqueue::VisitOMPReadClause(const OMPReadClause *) {}
2091
Alexey Bataevdea47612014-07-23 07:46:59 +00002092void OMPClauseEnqueue::VisitOMPWriteClause(const OMPWriteClause *) {}
2093
Alexey Bataev67a4f222014-07-23 10:25:33 +00002094void OMPClauseEnqueue::VisitOMPUpdateClause(const OMPUpdateClause *) {}
2095
Alexey Bataev459dec02014-07-24 06:46:57 +00002096void OMPClauseEnqueue::VisitOMPCaptureClause(const OMPCaptureClause *) {}
2097
Alexey Bataev82bad8b2014-07-24 08:55:34 +00002098void OMPClauseEnqueue::VisitOMPSeqCstClause(const OMPSeqCstClause *) {}
2099
Alexey Bataev346265e2015-09-25 10:37:12 +00002100void OMPClauseEnqueue::VisitOMPThreadsClause(const OMPThreadsClause *) {}
2101
Alexey Bataevd14d1e62015-09-28 06:39:35 +00002102void OMPClauseEnqueue::VisitOMPSIMDClause(const OMPSIMDClause *) {}
2103
Alexey Bataevb825de12015-12-07 10:51:44 +00002104void OMPClauseEnqueue::VisitOMPNogroupClause(const OMPNogroupClause *) {}
2105
Michael Wonge710d542015-08-07 16:16:36 +00002106void OMPClauseEnqueue::VisitOMPDeviceClause(const OMPDeviceClause *C) {
2107 Visitor->AddStmt(C->getDevice());
2108}
2109
Kelvin Li099bb8c2015-11-24 20:50:12 +00002110void OMPClauseEnqueue::VisitOMPNumTeamsClause(const OMPNumTeamsClause *C) {
2111 Visitor->AddStmt(C->getNumTeams());
2112}
2113
Kelvin Lia15fb1a2015-11-27 18:47:36 +00002114void OMPClauseEnqueue::VisitOMPThreadLimitClause(const OMPThreadLimitClause *C) {
2115 Visitor->AddStmt(C->getThreadLimit());
2116}
2117
Alexey Bataeva0569352015-12-01 10:17:31 +00002118void OMPClauseEnqueue::VisitOMPPriorityClause(const OMPPriorityClause *C) {
2119 Visitor->AddStmt(C->getPriority());
2120}
2121
Alexey Bataev1fd4aed2015-12-07 12:52:51 +00002122void OMPClauseEnqueue::VisitOMPGrainsizeClause(const OMPGrainsizeClause *C) {
2123 Visitor->AddStmt(C->getGrainsize());
2124}
2125
Alexey Bataev382967a2015-12-08 12:06:20 +00002126void OMPClauseEnqueue::VisitOMPNumTasksClause(const OMPNumTasksClause *C) {
2127 Visitor->AddStmt(C->getNumTasks());
2128}
2129
Alexey Bataev28c75412015-12-15 08:19:24 +00002130void OMPClauseEnqueue::VisitOMPHintClause(const OMPHintClause *C) {
2131 Visitor->AddStmt(C->getHint());
2132}
2133
Alexey Bataev756c1962013-09-24 03:17:45 +00002134template<typename T>
2135void OMPClauseEnqueue::VisitOMPClauseList(T *Node) {
Alexey Bataev03b340a2014-10-21 03:16:40 +00002136 for (const auto *I : Node->varlists()) {
Aaron Ballman2205d2a2014-03-14 15:55:35 +00002137 Visitor->AddStmt(I);
Alexey Bataev03b340a2014-10-21 03:16:40 +00002138 }
Alexey Bataev756c1962013-09-24 03:17:45 +00002139}
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002140
2141void OMPClauseEnqueue::VisitOMPPrivateClause(const OMPPrivateClause *C) {
Alexey Bataev756c1962013-09-24 03:17:45 +00002142 VisitOMPClauseList(C);
Alexey Bataev03b340a2014-10-21 03:16:40 +00002143 for (const auto *E : C->private_copies()) {
2144 Visitor->AddStmt(E);
2145 }
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002146}
Alexey Bataevd5af8e42013-10-01 05:32:34 +00002147void OMPClauseEnqueue::VisitOMPFirstprivateClause(
2148 const OMPFirstprivateClause *C) {
2149 VisitOMPClauseList(C);
Alexey Bataev417089f2016-02-17 13:19:37 +00002150 VisitOMPClauseWithPreInit(C);
2151 for (const auto *E : C->private_copies()) {
2152 Visitor->AddStmt(E);
2153 }
2154 for (const auto *E : C->inits()) {
2155 Visitor->AddStmt(E);
2156 }
Alexey Bataevd5af8e42013-10-01 05:32:34 +00002157}
Alexander Musman1bb328c2014-06-04 13:06:39 +00002158void OMPClauseEnqueue::VisitOMPLastprivateClause(
2159 const OMPLastprivateClause *C) {
2160 VisitOMPClauseList(C);
Alexey Bataev005248a2016-02-25 05:25:57 +00002161 VisitOMPClauseWithPreInit(C);
2162 VisitOMPClauseWithPostUpdate(C);
Alexey Bataev38e89532015-04-16 04:54:05 +00002163 for (auto *E : C->private_copies()) {
2164 Visitor->AddStmt(E);
2165 }
2166 for (auto *E : C->source_exprs()) {
2167 Visitor->AddStmt(E);
2168 }
2169 for (auto *E : C->destination_exprs()) {
2170 Visitor->AddStmt(E);
2171 }
2172 for (auto *E : C->assignment_ops()) {
2173 Visitor->AddStmt(E);
2174 }
Alexander Musman1bb328c2014-06-04 13:06:39 +00002175}
Alexey Bataev758e55e2013-09-06 18:03:48 +00002176void OMPClauseEnqueue::VisitOMPSharedClause(const OMPSharedClause *C) {
Alexey Bataev756c1962013-09-24 03:17:45 +00002177 VisitOMPClauseList(C);
Alexey Bataev758e55e2013-09-06 18:03:48 +00002178}
Alexey Bataevc5e02582014-06-16 07:08:35 +00002179void OMPClauseEnqueue::VisitOMPReductionClause(const OMPReductionClause *C) {
2180 VisitOMPClauseList(C);
Alexey Bataev61205072016-03-02 04:57:40 +00002181 VisitOMPClauseWithPreInit(C);
2182 VisitOMPClauseWithPostUpdate(C);
Alexey Bataevf24e7b12015-10-08 09:10:53 +00002183 for (auto *E : C->privates()) {
2184 Visitor->AddStmt(E);
2185 }
Alexey Bataev794ba0d2015-04-10 10:43:45 +00002186 for (auto *E : C->lhs_exprs()) {
2187 Visitor->AddStmt(E);
2188 }
2189 for (auto *E : C->rhs_exprs()) {
2190 Visitor->AddStmt(E);
2191 }
2192 for (auto *E : C->reduction_ops()) {
2193 Visitor->AddStmt(E);
2194 }
Alexey Bataevc5e02582014-06-16 07:08:35 +00002195}
Alexander Musman8dba6642014-04-22 13:09:42 +00002196void OMPClauseEnqueue::VisitOMPLinearClause(const OMPLinearClause *C) {
2197 VisitOMPClauseList(C);
Alexey Bataevbd9fec12015-08-18 06:47:21 +00002198 for (const auto *E : C->privates()) {
2199 Visitor->AddStmt(E);
2200 }
Alexander Musman3276a272015-03-21 10:12:56 +00002201 for (const auto *E : C->inits()) {
2202 Visitor->AddStmt(E);
2203 }
2204 for (const auto *E : C->updates()) {
2205 Visitor->AddStmt(E);
2206 }
2207 for (const auto *E : C->finals()) {
2208 Visitor->AddStmt(E);
2209 }
Alexander Musman8dba6642014-04-22 13:09:42 +00002210 Visitor->AddStmt(C->getStep());
Alexander Musman3276a272015-03-21 10:12:56 +00002211 Visitor->AddStmt(C->getCalcStep());
Alexander Musman8dba6642014-04-22 13:09:42 +00002212}
Alexander Musmanf0d76e72014-05-29 14:36:25 +00002213void OMPClauseEnqueue::VisitOMPAlignedClause(const OMPAlignedClause *C) {
2214 VisitOMPClauseList(C);
2215 Visitor->AddStmt(C->getAlignment());
2216}
Alexey Bataevd48bcd82014-03-31 03:36:38 +00002217void OMPClauseEnqueue::VisitOMPCopyinClause(const OMPCopyinClause *C) {
2218 VisitOMPClauseList(C);
Alexey Bataevf56f98c2015-04-16 05:39:01 +00002219 for (auto *E : C->source_exprs()) {
2220 Visitor->AddStmt(E);
2221 }
2222 for (auto *E : C->destination_exprs()) {
2223 Visitor->AddStmt(E);
2224 }
2225 for (auto *E : C->assignment_ops()) {
2226 Visitor->AddStmt(E);
2227 }
Alexey Bataevd48bcd82014-03-31 03:36:38 +00002228}
Alexey Bataevbae9a792014-06-27 10:37:06 +00002229void
2230OMPClauseEnqueue::VisitOMPCopyprivateClause(const OMPCopyprivateClause *C) {
2231 VisitOMPClauseList(C);
Alexey Bataeva63048e2015-03-23 06:18:07 +00002232 for (auto *E : C->source_exprs()) {
2233 Visitor->AddStmt(E);
2234 }
2235 for (auto *E : C->destination_exprs()) {
2236 Visitor->AddStmt(E);
2237 }
2238 for (auto *E : C->assignment_ops()) {
2239 Visitor->AddStmt(E);
2240 }
Alexey Bataevbae9a792014-06-27 10:37:06 +00002241}
Alexey Bataev6125da92014-07-21 11:26:11 +00002242void OMPClauseEnqueue::VisitOMPFlushClause(const OMPFlushClause *C) {
2243 VisitOMPClauseList(C);
2244}
Alexey Bataev1c2cfbc2015-06-23 14:25:19 +00002245void OMPClauseEnqueue::VisitOMPDependClause(const OMPDependClause *C) {
2246 VisitOMPClauseList(C);
2247}
Kelvin Li0bff7af2015-11-23 05:32:03 +00002248void OMPClauseEnqueue::VisitOMPMapClause(const OMPMapClause *C) {
2249 VisitOMPClauseList(C);
2250}
Carlo Bertollib4adf552016-01-15 18:50:31 +00002251void OMPClauseEnqueue::VisitOMPDistScheduleClause(
2252 const OMPDistScheduleClause *C) {
Alexey Bataev3392d762016-02-16 11:18:12 +00002253 VisitOMPClauseWithPreInit(C);
Carlo Bertollib4adf552016-01-15 18:50:31 +00002254 Visitor->AddStmt(C->getChunkSize());
Carlo Bertollib4adf552016-01-15 18:50:31 +00002255}
Alexey Bataev3392d762016-02-16 11:18:12 +00002256void OMPClauseEnqueue::VisitOMPDefaultmapClause(
2257 const OMPDefaultmapClause * /*C*/) {}
Alexander Kornienkoab9db512015-06-22 23:07:51 +00002258}
Alexey Bataev756c1962013-09-24 03:17:45 +00002259
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002260void EnqueueVisitor::EnqueueChildren(const OMPClause *S) {
2261 unsigned size = WL.size();
2262 OMPClauseEnqueue Visitor(this);
2263 Visitor.Visit(S);
2264 if (size == WL.size())
2265 return;
2266 // Now reverse the entries we just added. This will match the DFS
2267 // ordering performed by the worklist.
2268 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
2269 std::reverse(I, E);
2270}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002271void EnqueueVisitor::VisitAddrLabelExpr(const AddrLabelExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002272 WL.push_back(LabelRefVisit(E->getLabel(), E->getLabelLoc(), Parent));
2273}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002274void EnqueueVisitor::VisitBlockExpr(const BlockExpr *B) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002275 AddDecl(B->getBlockDecl());
2276}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002277void EnqueueVisitor::VisitCompoundLiteralExpr(const CompoundLiteralExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002278 EnqueueChildren(E);
2279 AddTypeLoc(E->getTypeSourceInfo());
2280}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002281void EnqueueVisitor::VisitCompoundStmt(const CompoundStmt *S) {
Pete Cooper57d3f142015-07-30 17:22:52 +00002282 for (auto &I : llvm::reverse(S->body()))
2283 AddStmt(I);
Guy Benyei11169dd2012-12-18 14:30:41 +00002284}
2285void EnqueueVisitor::
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002286VisitMSDependentExistsStmt(const MSDependentExistsStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002287 AddStmt(S->getSubStmt());
2288 AddDeclarationNameInfo(S);
2289 if (NestedNameSpecifierLoc QualifierLoc = S->getQualifierLoc())
2290 AddNestedNameSpecifierLoc(QualifierLoc);
2291}
2292
2293void EnqueueVisitor::
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002294VisitCXXDependentScopeMemberExpr(const CXXDependentScopeMemberExpr *E) {
James Y Knight04ec5bf2015-12-24 02:59:37 +00002295 if (E->hasExplicitTemplateArgs())
2296 AddExplicitTemplateArgs(E->getTemplateArgs(), E->getNumTemplateArgs());
Guy Benyei11169dd2012-12-18 14:30:41 +00002297 AddDeclarationNameInfo(E);
2298 if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
2299 AddNestedNameSpecifierLoc(QualifierLoc);
2300 if (!E->isImplicitAccess())
2301 AddStmt(E->getBase());
2302}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002303void EnqueueVisitor::VisitCXXNewExpr(const CXXNewExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002304 // Enqueue the initializer , if any.
2305 AddStmt(E->getInitializer());
2306 // Enqueue the array size, if any.
2307 AddStmt(E->getArraySize());
2308 // Enqueue the allocated type.
2309 AddTypeLoc(E->getAllocatedTypeSourceInfo());
2310 // Enqueue the placement arguments.
2311 for (unsigned I = E->getNumPlacementArgs(); I > 0; --I)
2312 AddStmt(E->getPlacementArg(I-1));
2313}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002314void EnqueueVisitor::VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *CE) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002315 for (unsigned I = CE->getNumArgs(); I > 1 /* Yes, this is 1 */; --I)
2316 AddStmt(CE->getArg(I-1));
2317 AddStmt(CE->getCallee());
2318 AddStmt(CE->getArg(0));
2319}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002320void EnqueueVisitor::VisitCXXPseudoDestructorExpr(
2321 const CXXPseudoDestructorExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002322 // Visit the name of the type being destroyed.
2323 AddTypeLoc(E->getDestroyedTypeInfo());
2324 // Visit the scope type that looks disturbingly like the nested-name-specifier
2325 // but isn't.
2326 AddTypeLoc(E->getScopeTypeInfo());
2327 // Visit the nested-name-specifier.
2328 if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
2329 AddNestedNameSpecifierLoc(QualifierLoc);
2330 // Visit base expression.
2331 AddStmt(E->getBase());
2332}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002333void EnqueueVisitor::VisitCXXScalarValueInitExpr(
2334 const CXXScalarValueInitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002335 AddTypeLoc(E->getTypeSourceInfo());
2336}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002337void EnqueueVisitor::VisitCXXTemporaryObjectExpr(
2338 const CXXTemporaryObjectExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002339 EnqueueChildren(E);
2340 AddTypeLoc(E->getTypeSourceInfo());
2341}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002342void EnqueueVisitor::VisitCXXTypeidExpr(const CXXTypeidExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002343 EnqueueChildren(E);
2344 if (E->isTypeOperand())
2345 AddTypeLoc(E->getTypeOperandSourceInfo());
2346}
2347
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002348void EnqueueVisitor::VisitCXXUnresolvedConstructExpr(
2349 const CXXUnresolvedConstructExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002350 EnqueueChildren(E);
2351 AddTypeLoc(E->getTypeSourceInfo());
2352}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002353void EnqueueVisitor::VisitCXXUuidofExpr(const CXXUuidofExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002354 EnqueueChildren(E);
2355 if (E->isTypeOperand())
2356 AddTypeLoc(E->getTypeOperandSourceInfo());
2357}
2358
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002359void EnqueueVisitor::VisitCXXCatchStmt(const CXXCatchStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002360 EnqueueChildren(S);
2361 AddDecl(S->getExceptionDecl());
2362}
2363
Argyrios Kyrtzidis99891242014-11-13 09:03:21 +00002364void EnqueueVisitor::VisitCXXForRangeStmt(const CXXForRangeStmt *S) {
Argyrios Kyrtzidiscde70692014-11-13 09:50:19 +00002365 AddStmt(S->getBody());
Argyrios Kyrtzidis99891242014-11-13 09:03:21 +00002366 AddStmt(S->getRangeInit());
Argyrios Kyrtzidiscde70692014-11-13 09:50:19 +00002367 AddDecl(S->getLoopVariable());
Argyrios Kyrtzidis99891242014-11-13 09:03:21 +00002368}
2369
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002370void EnqueueVisitor::VisitDeclRefExpr(const DeclRefExpr *DR) {
James Y Knight04ec5bf2015-12-24 02:59:37 +00002371 if (DR->hasExplicitTemplateArgs())
2372 AddExplicitTemplateArgs(DR->getTemplateArgs(), DR->getNumTemplateArgs());
Guy Benyei11169dd2012-12-18 14:30:41 +00002373 WL.push_back(DeclRefExprParts(DR, Parent));
2374}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002375void EnqueueVisitor::VisitDependentScopeDeclRefExpr(
2376 const DependentScopeDeclRefExpr *E) {
James Y Knight04ec5bf2015-12-24 02:59:37 +00002377 if (E->hasExplicitTemplateArgs())
2378 AddExplicitTemplateArgs(E->getTemplateArgs(), E->getNumTemplateArgs());
Guy Benyei11169dd2012-12-18 14:30:41 +00002379 AddDeclarationNameInfo(E);
2380 AddNestedNameSpecifierLoc(E->getQualifierLoc());
2381}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002382void EnqueueVisitor::VisitDeclStmt(const DeclStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002383 unsigned size = WL.size();
2384 bool isFirst = true;
Aaron Ballman535bbcc2014-03-14 17:01:24 +00002385 for (const auto *D : S->decls()) {
2386 AddDecl(D, isFirst);
Guy Benyei11169dd2012-12-18 14:30:41 +00002387 isFirst = false;
2388 }
2389 if (size == WL.size())
2390 return;
2391 // Now reverse the entries we just added. This will match the DFS
2392 // ordering performed by the worklist.
2393 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
2394 std::reverse(I, E);
2395}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002396void EnqueueVisitor::VisitDesignatedInitExpr(const DesignatedInitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002397 AddStmt(E->getInit());
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002398 for (DesignatedInitExpr::const_reverse_designators_iterator
Guy Benyei11169dd2012-12-18 14:30:41 +00002399 D = E->designators_rbegin(), DEnd = E->designators_rend();
2400 D != DEnd; ++D) {
2401 if (D->isFieldDesignator()) {
2402 if (FieldDecl *Field = D->getField())
2403 AddMemberRef(Field, D->getFieldLoc());
2404 continue;
2405 }
2406 if (D->isArrayDesignator()) {
2407 AddStmt(E->getArrayIndex(*D));
2408 continue;
2409 }
2410 assert(D->isArrayRangeDesignator() && "Unknown designator kind");
2411 AddStmt(E->getArrayRangeEnd(*D));
2412 AddStmt(E->getArrayRangeStart(*D));
2413 }
2414}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002415void EnqueueVisitor::VisitExplicitCastExpr(const ExplicitCastExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002416 EnqueueChildren(E);
2417 AddTypeLoc(E->getTypeInfoAsWritten());
2418}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002419void EnqueueVisitor::VisitForStmt(const ForStmt *FS) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002420 AddStmt(FS->getBody());
2421 AddStmt(FS->getInc());
2422 AddStmt(FS->getCond());
2423 AddDecl(FS->getConditionVariable());
2424 AddStmt(FS->getInit());
2425}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002426void EnqueueVisitor::VisitGotoStmt(const GotoStmt *GS) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002427 WL.push_back(LabelRefVisit(GS->getLabel(), GS->getLabelLoc(), Parent));
2428}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002429void EnqueueVisitor::VisitIfStmt(const IfStmt *If) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002430 AddStmt(If->getElse());
2431 AddStmt(If->getThen());
2432 AddStmt(If->getCond());
2433 AddDecl(If->getConditionVariable());
2434}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002435void EnqueueVisitor::VisitInitListExpr(const InitListExpr *IE) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002436 // We care about the syntactic form of the initializer list, only.
2437 if (InitListExpr *Syntactic = IE->getSyntacticForm())
2438 IE = Syntactic;
2439 EnqueueChildren(IE);
2440}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002441void EnqueueVisitor::VisitMemberExpr(const MemberExpr *M) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002442 WL.push_back(MemberExprParts(M, Parent));
2443
2444 // If the base of the member access expression is an implicit 'this', don't
2445 // visit it.
2446 // FIXME: If we ever want to show these implicit accesses, this will be
2447 // unfortunate. However, clang_getCursor() relies on this behavior.
Argyrios Kyrtzidis58d0e7a2015-03-13 04:40:07 +00002448 if (M->isImplicitAccess())
2449 return;
2450
2451 // Ignore base anonymous struct/union fields, otherwise they will shadow the
2452 // real field that that we are interested in.
2453 if (auto *SubME = dyn_cast<MemberExpr>(M->getBase())) {
2454 if (auto *FD = dyn_cast_or_null<FieldDecl>(SubME->getMemberDecl())) {
2455 if (FD->isAnonymousStructOrUnion()) {
2456 AddStmt(SubME->getBase());
2457 return;
2458 }
2459 }
2460 }
2461
2462 AddStmt(M->getBase());
Guy Benyei11169dd2012-12-18 14:30:41 +00002463}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002464void EnqueueVisitor::VisitObjCEncodeExpr(const ObjCEncodeExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002465 AddTypeLoc(E->getEncodedTypeSourceInfo());
2466}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002467void EnqueueVisitor::VisitObjCMessageExpr(const ObjCMessageExpr *M) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002468 EnqueueChildren(M);
2469 AddTypeLoc(M->getClassReceiverTypeInfo());
2470}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002471void EnqueueVisitor::VisitOffsetOfExpr(const OffsetOfExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002472 // Visit the components of the offsetof expression.
2473 for (unsigned N = E->getNumComponents(), I = N; I > 0; --I) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002474 const OffsetOfNode &Node = E->getComponent(I-1);
2475 switch (Node.getKind()) {
2476 case OffsetOfNode::Array:
2477 AddStmt(E->getIndexExpr(Node.getArrayExprIndex()));
2478 break;
2479 case OffsetOfNode::Field:
2480 AddMemberRef(Node.getField(), Node.getSourceRange().getEnd());
2481 break;
2482 case OffsetOfNode::Identifier:
2483 case OffsetOfNode::Base:
2484 continue;
2485 }
2486 }
2487 // Visit the type into which we're computing the offset.
2488 AddTypeLoc(E->getTypeSourceInfo());
2489}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002490void EnqueueVisitor::VisitOverloadExpr(const OverloadExpr *E) {
James Y Knight04ec5bf2015-12-24 02:59:37 +00002491 if (E->hasExplicitTemplateArgs())
2492 AddExplicitTemplateArgs(E->getTemplateArgs(), E->getNumTemplateArgs());
Guy Benyei11169dd2012-12-18 14:30:41 +00002493 WL.push_back(OverloadExprParts(E, Parent));
2494}
2495void EnqueueVisitor::VisitUnaryExprOrTypeTraitExpr(
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002496 const UnaryExprOrTypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002497 EnqueueChildren(E);
2498 if (E->isArgumentType())
2499 AddTypeLoc(E->getArgumentTypeInfo());
2500}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002501void EnqueueVisitor::VisitStmt(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002502 EnqueueChildren(S);
2503}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002504void EnqueueVisitor::VisitSwitchStmt(const SwitchStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002505 AddStmt(S->getBody());
2506 AddStmt(S->getCond());
2507 AddDecl(S->getConditionVariable());
2508}
2509
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002510void EnqueueVisitor::VisitWhileStmt(const WhileStmt *W) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002511 AddStmt(W->getBody());
2512 AddStmt(W->getCond());
2513 AddDecl(W->getConditionVariable());
2514}
2515
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002516void EnqueueVisitor::VisitTypeTraitExpr(const TypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002517 for (unsigned I = E->getNumArgs(); I > 0; --I)
2518 AddTypeLoc(E->getArg(I-1));
2519}
2520
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002521void EnqueueVisitor::VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002522 AddTypeLoc(E->getQueriedTypeSourceInfo());
2523}
2524
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002525void EnqueueVisitor::VisitExpressionTraitExpr(const ExpressionTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002526 EnqueueChildren(E);
2527}
2528
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002529void EnqueueVisitor::VisitUnresolvedMemberExpr(const UnresolvedMemberExpr *U) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002530 VisitOverloadExpr(U);
2531 if (!U->isImplicitAccess())
2532 AddStmt(U->getBase());
2533}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002534void EnqueueVisitor::VisitVAArgExpr(const VAArgExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002535 AddStmt(E->getSubExpr());
2536 AddTypeLoc(E->getWrittenTypeInfo());
2537}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002538void EnqueueVisitor::VisitSizeOfPackExpr(const SizeOfPackExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002539 WL.push_back(SizeOfPackExprParts(E, Parent));
2540}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002541void EnqueueVisitor::VisitOpaqueValueExpr(const OpaqueValueExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002542 // If the opaque value has a source expression, just transparently
2543 // visit that. This is useful for (e.g.) pseudo-object expressions.
2544 if (Expr *SourceExpr = E->getSourceExpr())
2545 return Visit(SourceExpr);
2546}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002547void EnqueueVisitor::VisitLambdaExpr(const LambdaExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002548 AddStmt(E->getBody());
2549 WL.push_back(LambdaExprParts(E, Parent));
2550}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002551void EnqueueVisitor::VisitPseudoObjectExpr(const PseudoObjectExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002552 // Treat the expression like its syntactic form.
2553 Visit(E->getSyntacticForm());
2554}
2555
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002556void EnqueueVisitor::VisitOMPExecutableDirective(
2557 const OMPExecutableDirective *D) {
2558 EnqueueChildren(D);
2559 for (ArrayRef<OMPClause *>::iterator I = D->clauses().begin(),
2560 E = D->clauses().end();
2561 I != E; ++I)
2562 EnqueueChildren(*I);
2563}
2564
Alexander Musman3aaab662014-08-19 11:27:13 +00002565void EnqueueVisitor::VisitOMPLoopDirective(const OMPLoopDirective *D) {
2566 VisitOMPExecutableDirective(D);
2567}
2568
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002569void EnqueueVisitor::VisitOMPParallelDirective(const OMPParallelDirective *D) {
2570 VisitOMPExecutableDirective(D);
2571}
2572
Alexey Bataev1b59ab52014-02-27 08:29:12 +00002573void EnqueueVisitor::VisitOMPSimdDirective(const OMPSimdDirective *D) {
Alexander Musman3aaab662014-08-19 11:27:13 +00002574 VisitOMPLoopDirective(D);
Alexey Bataev1b59ab52014-02-27 08:29:12 +00002575}
2576
Alexey Bataevf29276e2014-06-18 04:14:57 +00002577void EnqueueVisitor::VisitOMPForDirective(const OMPForDirective *D) {
Alexander Musman3aaab662014-08-19 11:27:13 +00002578 VisitOMPLoopDirective(D);
Alexey Bataevf29276e2014-06-18 04:14:57 +00002579}
2580
Alexander Musmanf82886e2014-09-18 05:12:34 +00002581void EnqueueVisitor::VisitOMPForSimdDirective(const OMPForSimdDirective *D) {
2582 VisitOMPLoopDirective(D);
2583}
2584
Alexey Bataevd3f8dd22014-06-25 11:44:49 +00002585void EnqueueVisitor::VisitOMPSectionsDirective(const OMPSectionsDirective *D) {
2586 VisitOMPExecutableDirective(D);
2587}
2588
Alexey Bataev1e0498a2014-06-26 08:21:58 +00002589void EnqueueVisitor::VisitOMPSectionDirective(const OMPSectionDirective *D) {
2590 VisitOMPExecutableDirective(D);
2591}
2592
Alexey Bataevd1e40fb2014-06-26 12:05:45 +00002593void EnqueueVisitor::VisitOMPSingleDirective(const OMPSingleDirective *D) {
2594 VisitOMPExecutableDirective(D);
2595}
2596
Alexander Musman80c22892014-07-17 08:54:58 +00002597void EnqueueVisitor::VisitOMPMasterDirective(const OMPMasterDirective *D) {
2598 VisitOMPExecutableDirective(D);
2599}
2600
Alexander Musmand9ed09f2014-07-21 09:42:05 +00002601void EnqueueVisitor::VisitOMPCriticalDirective(const OMPCriticalDirective *D) {
2602 VisitOMPExecutableDirective(D);
2603 AddDeclarationNameInfo(D);
2604}
2605
Alexey Bataev4acb8592014-07-07 13:01:15 +00002606void
2607EnqueueVisitor::VisitOMPParallelForDirective(const OMPParallelForDirective *D) {
Alexander Musman3aaab662014-08-19 11:27:13 +00002608 VisitOMPLoopDirective(D);
Alexey Bataev4acb8592014-07-07 13:01:15 +00002609}
2610
Alexander Musmane4e893b2014-09-23 09:33:00 +00002611void EnqueueVisitor::VisitOMPParallelForSimdDirective(
2612 const OMPParallelForSimdDirective *D) {
2613 VisitOMPLoopDirective(D);
2614}
2615
Alexey Bataev84d0b3e2014-07-08 08:12:03 +00002616void EnqueueVisitor::VisitOMPParallelSectionsDirective(
2617 const OMPParallelSectionsDirective *D) {
2618 VisitOMPExecutableDirective(D);
2619}
2620
Alexey Bataev9c2e8ee2014-07-11 11:25:16 +00002621void EnqueueVisitor::VisitOMPTaskDirective(const OMPTaskDirective *D) {
2622 VisitOMPExecutableDirective(D);
2623}
2624
Alexey Bataev68446b72014-07-18 07:47:19 +00002625void
2626EnqueueVisitor::VisitOMPTaskyieldDirective(const OMPTaskyieldDirective *D) {
2627 VisitOMPExecutableDirective(D);
2628}
2629
Alexey Bataev4d1dfea2014-07-18 09:11:51 +00002630void EnqueueVisitor::VisitOMPBarrierDirective(const OMPBarrierDirective *D) {
2631 VisitOMPExecutableDirective(D);
2632}
2633
Alexey Bataev2df347a2014-07-18 10:17:07 +00002634void EnqueueVisitor::VisitOMPTaskwaitDirective(const OMPTaskwaitDirective *D) {
2635 VisitOMPExecutableDirective(D);
2636}
2637
Alexey Bataevc30dd2d2015-06-18 12:14:09 +00002638void EnqueueVisitor::VisitOMPTaskgroupDirective(
2639 const OMPTaskgroupDirective *D) {
2640 VisitOMPExecutableDirective(D);
2641}
2642
Alexey Bataev6125da92014-07-21 11:26:11 +00002643void EnqueueVisitor::VisitOMPFlushDirective(const OMPFlushDirective *D) {
2644 VisitOMPExecutableDirective(D);
2645}
2646
Alexey Bataev9fb6e642014-07-22 06:45:04 +00002647void EnqueueVisitor::VisitOMPOrderedDirective(const OMPOrderedDirective *D) {
2648 VisitOMPExecutableDirective(D);
2649}
2650
Alexey Bataev0162e452014-07-22 10:10:35 +00002651void EnqueueVisitor::VisitOMPAtomicDirective(const OMPAtomicDirective *D) {
2652 VisitOMPExecutableDirective(D);
2653}
2654
Alexey Bataev0bd520b2014-09-19 08:19:49 +00002655void EnqueueVisitor::VisitOMPTargetDirective(const OMPTargetDirective *D) {
2656 VisitOMPExecutableDirective(D);
2657}
2658
Michael Wong65f367f2015-07-21 13:44:28 +00002659void EnqueueVisitor::VisitOMPTargetDataDirective(const
2660 OMPTargetDataDirective *D) {
2661 VisitOMPExecutableDirective(D);
2662}
2663
Samuel Antaodf67fc42016-01-19 19:15:56 +00002664void EnqueueVisitor::VisitOMPTargetEnterDataDirective(
2665 const OMPTargetEnterDataDirective *D) {
2666 VisitOMPExecutableDirective(D);
2667}
2668
Samuel Antao72590762016-01-19 20:04:50 +00002669void EnqueueVisitor::VisitOMPTargetExitDataDirective(
2670 const OMPTargetExitDataDirective *D) {
2671 VisitOMPExecutableDirective(D);
2672}
2673
Arpith Chacko Jacobe955b3d2016-01-26 18:48:41 +00002674void EnqueueVisitor::VisitOMPTargetParallelDirective(
2675 const OMPTargetParallelDirective *D) {
2676 VisitOMPExecutableDirective(D);
2677}
2678
Arpith Chacko Jacob05bebb52016-02-03 15:46:42 +00002679void EnqueueVisitor::VisitOMPTargetParallelForDirective(
2680 const OMPTargetParallelForDirective *D) {
2681 VisitOMPLoopDirective(D);
2682}
2683
Alexey Bataev13314bf2014-10-09 04:18:56 +00002684void EnqueueVisitor::VisitOMPTeamsDirective(const OMPTeamsDirective *D) {
2685 VisitOMPExecutableDirective(D);
2686}
2687
Alexey Bataev6d4ed052015-07-01 06:57:41 +00002688void EnqueueVisitor::VisitOMPCancellationPointDirective(
2689 const OMPCancellationPointDirective *D) {
2690 VisitOMPExecutableDirective(D);
2691}
2692
Alexey Bataev80909872015-07-02 11:25:17 +00002693void EnqueueVisitor::VisitOMPCancelDirective(const OMPCancelDirective *D) {
2694 VisitOMPExecutableDirective(D);
2695}
2696
Alexey Bataev49f6e782015-12-01 04:18:41 +00002697void EnqueueVisitor::VisitOMPTaskLoopDirective(const OMPTaskLoopDirective *D) {
2698 VisitOMPLoopDirective(D);
2699}
2700
Alexey Bataev0a6ed842015-12-03 09:40:15 +00002701void EnqueueVisitor::VisitOMPTaskLoopSimdDirective(
2702 const OMPTaskLoopSimdDirective *D) {
2703 VisitOMPLoopDirective(D);
2704}
2705
Carlo Bertolli6200a3d2015-12-14 14:51:25 +00002706void EnqueueVisitor::VisitOMPDistributeDirective(
2707 const OMPDistributeDirective *D) {
2708 VisitOMPLoopDirective(D);
2709}
2710
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002711void CursorVisitor::EnqueueWorkList(VisitorWorkList &WL, const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002712 EnqueueVisitor(WL, MakeCXCursor(S, StmtParent, TU,RegionOfInterest)).Visit(S);
2713}
2714
2715bool CursorVisitor::IsInRegionOfInterest(CXCursor C) {
2716 if (RegionOfInterest.isValid()) {
2717 SourceRange Range = getRawCursorExtent(C);
2718 if (Range.isInvalid() || CompareRegionOfInterest(Range))
2719 return false;
2720 }
2721 return true;
2722}
2723
2724bool CursorVisitor::RunVisitorWorkList(VisitorWorkList &WL) {
2725 while (!WL.empty()) {
2726 // Dequeue the worklist item.
Robert Wilhelm25284cc2013-08-23 16:11:15 +00002727 VisitorJob LI = WL.pop_back_val();
Guy Benyei11169dd2012-12-18 14:30:41 +00002728
2729 // Set the Parent field, then back to its old value once we're done.
2730 SetParentRAII SetParent(Parent, StmtParent, LI.getParent());
2731
2732 switch (LI.getKind()) {
2733 case VisitorJob::DeclVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002734 const Decl *D = cast<DeclVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002735 if (!D)
2736 continue;
2737
2738 // For now, perform default visitation for Decls.
2739 if (Visit(MakeCXCursor(D, TU, RegionOfInterest,
2740 cast<DeclVisit>(&LI)->isFirst())))
2741 return true;
2742
2743 continue;
2744 }
2745 case VisitorJob::ExplicitTemplateArgsVisitKind: {
James Y Knight04ec5bf2015-12-24 02:59:37 +00002746 for (const TemplateArgumentLoc &Arg :
2747 *cast<ExplicitTemplateArgsVisit>(&LI)) {
2748 if (VisitTemplateArgumentLoc(Arg))
Guy Benyei11169dd2012-12-18 14:30:41 +00002749 return true;
2750 }
2751 continue;
2752 }
2753 case VisitorJob::TypeLocVisitKind: {
2754 // Perform default visitation for TypeLocs.
2755 if (Visit(cast<TypeLocVisit>(&LI)->get()))
2756 return true;
2757 continue;
2758 }
2759 case VisitorJob::LabelRefVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002760 const LabelDecl *LS = cast<LabelRefVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002761 if (LabelStmt *stmt = LS->getStmt()) {
2762 if (Visit(MakeCursorLabelRef(stmt, cast<LabelRefVisit>(&LI)->getLoc(),
2763 TU))) {
2764 return true;
2765 }
2766 }
2767 continue;
2768 }
2769
2770 case VisitorJob::NestedNameSpecifierLocVisitKind: {
2771 NestedNameSpecifierLocVisit *V = cast<NestedNameSpecifierLocVisit>(&LI);
2772 if (VisitNestedNameSpecifierLoc(V->get()))
2773 return true;
2774 continue;
2775 }
2776
2777 case VisitorJob::DeclarationNameInfoVisitKind: {
2778 if (VisitDeclarationNameInfo(cast<DeclarationNameInfoVisit>(&LI)
2779 ->get()))
2780 return true;
2781 continue;
2782 }
2783 case VisitorJob::MemberRefVisitKind: {
2784 MemberRefVisit *V = cast<MemberRefVisit>(&LI);
2785 if (Visit(MakeCursorMemberRef(V->get(), V->getLoc(), TU)))
2786 return true;
2787 continue;
2788 }
2789 case VisitorJob::StmtVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002790 const Stmt *S = cast<StmtVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002791 if (!S)
2792 continue;
2793
2794 // Update the current cursor.
2795 CXCursor Cursor = MakeCXCursor(S, StmtParent, TU, RegionOfInterest);
2796 if (!IsInRegionOfInterest(Cursor))
2797 continue;
2798 switch (Visitor(Cursor, Parent, ClientData)) {
2799 case CXChildVisit_Break: return true;
2800 case CXChildVisit_Continue: break;
2801 case CXChildVisit_Recurse:
2802 if (PostChildrenVisitor)
Craig Topper69186e72014-06-08 08:38:04 +00002803 WL.push_back(PostChildrenVisit(nullptr, Cursor));
Guy Benyei11169dd2012-12-18 14:30:41 +00002804 EnqueueWorkList(WL, S);
2805 break;
2806 }
2807 continue;
2808 }
2809 case VisitorJob::MemberExprPartsKind: {
2810 // Handle the other pieces in the MemberExpr besides the base.
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002811 const MemberExpr *M = cast<MemberExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002812
2813 // Visit the nested-name-specifier
2814 if (NestedNameSpecifierLoc QualifierLoc = M->getQualifierLoc())
2815 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2816 return true;
2817
2818 // Visit the declaration name.
2819 if (VisitDeclarationNameInfo(M->getMemberNameInfo()))
2820 return true;
2821
2822 // Visit the explicitly-specified template arguments, if any.
2823 if (M->hasExplicitTemplateArgs()) {
2824 for (const TemplateArgumentLoc *Arg = M->getTemplateArgs(),
2825 *ArgEnd = Arg + M->getNumTemplateArgs();
2826 Arg != ArgEnd; ++Arg) {
2827 if (VisitTemplateArgumentLoc(*Arg))
2828 return true;
2829 }
2830 }
2831 continue;
2832 }
2833 case VisitorJob::DeclRefExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002834 const DeclRefExpr *DR = cast<DeclRefExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002835 // Visit nested-name-specifier, if present.
2836 if (NestedNameSpecifierLoc QualifierLoc = DR->getQualifierLoc())
2837 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2838 return true;
2839 // Visit declaration name.
2840 if (VisitDeclarationNameInfo(DR->getNameInfo()))
2841 return true;
2842 continue;
2843 }
2844 case VisitorJob::OverloadExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002845 const OverloadExpr *O = cast<OverloadExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002846 // Visit the nested-name-specifier.
2847 if (NestedNameSpecifierLoc QualifierLoc = O->getQualifierLoc())
2848 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2849 return true;
2850 // Visit the declaration name.
2851 if (VisitDeclarationNameInfo(O->getNameInfo()))
2852 return true;
2853 // Visit the overloaded declaration reference.
2854 if (Visit(MakeCursorOverloadedDeclRef(O, TU)))
2855 return true;
2856 continue;
2857 }
2858 case VisitorJob::SizeOfPackExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002859 const SizeOfPackExpr *E = cast<SizeOfPackExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002860 NamedDecl *Pack = E->getPack();
2861 if (isa<TemplateTypeParmDecl>(Pack)) {
2862 if (Visit(MakeCursorTypeRef(cast<TemplateTypeParmDecl>(Pack),
2863 E->getPackLoc(), TU)))
2864 return true;
2865
2866 continue;
2867 }
2868
2869 if (isa<TemplateTemplateParmDecl>(Pack)) {
2870 if (Visit(MakeCursorTemplateRef(cast<TemplateTemplateParmDecl>(Pack),
2871 E->getPackLoc(), TU)))
2872 return true;
2873
2874 continue;
2875 }
2876
2877 // Non-type template parameter packs and function parameter packs are
2878 // treated like DeclRefExpr cursors.
2879 continue;
2880 }
2881
2882 case VisitorJob::LambdaExprPartsKind: {
2883 // Visit captures.
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002884 const LambdaExpr *E = cast<LambdaExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002885 for (LambdaExpr::capture_iterator C = E->explicit_capture_begin(),
2886 CEnd = E->explicit_capture_end();
2887 C != CEnd; ++C) {
Richard Smithba71c082013-05-16 06:20:58 +00002888 // FIXME: Lambda init-captures.
2889 if (!C->capturesVariable())
Guy Benyei11169dd2012-12-18 14:30:41 +00002890 continue;
Richard Smithba71c082013-05-16 06:20:58 +00002891
Guy Benyei11169dd2012-12-18 14:30:41 +00002892 if (Visit(MakeCursorVariableRef(C->getCapturedVar(),
2893 C->getLocation(),
2894 TU)))
2895 return true;
2896 }
2897
2898 // Visit parameters and return type, if present.
2899 if (E->hasExplicitParameters() || E->hasExplicitResultType()) {
2900 TypeLoc TL = E->getCallOperator()->getTypeSourceInfo()->getTypeLoc();
2901 if (E->hasExplicitParameters() && E->hasExplicitResultType()) {
2902 // Visit the whole type.
2903 if (Visit(TL))
2904 return true;
David Blaikie6adc78e2013-02-18 22:06:02 +00002905 } else if (FunctionProtoTypeLoc Proto =
2906 TL.getAs<FunctionProtoTypeLoc>()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002907 if (E->hasExplicitParameters()) {
2908 // Visit parameters.
Alp Tokerb3fd5cf2014-01-21 00:32:38 +00002909 for (unsigned I = 0, N = Proto.getNumParams(); I != N; ++I)
2910 if (Visit(MakeCXCursor(Proto.getParam(I), TU)))
Guy Benyei11169dd2012-12-18 14:30:41 +00002911 return true;
2912 } else {
2913 // Visit result type.
Alp Toker42a16a62014-01-25 23:51:36 +00002914 if (Visit(Proto.getReturnLoc()))
Guy Benyei11169dd2012-12-18 14:30:41 +00002915 return true;
2916 }
2917 }
2918 }
2919 break;
2920 }
2921
2922 case VisitorJob::PostChildrenVisitKind:
2923 if (PostChildrenVisitor(Parent, ClientData))
2924 return true;
2925 break;
2926 }
2927 }
2928 return false;
2929}
2930
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002931bool CursorVisitor::Visit(const Stmt *S) {
Craig Topper69186e72014-06-08 08:38:04 +00002932 VisitorWorkList *WL = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00002933 if (!WorkListFreeList.empty()) {
2934 WL = WorkListFreeList.back();
2935 WL->clear();
2936 WorkListFreeList.pop_back();
2937 }
2938 else {
2939 WL = new VisitorWorkList();
2940 WorkListCache.push_back(WL);
2941 }
2942 EnqueueWorkList(*WL, S);
2943 bool result = RunVisitorWorkList(*WL);
2944 WorkListFreeList.push_back(WL);
2945 return result;
2946}
2947
2948namespace {
Dmitri Gribenkof8579502013-01-12 19:30:44 +00002949typedef SmallVector<SourceRange, 4> RefNamePieces;
James Y Knight04ec5bf2015-12-24 02:59:37 +00002950RefNamePieces buildPieces(unsigned NameFlags, bool IsMemberRefExpr,
2951 const DeclarationNameInfo &NI, SourceRange QLoc,
2952 const SourceRange *TemplateArgsLoc = nullptr) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002953 const bool WantQualifier = NameFlags & CXNameRange_WantQualifier;
2954 const bool WantTemplateArgs = NameFlags & CXNameRange_WantTemplateArgs;
2955 const bool WantSinglePiece = NameFlags & CXNameRange_WantSinglePiece;
2956
2957 const DeclarationName::NameKind Kind = NI.getName().getNameKind();
2958
2959 RefNamePieces Pieces;
2960
2961 if (WantQualifier && QLoc.isValid())
2962 Pieces.push_back(QLoc);
2963
2964 if (Kind != DeclarationName::CXXOperatorName || IsMemberRefExpr)
2965 Pieces.push_back(NI.getLoc());
James Y Knight04ec5bf2015-12-24 02:59:37 +00002966
2967 if (WantTemplateArgs && TemplateArgsLoc && TemplateArgsLoc->isValid())
2968 Pieces.push_back(*TemplateArgsLoc);
2969
Guy Benyei11169dd2012-12-18 14:30:41 +00002970 if (Kind == DeclarationName::CXXOperatorName) {
2971 Pieces.push_back(SourceLocation::getFromRawEncoding(
2972 NI.getInfo().CXXOperatorName.BeginOpNameLoc));
2973 Pieces.push_back(SourceLocation::getFromRawEncoding(
2974 NI.getInfo().CXXOperatorName.EndOpNameLoc));
2975 }
2976
2977 if (WantSinglePiece) {
2978 SourceRange R(Pieces.front().getBegin(), Pieces.back().getEnd());
2979 Pieces.clear();
2980 Pieces.push_back(R);
2981 }
2982
2983 return Pieces;
2984}
Alexander Kornienkoab9db512015-06-22 23:07:51 +00002985}
Guy Benyei11169dd2012-12-18 14:30:41 +00002986
2987//===----------------------------------------------------------------------===//
2988// Misc. API hooks.
2989//===----------------------------------------------------------------------===//
2990
Chad Rosier05c71aa2013-03-27 18:28:23 +00002991static void fatal_error_handler(void *user_data, const std::string& reason,
2992 bool gen_crash_diag) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002993 // Write the result out to stderr avoiding errs() because raw_ostreams can
2994 // call report_fatal_error.
2995 fprintf(stderr, "LIBCLANG FATAL ERROR: %s\n", reason.c_str());
2996 ::abort();
2997}
2998
Chandler Carruth66660742014-06-27 16:37:27 +00002999namespace {
3000struct RegisterFatalErrorHandler {
3001 RegisterFatalErrorHandler() {
3002 llvm::install_fatal_error_handler(fatal_error_handler, nullptr);
3003 }
3004};
3005}
3006
3007static llvm::ManagedStatic<RegisterFatalErrorHandler> RegisterFatalErrorHandlerOnce;
3008
Guy Benyei11169dd2012-12-18 14:30:41 +00003009extern "C" {
3010CXIndex clang_createIndex(int excludeDeclarationsFromPCH,
3011 int displayDiagnostics) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003012 // We use crash recovery to make some of our APIs more reliable, implicitly
3013 // enable it.
Argyrios Kyrtzidis3701f542013-11-27 08:58:09 +00003014 if (!getenv("LIBCLANG_DISABLE_CRASH_RECOVERY"))
3015 llvm::CrashRecoveryContext::Enable();
Guy Benyei11169dd2012-12-18 14:30:41 +00003016
Chandler Carruth66660742014-06-27 16:37:27 +00003017 // Look through the managed static to trigger construction of the managed
3018 // static which registers our fatal error handler. This ensures it is only
3019 // registered once.
3020 (void)*RegisterFatalErrorHandlerOnce;
Guy Benyei11169dd2012-12-18 14:30:41 +00003021
Adrian Prantlbc068582015-07-08 01:00:30 +00003022 // Initialize targets for clang module support.
3023 llvm::InitializeAllTargets();
3024 llvm::InitializeAllTargetMCs();
3025 llvm::InitializeAllAsmPrinters();
3026 llvm::InitializeAllAsmParsers();
3027
Adrian Prantlfb2398d2015-07-17 01:19:54 +00003028 CIndexer *CIdxr = new CIndexer();
3029
Guy Benyei11169dd2012-12-18 14:30:41 +00003030 if (excludeDeclarationsFromPCH)
3031 CIdxr->setOnlyLocalDecls();
3032 if (displayDiagnostics)
3033 CIdxr->setDisplayDiagnostics();
3034
3035 if (getenv("LIBCLANG_BGPRIO_INDEX"))
3036 CIdxr->setCXGlobalOptFlags(CIdxr->getCXGlobalOptFlags() |
3037 CXGlobalOpt_ThreadBackgroundPriorityForIndexing);
3038 if (getenv("LIBCLANG_BGPRIO_EDIT"))
3039 CIdxr->setCXGlobalOptFlags(CIdxr->getCXGlobalOptFlags() |
3040 CXGlobalOpt_ThreadBackgroundPriorityForEditing);
3041
3042 return CIdxr;
3043}
3044
3045void clang_disposeIndex(CXIndex CIdx) {
3046 if (CIdx)
3047 delete static_cast<CIndexer *>(CIdx);
3048}
3049
3050void clang_CXIndex_setGlobalOptions(CXIndex CIdx, unsigned options) {
3051 if (CIdx)
3052 static_cast<CIndexer *>(CIdx)->setCXGlobalOptFlags(options);
3053}
3054
3055unsigned clang_CXIndex_getGlobalOptions(CXIndex CIdx) {
3056 if (CIdx)
3057 return static_cast<CIndexer *>(CIdx)->getCXGlobalOptFlags();
3058 return 0;
3059}
3060
3061void clang_toggleCrashRecovery(unsigned isEnabled) {
3062 if (isEnabled)
3063 llvm::CrashRecoveryContext::Enable();
3064 else
3065 llvm::CrashRecoveryContext::Disable();
3066}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003067
Guy Benyei11169dd2012-12-18 14:30:41 +00003068CXTranslationUnit clang_createTranslationUnit(CXIndex CIdx,
3069 const char *ast_filename) {
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00003070 CXTranslationUnit TU;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003071 enum CXErrorCode Result =
3072 clang_createTranslationUnit2(CIdx, ast_filename, &TU);
Reid Klecknerfd48fc62014-02-12 23:56:20 +00003073 (void)Result;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003074 assert((TU && Result == CXError_Success) ||
3075 (!TU && Result != CXError_Success));
3076 return TU;
3077}
3078
3079enum CXErrorCode clang_createTranslationUnit2(CXIndex CIdx,
3080 const char *ast_filename,
3081 CXTranslationUnit *out_TU) {
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00003082 if (out_TU)
Craig Topper69186e72014-06-08 08:38:04 +00003083 *out_TU = nullptr;
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00003084
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003085 if (!CIdx || !ast_filename || !out_TU)
3086 return CXError_InvalidArguments;
Guy Benyei11169dd2012-12-18 14:30:41 +00003087
Argyrios Kyrtzidis27021012013-05-24 22:24:07 +00003088 LOG_FUNC_SECTION {
3089 *Log << ast_filename;
3090 }
3091
Guy Benyei11169dd2012-12-18 14:30:41 +00003092 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
3093 FileSystemOptions FileSystemOpts;
3094
Justin Bognerd512c1e2014-10-15 00:33:06 +00003095 IntrusiveRefCntPtr<DiagnosticsEngine> Diags =
3096 CompilerInstance::createDiagnostics(new DiagnosticOptions());
David Blaikie6f7382d2014-08-10 19:08:04 +00003097 std::unique_ptr<ASTUnit> AU = ASTUnit::LoadFromASTFile(
Adrian Prantlfb2398d2015-07-17 01:19:54 +00003098 ast_filename, CXXIdx->getPCHContainerOperations()->getRawReader(), Diags,
Adrian Prantl6b21ab22015-08-27 19:46:20 +00003099 FileSystemOpts, /*UseDebugInfo=*/false,
3100 CXXIdx->getOnlyLocalDecls(), None,
David Blaikie6f7382d2014-08-10 19:08:04 +00003101 /*CaptureDiagnostics=*/true,
3102 /*AllowPCHWithCompilerErrors=*/true,
3103 /*UserFilesAreVolatile=*/true);
3104 *out_TU = MakeCXTranslationUnit(CXXIdx, AU.release());
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003105 return *out_TU ? CXError_Success : CXError_Failure;
Guy Benyei11169dd2012-12-18 14:30:41 +00003106}
3107
3108unsigned clang_defaultEditingTranslationUnitOptions() {
3109 return CXTranslationUnit_PrecompiledPreamble |
3110 CXTranslationUnit_CacheCompletionResults;
3111}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003112
Guy Benyei11169dd2012-12-18 14:30:41 +00003113CXTranslationUnit
3114clang_createTranslationUnitFromSourceFile(CXIndex CIdx,
3115 const char *source_filename,
3116 int num_command_line_args,
3117 const char * const *command_line_args,
3118 unsigned num_unsaved_files,
3119 struct CXUnsavedFile *unsaved_files) {
3120 unsigned Options = CXTranslationUnit_DetailedPreprocessingRecord;
3121 return clang_parseTranslationUnit(CIdx, source_filename,
3122 command_line_args, num_command_line_args,
3123 unsaved_files, num_unsaved_files,
3124 Options);
3125}
3126
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003127static CXErrorCode
3128clang_parseTranslationUnit_Impl(CXIndex CIdx, const char *source_filename,
3129 const char *const *command_line_args,
3130 int num_command_line_args,
3131 ArrayRef<CXUnsavedFile> unsaved_files,
3132 unsigned options, CXTranslationUnit *out_TU) {
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00003133 // Set up the initial return values.
3134 if (out_TU)
Craig Topper69186e72014-06-08 08:38:04 +00003135 *out_TU = nullptr;
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00003136
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003137 // Check arguments.
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003138 if (!CIdx || !out_TU)
3139 return CXError_InvalidArguments;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003140
Guy Benyei11169dd2012-12-18 14:30:41 +00003141 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
3142
3143 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
3144 setThreadBackgroundPriority();
3145
3146 bool PrecompilePreamble = options & CXTranslationUnit_PrecompiledPreamble;
Benjamin Kramer5c248d82015-12-15 09:30:31 +00003147 bool CreatePreambleOnFirstParse =
3148 options & CXTranslationUnit_CreatePreambleOnFirstParse;
Guy Benyei11169dd2012-12-18 14:30:41 +00003149 // FIXME: Add a flag for modules.
3150 TranslationUnitKind TUKind
3151 = (options & CXTranslationUnit_Incomplete)? TU_Prefix : TU_Complete;
Alp Toker8c8a8752013-12-03 06:53:35 +00003152 bool CacheCodeCompletionResults
Guy Benyei11169dd2012-12-18 14:30:41 +00003153 = options & CXTranslationUnit_CacheCompletionResults;
3154 bool IncludeBriefCommentsInCodeCompletion
3155 = options & CXTranslationUnit_IncludeBriefCommentsInCodeCompletion;
3156 bool SkipFunctionBodies = options & CXTranslationUnit_SkipFunctionBodies;
3157 bool ForSerialization = options & CXTranslationUnit_ForSerialization;
3158
3159 // Configure the diagnostics.
3160 IntrusiveRefCntPtr<DiagnosticsEngine>
Sean Silvaf1b49e22013-01-20 01:58:28 +00003161 Diags(CompilerInstance::createDiagnostics(new DiagnosticOptions));
Guy Benyei11169dd2012-12-18 14:30:41 +00003162
Manuel Klimek016c0242016-03-01 10:56:19 +00003163 if (options & CXTranslationUnit_KeepGoing)
3164 Diags->setFatalsAsError(true);
3165
Guy Benyei11169dd2012-12-18 14:30:41 +00003166 // Recover resources if we crash before exiting this function.
3167 llvm::CrashRecoveryContextCleanupRegistrar<DiagnosticsEngine,
3168 llvm::CrashRecoveryContextReleaseRefCleanup<DiagnosticsEngine> >
Alp Tokerf994cef2014-07-05 03:08:06 +00003169 DiagCleanup(Diags.get());
Guy Benyei11169dd2012-12-18 14:30:41 +00003170
Ahmed Charlesb8984322014-03-07 20:03:18 +00003171 std::unique_ptr<std::vector<ASTUnit::RemappedFile>> RemappedFiles(
3172 new std::vector<ASTUnit::RemappedFile>());
Guy Benyei11169dd2012-12-18 14:30:41 +00003173
3174 // Recover resources if we crash before exiting this function.
3175 llvm::CrashRecoveryContextCleanupRegistrar<
3176 std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
3177
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003178 for (auto &UF : unsaved_files) {
Rafael Espindolad87f8d72014-08-27 20:03:29 +00003179 std::unique_ptr<llvm::MemoryBuffer> MB =
Alp Toker9d85b182014-07-07 01:23:14 +00003180 llvm::MemoryBuffer::getMemBufferCopy(getContents(UF), UF.Filename);
Rafael Espindolad87f8d72014-08-27 20:03:29 +00003181 RemappedFiles->push_back(std::make_pair(UF.Filename, MB.release()));
Guy Benyei11169dd2012-12-18 14:30:41 +00003182 }
3183
Ahmed Charlesb8984322014-03-07 20:03:18 +00003184 std::unique_ptr<std::vector<const char *>> Args(
3185 new std::vector<const char *>());
Guy Benyei11169dd2012-12-18 14:30:41 +00003186
3187 // Recover resources if we crash before exiting this method.
3188 llvm::CrashRecoveryContextCleanupRegistrar<std::vector<const char*> >
3189 ArgsCleanup(Args.get());
3190
3191 // Since the Clang C library is primarily used by batch tools dealing with
3192 // (often very broken) source code, where spell-checking can have a
3193 // significant negative impact on performance (particularly when
3194 // precompiled headers are involved), we disable it by default.
3195 // Only do this if we haven't found a spell-checking-related argument.
3196 bool FoundSpellCheckingArgument = false;
3197 for (int I = 0; I != num_command_line_args; ++I) {
3198 if (strcmp(command_line_args[I], "-fno-spell-checking") == 0 ||
3199 strcmp(command_line_args[I], "-fspell-checking") == 0) {
3200 FoundSpellCheckingArgument = true;
3201 break;
3202 }
3203 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003204 Args->insert(Args->end(), command_line_args,
3205 command_line_args + num_command_line_args);
3206
Benjamin Kramerc02670e2015-11-18 16:14:27 +00003207 if (!FoundSpellCheckingArgument)
3208 Args->insert(Args->begin() + 1, "-fno-spell-checking");
3209
Guy Benyei11169dd2012-12-18 14:30:41 +00003210 // The 'source_filename' argument is optional. If the caller does not
3211 // specify it then it is assumed that the source file is specified
3212 // in the actual argument list.
3213 // Put the source file after command_line_args otherwise if '-x' flag is
3214 // present it will be unused.
3215 if (source_filename)
3216 Args->push_back(source_filename);
3217
3218 // Do we need the detailed preprocessing record?
3219 if (options & CXTranslationUnit_DetailedPreprocessingRecord) {
3220 Args->push_back("-Xclang");
3221 Args->push_back("-detailed-preprocessing-record");
3222 }
3223
3224 unsigned NumErrors = Diags->getClient()->getNumErrors();
Ahmed Charlesb8984322014-03-07 20:03:18 +00003225 std::unique_ptr<ASTUnit> ErrUnit;
Benjamin Kramer5c248d82015-12-15 09:30:31 +00003226 // Unless the user specified that they want the preamble on the first parse
3227 // set it up to be created on the first reparse. This makes the first parse
3228 // faster, trading for a slower (first) reparse.
3229 unsigned PrecompilePreambleAfterNParses =
3230 !PrecompilePreamble ? 0 : 2 - CreatePreambleOnFirstParse;
Ahmed Charlesb8984322014-03-07 20:03:18 +00003231 std::unique_ptr<ASTUnit> Unit(ASTUnit::LoadFromCommandLine(
Adrian Prantlbb165fb2015-06-20 18:53:08 +00003232 Args->data(), Args->data() + Args->size(),
3233 CXXIdx->getPCHContainerOperations(), Diags,
Ahmed Charlesb8984322014-03-07 20:03:18 +00003234 CXXIdx->getClangResourcesPath(), CXXIdx->getOnlyLocalDecls(),
3235 /*CaptureDiagnostics=*/true, *RemappedFiles.get(),
Benjamin Kramer5c248d82015-12-15 09:30:31 +00003236 /*RemappedFilesKeepOriginalName=*/true, PrecompilePreambleAfterNParses,
3237 TUKind, CacheCodeCompletionResults, IncludeBriefCommentsInCodeCompletion,
Ahmed Charlesb8984322014-03-07 20:03:18 +00003238 /*AllowPCHWithCompilerErrors=*/true, SkipFunctionBodies,
Argyrios Kyrtzidisa3e2ff12015-11-20 03:36:21 +00003239 /*UserFilesAreVolatile=*/true, ForSerialization,
3240 CXXIdx->getPCHContainerOperations()->getRawReader().getFormat(),
3241 &ErrUnit));
Guy Benyei11169dd2012-12-18 14:30:41 +00003242
Artem Belevich0ff05cd2015-07-13 23:27:56 +00003243 // Early failures in LoadFromCommandLine may return with ErrUnit unset.
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003244 if (!Unit && !ErrUnit)
3245 return CXError_ASTReadError;
Artem Belevich0ff05cd2015-07-13 23:27:56 +00003246
Guy Benyei11169dd2012-12-18 14:30:41 +00003247 if (NumErrors != Diags->getClient()->getNumErrors()) {
3248 // Make sure to check that 'Unit' is non-NULL.
3249 if (CXXIdx->getDisplayDiagnostics())
3250 printDiagsToStderr(Unit ? Unit.get() : ErrUnit.get());
3251 }
3252
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003253 if (isASTReadError(Unit ? Unit.get() : ErrUnit.get()))
3254 return CXError_ASTReadError;
3255
3256 *out_TU = MakeCXTranslationUnit(CXXIdx, Unit.release());
3257 return *out_TU ? CXError_Success : CXError_Failure;
Guy Benyei11169dd2012-12-18 14:30:41 +00003258}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003259
3260CXTranslationUnit
3261clang_parseTranslationUnit(CXIndex CIdx,
3262 const char *source_filename,
3263 const char *const *command_line_args,
3264 int num_command_line_args,
3265 struct CXUnsavedFile *unsaved_files,
3266 unsigned num_unsaved_files,
3267 unsigned options) {
3268 CXTranslationUnit TU;
3269 enum CXErrorCode Result = clang_parseTranslationUnit2(
3270 CIdx, source_filename, command_line_args, num_command_line_args,
3271 unsaved_files, num_unsaved_files, options, &TU);
Reid Kleckner6eaf05a2014-02-13 01:19:59 +00003272 (void)Result;
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00003273 assert((TU && Result == CXError_Success) ||
3274 (!TU && Result != CXError_Success));
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003275 return TU;
3276}
3277
3278enum CXErrorCode clang_parseTranslationUnit2(
Benjamin Kramerc02670e2015-11-18 16:14:27 +00003279 CXIndex CIdx, const char *source_filename,
3280 const char *const *command_line_args, int num_command_line_args,
3281 struct CXUnsavedFile *unsaved_files, unsigned num_unsaved_files,
3282 unsigned options, CXTranslationUnit *out_TU) {
3283 SmallVector<const char *, 4> Args;
3284 Args.push_back("clang");
3285 Args.append(command_line_args, command_line_args + num_command_line_args);
3286 return clang_parseTranslationUnit2FullArgv(
3287 CIdx, source_filename, Args.data(), Args.size(), unsaved_files,
3288 num_unsaved_files, options, out_TU);
3289}
3290
3291enum CXErrorCode clang_parseTranslationUnit2FullArgv(
3292 CXIndex CIdx, const char *source_filename,
3293 const char *const *command_line_args, int num_command_line_args,
3294 struct CXUnsavedFile *unsaved_files, unsigned num_unsaved_files,
3295 unsigned options, CXTranslationUnit *out_TU) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00003296 LOG_FUNC_SECTION {
3297 *Log << source_filename << ": ";
3298 for (int i = 0; i != num_command_line_args; ++i)
3299 *Log << command_line_args[i] << " ";
3300 }
3301
Alp Toker9d85b182014-07-07 01:23:14 +00003302 if (num_unsaved_files && !unsaved_files)
3303 return CXError_InvalidArguments;
3304
Alp Toker5c532982014-07-07 22:42:03 +00003305 CXErrorCode result = CXError_Failure;
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003306 auto ParseTranslationUnitImpl = [=, &result] {
3307 result = clang_parseTranslationUnit_Impl(
3308 CIdx, source_filename, command_line_args, num_command_line_args,
3309 llvm::makeArrayRef(unsaved_files, num_unsaved_files), options, out_TU);
3310 };
Guy Benyei11169dd2012-12-18 14:30:41 +00003311 llvm::CrashRecoveryContext CRC;
3312
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003313 if (!RunSafely(CRC, ParseTranslationUnitImpl)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003314 fprintf(stderr, "libclang: crash detected during parsing: {\n");
3315 fprintf(stderr, " 'source_filename' : '%s'\n", source_filename);
3316 fprintf(stderr, " 'command_line_args' : [");
3317 for (int i = 0; i != num_command_line_args; ++i) {
3318 if (i)
3319 fprintf(stderr, ", ");
3320 fprintf(stderr, "'%s'", command_line_args[i]);
3321 }
3322 fprintf(stderr, "],\n");
3323 fprintf(stderr, " 'unsaved_files' : [");
3324 for (unsigned i = 0; i != num_unsaved_files; ++i) {
3325 if (i)
3326 fprintf(stderr, ", ");
3327 fprintf(stderr, "('%s', '...', %ld)", unsaved_files[i].Filename,
3328 unsaved_files[i].Length);
3329 }
3330 fprintf(stderr, "],\n");
3331 fprintf(stderr, " 'options' : %d,\n", options);
3332 fprintf(stderr, "}\n");
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003333
3334 return CXError_Crashed;
Guy Benyei11169dd2012-12-18 14:30:41 +00003335 } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003336 if (CXTranslationUnit *TU = out_TU)
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003337 PrintLibclangResourceUsage(*TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003338 }
Alp Toker5c532982014-07-07 22:42:03 +00003339
3340 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003341}
3342
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003343CXString clang_Type_getObjCEncoding(CXType CT) {
3344 CXTranslationUnit tu = static_cast<CXTranslationUnit>(CT.data[1]);
3345 ASTContext &Ctx = getASTUnit(tu)->getASTContext();
3346 std::string encoding;
3347 Ctx.getObjCEncodingForType(QualType::getFromOpaquePtr(CT.data[0]),
3348 encoding);
3349
3350 return cxstring::createDup(encoding);
3351}
3352
3353static const IdentifierInfo *getMacroIdentifier(CXCursor C) {
3354 if (C.kind == CXCursor_MacroDefinition) {
3355 if (const MacroDefinitionRecord *MDR = getCursorMacroDefinition(C))
3356 return MDR->getName();
3357 } else if (C.kind == CXCursor_MacroExpansion) {
3358 MacroExpansionCursor ME = getCursorMacroExpansion(C);
3359 return ME.getName();
3360 }
3361 return nullptr;
3362}
3363
3364unsigned clang_Cursor_isMacroFunctionLike(CXCursor C) {
3365 const IdentifierInfo *II = getMacroIdentifier(C);
3366 if (!II) {
3367 return false;
3368 }
3369 ASTUnit *ASTU = getCursorASTUnit(C);
3370 Preprocessor &PP = ASTU->getPreprocessor();
3371 if (const MacroInfo *MI = PP.getMacroInfo(II))
3372 return MI->isFunctionLike();
3373 return false;
3374}
3375
3376unsigned clang_Cursor_isMacroBuiltin(CXCursor C) {
3377 const IdentifierInfo *II = getMacroIdentifier(C);
3378 if (!II) {
3379 return false;
3380 }
3381 ASTUnit *ASTU = getCursorASTUnit(C);
3382 Preprocessor &PP = ASTU->getPreprocessor();
3383 if (const MacroInfo *MI = PP.getMacroInfo(II))
3384 return MI->isBuiltinMacro();
3385 return false;
3386}
3387
3388unsigned clang_Cursor_isFunctionInlined(CXCursor C) {
3389 const Decl *D = getCursorDecl(C);
3390 const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(D);
3391 if (!FD) {
3392 return false;
3393 }
3394 return FD->isInlined();
3395}
3396
3397static StringLiteral* getCFSTR_value(CallExpr *callExpr) {
3398 if (callExpr->getNumArgs() != 1) {
3399 return nullptr;
3400 }
3401
3402 StringLiteral *S = nullptr;
3403 auto *arg = callExpr->getArg(0);
3404 if (arg->getStmtClass() == Stmt::ImplicitCastExprClass) {
3405 ImplicitCastExpr *I = static_cast<ImplicitCastExpr *>(arg);
3406 auto *subExpr = I->getSubExprAsWritten();
3407
3408 if(subExpr->getStmtClass() != Stmt::StringLiteralClass){
3409 return nullptr;
3410 }
3411
3412 S = static_cast<StringLiteral *>(I->getSubExprAsWritten());
3413 } else if (arg->getStmtClass() == Stmt::StringLiteralClass) {
3414 S = static_cast<StringLiteral *>(callExpr->getArg(0));
3415 } else {
3416 return nullptr;
3417 }
3418 return S;
3419}
3420
3421typedef struct {
3422 CXEvalResultKind EvalType;
3423 union {
3424 int intVal;
3425 double floatVal;
3426 char *stringVal;
3427 } EvalData;
3428} ExprEvalResult;
3429
3430void clang_EvalResult_dispose(CXEvalResult E) {
3431 ExprEvalResult *ER = (ExprEvalResult *)E;
3432 if (ER) {
3433 CXEvalResultKind evalType = ER->EvalType;
3434
3435 if (evalType != CXEval_UnExposed && evalType != CXEval_Float &&
3436 evalType != CXEval_Int && ER->EvalData.stringVal) {
3437 free((void *) ER->EvalData.stringVal);
3438 }
3439 free((void *)ER);
3440 }
3441}
3442
3443CXEvalResultKind clang_EvalResult_getKind(CXEvalResult E) {
3444 if (!E) {
3445 return CXEval_UnExposed;
3446 }
3447 return ((ExprEvalResult *)E)->EvalType;
3448}
3449
3450int clang_EvalResult_getAsInt(CXEvalResult E) {
3451 if (!E) {
3452 return 0;
3453 }
3454 return ((ExprEvalResult *)E)->EvalData.intVal;
3455}
3456
3457double clang_EvalResult_getAsDouble(CXEvalResult E) {
3458 if (!E) {
3459 return 0;
3460 }
3461 return ((ExprEvalResult *)E)->EvalData.floatVal;
3462}
3463
3464const char* clang_EvalResult_getAsStr(CXEvalResult E) {
3465 if (!E) {
3466 return nullptr;
3467 }
3468 return ((ExprEvalResult *)E)->EvalData.stringVal;
3469}
3470
3471static const ExprEvalResult* evaluateExpr(Expr *expr, CXCursor C) {
3472 Expr::EvalResult ER;
3473 ASTContext &ctx = getCursorContext(C);
3474 if (!expr) {
3475 return nullptr;
3476 }
3477 expr = expr->IgnoreParens();
3478 bool res = expr->EvaluateAsRValue(ER, ctx);
3479 QualType rettype;
3480 CallExpr *callExpr;
3481 ExprEvalResult *result = (ExprEvalResult *) malloc(sizeof(ExprEvalResult));
3482 if (!result) {
3483 return nullptr;
3484 }
3485 result->EvalType = CXEval_UnExposed;
3486
3487 if (res) {
3488
3489 if (ER.Val.isInt()) {
3490 result->EvalType = CXEval_Int;
3491 result->EvalData.intVal = ER.Val.getInt().getExtValue();
3492 return result;
3493 } else if (ER.Val.isFloat()) {
3494
3495 llvm::SmallVector<char, 100> Buffer;
3496 ER.Val.getFloat().toString(Buffer);
3497 std::string floatStr(Buffer.data(), Buffer.size());
3498 result->EvalType = CXEval_Float;
3499 bool ignored;
3500 llvm::APFloat apFloat = ER.Val.getFloat();
3501 apFloat.convert(llvm::APFloat::IEEEdouble,
3502 llvm::APFloat::rmNearestTiesToEven, &ignored);
3503 result->EvalData.floatVal = apFloat.convertToDouble();
3504 return result;
3505
3506 } else if (expr->getStmtClass() == Stmt::ImplicitCastExprClass) {
3507
3508 const ImplicitCastExpr *I = dyn_cast<ImplicitCastExpr>(expr);
3509 auto *subExpr = I->getSubExprAsWritten();
3510 if (subExpr->getStmtClass() == Stmt::StringLiteralClass ||
3511 subExpr->getStmtClass() == Stmt::ObjCStringLiteralClass) {
3512
3513 const StringLiteral *StrE = nullptr;
3514 const ObjCStringLiteral *ObjCExpr;
3515 ObjCExpr = dyn_cast<ObjCStringLiteral>(subExpr);
3516
3517 if (ObjCExpr) {
3518 StrE = ObjCExpr->getString();
3519 result->EvalType = CXEval_ObjCStrLiteral;
3520 } else {
3521 StrE = cast<StringLiteral>(I->getSubExprAsWritten());
3522 result->EvalType = CXEval_StrLiteral;
3523 }
3524
3525 std::string strRef(StrE->getString().str());
3526 result->EvalData.stringVal = (char *)malloc(strRef.size()+1);
3527 strncpy((char*)result->EvalData.stringVal, strRef.c_str(),
3528 strRef.size());
3529 result->EvalData.stringVal[strRef.size()] = '\0';
3530 return result;
3531 }
3532
3533 } else if (expr->getStmtClass() == Stmt::ObjCStringLiteralClass ||
3534 expr->getStmtClass() == Stmt::StringLiteralClass) {
3535
3536 const StringLiteral *StrE = nullptr;
3537 const ObjCStringLiteral *ObjCExpr;
3538 ObjCExpr = dyn_cast<ObjCStringLiteral>(expr);
3539
3540 if (ObjCExpr) {
3541 StrE = ObjCExpr->getString();
3542 result->EvalType = CXEval_ObjCStrLiteral;
3543 } else {
3544 StrE = cast<StringLiteral>(expr);
3545 result->EvalType = CXEval_StrLiteral;
3546 }
3547
3548 std::string strRef(StrE->getString().str());
3549 result->EvalData.stringVal = (char *)malloc(strRef.size()+1);
3550 strncpy((char*)result->EvalData.stringVal, strRef.c_str(),
3551 strRef.size());
3552 result->EvalData.stringVal[strRef.size()] = '\0';
3553 return result;
3554
3555 } else if (expr->getStmtClass() == Stmt::CStyleCastExprClass) {
3556
3557 CStyleCastExpr *CC = static_cast<CStyleCastExpr *>(expr);
3558
3559 rettype = CC->getType();
3560 if (rettype.getAsString() == "CFStringRef" &&
3561 CC->getSubExpr()->getStmtClass() == Stmt::CallExprClass) {
3562
3563 callExpr = static_cast<CallExpr *>(CC->getSubExpr());
3564 StringLiteral* S = getCFSTR_value(callExpr);
3565 if (S) {
3566 std::string strLiteral(S->getString().str());
3567 result->EvalType = CXEval_CFStr;
3568
3569 result->EvalData.stringVal = (char *)malloc(strLiteral.size()+1);
3570 strncpy((char*)result->EvalData.stringVal, strLiteral.c_str(),
3571 strLiteral.size());
3572 result->EvalData.stringVal[strLiteral.size()] = '\0';
3573 return result;
3574 }
3575 }
3576
3577 } else if (expr->getStmtClass() == Stmt::CallExprClass) {
3578
3579 callExpr = static_cast<CallExpr *>(expr);
3580 rettype = callExpr->getCallReturnType(ctx);
3581
3582 if (rettype->isVectorType() || callExpr->getNumArgs() > 1) {
3583 return nullptr;
3584 }
3585 if (rettype->isIntegralType(ctx) || rettype->isRealFloatingType()) {
3586 if(callExpr->getNumArgs() == 1 &&
3587 !callExpr->getArg(0)->getType()->isIntegralType(ctx)){
3588
3589 return nullptr;
3590 }
3591 } else if(rettype.getAsString() == "CFStringRef") {
3592
3593 StringLiteral* S = getCFSTR_value(callExpr);
3594 if (S) {
3595 std::string strLiteral(S->getString().str());
3596 result->EvalType = CXEval_CFStr;
3597 result->EvalData.stringVal = (char *)malloc(strLiteral.size()+1);
3598 strncpy((char*)result->EvalData.stringVal, strLiteral.c_str(),
3599 strLiteral.size());
3600 result->EvalData.stringVal[strLiteral.size()] = '\0';
3601 return result;
3602 }
3603 }
3604
3605 } else if (expr->getStmtClass() == Stmt::DeclRefExprClass) {
3606
3607 DeclRefExpr *D = static_cast<DeclRefExpr *>(expr);
3608 ValueDecl *V = D->getDecl();
3609 if (V->getKind() == Decl::Function) {
3610 std::string strName(V->getNameAsString());
3611 result->EvalType = CXEval_Other;
3612 result->EvalData.stringVal = (char *)malloc(strName.size()+1);
3613 strncpy((char*)result->EvalData.stringVal, strName.c_str(),
3614 strName.size());
3615 result->EvalData.stringVal[strName.size()] = '\0';
3616 return result;
3617 }
3618 }
3619
3620 }
3621
3622 clang_EvalResult_dispose((CXEvalResult *)result);
3623 return nullptr;
3624}
3625
3626CXEvalResult clang_Cursor_Evaluate(CXCursor C) {
3627 const Decl *D = getCursorDecl(C);
3628 if (D) {
3629 const Expr *expr = nullptr;
3630 if (auto *Var = dyn_cast<VarDecl>(D)) {
3631 expr = Var->getInit();
3632 } else if (auto *Field = dyn_cast<FieldDecl>(D)) {
3633 expr = Field->getInClassInitializer();
3634 }
3635 if (expr)
Aaron Ballman01dc1572016-01-20 15:25:30 +00003636 return const_cast<CXEvalResult>(reinterpret_cast<const void *>(
3637 evaluateExpr(const_cast<Expr *>(expr), C)));
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003638 return nullptr;
3639 }
3640
3641 const CompoundStmt *compoundStmt = dyn_cast_or_null<CompoundStmt>(getCursorStmt(C));
3642 if (compoundStmt) {
3643 Expr *expr = nullptr;
3644 for (auto *bodyIterator : compoundStmt->body()) {
3645 if ((expr = dyn_cast<Expr>(bodyIterator))) {
3646 break;
3647 }
3648 }
3649 if (expr)
Aaron Ballman01dc1572016-01-20 15:25:30 +00003650 return const_cast<CXEvalResult>(
3651 reinterpret_cast<const void *>(evaluateExpr(expr, C)));
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003652 }
3653 return nullptr;
3654}
3655
3656unsigned clang_Cursor_hasAttrs(CXCursor C) {
3657 const Decl *D = getCursorDecl(C);
3658 if (!D) {
3659 return 0;
3660 }
3661
3662 if (D->hasAttrs()) {
3663 return 1;
3664 }
3665
3666 return 0;
3667}
Guy Benyei11169dd2012-12-18 14:30:41 +00003668unsigned clang_defaultSaveOptions(CXTranslationUnit TU) {
3669 return CXSaveTranslationUnit_None;
3670}
3671
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003672static CXSaveError clang_saveTranslationUnit_Impl(CXTranslationUnit TU,
3673 const char *FileName,
3674 unsigned options) {
3675 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00003676 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
3677 setThreadBackgroundPriority();
3678
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003679 bool hadError = cxtu::getASTUnit(TU)->Save(FileName);
3680 return hadError ? CXSaveError_Unknown : CXSaveError_None;
Guy Benyei11169dd2012-12-18 14:30:41 +00003681}
3682
3683int clang_saveTranslationUnit(CXTranslationUnit TU, const char *FileName,
3684 unsigned options) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00003685 LOG_FUNC_SECTION {
3686 *Log << TU << ' ' << FileName;
3687 }
3688
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003689 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003690 LOG_BAD_TU(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003691 return CXSaveError_InvalidTU;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003692 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003693
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003694 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003695 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
3696 if (!CXXUnit->hasSema())
3697 return CXSaveError_InvalidTU;
3698
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003699 CXSaveError result;
3700 auto SaveTranslationUnitImpl = [=, &result]() {
3701 result = clang_saveTranslationUnit_Impl(TU, FileName, options);
3702 };
Guy Benyei11169dd2012-12-18 14:30:41 +00003703
3704 if (!CXXUnit->getDiagnostics().hasUnrecoverableErrorOccurred() ||
3705 getenv("LIBCLANG_NOTHREADS")) {
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003706 SaveTranslationUnitImpl();
Guy Benyei11169dd2012-12-18 14:30:41 +00003707
3708 if (getenv("LIBCLANG_RESOURCE_USAGE"))
3709 PrintLibclangResourceUsage(TU);
3710
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003711 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003712 }
3713
3714 // We have an AST that has invalid nodes due to compiler errors.
3715 // Use a crash recovery thread for protection.
3716
3717 llvm::CrashRecoveryContext CRC;
3718
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003719 if (!RunSafely(CRC, SaveTranslationUnitImpl)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003720 fprintf(stderr, "libclang: crash detected during AST saving: {\n");
3721 fprintf(stderr, " 'filename' : '%s'\n", FileName);
3722 fprintf(stderr, " 'options' : %d,\n", options);
3723 fprintf(stderr, "}\n");
3724
3725 return CXSaveError_Unknown;
3726
3727 } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
3728 PrintLibclangResourceUsage(TU);
3729 }
3730
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003731 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003732}
3733
3734void clang_disposeTranslationUnit(CXTranslationUnit CTUnit) {
3735 if (CTUnit) {
3736 // If the translation unit has been marked as unsafe to free, just discard
3737 // it.
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003738 ASTUnit *Unit = cxtu::getASTUnit(CTUnit);
3739 if (Unit && Unit->isUnsafeToFree())
Guy Benyei11169dd2012-12-18 14:30:41 +00003740 return;
3741
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003742 delete cxtu::getASTUnit(CTUnit);
Dmitri Gribenkob95b3f12013-01-26 22:44:19 +00003743 delete CTUnit->StringPool;
Guy Benyei11169dd2012-12-18 14:30:41 +00003744 delete static_cast<CXDiagnosticSetImpl *>(CTUnit->Diagnostics);
3745 disposeOverridenCXCursorsPool(CTUnit->OverridenCursorsPool);
Dmitri Gribenko9e605112013-11-13 22:16:51 +00003746 delete CTUnit->CommentToXML;
Guy Benyei11169dd2012-12-18 14:30:41 +00003747 delete CTUnit;
3748 }
3749}
3750
3751unsigned clang_defaultReparseOptions(CXTranslationUnit TU) {
3752 return CXReparse_None;
3753}
3754
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003755static CXErrorCode
3756clang_reparseTranslationUnit_Impl(CXTranslationUnit TU,
3757 ArrayRef<CXUnsavedFile> unsaved_files,
3758 unsigned options) {
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003759 // Check arguments.
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003760 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003761 LOG_BAD_TU(TU);
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003762 return CXError_InvalidArguments;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003763 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003764
3765 // Reset the associated diagnostics.
3766 delete static_cast<CXDiagnosticSetImpl*>(TU->Diagnostics);
Craig Topper69186e72014-06-08 08:38:04 +00003767 TU->Diagnostics = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00003768
Dmitri Gribenko183436e2013-01-26 21:49:50 +00003769 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00003770 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
3771 setThreadBackgroundPriority();
3772
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003773 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003774 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
Ahmed Charlesb8984322014-03-07 20:03:18 +00003775
3776 std::unique_ptr<std::vector<ASTUnit::RemappedFile>> RemappedFiles(
3777 new std::vector<ASTUnit::RemappedFile>());
3778
Guy Benyei11169dd2012-12-18 14:30:41 +00003779 // Recover resources if we crash before exiting this function.
3780 llvm::CrashRecoveryContextCleanupRegistrar<
3781 std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
Alp Toker9d85b182014-07-07 01:23:14 +00003782
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003783 for (auto &UF : unsaved_files) {
Rafael Espindolad87f8d72014-08-27 20:03:29 +00003784 std::unique_ptr<llvm::MemoryBuffer> MB =
Alp Toker9d85b182014-07-07 01:23:14 +00003785 llvm::MemoryBuffer::getMemBufferCopy(getContents(UF), UF.Filename);
Rafael Espindolad87f8d72014-08-27 20:03:29 +00003786 RemappedFiles->push_back(std::make_pair(UF.Filename, MB.release()));
Guy Benyei11169dd2012-12-18 14:30:41 +00003787 }
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003788
Adrian Prantlbb165fb2015-06-20 18:53:08 +00003789 if (!CXXUnit->Reparse(CXXIdx->getPCHContainerOperations(),
3790 *RemappedFiles.get()))
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003791 return CXError_Success;
3792 if (isASTReadError(CXXUnit))
3793 return CXError_ASTReadError;
3794 return CXError_Failure;
Guy Benyei11169dd2012-12-18 14:30:41 +00003795}
3796
3797int clang_reparseTranslationUnit(CXTranslationUnit TU,
3798 unsigned num_unsaved_files,
3799 struct CXUnsavedFile *unsaved_files,
3800 unsigned options) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00003801 LOG_FUNC_SECTION {
3802 *Log << TU;
3803 }
3804
Alp Toker9d85b182014-07-07 01:23:14 +00003805 if (num_unsaved_files && !unsaved_files)
3806 return CXError_InvalidArguments;
3807
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003808 CXErrorCode result;
3809 auto ReparseTranslationUnitImpl = [=, &result]() {
3810 result = clang_reparseTranslationUnit_Impl(
3811 TU, llvm::makeArrayRef(unsaved_files, num_unsaved_files), options);
3812 };
Guy Benyei11169dd2012-12-18 14:30:41 +00003813
3814 if (getenv("LIBCLANG_NOTHREADS")) {
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003815 ReparseTranslationUnitImpl();
Alp Toker5c532982014-07-07 22:42:03 +00003816 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003817 }
3818
3819 llvm::CrashRecoveryContext CRC;
3820
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003821 if (!RunSafely(CRC, ReparseTranslationUnitImpl)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003822 fprintf(stderr, "libclang: crash detected during reparsing\n");
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003823 cxtu::getASTUnit(TU)->setUnsafeToFree(true);
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003824 return CXError_Crashed;
Guy Benyei11169dd2012-12-18 14:30:41 +00003825 } else if (getenv("LIBCLANG_RESOURCE_USAGE"))
3826 PrintLibclangResourceUsage(TU);
3827
Alp Toker5c532982014-07-07 22:42:03 +00003828 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003829}
3830
3831
3832CXString clang_getTranslationUnitSpelling(CXTranslationUnit CTUnit) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003833 if (isNotUsableTU(CTUnit)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003834 LOG_BAD_TU(CTUnit);
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003835 return cxstring::createEmpty();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003836 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003837
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003838 ASTUnit *CXXUnit = cxtu::getASTUnit(CTUnit);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003839 return cxstring::createDup(CXXUnit->getOriginalSourceFileName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003840}
3841
3842CXCursor clang_getTranslationUnitCursor(CXTranslationUnit TU) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003843 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003844 LOG_BAD_TU(TU);
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00003845 return clang_getNullCursor();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003846 }
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00003847
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003848 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003849 return MakeCXCursor(CXXUnit->getASTContext().getTranslationUnitDecl(), TU);
3850}
3851
3852} // end: extern "C"
3853
3854//===----------------------------------------------------------------------===//
3855// CXFile Operations.
3856//===----------------------------------------------------------------------===//
3857
3858extern "C" {
3859CXString clang_getFileName(CXFile SFile) {
3860 if (!SFile)
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00003861 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00003862
3863 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003864 return cxstring::createRef(FEnt->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003865}
3866
3867time_t clang_getFileTime(CXFile SFile) {
3868 if (!SFile)
3869 return 0;
3870
3871 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
3872 return FEnt->getModificationTime();
3873}
3874
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003875CXFile clang_getFile(CXTranslationUnit TU, const char *file_name) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003876 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003877 LOG_BAD_TU(TU);
Craig Topper69186e72014-06-08 08:38:04 +00003878 return nullptr;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003879 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003880
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003881 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003882
3883 FileManager &FMgr = CXXUnit->getFileManager();
3884 return const_cast<FileEntry *>(FMgr.getFile(file_name));
3885}
3886
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003887unsigned clang_isFileMultipleIncludeGuarded(CXTranslationUnit TU,
3888 CXFile file) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003889 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003890 LOG_BAD_TU(TU);
3891 return 0;
3892 }
3893
3894 if (!file)
Guy Benyei11169dd2012-12-18 14:30:41 +00003895 return 0;
3896
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003897 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003898 FileEntry *FEnt = static_cast<FileEntry *>(file);
3899 return CXXUnit->getPreprocessor().getHeaderSearchInfo()
3900 .isFileMultipleIncludeGuarded(FEnt);
3901}
3902
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003903int clang_getFileUniqueID(CXFile file, CXFileUniqueID *outID) {
3904 if (!file || !outID)
3905 return 1;
3906
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003907 FileEntry *FEnt = static_cast<FileEntry *>(file);
Rafael Espindolaf8f91b82013-08-01 21:42:11 +00003908 const llvm::sys::fs::UniqueID &ID = FEnt->getUniqueID();
3909 outID->data[0] = ID.getDevice();
3910 outID->data[1] = ID.getFile();
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003911 outID->data[2] = FEnt->getModificationTime();
3912 return 0;
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003913}
3914
Argyrios Kyrtzidisac3997e2014-08-16 00:26:19 +00003915int clang_File_isEqual(CXFile file1, CXFile file2) {
3916 if (file1 == file2)
3917 return true;
3918
3919 if (!file1 || !file2)
3920 return false;
3921
3922 FileEntry *FEnt1 = static_cast<FileEntry *>(file1);
3923 FileEntry *FEnt2 = static_cast<FileEntry *>(file2);
3924 return FEnt1->getUniqueID() == FEnt2->getUniqueID();
3925}
3926
Guy Benyei11169dd2012-12-18 14:30:41 +00003927} // end: extern "C"
3928
3929//===----------------------------------------------------------------------===//
3930// CXCursor Operations.
3931//===----------------------------------------------------------------------===//
3932
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003933static const Decl *getDeclFromExpr(const Stmt *E) {
3934 if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003935 return getDeclFromExpr(CE->getSubExpr());
3936
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003937 if (const DeclRefExpr *RefExpr = dyn_cast<DeclRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003938 return RefExpr->getDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003939 if (const MemberExpr *ME = dyn_cast<MemberExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003940 return ME->getMemberDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003941 if (const ObjCIvarRefExpr *RE = dyn_cast<ObjCIvarRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003942 return RE->getDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003943 if (const ObjCPropertyRefExpr *PRE = dyn_cast<ObjCPropertyRefExpr>(E)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003944 if (PRE->isExplicitProperty())
3945 return PRE->getExplicitProperty();
3946 // It could be messaging both getter and setter as in:
3947 // ++myobj.myprop;
3948 // in which case prefer to associate the setter since it is less obvious
3949 // from inspecting the source that the setter is going to get called.
3950 if (PRE->isMessagingSetter())
3951 return PRE->getImplicitPropertySetter();
3952 return PRE->getImplicitPropertyGetter();
3953 }
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003954 if (const PseudoObjectExpr *POE = dyn_cast<PseudoObjectExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003955 return getDeclFromExpr(POE->getSyntacticForm());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003956 if (const OpaqueValueExpr *OVE = dyn_cast<OpaqueValueExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003957 if (Expr *Src = OVE->getSourceExpr())
3958 return getDeclFromExpr(Src);
3959
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003960 if (const CallExpr *CE = dyn_cast<CallExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003961 return getDeclFromExpr(CE->getCallee());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003962 if (const CXXConstructExpr *CE = dyn_cast<CXXConstructExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003963 if (!CE->isElidable())
3964 return CE->getConstructor();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003965 if (const ObjCMessageExpr *OME = dyn_cast<ObjCMessageExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003966 return OME->getMethodDecl();
3967
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003968 if (const ObjCProtocolExpr *PE = dyn_cast<ObjCProtocolExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003969 return PE->getProtocol();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003970 if (const SubstNonTypeTemplateParmPackExpr *NTTP
Guy Benyei11169dd2012-12-18 14:30:41 +00003971 = dyn_cast<SubstNonTypeTemplateParmPackExpr>(E))
3972 return NTTP->getParameterPack();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003973 if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003974 if (isa<NonTypeTemplateParmDecl>(SizeOfPack->getPack()) ||
3975 isa<ParmVarDecl>(SizeOfPack->getPack()))
3976 return SizeOfPack->getPack();
Craig Topper69186e72014-06-08 08:38:04 +00003977
3978 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00003979}
3980
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003981static SourceLocation getLocationFromExpr(const Expr *E) {
3982 if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003983 return getLocationFromExpr(CE->getSubExpr());
3984
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003985 if (const ObjCMessageExpr *Msg = dyn_cast<ObjCMessageExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003986 return /*FIXME:*/Msg->getLeftLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003987 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003988 return DRE->getLocation();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003989 if (const MemberExpr *Member = dyn_cast<MemberExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003990 return Member->getMemberLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003991 if (const ObjCIvarRefExpr *Ivar = dyn_cast<ObjCIvarRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003992 return Ivar->getLocation();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003993 if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003994 return SizeOfPack->getPackLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003995 if (const ObjCPropertyRefExpr *PropRef = dyn_cast<ObjCPropertyRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003996 return PropRef->getLocation();
3997
3998 return E->getLocStart();
3999}
4000
4001extern "C" {
4002
4003unsigned clang_visitChildren(CXCursor parent,
4004 CXCursorVisitor visitor,
4005 CXClientData client_data) {
4006 CursorVisitor CursorVis(getCursorTU(parent), visitor, client_data,
4007 /*VisitPreprocessorLast=*/false);
4008 return CursorVis.VisitChildren(parent);
4009}
4010
4011#ifndef __has_feature
4012#define __has_feature(x) 0
4013#endif
4014#if __has_feature(blocks)
4015typedef enum CXChildVisitResult
4016 (^CXCursorVisitorBlock)(CXCursor cursor, CXCursor parent);
4017
4018static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
4019 CXClientData client_data) {
4020 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
4021 return block(cursor, parent);
4022}
4023#else
4024// If we are compiled with a compiler that doesn't have native blocks support,
4025// define and call the block manually, so the
4026typedef struct _CXChildVisitResult
4027{
4028 void *isa;
4029 int flags;
4030 int reserved;
4031 enum CXChildVisitResult(*invoke)(struct _CXChildVisitResult*, CXCursor,
4032 CXCursor);
4033} *CXCursorVisitorBlock;
4034
4035static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
4036 CXClientData client_data) {
4037 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
4038 return block->invoke(block, cursor, parent);
4039}
4040#endif
4041
4042
4043unsigned clang_visitChildrenWithBlock(CXCursor parent,
4044 CXCursorVisitorBlock block) {
4045 return clang_visitChildren(parent, visitWithBlock, block);
4046}
4047
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004048static CXString getDeclSpelling(const Decl *D) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004049 if (!D)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00004050 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00004051
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004052 const NamedDecl *ND = dyn_cast<NamedDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00004053 if (!ND) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004054 if (const ObjCPropertyImplDecl *PropImpl =
4055 dyn_cast<ObjCPropertyImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004056 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004057 return cxstring::createDup(Property->getIdentifier()->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00004058
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004059 if (const ImportDecl *ImportD = dyn_cast<ImportDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004060 if (Module *Mod = ImportD->getImportedModule())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004061 return cxstring::createDup(Mod->getFullModuleName());
Guy Benyei11169dd2012-12-18 14:30:41 +00004062
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00004063 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00004064 }
4065
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004066 if (const ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(ND))
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004067 return cxstring::createDup(OMD->getSelector().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00004068
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004069 if (const ObjCCategoryImplDecl *CIMP = dyn_cast<ObjCCategoryImplDecl>(ND))
Guy Benyei11169dd2012-12-18 14:30:41 +00004070 // No, this isn't the same as the code below. getIdentifier() is non-virtual
4071 // and returns different names. NamedDecl returns the class name and
4072 // ObjCCategoryImplDecl returns the category name.
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004073 return cxstring::createRef(CIMP->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00004074
4075 if (isa<UsingDirectiveDecl>(D))
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00004076 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00004077
4078 SmallString<1024> S;
4079 llvm::raw_svector_ostream os(S);
4080 ND->printName(os);
4081
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004082 return cxstring::createDup(os.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00004083}
4084
4085CXString clang_getCursorSpelling(CXCursor C) {
4086 if (clang_isTranslationUnit(C.kind))
Dmitri Gribenko2c173b42013-01-11 19:28:44 +00004087 return clang_getTranslationUnitSpelling(getCursorTU(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00004088
4089 if (clang_isReference(C.kind)) {
4090 switch (C.kind) {
4091 case CXCursor_ObjCSuperClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004092 const ObjCInterfaceDecl *Super = getCursorObjCSuperClassRef(C).first;
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004093 return cxstring::createRef(Super->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00004094 }
4095 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004096 const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004097 return cxstring::createRef(Class->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00004098 }
4099 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004100 const ObjCProtocolDecl *OID = getCursorObjCProtocolRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00004101 assert(OID && "getCursorSpelling(): Missing protocol decl");
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004102 return cxstring::createRef(OID->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00004103 }
4104 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004105 const CXXBaseSpecifier *B = getCursorCXXBaseSpecifier(C);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004106 return cxstring::createDup(B->getType().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00004107 }
4108 case CXCursor_TypeRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004109 const TypeDecl *Type = getCursorTypeRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00004110 assert(Type && "Missing type decl");
4111
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004112 return cxstring::createDup(getCursorContext(C).getTypeDeclType(Type).
Guy Benyei11169dd2012-12-18 14:30:41 +00004113 getAsString());
4114 }
4115 case CXCursor_TemplateRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004116 const TemplateDecl *Template = getCursorTemplateRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00004117 assert(Template && "Missing template decl");
4118
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004119 return cxstring::createDup(Template->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00004120 }
4121
4122 case CXCursor_NamespaceRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004123 const NamedDecl *NS = getCursorNamespaceRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00004124 assert(NS && "Missing namespace decl");
4125
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004126 return cxstring::createDup(NS->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00004127 }
4128
4129 case CXCursor_MemberRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004130 const FieldDecl *Field = getCursorMemberRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00004131 assert(Field && "Missing member decl");
4132
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004133 return cxstring::createDup(Field->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00004134 }
4135
4136 case CXCursor_LabelRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004137 const LabelStmt *Label = getCursorLabelRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00004138 assert(Label && "Missing label");
4139
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004140 return cxstring::createRef(Label->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00004141 }
4142
4143 case CXCursor_OverloadedDeclRef: {
4144 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004145 if (const Decl *D = Storage.dyn_cast<const Decl *>()) {
4146 if (const NamedDecl *ND = dyn_cast<NamedDecl>(D))
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004147 return cxstring::createDup(ND->getNameAsString());
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00004148 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00004149 }
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004150 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004151 return cxstring::createDup(E->getName().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00004152 OverloadedTemplateStorage *Ovl
4153 = Storage.get<OverloadedTemplateStorage*>();
4154 if (Ovl->size() == 0)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00004155 return cxstring::createEmpty();
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004156 return cxstring::createDup((*Ovl->begin())->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00004157 }
4158
4159 case CXCursor_VariableRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004160 const VarDecl *Var = getCursorVariableRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00004161 assert(Var && "Missing variable decl");
4162
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004163 return cxstring::createDup(Var->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00004164 }
4165
4166 default:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004167 return cxstring::createRef("<not implemented>");
Guy Benyei11169dd2012-12-18 14:30:41 +00004168 }
4169 }
4170
4171 if (clang_isExpression(C.kind)) {
Argyrios Kyrtzidis3227d862014-03-03 19:40:52 +00004172 const Expr *E = getCursorExpr(C);
4173
4174 if (C.kind == CXCursor_ObjCStringLiteral ||
4175 C.kind == CXCursor_StringLiteral) {
4176 const StringLiteral *SLit;
4177 if (const ObjCStringLiteral *OSL = dyn_cast<ObjCStringLiteral>(E)) {
4178 SLit = OSL->getString();
4179 } else {
4180 SLit = cast<StringLiteral>(E);
4181 }
4182 SmallString<256> Buf;
4183 llvm::raw_svector_ostream OS(Buf);
4184 SLit->outputString(OS);
4185 return cxstring::createDup(OS.str());
4186 }
4187
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004188 const Decl *D = getDeclFromExpr(getCursorExpr(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00004189 if (D)
4190 return getDeclSpelling(D);
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00004191 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00004192 }
4193
4194 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004195 const Stmt *S = getCursorStmt(C);
4196 if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S))
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004197 return cxstring::createRef(Label->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00004198
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00004199 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00004200 }
4201
4202 if (C.kind == CXCursor_MacroExpansion)
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004203 return cxstring::createRef(getCursorMacroExpansion(C).getName()
Guy Benyei11169dd2012-12-18 14:30:41 +00004204 ->getNameStart());
4205
4206 if (C.kind == CXCursor_MacroDefinition)
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004207 return cxstring::createRef(getCursorMacroDefinition(C)->getName()
Guy Benyei11169dd2012-12-18 14:30:41 +00004208 ->getNameStart());
4209
4210 if (C.kind == CXCursor_InclusionDirective)
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004211 return cxstring::createDup(getCursorInclusionDirective(C)->getFileName());
Guy Benyei11169dd2012-12-18 14:30:41 +00004212
4213 if (clang_isDeclaration(C.kind))
4214 return getDeclSpelling(getCursorDecl(C));
4215
4216 if (C.kind == CXCursor_AnnotateAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00004217 const AnnotateAttr *AA = cast<AnnotateAttr>(cxcursor::getCursorAttr(C));
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004218 return cxstring::createDup(AA->getAnnotation());
Guy Benyei11169dd2012-12-18 14:30:41 +00004219 }
4220
4221 if (C.kind == CXCursor_AsmLabelAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00004222 const AsmLabelAttr *AA = cast<AsmLabelAttr>(cxcursor::getCursorAttr(C));
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004223 return cxstring::createDup(AA->getLabel());
Guy Benyei11169dd2012-12-18 14:30:41 +00004224 }
4225
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00004226 if (C.kind == CXCursor_PackedAttr) {
4227 return cxstring::createRef("packed");
4228 }
4229
Saleem Abdulrasool79c69712015-09-05 18:53:43 +00004230 if (C.kind == CXCursor_VisibilityAttr) {
4231 const VisibilityAttr *AA = cast<VisibilityAttr>(cxcursor::getCursorAttr(C));
4232 switch (AA->getVisibility()) {
4233 case VisibilityAttr::VisibilityType::Default:
4234 return cxstring::createRef("default");
4235 case VisibilityAttr::VisibilityType::Hidden:
4236 return cxstring::createRef("hidden");
4237 case VisibilityAttr::VisibilityType::Protected:
4238 return cxstring::createRef("protected");
4239 }
4240 llvm_unreachable("unknown visibility type");
4241 }
4242
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00004243 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00004244}
4245
4246CXSourceRange clang_Cursor_getSpellingNameRange(CXCursor C,
4247 unsigned pieceIndex,
4248 unsigned options) {
4249 if (clang_Cursor_isNull(C))
4250 return clang_getNullRange();
4251
4252 ASTContext &Ctx = getCursorContext(C);
4253
4254 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004255 const Stmt *S = getCursorStmt(C);
4256 if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004257 if (pieceIndex > 0)
4258 return clang_getNullRange();
4259 return cxloc::translateSourceRange(Ctx, Label->getIdentLoc());
4260 }
4261
4262 return clang_getNullRange();
4263 }
4264
4265 if (C.kind == CXCursor_ObjCMessageExpr) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004266 if (const ObjCMessageExpr *
Guy Benyei11169dd2012-12-18 14:30:41 +00004267 ME = dyn_cast_or_null<ObjCMessageExpr>(getCursorExpr(C))) {
4268 if (pieceIndex >= ME->getNumSelectorLocs())
4269 return clang_getNullRange();
4270 return cxloc::translateSourceRange(Ctx, ME->getSelectorLoc(pieceIndex));
4271 }
4272 }
4273
4274 if (C.kind == CXCursor_ObjCInstanceMethodDecl ||
4275 C.kind == CXCursor_ObjCClassMethodDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004276 if (const ObjCMethodDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00004277 MD = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(C))) {
4278 if (pieceIndex >= MD->getNumSelectorLocs())
4279 return clang_getNullRange();
4280 return cxloc::translateSourceRange(Ctx, MD->getSelectorLoc(pieceIndex));
4281 }
4282 }
4283
4284 if (C.kind == CXCursor_ObjCCategoryDecl ||
4285 C.kind == CXCursor_ObjCCategoryImplDecl) {
4286 if (pieceIndex > 0)
4287 return clang_getNullRange();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004288 if (const ObjCCategoryDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00004289 CD = dyn_cast_or_null<ObjCCategoryDecl>(getCursorDecl(C)))
4290 return cxloc::translateSourceRange(Ctx, CD->getCategoryNameLoc());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004291 if (const ObjCCategoryImplDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00004292 CID = dyn_cast_or_null<ObjCCategoryImplDecl>(getCursorDecl(C)))
4293 return cxloc::translateSourceRange(Ctx, CID->getCategoryNameLoc());
4294 }
4295
4296 if (C.kind == CXCursor_ModuleImportDecl) {
4297 if (pieceIndex > 0)
4298 return clang_getNullRange();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004299 if (const ImportDecl *ImportD =
4300 dyn_cast_or_null<ImportDecl>(getCursorDecl(C))) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004301 ArrayRef<SourceLocation> Locs = ImportD->getIdentifierLocs();
4302 if (!Locs.empty())
4303 return cxloc::translateSourceRange(Ctx,
4304 SourceRange(Locs.front(), Locs.back()));
4305 }
4306 return clang_getNullRange();
4307 }
4308
Argyrios Kyrtzidisa2a1e532014-08-26 20:23:26 +00004309 if (C.kind == CXCursor_CXXMethod || C.kind == CXCursor_Destructor ||
4310 C.kind == CXCursor_ConversionFunction) {
4311 if (pieceIndex > 0)
4312 return clang_getNullRange();
4313 if (const FunctionDecl *FD =
4314 dyn_cast_or_null<FunctionDecl>(getCursorDecl(C))) {
4315 DeclarationNameInfo FunctionName = FD->getNameInfo();
4316 return cxloc::translateSourceRange(Ctx, FunctionName.getSourceRange());
4317 }
4318 return clang_getNullRange();
4319 }
4320
Guy Benyei11169dd2012-12-18 14:30:41 +00004321 // FIXME: A CXCursor_InclusionDirective should give the location of the
4322 // filename, but we don't keep track of this.
4323
4324 // FIXME: A CXCursor_AnnotateAttr should give the location of the annotation
4325 // but we don't keep track of this.
4326
4327 // FIXME: A CXCursor_AsmLabelAttr should give the location of the label
4328 // but we don't keep track of this.
4329
4330 // Default handling, give the location of the cursor.
4331
4332 if (pieceIndex > 0)
4333 return clang_getNullRange();
4334
4335 CXSourceLocation CXLoc = clang_getCursorLocation(C);
4336 SourceLocation Loc = cxloc::translateSourceLocation(CXLoc);
4337 return cxloc::translateSourceRange(Ctx, Loc);
4338}
4339
Eli Bendersky44a206f2014-07-31 18:04:56 +00004340CXString clang_Cursor_getMangling(CXCursor C) {
4341 if (clang_isInvalid(C.kind) || !clang_isDeclaration(C.kind))
4342 return cxstring::createEmpty();
4343
Eli Bendersky44a206f2014-07-31 18:04:56 +00004344 // Mangling only works for functions and variables.
Eli Bendersky79759592014-08-01 15:01:10 +00004345 const Decl *D = getCursorDecl(C);
Eli Bendersky44a206f2014-07-31 18:04:56 +00004346 if (!D || !(isa<FunctionDecl>(D) || isa<VarDecl>(D)))
4347 return cxstring::createEmpty();
4348
Argyrios Kyrtzidisca741ce2016-02-14 22:30:14 +00004349 ASTContext &Ctx = D->getASTContext();
4350 index::CodegenNameGenerator CGNameGen(Ctx);
4351 return cxstring::createDup(CGNameGen.getName(D));
Eli Bendersky44a206f2014-07-31 18:04:56 +00004352}
4353
Saleem Abdulrasool60034432015-11-12 03:57:22 +00004354CXStringSet *clang_Cursor_getCXXManglings(CXCursor C) {
4355 if (clang_isInvalid(C.kind) || !clang_isDeclaration(C.kind))
4356 return nullptr;
4357
4358 const Decl *D = getCursorDecl(C);
4359 if (!(isa<CXXRecordDecl>(D) || isa<CXXMethodDecl>(D)))
4360 return nullptr;
4361
Argyrios Kyrtzidisca741ce2016-02-14 22:30:14 +00004362 ASTContext &Ctx = D->getASTContext();
4363 index::CodegenNameGenerator CGNameGen(Ctx);
4364 std::vector<std::string> Manglings = CGNameGen.getAllManglings(D);
Saleem Abdulrasool60034432015-11-12 03:57:22 +00004365 return cxstring::createSet(Manglings);
4366}
4367
Guy Benyei11169dd2012-12-18 14:30:41 +00004368CXString clang_getCursorDisplayName(CXCursor C) {
4369 if (!clang_isDeclaration(C.kind))
4370 return clang_getCursorSpelling(C);
4371
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004372 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004373 if (!D)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00004374 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00004375
4376 PrintingPolicy Policy = getCursorContext(C).getPrintingPolicy();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004377 if (const FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004378 D = FunTmpl->getTemplatedDecl();
4379
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004380 if (const FunctionDecl *Function = dyn_cast<FunctionDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004381 SmallString<64> Str;
4382 llvm::raw_svector_ostream OS(Str);
4383 OS << *Function;
4384 if (Function->getPrimaryTemplate())
4385 OS << "<>";
4386 OS << "(";
4387 for (unsigned I = 0, N = Function->getNumParams(); I != N; ++I) {
4388 if (I)
4389 OS << ", ";
4390 OS << Function->getParamDecl(I)->getType().getAsString(Policy);
4391 }
4392
4393 if (Function->isVariadic()) {
4394 if (Function->getNumParams())
4395 OS << ", ";
4396 OS << "...";
4397 }
4398 OS << ")";
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004399 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00004400 }
4401
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004402 if (const ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004403 SmallString<64> Str;
4404 llvm::raw_svector_ostream OS(Str);
4405 OS << *ClassTemplate;
4406 OS << "<";
4407 TemplateParameterList *Params = ClassTemplate->getTemplateParameters();
4408 for (unsigned I = 0, N = Params->size(); I != N; ++I) {
4409 if (I)
4410 OS << ", ";
4411
4412 NamedDecl *Param = Params->getParam(I);
4413 if (Param->getIdentifier()) {
4414 OS << Param->getIdentifier()->getName();
4415 continue;
4416 }
4417
4418 // There is no parameter name, which makes this tricky. Try to come up
4419 // with something useful that isn't too long.
4420 if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(Param))
4421 OS << (TTP->wasDeclaredWithTypename()? "typename" : "class");
4422 else if (NonTypeTemplateParmDecl *NTTP
4423 = dyn_cast<NonTypeTemplateParmDecl>(Param))
4424 OS << NTTP->getType().getAsString(Policy);
4425 else
4426 OS << "template<...> class";
4427 }
4428
4429 OS << ">";
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004430 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00004431 }
4432
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004433 if (const ClassTemplateSpecializationDecl *ClassSpec
Guy Benyei11169dd2012-12-18 14:30:41 +00004434 = dyn_cast<ClassTemplateSpecializationDecl>(D)) {
4435 // If the type was explicitly written, use that.
4436 if (TypeSourceInfo *TSInfo = ClassSpec->getTypeAsWritten())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004437 return cxstring::createDup(TSInfo->getType().getAsString(Policy));
Guy Benyei11169dd2012-12-18 14:30:41 +00004438
Benjamin Kramer9170e912013-02-22 15:46:01 +00004439 SmallString<128> Str;
Guy Benyei11169dd2012-12-18 14:30:41 +00004440 llvm::raw_svector_ostream OS(Str);
4441 OS << *ClassSpec;
Benjamin Kramer9170e912013-02-22 15:46:01 +00004442 TemplateSpecializationType::PrintTemplateArgumentList(OS,
Guy Benyei11169dd2012-12-18 14:30:41 +00004443 ClassSpec->getTemplateArgs().data(),
4444 ClassSpec->getTemplateArgs().size(),
4445 Policy);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004446 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00004447 }
4448
4449 return clang_getCursorSpelling(C);
4450}
4451
4452CXString clang_getCursorKindSpelling(enum CXCursorKind Kind) {
4453 switch (Kind) {
4454 case CXCursor_FunctionDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004455 return cxstring::createRef("FunctionDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004456 case CXCursor_TypedefDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004457 return cxstring::createRef("TypedefDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004458 case CXCursor_EnumDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004459 return cxstring::createRef("EnumDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004460 case CXCursor_EnumConstantDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004461 return cxstring::createRef("EnumConstantDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004462 case CXCursor_StructDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004463 return cxstring::createRef("StructDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004464 case CXCursor_UnionDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004465 return cxstring::createRef("UnionDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004466 case CXCursor_ClassDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004467 return cxstring::createRef("ClassDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004468 case CXCursor_FieldDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004469 return cxstring::createRef("FieldDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004470 case CXCursor_VarDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004471 return cxstring::createRef("VarDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004472 case CXCursor_ParmDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004473 return cxstring::createRef("ParmDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004474 case CXCursor_ObjCInterfaceDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004475 return cxstring::createRef("ObjCInterfaceDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004476 case CXCursor_ObjCCategoryDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004477 return cxstring::createRef("ObjCCategoryDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004478 case CXCursor_ObjCProtocolDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004479 return cxstring::createRef("ObjCProtocolDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004480 case CXCursor_ObjCPropertyDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004481 return cxstring::createRef("ObjCPropertyDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004482 case CXCursor_ObjCIvarDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004483 return cxstring::createRef("ObjCIvarDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004484 case CXCursor_ObjCInstanceMethodDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004485 return cxstring::createRef("ObjCInstanceMethodDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004486 case CXCursor_ObjCClassMethodDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004487 return cxstring::createRef("ObjCClassMethodDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004488 case CXCursor_ObjCImplementationDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004489 return cxstring::createRef("ObjCImplementationDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004490 case CXCursor_ObjCCategoryImplDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004491 return cxstring::createRef("ObjCCategoryImplDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004492 case CXCursor_CXXMethod:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004493 return cxstring::createRef("CXXMethod");
Guy Benyei11169dd2012-12-18 14:30:41 +00004494 case CXCursor_UnexposedDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004495 return cxstring::createRef("UnexposedDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004496 case CXCursor_ObjCSuperClassRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004497 return cxstring::createRef("ObjCSuperClassRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004498 case CXCursor_ObjCProtocolRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004499 return cxstring::createRef("ObjCProtocolRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004500 case CXCursor_ObjCClassRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004501 return cxstring::createRef("ObjCClassRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004502 case CXCursor_TypeRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004503 return cxstring::createRef("TypeRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004504 case CXCursor_TemplateRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004505 return cxstring::createRef("TemplateRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004506 case CXCursor_NamespaceRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004507 return cxstring::createRef("NamespaceRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004508 case CXCursor_MemberRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004509 return cxstring::createRef("MemberRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004510 case CXCursor_LabelRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004511 return cxstring::createRef("LabelRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004512 case CXCursor_OverloadedDeclRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004513 return cxstring::createRef("OverloadedDeclRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004514 case CXCursor_VariableRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004515 return cxstring::createRef("VariableRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004516 case CXCursor_IntegerLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004517 return cxstring::createRef("IntegerLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00004518 case CXCursor_FloatingLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004519 return cxstring::createRef("FloatingLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00004520 case CXCursor_ImaginaryLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004521 return cxstring::createRef("ImaginaryLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00004522 case CXCursor_StringLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004523 return cxstring::createRef("StringLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00004524 case CXCursor_CharacterLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004525 return cxstring::createRef("CharacterLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00004526 case CXCursor_ParenExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004527 return cxstring::createRef("ParenExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004528 case CXCursor_UnaryOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004529 return cxstring::createRef("UnaryOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00004530 case CXCursor_ArraySubscriptExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004531 return cxstring::createRef("ArraySubscriptExpr");
Alexey Bataev1a3320e2015-08-25 14:24:04 +00004532 case CXCursor_OMPArraySectionExpr:
4533 return cxstring::createRef("OMPArraySectionExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004534 case CXCursor_BinaryOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004535 return cxstring::createRef("BinaryOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00004536 case CXCursor_CompoundAssignOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004537 return cxstring::createRef("CompoundAssignOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00004538 case CXCursor_ConditionalOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004539 return cxstring::createRef("ConditionalOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00004540 case CXCursor_CStyleCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004541 return cxstring::createRef("CStyleCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004542 case CXCursor_CompoundLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004543 return cxstring::createRef("CompoundLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004544 case CXCursor_InitListExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004545 return cxstring::createRef("InitListExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004546 case CXCursor_AddrLabelExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004547 return cxstring::createRef("AddrLabelExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004548 case CXCursor_StmtExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004549 return cxstring::createRef("StmtExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004550 case CXCursor_GenericSelectionExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004551 return cxstring::createRef("GenericSelectionExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004552 case CXCursor_GNUNullExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004553 return cxstring::createRef("GNUNullExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004554 case CXCursor_CXXStaticCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004555 return cxstring::createRef("CXXStaticCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004556 case CXCursor_CXXDynamicCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004557 return cxstring::createRef("CXXDynamicCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004558 case CXCursor_CXXReinterpretCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004559 return cxstring::createRef("CXXReinterpretCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004560 case CXCursor_CXXConstCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004561 return cxstring::createRef("CXXConstCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004562 case CXCursor_CXXFunctionalCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004563 return cxstring::createRef("CXXFunctionalCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004564 case CXCursor_CXXTypeidExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004565 return cxstring::createRef("CXXTypeidExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004566 case CXCursor_CXXBoolLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004567 return cxstring::createRef("CXXBoolLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004568 case CXCursor_CXXNullPtrLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004569 return cxstring::createRef("CXXNullPtrLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004570 case CXCursor_CXXThisExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004571 return cxstring::createRef("CXXThisExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004572 case CXCursor_CXXThrowExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004573 return cxstring::createRef("CXXThrowExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004574 case CXCursor_CXXNewExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004575 return cxstring::createRef("CXXNewExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004576 case CXCursor_CXXDeleteExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004577 return cxstring::createRef("CXXDeleteExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004578 case CXCursor_UnaryExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004579 return cxstring::createRef("UnaryExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004580 case CXCursor_ObjCStringLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004581 return cxstring::createRef("ObjCStringLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00004582 case CXCursor_ObjCBoolLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004583 return cxstring::createRef("ObjCBoolLiteralExpr");
Argyrios Kyrtzidisc2233be2013-04-23 17:57:17 +00004584 case CXCursor_ObjCSelfExpr:
4585 return cxstring::createRef("ObjCSelfExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004586 case CXCursor_ObjCEncodeExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004587 return cxstring::createRef("ObjCEncodeExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004588 case CXCursor_ObjCSelectorExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004589 return cxstring::createRef("ObjCSelectorExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004590 case CXCursor_ObjCProtocolExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004591 return cxstring::createRef("ObjCProtocolExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004592 case CXCursor_ObjCBridgedCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004593 return cxstring::createRef("ObjCBridgedCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004594 case CXCursor_BlockExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004595 return cxstring::createRef("BlockExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004596 case CXCursor_PackExpansionExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004597 return cxstring::createRef("PackExpansionExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004598 case CXCursor_SizeOfPackExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004599 return cxstring::createRef("SizeOfPackExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004600 case CXCursor_LambdaExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004601 return cxstring::createRef("LambdaExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004602 case CXCursor_UnexposedExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004603 return cxstring::createRef("UnexposedExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004604 case CXCursor_DeclRefExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004605 return cxstring::createRef("DeclRefExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004606 case CXCursor_MemberRefExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004607 return cxstring::createRef("MemberRefExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004608 case CXCursor_CallExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004609 return cxstring::createRef("CallExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004610 case CXCursor_ObjCMessageExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004611 return cxstring::createRef("ObjCMessageExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004612 case CXCursor_UnexposedStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004613 return cxstring::createRef("UnexposedStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004614 case CXCursor_DeclStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004615 return cxstring::createRef("DeclStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004616 case CXCursor_LabelStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004617 return cxstring::createRef("LabelStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004618 case CXCursor_CompoundStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004619 return cxstring::createRef("CompoundStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004620 case CXCursor_CaseStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004621 return cxstring::createRef("CaseStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004622 case CXCursor_DefaultStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004623 return cxstring::createRef("DefaultStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004624 case CXCursor_IfStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004625 return cxstring::createRef("IfStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004626 case CXCursor_SwitchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004627 return cxstring::createRef("SwitchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004628 case CXCursor_WhileStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004629 return cxstring::createRef("WhileStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004630 case CXCursor_DoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004631 return cxstring::createRef("DoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004632 case CXCursor_ForStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004633 return cxstring::createRef("ForStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004634 case CXCursor_GotoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004635 return cxstring::createRef("GotoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004636 case CXCursor_IndirectGotoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004637 return cxstring::createRef("IndirectGotoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004638 case CXCursor_ContinueStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004639 return cxstring::createRef("ContinueStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004640 case CXCursor_BreakStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004641 return cxstring::createRef("BreakStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004642 case CXCursor_ReturnStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004643 return cxstring::createRef("ReturnStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004644 case CXCursor_GCCAsmStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004645 return cxstring::createRef("GCCAsmStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004646 case CXCursor_MSAsmStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004647 return cxstring::createRef("MSAsmStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004648 case CXCursor_ObjCAtTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004649 return cxstring::createRef("ObjCAtTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004650 case CXCursor_ObjCAtCatchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004651 return cxstring::createRef("ObjCAtCatchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004652 case CXCursor_ObjCAtFinallyStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004653 return cxstring::createRef("ObjCAtFinallyStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004654 case CXCursor_ObjCAtThrowStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004655 return cxstring::createRef("ObjCAtThrowStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004656 case CXCursor_ObjCAtSynchronizedStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004657 return cxstring::createRef("ObjCAtSynchronizedStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004658 case CXCursor_ObjCAutoreleasePoolStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004659 return cxstring::createRef("ObjCAutoreleasePoolStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004660 case CXCursor_ObjCForCollectionStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004661 return cxstring::createRef("ObjCForCollectionStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004662 case CXCursor_CXXCatchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004663 return cxstring::createRef("CXXCatchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004664 case CXCursor_CXXTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004665 return cxstring::createRef("CXXTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004666 case CXCursor_CXXForRangeStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004667 return cxstring::createRef("CXXForRangeStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004668 case CXCursor_SEHTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004669 return cxstring::createRef("SEHTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004670 case CXCursor_SEHExceptStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004671 return cxstring::createRef("SEHExceptStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004672 case CXCursor_SEHFinallyStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004673 return cxstring::createRef("SEHFinallyStmt");
Nico Weber9b982072014-07-07 00:12:30 +00004674 case CXCursor_SEHLeaveStmt:
4675 return cxstring::createRef("SEHLeaveStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004676 case CXCursor_NullStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004677 return cxstring::createRef("NullStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004678 case CXCursor_InvalidFile:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004679 return cxstring::createRef("InvalidFile");
Guy Benyei11169dd2012-12-18 14:30:41 +00004680 case CXCursor_InvalidCode:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004681 return cxstring::createRef("InvalidCode");
Guy Benyei11169dd2012-12-18 14:30:41 +00004682 case CXCursor_NoDeclFound:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004683 return cxstring::createRef("NoDeclFound");
Guy Benyei11169dd2012-12-18 14:30:41 +00004684 case CXCursor_NotImplemented:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004685 return cxstring::createRef("NotImplemented");
Guy Benyei11169dd2012-12-18 14:30:41 +00004686 case CXCursor_TranslationUnit:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004687 return cxstring::createRef("TranslationUnit");
Guy Benyei11169dd2012-12-18 14:30:41 +00004688 case CXCursor_UnexposedAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004689 return cxstring::createRef("UnexposedAttr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004690 case CXCursor_IBActionAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004691 return cxstring::createRef("attribute(ibaction)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004692 case CXCursor_IBOutletAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004693 return cxstring::createRef("attribute(iboutlet)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004694 case CXCursor_IBOutletCollectionAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004695 return cxstring::createRef("attribute(iboutletcollection)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004696 case CXCursor_CXXFinalAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004697 return cxstring::createRef("attribute(final)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004698 case CXCursor_CXXOverrideAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004699 return cxstring::createRef("attribute(override)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004700 case CXCursor_AnnotateAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004701 return cxstring::createRef("attribute(annotate)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004702 case CXCursor_AsmLabelAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004703 return cxstring::createRef("asm label");
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00004704 case CXCursor_PackedAttr:
4705 return cxstring::createRef("attribute(packed)");
Joey Gouly81228382014-05-01 15:41:58 +00004706 case CXCursor_PureAttr:
4707 return cxstring::createRef("attribute(pure)");
4708 case CXCursor_ConstAttr:
4709 return cxstring::createRef("attribute(const)");
4710 case CXCursor_NoDuplicateAttr:
4711 return cxstring::createRef("attribute(noduplicate)");
Eli Bendersky2581e662014-05-28 19:29:58 +00004712 case CXCursor_CUDAConstantAttr:
4713 return cxstring::createRef("attribute(constant)");
4714 case CXCursor_CUDADeviceAttr:
4715 return cxstring::createRef("attribute(device)");
4716 case CXCursor_CUDAGlobalAttr:
4717 return cxstring::createRef("attribute(global)");
4718 case CXCursor_CUDAHostAttr:
4719 return cxstring::createRef("attribute(host)");
Eli Bendersky9b071472014-08-08 14:59:00 +00004720 case CXCursor_CUDASharedAttr:
4721 return cxstring::createRef("attribute(shared)");
Saleem Abdulrasool79c69712015-09-05 18:53:43 +00004722 case CXCursor_VisibilityAttr:
4723 return cxstring::createRef("attribute(visibility)");
Saleem Abdulrasool8aa0b802015-12-10 18:45:18 +00004724 case CXCursor_DLLExport:
4725 return cxstring::createRef("attribute(dllexport)");
4726 case CXCursor_DLLImport:
4727 return cxstring::createRef("attribute(dllimport)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004728 case CXCursor_PreprocessingDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004729 return cxstring::createRef("preprocessing directive");
Guy Benyei11169dd2012-12-18 14:30:41 +00004730 case CXCursor_MacroDefinition:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004731 return cxstring::createRef("macro definition");
Guy Benyei11169dd2012-12-18 14:30:41 +00004732 case CXCursor_MacroExpansion:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004733 return cxstring::createRef("macro expansion");
Guy Benyei11169dd2012-12-18 14:30:41 +00004734 case CXCursor_InclusionDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004735 return cxstring::createRef("inclusion directive");
Guy Benyei11169dd2012-12-18 14:30:41 +00004736 case CXCursor_Namespace:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004737 return cxstring::createRef("Namespace");
Guy Benyei11169dd2012-12-18 14:30:41 +00004738 case CXCursor_LinkageSpec:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004739 return cxstring::createRef("LinkageSpec");
Guy Benyei11169dd2012-12-18 14:30:41 +00004740 case CXCursor_CXXBaseSpecifier:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004741 return cxstring::createRef("C++ base class specifier");
Guy Benyei11169dd2012-12-18 14:30:41 +00004742 case CXCursor_Constructor:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004743 return cxstring::createRef("CXXConstructor");
Guy Benyei11169dd2012-12-18 14:30:41 +00004744 case CXCursor_Destructor:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004745 return cxstring::createRef("CXXDestructor");
Guy Benyei11169dd2012-12-18 14:30:41 +00004746 case CXCursor_ConversionFunction:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004747 return cxstring::createRef("CXXConversion");
Guy Benyei11169dd2012-12-18 14:30:41 +00004748 case CXCursor_TemplateTypeParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004749 return cxstring::createRef("TemplateTypeParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00004750 case CXCursor_NonTypeTemplateParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004751 return cxstring::createRef("NonTypeTemplateParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00004752 case CXCursor_TemplateTemplateParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004753 return cxstring::createRef("TemplateTemplateParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00004754 case CXCursor_FunctionTemplate:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004755 return cxstring::createRef("FunctionTemplate");
Guy Benyei11169dd2012-12-18 14:30:41 +00004756 case CXCursor_ClassTemplate:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004757 return cxstring::createRef("ClassTemplate");
Guy Benyei11169dd2012-12-18 14:30:41 +00004758 case CXCursor_ClassTemplatePartialSpecialization:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004759 return cxstring::createRef("ClassTemplatePartialSpecialization");
Guy Benyei11169dd2012-12-18 14:30:41 +00004760 case CXCursor_NamespaceAlias:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004761 return cxstring::createRef("NamespaceAlias");
Guy Benyei11169dd2012-12-18 14:30:41 +00004762 case CXCursor_UsingDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004763 return cxstring::createRef("UsingDirective");
Guy Benyei11169dd2012-12-18 14:30:41 +00004764 case CXCursor_UsingDeclaration:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004765 return cxstring::createRef("UsingDeclaration");
Guy Benyei11169dd2012-12-18 14:30:41 +00004766 case CXCursor_TypeAliasDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004767 return cxstring::createRef("TypeAliasDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004768 case CXCursor_ObjCSynthesizeDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004769 return cxstring::createRef("ObjCSynthesizeDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004770 case CXCursor_ObjCDynamicDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004771 return cxstring::createRef("ObjCDynamicDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004772 case CXCursor_CXXAccessSpecifier:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004773 return cxstring::createRef("CXXAccessSpecifier");
Guy Benyei11169dd2012-12-18 14:30:41 +00004774 case CXCursor_ModuleImportDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004775 return cxstring::createRef("ModuleImport");
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00004776 case CXCursor_OMPParallelDirective:
Alexey Bataev1b59ab52014-02-27 08:29:12 +00004777 return cxstring::createRef("OMPParallelDirective");
4778 case CXCursor_OMPSimdDirective:
4779 return cxstring::createRef("OMPSimdDirective");
Alexey Bataevf29276e2014-06-18 04:14:57 +00004780 case CXCursor_OMPForDirective:
4781 return cxstring::createRef("OMPForDirective");
Alexander Musmanf82886e2014-09-18 05:12:34 +00004782 case CXCursor_OMPForSimdDirective:
4783 return cxstring::createRef("OMPForSimdDirective");
Alexey Bataevd3f8dd22014-06-25 11:44:49 +00004784 case CXCursor_OMPSectionsDirective:
4785 return cxstring::createRef("OMPSectionsDirective");
Alexey Bataev1e0498a2014-06-26 08:21:58 +00004786 case CXCursor_OMPSectionDirective:
4787 return cxstring::createRef("OMPSectionDirective");
Alexey Bataevd1e40fb2014-06-26 12:05:45 +00004788 case CXCursor_OMPSingleDirective:
4789 return cxstring::createRef("OMPSingleDirective");
Alexander Musman80c22892014-07-17 08:54:58 +00004790 case CXCursor_OMPMasterDirective:
4791 return cxstring::createRef("OMPMasterDirective");
Alexander Musmand9ed09f2014-07-21 09:42:05 +00004792 case CXCursor_OMPCriticalDirective:
4793 return cxstring::createRef("OMPCriticalDirective");
Alexey Bataev4acb8592014-07-07 13:01:15 +00004794 case CXCursor_OMPParallelForDirective:
4795 return cxstring::createRef("OMPParallelForDirective");
Alexander Musmane4e893b2014-09-23 09:33:00 +00004796 case CXCursor_OMPParallelForSimdDirective:
4797 return cxstring::createRef("OMPParallelForSimdDirective");
Alexey Bataev84d0b3e2014-07-08 08:12:03 +00004798 case CXCursor_OMPParallelSectionsDirective:
4799 return cxstring::createRef("OMPParallelSectionsDirective");
Alexey Bataev9c2e8ee2014-07-11 11:25:16 +00004800 case CXCursor_OMPTaskDirective:
4801 return cxstring::createRef("OMPTaskDirective");
Alexey Bataev68446b72014-07-18 07:47:19 +00004802 case CXCursor_OMPTaskyieldDirective:
4803 return cxstring::createRef("OMPTaskyieldDirective");
Alexey Bataev4d1dfea2014-07-18 09:11:51 +00004804 case CXCursor_OMPBarrierDirective:
4805 return cxstring::createRef("OMPBarrierDirective");
Alexey Bataev2df347a2014-07-18 10:17:07 +00004806 case CXCursor_OMPTaskwaitDirective:
4807 return cxstring::createRef("OMPTaskwaitDirective");
Alexey Bataevc30dd2d2015-06-18 12:14:09 +00004808 case CXCursor_OMPTaskgroupDirective:
4809 return cxstring::createRef("OMPTaskgroupDirective");
Alexey Bataev6125da92014-07-21 11:26:11 +00004810 case CXCursor_OMPFlushDirective:
4811 return cxstring::createRef("OMPFlushDirective");
Alexey Bataev9fb6e642014-07-22 06:45:04 +00004812 case CXCursor_OMPOrderedDirective:
4813 return cxstring::createRef("OMPOrderedDirective");
Alexey Bataev0162e452014-07-22 10:10:35 +00004814 case CXCursor_OMPAtomicDirective:
4815 return cxstring::createRef("OMPAtomicDirective");
Alexey Bataev0bd520b2014-09-19 08:19:49 +00004816 case CXCursor_OMPTargetDirective:
4817 return cxstring::createRef("OMPTargetDirective");
Michael Wong65f367f2015-07-21 13:44:28 +00004818 case CXCursor_OMPTargetDataDirective:
4819 return cxstring::createRef("OMPTargetDataDirective");
Samuel Antaodf67fc42016-01-19 19:15:56 +00004820 case CXCursor_OMPTargetEnterDataDirective:
4821 return cxstring::createRef("OMPTargetEnterDataDirective");
Samuel Antao72590762016-01-19 20:04:50 +00004822 case CXCursor_OMPTargetExitDataDirective:
4823 return cxstring::createRef("OMPTargetExitDataDirective");
Arpith Chacko Jacobe955b3d2016-01-26 18:48:41 +00004824 case CXCursor_OMPTargetParallelDirective:
4825 return cxstring::createRef("OMPTargetParallelDirective");
Arpith Chacko Jacob05bebb52016-02-03 15:46:42 +00004826 case CXCursor_OMPTargetParallelForDirective:
4827 return cxstring::createRef("OMPTargetParallelForDirective");
Alexey Bataev13314bf2014-10-09 04:18:56 +00004828 case CXCursor_OMPTeamsDirective:
4829 return cxstring::createRef("OMPTeamsDirective");
Alexey Bataev6d4ed052015-07-01 06:57:41 +00004830 case CXCursor_OMPCancellationPointDirective:
4831 return cxstring::createRef("OMPCancellationPointDirective");
Alexey Bataev80909872015-07-02 11:25:17 +00004832 case CXCursor_OMPCancelDirective:
4833 return cxstring::createRef("OMPCancelDirective");
Alexey Bataev49f6e782015-12-01 04:18:41 +00004834 case CXCursor_OMPTaskLoopDirective:
4835 return cxstring::createRef("OMPTaskLoopDirective");
Alexey Bataev0a6ed842015-12-03 09:40:15 +00004836 case CXCursor_OMPTaskLoopSimdDirective:
4837 return cxstring::createRef("OMPTaskLoopSimdDirective");
Carlo Bertolli6200a3d2015-12-14 14:51:25 +00004838 case CXCursor_OMPDistributeDirective:
4839 return cxstring::createRef("OMPDistributeDirective");
Francisco Lopes da Silva975a9f62015-01-21 16:24:11 +00004840 case CXCursor_OverloadCandidate:
4841 return cxstring::createRef("OverloadCandidate");
Sergey Kalinichev8f3b1872015-11-15 13:48:32 +00004842 case CXCursor_TypeAliasTemplateDecl:
4843 return cxstring::createRef("TypeAliasTemplateDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004844 }
4845
4846 llvm_unreachable("Unhandled CXCursorKind");
4847}
4848
4849struct GetCursorData {
4850 SourceLocation TokenBeginLoc;
4851 bool PointsAtMacroArgExpansion;
4852 bool VisitedObjCPropertyImplDecl;
4853 SourceLocation VisitedDeclaratorDeclStartLoc;
4854 CXCursor &BestCursor;
4855
4856 GetCursorData(SourceManager &SM,
4857 SourceLocation tokenBegin, CXCursor &outputCursor)
4858 : TokenBeginLoc(tokenBegin), BestCursor(outputCursor) {
4859 PointsAtMacroArgExpansion = SM.isMacroArgExpansion(tokenBegin);
4860 VisitedObjCPropertyImplDecl = false;
4861 }
4862};
4863
4864static enum CXChildVisitResult GetCursorVisitor(CXCursor cursor,
4865 CXCursor parent,
4866 CXClientData client_data) {
4867 GetCursorData *Data = static_cast<GetCursorData *>(client_data);
4868 CXCursor *BestCursor = &Data->BestCursor;
4869
4870 // If we point inside a macro argument we should provide info of what the
4871 // token is so use the actual cursor, don't replace it with a macro expansion
4872 // cursor.
4873 if (cursor.kind == CXCursor_MacroExpansion && Data->PointsAtMacroArgExpansion)
4874 return CXChildVisit_Recurse;
4875
4876 if (clang_isDeclaration(cursor.kind)) {
4877 // Avoid having the implicit methods override the property decls.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004878 if (const ObjCMethodDecl *MD
Guy Benyei11169dd2012-12-18 14:30:41 +00004879 = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
4880 if (MD->isImplicit())
4881 return CXChildVisit_Break;
4882
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004883 } else if (const ObjCInterfaceDecl *ID
Guy Benyei11169dd2012-12-18 14:30:41 +00004884 = dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(cursor))) {
4885 // Check that when we have multiple @class references in the same line,
4886 // that later ones do not override the previous ones.
4887 // If we have:
4888 // @class Foo, Bar;
4889 // source ranges for both start at '@', so 'Bar' will end up overriding
4890 // 'Foo' even though the cursor location was at 'Foo'.
4891 if (BestCursor->kind == CXCursor_ObjCInterfaceDecl ||
4892 BestCursor->kind == CXCursor_ObjCClassRef)
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004893 if (const ObjCInterfaceDecl *PrevID
Guy Benyei11169dd2012-12-18 14:30:41 +00004894 = dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(*BestCursor))){
4895 if (PrevID != ID &&
4896 !PrevID->isThisDeclarationADefinition() &&
4897 !ID->isThisDeclarationADefinition())
4898 return CXChildVisit_Break;
4899 }
4900
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004901 } else if (const DeclaratorDecl *DD
Guy Benyei11169dd2012-12-18 14:30:41 +00004902 = dyn_cast_or_null<DeclaratorDecl>(getCursorDecl(cursor))) {
4903 SourceLocation StartLoc = DD->getSourceRange().getBegin();
4904 // Check that when we have multiple declarators in the same line,
4905 // that later ones do not override the previous ones.
4906 // If we have:
4907 // int Foo, Bar;
4908 // source ranges for both start at 'int', so 'Bar' will end up overriding
4909 // 'Foo' even though the cursor location was at 'Foo'.
4910 if (Data->VisitedDeclaratorDeclStartLoc == StartLoc)
4911 return CXChildVisit_Break;
4912 Data->VisitedDeclaratorDeclStartLoc = StartLoc;
4913
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004914 } else if (const ObjCPropertyImplDecl *PropImp
Guy Benyei11169dd2012-12-18 14:30:41 +00004915 = dyn_cast_or_null<ObjCPropertyImplDecl>(getCursorDecl(cursor))) {
4916 (void)PropImp;
4917 // Check that when we have multiple @synthesize in the same line,
4918 // that later ones do not override the previous ones.
4919 // If we have:
4920 // @synthesize Foo, Bar;
4921 // source ranges for both start at '@', so 'Bar' will end up overriding
4922 // 'Foo' even though the cursor location was at 'Foo'.
4923 if (Data->VisitedObjCPropertyImplDecl)
4924 return CXChildVisit_Break;
4925 Data->VisitedObjCPropertyImplDecl = true;
4926 }
4927 }
4928
4929 if (clang_isExpression(cursor.kind) &&
4930 clang_isDeclaration(BestCursor->kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004931 if (const Decl *D = getCursorDecl(*BestCursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004932 // Avoid having the cursor of an expression replace the declaration cursor
4933 // when the expression source range overlaps the declaration range.
4934 // This can happen for C++ constructor expressions whose range generally
4935 // include the variable declaration, e.g.:
4936 // MyCXXClass foo; // Make sure pointing at 'foo' returns a VarDecl cursor.
4937 if (D->getLocation().isValid() && Data->TokenBeginLoc.isValid() &&
4938 D->getLocation() == Data->TokenBeginLoc)
4939 return CXChildVisit_Break;
4940 }
4941 }
4942
4943 // If our current best cursor is the construction of a temporary object,
4944 // don't replace that cursor with a type reference, because we want
4945 // clang_getCursor() to point at the constructor.
4946 if (clang_isExpression(BestCursor->kind) &&
4947 isa<CXXTemporaryObjectExpr>(getCursorExpr(*BestCursor)) &&
4948 cursor.kind == CXCursor_TypeRef) {
4949 // Keep the cursor pointing at CXXTemporaryObjectExpr but also mark it
4950 // as having the actual point on the type reference.
4951 *BestCursor = getTypeRefedCallExprCursor(*BestCursor);
4952 return CXChildVisit_Recurse;
4953 }
Douglas Gregore9d95f12015-07-07 03:57:35 +00004954
4955 // If we already have an Objective-C superclass reference, don't
4956 // update it further.
4957 if (BestCursor->kind == CXCursor_ObjCSuperClassRef)
4958 return CXChildVisit_Break;
4959
Guy Benyei11169dd2012-12-18 14:30:41 +00004960 *BestCursor = cursor;
4961 return CXChildVisit_Recurse;
4962}
4963
4964CXCursor clang_getCursor(CXTranslationUnit TU, CXSourceLocation Loc) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00004965 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004966 LOG_BAD_TU(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004967 return clang_getNullCursor();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004968 }
Guy Benyei11169dd2012-12-18 14:30:41 +00004969
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004970 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004971 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
4972
4973 SourceLocation SLoc = cxloc::translateSourceLocation(Loc);
4974 CXCursor Result = cxcursor::getCursor(TU, SLoc);
4975
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004976 LOG_FUNC_SECTION {
Guy Benyei11169dd2012-12-18 14:30:41 +00004977 CXFile SearchFile;
4978 unsigned SearchLine, SearchColumn;
4979 CXFile ResultFile;
4980 unsigned ResultLine, ResultColumn;
4981 CXString SearchFileName, ResultFileName, KindSpelling, USR;
4982 const char *IsDef = clang_isCursorDefinition(Result)? " (Definition)" : "";
4983 CXSourceLocation ResultLoc = clang_getCursorLocation(Result);
Craig Topper69186e72014-06-08 08:38:04 +00004984
4985 clang_getFileLocation(Loc, &SearchFile, &SearchLine, &SearchColumn,
4986 nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004987 clang_getFileLocation(ResultLoc, &ResultFile, &ResultLine,
Craig Topper69186e72014-06-08 08:38:04 +00004988 &ResultColumn, nullptr);
Guy Benyei11169dd2012-12-18 14:30:41 +00004989 SearchFileName = clang_getFileName(SearchFile);
4990 ResultFileName = clang_getFileName(ResultFile);
4991 KindSpelling = clang_getCursorKindSpelling(Result.kind);
4992 USR = clang_getCursorUSR(Result);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004993 *Log << llvm::format("(%s:%d:%d) = %s",
4994 clang_getCString(SearchFileName), SearchLine, SearchColumn,
4995 clang_getCString(KindSpelling))
4996 << llvm::format("(%s:%d:%d):%s%s",
4997 clang_getCString(ResultFileName), ResultLine, ResultColumn,
4998 clang_getCString(USR), IsDef);
Guy Benyei11169dd2012-12-18 14:30:41 +00004999 clang_disposeString(SearchFileName);
5000 clang_disposeString(ResultFileName);
5001 clang_disposeString(KindSpelling);
5002 clang_disposeString(USR);
5003
5004 CXCursor Definition = clang_getCursorDefinition(Result);
5005 if (!clang_equalCursors(Definition, clang_getNullCursor())) {
5006 CXSourceLocation DefinitionLoc = clang_getCursorLocation(Definition);
5007 CXString DefinitionKindSpelling
5008 = clang_getCursorKindSpelling(Definition.kind);
5009 CXFile DefinitionFile;
5010 unsigned DefinitionLine, DefinitionColumn;
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00005011 clang_getFileLocation(DefinitionLoc, &DefinitionFile,
Craig Topper69186e72014-06-08 08:38:04 +00005012 &DefinitionLine, &DefinitionColumn, nullptr);
Guy Benyei11169dd2012-12-18 14:30:41 +00005013 CXString DefinitionFileName = clang_getFileName(DefinitionFile);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00005014 *Log << llvm::format(" -> %s(%s:%d:%d)",
5015 clang_getCString(DefinitionKindSpelling),
5016 clang_getCString(DefinitionFileName),
5017 DefinitionLine, DefinitionColumn);
Guy Benyei11169dd2012-12-18 14:30:41 +00005018 clang_disposeString(DefinitionFileName);
5019 clang_disposeString(DefinitionKindSpelling);
5020 }
5021 }
5022
5023 return Result;
5024}
5025
5026CXCursor clang_getNullCursor(void) {
5027 return MakeCXCursorInvalid(CXCursor_InvalidFile);
5028}
5029
5030unsigned clang_equalCursors(CXCursor X, CXCursor Y) {
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00005031 // Clear out the "FirstInDeclGroup" part in a declaration cursor, since we
5032 // can't set consistently. For example, when visiting a DeclStmt we will set
5033 // it but we don't set it on the result of clang_getCursorDefinition for
5034 // a reference of the same declaration.
5035 // FIXME: Setting "FirstInDeclGroup" in CXCursors is a hack that only works
5036 // when visiting a DeclStmt currently, the AST should be enhanced to be able
5037 // to provide that kind of info.
5038 if (clang_isDeclaration(X.kind))
Craig Topper69186e72014-06-08 08:38:04 +00005039 X.data[1] = nullptr;
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00005040 if (clang_isDeclaration(Y.kind))
Craig Topper69186e72014-06-08 08:38:04 +00005041 Y.data[1] = nullptr;
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00005042
Guy Benyei11169dd2012-12-18 14:30:41 +00005043 return X == Y;
5044}
5045
5046unsigned clang_hashCursor(CXCursor C) {
5047 unsigned Index = 0;
5048 if (clang_isExpression(C.kind) || clang_isStatement(C.kind))
5049 Index = 1;
5050
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005051 return llvm::DenseMapInfo<std::pair<unsigned, const void*> >::getHashValue(
Guy Benyei11169dd2012-12-18 14:30:41 +00005052 std::make_pair(C.kind, C.data[Index]));
5053}
5054
5055unsigned clang_isInvalid(enum CXCursorKind K) {
5056 return K >= CXCursor_FirstInvalid && K <= CXCursor_LastInvalid;
5057}
5058
5059unsigned clang_isDeclaration(enum CXCursorKind K) {
5060 return (K >= CXCursor_FirstDecl && K <= CXCursor_LastDecl) ||
5061 (K >= CXCursor_FirstExtraDecl && K <= CXCursor_LastExtraDecl);
5062}
5063
5064unsigned clang_isReference(enum CXCursorKind K) {
5065 return K >= CXCursor_FirstRef && K <= CXCursor_LastRef;
5066}
5067
5068unsigned clang_isExpression(enum CXCursorKind K) {
5069 return K >= CXCursor_FirstExpr && K <= CXCursor_LastExpr;
5070}
5071
5072unsigned clang_isStatement(enum CXCursorKind K) {
5073 return K >= CXCursor_FirstStmt && K <= CXCursor_LastStmt;
5074}
5075
5076unsigned clang_isAttribute(enum CXCursorKind K) {
5077 return K >= CXCursor_FirstAttr && K <= CXCursor_LastAttr;
5078}
5079
5080unsigned clang_isTranslationUnit(enum CXCursorKind K) {
5081 return K == CXCursor_TranslationUnit;
5082}
5083
5084unsigned clang_isPreprocessing(enum CXCursorKind K) {
5085 return K >= CXCursor_FirstPreprocessing && K <= CXCursor_LastPreprocessing;
5086}
5087
5088unsigned clang_isUnexposed(enum CXCursorKind K) {
5089 switch (K) {
5090 case CXCursor_UnexposedDecl:
5091 case CXCursor_UnexposedExpr:
5092 case CXCursor_UnexposedStmt:
5093 case CXCursor_UnexposedAttr:
5094 return true;
5095 default:
5096 return false;
5097 }
5098}
5099
5100CXCursorKind clang_getCursorKind(CXCursor C) {
5101 return C.kind;
5102}
5103
5104CXSourceLocation clang_getCursorLocation(CXCursor C) {
5105 if (clang_isReference(C.kind)) {
5106 switch (C.kind) {
5107 case CXCursor_ObjCSuperClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005108 std::pair<const ObjCInterfaceDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00005109 = getCursorObjCSuperClassRef(C);
5110 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
5111 }
5112
5113 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005114 std::pair<const ObjCProtocolDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00005115 = getCursorObjCProtocolRef(C);
5116 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
5117 }
5118
5119 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005120 std::pair<const ObjCInterfaceDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00005121 = getCursorObjCClassRef(C);
5122 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
5123 }
5124
5125 case CXCursor_TypeRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005126 std::pair<const TypeDecl *, SourceLocation> P = getCursorTypeRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005127 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
5128 }
5129
5130 case CXCursor_TemplateRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005131 std::pair<const TemplateDecl *, SourceLocation> P =
5132 getCursorTemplateRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005133 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
5134 }
5135
5136 case CXCursor_NamespaceRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005137 std::pair<const NamedDecl *, SourceLocation> P = getCursorNamespaceRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005138 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
5139 }
5140
5141 case CXCursor_MemberRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005142 std::pair<const FieldDecl *, SourceLocation> P = getCursorMemberRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005143 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
5144 }
5145
5146 case CXCursor_VariableRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005147 std::pair<const VarDecl *, SourceLocation> P = getCursorVariableRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005148 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
5149 }
5150
5151 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005152 const CXXBaseSpecifier *BaseSpec = getCursorCXXBaseSpecifier(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005153 if (!BaseSpec)
5154 return clang_getNullLocation();
5155
5156 if (TypeSourceInfo *TSInfo = BaseSpec->getTypeSourceInfo())
5157 return cxloc::translateSourceLocation(getCursorContext(C),
5158 TSInfo->getTypeLoc().getBeginLoc());
5159
5160 return cxloc::translateSourceLocation(getCursorContext(C),
5161 BaseSpec->getLocStart());
5162 }
5163
5164 case CXCursor_LabelRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005165 std::pair<const LabelStmt *, SourceLocation> P = getCursorLabelRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005166 return cxloc::translateSourceLocation(getCursorContext(C), P.second);
5167 }
5168
5169 case CXCursor_OverloadedDeclRef:
5170 return cxloc::translateSourceLocation(getCursorContext(C),
5171 getCursorOverloadedDeclRef(C).second);
5172
5173 default:
5174 // FIXME: Need a way to enumerate all non-reference cases.
5175 llvm_unreachable("Missed a reference kind");
5176 }
5177 }
5178
5179 if (clang_isExpression(C.kind))
5180 return cxloc::translateSourceLocation(getCursorContext(C),
5181 getLocationFromExpr(getCursorExpr(C)));
5182
5183 if (clang_isStatement(C.kind))
5184 return cxloc::translateSourceLocation(getCursorContext(C),
5185 getCursorStmt(C)->getLocStart());
5186
5187 if (C.kind == CXCursor_PreprocessingDirective) {
5188 SourceLocation L = cxcursor::getCursorPreprocessingDirective(C).getBegin();
5189 return cxloc::translateSourceLocation(getCursorContext(C), L);
5190 }
5191
5192 if (C.kind == CXCursor_MacroExpansion) {
5193 SourceLocation L
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00005194 = cxcursor::getCursorMacroExpansion(C).getSourceRange().getBegin();
Guy Benyei11169dd2012-12-18 14:30:41 +00005195 return cxloc::translateSourceLocation(getCursorContext(C), L);
5196 }
5197
5198 if (C.kind == CXCursor_MacroDefinition) {
5199 SourceLocation L = cxcursor::getCursorMacroDefinition(C)->getLocation();
5200 return cxloc::translateSourceLocation(getCursorContext(C), L);
5201 }
5202
5203 if (C.kind == CXCursor_InclusionDirective) {
5204 SourceLocation L
5205 = cxcursor::getCursorInclusionDirective(C)->getSourceRange().getBegin();
5206 return cxloc::translateSourceLocation(getCursorContext(C), L);
5207 }
5208
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00005209 if (clang_isAttribute(C.kind)) {
5210 SourceLocation L
5211 = cxcursor::getCursorAttr(C)->getLocation();
5212 return cxloc::translateSourceLocation(getCursorContext(C), L);
5213 }
5214
Guy Benyei11169dd2012-12-18 14:30:41 +00005215 if (!clang_isDeclaration(C.kind))
5216 return clang_getNullLocation();
5217
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005218 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005219 if (!D)
5220 return clang_getNullLocation();
5221
5222 SourceLocation Loc = D->getLocation();
5223 // FIXME: Multiple variables declared in a single declaration
5224 // currently lack the information needed to correctly determine their
5225 // ranges when accounting for the type-specifier. We use context
5226 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
5227 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005228 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005229 if (!cxcursor::isFirstInDeclGroup(C))
5230 Loc = VD->getLocation();
5231 }
5232
5233 // For ObjC methods, give the start location of the method name.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005234 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00005235 Loc = MD->getSelectorStartLoc();
5236
5237 return cxloc::translateSourceLocation(getCursorContext(C), Loc);
5238}
5239
5240} // end extern "C"
5241
5242CXCursor cxcursor::getCursor(CXTranslationUnit TU, SourceLocation SLoc) {
5243 assert(TU);
5244
5245 // Guard against an invalid SourceLocation, or we may assert in one
5246 // of the following calls.
5247 if (SLoc.isInvalid())
5248 return clang_getNullCursor();
5249
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005250 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005251
5252 // Translate the given source location to make it point at the beginning of
5253 // the token under the cursor.
5254 SLoc = Lexer::GetBeginningOfToken(SLoc, CXXUnit->getSourceManager(),
5255 CXXUnit->getASTContext().getLangOpts());
5256
5257 CXCursor Result = MakeCXCursorInvalid(CXCursor_NoDeclFound);
5258 if (SLoc.isValid()) {
5259 GetCursorData ResultData(CXXUnit->getSourceManager(), SLoc, Result);
5260 CursorVisitor CursorVis(TU, GetCursorVisitor, &ResultData,
5261 /*VisitPreprocessorLast=*/true,
5262 /*VisitIncludedEntities=*/false,
5263 SourceLocation(SLoc));
5264 CursorVis.visitFileRegion();
5265 }
5266
5267 return Result;
5268}
5269
5270static SourceRange getRawCursorExtent(CXCursor C) {
5271 if (clang_isReference(C.kind)) {
5272 switch (C.kind) {
5273 case CXCursor_ObjCSuperClassRef:
5274 return getCursorObjCSuperClassRef(C).second;
5275
5276 case CXCursor_ObjCProtocolRef:
5277 return getCursorObjCProtocolRef(C).second;
5278
5279 case CXCursor_ObjCClassRef:
5280 return getCursorObjCClassRef(C).second;
5281
5282 case CXCursor_TypeRef:
5283 return getCursorTypeRef(C).second;
5284
5285 case CXCursor_TemplateRef:
5286 return getCursorTemplateRef(C).second;
5287
5288 case CXCursor_NamespaceRef:
5289 return getCursorNamespaceRef(C).second;
5290
5291 case CXCursor_MemberRef:
5292 return getCursorMemberRef(C).second;
5293
5294 case CXCursor_CXXBaseSpecifier:
5295 return getCursorCXXBaseSpecifier(C)->getSourceRange();
5296
5297 case CXCursor_LabelRef:
5298 return getCursorLabelRef(C).second;
5299
5300 case CXCursor_OverloadedDeclRef:
5301 return getCursorOverloadedDeclRef(C).second;
5302
5303 case CXCursor_VariableRef:
5304 return getCursorVariableRef(C).second;
5305
5306 default:
5307 // FIXME: Need a way to enumerate all non-reference cases.
5308 llvm_unreachable("Missed a reference kind");
5309 }
5310 }
5311
5312 if (clang_isExpression(C.kind))
5313 return getCursorExpr(C)->getSourceRange();
5314
5315 if (clang_isStatement(C.kind))
5316 return getCursorStmt(C)->getSourceRange();
5317
5318 if (clang_isAttribute(C.kind))
5319 return getCursorAttr(C)->getRange();
5320
5321 if (C.kind == CXCursor_PreprocessingDirective)
5322 return cxcursor::getCursorPreprocessingDirective(C);
5323
5324 if (C.kind == CXCursor_MacroExpansion) {
5325 ASTUnit *TU = getCursorASTUnit(C);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00005326 SourceRange Range = cxcursor::getCursorMacroExpansion(C).getSourceRange();
Guy Benyei11169dd2012-12-18 14:30:41 +00005327 return TU->mapRangeFromPreamble(Range);
5328 }
5329
5330 if (C.kind == CXCursor_MacroDefinition) {
5331 ASTUnit *TU = getCursorASTUnit(C);
5332 SourceRange Range = cxcursor::getCursorMacroDefinition(C)->getSourceRange();
5333 return TU->mapRangeFromPreamble(Range);
5334 }
5335
5336 if (C.kind == CXCursor_InclusionDirective) {
5337 ASTUnit *TU = getCursorASTUnit(C);
5338 SourceRange Range = cxcursor::getCursorInclusionDirective(C)->getSourceRange();
5339 return TU->mapRangeFromPreamble(Range);
5340 }
5341
5342 if (C.kind == CXCursor_TranslationUnit) {
5343 ASTUnit *TU = getCursorASTUnit(C);
5344 FileID MainID = TU->getSourceManager().getMainFileID();
5345 SourceLocation Start = TU->getSourceManager().getLocForStartOfFile(MainID);
5346 SourceLocation End = TU->getSourceManager().getLocForEndOfFile(MainID);
5347 return SourceRange(Start, End);
5348 }
5349
5350 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005351 const Decl *D = cxcursor::getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005352 if (!D)
5353 return SourceRange();
5354
5355 SourceRange R = D->getSourceRange();
5356 // FIXME: Multiple variables declared in a single declaration
5357 // currently lack the information needed to correctly determine their
5358 // ranges when accounting for the type-specifier. We use context
5359 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
5360 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005361 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005362 if (!cxcursor::isFirstInDeclGroup(C))
5363 R.setBegin(VD->getLocation());
5364 }
5365 return R;
5366 }
5367 return SourceRange();
5368}
5369
5370/// \brief Retrieves the "raw" cursor extent, which is then extended to include
5371/// the decl-specifier-seq for declarations.
5372static SourceRange getFullCursorExtent(CXCursor C, SourceManager &SrcMgr) {
5373 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005374 const Decl *D = cxcursor::getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005375 if (!D)
5376 return SourceRange();
5377
5378 SourceRange R = D->getSourceRange();
5379
5380 // Adjust the start of the location for declarations preceded by
5381 // declaration specifiers.
5382 SourceLocation StartLoc;
5383 if (const DeclaratorDecl *DD = dyn_cast<DeclaratorDecl>(D)) {
5384 if (TypeSourceInfo *TI = DD->getTypeSourceInfo())
5385 StartLoc = TI->getTypeLoc().getLocStart();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005386 } else if (const TypedefDecl *Typedef = dyn_cast<TypedefDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005387 if (TypeSourceInfo *TI = Typedef->getTypeSourceInfo())
5388 StartLoc = TI->getTypeLoc().getLocStart();
5389 }
5390
5391 if (StartLoc.isValid() && R.getBegin().isValid() &&
5392 SrcMgr.isBeforeInTranslationUnit(StartLoc, R.getBegin()))
5393 R.setBegin(StartLoc);
5394
5395 // FIXME: Multiple variables declared in a single declaration
5396 // currently lack the information needed to correctly determine their
5397 // ranges when accounting for the type-specifier. We use context
5398 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
5399 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005400 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005401 if (!cxcursor::isFirstInDeclGroup(C))
5402 R.setBegin(VD->getLocation());
5403 }
5404
5405 return R;
5406 }
5407
5408 return getRawCursorExtent(C);
5409}
5410
5411extern "C" {
5412
5413CXSourceRange clang_getCursorExtent(CXCursor C) {
5414 SourceRange R = getRawCursorExtent(C);
5415 if (R.isInvalid())
5416 return clang_getNullRange();
5417
5418 return cxloc::translateSourceRange(getCursorContext(C), R);
5419}
5420
5421CXCursor clang_getCursorReferenced(CXCursor C) {
5422 if (clang_isInvalid(C.kind))
5423 return clang_getNullCursor();
5424
5425 CXTranslationUnit tu = getCursorTU(C);
5426 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005427 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005428 if (!D)
5429 return clang_getNullCursor();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005430 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00005431 return MakeCursorOverloadedDeclRef(Using, D->getLocation(), tu);
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005432 if (const ObjCPropertyImplDecl *PropImpl =
5433 dyn_cast<ObjCPropertyImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00005434 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
5435 return MakeCXCursor(Property, tu);
5436
5437 return C;
5438 }
5439
5440 if (clang_isExpression(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005441 const Expr *E = getCursorExpr(C);
5442 const Decl *D = getDeclFromExpr(E);
Guy Benyei11169dd2012-12-18 14:30:41 +00005443 if (D) {
5444 CXCursor declCursor = MakeCXCursor(D, tu);
5445 declCursor = getSelectorIdentifierCursor(getSelectorIdentifierIndex(C),
5446 declCursor);
5447 return declCursor;
5448 }
5449
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005450 if (const OverloadExpr *Ovl = dyn_cast_or_null<OverloadExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00005451 return MakeCursorOverloadedDeclRef(Ovl, tu);
5452
5453 return clang_getNullCursor();
5454 }
5455
5456 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005457 const Stmt *S = getCursorStmt(C);
5458 if (const GotoStmt *Goto = dyn_cast_or_null<GotoStmt>(S))
Guy Benyei11169dd2012-12-18 14:30:41 +00005459 if (LabelDecl *label = Goto->getLabel())
5460 if (LabelStmt *labelS = label->getStmt())
5461 return MakeCXCursor(labelS, getCursorDecl(C), tu);
5462
5463 return clang_getNullCursor();
5464 }
Richard Smith66a81862015-05-04 02:25:31 +00005465
Guy Benyei11169dd2012-12-18 14:30:41 +00005466 if (C.kind == CXCursor_MacroExpansion) {
Richard Smith66a81862015-05-04 02:25:31 +00005467 if (const MacroDefinitionRecord *Def =
5468 getCursorMacroExpansion(C).getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005469 return MakeMacroDefinitionCursor(Def, tu);
5470 }
5471
5472 if (!clang_isReference(C.kind))
5473 return clang_getNullCursor();
5474
5475 switch (C.kind) {
5476 case CXCursor_ObjCSuperClassRef:
5477 return MakeCXCursor(getCursorObjCSuperClassRef(C).first, tu);
5478
5479 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005480 const ObjCProtocolDecl *Prot = getCursorObjCProtocolRef(C).first;
5481 if (const ObjCProtocolDecl *Def = Prot->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005482 return MakeCXCursor(Def, tu);
5483
5484 return MakeCXCursor(Prot, tu);
5485 }
5486
5487 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005488 const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
5489 if (const ObjCInterfaceDecl *Def = Class->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005490 return MakeCXCursor(Def, tu);
5491
5492 return MakeCXCursor(Class, tu);
5493 }
5494
5495 case CXCursor_TypeRef:
5496 return MakeCXCursor(getCursorTypeRef(C).first, tu );
5497
5498 case CXCursor_TemplateRef:
5499 return MakeCXCursor(getCursorTemplateRef(C).first, tu );
5500
5501 case CXCursor_NamespaceRef:
5502 return MakeCXCursor(getCursorNamespaceRef(C).first, tu );
5503
5504 case CXCursor_MemberRef:
5505 return MakeCXCursor(getCursorMemberRef(C).first, tu );
5506
5507 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005508 const CXXBaseSpecifier *B = cxcursor::getCursorCXXBaseSpecifier(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005509 return clang_getTypeDeclaration(cxtype::MakeCXType(B->getType(),
5510 tu ));
5511 }
5512
5513 case CXCursor_LabelRef:
5514 // FIXME: We end up faking the "parent" declaration here because we
5515 // don't want to make CXCursor larger.
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005516 return MakeCXCursor(getCursorLabelRef(C).first,
5517 cxtu::getASTUnit(tu)->getASTContext()
5518 .getTranslationUnitDecl(),
Guy Benyei11169dd2012-12-18 14:30:41 +00005519 tu);
5520
5521 case CXCursor_OverloadedDeclRef:
5522 return C;
5523
5524 case CXCursor_VariableRef:
5525 return MakeCXCursor(getCursorVariableRef(C).first, tu);
5526
5527 default:
5528 // We would prefer to enumerate all non-reference cursor kinds here.
5529 llvm_unreachable("Unhandled reference cursor kind");
5530 }
5531}
5532
5533CXCursor clang_getCursorDefinition(CXCursor C) {
5534 if (clang_isInvalid(C.kind))
5535 return clang_getNullCursor();
5536
5537 CXTranslationUnit TU = getCursorTU(C);
5538
5539 bool WasReference = false;
5540 if (clang_isReference(C.kind) || clang_isExpression(C.kind)) {
5541 C = clang_getCursorReferenced(C);
5542 WasReference = true;
5543 }
5544
5545 if (C.kind == CXCursor_MacroExpansion)
5546 return clang_getCursorReferenced(C);
5547
5548 if (!clang_isDeclaration(C.kind))
5549 return clang_getNullCursor();
5550
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005551 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005552 if (!D)
5553 return clang_getNullCursor();
5554
5555 switch (D->getKind()) {
5556 // Declaration kinds that don't really separate the notions of
5557 // declaration and definition.
5558 case Decl::Namespace:
5559 case Decl::Typedef:
5560 case Decl::TypeAlias:
5561 case Decl::TypeAliasTemplate:
5562 case Decl::TemplateTypeParm:
5563 case Decl::EnumConstant:
5564 case Decl::Field:
John McCall5e77d762013-04-16 07:28:30 +00005565 case Decl::MSProperty:
Guy Benyei11169dd2012-12-18 14:30:41 +00005566 case Decl::IndirectField:
5567 case Decl::ObjCIvar:
5568 case Decl::ObjCAtDefsField:
5569 case Decl::ImplicitParam:
5570 case Decl::ParmVar:
5571 case Decl::NonTypeTemplateParm:
5572 case Decl::TemplateTemplateParm:
5573 case Decl::ObjCCategoryImpl:
5574 case Decl::ObjCImplementation:
5575 case Decl::AccessSpec:
5576 case Decl::LinkageSpec:
5577 case Decl::ObjCPropertyImpl:
5578 case Decl::FileScopeAsm:
5579 case Decl::StaticAssert:
5580 case Decl::Block:
Tareq A. Siraj6dfa25a2013-04-16 19:37:38 +00005581 case Decl::Captured:
Alexey Bataev4244be22016-02-11 05:35:55 +00005582 case Decl::OMPCapturedExpr:
Guy Benyei11169dd2012-12-18 14:30:41 +00005583 case Decl::Label: // FIXME: Is this right??
5584 case Decl::ClassScopeFunctionSpecialization:
5585 case Decl::Import:
Alexey Bataeva769e072013-03-22 06:34:35 +00005586 case Decl::OMPThreadPrivate:
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:
Guy Benyei11169dd2012-12-18 14:30:41 +00005590 return C;
5591
5592 // Declaration kinds that don't make any sense here, but are
5593 // nonetheless harmless.
David Blaikief005d3c2013-02-22 17:44:58 +00005594 case Decl::Empty:
Guy Benyei11169dd2012-12-18 14:30:41 +00005595 case Decl::TranslationUnit:
Richard Smithf19e1272015-03-07 00:04:49 +00005596 case Decl::ExternCContext:
Guy Benyei11169dd2012-12-18 14:30:41 +00005597 break;
5598
5599 // Declaration kinds for which the definition is not resolvable.
5600 case Decl::UnresolvedUsingTypename:
5601 case Decl::UnresolvedUsingValue:
5602 break;
5603
5604 case Decl::UsingDirective:
5605 return MakeCXCursor(cast<UsingDirectiveDecl>(D)->getNominatedNamespace(),
5606 TU);
5607
5608 case Decl::NamespaceAlias:
5609 return MakeCXCursor(cast<NamespaceAliasDecl>(D)->getNamespace(), TU);
5610
5611 case Decl::Enum:
5612 case Decl::Record:
5613 case Decl::CXXRecord:
5614 case Decl::ClassTemplateSpecialization:
5615 case Decl::ClassTemplatePartialSpecialization:
5616 if (TagDecl *Def = cast<TagDecl>(D)->getDefinition())
5617 return MakeCXCursor(Def, TU);
5618 return clang_getNullCursor();
5619
5620 case Decl::Function:
5621 case Decl::CXXMethod:
5622 case Decl::CXXConstructor:
5623 case Decl::CXXDestructor:
5624 case Decl::CXXConversion: {
Craig Topper69186e72014-06-08 08:38:04 +00005625 const FunctionDecl *Def = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005626 if (cast<FunctionDecl>(D)->getBody(Def))
Dmitri Gribenko9c256e32013-01-14 00:46:27 +00005627 return MakeCXCursor(Def, TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005628 return clang_getNullCursor();
5629 }
5630
Larisse Voufo39a1e502013-08-06 01:03:05 +00005631 case Decl::Var:
5632 case Decl::VarTemplateSpecialization:
5633 case Decl::VarTemplatePartialSpecialization: {
Guy Benyei11169dd2012-12-18 14:30:41 +00005634 // Ask the variable if it has a definition.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005635 if (const VarDecl *Def = cast<VarDecl>(D)->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005636 return MakeCXCursor(Def, TU);
5637 return clang_getNullCursor();
5638 }
5639
5640 case Decl::FunctionTemplate: {
Craig Topper69186e72014-06-08 08:38:04 +00005641 const FunctionDecl *Def = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005642 if (cast<FunctionTemplateDecl>(D)->getTemplatedDecl()->getBody(Def))
5643 return MakeCXCursor(Def->getDescribedFunctionTemplate(), TU);
5644 return clang_getNullCursor();
5645 }
5646
5647 case Decl::ClassTemplate: {
5648 if (RecordDecl *Def = cast<ClassTemplateDecl>(D)->getTemplatedDecl()
5649 ->getDefinition())
5650 return MakeCXCursor(cast<CXXRecordDecl>(Def)->getDescribedClassTemplate(),
5651 TU);
5652 return clang_getNullCursor();
5653 }
5654
Larisse Voufo39a1e502013-08-06 01:03:05 +00005655 case Decl::VarTemplate: {
5656 if (VarDecl *Def =
5657 cast<VarTemplateDecl>(D)->getTemplatedDecl()->getDefinition())
5658 return MakeCXCursor(cast<VarDecl>(Def)->getDescribedVarTemplate(), TU);
5659 return clang_getNullCursor();
5660 }
5661
Guy Benyei11169dd2012-12-18 14:30:41 +00005662 case Decl::Using:
5663 return MakeCursorOverloadedDeclRef(cast<UsingDecl>(D),
5664 D->getLocation(), TU);
5665
5666 case Decl::UsingShadow:
5667 return clang_getCursorDefinition(
5668 MakeCXCursor(cast<UsingShadowDecl>(D)->getTargetDecl(),
5669 TU));
5670
5671 case Decl::ObjCMethod: {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005672 const ObjCMethodDecl *Method = cast<ObjCMethodDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00005673 if (Method->isThisDeclarationADefinition())
5674 return C;
5675
5676 // Dig out the method definition in the associated
5677 // @implementation, if we have it.
5678 // FIXME: The ASTs should make finding the definition easier.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005679 if (const ObjCInterfaceDecl *Class
Guy Benyei11169dd2012-12-18 14:30:41 +00005680 = dyn_cast<ObjCInterfaceDecl>(Method->getDeclContext()))
5681 if (ObjCImplementationDecl *ClassImpl = Class->getImplementation())
5682 if (ObjCMethodDecl *Def = ClassImpl->getMethod(Method->getSelector(),
5683 Method->isInstanceMethod()))
5684 if (Def->isThisDeclarationADefinition())
5685 return MakeCXCursor(Def, TU);
5686
5687 return clang_getNullCursor();
5688 }
5689
5690 case Decl::ObjCCategory:
5691 if (ObjCCategoryImplDecl *Impl
5692 = cast<ObjCCategoryDecl>(D)->getImplementation())
5693 return MakeCXCursor(Impl, TU);
5694 return clang_getNullCursor();
5695
5696 case Decl::ObjCProtocol:
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005697 if (const ObjCProtocolDecl *Def = cast<ObjCProtocolDecl>(D)->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005698 return MakeCXCursor(Def, TU);
5699 return clang_getNullCursor();
5700
5701 case Decl::ObjCInterface: {
5702 // There are two notions of a "definition" for an Objective-C
5703 // class: the interface and its implementation. When we resolved a
5704 // reference to an Objective-C class, produce the @interface as
5705 // the definition; when we were provided with the interface,
5706 // produce the @implementation as the definition.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005707 const ObjCInterfaceDecl *IFace = cast<ObjCInterfaceDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00005708 if (WasReference) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005709 if (const ObjCInterfaceDecl *Def = IFace->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005710 return MakeCXCursor(Def, TU);
5711 } else if (ObjCImplementationDecl *Impl = IFace->getImplementation())
5712 return MakeCXCursor(Impl, TU);
5713 return clang_getNullCursor();
5714 }
5715
5716 case Decl::ObjCProperty:
5717 // FIXME: We don't really know where to find the
5718 // ObjCPropertyImplDecls that implement this property.
5719 return clang_getNullCursor();
5720
5721 case Decl::ObjCCompatibleAlias:
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005722 if (const ObjCInterfaceDecl *Class
Guy Benyei11169dd2012-12-18 14:30:41 +00005723 = cast<ObjCCompatibleAliasDecl>(D)->getClassInterface())
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005724 if (const ObjCInterfaceDecl *Def = Class->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005725 return MakeCXCursor(Def, TU);
5726
5727 return clang_getNullCursor();
5728
5729 case Decl::Friend:
5730 if (NamedDecl *Friend = cast<FriendDecl>(D)->getFriendDecl())
5731 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
5732 return clang_getNullCursor();
5733
5734 case Decl::FriendTemplate:
5735 if (NamedDecl *Friend = cast<FriendTemplateDecl>(D)->getFriendDecl())
5736 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
5737 return clang_getNullCursor();
5738 }
5739
5740 return clang_getNullCursor();
5741}
5742
5743unsigned clang_isCursorDefinition(CXCursor C) {
5744 if (!clang_isDeclaration(C.kind))
5745 return 0;
5746
5747 return clang_getCursorDefinition(C) == C;
5748}
5749
5750CXCursor clang_getCanonicalCursor(CXCursor C) {
5751 if (!clang_isDeclaration(C.kind))
5752 return C;
5753
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005754 if (const Decl *D = getCursorDecl(C)) {
5755 if (const ObjCCategoryImplDecl *CatImplD = dyn_cast<ObjCCategoryImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00005756 if (ObjCCategoryDecl *CatD = CatImplD->getCategoryDecl())
5757 return MakeCXCursor(CatD, getCursorTU(C));
5758
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005759 if (const ObjCImplDecl *ImplD = dyn_cast<ObjCImplDecl>(D))
5760 if (const ObjCInterfaceDecl *IFD = ImplD->getClassInterface())
Guy Benyei11169dd2012-12-18 14:30:41 +00005761 return MakeCXCursor(IFD, getCursorTU(C));
5762
5763 return MakeCXCursor(D->getCanonicalDecl(), getCursorTU(C));
5764 }
5765
5766 return C;
5767}
5768
5769int clang_Cursor_getObjCSelectorIndex(CXCursor cursor) {
5770 return cxcursor::getSelectorIdentifierIndexAndLoc(cursor).first;
5771}
5772
5773unsigned clang_getNumOverloadedDecls(CXCursor C) {
5774 if (C.kind != CXCursor_OverloadedDeclRef)
5775 return 0;
5776
5777 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005778 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Guy Benyei11169dd2012-12-18 14:30:41 +00005779 return E->getNumDecls();
5780
5781 if (OverloadedTemplateStorage *S
5782 = Storage.dyn_cast<OverloadedTemplateStorage*>())
5783 return S->size();
5784
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005785 const Decl *D = Storage.get<const Decl *>();
5786 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00005787 return Using->shadow_size();
5788
5789 return 0;
5790}
5791
5792CXCursor clang_getOverloadedDecl(CXCursor cursor, unsigned index) {
5793 if (cursor.kind != CXCursor_OverloadedDeclRef)
5794 return clang_getNullCursor();
5795
5796 if (index >= clang_getNumOverloadedDecls(cursor))
5797 return clang_getNullCursor();
5798
5799 CXTranslationUnit TU = getCursorTU(cursor);
5800 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(cursor).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005801 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Guy Benyei11169dd2012-12-18 14:30:41 +00005802 return MakeCXCursor(E->decls_begin()[index], TU);
5803
5804 if (OverloadedTemplateStorage *S
5805 = Storage.dyn_cast<OverloadedTemplateStorage*>())
5806 return MakeCXCursor(S->begin()[index], TU);
5807
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005808 const Decl *D = Storage.get<const Decl *>();
5809 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005810 // FIXME: This is, unfortunately, linear time.
5811 UsingDecl::shadow_iterator Pos = Using->shadow_begin();
5812 std::advance(Pos, index);
5813 return MakeCXCursor(cast<UsingShadowDecl>(*Pos)->getTargetDecl(), TU);
5814 }
5815
5816 return clang_getNullCursor();
5817}
5818
5819void clang_getDefinitionSpellingAndExtent(CXCursor C,
5820 const char **startBuf,
5821 const char **endBuf,
5822 unsigned *startLine,
5823 unsigned *startColumn,
5824 unsigned *endLine,
5825 unsigned *endColumn) {
5826 assert(getCursorDecl(C) && "CXCursor has null decl");
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005827 const FunctionDecl *FD = dyn_cast<FunctionDecl>(getCursorDecl(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00005828 CompoundStmt *Body = dyn_cast<CompoundStmt>(FD->getBody());
5829
5830 SourceManager &SM = FD->getASTContext().getSourceManager();
5831 *startBuf = SM.getCharacterData(Body->getLBracLoc());
5832 *endBuf = SM.getCharacterData(Body->getRBracLoc());
5833 *startLine = SM.getSpellingLineNumber(Body->getLBracLoc());
5834 *startColumn = SM.getSpellingColumnNumber(Body->getLBracLoc());
5835 *endLine = SM.getSpellingLineNumber(Body->getRBracLoc());
5836 *endColumn = SM.getSpellingColumnNumber(Body->getRBracLoc());
5837}
5838
5839
5840CXSourceRange clang_getCursorReferenceNameRange(CXCursor C, unsigned NameFlags,
5841 unsigned PieceIndex) {
5842 RefNamePieces Pieces;
5843
5844 switch (C.kind) {
5845 case CXCursor_MemberRefExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005846 if (const MemberExpr *E = dyn_cast<MemberExpr>(getCursorExpr(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00005847 Pieces = buildPieces(NameFlags, true, E->getMemberNameInfo(),
5848 E->getQualifierLoc().getSourceRange());
5849 break;
5850
5851 case CXCursor_DeclRefExpr:
James Y Knight04ec5bf2015-12-24 02:59:37 +00005852 if (const DeclRefExpr *E = dyn_cast<DeclRefExpr>(getCursorExpr(C))) {
5853 SourceRange TemplateArgLoc(E->getLAngleLoc(), E->getRAngleLoc());
5854 Pieces =
5855 buildPieces(NameFlags, false, E->getNameInfo(),
5856 E->getQualifierLoc().getSourceRange(), &TemplateArgLoc);
5857 }
Guy Benyei11169dd2012-12-18 14:30:41 +00005858 break;
5859
5860 case CXCursor_CallExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005861 if (const CXXOperatorCallExpr *OCE =
Guy Benyei11169dd2012-12-18 14:30:41 +00005862 dyn_cast<CXXOperatorCallExpr>(getCursorExpr(C))) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005863 const Expr *Callee = OCE->getCallee();
5864 if (const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Callee))
Guy Benyei11169dd2012-12-18 14:30:41 +00005865 Callee = ICE->getSubExpr();
5866
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005867 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(Callee))
Guy Benyei11169dd2012-12-18 14:30:41 +00005868 Pieces = buildPieces(NameFlags, false, DRE->getNameInfo(),
5869 DRE->getQualifierLoc().getSourceRange());
5870 }
5871 break;
5872
5873 default:
5874 break;
5875 }
5876
5877 if (Pieces.empty()) {
5878 if (PieceIndex == 0)
5879 return clang_getCursorExtent(C);
5880 } else if (PieceIndex < Pieces.size()) {
5881 SourceRange R = Pieces[PieceIndex];
5882 if (R.isValid())
5883 return cxloc::translateSourceRange(getCursorContext(C), R);
5884 }
5885
5886 return clang_getNullRange();
5887}
5888
5889void clang_enableStackTraces(void) {
5890 llvm::sys::PrintStackTraceOnErrorSignal();
5891}
5892
5893void clang_executeOnThread(void (*fn)(void*), void *user_data,
5894 unsigned stack_size) {
5895 llvm::llvm_execute_on_thread(fn, user_data, stack_size);
5896}
5897
5898} // end: extern "C"
5899
5900//===----------------------------------------------------------------------===//
5901// Token-based Operations.
5902//===----------------------------------------------------------------------===//
5903
5904/* CXToken layout:
5905 * int_data[0]: a CXTokenKind
5906 * int_data[1]: starting token location
5907 * int_data[2]: token length
5908 * int_data[3]: reserved
5909 * ptr_data: for identifiers and keywords, an IdentifierInfo*.
5910 * otherwise unused.
5911 */
5912extern "C" {
5913
5914CXTokenKind clang_getTokenKind(CXToken CXTok) {
5915 return static_cast<CXTokenKind>(CXTok.int_data[0]);
5916}
5917
5918CXString clang_getTokenSpelling(CXTranslationUnit TU, CXToken CXTok) {
5919 switch (clang_getTokenKind(CXTok)) {
5920 case CXToken_Identifier:
5921 case CXToken_Keyword:
5922 // We know we have an IdentifierInfo*, so use that.
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005923 return cxstring::createRef(static_cast<IdentifierInfo *>(CXTok.ptr_data)
Guy Benyei11169dd2012-12-18 14:30:41 +00005924 ->getNameStart());
5925
5926 case CXToken_Literal: {
5927 // We have stashed the starting pointer in the ptr_data field. Use it.
5928 const char *Text = static_cast<const char *>(CXTok.ptr_data);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00005929 return cxstring::createDup(StringRef(Text, CXTok.int_data[2]));
Guy Benyei11169dd2012-12-18 14:30:41 +00005930 }
5931
5932 case CXToken_Punctuation:
5933 case CXToken_Comment:
5934 break;
5935 }
5936
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005937 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005938 LOG_BAD_TU(TU);
5939 return cxstring::createEmpty();
5940 }
5941
Guy Benyei11169dd2012-12-18 14:30:41 +00005942 // We have to find the starting buffer pointer the hard way, by
5943 // deconstructing the source location.
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005944 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005945 if (!CXXUnit)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00005946 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00005947
5948 SourceLocation Loc = SourceLocation::getFromRawEncoding(CXTok.int_data[1]);
5949 std::pair<FileID, unsigned> LocInfo
5950 = CXXUnit->getSourceManager().getDecomposedSpellingLoc(Loc);
5951 bool Invalid = false;
5952 StringRef Buffer
5953 = CXXUnit->getSourceManager().getBufferData(LocInfo.first, &Invalid);
5954 if (Invalid)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00005955 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00005956
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00005957 return cxstring::createDup(Buffer.substr(LocInfo.second, CXTok.int_data[2]));
Guy Benyei11169dd2012-12-18 14:30:41 +00005958}
5959
5960CXSourceLocation clang_getTokenLocation(CXTranslationUnit TU, CXToken CXTok) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005961 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005962 LOG_BAD_TU(TU);
5963 return clang_getNullLocation();
5964 }
5965
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005966 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005967 if (!CXXUnit)
5968 return clang_getNullLocation();
5969
5970 return cxloc::translateSourceLocation(CXXUnit->getASTContext(),
5971 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
5972}
5973
5974CXSourceRange clang_getTokenExtent(CXTranslationUnit TU, CXToken CXTok) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005975 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005976 LOG_BAD_TU(TU);
5977 return clang_getNullRange();
5978 }
5979
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005980 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005981 if (!CXXUnit)
5982 return clang_getNullRange();
5983
5984 return cxloc::translateSourceRange(CXXUnit->getASTContext(),
5985 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
5986}
5987
5988static void getTokens(ASTUnit *CXXUnit, SourceRange Range,
5989 SmallVectorImpl<CXToken> &CXTokens) {
5990 SourceManager &SourceMgr = CXXUnit->getSourceManager();
5991 std::pair<FileID, unsigned> BeginLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005992 = SourceMgr.getDecomposedSpellingLoc(Range.getBegin());
Guy Benyei11169dd2012-12-18 14:30:41 +00005993 std::pair<FileID, unsigned> EndLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005994 = SourceMgr.getDecomposedSpellingLoc(Range.getEnd());
Guy Benyei11169dd2012-12-18 14:30:41 +00005995
5996 // Cannot tokenize across files.
5997 if (BeginLocInfo.first != EndLocInfo.first)
5998 return;
5999
6000 // Create a lexer
6001 bool Invalid = false;
6002 StringRef Buffer
6003 = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
6004 if (Invalid)
6005 return;
6006
6007 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
6008 CXXUnit->getASTContext().getLangOpts(),
6009 Buffer.begin(), Buffer.data() + BeginLocInfo.second, Buffer.end());
6010 Lex.SetCommentRetentionState(true);
6011
6012 // Lex tokens until we hit the end of the range.
6013 const char *EffectiveBufferEnd = Buffer.data() + EndLocInfo.second;
6014 Token Tok;
6015 bool previousWasAt = false;
6016 do {
6017 // Lex the next token
6018 Lex.LexFromRawLexer(Tok);
6019 if (Tok.is(tok::eof))
6020 break;
6021
6022 // Initialize the CXToken.
6023 CXToken CXTok;
6024
6025 // - Common fields
6026 CXTok.int_data[1] = Tok.getLocation().getRawEncoding();
6027 CXTok.int_data[2] = Tok.getLength();
6028 CXTok.int_data[3] = 0;
6029
6030 // - Kind-specific fields
6031 if (Tok.isLiteral()) {
6032 CXTok.int_data[0] = CXToken_Literal;
Dmitri Gribenkof9304482013-01-23 15:56:07 +00006033 CXTok.ptr_data = const_cast<char *>(Tok.getLiteralData());
Guy Benyei11169dd2012-12-18 14:30:41 +00006034 } else if (Tok.is(tok::raw_identifier)) {
6035 // Lookup the identifier to determine whether we have a keyword.
6036 IdentifierInfo *II
6037 = CXXUnit->getPreprocessor().LookUpIdentifierInfo(Tok);
6038
6039 if ((II->getObjCKeywordID() != tok::objc_not_keyword) && previousWasAt) {
6040 CXTok.int_data[0] = CXToken_Keyword;
6041 }
6042 else {
6043 CXTok.int_data[0] = Tok.is(tok::identifier)
6044 ? CXToken_Identifier
6045 : CXToken_Keyword;
6046 }
6047 CXTok.ptr_data = II;
6048 } else if (Tok.is(tok::comment)) {
6049 CXTok.int_data[0] = CXToken_Comment;
Craig Topper69186e72014-06-08 08:38:04 +00006050 CXTok.ptr_data = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006051 } else {
6052 CXTok.int_data[0] = CXToken_Punctuation;
Craig Topper69186e72014-06-08 08:38:04 +00006053 CXTok.ptr_data = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006054 }
6055 CXTokens.push_back(CXTok);
6056 previousWasAt = Tok.is(tok::at);
6057 } while (Lex.getBufferLocation() <= EffectiveBufferEnd);
6058}
6059
6060void clang_tokenize(CXTranslationUnit TU, CXSourceRange Range,
6061 CXToken **Tokens, unsigned *NumTokens) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006062 LOG_FUNC_SECTION {
6063 *Log << TU << ' ' << Range;
6064 }
6065
Guy Benyei11169dd2012-12-18 14:30:41 +00006066 if (Tokens)
Craig Topper69186e72014-06-08 08:38:04 +00006067 *Tokens = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006068 if (NumTokens)
6069 *NumTokens = 0;
6070
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006071 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006072 LOG_BAD_TU(TU);
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00006073 return;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006074 }
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00006075
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006076 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00006077 if (!CXXUnit || !Tokens || !NumTokens)
6078 return;
6079
6080 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
6081
6082 SourceRange R = cxloc::translateCXSourceRange(Range);
6083 if (R.isInvalid())
6084 return;
6085
6086 SmallVector<CXToken, 32> CXTokens;
6087 getTokens(CXXUnit, R, CXTokens);
6088
6089 if (CXTokens.empty())
6090 return;
6091
6092 *Tokens = (CXToken *)malloc(sizeof(CXToken) * CXTokens.size());
6093 memmove(*Tokens, CXTokens.data(), sizeof(CXToken) * CXTokens.size());
6094 *NumTokens = CXTokens.size();
6095}
6096
6097void clang_disposeTokens(CXTranslationUnit TU,
6098 CXToken *Tokens, unsigned NumTokens) {
6099 free(Tokens);
6100}
6101
6102} // end: extern "C"
6103
6104//===----------------------------------------------------------------------===//
6105// Token annotation APIs.
6106//===----------------------------------------------------------------------===//
6107
Guy Benyei11169dd2012-12-18 14:30:41 +00006108static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
6109 CXCursor parent,
6110 CXClientData client_data);
6111static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
6112 CXClientData client_data);
6113
6114namespace {
6115class AnnotateTokensWorker {
Guy Benyei11169dd2012-12-18 14:30:41 +00006116 CXToken *Tokens;
6117 CXCursor *Cursors;
6118 unsigned NumTokens;
6119 unsigned TokIdx;
6120 unsigned PreprocessingTokIdx;
6121 CursorVisitor AnnotateVis;
6122 SourceManager &SrcMgr;
6123 bool HasContextSensitiveKeywords;
6124
6125 struct PostChildrenInfo {
6126 CXCursor Cursor;
6127 SourceRange CursorRange;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00006128 unsigned BeforeReachingCursorIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00006129 unsigned BeforeChildrenTokenIdx;
6130 };
Dmitri Gribenkof8579502013-01-12 19:30:44 +00006131 SmallVector<PostChildrenInfo, 8> PostChildrenInfos;
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00006132
6133 CXToken &getTok(unsigned Idx) {
6134 assert(Idx < NumTokens);
6135 return Tokens[Idx];
6136 }
6137 const CXToken &getTok(unsigned Idx) const {
6138 assert(Idx < NumTokens);
6139 return Tokens[Idx];
6140 }
Guy Benyei11169dd2012-12-18 14:30:41 +00006141 bool MoreTokens() const { return TokIdx < NumTokens; }
6142 unsigned NextToken() const { return TokIdx; }
6143 void AdvanceToken() { ++TokIdx; }
6144 SourceLocation GetTokenLoc(unsigned tokI) {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00006145 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[1]);
Guy Benyei11169dd2012-12-18 14:30:41 +00006146 }
6147 bool isFunctionMacroToken(unsigned tokI) const {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00006148 return getTok(tokI).int_data[3] != 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00006149 }
6150 SourceLocation getFunctionMacroTokenLoc(unsigned tokI) const {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00006151 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[3]);
Guy Benyei11169dd2012-12-18 14:30:41 +00006152 }
6153
6154 void annotateAndAdvanceTokens(CXCursor, RangeComparisonResult, SourceRange);
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00006155 bool annotateAndAdvanceFunctionMacroTokens(CXCursor, RangeComparisonResult,
Guy Benyei11169dd2012-12-18 14:30:41 +00006156 SourceRange);
6157
6158public:
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006159 AnnotateTokensWorker(CXToken *tokens, CXCursor *cursors, unsigned numTokens,
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006160 CXTranslationUnit TU, SourceRange RegionOfInterest)
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006161 : Tokens(tokens), Cursors(cursors),
Guy Benyei11169dd2012-12-18 14:30:41 +00006162 NumTokens(numTokens), TokIdx(0), PreprocessingTokIdx(0),
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006163 AnnotateVis(TU,
Guy Benyei11169dd2012-12-18 14:30:41 +00006164 AnnotateTokensVisitor, this,
6165 /*VisitPreprocessorLast=*/true,
6166 /*VisitIncludedEntities=*/false,
6167 RegionOfInterest,
6168 /*VisitDeclsOnly=*/false,
6169 AnnotateTokensPostChildrenVisitor),
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006170 SrcMgr(cxtu::getASTUnit(TU)->getSourceManager()),
Guy Benyei11169dd2012-12-18 14:30:41 +00006171 HasContextSensitiveKeywords(false) { }
6172
6173 void VisitChildren(CXCursor C) { AnnotateVis.VisitChildren(C); }
6174 enum CXChildVisitResult Visit(CXCursor cursor, CXCursor parent);
6175 bool postVisitChildren(CXCursor cursor);
6176 void AnnotateTokens();
6177
6178 /// \brief Determine whether the annotator saw any cursors that have
6179 /// context-sensitive keywords.
6180 bool hasContextSensitiveKeywords() const {
6181 return HasContextSensitiveKeywords;
6182 }
6183
6184 ~AnnotateTokensWorker() {
6185 assert(PostChildrenInfos.empty());
6186 }
6187};
Alexander Kornienkoab9db512015-06-22 23:07:51 +00006188}
Guy Benyei11169dd2012-12-18 14:30:41 +00006189
6190void AnnotateTokensWorker::AnnotateTokens() {
6191 // Walk the AST within the region of interest, annotating tokens
6192 // along the way.
6193 AnnotateVis.visitFileRegion();
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006194}
Guy Benyei11169dd2012-12-18 14:30:41 +00006195
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006196static inline void updateCursorAnnotation(CXCursor &Cursor,
6197 const CXCursor &updateC) {
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00006198 if (clang_isInvalid(updateC.kind) || !clang_isInvalid(Cursor.kind))
Guy Benyei11169dd2012-12-18 14:30:41 +00006199 return;
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006200 Cursor = updateC;
Guy Benyei11169dd2012-12-18 14:30:41 +00006201}
6202
6203/// \brief It annotates and advances tokens with a cursor until the comparison
6204//// between the cursor location and the source range is the same as
6205/// \arg compResult.
6206///
6207/// Pass RangeBefore to annotate tokens with a cursor until a range is reached.
6208/// Pass RangeOverlap to annotate tokens inside a range.
6209void AnnotateTokensWorker::annotateAndAdvanceTokens(CXCursor updateC,
6210 RangeComparisonResult compResult,
6211 SourceRange range) {
6212 while (MoreTokens()) {
6213 const unsigned I = NextToken();
6214 if (isFunctionMacroToken(I))
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00006215 if (!annotateAndAdvanceFunctionMacroTokens(updateC, compResult, range))
6216 return;
Guy Benyei11169dd2012-12-18 14:30:41 +00006217
6218 SourceLocation TokLoc = GetTokenLoc(I);
6219 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006220 updateCursorAnnotation(Cursors[I], updateC);
Guy Benyei11169dd2012-12-18 14:30:41 +00006221 AdvanceToken();
6222 continue;
6223 }
6224 break;
6225 }
6226}
6227
6228/// \brief Special annotation handling for macro argument tokens.
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00006229/// \returns true if it advanced beyond all macro tokens, false otherwise.
6230bool AnnotateTokensWorker::annotateAndAdvanceFunctionMacroTokens(
Guy Benyei11169dd2012-12-18 14:30:41 +00006231 CXCursor updateC,
6232 RangeComparisonResult compResult,
6233 SourceRange range) {
6234 assert(MoreTokens());
6235 assert(isFunctionMacroToken(NextToken()) &&
6236 "Should be called only for macro arg tokens");
6237
6238 // This works differently than annotateAndAdvanceTokens; because expanded
6239 // macro arguments can have arbitrary translation-unit source order, we do not
6240 // advance the token index one by one until a token fails the range test.
6241 // We only advance once past all of the macro arg tokens if all of them
6242 // pass the range test. If one of them fails we keep the token index pointing
6243 // at the start of the macro arg tokens so that the failing token will be
6244 // annotated by a subsequent annotation try.
6245
6246 bool atLeastOneCompFail = false;
6247
6248 unsigned I = NextToken();
6249 for (; I < NumTokens && isFunctionMacroToken(I); ++I) {
6250 SourceLocation TokLoc = getFunctionMacroTokenLoc(I);
6251 if (TokLoc.isFileID())
6252 continue; // not macro arg token, it's parens or comma.
6253 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
6254 if (clang_isInvalid(clang_getCursorKind(Cursors[I])))
6255 Cursors[I] = updateC;
6256 } else
6257 atLeastOneCompFail = true;
6258 }
6259
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00006260 if (atLeastOneCompFail)
6261 return false;
6262
6263 TokIdx = I; // All of the tokens were handled, advance beyond all of them.
6264 return true;
Guy Benyei11169dd2012-12-18 14:30:41 +00006265}
6266
6267enum CXChildVisitResult
6268AnnotateTokensWorker::Visit(CXCursor cursor, CXCursor parent) {
Guy Benyei11169dd2012-12-18 14:30:41 +00006269 SourceRange cursorRange = getRawCursorExtent(cursor);
6270 if (cursorRange.isInvalid())
6271 return CXChildVisit_Recurse;
6272
6273 if (!HasContextSensitiveKeywords) {
6274 // Objective-C properties can have context-sensitive keywords.
6275 if (cursor.kind == CXCursor_ObjCPropertyDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006276 if (const ObjCPropertyDecl *Property
Guy Benyei11169dd2012-12-18 14:30:41 +00006277 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(cursor)))
6278 HasContextSensitiveKeywords = Property->getPropertyAttributesAsWritten() != 0;
6279 }
6280 // Objective-C methods can have context-sensitive keywords.
6281 else if (cursor.kind == CXCursor_ObjCInstanceMethodDecl ||
6282 cursor.kind == CXCursor_ObjCClassMethodDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006283 if (const ObjCMethodDecl *Method
Guy Benyei11169dd2012-12-18 14:30:41 +00006284 = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
6285 if (Method->getObjCDeclQualifier())
6286 HasContextSensitiveKeywords = true;
6287 else {
Aaron Ballman43b68be2014-03-07 17:50:17 +00006288 for (const auto *P : Method->params()) {
6289 if (P->getObjCDeclQualifier()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00006290 HasContextSensitiveKeywords = true;
6291 break;
6292 }
6293 }
6294 }
6295 }
6296 }
6297 // C++ methods can have context-sensitive keywords.
6298 else if (cursor.kind == CXCursor_CXXMethod) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006299 if (const CXXMethodDecl *Method
Guy Benyei11169dd2012-12-18 14:30:41 +00006300 = dyn_cast_or_null<CXXMethodDecl>(getCursorDecl(cursor))) {
6301 if (Method->hasAttr<FinalAttr>() || Method->hasAttr<OverrideAttr>())
6302 HasContextSensitiveKeywords = true;
6303 }
6304 }
6305 // C++ classes can have context-sensitive keywords.
6306 else if (cursor.kind == CXCursor_StructDecl ||
6307 cursor.kind == CXCursor_ClassDecl ||
6308 cursor.kind == CXCursor_ClassTemplate ||
6309 cursor.kind == CXCursor_ClassTemplatePartialSpecialization) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006310 if (const Decl *D = getCursorDecl(cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +00006311 if (D->hasAttr<FinalAttr>())
6312 HasContextSensitiveKeywords = true;
6313 }
6314 }
Argyrios Kyrtzidis990b3862013-06-04 18:24:30 +00006315
6316 // Don't override a property annotation with its getter/setter method.
6317 if (cursor.kind == CXCursor_ObjCInstanceMethodDecl &&
6318 parent.kind == CXCursor_ObjCPropertyDecl)
6319 return CXChildVisit_Continue;
Guy Benyei11169dd2012-12-18 14:30:41 +00006320
6321 if (clang_isPreprocessing(cursor.kind)) {
6322 // Items in the preprocessing record are kept separate from items in
6323 // declarations, so we keep a separate token index.
6324 unsigned SavedTokIdx = TokIdx;
6325 TokIdx = PreprocessingTokIdx;
6326
6327 // Skip tokens up until we catch up to the beginning of the preprocessing
6328 // entry.
6329 while (MoreTokens()) {
6330 const unsigned I = NextToken();
6331 SourceLocation TokLoc = GetTokenLoc(I);
6332 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
6333 case RangeBefore:
6334 AdvanceToken();
6335 continue;
6336 case RangeAfter:
6337 case RangeOverlap:
6338 break;
6339 }
6340 break;
6341 }
6342
6343 // Look at all of the tokens within this range.
6344 while (MoreTokens()) {
6345 const unsigned I = NextToken();
6346 SourceLocation TokLoc = GetTokenLoc(I);
6347 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
6348 case RangeBefore:
6349 llvm_unreachable("Infeasible");
6350 case RangeAfter:
6351 break;
6352 case RangeOverlap:
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00006353 // For macro expansions, just note where the beginning of the macro
6354 // expansion occurs.
6355 if (cursor.kind == CXCursor_MacroExpansion) {
6356 if (TokLoc == cursorRange.getBegin())
6357 Cursors[I] = cursor;
6358 AdvanceToken();
6359 break;
6360 }
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006361 // We may have already annotated macro names inside macro definitions.
6362 if (Cursors[I].kind != CXCursor_MacroExpansion)
6363 Cursors[I] = cursor;
Guy Benyei11169dd2012-12-18 14:30:41 +00006364 AdvanceToken();
Guy Benyei11169dd2012-12-18 14:30:41 +00006365 continue;
6366 }
6367 break;
6368 }
6369
6370 // Save the preprocessing token index; restore the non-preprocessing
6371 // token index.
6372 PreprocessingTokIdx = TokIdx;
6373 TokIdx = SavedTokIdx;
6374 return CXChildVisit_Recurse;
6375 }
6376
6377 if (cursorRange.isInvalid())
6378 return CXChildVisit_Continue;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00006379
6380 unsigned BeforeReachingCursorIdx = NextToken();
Guy Benyei11169dd2012-12-18 14:30:41 +00006381 const enum CXCursorKind cursorK = clang_getCursorKind(cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00006382 const enum CXCursorKind K = clang_getCursorKind(parent);
6383 const CXCursor updateC =
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00006384 (clang_isInvalid(K) || K == CXCursor_TranslationUnit ||
6385 // Attributes are annotated out-of-order, skip tokens until we reach it.
6386 clang_isAttribute(cursor.kind))
Guy Benyei11169dd2012-12-18 14:30:41 +00006387 ? clang_getNullCursor() : parent;
6388
6389 annotateAndAdvanceTokens(updateC, RangeBefore, cursorRange);
6390
6391 // Avoid having the cursor of an expression "overwrite" the annotation of the
6392 // variable declaration that it belongs to.
6393 // This can happen for C++ constructor expressions whose range generally
6394 // include the variable declaration, e.g.:
6395 // MyCXXClass foo; // Make sure we don't annotate 'foo' as a CallExpr cursor.
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00006396 if (clang_isExpression(cursorK) && MoreTokens()) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00006397 const Expr *E = getCursorExpr(cursor);
Dmitri Gribenkoa1691182013-01-26 18:12:08 +00006398 if (const Decl *D = getCursorParentDecl(cursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00006399 const unsigned I = NextToken();
6400 if (E->getLocStart().isValid() && D->getLocation().isValid() &&
6401 E->getLocStart() == D->getLocation() &&
6402 E->getLocStart() == GetTokenLoc(I)) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006403 updateCursorAnnotation(Cursors[I], updateC);
Guy Benyei11169dd2012-12-18 14:30:41 +00006404 AdvanceToken();
6405 }
6406 }
6407 }
6408
6409 // Before recursing into the children keep some state that we are going
6410 // to use in the AnnotateTokensWorker::postVisitChildren callback to do some
6411 // extra work after the child nodes are visited.
6412 // Note that we don't call VisitChildren here to avoid traversing statements
6413 // code-recursively which can blow the stack.
6414
6415 PostChildrenInfo Info;
6416 Info.Cursor = cursor;
6417 Info.CursorRange = cursorRange;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00006418 Info.BeforeReachingCursorIdx = BeforeReachingCursorIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00006419 Info.BeforeChildrenTokenIdx = NextToken();
6420 PostChildrenInfos.push_back(Info);
6421
6422 return CXChildVisit_Recurse;
6423}
6424
6425bool AnnotateTokensWorker::postVisitChildren(CXCursor cursor) {
6426 if (PostChildrenInfos.empty())
6427 return false;
6428 const PostChildrenInfo &Info = PostChildrenInfos.back();
6429 if (!clang_equalCursors(Info.Cursor, cursor))
6430 return false;
6431
6432 const unsigned BeforeChildren = Info.BeforeChildrenTokenIdx;
6433 const unsigned AfterChildren = NextToken();
6434 SourceRange cursorRange = Info.CursorRange;
6435
6436 // Scan the tokens that are at the end of the cursor, but are not captured
6437 // but the child cursors.
6438 annotateAndAdvanceTokens(cursor, RangeOverlap, cursorRange);
6439
6440 // Scan the tokens that are at the beginning of the cursor, but are not
6441 // capture by the child cursors.
6442 for (unsigned I = BeforeChildren; I != AfterChildren; ++I) {
6443 if (!clang_isInvalid(clang_getCursorKind(Cursors[I])))
6444 break;
6445
6446 Cursors[I] = cursor;
6447 }
6448
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00006449 // Attributes are annotated out-of-order, rewind TokIdx to when we first
6450 // encountered the attribute cursor.
6451 if (clang_isAttribute(cursor.kind))
6452 TokIdx = Info.BeforeReachingCursorIdx;
6453
Guy Benyei11169dd2012-12-18 14:30:41 +00006454 PostChildrenInfos.pop_back();
6455 return false;
6456}
6457
6458static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
6459 CXCursor parent,
6460 CXClientData client_data) {
6461 return static_cast<AnnotateTokensWorker*>(client_data)->Visit(cursor, parent);
6462}
6463
6464static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
6465 CXClientData client_data) {
6466 return static_cast<AnnotateTokensWorker*>(client_data)->
6467 postVisitChildren(cursor);
6468}
6469
6470namespace {
6471
6472/// \brief Uses the macro expansions in the preprocessing record to find
6473/// and mark tokens that are macro arguments. This info is used by the
6474/// AnnotateTokensWorker.
6475class MarkMacroArgTokensVisitor {
6476 SourceManager &SM;
6477 CXToken *Tokens;
6478 unsigned NumTokens;
6479 unsigned CurIdx;
6480
6481public:
6482 MarkMacroArgTokensVisitor(SourceManager &SM,
6483 CXToken *tokens, unsigned numTokens)
6484 : SM(SM), Tokens(tokens), NumTokens(numTokens), CurIdx(0) { }
6485
6486 CXChildVisitResult visit(CXCursor cursor, CXCursor parent) {
6487 if (cursor.kind != CXCursor_MacroExpansion)
6488 return CXChildVisit_Continue;
6489
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006490 SourceRange macroRange = getCursorMacroExpansion(cursor).getSourceRange();
Guy Benyei11169dd2012-12-18 14:30:41 +00006491 if (macroRange.getBegin() == macroRange.getEnd())
6492 return CXChildVisit_Continue; // it's not a function macro.
6493
6494 for (; CurIdx < NumTokens; ++CurIdx) {
6495 if (!SM.isBeforeInTranslationUnit(getTokenLoc(CurIdx),
6496 macroRange.getBegin()))
6497 break;
6498 }
6499
6500 if (CurIdx == NumTokens)
6501 return CXChildVisit_Break;
6502
6503 for (; CurIdx < NumTokens; ++CurIdx) {
6504 SourceLocation tokLoc = getTokenLoc(CurIdx);
6505 if (!SM.isBeforeInTranslationUnit(tokLoc, macroRange.getEnd()))
6506 break;
6507
6508 setFunctionMacroTokenLoc(CurIdx, SM.getMacroArgExpandedLocation(tokLoc));
6509 }
6510
6511 if (CurIdx == NumTokens)
6512 return CXChildVisit_Break;
6513
6514 return CXChildVisit_Continue;
6515 }
6516
6517private:
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00006518 CXToken &getTok(unsigned Idx) {
6519 assert(Idx < NumTokens);
6520 return Tokens[Idx];
6521 }
6522 const CXToken &getTok(unsigned Idx) const {
6523 assert(Idx < NumTokens);
6524 return Tokens[Idx];
6525 }
6526
Guy Benyei11169dd2012-12-18 14:30:41 +00006527 SourceLocation getTokenLoc(unsigned tokI) {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00006528 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[1]);
Guy Benyei11169dd2012-12-18 14:30:41 +00006529 }
6530
6531 void setFunctionMacroTokenLoc(unsigned tokI, SourceLocation loc) {
6532 // The third field is reserved and currently not used. Use it here
6533 // to mark macro arg expanded tokens with their expanded locations.
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00006534 getTok(tokI).int_data[3] = loc.getRawEncoding();
Guy Benyei11169dd2012-12-18 14:30:41 +00006535 }
6536};
6537
6538} // end anonymous namespace
6539
6540static CXChildVisitResult
6541MarkMacroArgTokensVisitorDelegate(CXCursor cursor, CXCursor parent,
6542 CXClientData client_data) {
6543 return static_cast<MarkMacroArgTokensVisitor*>(client_data)->visit(cursor,
6544 parent);
6545}
6546
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006547/// \brief Used by \c annotatePreprocessorTokens.
6548/// \returns true if lexing was finished, false otherwise.
6549static bool lexNext(Lexer &Lex, Token &Tok,
6550 unsigned &NextIdx, unsigned NumTokens) {
6551 if (NextIdx >= NumTokens)
6552 return true;
6553
6554 ++NextIdx;
6555 Lex.LexFromRawLexer(Tok);
Alexander Kornienko1a9f1842015-12-28 15:24:08 +00006556 return Tok.is(tok::eof);
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006557}
6558
Guy Benyei11169dd2012-12-18 14:30:41 +00006559static void annotatePreprocessorTokens(CXTranslationUnit TU,
6560 SourceRange RegionOfInterest,
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006561 CXCursor *Cursors,
6562 CXToken *Tokens,
6563 unsigned NumTokens) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006564 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00006565
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006566 Preprocessor &PP = CXXUnit->getPreprocessor();
Guy Benyei11169dd2012-12-18 14:30:41 +00006567 SourceManager &SourceMgr = CXXUnit->getSourceManager();
6568 std::pair<FileID, unsigned> BeginLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00006569 = SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getBegin());
Guy Benyei11169dd2012-12-18 14:30:41 +00006570 std::pair<FileID, unsigned> EndLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00006571 = SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getEnd());
Guy Benyei11169dd2012-12-18 14:30:41 +00006572
6573 if (BeginLocInfo.first != EndLocInfo.first)
6574 return;
6575
6576 StringRef Buffer;
6577 bool Invalid = false;
6578 Buffer = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
6579 if (Buffer.empty() || Invalid)
6580 return;
6581
6582 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
6583 CXXUnit->getASTContext().getLangOpts(),
6584 Buffer.begin(), Buffer.data() + BeginLocInfo.second,
6585 Buffer.end());
6586 Lex.SetCommentRetentionState(true);
6587
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006588 unsigned NextIdx = 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00006589 // Lex tokens in raw mode until we hit the end of the range, to avoid
6590 // entering #includes or expanding macros.
6591 while (true) {
6592 Token Tok;
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006593 if (lexNext(Lex, Tok, NextIdx, NumTokens))
6594 break;
6595 unsigned TokIdx = NextIdx-1;
6596 assert(Tok.getLocation() ==
6597 SourceLocation::getFromRawEncoding(Tokens[TokIdx].int_data[1]));
Guy Benyei11169dd2012-12-18 14:30:41 +00006598
6599 reprocess:
6600 if (Tok.is(tok::hash) && Tok.isAtStartOfLine()) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006601 // We have found a preprocessing directive. Annotate the tokens
6602 // appropriately.
Guy Benyei11169dd2012-12-18 14:30:41 +00006603 //
6604 // FIXME: Some simple tests here could identify macro definitions and
6605 // #undefs, to provide specific cursor kinds for those.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006606
6607 SourceLocation BeginLoc = Tok.getLocation();
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006608 if (lexNext(Lex, Tok, NextIdx, NumTokens))
6609 break;
6610
Craig Topper69186e72014-06-08 08:38:04 +00006611 MacroInfo *MI = nullptr;
Alp Toker2d57cea2014-05-17 04:53:25 +00006612 if (Tok.is(tok::raw_identifier) && Tok.getRawIdentifier() == "define") {
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006613 if (lexNext(Lex, Tok, NextIdx, NumTokens))
6614 break;
6615
6616 if (Tok.is(tok::raw_identifier)) {
Alp Toker2d57cea2014-05-17 04:53:25 +00006617 IdentifierInfo &II =
6618 PP.getIdentifierTable().get(Tok.getRawIdentifier());
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006619 SourceLocation MappedTokLoc =
6620 CXXUnit->mapLocationToPreamble(Tok.getLocation());
6621 MI = getMacroInfo(II, MappedTokLoc, TU);
6622 }
6623 }
6624
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006625 bool finished = false;
Guy Benyei11169dd2012-12-18 14:30:41 +00006626 do {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006627 if (lexNext(Lex, Tok, NextIdx, NumTokens)) {
6628 finished = true;
6629 break;
6630 }
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006631 // If we are in a macro definition, check if the token was ever a
6632 // macro name and annotate it if that's the case.
6633 if (MI) {
6634 SourceLocation SaveLoc = Tok.getLocation();
6635 Tok.setLocation(CXXUnit->mapLocationToPreamble(SaveLoc));
Richard Smith66a81862015-05-04 02:25:31 +00006636 MacroDefinitionRecord *MacroDef =
6637 checkForMacroInMacroDefinition(MI, Tok, TU);
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006638 Tok.setLocation(SaveLoc);
6639 if (MacroDef)
Richard Smith66a81862015-05-04 02:25:31 +00006640 Cursors[NextIdx - 1] =
6641 MakeMacroExpansionCursor(MacroDef, Tok.getLocation(), TU);
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006642 }
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006643 } while (!Tok.isAtStartOfLine());
6644
6645 unsigned LastIdx = finished ? NextIdx-1 : NextIdx-2;
6646 assert(TokIdx <= LastIdx);
6647 SourceLocation EndLoc =
6648 SourceLocation::getFromRawEncoding(Tokens[LastIdx].int_data[1]);
6649 CXCursor Cursor =
6650 MakePreprocessingDirectiveCursor(SourceRange(BeginLoc, EndLoc), TU);
6651
6652 for (; TokIdx <= LastIdx; ++TokIdx)
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006653 updateCursorAnnotation(Cursors[TokIdx], Cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00006654
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006655 if (finished)
6656 break;
6657 goto reprocess;
Guy Benyei11169dd2012-12-18 14:30:41 +00006658 }
Guy Benyei11169dd2012-12-18 14:30:41 +00006659 }
6660}
6661
6662// This gets run a separate thread to avoid stack blowout.
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00006663static void clang_annotateTokensImpl(CXTranslationUnit TU, ASTUnit *CXXUnit,
6664 CXToken *Tokens, unsigned NumTokens,
6665 CXCursor *Cursors) {
Dmitri Gribenko183436e2013-01-26 21:49:50 +00006666 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00006667 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
6668 setThreadBackgroundPriority();
6669
6670 // Determine the region of interest, which contains all of the tokens.
6671 SourceRange RegionOfInterest;
6672 RegionOfInterest.setBegin(
6673 cxloc::translateSourceLocation(clang_getTokenLocation(TU, Tokens[0])));
6674 RegionOfInterest.setEnd(
6675 cxloc::translateSourceLocation(clang_getTokenLocation(TU,
6676 Tokens[NumTokens-1])));
6677
Guy Benyei11169dd2012-12-18 14:30:41 +00006678 // Relex the tokens within the source range to look for preprocessing
6679 // directives.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006680 annotatePreprocessorTokens(TU, RegionOfInterest, Cursors, Tokens, NumTokens);
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00006681
6682 // If begin location points inside a macro argument, set it to the expansion
6683 // location so we can have the full context when annotating semantically.
6684 {
6685 SourceManager &SM = CXXUnit->getSourceManager();
6686 SourceLocation Loc =
6687 SM.getMacroArgExpandedLocation(RegionOfInterest.getBegin());
6688 if (Loc.isMacroID())
6689 RegionOfInterest.setBegin(SM.getExpansionLoc(Loc));
6690 }
6691
Guy Benyei11169dd2012-12-18 14:30:41 +00006692 if (CXXUnit->getPreprocessor().getPreprocessingRecord()) {
6693 // Search and mark tokens that are macro argument expansions.
6694 MarkMacroArgTokensVisitor Visitor(CXXUnit->getSourceManager(),
6695 Tokens, NumTokens);
6696 CursorVisitor MacroArgMarker(TU,
6697 MarkMacroArgTokensVisitorDelegate, &Visitor,
6698 /*VisitPreprocessorLast=*/true,
6699 /*VisitIncludedEntities=*/false,
6700 RegionOfInterest);
6701 MacroArgMarker.visitPreprocessedEntitiesInRegion();
6702 }
6703
6704 // Annotate all of the source locations in the region of interest that map to
6705 // a specific cursor.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006706 AnnotateTokensWorker W(Tokens, Cursors, NumTokens, TU, RegionOfInterest);
Guy Benyei11169dd2012-12-18 14:30:41 +00006707
6708 // FIXME: We use a ridiculous stack size here because the data-recursion
6709 // algorithm uses a large stack frame than the non-data recursive version,
6710 // and AnnotationTokensWorker currently transforms the data-recursion
6711 // algorithm back into a traditional recursion by explicitly calling
6712 // VisitChildren(). We will need to remove this explicit recursive call.
6713 W.AnnotateTokens();
6714
6715 // If we ran into any entities that involve context-sensitive keywords,
6716 // take another pass through the tokens to mark them as such.
6717 if (W.hasContextSensitiveKeywords()) {
6718 for (unsigned I = 0; I != NumTokens; ++I) {
6719 if (clang_getTokenKind(Tokens[I]) != CXToken_Identifier)
6720 continue;
6721
6722 if (Cursors[I].kind == CXCursor_ObjCPropertyDecl) {
6723 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006724 if (const ObjCPropertyDecl *Property
Guy Benyei11169dd2012-12-18 14:30:41 +00006725 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(Cursors[I]))) {
6726 if (Property->getPropertyAttributesAsWritten() != 0 &&
6727 llvm::StringSwitch<bool>(II->getName())
6728 .Case("readonly", true)
6729 .Case("assign", true)
6730 .Case("unsafe_unretained", true)
6731 .Case("readwrite", true)
6732 .Case("retain", true)
6733 .Case("copy", true)
6734 .Case("nonatomic", true)
6735 .Case("atomic", true)
6736 .Case("getter", true)
6737 .Case("setter", true)
6738 .Case("strong", true)
6739 .Case("weak", true)
6740 .Default(false))
6741 Tokens[I].int_data[0] = CXToken_Keyword;
6742 }
6743 continue;
6744 }
6745
6746 if (Cursors[I].kind == CXCursor_ObjCInstanceMethodDecl ||
6747 Cursors[I].kind == CXCursor_ObjCClassMethodDecl) {
6748 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
6749 if (llvm::StringSwitch<bool>(II->getName())
6750 .Case("in", true)
6751 .Case("out", true)
6752 .Case("inout", true)
6753 .Case("oneway", true)
6754 .Case("bycopy", true)
6755 .Case("byref", true)
6756 .Default(false))
6757 Tokens[I].int_data[0] = CXToken_Keyword;
6758 continue;
6759 }
6760
6761 if (Cursors[I].kind == CXCursor_CXXFinalAttr ||
6762 Cursors[I].kind == CXCursor_CXXOverrideAttr) {
6763 Tokens[I].int_data[0] = CXToken_Keyword;
6764 continue;
6765 }
6766 }
6767 }
6768}
6769
6770extern "C" {
6771
6772void clang_annotateTokens(CXTranslationUnit TU,
6773 CXToken *Tokens, unsigned NumTokens,
6774 CXCursor *Cursors) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006775 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006776 LOG_BAD_TU(TU);
6777 return;
6778 }
6779 if (NumTokens == 0 || !Tokens || !Cursors) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006780 LOG_FUNC_SECTION { *Log << "<null input>"; }
Guy Benyei11169dd2012-12-18 14:30:41 +00006781 return;
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006782 }
6783
6784 LOG_FUNC_SECTION {
6785 *Log << TU << ' ';
6786 CXSourceLocation bloc = clang_getTokenLocation(TU, Tokens[0]);
6787 CXSourceLocation eloc = clang_getTokenLocation(TU, Tokens[NumTokens-1]);
6788 *Log << clang_getRange(bloc, eloc);
6789 }
Guy Benyei11169dd2012-12-18 14:30:41 +00006790
6791 // Any token we don't specifically annotate will have a NULL cursor.
6792 CXCursor C = clang_getNullCursor();
6793 for (unsigned I = 0; I != NumTokens; ++I)
6794 Cursors[I] = C;
6795
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006796 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00006797 if (!CXXUnit)
6798 return;
6799
6800 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00006801
6802 auto AnnotateTokensImpl = [=]() {
6803 clang_annotateTokensImpl(TU, CXXUnit, Tokens, NumTokens, Cursors);
6804 };
Guy Benyei11169dd2012-12-18 14:30:41 +00006805 llvm::CrashRecoveryContext CRC;
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00006806 if (!RunSafely(CRC, AnnotateTokensImpl, GetSafetyThreadStackSize() * 2)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00006807 fprintf(stderr, "libclang: crash detected while annotating tokens\n");
6808 }
6809}
6810
6811} // end: extern "C"
6812
6813//===----------------------------------------------------------------------===//
6814// Operations for querying linkage of a cursor.
6815//===----------------------------------------------------------------------===//
6816
6817extern "C" {
6818CXLinkageKind clang_getCursorLinkage(CXCursor cursor) {
6819 if (!clang_isDeclaration(cursor.kind))
6820 return CXLinkage_Invalid;
6821
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006822 const Decl *D = cxcursor::getCursorDecl(cursor);
6823 if (const NamedDecl *ND = dyn_cast_or_null<NamedDecl>(D))
Rafael Espindola3ae00052013-05-13 00:12:11 +00006824 switch (ND->getLinkageInternal()) {
Rafael Espindola50df3a02013-05-25 17:16:20 +00006825 case NoLinkage:
6826 case VisibleNoLinkage: return CXLinkage_NoLinkage;
Guy Benyei11169dd2012-12-18 14:30:41 +00006827 case InternalLinkage: return CXLinkage_Internal;
6828 case UniqueExternalLinkage: return CXLinkage_UniqueExternal;
6829 case ExternalLinkage: return CXLinkage_External;
6830 };
6831
6832 return CXLinkage_Invalid;
6833}
6834} // end: extern "C"
6835
6836//===----------------------------------------------------------------------===//
Ehsan Akhgari93697fa2015-11-23 19:56:46 +00006837// Operations for querying visibility of a cursor.
6838//===----------------------------------------------------------------------===//
6839
6840extern "C" {
6841CXVisibilityKind clang_getCursorVisibility(CXCursor cursor) {
6842 if (!clang_isDeclaration(cursor.kind))
6843 return CXVisibility_Invalid;
6844
6845 const Decl *D = cxcursor::getCursorDecl(cursor);
6846 if (const NamedDecl *ND = dyn_cast_or_null<NamedDecl>(D))
6847 switch (ND->getVisibility()) {
6848 case HiddenVisibility: return CXVisibility_Hidden;
6849 case ProtectedVisibility: return CXVisibility_Protected;
6850 case DefaultVisibility: return CXVisibility_Default;
6851 };
6852
6853 return CXVisibility_Invalid;
6854}
6855} // end: extern "C"
6856
6857//===----------------------------------------------------------------------===//
Guy Benyei11169dd2012-12-18 14:30:41 +00006858// Operations for querying language of a cursor.
6859//===----------------------------------------------------------------------===//
6860
6861static CXLanguageKind getDeclLanguage(const Decl *D) {
6862 if (!D)
6863 return CXLanguage_C;
6864
6865 switch (D->getKind()) {
6866 default:
6867 break;
6868 case Decl::ImplicitParam:
6869 case Decl::ObjCAtDefsField:
6870 case Decl::ObjCCategory:
6871 case Decl::ObjCCategoryImpl:
6872 case Decl::ObjCCompatibleAlias:
6873 case Decl::ObjCImplementation:
6874 case Decl::ObjCInterface:
6875 case Decl::ObjCIvar:
6876 case Decl::ObjCMethod:
6877 case Decl::ObjCProperty:
6878 case Decl::ObjCPropertyImpl:
6879 case Decl::ObjCProtocol:
Douglas Gregor85f3f952015-07-07 03:57:15 +00006880 case Decl::ObjCTypeParam:
Guy Benyei11169dd2012-12-18 14:30:41 +00006881 return CXLanguage_ObjC;
6882 case Decl::CXXConstructor:
6883 case Decl::CXXConversion:
6884 case Decl::CXXDestructor:
6885 case Decl::CXXMethod:
6886 case Decl::CXXRecord:
6887 case Decl::ClassTemplate:
6888 case Decl::ClassTemplatePartialSpecialization:
6889 case Decl::ClassTemplateSpecialization:
6890 case Decl::Friend:
6891 case Decl::FriendTemplate:
6892 case Decl::FunctionTemplate:
6893 case Decl::LinkageSpec:
6894 case Decl::Namespace:
6895 case Decl::NamespaceAlias:
6896 case Decl::NonTypeTemplateParm:
6897 case Decl::StaticAssert:
6898 case Decl::TemplateTemplateParm:
6899 case Decl::TemplateTypeParm:
6900 case Decl::UnresolvedUsingTypename:
6901 case Decl::UnresolvedUsingValue:
6902 case Decl::Using:
6903 case Decl::UsingDirective:
6904 case Decl::UsingShadow:
6905 return CXLanguage_CPlusPlus;
6906 }
6907
6908 return CXLanguage_C;
6909}
6910
6911extern "C" {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006912
6913static CXAvailabilityKind getCursorAvailabilityForDecl(const Decl *D) {
6914 if (isa<FunctionDecl>(D) && cast<FunctionDecl>(D)->isDeleted())
Manuel Klimek8e3a7ed2015-09-25 17:53:16 +00006915 return CXAvailability_NotAvailable;
Guy Benyei11169dd2012-12-18 14:30:41 +00006916
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006917 switch (D->getAvailability()) {
6918 case AR_Available:
6919 case AR_NotYetIntroduced:
6920 if (const EnumConstantDecl *EnumConst = dyn_cast<EnumConstantDecl>(D))
Benjamin Kramer656363d2013-10-15 18:53:18 +00006921 return getCursorAvailabilityForDecl(
6922 cast<Decl>(EnumConst->getDeclContext()));
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006923 return CXAvailability_Available;
6924
6925 case AR_Deprecated:
6926 return CXAvailability_Deprecated;
6927
6928 case AR_Unavailable:
6929 return CXAvailability_NotAvailable;
6930 }
Benjamin Kramer656363d2013-10-15 18:53:18 +00006931
6932 llvm_unreachable("Unknown availability kind!");
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006933}
6934
Guy Benyei11169dd2012-12-18 14:30:41 +00006935enum CXAvailabilityKind clang_getCursorAvailability(CXCursor cursor) {
6936 if (clang_isDeclaration(cursor.kind))
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006937 if (const Decl *D = cxcursor::getCursorDecl(cursor))
6938 return getCursorAvailabilityForDecl(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00006939
6940 return CXAvailability_Available;
6941}
6942
6943static CXVersion convertVersion(VersionTuple In) {
6944 CXVersion Out = { -1, -1, -1 };
6945 if (In.empty())
6946 return Out;
6947
6948 Out.Major = In.getMajor();
6949
NAKAMURA Takumic2b5d1f2013-02-21 02:32:34 +00006950 Optional<unsigned> Minor = In.getMinor();
6951 if (Minor.hasValue())
Guy Benyei11169dd2012-12-18 14:30:41 +00006952 Out.Minor = *Minor;
6953 else
6954 return Out;
6955
NAKAMURA Takumic2b5d1f2013-02-21 02:32:34 +00006956 Optional<unsigned> Subminor = In.getSubminor();
6957 if (Subminor.hasValue())
Guy Benyei11169dd2012-12-18 14:30:41 +00006958 Out.Subminor = *Subminor;
6959
6960 return Out;
6961}
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006962
6963static int getCursorPlatformAvailabilityForDecl(const Decl *D,
6964 int *always_deprecated,
6965 CXString *deprecated_message,
6966 int *always_unavailable,
6967 CXString *unavailable_message,
6968 CXPlatformAvailability *availability,
6969 int availability_size) {
6970 bool HadAvailAttr = false;
6971 int N = 0;
Aaron Ballmanb97112e2014-03-08 22:19:01 +00006972 for (auto A : D->attrs()) {
6973 if (DeprecatedAttr *Deprecated = dyn_cast<DeprecatedAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006974 HadAvailAttr = true;
6975 if (always_deprecated)
6976 *always_deprecated = 1;
Nico Weberaacf0312014-04-24 05:16:45 +00006977 if (deprecated_message) {
Argyrios Kyrtzidisedfe07f2014-04-24 06:05:40 +00006978 clang_disposeString(*deprecated_message);
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006979 *deprecated_message = cxstring::createDup(Deprecated->getMessage());
Nico Weberaacf0312014-04-24 05:16:45 +00006980 }
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006981 continue;
6982 }
6983
Aaron Ballmanb97112e2014-03-08 22:19:01 +00006984 if (UnavailableAttr *Unavailable = dyn_cast<UnavailableAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006985 HadAvailAttr = true;
6986 if (always_unavailable)
6987 *always_unavailable = 1;
6988 if (unavailable_message) {
Argyrios Kyrtzidisedfe07f2014-04-24 06:05:40 +00006989 clang_disposeString(*unavailable_message);
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006990 *unavailable_message = cxstring::createDup(Unavailable->getMessage());
6991 }
6992 continue;
6993 }
6994
Aaron Ballmanb97112e2014-03-08 22:19:01 +00006995 if (AvailabilityAttr *Avail = dyn_cast<AvailabilityAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006996 HadAvailAttr = true;
6997 if (N < availability_size) {
6998 availability[N].Platform
6999 = cxstring::createDup(Avail->getPlatform()->getName());
7000 availability[N].Introduced = convertVersion(Avail->getIntroduced());
7001 availability[N].Deprecated = convertVersion(Avail->getDeprecated());
7002 availability[N].Obsoleted = convertVersion(Avail->getObsoleted());
7003 availability[N].Unavailable = Avail->getUnavailable();
7004 availability[N].Message = cxstring::createDup(Avail->getMessage());
7005 }
7006 ++N;
7007 }
7008 }
7009
7010 if (!HadAvailAttr)
7011 if (const EnumConstantDecl *EnumConst = dyn_cast<EnumConstantDecl>(D))
7012 return getCursorPlatformAvailabilityForDecl(
7013 cast<Decl>(EnumConst->getDeclContext()),
7014 always_deprecated,
7015 deprecated_message,
7016 always_unavailable,
7017 unavailable_message,
7018 availability,
7019 availability_size);
Guy Benyei11169dd2012-12-18 14:30:41 +00007020
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00007021 return N;
7022}
7023
Guy Benyei11169dd2012-12-18 14:30:41 +00007024int clang_getCursorPlatformAvailability(CXCursor cursor,
7025 int *always_deprecated,
7026 CXString *deprecated_message,
7027 int *always_unavailable,
7028 CXString *unavailable_message,
7029 CXPlatformAvailability *availability,
7030 int availability_size) {
7031 if (always_deprecated)
7032 *always_deprecated = 0;
7033 if (deprecated_message)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00007034 *deprecated_message = cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00007035 if (always_unavailable)
7036 *always_unavailable = 0;
7037 if (unavailable_message)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00007038 *unavailable_message = cxstring::createEmpty();
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00007039
Guy Benyei11169dd2012-12-18 14:30:41 +00007040 if (!clang_isDeclaration(cursor.kind))
7041 return 0;
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00007042
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00007043 const Decl *D = cxcursor::getCursorDecl(cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00007044 if (!D)
7045 return 0;
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00007046
7047 return getCursorPlatformAvailabilityForDecl(D, always_deprecated,
7048 deprecated_message,
7049 always_unavailable,
7050 unavailable_message,
7051 availability,
7052 availability_size);
Guy Benyei11169dd2012-12-18 14:30:41 +00007053}
7054
7055void clang_disposeCXPlatformAvailability(CXPlatformAvailability *availability) {
7056 clang_disposeString(availability->Platform);
7057 clang_disposeString(availability->Message);
7058}
7059
7060CXLanguageKind clang_getCursorLanguage(CXCursor cursor) {
7061 if (clang_isDeclaration(cursor.kind))
7062 return getDeclLanguage(cxcursor::getCursorDecl(cursor));
7063
7064 return CXLanguage_Invalid;
7065}
7066
7067 /// \brief If the given cursor is the "templated" declaration
7068 /// descibing a class or function template, return the class or
7069 /// function template.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00007070static const Decl *maybeGetTemplateCursor(const Decl *D) {
Guy Benyei11169dd2012-12-18 14:30:41 +00007071 if (!D)
Craig Topper69186e72014-06-08 08:38:04 +00007072 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00007073
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00007074 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00007075 if (FunctionTemplateDecl *FunTmpl = FD->getDescribedFunctionTemplate())
7076 return FunTmpl;
7077
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00007078 if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00007079 if (ClassTemplateDecl *ClassTmpl = RD->getDescribedClassTemplate())
7080 return ClassTmpl;
7081
7082 return D;
7083}
7084
Argyrios Kyrtzidis4e0854f2014-10-15 17:05:31 +00007085
7086enum CX_StorageClass clang_Cursor_getStorageClass(CXCursor C) {
7087 StorageClass sc = SC_None;
7088 const Decl *D = getCursorDecl(C);
7089 if (D) {
7090 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
7091 sc = FD->getStorageClass();
7092 } else if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
7093 sc = VD->getStorageClass();
7094 } else {
7095 return CX_SC_Invalid;
7096 }
7097 } else {
7098 return CX_SC_Invalid;
7099 }
7100 switch (sc) {
7101 case SC_None:
7102 return CX_SC_None;
7103 case SC_Extern:
7104 return CX_SC_Extern;
7105 case SC_Static:
7106 return CX_SC_Static;
7107 case SC_PrivateExtern:
7108 return CX_SC_PrivateExtern;
Argyrios Kyrtzidis4e0854f2014-10-15 17:05:31 +00007109 case SC_Auto:
7110 return CX_SC_Auto;
7111 case SC_Register:
7112 return CX_SC_Register;
Argyrios Kyrtzidis4e0854f2014-10-15 17:05:31 +00007113 }
Kaelyn Takataab61e702014-10-15 18:03:26 +00007114 llvm_unreachable("Unhandled storage class!");
Argyrios Kyrtzidis4e0854f2014-10-15 17:05:31 +00007115}
7116
Guy Benyei11169dd2012-12-18 14:30:41 +00007117CXCursor clang_getCursorSemanticParent(CXCursor cursor) {
7118 if (clang_isDeclaration(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00007119 if (const Decl *D = getCursorDecl(cursor)) {
7120 const DeclContext *DC = D->getDeclContext();
Guy Benyei11169dd2012-12-18 14:30:41 +00007121 if (!DC)
7122 return clang_getNullCursor();
7123
7124 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
7125 getCursorTU(cursor));
7126 }
7127 }
7128
7129 if (clang_isStatement(cursor.kind) || clang_isExpression(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00007130 if (const Decl *D = getCursorDecl(cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +00007131 return MakeCXCursor(D, getCursorTU(cursor));
7132 }
7133
7134 return clang_getNullCursor();
7135}
7136
7137CXCursor clang_getCursorLexicalParent(CXCursor cursor) {
7138 if (clang_isDeclaration(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00007139 if (const Decl *D = getCursorDecl(cursor)) {
7140 const DeclContext *DC = D->getLexicalDeclContext();
Guy Benyei11169dd2012-12-18 14:30:41 +00007141 if (!DC)
7142 return clang_getNullCursor();
7143
7144 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
7145 getCursorTU(cursor));
7146 }
7147 }
7148
7149 // FIXME: Note that we can't easily compute the lexical context of a
7150 // statement or expression, so we return nothing.
7151 return clang_getNullCursor();
7152}
7153
7154CXFile clang_getIncludedFile(CXCursor cursor) {
7155 if (cursor.kind != CXCursor_InclusionDirective)
Craig Topper69186e72014-06-08 08:38:04 +00007156 return nullptr;
7157
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00007158 const InclusionDirective *ID = getCursorInclusionDirective(cursor);
Dmitri Gribenkof9304482013-01-23 15:56:07 +00007159 return const_cast<FileEntry *>(ID->getFile());
Guy Benyei11169dd2012-12-18 14:30:41 +00007160}
7161
Argyrios Kyrtzidis9adfd8a2013-04-18 22:15:49 +00007162unsigned clang_Cursor_getObjCPropertyAttributes(CXCursor C, unsigned reserved) {
7163 if (C.kind != CXCursor_ObjCPropertyDecl)
7164 return CXObjCPropertyAttr_noattr;
7165
7166 unsigned Result = CXObjCPropertyAttr_noattr;
7167 const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(getCursorDecl(C));
7168 ObjCPropertyDecl::PropertyAttributeKind Attr =
7169 PD->getPropertyAttributesAsWritten();
7170
7171#define SET_CXOBJCPROP_ATTR(A) \
7172 if (Attr & ObjCPropertyDecl::OBJC_PR_##A) \
7173 Result |= CXObjCPropertyAttr_##A
7174 SET_CXOBJCPROP_ATTR(readonly);
7175 SET_CXOBJCPROP_ATTR(getter);
7176 SET_CXOBJCPROP_ATTR(assign);
7177 SET_CXOBJCPROP_ATTR(readwrite);
7178 SET_CXOBJCPROP_ATTR(retain);
7179 SET_CXOBJCPROP_ATTR(copy);
7180 SET_CXOBJCPROP_ATTR(nonatomic);
7181 SET_CXOBJCPROP_ATTR(setter);
7182 SET_CXOBJCPROP_ATTR(atomic);
7183 SET_CXOBJCPROP_ATTR(weak);
7184 SET_CXOBJCPROP_ATTR(strong);
7185 SET_CXOBJCPROP_ATTR(unsafe_unretained);
7186#undef SET_CXOBJCPROP_ATTR
7187
7188 return Result;
7189}
7190
Argyrios Kyrtzidis9d9bc012013-04-18 23:29:12 +00007191unsigned clang_Cursor_getObjCDeclQualifiers(CXCursor C) {
7192 if (!clang_isDeclaration(C.kind))
7193 return CXObjCDeclQualifier_None;
7194
7195 Decl::ObjCDeclQualifier QT = Decl::OBJC_TQ_None;
7196 const Decl *D = getCursorDecl(C);
7197 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
7198 QT = MD->getObjCDeclQualifier();
7199 else if (const ParmVarDecl *PD = dyn_cast<ParmVarDecl>(D))
7200 QT = PD->getObjCDeclQualifier();
7201 if (QT == Decl::OBJC_TQ_None)
7202 return CXObjCDeclQualifier_None;
7203
7204 unsigned Result = CXObjCDeclQualifier_None;
7205 if (QT & Decl::OBJC_TQ_In) Result |= CXObjCDeclQualifier_In;
7206 if (QT & Decl::OBJC_TQ_Inout) Result |= CXObjCDeclQualifier_Inout;
7207 if (QT & Decl::OBJC_TQ_Out) Result |= CXObjCDeclQualifier_Out;
7208 if (QT & Decl::OBJC_TQ_Bycopy) Result |= CXObjCDeclQualifier_Bycopy;
7209 if (QT & Decl::OBJC_TQ_Byref) Result |= CXObjCDeclQualifier_Byref;
7210 if (QT & Decl::OBJC_TQ_Oneway) Result |= CXObjCDeclQualifier_Oneway;
7211
7212 return Result;
7213}
7214
Argyrios Kyrtzidis7b50fc52013-07-05 20:44:37 +00007215unsigned clang_Cursor_isObjCOptional(CXCursor C) {
7216 if (!clang_isDeclaration(C.kind))
7217 return 0;
7218
7219 const Decl *D = getCursorDecl(C);
7220 if (const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(D))
7221 return PD->getPropertyImplementation() == ObjCPropertyDecl::Optional;
7222 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
7223 return MD->getImplementationControl() == ObjCMethodDecl::Optional;
7224
7225 return 0;
7226}
7227
Argyrios Kyrtzidis23814e42013-04-18 23:53:05 +00007228unsigned clang_Cursor_isVariadic(CXCursor C) {
7229 if (!clang_isDeclaration(C.kind))
7230 return 0;
7231
7232 const Decl *D = getCursorDecl(C);
7233 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
7234 return FD->isVariadic();
7235 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
7236 return MD->isVariadic();
7237
7238 return 0;
7239}
7240
Guy Benyei11169dd2012-12-18 14:30:41 +00007241CXSourceRange clang_Cursor_getCommentRange(CXCursor C) {
7242 if (!clang_isDeclaration(C.kind))
7243 return clang_getNullRange();
7244
7245 const Decl *D = getCursorDecl(C);
7246 ASTContext &Context = getCursorContext(C);
7247 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
7248 if (!RC)
7249 return clang_getNullRange();
7250
7251 return cxloc::translateSourceRange(Context, RC->getSourceRange());
7252}
7253
7254CXString clang_Cursor_getRawCommentText(CXCursor C) {
7255 if (!clang_isDeclaration(C.kind))
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00007256 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00007257
7258 const Decl *D = getCursorDecl(C);
7259 ASTContext &Context = getCursorContext(C);
7260 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
7261 StringRef RawText = RC ? RC->getRawText(Context.getSourceManager()) :
7262 StringRef();
7263
7264 // Don't duplicate the string because RawText points directly into source
7265 // code.
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00007266 return cxstring::createRef(RawText);
Guy Benyei11169dd2012-12-18 14:30:41 +00007267}
7268
7269CXString clang_Cursor_getBriefCommentText(CXCursor C) {
7270 if (!clang_isDeclaration(C.kind))
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00007271 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00007272
7273 const Decl *D = getCursorDecl(C);
7274 const ASTContext &Context = getCursorContext(C);
7275 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
7276
7277 if (RC) {
7278 StringRef BriefText = RC->getBriefText(Context);
7279
7280 // Don't duplicate the string because RawComment ensures that this memory
7281 // will not go away.
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00007282 return cxstring::createRef(BriefText);
Guy Benyei11169dd2012-12-18 14:30:41 +00007283 }
7284
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00007285 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00007286}
7287
Guy Benyei11169dd2012-12-18 14:30:41 +00007288CXModule clang_Cursor_getModule(CXCursor C) {
7289 if (C.kind == CXCursor_ModuleImportDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00007290 if (const ImportDecl *ImportD =
7291 dyn_cast_or_null<ImportDecl>(getCursorDecl(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00007292 return ImportD->getImportedModule();
7293 }
7294
Craig Topper69186e72014-06-08 08:38:04 +00007295 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00007296}
7297
Argyrios Kyrtzidisf6d49c32014-05-14 23:14:37 +00007298CXModule clang_getModuleForFile(CXTranslationUnit TU, CXFile File) {
7299 if (isNotUsableTU(TU)) {
7300 LOG_BAD_TU(TU);
7301 return nullptr;
7302 }
7303 if (!File)
7304 return nullptr;
7305 FileEntry *FE = static_cast<FileEntry *>(File);
7306
7307 ASTUnit &Unit = *cxtu::getASTUnit(TU);
7308 HeaderSearch &HS = Unit.getPreprocessor().getHeaderSearchInfo();
7309 ModuleMap::KnownHeader Header = HS.findModuleForHeader(FE);
7310
Richard Smithfeb54b62014-10-23 02:01:19 +00007311 return Header.getModule();
Argyrios Kyrtzidisf6d49c32014-05-14 23:14:37 +00007312}
7313
Argyrios Kyrtzidis12fdb9e2013-04-26 22:47:49 +00007314CXFile clang_Module_getASTFile(CXModule CXMod) {
7315 if (!CXMod)
Craig Topper69186e72014-06-08 08:38:04 +00007316 return nullptr;
Argyrios Kyrtzidis12fdb9e2013-04-26 22:47:49 +00007317 Module *Mod = static_cast<Module*>(CXMod);
7318 return const_cast<FileEntry *>(Mod->getASTFile());
7319}
7320
Guy Benyei11169dd2012-12-18 14:30:41 +00007321CXModule clang_Module_getParent(CXModule CXMod) {
7322 if (!CXMod)
Craig Topper69186e72014-06-08 08:38:04 +00007323 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00007324 Module *Mod = static_cast<Module*>(CXMod);
7325 return Mod->Parent;
7326}
7327
7328CXString clang_Module_getName(CXModule CXMod) {
7329 if (!CXMod)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00007330 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00007331 Module *Mod = static_cast<Module*>(CXMod);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00007332 return cxstring::createDup(Mod->Name);
Guy Benyei11169dd2012-12-18 14:30:41 +00007333}
7334
7335CXString clang_Module_getFullName(CXModule CXMod) {
7336 if (!CXMod)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00007337 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00007338 Module *Mod = static_cast<Module*>(CXMod);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00007339 return cxstring::createDup(Mod->getFullModuleName());
Guy Benyei11169dd2012-12-18 14:30:41 +00007340}
7341
Argyrios Kyrtzidis884337f2014-05-15 04:44:25 +00007342int clang_Module_isSystem(CXModule CXMod) {
7343 if (!CXMod)
7344 return 0;
7345 Module *Mod = static_cast<Module*>(CXMod);
7346 return Mod->IsSystem;
7347}
7348
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00007349unsigned clang_Module_getNumTopLevelHeaders(CXTranslationUnit TU,
7350 CXModule CXMod) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00007351 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00007352 LOG_BAD_TU(TU);
7353 return 0;
7354 }
7355 if (!CXMod)
Guy Benyei11169dd2012-12-18 14:30:41 +00007356 return 0;
7357 Module *Mod = static_cast<Module*>(CXMod);
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00007358 FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
7359 ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
7360 return TopHeaders.size();
Guy Benyei11169dd2012-12-18 14:30:41 +00007361}
7362
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00007363CXFile clang_Module_getTopLevelHeader(CXTranslationUnit TU,
7364 CXModule CXMod, unsigned Index) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00007365 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00007366 LOG_BAD_TU(TU);
Craig Topper69186e72014-06-08 08:38:04 +00007367 return nullptr;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00007368 }
7369 if (!CXMod)
Craig Topper69186e72014-06-08 08:38:04 +00007370 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00007371 Module *Mod = static_cast<Module*>(CXMod);
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00007372 FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
Guy Benyei11169dd2012-12-18 14:30:41 +00007373
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00007374 ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
7375 if (Index < TopHeaders.size())
7376 return const_cast<FileEntry *>(TopHeaders[Index]);
Guy Benyei11169dd2012-12-18 14:30:41 +00007377
Craig Topper69186e72014-06-08 08:38:04 +00007378 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00007379}
7380
7381} // end: extern "C"
7382
7383//===----------------------------------------------------------------------===//
7384// C++ AST instrospection.
7385//===----------------------------------------------------------------------===//
7386
7387extern "C" {
Saleem Abdulrasool6ea75db2015-10-27 15:50:22 +00007388unsigned clang_CXXField_isMutable(CXCursor C) {
7389 if (!clang_isDeclaration(C.kind))
7390 return 0;
7391
7392 if (const auto D = cxcursor::getCursorDecl(C))
7393 if (const auto FD = dyn_cast_or_null<FieldDecl>(D))
7394 return FD->isMutable() ? 1 : 0;
7395 return 0;
7396}
7397
Dmitri Gribenko62770be2013-05-17 18:38:35 +00007398unsigned clang_CXXMethod_isPureVirtual(CXCursor C) {
7399 if (!clang_isDeclaration(C.kind))
7400 return 0;
7401
Dmitri Gribenko62770be2013-05-17 18:38:35 +00007402 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00007403 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00007404 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Dmitri Gribenko62770be2013-05-17 18:38:35 +00007405 return (Method && Method->isVirtual() && Method->isPure()) ? 1 : 0;
7406}
7407
Dmitri Gribenkoe570ede2014-04-07 14:59:13 +00007408unsigned clang_CXXMethod_isConst(CXCursor C) {
7409 if (!clang_isDeclaration(C.kind))
7410 return 0;
7411
7412 const Decl *D = cxcursor::getCursorDecl(C);
7413 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00007414 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Dmitri Gribenkoe570ede2014-04-07 14:59:13 +00007415 return (Method && (Method->getTypeQualifiers() & Qualifiers::Const)) ? 1 : 0;
7416}
7417
Guy Benyei11169dd2012-12-18 14:30:41 +00007418unsigned clang_CXXMethod_isStatic(CXCursor C) {
7419 if (!clang_isDeclaration(C.kind))
7420 return 0;
7421
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00007422 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00007423 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00007424 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00007425 return (Method && Method->isStatic()) ? 1 : 0;
7426}
7427
7428unsigned clang_CXXMethod_isVirtual(CXCursor C) {
7429 if (!clang_isDeclaration(C.kind))
7430 return 0;
7431
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00007432 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00007433 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00007434 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00007435 return (Method && Method->isVirtual()) ? 1 : 0;
7436}
7437} // end: extern "C"
7438
7439//===----------------------------------------------------------------------===//
7440// Attribute introspection.
7441//===----------------------------------------------------------------------===//
7442
7443extern "C" {
7444CXType clang_getIBOutletCollectionType(CXCursor C) {
7445 if (C.kind != CXCursor_IBOutletCollectionAttr)
7446 return cxtype::MakeCXType(QualType(), cxcursor::getCursorTU(C));
7447
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00007448 const IBOutletCollectionAttr *A =
Guy Benyei11169dd2012-12-18 14:30:41 +00007449 cast<IBOutletCollectionAttr>(cxcursor::getCursorAttr(C));
7450
7451 return cxtype::MakeCXType(A->getInterface(), cxcursor::getCursorTU(C));
7452}
7453} // end: extern "C"
7454
7455//===----------------------------------------------------------------------===//
7456// Inspecting memory usage.
7457//===----------------------------------------------------------------------===//
7458
7459typedef std::vector<CXTUResourceUsageEntry> MemUsageEntries;
7460
7461static inline void createCXTUResourceUsageEntry(MemUsageEntries &entries,
7462 enum CXTUResourceUsageKind k,
7463 unsigned long amount) {
7464 CXTUResourceUsageEntry entry = { k, amount };
7465 entries.push_back(entry);
7466}
7467
7468extern "C" {
7469
7470const char *clang_getTUResourceUsageName(CXTUResourceUsageKind kind) {
7471 const char *str = "";
7472 switch (kind) {
7473 case CXTUResourceUsage_AST:
7474 str = "ASTContext: expressions, declarations, and types";
7475 break;
7476 case CXTUResourceUsage_Identifiers:
7477 str = "ASTContext: identifiers";
7478 break;
7479 case CXTUResourceUsage_Selectors:
7480 str = "ASTContext: selectors";
7481 break;
7482 case CXTUResourceUsage_GlobalCompletionResults:
7483 str = "Code completion: cached global results";
7484 break;
7485 case CXTUResourceUsage_SourceManagerContentCache:
7486 str = "SourceManager: content cache allocator";
7487 break;
7488 case CXTUResourceUsage_AST_SideTables:
7489 str = "ASTContext: side tables";
7490 break;
7491 case CXTUResourceUsage_SourceManager_Membuffer_Malloc:
7492 str = "SourceManager: malloc'ed memory buffers";
7493 break;
7494 case CXTUResourceUsage_SourceManager_Membuffer_MMap:
7495 str = "SourceManager: mmap'ed memory buffers";
7496 break;
7497 case CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc:
7498 str = "ExternalASTSource: malloc'ed memory buffers";
7499 break;
7500 case CXTUResourceUsage_ExternalASTSource_Membuffer_MMap:
7501 str = "ExternalASTSource: mmap'ed memory buffers";
7502 break;
7503 case CXTUResourceUsage_Preprocessor:
7504 str = "Preprocessor: malloc'ed memory";
7505 break;
7506 case CXTUResourceUsage_PreprocessingRecord:
7507 str = "Preprocessor: PreprocessingRecord";
7508 break;
7509 case CXTUResourceUsage_SourceManager_DataStructures:
7510 str = "SourceManager: data structures and tables";
7511 break;
7512 case CXTUResourceUsage_Preprocessor_HeaderSearch:
7513 str = "Preprocessor: header search tables";
7514 break;
7515 }
7516 return str;
7517}
7518
7519CXTUResourceUsage clang_getCXTUResourceUsage(CXTranslationUnit TU) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00007520 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00007521 LOG_BAD_TU(TU);
Craig Topper69186e72014-06-08 08:38:04 +00007522 CXTUResourceUsage usage = { (void*) nullptr, 0, nullptr };
Guy Benyei11169dd2012-12-18 14:30:41 +00007523 return usage;
7524 }
7525
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007526 ASTUnit *astUnit = cxtu::getASTUnit(TU);
Ahmed Charlesb8984322014-03-07 20:03:18 +00007527 std::unique_ptr<MemUsageEntries> entries(new MemUsageEntries());
Guy Benyei11169dd2012-12-18 14:30:41 +00007528 ASTContext &astContext = astUnit->getASTContext();
7529
7530 // How much memory is used by AST nodes and types?
7531 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST,
7532 (unsigned long) astContext.getASTAllocatedMemory());
7533
7534 // How much memory is used by identifiers?
7535 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Identifiers,
7536 (unsigned long) astContext.Idents.getAllocator().getTotalMemory());
7537
7538 // How much memory is used for selectors?
7539 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Selectors,
7540 (unsigned long) astContext.Selectors.getTotalMemory());
7541
7542 // How much memory is used by ASTContext's side tables?
7543 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST_SideTables,
7544 (unsigned long) astContext.getSideTableAllocatedMemory());
7545
7546 // How much memory is used for caching global code completion results?
7547 unsigned long completionBytes = 0;
7548 if (GlobalCodeCompletionAllocator *completionAllocator =
Alp Tokerf994cef2014-07-05 03:08:06 +00007549 astUnit->getCachedCompletionAllocator().get()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00007550 completionBytes = completionAllocator->getTotalMemory();
7551 }
7552 createCXTUResourceUsageEntry(*entries,
7553 CXTUResourceUsage_GlobalCompletionResults,
7554 completionBytes);
7555
7556 // How much memory is being used by SourceManager's content cache?
7557 createCXTUResourceUsageEntry(*entries,
7558 CXTUResourceUsage_SourceManagerContentCache,
7559 (unsigned long) astContext.getSourceManager().getContentCacheSize());
7560
7561 // How much memory is being used by the MemoryBuffer's in SourceManager?
7562 const SourceManager::MemoryBufferSizes &srcBufs =
7563 astUnit->getSourceManager().getMemoryBufferSizes();
7564
7565 createCXTUResourceUsageEntry(*entries,
7566 CXTUResourceUsage_SourceManager_Membuffer_Malloc,
7567 (unsigned long) srcBufs.malloc_bytes);
7568 createCXTUResourceUsageEntry(*entries,
7569 CXTUResourceUsage_SourceManager_Membuffer_MMap,
7570 (unsigned long) srcBufs.mmap_bytes);
7571 createCXTUResourceUsageEntry(*entries,
7572 CXTUResourceUsage_SourceManager_DataStructures,
7573 (unsigned long) astContext.getSourceManager()
7574 .getDataStructureSizes());
7575
7576 // How much memory is being used by the ExternalASTSource?
7577 if (ExternalASTSource *esrc = astContext.getExternalSource()) {
7578 const ExternalASTSource::MemoryBufferSizes &sizes =
7579 esrc->getMemoryBufferSizes();
7580
7581 createCXTUResourceUsageEntry(*entries,
7582 CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc,
7583 (unsigned long) sizes.malloc_bytes);
7584 createCXTUResourceUsageEntry(*entries,
7585 CXTUResourceUsage_ExternalASTSource_Membuffer_MMap,
7586 (unsigned long) sizes.mmap_bytes);
7587 }
7588
7589 // How much memory is being used by the Preprocessor?
7590 Preprocessor &pp = astUnit->getPreprocessor();
7591 createCXTUResourceUsageEntry(*entries,
7592 CXTUResourceUsage_Preprocessor,
7593 pp.getTotalMemory());
7594
7595 if (PreprocessingRecord *pRec = pp.getPreprocessingRecord()) {
7596 createCXTUResourceUsageEntry(*entries,
7597 CXTUResourceUsage_PreprocessingRecord,
7598 pRec->getTotalMemory());
7599 }
7600
7601 createCXTUResourceUsageEntry(*entries,
7602 CXTUResourceUsage_Preprocessor_HeaderSearch,
7603 pp.getHeaderSearchInfo().getTotalMemory());
Craig Topper69186e72014-06-08 08:38:04 +00007604
Guy Benyei11169dd2012-12-18 14:30:41 +00007605 CXTUResourceUsage usage = { (void*) entries.get(),
7606 (unsigned) entries->size(),
Alexander Kornienko6ee521c2015-01-23 15:36:10 +00007607 !entries->empty() ? &(*entries)[0] : nullptr };
Ahmed Charles9a16beb2014-03-07 19:33:25 +00007608 entries.release();
Guy Benyei11169dd2012-12-18 14:30:41 +00007609 return usage;
7610}
7611
7612void clang_disposeCXTUResourceUsage(CXTUResourceUsage usage) {
7613 if (usage.data)
7614 delete (MemUsageEntries*) usage.data;
7615}
7616
Argyrios Kyrtzidis0e282ef2013-12-06 18:55:45 +00007617CXSourceRangeList *clang_getSkippedRanges(CXTranslationUnit TU, CXFile file) {
7618 CXSourceRangeList *skipped = new CXSourceRangeList;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00007619 skipped->count = 0;
Craig Topper69186e72014-06-08 08:38:04 +00007620 skipped->ranges = nullptr;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00007621
Dmitri Gribenko852d6222014-02-11 15:02:48 +00007622 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00007623 LOG_BAD_TU(TU);
7624 return skipped;
7625 }
7626
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00007627 if (!file)
7628 return skipped;
7629
7630 ASTUnit *astUnit = cxtu::getASTUnit(TU);
7631 PreprocessingRecord *ppRec = astUnit->getPreprocessor().getPreprocessingRecord();
7632 if (!ppRec)
7633 return skipped;
7634
7635 ASTContext &Ctx = astUnit->getASTContext();
7636 SourceManager &sm = Ctx.getSourceManager();
7637 FileEntry *fileEntry = static_cast<FileEntry *>(file);
7638 FileID wantedFileID = sm.translateFile(fileEntry);
7639
7640 const std::vector<SourceRange> &SkippedRanges = ppRec->getSkippedRanges();
7641 std::vector<SourceRange> wantedRanges;
7642 for (std::vector<SourceRange>::const_iterator i = SkippedRanges.begin(), ei = SkippedRanges.end();
7643 i != ei; ++i) {
7644 if (sm.getFileID(i->getBegin()) == wantedFileID || sm.getFileID(i->getEnd()) == wantedFileID)
7645 wantedRanges.push_back(*i);
7646 }
7647
7648 skipped->count = wantedRanges.size();
7649 skipped->ranges = new CXSourceRange[skipped->count];
7650 for (unsigned i = 0, ei = skipped->count; i != ei; ++i)
7651 skipped->ranges[i] = cxloc::translateSourceRange(Ctx, wantedRanges[i]);
7652
7653 return skipped;
7654}
7655
Argyrios Kyrtzidis0e282ef2013-12-06 18:55:45 +00007656void clang_disposeSourceRangeList(CXSourceRangeList *ranges) {
7657 if (ranges) {
7658 delete[] ranges->ranges;
7659 delete ranges;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00007660 }
7661}
7662
Guy Benyei11169dd2012-12-18 14:30:41 +00007663} // end extern "C"
7664
7665void clang::PrintLibclangResourceUsage(CXTranslationUnit TU) {
7666 CXTUResourceUsage Usage = clang_getCXTUResourceUsage(TU);
7667 for (unsigned I = 0; I != Usage.numEntries; ++I)
7668 fprintf(stderr, " %s: %lu\n",
7669 clang_getTUResourceUsageName(Usage.entries[I].kind),
7670 Usage.entries[I].amount);
7671
7672 clang_disposeCXTUResourceUsage(Usage);
7673}
7674
7675//===----------------------------------------------------------------------===//
7676// Misc. utility functions.
7677//===----------------------------------------------------------------------===//
7678
7679/// Default to using an 8 MB stack size on "safety" threads.
7680static unsigned SafetyStackThreadSize = 8 << 20;
7681
7682namespace clang {
7683
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00007684bool RunSafely(llvm::CrashRecoveryContext &CRC, llvm::function_ref<void()> Fn,
Guy Benyei11169dd2012-12-18 14:30:41 +00007685 unsigned Size) {
7686 if (!Size)
7687 Size = GetSafetyThreadStackSize();
7688 if (Size)
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00007689 return CRC.RunSafelyOnThread(Fn, Size);
7690 return CRC.RunSafely(Fn);
Guy Benyei11169dd2012-12-18 14:30:41 +00007691}
7692
7693unsigned GetSafetyThreadStackSize() {
7694 return SafetyStackThreadSize;
7695}
7696
7697void SetSafetyThreadStackSize(unsigned Value) {
7698 SafetyStackThreadSize = Value;
7699}
7700
Alexander Kornienkoab9db512015-06-22 23:07:51 +00007701}
Guy Benyei11169dd2012-12-18 14:30:41 +00007702
7703void clang::setThreadBackgroundPriority() {
7704 if (getenv("LIBCLANG_BGPRIO_DISABLE"))
7705 return;
7706
Alp Toker1a86ad22014-07-06 06:24:00 +00007707#ifdef USE_DARWIN_THREADS
Guy Benyei11169dd2012-12-18 14:30:41 +00007708 setpriority(PRIO_DARWIN_THREAD, 0, PRIO_DARWIN_BG);
7709#endif
7710}
7711
7712void cxindex::printDiagsToStderr(ASTUnit *Unit) {
7713 if (!Unit)
7714 return;
7715
7716 for (ASTUnit::stored_diag_iterator D = Unit->stored_diag_begin(),
7717 DEnd = Unit->stored_diag_end();
7718 D != DEnd; ++D) {
Ben Langmuir749323f2014-04-22 17:40:12 +00007719 CXStoredDiagnostic Diag(*D, Unit->getLangOpts());
Guy Benyei11169dd2012-12-18 14:30:41 +00007720 CXString Msg = clang_formatDiagnostic(&Diag,
7721 clang_defaultDiagnosticDisplayOptions());
7722 fprintf(stderr, "%s\n", clang_getCString(Msg));
7723 clang_disposeString(Msg);
7724 }
7725#ifdef LLVM_ON_WIN32
7726 // On Windows, force a flush, since there may be multiple copies of
7727 // stderr and stdout in the file system, all with different buffers
7728 // but writing to the same device.
7729 fflush(stderr);
7730#endif
7731}
7732
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007733MacroInfo *cxindex::getMacroInfo(const IdentifierInfo &II,
7734 SourceLocation MacroDefLoc,
7735 CXTranslationUnit TU){
7736 if (MacroDefLoc.isInvalid() || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00007737 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007738 if (!II.hadMacroDefinition())
Craig Topper69186e72014-06-08 08:38:04 +00007739 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007740
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007741 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00007742 Preprocessor &PP = Unit->getPreprocessor();
Richard Smith20e883e2015-04-29 23:20:19 +00007743 MacroDirective *MD = PP.getLocalMacroDirectiveHistory(&II);
Argyrios Kyrtzidisb6210df2013-03-26 17:17:01 +00007744 if (MD) {
7745 for (MacroDirective::DefInfo
7746 Def = MD->getDefinition(); Def; Def = Def.getPreviousDefinition()) {
7747 if (MacroDefLoc == Def.getMacroInfo()->getDefinitionLoc())
7748 return Def.getMacroInfo();
7749 }
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007750 }
7751
Craig Topper69186e72014-06-08 08:38:04 +00007752 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007753}
7754
Richard Smith66a81862015-05-04 02:25:31 +00007755const MacroInfo *cxindex::getMacroInfo(const MacroDefinitionRecord *MacroDef,
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00007756 CXTranslationUnit TU) {
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007757 if (!MacroDef || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00007758 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007759 const IdentifierInfo *II = MacroDef->getName();
7760 if (!II)
Craig Topper69186e72014-06-08 08:38:04 +00007761 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007762
7763 return getMacroInfo(*II, MacroDef->getLocation(), TU);
7764}
7765
Richard Smith66a81862015-05-04 02:25:31 +00007766MacroDefinitionRecord *
7767cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI, const Token &Tok,
7768 CXTranslationUnit TU) {
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007769 if (!MI || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00007770 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007771 if (Tok.isNot(tok::raw_identifier))
Craig Topper69186e72014-06-08 08:38:04 +00007772 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007773
7774 if (MI->getNumTokens() == 0)
Craig Topper69186e72014-06-08 08:38:04 +00007775 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007776 SourceRange DefRange(MI->getReplacementToken(0).getLocation(),
7777 MI->getDefinitionEndLoc());
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007778 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007779
7780 // Check that the token is inside the definition and not its argument list.
7781 SourceManager &SM = Unit->getSourceManager();
7782 if (SM.isBeforeInTranslationUnit(Tok.getLocation(), DefRange.getBegin()))
Craig Topper69186e72014-06-08 08:38:04 +00007783 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007784 if (SM.isBeforeInTranslationUnit(DefRange.getEnd(), Tok.getLocation()))
Craig Topper69186e72014-06-08 08:38:04 +00007785 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007786
7787 Preprocessor &PP = Unit->getPreprocessor();
7788 PreprocessingRecord *PPRec = PP.getPreprocessingRecord();
7789 if (!PPRec)
Craig Topper69186e72014-06-08 08:38:04 +00007790 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007791
Alp Toker2d57cea2014-05-17 04:53:25 +00007792 IdentifierInfo &II = PP.getIdentifierTable().get(Tok.getRawIdentifier());
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007793 if (!II.hadMacroDefinition())
Craig Topper69186e72014-06-08 08:38:04 +00007794 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007795
7796 // Check that the identifier is not one of the macro arguments.
7797 if (std::find(MI->arg_begin(), MI->arg_end(), &II) != MI->arg_end())
Craig Topper69186e72014-06-08 08:38:04 +00007798 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007799
Richard Smith20e883e2015-04-29 23:20:19 +00007800 MacroDirective *InnerMD = PP.getLocalMacroDirectiveHistory(&II);
Argyrios Kyrtzidis09c9e812013-02-20 00:54:57 +00007801 if (!InnerMD)
Craig Topper69186e72014-06-08 08:38:04 +00007802 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007803
Argyrios Kyrtzidisb6210df2013-03-26 17:17:01 +00007804 return PPRec->findMacroDefinition(InnerMD->getMacroInfo());
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007805}
7806
Richard Smith66a81862015-05-04 02:25:31 +00007807MacroDefinitionRecord *
7808cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI, SourceLocation Loc,
7809 CXTranslationUnit TU) {
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007810 if (Loc.isInvalid() || !MI || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00007811 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007812
7813 if (MI->getNumTokens() == 0)
Craig Topper69186e72014-06-08 08:38:04 +00007814 return nullptr;
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007815 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007816 Preprocessor &PP = Unit->getPreprocessor();
7817 if (!PP.getPreprocessingRecord())
Craig Topper69186e72014-06-08 08:38:04 +00007818 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007819 Loc = Unit->getSourceManager().getSpellingLoc(Loc);
7820 Token Tok;
7821 if (PP.getRawToken(Loc, Tok))
Craig Topper69186e72014-06-08 08:38:04 +00007822 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007823
7824 return checkForMacroInMacroDefinition(MI, Tok, TU);
7825}
7826
Guy Benyei11169dd2012-12-18 14:30:41 +00007827extern "C" {
7828
7829CXString clang_getClangVersion() {
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00007830 return cxstring::createDup(getClangFullVersion());
Guy Benyei11169dd2012-12-18 14:30:41 +00007831}
7832
7833} // end: extern "C"
7834
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007835Logger &cxindex::Logger::operator<<(CXTranslationUnit TU) {
7836 if (TU) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007837 if (ASTUnit *Unit = cxtu::getASTUnit(TU)) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007838 LogOS << '<' << Unit->getMainFileName() << '>';
Argyrios Kyrtzidis37f2ab42013-03-05 20:21:14 +00007839 if (Unit->isMainFileAST())
7840 LogOS << " (" << Unit->getASTFileName() << ')';
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007841 return *this;
7842 }
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00007843 } else {
7844 LogOS << "<NULL TU>";
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007845 }
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007846 return *this;
7847}
7848
Argyrios Kyrtzidisba4b5f82013-03-08 02:32:26 +00007849Logger &cxindex::Logger::operator<<(const FileEntry *FE) {
7850 *this << FE->getName();
7851 return *this;
7852}
7853
7854Logger &cxindex::Logger::operator<<(CXCursor cursor) {
7855 CXString cursorName = clang_getCursorDisplayName(cursor);
7856 *this << cursorName << "@" << clang_getCursorLocation(cursor);
7857 clang_disposeString(cursorName);
7858 return *this;
7859}
7860
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007861Logger &cxindex::Logger::operator<<(CXSourceLocation Loc) {
7862 CXFile File;
7863 unsigned Line, Column;
Craig Topper69186e72014-06-08 08:38:04 +00007864 clang_getFileLocation(Loc, &File, &Line, &Column, nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007865 CXString FileName = clang_getFileName(File);
7866 *this << llvm::format("(%s:%d:%d)", clang_getCString(FileName), Line, Column);
7867 clang_disposeString(FileName);
7868 return *this;
7869}
7870
7871Logger &cxindex::Logger::operator<<(CXSourceRange range) {
7872 CXSourceLocation BLoc = clang_getRangeStart(range);
7873 CXSourceLocation ELoc = clang_getRangeEnd(range);
7874
7875 CXFile BFile;
7876 unsigned BLine, BColumn;
Craig Topper69186e72014-06-08 08:38:04 +00007877 clang_getFileLocation(BLoc, &BFile, &BLine, &BColumn, nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007878
7879 CXFile EFile;
7880 unsigned ELine, EColumn;
Craig Topper69186e72014-06-08 08:38:04 +00007881 clang_getFileLocation(ELoc, &EFile, &ELine, &EColumn, nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007882
7883 CXString BFileName = clang_getFileName(BFile);
7884 if (BFile == EFile) {
7885 *this << llvm::format("[%s %d:%d-%d:%d]", clang_getCString(BFileName),
7886 BLine, BColumn, ELine, EColumn);
7887 } else {
7888 CXString EFileName = clang_getFileName(EFile);
7889 *this << llvm::format("[%s:%d:%d - ", clang_getCString(BFileName),
7890 BLine, BColumn)
7891 << llvm::format("%s:%d:%d]", clang_getCString(EFileName),
7892 ELine, EColumn);
7893 clang_disposeString(EFileName);
7894 }
7895 clang_disposeString(BFileName);
7896 return *this;
7897}
7898
7899Logger &cxindex::Logger::operator<<(CXString Str) {
7900 *this << clang_getCString(Str);
7901 return *this;
7902}
7903
7904Logger &cxindex::Logger::operator<<(const llvm::format_object_base &Fmt) {
7905 LogOS << Fmt;
7906 return *this;
7907}
7908
Chandler Carruth37ad2582014-06-27 15:14:39 +00007909static llvm::ManagedStatic<llvm::sys::Mutex> LoggingMutex;
7910
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007911cxindex::Logger::~Logger() {
Chandler Carruth37ad2582014-06-27 15:14:39 +00007912 llvm::sys::ScopedLock L(*LoggingMutex);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007913
7914 static llvm::TimeRecord sBeginTR = llvm::TimeRecord::getCurrentTime();
7915
Dmitri Gribenkof8579502013-01-12 19:30:44 +00007916 raw_ostream &OS = llvm::errs();
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007917 OS << "[libclang:" << Name << ':';
7918
Alp Toker1a86ad22014-07-06 06:24:00 +00007919#ifdef USE_DARWIN_THREADS
7920 // TODO: Portability.
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007921 mach_port_t tid = pthread_mach_thread_np(pthread_self());
7922 OS << tid << ':';
7923#endif
7924
7925 llvm::TimeRecord TR = llvm::TimeRecord::getCurrentTime();
7926 OS << llvm::format("%7.4f] ", TR.getWallTime() - sBeginTR.getWallTime());
Yaron Keren09fb7c62015-03-10 07:33:23 +00007927 OS << Msg << '\n';
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007928
7929 if (Trace) {
Zachary Turner1fe2a8d2015-03-05 19:15:09 +00007930 llvm::sys::PrintStackTrace(OS);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007931 OS << "--------------------------------------------------\n";
7932 }
7933}