blob: f24b62f044e91734e172213bd738f73147da9a27 [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:
Nico Webercbbaeb12016-03-02 19:28:54 +00005590 case Decl::PragmaDetectMismatch:
Guy Benyei11169dd2012-12-18 14:30:41 +00005591 return C;
5592
5593 // Declaration kinds that don't make any sense here, but are
5594 // nonetheless harmless.
David Blaikief005d3c2013-02-22 17:44:58 +00005595 case Decl::Empty:
Guy Benyei11169dd2012-12-18 14:30:41 +00005596 case Decl::TranslationUnit:
Richard Smithf19e1272015-03-07 00:04:49 +00005597 case Decl::ExternCContext:
Guy Benyei11169dd2012-12-18 14:30:41 +00005598 break;
5599
5600 // Declaration kinds for which the definition is not resolvable.
5601 case Decl::UnresolvedUsingTypename:
5602 case Decl::UnresolvedUsingValue:
5603 break;
5604
5605 case Decl::UsingDirective:
5606 return MakeCXCursor(cast<UsingDirectiveDecl>(D)->getNominatedNamespace(),
5607 TU);
5608
5609 case Decl::NamespaceAlias:
5610 return MakeCXCursor(cast<NamespaceAliasDecl>(D)->getNamespace(), TU);
5611
5612 case Decl::Enum:
5613 case Decl::Record:
5614 case Decl::CXXRecord:
5615 case Decl::ClassTemplateSpecialization:
5616 case Decl::ClassTemplatePartialSpecialization:
5617 if (TagDecl *Def = cast<TagDecl>(D)->getDefinition())
5618 return MakeCXCursor(Def, TU);
5619 return clang_getNullCursor();
5620
5621 case Decl::Function:
5622 case Decl::CXXMethod:
5623 case Decl::CXXConstructor:
5624 case Decl::CXXDestructor:
5625 case Decl::CXXConversion: {
Craig Topper69186e72014-06-08 08:38:04 +00005626 const FunctionDecl *Def = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005627 if (cast<FunctionDecl>(D)->getBody(Def))
Dmitri Gribenko9c256e32013-01-14 00:46:27 +00005628 return MakeCXCursor(Def, TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005629 return clang_getNullCursor();
5630 }
5631
Larisse Voufo39a1e502013-08-06 01:03:05 +00005632 case Decl::Var:
5633 case Decl::VarTemplateSpecialization:
5634 case Decl::VarTemplatePartialSpecialization: {
Guy Benyei11169dd2012-12-18 14:30:41 +00005635 // Ask the variable if it has a definition.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005636 if (const VarDecl *Def = cast<VarDecl>(D)->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005637 return MakeCXCursor(Def, TU);
5638 return clang_getNullCursor();
5639 }
5640
5641 case Decl::FunctionTemplate: {
Craig Topper69186e72014-06-08 08:38:04 +00005642 const FunctionDecl *Def = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005643 if (cast<FunctionTemplateDecl>(D)->getTemplatedDecl()->getBody(Def))
5644 return MakeCXCursor(Def->getDescribedFunctionTemplate(), TU);
5645 return clang_getNullCursor();
5646 }
5647
5648 case Decl::ClassTemplate: {
5649 if (RecordDecl *Def = cast<ClassTemplateDecl>(D)->getTemplatedDecl()
5650 ->getDefinition())
5651 return MakeCXCursor(cast<CXXRecordDecl>(Def)->getDescribedClassTemplate(),
5652 TU);
5653 return clang_getNullCursor();
5654 }
5655
Larisse Voufo39a1e502013-08-06 01:03:05 +00005656 case Decl::VarTemplate: {
5657 if (VarDecl *Def =
5658 cast<VarTemplateDecl>(D)->getTemplatedDecl()->getDefinition())
5659 return MakeCXCursor(cast<VarDecl>(Def)->getDescribedVarTemplate(), TU);
5660 return clang_getNullCursor();
5661 }
5662
Guy Benyei11169dd2012-12-18 14:30:41 +00005663 case Decl::Using:
5664 return MakeCursorOverloadedDeclRef(cast<UsingDecl>(D),
5665 D->getLocation(), TU);
5666
5667 case Decl::UsingShadow:
5668 return clang_getCursorDefinition(
5669 MakeCXCursor(cast<UsingShadowDecl>(D)->getTargetDecl(),
5670 TU));
5671
5672 case Decl::ObjCMethod: {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005673 const ObjCMethodDecl *Method = cast<ObjCMethodDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00005674 if (Method->isThisDeclarationADefinition())
5675 return C;
5676
5677 // Dig out the method definition in the associated
5678 // @implementation, if we have it.
5679 // FIXME: The ASTs should make finding the definition easier.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005680 if (const ObjCInterfaceDecl *Class
Guy Benyei11169dd2012-12-18 14:30:41 +00005681 = dyn_cast<ObjCInterfaceDecl>(Method->getDeclContext()))
5682 if (ObjCImplementationDecl *ClassImpl = Class->getImplementation())
5683 if (ObjCMethodDecl *Def = ClassImpl->getMethod(Method->getSelector(),
5684 Method->isInstanceMethod()))
5685 if (Def->isThisDeclarationADefinition())
5686 return MakeCXCursor(Def, TU);
5687
5688 return clang_getNullCursor();
5689 }
5690
5691 case Decl::ObjCCategory:
5692 if (ObjCCategoryImplDecl *Impl
5693 = cast<ObjCCategoryDecl>(D)->getImplementation())
5694 return MakeCXCursor(Impl, TU);
5695 return clang_getNullCursor();
5696
5697 case Decl::ObjCProtocol:
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005698 if (const ObjCProtocolDecl *Def = cast<ObjCProtocolDecl>(D)->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005699 return MakeCXCursor(Def, TU);
5700 return clang_getNullCursor();
5701
5702 case Decl::ObjCInterface: {
5703 // There are two notions of a "definition" for an Objective-C
5704 // class: the interface and its implementation. When we resolved a
5705 // reference to an Objective-C class, produce the @interface as
5706 // the definition; when we were provided with the interface,
5707 // produce the @implementation as the definition.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005708 const ObjCInterfaceDecl *IFace = cast<ObjCInterfaceDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00005709 if (WasReference) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005710 if (const ObjCInterfaceDecl *Def = IFace->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005711 return MakeCXCursor(Def, TU);
5712 } else if (ObjCImplementationDecl *Impl = IFace->getImplementation())
5713 return MakeCXCursor(Impl, TU);
5714 return clang_getNullCursor();
5715 }
5716
5717 case Decl::ObjCProperty:
5718 // FIXME: We don't really know where to find the
5719 // ObjCPropertyImplDecls that implement this property.
5720 return clang_getNullCursor();
5721
5722 case Decl::ObjCCompatibleAlias:
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005723 if (const ObjCInterfaceDecl *Class
Guy Benyei11169dd2012-12-18 14:30:41 +00005724 = cast<ObjCCompatibleAliasDecl>(D)->getClassInterface())
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005725 if (const ObjCInterfaceDecl *Def = Class->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005726 return MakeCXCursor(Def, TU);
5727
5728 return clang_getNullCursor();
5729
5730 case Decl::Friend:
5731 if (NamedDecl *Friend = cast<FriendDecl>(D)->getFriendDecl())
5732 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
5733 return clang_getNullCursor();
5734
5735 case Decl::FriendTemplate:
5736 if (NamedDecl *Friend = cast<FriendTemplateDecl>(D)->getFriendDecl())
5737 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
5738 return clang_getNullCursor();
5739 }
5740
5741 return clang_getNullCursor();
5742}
5743
5744unsigned clang_isCursorDefinition(CXCursor C) {
5745 if (!clang_isDeclaration(C.kind))
5746 return 0;
5747
5748 return clang_getCursorDefinition(C) == C;
5749}
5750
5751CXCursor clang_getCanonicalCursor(CXCursor C) {
5752 if (!clang_isDeclaration(C.kind))
5753 return C;
5754
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005755 if (const Decl *D = getCursorDecl(C)) {
5756 if (const ObjCCategoryImplDecl *CatImplD = dyn_cast<ObjCCategoryImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00005757 if (ObjCCategoryDecl *CatD = CatImplD->getCategoryDecl())
5758 return MakeCXCursor(CatD, getCursorTU(C));
5759
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005760 if (const ObjCImplDecl *ImplD = dyn_cast<ObjCImplDecl>(D))
5761 if (const ObjCInterfaceDecl *IFD = ImplD->getClassInterface())
Guy Benyei11169dd2012-12-18 14:30:41 +00005762 return MakeCXCursor(IFD, getCursorTU(C));
5763
5764 return MakeCXCursor(D->getCanonicalDecl(), getCursorTU(C));
5765 }
5766
5767 return C;
5768}
5769
5770int clang_Cursor_getObjCSelectorIndex(CXCursor cursor) {
5771 return cxcursor::getSelectorIdentifierIndexAndLoc(cursor).first;
5772}
5773
5774unsigned clang_getNumOverloadedDecls(CXCursor C) {
5775 if (C.kind != CXCursor_OverloadedDeclRef)
5776 return 0;
5777
5778 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005779 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Guy Benyei11169dd2012-12-18 14:30:41 +00005780 return E->getNumDecls();
5781
5782 if (OverloadedTemplateStorage *S
5783 = Storage.dyn_cast<OverloadedTemplateStorage*>())
5784 return S->size();
5785
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005786 const Decl *D = Storage.get<const Decl *>();
5787 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00005788 return Using->shadow_size();
5789
5790 return 0;
5791}
5792
5793CXCursor clang_getOverloadedDecl(CXCursor cursor, unsigned index) {
5794 if (cursor.kind != CXCursor_OverloadedDeclRef)
5795 return clang_getNullCursor();
5796
5797 if (index >= clang_getNumOverloadedDecls(cursor))
5798 return clang_getNullCursor();
5799
5800 CXTranslationUnit TU = getCursorTU(cursor);
5801 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(cursor).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005802 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Guy Benyei11169dd2012-12-18 14:30:41 +00005803 return MakeCXCursor(E->decls_begin()[index], TU);
5804
5805 if (OverloadedTemplateStorage *S
5806 = Storage.dyn_cast<OverloadedTemplateStorage*>())
5807 return MakeCXCursor(S->begin()[index], TU);
5808
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005809 const Decl *D = Storage.get<const Decl *>();
5810 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005811 // FIXME: This is, unfortunately, linear time.
5812 UsingDecl::shadow_iterator Pos = Using->shadow_begin();
5813 std::advance(Pos, index);
5814 return MakeCXCursor(cast<UsingShadowDecl>(*Pos)->getTargetDecl(), TU);
5815 }
5816
5817 return clang_getNullCursor();
5818}
5819
5820void clang_getDefinitionSpellingAndExtent(CXCursor C,
5821 const char **startBuf,
5822 const char **endBuf,
5823 unsigned *startLine,
5824 unsigned *startColumn,
5825 unsigned *endLine,
5826 unsigned *endColumn) {
5827 assert(getCursorDecl(C) && "CXCursor has null decl");
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005828 const FunctionDecl *FD = dyn_cast<FunctionDecl>(getCursorDecl(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00005829 CompoundStmt *Body = dyn_cast<CompoundStmt>(FD->getBody());
5830
5831 SourceManager &SM = FD->getASTContext().getSourceManager();
5832 *startBuf = SM.getCharacterData(Body->getLBracLoc());
5833 *endBuf = SM.getCharacterData(Body->getRBracLoc());
5834 *startLine = SM.getSpellingLineNumber(Body->getLBracLoc());
5835 *startColumn = SM.getSpellingColumnNumber(Body->getLBracLoc());
5836 *endLine = SM.getSpellingLineNumber(Body->getRBracLoc());
5837 *endColumn = SM.getSpellingColumnNumber(Body->getRBracLoc());
5838}
5839
5840
5841CXSourceRange clang_getCursorReferenceNameRange(CXCursor C, unsigned NameFlags,
5842 unsigned PieceIndex) {
5843 RefNamePieces Pieces;
5844
5845 switch (C.kind) {
5846 case CXCursor_MemberRefExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005847 if (const MemberExpr *E = dyn_cast<MemberExpr>(getCursorExpr(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00005848 Pieces = buildPieces(NameFlags, true, E->getMemberNameInfo(),
5849 E->getQualifierLoc().getSourceRange());
5850 break;
5851
5852 case CXCursor_DeclRefExpr:
James Y Knight04ec5bf2015-12-24 02:59:37 +00005853 if (const DeclRefExpr *E = dyn_cast<DeclRefExpr>(getCursorExpr(C))) {
5854 SourceRange TemplateArgLoc(E->getLAngleLoc(), E->getRAngleLoc());
5855 Pieces =
5856 buildPieces(NameFlags, false, E->getNameInfo(),
5857 E->getQualifierLoc().getSourceRange(), &TemplateArgLoc);
5858 }
Guy Benyei11169dd2012-12-18 14:30:41 +00005859 break;
5860
5861 case CXCursor_CallExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005862 if (const CXXOperatorCallExpr *OCE =
Guy Benyei11169dd2012-12-18 14:30:41 +00005863 dyn_cast<CXXOperatorCallExpr>(getCursorExpr(C))) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005864 const Expr *Callee = OCE->getCallee();
5865 if (const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Callee))
Guy Benyei11169dd2012-12-18 14:30:41 +00005866 Callee = ICE->getSubExpr();
5867
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005868 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(Callee))
Guy Benyei11169dd2012-12-18 14:30:41 +00005869 Pieces = buildPieces(NameFlags, false, DRE->getNameInfo(),
5870 DRE->getQualifierLoc().getSourceRange());
5871 }
5872 break;
5873
5874 default:
5875 break;
5876 }
5877
5878 if (Pieces.empty()) {
5879 if (PieceIndex == 0)
5880 return clang_getCursorExtent(C);
5881 } else if (PieceIndex < Pieces.size()) {
5882 SourceRange R = Pieces[PieceIndex];
5883 if (R.isValid())
5884 return cxloc::translateSourceRange(getCursorContext(C), R);
5885 }
5886
5887 return clang_getNullRange();
5888}
5889
5890void clang_enableStackTraces(void) {
5891 llvm::sys::PrintStackTraceOnErrorSignal();
5892}
5893
5894void clang_executeOnThread(void (*fn)(void*), void *user_data,
5895 unsigned stack_size) {
5896 llvm::llvm_execute_on_thread(fn, user_data, stack_size);
5897}
5898
5899} // end: extern "C"
5900
5901//===----------------------------------------------------------------------===//
5902// Token-based Operations.
5903//===----------------------------------------------------------------------===//
5904
5905/* CXToken layout:
5906 * int_data[0]: a CXTokenKind
5907 * int_data[1]: starting token location
5908 * int_data[2]: token length
5909 * int_data[3]: reserved
5910 * ptr_data: for identifiers and keywords, an IdentifierInfo*.
5911 * otherwise unused.
5912 */
5913extern "C" {
5914
5915CXTokenKind clang_getTokenKind(CXToken CXTok) {
5916 return static_cast<CXTokenKind>(CXTok.int_data[0]);
5917}
5918
5919CXString clang_getTokenSpelling(CXTranslationUnit TU, CXToken CXTok) {
5920 switch (clang_getTokenKind(CXTok)) {
5921 case CXToken_Identifier:
5922 case CXToken_Keyword:
5923 // We know we have an IdentifierInfo*, so use that.
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005924 return cxstring::createRef(static_cast<IdentifierInfo *>(CXTok.ptr_data)
Guy Benyei11169dd2012-12-18 14:30:41 +00005925 ->getNameStart());
5926
5927 case CXToken_Literal: {
5928 // We have stashed the starting pointer in the ptr_data field. Use it.
5929 const char *Text = static_cast<const char *>(CXTok.ptr_data);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00005930 return cxstring::createDup(StringRef(Text, CXTok.int_data[2]));
Guy Benyei11169dd2012-12-18 14:30:41 +00005931 }
5932
5933 case CXToken_Punctuation:
5934 case CXToken_Comment:
5935 break;
5936 }
5937
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005938 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005939 LOG_BAD_TU(TU);
5940 return cxstring::createEmpty();
5941 }
5942
Guy Benyei11169dd2012-12-18 14:30:41 +00005943 // We have to find the starting buffer pointer the hard way, by
5944 // deconstructing the source location.
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005945 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005946 if (!CXXUnit)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00005947 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00005948
5949 SourceLocation Loc = SourceLocation::getFromRawEncoding(CXTok.int_data[1]);
5950 std::pair<FileID, unsigned> LocInfo
5951 = CXXUnit->getSourceManager().getDecomposedSpellingLoc(Loc);
5952 bool Invalid = false;
5953 StringRef Buffer
5954 = CXXUnit->getSourceManager().getBufferData(LocInfo.first, &Invalid);
5955 if (Invalid)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00005956 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00005957
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00005958 return cxstring::createDup(Buffer.substr(LocInfo.second, CXTok.int_data[2]));
Guy Benyei11169dd2012-12-18 14:30:41 +00005959}
5960
5961CXSourceLocation clang_getTokenLocation(CXTranslationUnit TU, CXToken CXTok) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005962 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005963 LOG_BAD_TU(TU);
5964 return clang_getNullLocation();
5965 }
5966
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005967 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005968 if (!CXXUnit)
5969 return clang_getNullLocation();
5970
5971 return cxloc::translateSourceLocation(CXXUnit->getASTContext(),
5972 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
5973}
5974
5975CXSourceRange clang_getTokenExtent(CXTranslationUnit TU, CXToken CXTok) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005976 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005977 LOG_BAD_TU(TU);
5978 return clang_getNullRange();
5979 }
5980
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005981 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005982 if (!CXXUnit)
5983 return clang_getNullRange();
5984
5985 return cxloc::translateSourceRange(CXXUnit->getASTContext(),
5986 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
5987}
5988
5989static void getTokens(ASTUnit *CXXUnit, SourceRange Range,
5990 SmallVectorImpl<CXToken> &CXTokens) {
5991 SourceManager &SourceMgr = CXXUnit->getSourceManager();
5992 std::pair<FileID, unsigned> BeginLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005993 = SourceMgr.getDecomposedSpellingLoc(Range.getBegin());
Guy Benyei11169dd2012-12-18 14:30:41 +00005994 std::pair<FileID, unsigned> EndLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005995 = SourceMgr.getDecomposedSpellingLoc(Range.getEnd());
Guy Benyei11169dd2012-12-18 14:30:41 +00005996
5997 // Cannot tokenize across files.
5998 if (BeginLocInfo.first != EndLocInfo.first)
5999 return;
6000
6001 // Create a lexer
6002 bool Invalid = false;
6003 StringRef Buffer
6004 = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
6005 if (Invalid)
6006 return;
6007
6008 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
6009 CXXUnit->getASTContext().getLangOpts(),
6010 Buffer.begin(), Buffer.data() + BeginLocInfo.second, Buffer.end());
6011 Lex.SetCommentRetentionState(true);
6012
6013 // Lex tokens until we hit the end of the range.
6014 const char *EffectiveBufferEnd = Buffer.data() + EndLocInfo.second;
6015 Token Tok;
6016 bool previousWasAt = false;
6017 do {
6018 // Lex the next token
6019 Lex.LexFromRawLexer(Tok);
6020 if (Tok.is(tok::eof))
6021 break;
6022
6023 // Initialize the CXToken.
6024 CXToken CXTok;
6025
6026 // - Common fields
6027 CXTok.int_data[1] = Tok.getLocation().getRawEncoding();
6028 CXTok.int_data[2] = Tok.getLength();
6029 CXTok.int_data[3] = 0;
6030
6031 // - Kind-specific fields
6032 if (Tok.isLiteral()) {
6033 CXTok.int_data[0] = CXToken_Literal;
Dmitri Gribenkof9304482013-01-23 15:56:07 +00006034 CXTok.ptr_data = const_cast<char *>(Tok.getLiteralData());
Guy Benyei11169dd2012-12-18 14:30:41 +00006035 } else if (Tok.is(tok::raw_identifier)) {
6036 // Lookup the identifier to determine whether we have a keyword.
6037 IdentifierInfo *II
6038 = CXXUnit->getPreprocessor().LookUpIdentifierInfo(Tok);
6039
6040 if ((II->getObjCKeywordID() != tok::objc_not_keyword) && previousWasAt) {
6041 CXTok.int_data[0] = CXToken_Keyword;
6042 }
6043 else {
6044 CXTok.int_data[0] = Tok.is(tok::identifier)
6045 ? CXToken_Identifier
6046 : CXToken_Keyword;
6047 }
6048 CXTok.ptr_data = II;
6049 } else if (Tok.is(tok::comment)) {
6050 CXTok.int_data[0] = CXToken_Comment;
Craig Topper69186e72014-06-08 08:38:04 +00006051 CXTok.ptr_data = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006052 } else {
6053 CXTok.int_data[0] = CXToken_Punctuation;
Craig Topper69186e72014-06-08 08:38:04 +00006054 CXTok.ptr_data = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006055 }
6056 CXTokens.push_back(CXTok);
6057 previousWasAt = Tok.is(tok::at);
6058 } while (Lex.getBufferLocation() <= EffectiveBufferEnd);
6059}
6060
6061void clang_tokenize(CXTranslationUnit TU, CXSourceRange Range,
6062 CXToken **Tokens, unsigned *NumTokens) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006063 LOG_FUNC_SECTION {
6064 *Log << TU << ' ' << Range;
6065 }
6066
Guy Benyei11169dd2012-12-18 14:30:41 +00006067 if (Tokens)
Craig Topper69186e72014-06-08 08:38:04 +00006068 *Tokens = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006069 if (NumTokens)
6070 *NumTokens = 0;
6071
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006072 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006073 LOG_BAD_TU(TU);
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00006074 return;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006075 }
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00006076
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006077 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00006078 if (!CXXUnit || !Tokens || !NumTokens)
6079 return;
6080
6081 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
6082
6083 SourceRange R = cxloc::translateCXSourceRange(Range);
6084 if (R.isInvalid())
6085 return;
6086
6087 SmallVector<CXToken, 32> CXTokens;
6088 getTokens(CXXUnit, R, CXTokens);
6089
6090 if (CXTokens.empty())
6091 return;
6092
6093 *Tokens = (CXToken *)malloc(sizeof(CXToken) * CXTokens.size());
6094 memmove(*Tokens, CXTokens.data(), sizeof(CXToken) * CXTokens.size());
6095 *NumTokens = CXTokens.size();
6096}
6097
6098void clang_disposeTokens(CXTranslationUnit TU,
6099 CXToken *Tokens, unsigned NumTokens) {
6100 free(Tokens);
6101}
6102
6103} // end: extern "C"
6104
6105//===----------------------------------------------------------------------===//
6106// Token annotation APIs.
6107//===----------------------------------------------------------------------===//
6108
Guy Benyei11169dd2012-12-18 14:30:41 +00006109static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
6110 CXCursor parent,
6111 CXClientData client_data);
6112static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
6113 CXClientData client_data);
6114
6115namespace {
6116class AnnotateTokensWorker {
Guy Benyei11169dd2012-12-18 14:30:41 +00006117 CXToken *Tokens;
6118 CXCursor *Cursors;
6119 unsigned NumTokens;
6120 unsigned TokIdx;
6121 unsigned PreprocessingTokIdx;
6122 CursorVisitor AnnotateVis;
6123 SourceManager &SrcMgr;
6124 bool HasContextSensitiveKeywords;
6125
6126 struct PostChildrenInfo {
6127 CXCursor Cursor;
6128 SourceRange CursorRange;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00006129 unsigned BeforeReachingCursorIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00006130 unsigned BeforeChildrenTokenIdx;
6131 };
Dmitri Gribenkof8579502013-01-12 19:30:44 +00006132 SmallVector<PostChildrenInfo, 8> PostChildrenInfos;
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00006133
6134 CXToken &getTok(unsigned Idx) {
6135 assert(Idx < NumTokens);
6136 return Tokens[Idx];
6137 }
6138 const CXToken &getTok(unsigned Idx) const {
6139 assert(Idx < NumTokens);
6140 return Tokens[Idx];
6141 }
Guy Benyei11169dd2012-12-18 14:30:41 +00006142 bool MoreTokens() const { return TokIdx < NumTokens; }
6143 unsigned NextToken() const { return TokIdx; }
6144 void AdvanceToken() { ++TokIdx; }
6145 SourceLocation GetTokenLoc(unsigned tokI) {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00006146 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[1]);
Guy Benyei11169dd2012-12-18 14:30:41 +00006147 }
6148 bool isFunctionMacroToken(unsigned tokI) const {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00006149 return getTok(tokI).int_data[3] != 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00006150 }
6151 SourceLocation getFunctionMacroTokenLoc(unsigned tokI) const {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00006152 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[3]);
Guy Benyei11169dd2012-12-18 14:30:41 +00006153 }
6154
6155 void annotateAndAdvanceTokens(CXCursor, RangeComparisonResult, SourceRange);
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00006156 bool annotateAndAdvanceFunctionMacroTokens(CXCursor, RangeComparisonResult,
Guy Benyei11169dd2012-12-18 14:30:41 +00006157 SourceRange);
6158
6159public:
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006160 AnnotateTokensWorker(CXToken *tokens, CXCursor *cursors, unsigned numTokens,
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006161 CXTranslationUnit TU, SourceRange RegionOfInterest)
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006162 : Tokens(tokens), Cursors(cursors),
Guy Benyei11169dd2012-12-18 14:30:41 +00006163 NumTokens(numTokens), TokIdx(0), PreprocessingTokIdx(0),
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006164 AnnotateVis(TU,
Guy Benyei11169dd2012-12-18 14:30:41 +00006165 AnnotateTokensVisitor, this,
6166 /*VisitPreprocessorLast=*/true,
6167 /*VisitIncludedEntities=*/false,
6168 RegionOfInterest,
6169 /*VisitDeclsOnly=*/false,
6170 AnnotateTokensPostChildrenVisitor),
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006171 SrcMgr(cxtu::getASTUnit(TU)->getSourceManager()),
Guy Benyei11169dd2012-12-18 14:30:41 +00006172 HasContextSensitiveKeywords(false) { }
6173
6174 void VisitChildren(CXCursor C) { AnnotateVis.VisitChildren(C); }
6175 enum CXChildVisitResult Visit(CXCursor cursor, CXCursor parent);
6176 bool postVisitChildren(CXCursor cursor);
6177 void AnnotateTokens();
6178
6179 /// \brief Determine whether the annotator saw any cursors that have
6180 /// context-sensitive keywords.
6181 bool hasContextSensitiveKeywords() const {
6182 return HasContextSensitiveKeywords;
6183 }
6184
6185 ~AnnotateTokensWorker() {
6186 assert(PostChildrenInfos.empty());
6187 }
6188};
Alexander Kornienkoab9db512015-06-22 23:07:51 +00006189}
Guy Benyei11169dd2012-12-18 14:30:41 +00006190
6191void AnnotateTokensWorker::AnnotateTokens() {
6192 // Walk the AST within the region of interest, annotating tokens
6193 // along the way.
6194 AnnotateVis.visitFileRegion();
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006195}
Guy Benyei11169dd2012-12-18 14:30:41 +00006196
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006197static inline void updateCursorAnnotation(CXCursor &Cursor,
6198 const CXCursor &updateC) {
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00006199 if (clang_isInvalid(updateC.kind) || !clang_isInvalid(Cursor.kind))
Guy Benyei11169dd2012-12-18 14:30:41 +00006200 return;
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006201 Cursor = updateC;
Guy Benyei11169dd2012-12-18 14:30:41 +00006202}
6203
6204/// \brief It annotates and advances tokens with a cursor until the comparison
6205//// between the cursor location and the source range is the same as
6206/// \arg compResult.
6207///
6208/// Pass RangeBefore to annotate tokens with a cursor until a range is reached.
6209/// Pass RangeOverlap to annotate tokens inside a range.
6210void AnnotateTokensWorker::annotateAndAdvanceTokens(CXCursor updateC,
6211 RangeComparisonResult compResult,
6212 SourceRange range) {
6213 while (MoreTokens()) {
6214 const unsigned I = NextToken();
6215 if (isFunctionMacroToken(I))
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00006216 if (!annotateAndAdvanceFunctionMacroTokens(updateC, compResult, range))
6217 return;
Guy Benyei11169dd2012-12-18 14:30:41 +00006218
6219 SourceLocation TokLoc = GetTokenLoc(I);
6220 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006221 updateCursorAnnotation(Cursors[I], updateC);
Guy Benyei11169dd2012-12-18 14:30:41 +00006222 AdvanceToken();
6223 continue;
6224 }
6225 break;
6226 }
6227}
6228
6229/// \brief Special annotation handling for macro argument tokens.
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00006230/// \returns true if it advanced beyond all macro tokens, false otherwise.
6231bool AnnotateTokensWorker::annotateAndAdvanceFunctionMacroTokens(
Guy Benyei11169dd2012-12-18 14:30:41 +00006232 CXCursor updateC,
6233 RangeComparisonResult compResult,
6234 SourceRange range) {
6235 assert(MoreTokens());
6236 assert(isFunctionMacroToken(NextToken()) &&
6237 "Should be called only for macro arg tokens");
6238
6239 // This works differently than annotateAndAdvanceTokens; because expanded
6240 // macro arguments can have arbitrary translation-unit source order, we do not
6241 // advance the token index one by one until a token fails the range test.
6242 // We only advance once past all of the macro arg tokens if all of them
6243 // pass the range test. If one of them fails we keep the token index pointing
6244 // at the start of the macro arg tokens so that the failing token will be
6245 // annotated by a subsequent annotation try.
6246
6247 bool atLeastOneCompFail = false;
6248
6249 unsigned I = NextToken();
6250 for (; I < NumTokens && isFunctionMacroToken(I); ++I) {
6251 SourceLocation TokLoc = getFunctionMacroTokenLoc(I);
6252 if (TokLoc.isFileID())
6253 continue; // not macro arg token, it's parens or comma.
6254 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
6255 if (clang_isInvalid(clang_getCursorKind(Cursors[I])))
6256 Cursors[I] = updateC;
6257 } else
6258 atLeastOneCompFail = true;
6259 }
6260
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00006261 if (atLeastOneCompFail)
6262 return false;
6263
6264 TokIdx = I; // All of the tokens were handled, advance beyond all of them.
6265 return true;
Guy Benyei11169dd2012-12-18 14:30:41 +00006266}
6267
6268enum CXChildVisitResult
6269AnnotateTokensWorker::Visit(CXCursor cursor, CXCursor parent) {
Guy Benyei11169dd2012-12-18 14:30:41 +00006270 SourceRange cursorRange = getRawCursorExtent(cursor);
6271 if (cursorRange.isInvalid())
6272 return CXChildVisit_Recurse;
6273
6274 if (!HasContextSensitiveKeywords) {
6275 // Objective-C properties can have context-sensitive keywords.
6276 if (cursor.kind == CXCursor_ObjCPropertyDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006277 if (const ObjCPropertyDecl *Property
Guy Benyei11169dd2012-12-18 14:30:41 +00006278 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(cursor)))
6279 HasContextSensitiveKeywords = Property->getPropertyAttributesAsWritten() != 0;
6280 }
6281 // Objective-C methods can have context-sensitive keywords.
6282 else if (cursor.kind == CXCursor_ObjCInstanceMethodDecl ||
6283 cursor.kind == CXCursor_ObjCClassMethodDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006284 if (const ObjCMethodDecl *Method
Guy Benyei11169dd2012-12-18 14:30:41 +00006285 = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
6286 if (Method->getObjCDeclQualifier())
6287 HasContextSensitiveKeywords = true;
6288 else {
Aaron Ballman43b68be2014-03-07 17:50:17 +00006289 for (const auto *P : Method->params()) {
6290 if (P->getObjCDeclQualifier()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00006291 HasContextSensitiveKeywords = true;
6292 break;
6293 }
6294 }
6295 }
6296 }
6297 }
6298 // C++ methods can have context-sensitive keywords.
6299 else if (cursor.kind == CXCursor_CXXMethod) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006300 if (const CXXMethodDecl *Method
Guy Benyei11169dd2012-12-18 14:30:41 +00006301 = dyn_cast_or_null<CXXMethodDecl>(getCursorDecl(cursor))) {
6302 if (Method->hasAttr<FinalAttr>() || Method->hasAttr<OverrideAttr>())
6303 HasContextSensitiveKeywords = true;
6304 }
6305 }
6306 // C++ classes can have context-sensitive keywords.
6307 else if (cursor.kind == CXCursor_StructDecl ||
6308 cursor.kind == CXCursor_ClassDecl ||
6309 cursor.kind == CXCursor_ClassTemplate ||
6310 cursor.kind == CXCursor_ClassTemplatePartialSpecialization) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006311 if (const Decl *D = getCursorDecl(cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +00006312 if (D->hasAttr<FinalAttr>())
6313 HasContextSensitiveKeywords = true;
6314 }
6315 }
Argyrios Kyrtzidis990b3862013-06-04 18:24:30 +00006316
6317 // Don't override a property annotation with its getter/setter method.
6318 if (cursor.kind == CXCursor_ObjCInstanceMethodDecl &&
6319 parent.kind == CXCursor_ObjCPropertyDecl)
6320 return CXChildVisit_Continue;
Guy Benyei11169dd2012-12-18 14:30:41 +00006321
6322 if (clang_isPreprocessing(cursor.kind)) {
6323 // Items in the preprocessing record are kept separate from items in
6324 // declarations, so we keep a separate token index.
6325 unsigned SavedTokIdx = TokIdx;
6326 TokIdx = PreprocessingTokIdx;
6327
6328 // Skip tokens up until we catch up to the beginning of the preprocessing
6329 // entry.
6330 while (MoreTokens()) {
6331 const unsigned I = NextToken();
6332 SourceLocation TokLoc = GetTokenLoc(I);
6333 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
6334 case RangeBefore:
6335 AdvanceToken();
6336 continue;
6337 case RangeAfter:
6338 case RangeOverlap:
6339 break;
6340 }
6341 break;
6342 }
6343
6344 // Look at all of the tokens within this range.
6345 while (MoreTokens()) {
6346 const unsigned I = NextToken();
6347 SourceLocation TokLoc = GetTokenLoc(I);
6348 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
6349 case RangeBefore:
6350 llvm_unreachable("Infeasible");
6351 case RangeAfter:
6352 break;
6353 case RangeOverlap:
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00006354 // For macro expansions, just note where the beginning of the macro
6355 // expansion occurs.
6356 if (cursor.kind == CXCursor_MacroExpansion) {
6357 if (TokLoc == cursorRange.getBegin())
6358 Cursors[I] = cursor;
6359 AdvanceToken();
6360 break;
6361 }
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006362 // We may have already annotated macro names inside macro definitions.
6363 if (Cursors[I].kind != CXCursor_MacroExpansion)
6364 Cursors[I] = cursor;
Guy Benyei11169dd2012-12-18 14:30:41 +00006365 AdvanceToken();
Guy Benyei11169dd2012-12-18 14:30:41 +00006366 continue;
6367 }
6368 break;
6369 }
6370
6371 // Save the preprocessing token index; restore the non-preprocessing
6372 // token index.
6373 PreprocessingTokIdx = TokIdx;
6374 TokIdx = SavedTokIdx;
6375 return CXChildVisit_Recurse;
6376 }
6377
6378 if (cursorRange.isInvalid())
6379 return CXChildVisit_Continue;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00006380
6381 unsigned BeforeReachingCursorIdx = NextToken();
Guy Benyei11169dd2012-12-18 14:30:41 +00006382 const enum CXCursorKind cursorK = clang_getCursorKind(cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00006383 const enum CXCursorKind K = clang_getCursorKind(parent);
6384 const CXCursor updateC =
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00006385 (clang_isInvalid(K) || K == CXCursor_TranslationUnit ||
6386 // Attributes are annotated out-of-order, skip tokens until we reach it.
6387 clang_isAttribute(cursor.kind))
Guy Benyei11169dd2012-12-18 14:30:41 +00006388 ? clang_getNullCursor() : parent;
6389
6390 annotateAndAdvanceTokens(updateC, RangeBefore, cursorRange);
6391
6392 // Avoid having the cursor of an expression "overwrite" the annotation of the
6393 // variable declaration that it belongs to.
6394 // This can happen for C++ constructor expressions whose range generally
6395 // include the variable declaration, e.g.:
6396 // MyCXXClass foo; // Make sure we don't annotate 'foo' as a CallExpr cursor.
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00006397 if (clang_isExpression(cursorK) && MoreTokens()) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00006398 const Expr *E = getCursorExpr(cursor);
Dmitri Gribenkoa1691182013-01-26 18:12:08 +00006399 if (const Decl *D = getCursorParentDecl(cursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00006400 const unsigned I = NextToken();
6401 if (E->getLocStart().isValid() && D->getLocation().isValid() &&
6402 E->getLocStart() == D->getLocation() &&
6403 E->getLocStart() == GetTokenLoc(I)) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006404 updateCursorAnnotation(Cursors[I], updateC);
Guy Benyei11169dd2012-12-18 14:30:41 +00006405 AdvanceToken();
6406 }
6407 }
6408 }
6409
6410 // Before recursing into the children keep some state that we are going
6411 // to use in the AnnotateTokensWorker::postVisitChildren callback to do some
6412 // extra work after the child nodes are visited.
6413 // Note that we don't call VisitChildren here to avoid traversing statements
6414 // code-recursively which can blow the stack.
6415
6416 PostChildrenInfo Info;
6417 Info.Cursor = cursor;
6418 Info.CursorRange = cursorRange;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00006419 Info.BeforeReachingCursorIdx = BeforeReachingCursorIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00006420 Info.BeforeChildrenTokenIdx = NextToken();
6421 PostChildrenInfos.push_back(Info);
6422
6423 return CXChildVisit_Recurse;
6424}
6425
6426bool AnnotateTokensWorker::postVisitChildren(CXCursor cursor) {
6427 if (PostChildrenInfos.empty())
6428 return false;
6429 const PostChildrenInfo &Info = PostChildrenInfos.back();
6430 if (!clang_equalCursors(Info.Cursor, cursor))
6431 return false;
6432
6433 const unsigned BeforeChildren = Info.BeforeChildrenTokenIdx;
6434 const unsigned AfterChildren = NextToken();
6435 SourceRange cursorRange = Info.CursorRange;
6436
6437 // Scan the tokens that are at the end of the cursor, but are not captured
6438 // but the child cursors.
6439 annotateAndAdvanceTokens(cursor, RangeOverlap, cursorRange);
6440
6441 // Scan the tokens that are at the beginning of the cursor, but are not
6442 // capture by the child cursors.
6443 for (unsigned I = BeforeChildren; I != AfterChildren; ++I) {
6444 if (!clang_isInvalid(clang_getCursorKind(Cursors[I])))
6445 break;
6446
6447 Cursors[I] = cursor;
6448 }
6449
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00006450 // Attributes are annotated out-of-order, rewind TokIdx to when we first
6451 // encountered the attribute cursor.
6452 if (clang_isAttribute(cursor.kind))
6453 TokIdx = Info.BeforeReachingCursorIdx;
6454
Guy Benyei11169dd2012-12-18 14:30:41 +00006455 PostChildrenInfos.pop_back();
6456 return false;
6457}
6458
6459static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
6460 CXCursor parent,
6461 CXClientData client_data) {
6462 return static_cast<AnnotateTokensWorker*>(client_data)->Visit(cursor, parent);
6463}
6464
6465static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
6466 CXClientData client_data) {
6467 return static_cast<AnnotateTokensWorker*>(client_data)->
6468 postVisitChildren(cursor);
6469}
6470
6471namespace {
6472
6473/// \brief Uses the macro expansions in the preprocessing record to find
6474/// and mark tokens that are macro arguments. This info is used by the
6475/// AnnotateTokensWorker.
6476class MarkMacroArgTokensVisitor {
6477 SourceManager &SM;
6478 CXToken *Tokens;
6479 unsigned NumTokens;
6480 unsigned CurIdx;
6481
6482public:
6483 MarkMacroArgTokensVisitor(SourceManager &SM,
6484 CXToken *tokens, unsigned numTokens)
6485 : SM(SM), Tokens(tokens), NumTokens(numTokens), CurIdx(0) { }
6486
6487 CXChildVisitResult visit(CXCursor cursor, CXCursor parent) {
6488 if (cursor.kind != CXCursor_MacroExpansion)
6489 return CXChildVisit_Continue;
6490
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006491 SourceRange macroRange = getCursorMacroExpansion(cursor).getSourceRange();
Guy Benyei11169dd2012-12-18 14:30:41 +00006492 if (macroRange.getBegin() == macroRange.getEnd())
6493 return CXChildVisit_Continue; // it's not a function macro.
6494
6495 for (; CurIdx < NumTokens; ++CurIdx) {
6496 if (!SM.isBeforeInTranslationUnit(getTokenLoc(CurIdx),
6497 macroRange.getBegin()))
6498 break;
6499 }
6500
6501 if (CurIdx == NumTokens)
6502 return CXChildVisit_Break;
6503
6504 for (; CurIdx < NumTokens; ++CurIdx) {
6505 SourceLocation tokLoc = getTokenLoc(CurIdx);
6506 if (!SM.isBeforeInTranslationUnit(tokLoc, macroRange.getEnd()))
6507 break;
6508
6509 setFunctionMacroTokenLoc(CurIdx, SM.getMacroArgExpandedLocation(tokLoc));
6510 }
6511
6512 if (CurIdx == NumTokens)
6513 return CXChildVisit_Break;
6514
6515 return CXChildVisit_Continue;
6516 }
6517
6518private:
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00006519 CXToken &getTok(unsigned Idx) {
6520 assert(Idx < NumTokens);
6521 return Tokens[Idx];
6522 }
6523 const CXToken &getTok(unsigned Idx) const {
6524 assert(Idx < NumTokens);
6525 return Tokens[Idx];
6526 }
6527
Guy Benyei11169dd2012-12-18 14:30:41 +00006528 SourceLocation getTokenLoc(unsigned tokI) {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00006529 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[1]);
Guy Benyei11169dd2012-12-18 14:30:41 +00006530 }
6531
6532 void setFunctionMacroTokenLoc(unsigned tokI, SourceLocation loc) {
6533 // The third field is reserved and currently not used. Use it here
6534 // to mark macro arg expanded tokens with their expanded locations.
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00006535 getTok(tokI).int_data[3] = loc.getRawEncoding();
Guy Benyei11169dd2012-12-18 14:30:41 +00006536 }
6537};
6538
6539} // end anonymous namespace
6540
6541static CXChildVisitResult
6542MarkMacroArgTokensVisitorDelegate(CXCursor cursor, CXCursor parent,
6543 CXClientData client_data) {
6544 return static_cast<MarkMacroArgTokensVisitor*>(client_data)->visit(cursor,
6545 parent);
6546}
6547
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006548/// \brief Used by \c annotatePreprocessorTokens.
6549/// \returns true if lexing was finished, false otherwise.
6550static bool lexNext(Lexer &Lex, Token &Tok,
6551 unsigned &NextIdx, unsigned NumTokens) {
6552 if (NextIdx >= NumTokens)
6553 return true;
6554
6555 ++NextIdx;
6556 Lex.LexFromRawLexer(Tok);
Alexander Kornienko1a9f1842015-12-28 15:24:08 +00006557 return Tok.is(tok::eof);
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006558}
6559
Guy Benyei11169dd2012-12-18 14:30:41 +00006560static void annotatePreprocessorTokens(CXTranslationUnit TU,
6561 SourceRange RegionOfInterest,
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006562 CXCursor *Cursors,
6563 CXToken *Tokens,
6564 unsigned NumTokens) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006565 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00006566
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006567 Preprocessor &PP = CXXUnit->getPreprocessor();
Guy Benyei11169dd2012-12-18 14:30:41 +00006568 SourceManager &SourceMgr = CXXUnit->getSourceManager();
6569 std::pair<FileID, unsigned> BeginLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00006570 = SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getBegin());
Guy Benyei11169dd2012-12-18 14:30:41 +00006571 std::pair<FileID, unsigned> EndLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00006572 = SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getEnd());
Guy Benyei11169dd2012-12-18 14:30:41 +00006573
6574 if (BeginLocInfo.first != EndLocInfo.first)
6575 return;
6576
6577 StringRef Buffer;
6578 bool Invalid = false;
6579 Buffer = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
6580 if (Buffer.empty() || Invalid)
6581 return;
6582
6583 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
6584 CXXUnit->getASTContext().getLangOpts(),
6585 Buffer.begin(), Buffer.data() + BeginLocInfo.second,
6586 Buffer.end());
6587 Lex.SetCommentRetentionState(true);
6588
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006589 unsigned NextIdx = 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00006590 // Lex tokens in raw mode until we hit the end of the range, to avoid
6591 // entering #includes or expanding macros.
6592 while (true) {
6593 Token Tok;
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006594 if (lexNext(Lex, Tok, NextIdx, NumTokens))
6595 break;
6596 unsigned TokIdx = NextIdx-1;
6597 assert(Tok.getLocation() ==
6598 SourceLocation::getFromRawEncoding(Tokens[TokIdx].int_data[1]));
Guy Benyei11169dd2012-12-18 14:30:41 +00006599
6600 reprocess:
6601 if (Tok.is(tok::hash) && Tok.isAtStartOfLine()) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006602 // We have found a preprocessing directive. Annotate the tokens
6603 // appropriately.
Guy Benyei11169dd2012-12-18 14:30:41 +00006604 //
6605 // FIXME: Some simple tests here could identify macro definitions and
6606 // #undefs, to provide specific cursor kinds for those.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006607
6608 SourceLocation BeginLoc = Tok.getLocation();
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006609 if (lexNext(Lex, Tok, NextIdx, NumTokens))
6610 break;
6611
Craig Topper69186e72014-06-08 08:38:04 +00006612 MacroInfo *MI = nullptr;
Alp Toker2d57cea2014-05-17 04:53:25 +00006613 if (Tok.is(tok::raw_identifier) && Tok.getRawIdentifier() == "define") {
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006614 if (lexNext(Lex, Tok, NextIdx, NumTokens))
6615 break;
6616
6617 if (Tok.is(tok::raw_identifier)) {
Alp Toker2d57cea2014-05-17 04:53:25 +00006618 IdentifierInfo &II =
6619 PP.getIdentifierTable().get(Tok.getRawIdentifier());
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006620 SourceLocation MappedTokLoc =
6621 CXXUnit->mapLocationToPreamble(Tok.getLocation());
6622 MI = getMacroInfo(II, MappedTokLoc, TU);
6623 }
6624 }
6625
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006626 bool finished = false;
Guy Benyei11169dd2012-12-18 14:30:41 +00006627 do {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006628 if (lexNext(Lex, Tok, NextIdx, NumTokens)) {
6629 finished = true;
6630 break;
6631 }
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006632 // If we are in a macro definition, check if the token was ever a
6633 // macro name and annotate it if that's the case.
6634 if (MI) {
6635 SourceLocation SaveLoc = Tok.getLocation();
6636 Tok.setLocation(CXXUnit->mapLocationToPreamble(SaveLoc));
Richard Smith66a81862015-05-04 02:25:31 +00006637 MacroDefinitionRecord *MacroDef =
6638 checkForMacroInMacroDefinition(MI, Tok, TU);
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006639 Tok.setLocation(SaveLoc);
6640 if (MacroDef)
Richard Smith66a81862015-05-04 02:25:31 +00006641 Cursors[NextIdx - 1] =
6642 MakeMacroExpansionCursor(MacroDef, Tok.getLocation(), TU);
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006643 }
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006644 } while (!Tok.isAtStartOfLine());
6645
6646 unsigned LastIdx = finished ? NextIdx-1 : NextIdx-2;
6647 assert(TokIdx <= LastIdx);
6648 SourceLocation EndLoc =
6649 SourceLocation::getFromRawEncoding(Tokens[LastIdx].int_data[1]);
6650 CXCursor Cursor =
6651 MakePreprocessingDirectiveCursor(SourceRange(BeginLoc, EndLoc), TU);
6652
6653 for (; TokIdx <= LastIdx; ++TokIdx)
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006654 updateCursorAnnotation(Cursors[TokIdx], Cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00006655
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006656 if (finished)
6657 break;
6658 goto reprocess;
Guy Benyei11169dd2012-12-18 14:30:41 +00006659 }
Guy Benyei11169dd2012-12-18 14:30:41 +00006660 }
6661}
6662
6663// This gets run a separate thread to avoid stack blowout.
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00006664static void clang_annotateTokensImpl(CXTranslationUnit TU, ASTUnit *CXXUnit,
6665 CXToken *Tokens, unsigned NumTokens,
6666 CXCursor *Cursors) {
Dmitri Gribenko183436e2013-01-26 21:49:50 +00006667 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00006668 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
6669 setThreadBackgroundPriority();
6670
6671 // Determine the region of interest, which contains all of the tokens.
6672 SourceRange RegionOfInterest;
6673 RegionOfInterest.setBegin(
6674 cxloc::translateSourceLocation(clang_getTokenLocation(TU, Tokens[0])));
6675 RegionOfInterest.setEnd(
6676 cxloc::translateSourceLocation(clang_getTokenLocation(TU,
6677 Tokens[NumTokens-1])));
6678
Guy Benyei11169dd2012-12-18 14:30:41 +00006679 // Relex the tokens within the source range to look for preprocessing
6680 // directives.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006681 annotatePreprocessorTokens(TU, RegionOfInterest, Cursors, Tokens, NumTokens);
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00006682
6683 // If begin location points inside a macro argument, set it to the expansion
6684 // location so we can have the full context when annotating semantically.
6685 {
6686 SourceManager &SM = CXXUnit->getSourceManager();
6687 SourceLocation Loc =
6688 SM.getMacroArgExpandedLocation(RegionOfInterest.getBegin());
6689 if (Loc.isMacroID())
6690 RegionOfInterest.setBegin(SM.getExpansionLoc(Loc));
6691 }
6692
Guy Benyei11169dd2012-12-18 14:30:41 +00006693 if (CXXUnit->getPreprocessor().getPreprocessingRecord()) {
6694 // Search and mark tokens that are macro argument expansions.
6695 MarkMacroArgTokensVisitor Visitor(CXXUnit->getSourceManager(),
6696 Tokens, NumTokens);
6697 CursorVisitor MacroArgMarker(TU,
6698 MarkMacroArgTokensVisitorDelegate, &Visitor,
6699 /*VisitPreprocessorLast=*/true,
6700 /*VisitIncludedEntities=*/false,
6701 RegionOfInterest);
6702 MacroArgMarker.visitPreprocessedEntitiesInRegion();
6703 }
6704
6705 // Annotate all of the source locations in the region of interest that map to
6706 // a specific cursor.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006707 AnnotateTokensWorker W(Tokens, Cursors, NumTokens, TU, RegionOfInterest);
Guy Benyei11169dd2012-12-18 14:30:41 +00006708
6709 // FIXME: We use a ridiculous stack size here because the data-recursion
6710 // algorithm uses a large stack frame than the non-data recursive version,
6711 // and AnnotationTokensWorker currently transforms the data-recursion
6712 // algorithm back into a traditional recursion by explicitly calling
6713 // VisitChildren(). We will need to remove this explicit recursive call.
6714 W.AnnotateTokens();
6715
6716 // If we ran into any entities that involve context-sensitive keywords,
6717 // take another pass through the tokens to mark them as such.
6718 if (W.hasContextSensitiveKeywords()) {
6719 for (unsigned I = 0; I != NumTokens; ++I) {
6720 if (clang_getTokenKind(Tokens[I]) != CXToken_Identifier)
6721 continue;
6722
6723 if (Cursors[I].kind == CXCursor_ObjCPropertyDecl) {
6724 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006725 if (const ObjCPropertyDecl *Property
Guy Benyei11169dd2012-12-18 14:30:41 +00006726 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(Cursors[I]))) {
6727 if (Property->getPropertyAttributesAsWritten() != 0 &&
6728 llvm::StringSwitch<bool>(II->getName())
6729 .Case("readonly", true)
6730 .Case("assign", true)
6731 .Case("unsafe_unretained", true)
6732 .Case("readwrite", true)
6733 .Case("retain", true)
6734 .Case("copy", true)
6735 .Case("nonatomic", true)
6736 .Case("atomic", true)
6737 .Case("getter", true)
6738 .Case("setter", true)
6739 .Case("strong", true)
6740 .Case("weak", true)
6741 .Default(false))
6742 Tokens[I].int_data[0] = CXToken_Keyword;
6743 }
6744 continue;
6745 }
6746
6747 if (Cursors[I].kind == CXCursor_ObjCInstanceMethodDecl ||
6748 Cursors[I].kind == CXCursor_ObjCClassMethodDecl) {
6749 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
6750 if (llvm::StringSwitch<bool>(II->getName())
6751 .Case("in", true)
6752 .Case("out", true)
6753 .Case("inout", true)
6754 .Case("oneway", true)
6755 .Case("bycopy", true)
6756 .Case("byref", true)
6757 .Default(false))
6758 Tokens[I].int_data[0] = CXToken_Keyword;
6759 continue;
6760 }
6761
6762 if (Cursors[I].kind == CXCursor_CXXFinalAttr ||
6763 Cursors[I].kind == CXCursor_CXXOverrideAttr) {
6764 Tokens[I].int_data[0] = CXToken_Keyword;
6765 continue;
6766 }
6767 }
6768 }
6769}
6770
6771extern "C" {
6772
6773void clang_annotateTokens(CXTranslationUnit TU,
6774 CXToken *Tokens, unsigned NumTokens,
6775 CXCursor *Cursors) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006776 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006777 LOG_BAD_TU(TU);
6778 return;
6779 }
6780 if (NumTokens == 0 || !Tokens || !Cursors) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006781 LOG_FUNC_SECTION { *Log << "<null input>"; }
Guy Benyei11169dd2012-12-18 14:30:41 +00006782 return;
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006783 }
6784
6785 LOG_FUNC_SECTION {
6786 *Log << TU << ' ';
6787 CXSourceLocation bloc = clang_getTokenLocation(TU, Tokens[0]);
6788 CXSourceLocation eloc = clang_getTokenLocation(TU, Tokens[NumTokens-1]);
6789 *Log << clang_getRange(bloc, eloc);
6790 }
Guy Benyei11169dd2012-12-18 14:30:41 +00006791
6792 // Any token we don't specifically annotate will have a NULL cursor.
6793 CXCursor C = clang_getNullCursor();
6794 for (unsigned I = 0; I != NumTokens; ++I)
6795 Cursors[I] = C;
6796
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006797 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00006798 if (!CXXUnit)
6799 return;
6800
6801 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00006802
6803 auto AnnotateTokensImpl = [=]() {
6804 clang_annotateTokensImpl(TU, CXXUnit, Tokens, NumTokens, Cursors);
6805 };
Guy Benyei11169dd2012-12-18 14:30:41 +00006806 llvm::CrashRecoveryContext CRC;
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00006807 if (!RunSafely(CRC, AnnotateTokensImpl, GetSafetyThreadStackSize() * 2)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00006808 fprintf(stderr, "libclang: crash detected while annotating tokens\n");
6809 }
6810}
6811
6812} // end: extern "C"
6813
6814//===----------------------------------------------------------------------===//
6815// Operations for querying linkage of a cursor.
6816//===----------------------------------------------------------------------===//
6817
6818extern "C" {
6819CXLinkageKind clang_getCursorLinkage(CXCursor cursor) {
6820 if (!clang_isDeclaration(cursor.kind))
6821 return CXLinkage_Invalid;
6822
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006823 const Decl *D = cxcursor::getCursorDecl(cursor);
6824 if (const NamedDecl *ND = dyn_cast_or_null<NamedDecl>(D))
Rafael Espindola3ae00052013-05-13 00:12:11 +00006825 switch (ND->getLinkageInternal()) {
Rafael Espindola50df3a02013-05-25 17:16:20 +00006826 case NoLinkage:
6827 case VisibleNoLinkage: return CXLinkage_NoLinkage;
Guy Benyei11169dd2012-12-18 14:30:41 +00006828 case InternalLinkage: return CXLinkage_Internal;
6829 case UniqueExternalLinkage: return CXLinkage_UniqueExternal;
6830 case ExternalLinkage: return CXLinkage_External;
6831 };
6832
6833 return CXLinkage_Invalid;
6834}
6835} // end: extern "C"
6836
6837//===----------------------------------------------------------------------===//
Ehsan Akhgari93697fa2015-11-23 19:56:46 +00006838// Operations for querying visibility of a cursor.
6839//===----------------------------------------------------------------------===//
6840
6841extern "C" {
6842CXVisibilityKind clang_getCursorVisibility(CXCursor cursor) {
6843 if (!clang_isDeclaration(cursor.kind))
6844 return CXVisibility_Invalid;
6845
6846 const Decl *D = cxcursor::getCursorDecl(cursor);
6847 if (const NamedDecl *ND = dyn_cast_or_null<NamedDecl>(D))
6848 switch (ND->getVisibility()) {
6849 case HiddenVisibility: return CXVisibility_Hidden;
6850 case ProtectedVisibility: return CXVisibility_Protected;
6851 case DefaultVisibility: return CXVisibility_Default;
6852 };
6853
6854 return CXVisibility_Invalid;
6855}
6856} // end: extern "C"
6857
6858//===----------------------------------------------------------------------===//
Guy Benyei11169dd2012-12-18 14:30:41 +00006859// Operations for querying language of a cursor.
6860//===----------------------------------------------------------------------===//
6861
6862static CXLanguageKind getDeclLanguage(const Decl *D) {
6863 if (!D)
6864 return CXLanguage_C;
6865
6866 switch (D->getKind()) {
6867 default:
6868 break;
6869 case Decl::ImplicitParam:
6870 case Decl::ObjCAtDefsField:
6871 case Decl::ObjCCategory:
6872 case Decl::ObjCCategoryImpl:
6873 case Decl::ObjCCompatibleAlias:
6874 case Decl::ObjCImplementation:
6875 case Decl::ObjCInterface:
6876 case Decl::ObjCIvar:
6877 case Decl::ObjCMethod:
6878 case Decl::ObjCProperty:
6879 case Decl::ObjCPropertyImpl:
6880 case Decl::ObjCProtocol:
Douglas Gregor85f3f952015-07-07 03:57:15 +00006881 case Decl::ObjCTypeParam:
Guy Benyei11169dd2012-12-18 14:30:41 +00006882 return CXLanguage_ObjC;
6883 case Decl::CXXConstructor:
6884 case Decl::CXXConversion:
6885 case Decl::CXXDestructor:
6886 case Decl::CXXMethod:
6887 case Decl::CXXRecord:
6888 case Decl::ClassTemplate:
6889 case Decl::ClassTemplatePartialSpecialization:
6890 case Decl::ClassTemplateSpecialization:
6891 case Decl::Friend:
6892 case Decl::FriendTemplate:
6893 case Decl::FunctionTemplate:
6894 case Decl::LinkageSpec:
6895 case Decl::Namespace:
6896 case Decl::NamespaceAlias:
6897 case Decl::NonTypeTemplateParm:
6898 case Decl::StaticAssert:
6899 case Decl::TemplateTemplateParm:
6900 case Decl::TemplateTypeParm:
6901 case Decl::UnresolvedUsingTypename:
6902 case Decl::UnresolvedUsingValue:
6903 case Decl::Using:
6904 case Decl::UsingDirective:
6905 case Decl::UsingShadow:
6906 return CXLanguage_CPlusPlus;
6907 }
6908
6909 return CXLanguage_C;
6910}
6911
6912extern "C" {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006913
6914static CXAvailabilityKind getCursorAvailabilityForDecl(const Decl *D) {
6915 if (isa<FunctionDecl>(D) && cast<FunctionDecl>(D)->isDeleted())
Manuel Klimek8e3a7ed2015-09-25 17:53:16 +00006916 return CXAvailability_NotAvailable;
Guy Benyei11169dd2012-12-18 14:30:41 +00006917
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006918 switch (D->getAvailability()) {
6919 case AR_Available:
6920 case AR_NotYetIntroduced:
6921 if (const EnumConstantDecl *EnumConst = dyn_cast<EnumConstantDecl>(D))
Benjamin Kramer656363d2013-10-15 18:53:18 +00006922 return getCursorAvailabilityForDecl(
6923 cast<Decl>(EnumConst->getDeclContext()));
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006924 return CXAvailability_Available;
6925
6926 case AR_Deprecated:
6927 return CXAvailability_Deprecated;
6928
6929 case AR_Unavailable:
6930 return CXAvailability_NotAvailable;
6931 }
Benjamin Kramer656363d2013-10-15 18:53:18 +00006932
6933 llvm_unreachable("Unknown availability kind!");
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006934}
6935
Guy Benyei11169dd2012-12-18 14:30:41 +00006936enum CXAvailabilityKind clang_getCursorAvailability(CXCursor cursor) {
6937 if (clang_isDeclaration(cursor.kind))
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006938 if (const Decl *D = cxcursor::getCursorDecl(cursor))
6939 return getCursorAvailabilityForDecl(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00006940
6941 return CXAvailability_Available;
6942}
6943
6944static CXVersion convertVersion(VersionTuple In) {
6945 CXVersion Out = { -1, -1, -1 };
6946 if (In.empty())
6947 return Out;
6948
6949 Out.Major = In.getMajor();
6950
NAKAMURA Takumic2b5d1f2013-02-21 02:32:34 +00006951 Optional<unsigned> Minor = In.getMinor();
6952 if (Minor.hasValue())
Guy Benyei11169dd2012-12-18 14:30:41 +00006953 Out.Minor = *Minor;
6954 else
6955 return Out;
6956
NAKAMURA Takumic2b5d1f2013-02-21 02:32:34 +00006957 Optional<unsigned> Subminor = In.getSubminor();
6958 if (Subminor.hasValue())
Guy Benyei11169dd2012-12-18 14:30:41 +00006959 Out.Subminor = *Subminor;
6960
6961 return Out;
6962}
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006963
6964static int getCursorPlatformAvailabilityForDecl(const Decl *D,
6965 int *always_deprecated,
6966 CXString *deprecated_message,
6967 int *always_unavailable,
6968 CXString *unavailable_message,
6969 CXPlatformAvailability *availability,
6970 int availability_size) {
6971 bool HadAvailAttr = false;
6972 int N = 0;
Aaron Ballmanb97112e2014-03-08 22:19:01 +00006973 for (auto A : D->attrs()) {
6974 if (DeprecatedAttr *Deprecated = dyn_cast<DeprecatedAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006975 HadAvailAttr = true;
6976 if (always_deprecated)
6977 *always_deprecated = 1;
Nico Weberaacf0312014-04-24 05:16:45 +00006978 if (deprecated_message) {
Argyrios Kyrtzidisedfe07f2014-04-24 06:05:40 +00006979 clang_disposeString(*deprecated_message);
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006980 *deprecated_message = cxstring::createDup(Deprecated->getMessage());
Nico Weberaacf0312014-04-24 05:16:45 +00006981 }
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006982 continue;
6983 }
6984
Aaron Ballmanb97112e2014-03-08 22:19:01 +00006985 if (UnavailableAttr *Unavailable = dyn_cast<UnavailableAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006986 HadAvailAttr = true;
6987 if (always_unavailable)
6988 *always_unavailable = 1;
6989 if (unavailable_message) {
Argyrios Kyrtzidisedfe07f2014-04-24 06:05:40 +00006990 clang_disposeString(*unavailable_message);
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006991 *unavailable_message = cxstring::createDup(Unavailable->getMessage());
6992 }
6993 continue;
6994 }
6995
Aaron Ballmanb97112e2014-03-08 22:19:01 +00006996 if (AvailabilityAttr *Avail = dyn_cast<AvailabilityAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006997 HadAvailAttr = true;
6998 if (N < availability_size) {
6999 availability[N].Platform
7000 = cxstring::createDup(Avail->getPlatform()->getName());
7001 availability[N].Introduced = convertVersion(Avail->getIntroduced());
7002 availability[N].Deprecated = convertVersion(Avail->getDeprecated());
7003 availability[N].Obsoleted = convertVersion(Avail->getObsoleted());
7004 availability[N].Unavailable = Avail->getUnavailable();
7005 availability[N].Message = cxstring::createDup(Avail->getMessage());
7006 }
7007 ++N;
7008 }
7009 }
7010
7011 if (!HadAvailAttr)
7012 if (const EnumConstantDecl *EnumConst = dyn_cast<EnumConstantDecl>(D))
7013 return getCursorPlatformAvailabilityForDecl(
7014 cast<Decl>(EnumConst->getDeclContext()),
7015 always_deprecated,
7016 deprecated_message,
7017 always_unavailable,
7018 unavailable_message,
7019 availability,
7020 availability_size);
Guy Benyei11169dd2012-12-18 14:30:41 +00007021
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00007022 return N;
7023}
7024
Guy Benyei11169dd2012-12-18 14:30:41 +00007025int clang_getCursorPlatformAvailability(CXCursor cursor,
7026 int *always_deprecated,
7027 CXString *deprecated_message,
7028 int *always_unavailable,
7029 CXString *unavailable_message,
7030 CXPlatformAvailability *availability,
7031 int availability_size) {
7032 if (always_deprecated)
7033 *always_deprecated = 0;
7034 if (deprecated_message)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00007035 *deprecated_message = cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00007036 if (always_unavailable)
7037 *always_unavailable = 0;
7038 if (unavailable_message)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00007039 *unavailable_message = cxstring::createEmpty();
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00007040
Guy Benyei11169dd2012-12-18 14:30:41 +00007041 if (!clang_isDeclaration(cursor.kind))
7042 return 0;
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00007043
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00007044 const Decl *D = cxcursor::getCursorDecl(cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00007045 if (!D)
7046 return 0;
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00007047
7048 return getCursorPlatformAvailabilityForDecl(D, always_deprecated,
7049 deprecated_message,
7050 always_unavailable,
7051 unavailable_message,
7052 availability,
7053 availability_size);
Guy Benyei11169dd2012-12-18 14:30:41 +00007054}
7055
7056void clang_disposeCXPlatformAvailability(CXPlatformAvailability *availability) {
7057 clang_disposeString(availability->Platform);
7058 clang_disposeString(availability->Message);
7059}
7060
7061CXLanguageKind clang_getCursorLanguage(CXCursor cursor) {
7062 if (clang_isDeclaration(cursor.kind))
7063 return getDeclLanguage(cxcursor::getCursorDecl(cursor));
7064
7065 return CXLanguage_Invalid;
7066}
7067
7068 /// \brief If the given cursor is the "templated" declaration
7069 /// descibing a class or function template, return the class or
7070 /// function template.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00007071static const Decl *maybeGetTemplateCursor(const Decl *D) {
Guy Benyei11169dd2012-12-18 14:30:41 +00007072 if (!D)
Craig Topper69186e72014-06-08 08:38:04 +00007073 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00007074
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00007075 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00007076 if (FunctionTemplateDecl *FunTmpl = FD->getDescribedFunctionTemplate())
7077 return FunTmpl;
7078
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00007079 if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00007080 if (ClassTemplateDecl *ClassTmpl = RD->getDescribedClassTemplate())
7081 return ClassTmpl;
7082
7083 return D;
7084}
7085
Argyrios Kyrtzidis4e0854f2014-10-15 17:05:31 +00007086
7087enum CX_StorageClass clang_Cursor_getStorageClass(CXCursor C) {
7088 StorageClass sc = SC_None;
7089 const Decl *D = getCursorDecl(C);
7090 if (D) {
7091 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
7092 sc = FD->getStorageClass();
7093 } else if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
7094 sc = VD->getStorageClass();
7095 } else {
7096 return CX_SC_Invalid;
7097 }
7098 } else {
7099 return CX_SC_Invalid;
7100 }
7101 switch (sc) {
7102 case SC_None:
7103 return CX_SC_None;
7104 case SC_Extern:
7105 return CX_SC_Extern;
7106 case SC_Static:
7107 return CX_SC_Static;
7108 case SC_PrivateExtern:
7109 return CX_SC_PrivateExtern;
Argyrios Kyrtzidis4e0854f2014-10-15 17:05:31 +00007110 case SC_Auto:
7111 return CX_SC_Auto;
7112 case SC_Register:
7113 return CX_SC_Register;
Argyrios Kyrtzidis4e0854f2014-10-15 17:05:31 +00007114 }
Kaelyn Takataab61e702014-10-15 18:03:26 +00007115 llvm_unreachable("Unhandled storage class!");
Argyrios Kyrtzidis4e0854f2014-10-15 17:05:31 +00007116}
7117
Guy Benyei11169dd2012-12-18 14:30:41 +00007118CXCursor clang_getCursorSemanticParent(CXCursor cursor) {
7119 if (clang_isDeclaration(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00007120 if (const Decl *D = getCursorDecl(cursor)) {
7121 const DeclContext *DC = D->getDeclContext();
Guy Benyei11169dd2012-12-18 14:30:41 +00007122 if (!DC)
7123 return clang_getNullCursor();
7124
7125 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
7126 getCursorTU(cursor));
7127 }
7128 }
7129
7130 if (clang_isStatement(cursor.kind) || clang_isExpression(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00007131 if (const Decl *D = getCursorDecl(cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +00007132 return MakeCXCursor(D, getCursorTU(cursor));
7133 }
7134
7135 return clang_getNullCursor();
7136}
7137
7138CXCursor clang_getCursorLexicalParent(CXCursor cursor) {
7139 if (clang_isDeclaration(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00007140 if (const Decl *D = getCursorDecl(cursor)) {
7141 const DeclContext *DC = D->getLexicalDeclContext();
Guy Benyei11169dd2012-12-18 14:30:41 +00007142 if (!DC)
7143 return clang_getNullCursor();
7144
7145 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
7146 getCursorTU(cursor));
7147 }
7148 }
7149
7150 // FIXME: Note that we can't easily compute the lexical context of a
7151 // statement or expression, so we return nothing.
7152 return clang_getNullCursor();
7153}
7154
7155CXFile clang_getIncludedFile(CXCursor cursor) {
7156 if (cursor.kind != CXCursor_InclusionDirective)
Craig Topper69186e72014-06-08 08:38:04 +00007157 return nullptr;
7158
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00007159 const InclusionDirective *ID = getCursorInclusionDirective(cursor);
Dmitri Gribenkof9304482013-01-23 15:56:07 +00007160 return const_cast<FileEntry *>(ID->getFile());
Guy Benyei11169dd2012-12-18 14:30:41 +00007161}
7162
Argyrios Kyrtzidis9adfd8a2013-04-18 22:15:49 +00007163unsigned clang_Cursor_getObjCPropertyAttributes(CXCursor C, unsigned reserved) {
7164 if (C.kind != CXCursor_ObjCPropertyDecl)
7165 return CXObjCPropertyAttr_noattr;
7166
7167 unsigned Result = CXObjCPropertyAttr_noattr;
7168 const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(getCursorDecl(C));
7169 ObjCPropertyDecl::PropertyAttributeKind Attr =
7170 PD->getPropertyAttributesAsWritten();
7171
7172#define SET_CXOBJCPROP_ATTR(A) \
7173 if (Attr & ObjCPropertyDecl::OBJC_PR_##A) \
7174 Result |= CXObjCPropertyAttr_##A
7175 SET_CXOBJCPROP_ATTR(readonly);
7176 SET_CXOBJCPROP_ATTR(getter);
7177 SET_CXOBJCPROP_ATTR(assign);
7178 SET_CXOBJCPROP_ATTR(readwrite);
7179 SET_CXOBJCPROP_ATTR(retain);
7180 SET_CXOBJCPROP_ATTR(copy);
7181 SET_CXOBJCPROP_ATTR(nonatomic);
7182 SET_CXOBJCPROP_ATTR(setter);
7183 SET_CXOBJCPROP_ATTR(atomic);
7184 SET_CXOBJCPROP_ATTR(weak);
7185 SET_CXOBJCPROP_ATTR(strong);
7186 SET_CXOBJCPROP_ATTR(unsafe_unretained);
7187#undef SET_CXOBJCPROP_ATTR
7188
7189 return Result;
7190}
7191
Argyrios Kyrtzidis9d9bc012013-04-18 23:29:12 +00007192unsigned clang_Cursor_getObjCDeclQualifiers(CXCursor C) {
7193 if (!clang_isDeclaration(C.kind))
7194 return CXObjCDeclQualifier_None;
7195
7196 Decl::ObjCDeclQualifier QT = Decl::OBJC_TQ_None;
7197 const Decl *D = getCursorDecl(C);
7198 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
7199 QT = MD->getObjCDeclQualifier();
7200 else if (const ParmVarDecl *PD = dyn_cast<ParmVarDecl>(D))
7201 QT = PD->getObjCDeclQualifier();
7202 if (QT == Decl::OBJC_TQ_None)
7203 return CXObjCDeclQualifier_None;
7204
7205 unsigned Result = CXObjCDeclQualifier_None;
7206 if (QT & Decl::OBJC_TQ_In) Result |= CXObjCDeclQualifier_In;
7207 if (QT & Decl::OBJC_TQ_Inout) Result |= CXObjCDeclQualifier_Inout;
7208 if (QT & Decl::OBJC_TQ_Out) Result |= CXObjCDeclQualifier_Out;
7209 if (QT & Decl::OBJC_TQ_Bycopy) Result |= CXObjCDeclQualifier_Bycopy;
7210 if (QT & Decl::OBJC_TQ_Byref) Result |= CXObjCDeclQualifier_Byref;
7211 if (QT & Decl::OBJC_TQ_Oneway) Result |= CXObjCDeclQualifier_Oneway;
7212
7213 return Result;
7214}
7215
Argyrios Kyrtzidis7b50fc52013-07-05 20:44:37 +00007216unsigned clang_Cursor_isObjCOptional(CXCursor C) {
7217 if (!clang_isDeclaration(C.kind))
7218 return 0;
7219
7220 const Decl *D = getCursorDecl(C);
7221 if (const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(D))
7222 return PD->getPropertyImplementation() == ObjCPropertyDecl::Optional;
7223 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
7224 return MD->getImplementationControl() == ObjCMethodDecl::Optional;
7225
7226 return 0;
7227}
7228
Argyrios Kyrtzidis23814e42013-04-18 23:53:05 +00007229unsigned clang_Cursor_isVariadic(CXCursor C) {
7230 if (!clang_isDeclaration(C.kind))
7231 return 0;
7232
7233 const Decl *D = getCursorDecl(C);
7234 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
7235 return FD->isVariadic();
7236 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
7237 return MD->isVariadic();
7238
7239 return 0;
7240}
7241
Guy Benyei11169dd2012-12-18 14:30:41 +00007242CXSourceRange clang_Cursor_getCommentRange(CXCursor C) {
7243 if (!clang_isDeclaration(C.kind))
7244 return clang_getNullRange();
7245
7246 const Decl *D = getCursorDecl(C);
7247 ASTContext &Context = getCursorContext(C);
7248 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
7249 if (!RC)
7250 return clang_getNullRange();
7251
7252 return cxloc::translateSourceRange(Context, RC->getSourceRange());
7253}
7254
7255CXString clang_Cursor_getRawCommentText(CXCursor C) {
7256 if (!clang_isDeclaration(C.kind))
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00007257 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00007258
7259 const Decl *D = getCursorDecl(C);
7260 ASTContext &Context = getCursorContext(C);
7261 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
7262 StringRef RawText = RC ? RC->getRawText(Context.getSourceManager()) :
7263 StringRef();
7264
7265 // Don't duplicate the string because RawText points directly into source
7266 // code.
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00007267 return cxstring::createRef(RawText);
Guy Benyei11169dd2012-12-18 14:30:41 +00007268}
7269
7270CXString clang_Cursor_getBriefCommentText(CXCursor C) {
7271 if (!clang_isDeclaration(C.kind))
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00007272 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00007273
7274 const Decl *D = getCursorDecl(C);
7275 const ASTContext &Context = getCursorContext(C);
7276 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
7277
7278 if (RC) {
7279 StringRef BriefText = RC->getBriefText(Context);
7280
7281 // Don't duplicate the string because RawComment ensures that this memory
7282 // will not go away.
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00007283 return cxstring::createRef(BriefText);
Guy Benyei11169dd2012-12-18 14:30:41 +00007284 }
7285
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00007286 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00007287}
7288
Guy Benyei11169dd2012-12-18 14:30:41 +00007289CXModule clang_Cursor_getModule(CXCursor C) {
7290 if (C.kind == CXCursor_ModuleImportDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00007291 if (const ImportDecl *ImportD =
7292 dyn_cast_or_null<ImportDecl>(getCursorDecl(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00007293 return ImportD->getImportedModule();
7294 }
7295
Craig Topper69186e72014-06-08 08:38:04 +00007296 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00007297}
7298
Argyrios Kyrtzidisf6d49c32014-05-14 23:14:37 +00007299CXModule clang_getModuleForFile(CXTranslationUnit TU, CXFile File) {
7300 if (isNotUsableTU(TU)) {
7301 LOG_BAD_TU(TU);
7302 return nullptr;
7303 }
7304 if (!File)
7305 return nullptr;
7306 FileEntry *FE = static_cast<FileEntry *>(File);
7307
7308 ASTUnit &Unit = *cxtu::getASTUnit(TU);
7309 HeaderSearch &HS = Unit.getPreprocessor().getHeaderSearchInfo();
7310 ModuleMap::KnownHeader Header = HS.findModuleForHeader(FE);
7311
Richard Smithfeb54b62014-10-23 02:01:19 +00007312 return Header.getModule();
Argyrios Kyrtzidisf6d49c32014-05-14 23:14:37 +00007313}
7314
Argyrios Kyrtzidis12fdb9e2013-04-26 22:47:49 +00007315CXFile clang_Module_getASTFile(CXModule CXMod) {
7316 if (!CXMod)
Craig Topper69186e72014-06-08 08:38:04 +00007317 return nullptr;
Argyrios Kyrtzidis12fdb9e2013-04-26 22:47:49 +00007318 Module *Mod = static_cast<Module*>(CXMod);
7319 return const_cast<FileEntry *>(Mod->getASTFile());
7320}
7321
Guy Benyei11169dd2012-12-18 14:30:41 +00007322CXModule clang_Module_getParent(CXModule CXMod) {
7323 if (!CXMod)
Craig Topper69186e72014-06-08 08:38:04 +00007324 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00007325 Module *Mod = static_cast<Module*>(CXMod);
7326 return Mod->Parent;
7327}
7328
7329CXString clang_Module_getName(CXModule CXMod) {
7330 if (!CXMod)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00007331 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00007332 Module *Mod = static_cast<Module*>(CXMod);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00007333 return cxstring::createDup(Mod->Name);
Guy Benyei11169dd2012-12-18 14:30:41 +00007334}
7335
7336CXString clang_Module_getFullName(CXModule CXMod) {
7337 if (!CXMod)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00007338 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00007339 Module *Mod = static_cast<Module*>(CXMod);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00007340 return cxstring::createDup(Mod->getFullModuleName());
Guy Benyei11169dd2012-12-18 14:30:41 +00007341}
7342
Argyrios Kyrtzidis884337f2014-05-15 04:44:25 +00007343int clang_Module_isSystem(CXModule CXMod) {
7344 if (!CXMod)
7345 return 0;
7346 Module *Mod = static_cast<Module*>(CXMod);
7347 return Mod->IsSystem;
7348}
7349
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00007350unsigned clang_Module_getNumTopLevelHeaders(CXTranslationUnit TU,
7351 CXModule CXMod) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00007352 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00007353 LOG_BAD_TU(TU);
7354 return 0;
7355 }
7356 if (!CXMod)
Guy Benyei11169dd2012-12-18 14:30:41 +00007357 return 0;
7358 Module *Mod = static_cast<Module*>(CXMod);
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00007359 FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
7360 ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
7361 return TopHeaders.size();
Guy Benyei11169dd2012-12-18 14:30:41 +00007362}
7363
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00007364CXFile clang_Module_getTopLevelHeader(CXTranslationUnit TU,
7365 CXModule CXMod, unsigned Index) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00007366 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00007367 LOG_BAD_TU(TU);
Craig Topper69186e72014-06-08 08:38:04 +00007368 return nullptr;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00007369 }
7370 if (!CXMod)
Craig Topper69186e72014-06-08 08:38:04 +00007371 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00007372 Module *Mod = static_cast<Module*>(CXMod);
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00007373 FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
Guy Benyei11169dd2012-12-18 14:30:41 +00007374
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00007375 ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
7376 if (Index < TopHeaders.size())
7377 return const_cast<FileEntry *>(TopHeaders[Index]);
Guy Benyei11169dd2012-12-18 14:30:41 +00007378
Craig Topper69186e72014-06-08 08:38:04 +00007379 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00007380}
7381
7382} // end: extern "C"
7383
7384//===----------------------------------------------------------------------===//
7385// C++ AST instrospection.
7386//===----------------------------------------------------------------------===//
7387
7388extern "C" {
Saleem Abdulrasool6ea75db2015-10-27 15:50:22 +00007389unsigned clang_CXXField_isMutable(CXCursor C) {
7390 if (!clang_isDeclaration(C.kind))
7391 return 0;
7392
7393 if (const auto D = cxcursor::getCursorDecl(C))
7394 if (const auto FD = dyn_cast_or_null<FieldDecl>(D))
7395 return FD->isMutable() ? 1 : 0;
7396 return 0;
7397}
7398
Dmitri Gribenko62770be2013-05-17 18:38:35 +00007399unsigned clang_CXXMethod_isPureVirtual(CXCursor C) {
7400 if (!clang_isDeclaration(C.kind))
7401 return 0;
7402
Dmitri Gribenko62770be2013-05-17 18:38:35 +00007403 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00007404 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00007405 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Dmitri Gribenko62770be2013-05-17 18:38:35 +00007406 return (Method && Method->isVirtual() && Method->isPure()) ? 1 : 0;
7407}
7408
Dmitri Gribenkoe570ede2014-04-07 14:59:13 +00007409unsigned clang_CXXMethod_isConst(CXCursor C) {
7410 if (!clang_isDeclaration(C.kind))
7411 return 0;
7412
7413 const Decl *D = cxcursor::getCursorDecl(C);
7414 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00007415 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Dmitri Gribenkoe570ede2014-04-07 14:59:13 +00007416 return (Method && (Method->getTypeQualifiers() & Qualifiers::Const)) ? 1 : 0;
7417}
7418
Guy Benyei11169dd2012-12-18 14:30:41 +00007419unsigned clang_CXXMethod_isStatic(CXCursor C) {
7420 if (!clang_isDeclaration(C.kind))
7421 return 0;
7422
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00007423 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00007424 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00007425 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00007426 return (Method && Method->isStatic()) ? 1 : 0;
7427}
7428
7429unsigned clang_CXXMethod_isVirtual(CXCursor C) {
7430 if (!clang_isDeclaration(C.kind))
7431 return 0;
7432
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00007433 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00007434 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00007435 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00007436 return (Method && Method->isVirtual()) ? 1 : 0;
7437}
7438} // end: extern "C"
7439
7440//===----------------------------------------------------------------------===//
7441// Attribute introspection.
7442//===----------------------------------------------------------------------===//
7443
7444extern "C" {
7445CXType clang_getIBOutletCollectionType(CXCursor C) {
7446 if (C.kind != CXCursor_IBOutletCollectionAttr)
7447 return cxtype::MakeCXType(QualType(), cxcursor::getCursorTU(C));
7448
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00007449 const IBOutletCollectionAttr *A =
Guy Benyei11169dd2012-12-18 14:30:41 +00007450 cast<IBOutletCollectionAttr>(cxcursor::getCursorAttr(C));
7451
7452 return cxtype::MakeCXType(A->getInterface(), cxcursor::getCursorTU(C));
7453}
7454} // end: extern "C"
7455
7456//===----------------------------------------------------------------------===//
7457// Inspecting memory usage.
7458//===----------------------------------------------------------------------===//
7459
7460typedef std::vector<CXTUResourceUsageEntry> MemUsageEntries;
7461
7462static inline void createCXTUResourceUsageEntry(MemUsageEntries &entries,
7463 enum CXTUResourceUsageKind k,
7464 unsigned long amount) {
7465 CXTUResourceUsageEntry entry = { k, amount };
7466 entries.push_back(entry);
7467}
7468
7469extern "C" {
7470
7471const char *clang_getTUResourceUsageName(CXTUResourceUsageKind kind) {
7472 const char *str = "";
7473 switch (kind) {
7474 case CXTUResourceUsage_AST:
7475 str = "ASTContext: expressions, declarations, and types";
7476 break;
7477 case CXTUResourceUsage_Identifiers:
7478 str = "ASTContext: identifiers";
7479 break;
7480 case CXTUResourceUsage_Selectors:
7481 str = "ASTContext: selectors";
7482 break;
7483 case CXTUResourceUsage_GlobalCompletionResults:
7484 str = "Code completion: cached global results";
7485 break;
7486 case CXTUResourceUsage_SourceManagerContentCache:
7487 str = "SourceManager: content cache allocator";
7488 break;
7489 case CXTUResourceUsage_AST_SideTables:
7490 str = "ASTContext: side tables";
7491 break;
7492 case CXTUResourceUsage_SourceManager_Membuffer_Malloc:
7493 str = "SourceManager: malloc'ed memory buffers";
7494 break;
7495 case CXTUResourceUsage_SourceManager_Membuffer_MMap:
7496 str = "SourceManager: mmap'ed memory buffers";
7497 break;
7498 case CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc:
7499 str = "ExternalASTSource: malloc'ed memory buffers";
7500 break;
7501 case CXTUResourceUsage_ExternalASTSource_Membuffer_MMap:
7502 str = "ExternalASTSource: mmap'ed memory buffers";
7503 break;
7504 case CXTUResourceUsage_Preprocessor:
7505 str = "Preprocessor: malloc'ed memory";
7506 break;
7507 case CXTUResourceUsage_PreprocessingRecord:
7508 str = "Preprocessor: PreprocessingRecord";
7509 break;
7510 case CXTUResourceUsage_SourceManager_DataStructures:
7511 str = "SourceManager: data structures and tables";
7512 break;
7513 case CXTUResourceUsage_Preprocessor_HeaderSearch:
7514 str = "Preprocessor: header search tables";
7515 break;
7516 }
7517 return str;
7518}
7519
7520CXTUResourceUsage clang_getCXTUResourceUsage(CXTranslationUnit TU) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00007521 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00007522 LOG_BAD_TU(TU);
Craig Topper69186e72014-06-08 08:38:04 +00007523 CXTUResourceUsage usage = { (void*) nullptr, 0, nullptr };
Guy Benyei11169dd2012-12-18 14:30:41 +00007524 return usage;
7525 }
7526
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007527 ASTUnit *astUnit = cxtu::getASTUnit(TU);
Ahmed Charlesb8984322014-03-07 20:03:18 +00007528 std::unique_ptr<MemUsageEntries> entries(new MemUsageEntries());
Guy Benyei11169dd2012-12-18 14:30:41 +00007529 ASTContext &astContext = astUnit->getASTContext();
7530
7531 // How much memory is used by AST nodes and types?
7532 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST,
7533 (unsigned long) astContext.getASTAllocatedMemory());
7534
7535 // How much memory is used by identifiers?
7536 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Identifiers,
7537 (unsigned long) astContext.Idents.getAllocator().getTotalMemory());
7538
7539 // How much memory is used for selectors?
7540 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Selectors,
7541 (unsigned long) astContext.Selectors.getTotalMemory());
7542
7543 // How much memory is used by ASTContext's side tables?
7544 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST_SideTables,
7545 (unsigned long) astContext.getSideTableAllocatedMemory());
7546
7547 // How much memory is used for caching global code completion results?
7548 unsigned long completionBytes = 0;
7549 if (GlobalCodeCompletionAllocator *completionAllocator =
Alp Tokerf994cef2014-07-05 03:08:06 +00007550 astUnit->getCachedCompletionAllocator().get()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00007551 completionBytes = completionAllocator->getTotalMemory();
7552 }
7553 createCXTUResourceUsageEntry(*entries,
7554 CXTUResourceUsage_GlobalCompletionResults,
7555 completionBytes);
7556
7557 // How much memory is being used by SourceManager's content cache?
7558 createCXTUResourceUsageEntry(*entries,
7559 CXTUResourceUsage_SourceManagerContentCache,
7560 (unsigned long) astContext.getSourceManager().getContentCacheSize());
7561
7562 // How much memory is being used by the MemoryBuffer's in SourceManager?
7563 const SourceManager::MemoryBufferSizes &srcBufs =
7564 astUnit->getSourceManager().getMemoryBufferSizes();
7565
7566 createCXTUResourceUsageEntry(*entries,
7567 CXTUResourceUsage_SourceManager_Membuffer_Malloc,
7568 (unsigned long) srcBufs.malloc_bytes);
7569 createCXTUResourceUsageEntry(*entries,
7570 CXTUResourceUsage_SourceManager_Membuffer_MMap,
7571 (unsigned long) srcBufs.mmap_bytes);
7572 createCXTUResourceUsageEntry(*entries,
7573 CXTUResourceUsage_SourceManager_DataStructures,
7574 (unsigned long) astContext.getSourceManager()
7575 .getDataStructureSizes());
7576
7577 // How much memory is being used by the ExternalASTSource?
7578 if (ExternalASTSource *esrc = astContext.getExternalSource()) {
7579 const ExternalASTSource::MemoryBufferSizes &sizes =
7580 esrc->getMemoryBufferSizes();
7581
7582 createCXTUResourceUsageEntry(*entries,
7583 CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc,
7584 (unsigned long) sizes.malloc_bytes);
7585 createCXTUResourceUsageEntry(*entries,
7586 CXTUResourceUsage_ExternalASTSource_Membuffer_MMap,
7587 (unsigned long) sizes.mmap_bytes);
7588 }
7589
7590 // How much memory is being used by the Preprocessor?
7591 Preprocessor &pp = astUnit->getPreprocessor();
7592 createCXTUResourceUsageEntry(*entries,
7593 CXTUResourceUsage_Preprocessor,
7594 pp.getTotalMemory());
7595
7596 if (PreprocessingRecord *pRec = pp.getPreprocessingRecord()) {
7597 createCXTUResourceUsageEntry(*entries,
7598 CXTUResourceUsage_PreprocessingRecord,
7599 pRec->getTotalMemory());
7600 }
7601
7602 createCXTUResourceUsageEntry(*entries,
7603 CXTUResourceUsage_Preprocessor_HeaderSearch,
7604 pp.getHeaderSearchInfo().getTotalMemory());
Craig Topper69186e72014-06-08 08:38:04 +00007605
Guy Benyei11169dd2012-12-18 14:30:41 +00007606 CXTUResourceUsage usage = { (void*) entries.get(),
7607 (unsigned) entries->size(),
Alexander Kornienko6ee521c2015-01-23 15:36:10 +00007608 !entries->empty() ? &(*entries)[0] : nullptr };
Ahmed Charles9a16beb2014-03-07 19:33:25 +00007609 entries.release();
Guy Benyei11169dd2012-12-18 14:30:41 +00007610 return usage;
7611}
7612
7613void clang_disposeCXTUResourceUsage(CXTUResourceUsage usage) {
7614 if (usage.data)
7615 delete (MemUsageEntries*) usage.data;
7616}
7617
Argyrios Kyrtzidis0e282ef2013-12-06 18:55:45 +00007618CXSourceRangeList *clang_getSkippedRanges(CXTranslationUnit TU, CXFile file) {
7619 CXSourceRangeList *skipped = new CXSourceRangeList;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00007620 skipped->count = 0;
Craig Topper69186e72014-06-08 08:38:04 +00007621 skipped->ranges = nullptr;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00007622
Dmitri Gribenko852d6222014-02-11 15:02:48 +00007623 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00007624 LOG_BAD_TU(TU);
7625 return skipped;
7626 }
7627
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00007628 if (!file)
7629 return skipped;
7630
7631 ASTUnit *astUnit = cxtu::getASTUnit(TU);
7632 PreprocessingRecord *ppRec = astUnit->getPreprocessor().getPreprocessingRecord();
7633 if (!ppRec)
7634 return skipped;
7635
7636 ASTContext &Ctx = astUnit->getASTContext();
7637 SourceManager &sm = Ctx.getSourceManager();
7638 FileEntry *fileEntry = static_cast<FileEntry *>(file);
7639 FileID wantedFileID = sm.translateFile(fileEntry);
7640
7641 const std::vector<SourceRange> &SkippedRanges = ppRec->getSkippedRanges();
7642 std::vector<SourceRange> wantedRanges;
7643 for (std::vector<SourceRange>::const_iterator i = SkippedRanges.begin(), ei = SkippedRanges.end();
7644 i != ei; ++i) {
7645 if (sm.getFileID(i->getBegin()) == wantedFileID || sm.getFileID(i->getEnd()) == wantedFileID)
7646 wantedRanges.push_back(*i);
7647 }
7648
7649 skipped->count = wantedRanges.size();
7650 skipped->ranges = new CXSourceRange[skipped->count];
7651 for (unsigned i = 0, ei = skipped->count; i != ei; ++i)
7652 skipped->ranges[i] = cxloc::translateSourceRange(Ctx, wantedRanges[i]);
7653
7654 return skipped;
7655}
7656
Argyrios Kyrtzidis0e282ef2013-12-06 18:55:45 +00007657void clang_disposeSourceRangeList(CXSourceRangeList *ranges) {
7658 if (ranges) {
7659 delete[] ranges->ranges;
7660 delete ranges;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00007661 }
7662}
7663
Guy Benyei11169dd2012-12-18 14:30:41 +00007664} // end extern "C"
7665
7666void clang::PrintLibclangResourceUsage(CXTranslationUnit TU) {
7667 CXTUResourceUsage Usage = clang_getCXTUResourceUsage(TU);
7668 for (unsigned I = 0; I != Usage.numEntries; ++I)
7669 fprintf(stderr, " %s: %lu\n",
7670 clang_getTUResourceUsageName(Usage.entries[I].kind),
7671 Usage.entries[I].amount);
7672
7673 clang_disposeCXTUResourceUsage(Usage);
7674}
7675
7676//===----------------------------------------------------------------------===//
7677// Misc. utility functions.
7678//===----------------------------------------------------------------------===//
7679
7680/// Default to using an 8 MB stack size on "safety" threads.
7681static unsigned SafetyStackThreadSize = 8 << 20;
7682
7683namespace clang {
7684
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00007685bool RunSafely(llvm::CrashRecoveryContext &CRC, llvm::function_ref<void()> Fn,
Guy Benyei11169dd2012-12-18 14:30:41 +00007686 unsigned Size) {
7687 if (!Size)
7688 Size = GetSafetyThreadStackSize();
7689 if (Size)
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00007690 return CRC.RunSafelyOnThread(Fn, Size);
7691 return CRC.RunSafely(Fn);
Guy Benyei11169dd2012-12-18 14:30:41 +00007692}
7693
7694unsigned GetSafetyThreadStackSize() {
7695 return SafetyStackThreadSize;
7696}
7697
7698void SetSafetyThreadStackSize(unsigned Value) {
7699 SafetyStackThreadSize = Value;
7700}
7701
Alexander Kornienkoab9db512015-06-22 23:07:51 +00007702}
Guy Benyei11169dd2012-12-18 14:30:41 +00007703
7704void clang::setThreadBackgroundPriority() {
7705 if (getenv("LIBCLANG_BGPRIO_DISABLE"))
7706 return;
7707
Alp Toker1a86ad22014-07-06 06:24:00 +00007708#ifdef USE_DARWIN_THREADS
Guy Benyei11169dd2012-12-18 14:30:41 +00007709 setpriority(PRIO_DARWIN_THREAD, 0, PRIO_DARWIN_BG);
7710#endif
7711}
7712
7713void cxindex::printDiagsToStderr(ASTUnit *Unit) {
7714 if (!Unit)
7715 return;
7716
7717 for (ASTUnit::stored_diag_iterator D = Unit->stored_diag_begin(),
7718 DEnd = Unit->stored_diag_end();
7719 D != DEnd; ++D) {
Ben Langmuir749323f2014-04-22 17:40:12 +00007720 CXStoredDiagnostic Diag(*D, Unit->getLangOpts());
Guy Benyei11169dd2012-12-18 14:30:41 +00007721 CXString Msg = clang_formatDiagnostic(&Diag,
7722 clang_defaultDiagnosticDisplayOptions());
7723 fprintf(stderr, "%s\n", clang_getCString(Msg));
7724 clang_disposeString(Msg);
7725 }
7726#ifdef LLVM_ON_WIN32
7727 // On Windows, force a flush, since there may be multiple copies of
7728 // stderr and stdout in the file system, all with different buffers
7729 // but writing to the same device.
7730 fflush(stderr);
7731#endif
7732}
7733
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007734MacroInfo *cxindex::getMacroInfo(const IdentifierInfo &II,
7735 SourceLocation MacroDefLoc,
7736 CXTranslationUnit TU){
7737 if (MacroDefLoc.isInvalid() || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00007738 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007739 if (!II.hadMacroDefinition())
Craig Topper69186e72014-06-08 08:38:04 +00007740 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007741
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007742 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00007743 Preprocessor &PP = Unit->getPreprocessor();
Richard Smith20e883e2015-04-29 23:20:19 +00007744 MacroDirective *MD = PP.getLocalMacroDirectiveHistory(&II);
Argyrios Kyrtzidisb6210df2013-03-26 17:17:01 +00007745 if (MD) {
7746 for (MacroDirective::DefInfo
7747 Def = MD->getDefinition(); Def; Def = Def.getPreviousDefinition()) {
7748 if (MacroDefLoc == Def.getMacroInfo()->getDefinitionLoc())
7749 return Def.getMacroInfo();
7750 }
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007751 }
7752
Craig Topper69186e72014-06-08 08:38:04 +00007753 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007754}
7755
Richard Smith66a81862015-05-04 02:25:31 +00007756const MacroInfo *cxindex::getMacroInfo(const MacroDefinitionRecord *MacroDef,
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00007757 CXTranslationUnit TU) {
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007758 if (!MacroDef || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00007759 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007760 const IdentifierInfo *II = MacroDef->getName();
7761 if (!II)
Craig Topper69186e72014-06-08 08:38:04 +00007762 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007763
7764 return getMacroInfo(*II, MacroDef->getLocation(), TU);
7765}
7766
Richard Smith66a81862015-05-04 02:25:31 +00007767MacroDefinitionRecord *
7768cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI, const Token &Tok,
7769 CXTranslationUnit TU) {
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007770 if (!MI || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00007771 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007772 if (Tok.isNot(tok::raw_identifier))
Craig Topper69186e72014-06-08 08:38:04 +00007773 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007774
7775 if (MI->getNumTokens() == 0)
Craig Topper69186e72014-06-08 08:38:04 +00007776 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007777 SourceRange DefRange(MI->getReplacementToken(0).getLocation(),
7778 MI->getDefinitionEndLoc());
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007779 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007780
7781 // Check that the token is inside the definition and not its argument list.
7782 SourceManager &SM = Unit->getSourceManager();
7783 if (SM.isBeforeInTranslationUnit(Tok.getLocation(), DefRange.getBegin()))
Craig Topper69186e72014-06-08 08:38:04 +00007784 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007785 if (SM.isBeforeInTranslationUnit(DefRange.getEnd(), Tok.getLocation()))
Craig Topper69186e72014-06-08 08:38:04 +00007786 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007787
7788 Preprocessor &PP = Unit->getPreprocessor();
7789 PreprocessingRecord *PPRec = PP.getPreprocessingRecord();
7790 if (!PPRec)
Craig Topper69186e72014-06-08 08:38:04 +00007791 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007792
Alp Toker2d57cea2014-05-17 04:53:25 +00007793 IdentifierInfo &II = PP.getIdentifierTable().get(Tok.getRawIdentifier());
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007794 if (!II.hadMacroDefinition())
Craig Topper69186e72014-06-08 08:38:04 +00007795 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007796
7797 // Check that the identifier is not one of the macro arguments.
7798 if (std::find(MI->arg_begin(), MI->arg_end(), &II) != MI->arg_end())
Craig Topper69186e72014-06-08 08:38:04 +00007799 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007800
Richard Smith20e883e2015-04-29 23:20:19 +00007801 MacroDirective *InnerMD = PP.getLocalMacroDirectiveHistory(&II);
Argyrios Kyrtzidis09c9e812013-02-20 00:54:57 +00007802 if (!InnerMD)
Craig Topper69186e72014-06-08 08:38:04 +00007803 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007804
Argyrios Kyrtzidisb6210df2013-03-26 17:17:01 +00007805 return PPRec->findMacroDefinition(InnerMD->getMacroInfo());
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007806}
7807
Richard Smith66a81862015-05-04 02:25:31 +00007808MacroDefinitionRecord *
7809cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI, SourceLocation Loc,
7810 CXTranslationUnit TU) {
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007811 if (Loc.isInvalid() || !MI || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00007812 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007813
7814 if (MI->getNumTokens() == 0)
Craig Topper69186e72014-06-08 08:38:04 +00007815 return nullptr;
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007816 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007817 Preprocessor &PP = Unit->getPreprocessor();
7818 if (!PP.getPreprocessingRecord())
Craig Topper69186e72014-06-08 08:38:04 +00007819 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007820 Loc = Unit->getSourceManager().getSpellingLoc(Loc);
7821 Token Tok;
7822 if (PP.getRawToken(Loc, Tok))
Craig Topper69186e72014-06-08 08:38:04 +00007823 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007824
7825 return checkForMacroInMacroDefinition(MI, Tok, TU);
7826}
7827
Guy Benyei11169dd2012-12-18 14:30:41 +00007828extern "C" {
7829
7830CXString clang_getClangVersion() {
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00007831 return cxstring::createDup(getClangFullVersion());
Guy Benyei11169dd2012-12-18 14:30:41 +00007832}
7833
7834} // end: extern "C"
7835
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007836Logger &cxindex::Logger::operator<<(CXTranslationUnit TU) {
7837 if (TU) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007838 if (ASTUnit *Unit = cxtu::getASTUnit(TU)) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007839 LogOS << '<' << Unit->getMainFileName() << '>';
Argyrios Kyrtzidis37f2ab42013-03-05 20:21:14 +00007840 if (Unit->isMainFileAST())
7841 LogOS << " (" << Unit->getASTFileName() << ')';
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007842 return *this;
7843 }
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00007844 } else {
7845 LogOS << "<NULL TU>";
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007846 }
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007847 return *this;
7848}
7849
Argyrios Kyrtzidisba4b5f82013-03-08 02:32:26 +00007850Logger &cxindex::Logger::operator<<(const FileEntry *FE) {
7851 *this << FE->getName();
7852 return *this;
7853}
7854
7855Logger &cxindex::Logger::operator<<(CXCursor cursor) {
7856 CXString cursorName = clang_getCursorDisplayName(cursor);
7857 *this << cursorName << "@" << clang_getCursorLocation(cursor);
7858 clang_disposeString(cursorName);
7859 return *this;
7860}
7861
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007862Logger &cxindex::Logger::operator<<(CXSourceLocation Loc) {
7863 CXFile File;
7864 unsigned Line, Column;
Craig Topper69186e72014-06-08 08:38:04 +00007865 clang_getFileLocation(Loc, &File, &Line, &Column, nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007866 CXString FileName = clang_getFileName(File);
7867 *this << llvm::format("(%s:%d:%d)", clang_getCString(FileName), Line, Column);
7868 clang_disposeString(FileName);
7869 return *this;
7870}
7871
7872Logger &cxindex::Logger::operator<<(CXSourceRange range) {
7873 CXSourceLocation BLoc = clang_getRangeStart(range);
7874 CXSourceLocation ELoc = clang_getRangeEnd(range);
7875
7876 CXFile BFile;
7877 unsigned BLine, BColumn;
Craig Topper69186e72014-06-08 08:38:04 +00007878 clang_getFileLocation(BLoc, &BFile, &BLine, &BColumn, nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007879
7880 CXFile EFile;
7881 unsigned ELine, EColumn;
Craig Topper69186e72014-06-08 08:38:04 +00007882 clang_getFileLocation(ELoc, &EFile, &ELine, &EColumn, nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007883
7884 CXString BFileName = clang_getFileName(BFile);
7885 if (BFile == EFile) {
7886 *this << llvm::format("[%s %d:%d-%d:%d]", clang_getCString(BFileName),
7887 BLine, BColumn, ELine, EColumn);
7888 } else {
7889 CXString EFileName = clang_getFileName(EFile);
7890 *this << llvm::format("[%s:%d:%d - ", clang_getCString(BFileName),
7891 BLine, BColumn)
7892 << llvm::format("%s:%d:%d]", clang_getCString(EFileName),
7893 ELine, EColumn);
7894 clang_disposeString(EFileName);
7895 }
7896 clang_disposeString(BFileName);
7897 return *this;
7898}
7899
7900Logger &cxindex::Logger::operator<<(CXString Str) {
7901 *this << clang_getCString(Str);
7902 return *this;
7903}
7904
7905Logger &cxindex::Logger::operator<<(const llvm::format_object_base &Fmt) {
7906 LogOS << Fmt;
7907 return *this;
7908}
7909
Chandler Carruth37ad2582014-06-27 15:14:39 +00007910static llvm::ManagedStatic<llvm::sys::Mutex> LoggingMutex;
7911
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007912cxindex::Logger::~Logger() {
Chandler Carruth37ad2582014-06-27 15:14:39 +00007913 llvm::sys::ScopedLock L(*LoggingMutex);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007914
7915 static llvm::TimeRecord sBeginTR = llvm::TimeRecord::getCurrentTime();
7916
Dmitri Gribenkof8579502013-01-12 19:30:44 +00007917 raw_ostream &OS = llvm::errs();
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007918 OS << "[libclang:" << Name << ':';
7919
Alp Toker1a86ad22014-07-06 06:24:00 +00007920#ifdef USE_DARWIN_THREADS
7921 // TODO: Portability.
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007922 mach_port_t tid = pthread_mach_thread_np(pthread_self());
7923 OS << tid << ':';
7924#endif
7925
7926 llvm::TimeRecord TR = llvm::TimeRecord::getCurrentTime();
7927 OS << llvm::format("%7.4f] ", TR.getWallTime() - sBeginTR.getWallTime());
Yaron Keren09fb7c62015-03-10 07:33:23 +00007928 OS << Msg << '\n';
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007929
7930 if (Trace) {
Zachary Turner1fe2a8d2015-03-05 19:15:09 +00007931 llvm::sys::PrintStackTrace(OS);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007932 OS << "--------------------------------------------------\n";
7933 }
7934}