blob: 78df3ce264cb3aa23203a5d1baf066887b5241f9 [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:
Alexey Bader954ba212016-04-08 13:40:33 +00001457#define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \
1458 case BuiltinType::Id:
Alexey Baderb62f1442016-04-13 08:33:41 +00001459#include "clang/Basic/OpenCLImageTypes.def"
NAKAMURA Takumi288c42e2013-02-07 12:47:42 +00001460 case BuiltinType::OCLSampler:
Guy Benyei1b4fb3e2013-01-20 12:31:11 +00001461 case BuiltinType::OCLEvent:
Alexey Bader9c8453f2015-09-15 11:18:52 +00001462 case BuiltinType::OCLClkEvent:
1463 case BuiltinType::OCLQueue:
1464 case BuiltinType::OCLNDRange:
1465 case BuiltinType::OCLReserveID:
Guy Benyei11169dd2012-12-18 14:30:41 +00001466#define BUILTIN_TYPE(Id, SingletonId)
1467#define SIGNED_TYPE(Id, SingletonId) case BuiltinType::Id:
1468#define UNSIGNED_TYPE(Id, SingletonId) case BuiltinType::Id:
1469#define FLOATING_TYPE(Id, SingletonId) case BuiltinType::Id:
1470#define PLACEHOLDER_TYPE(Id, SingletonId) case BuiltinType::Id:
1471#include "clang/AST/BuiltinTypes.def"
1472 break;
1473
1474 case BuiltinType::ObjCId:
1475 VisitType = Context.getObjCIdType();
1476 break;
1477
1478 case BuiltinType::ObjCClass:
1479 VisitType = Context.getObjCClassType();
1480 break;
1481
1482 case BuiltinType::ObjCSel:
1483 VisitType = Context.getObjCSelType();
1484 break;
1485 }
1486
1487 if (!VisitType.isNull()) {
1488 if (const TypedefType *Typedef = VisitType->getAs<TypedefType>())
1489 return Visit(MakeCursorTypeRef(Typedef->getDecl(), TL.getBuiltinLoc(),
1490 TU));
1491 }
1492
1493 return false;
1494}
1495
1496bool CursorVisitor::VisitTypedefTypeLoc(TypedefTypeLoc TL) {
1497 return Visit(MakeCursorTypeRef(TL.getTypedefNameDecl(), TL.getNameLoc(), TU));
1498}
1499
1500bool CursorVisitor::VisitUnresolvedUsingTypeLoc(UnresolvedUsingTypeLoc TL) {
1501 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1502}
1503
1504bool CursorVisitor::VisitTagTypeLoc(TagTypeLoc TL) {
1505 if (TL.isDefinition())
1506 return Visit(MakeCXCursor(TL.getDecl(), TU, RegionOfInterest));
1507
1508 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1509}
1510
1511bool CursorVisitor::VisitTemplateTypeParmTypeLoc(TemplateTypeParmTypeLoc TL) {
1512 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1513}
1514
1515bool CursorVisitor::VisitObjCInterfaceTypeLoc(ObjCInterfaceTypeLoc TL) {
Hans Wennborg59dbe862015-09-29 20:56:43 +00001516 return Visit(MakeCursorObjCClassRef(TL.getIFaceDecl(), TL.getNameLoc(), TU));
Guy Benyei11169dd2012-12-18 14:30:41 +00001517}
1518
1519bool CursorVisitor::VisitObjCObjectTypeLoc(ObjCObjectTypeLoc TL) {
1520 if (TL.hasBaseTypeAsWritten() && Visit(TL.getBaseLoc()))
1521 return true;
1522
Douglas Gregore9d95f12015-07-07 03:57:35 +00001523 for (unsigned I = 0, N = TL.getNumTypeArgs(); I != N; ++I) {
1524 if (Visit(TL.getTypeArgTInfo(I)->getTypeLoc()))
1525 return true;
1526 }
1527
Guy Benyei11169dd2012-12-18 14:30:41 +00001528 for (unsigned I = 0, N = TL.getNumProtocols(); I != N; ++I) {
1529 if (Visit(MakeCursorObjCProtocolRef(TL.getProtocol(I), TL.getProtocolLoc(I),
1530 TU)))
1531 return true;
1532 }
1533
1534 return false;
1535}
1536
1537bool CursorVisitor::VisitObjCObjectPointerTypeLoc(ObjCObjectPointerTypeLoc TL) {
1538 return Visit(TL.getPointeeLoc());
1539}
1540
1541bool CursorVisitor::VisitParenTypeLoc(ParenTypeLoc TL) {
1542 return Visit(TL.getInnerLoc());
1543}
1544
1545bool CursorVisitor::VisitPointerTypeLoc(PointerTypeLoc TL) {
1546 return Visit(TL.getPointeeLoc());
1547}
1548
1549bool CursorVisitor::VisitBlockPointerTypeLoc(BlockPointerTypeLoc TL) {
1550 return Visit(TL.getPointeeLoc());
1551}
1552
1553bool CursorVisitor::VisitMemberPointerTypeLoc(MemberPointerTypeLoc TL) {
1554 return Visit(TL.getPointeeLoc());
1555}
1556
1557bool CursorVisitor::VisitLValueReferenceTypeLoc(LValueReferenceTypeLoc TL) {
1558 return Visit(TL.getPointeeLoc());
1559}
1560
1561bool CursorVisitor::VisitRValueReferenceTypeLoc(RValueReferenceTypeLoc TL) {
1562 return Visit(TL.getPointeeLoc());
1563}
1564
1565bool CursorVisitor::VisitAttributedTypeLoc(AttributedTypeLoc TL) {
1566 return Visit(TL.getModifiedLoc());
1567}
1568
1569bool CursorVisitor::VisitFunctionTypeLoc(FunctionTypeLoc TL,
1570 bool SkipResultType) {
Alp Toker42a16a62014-01-25 23:51:36 +00001571 if (!SkipResultType && Visit(TL.getReturnLoc()))
Guy Benyei11169dd2012-12-18 14:30:41 +00001572 return true;
1573
Alp Tokerb3fd5cf2014-01-21 00:32:38 +00001574 for (unsigned I = 0, N = TL.getNumParams(); I != N; ++I)
1575 if (Decl *D = TL.getParam(I))
Guy Benyei11169dd2012-12-18 14:30:41 +00001576 if (Visit(MakeCXCursor(D, TU, RegionOfInterest)))
1577 return true;
1578
1579 return false;
1580}
1581
1582bool CursorVisitor::VisitArrayTypeLoc(ArrayTypeLoc TL) {
1583 if (Visit(TL.getElementLoc()))
1584 return true;
1585
1586 if (Expr *Size = TL.getSizeExpr())
1587 return Visit(MakeCXCursor(Size, StmtParent, TU, RegionOfInterest));
1588
1589 return false;
1590}
1591
Reid Kleckner8a365022013-06-24 17:51:48 +00001592bool CursorVisitor::VisitDecayedTypeLoc(DecayedTypeLoc TL) {
1593 return Visit(TL.getOriginalLoc());
1594}
1595
Reid Kleckner0503a872013-12-05 01:23:43 +00001596bool CursorVisitor::VisitAdjustedTypeLoc(AdjustedTypeLoc TL) {
1597 return Visit(TL.getOriginalLoc());
1598}
1599
Guy Benyei11169dd2012-12-18 14:30:41 +00001600bool CursorVisitor::VisitTemplateSpecializationTypeLoc(
1601 TemplateSpecializationTypeLoc TL) {
1602 // Visit the template name.
1603 if (VisitTemplateName(TL.getTypePtr()->getTemplateName(),
1604 TL.getTemplateNameLoc()))
1605 return true;
1606
1607 // Visit the template arguments.
1608 for (unsigned I = 0, N = TL.getNumArgs(); I != N; ++I)
1609 if (VisitTemplateArgumentLoc(TL.getArgLoc(I)))
1610 return true;
1611
1612 return false;
1613}
1614
1615bool CursorVisitor::VisitTypeOfExprTypeLoc(TypeOfExprTypeLoc TL) {
1616 return Visit(MakeCXCursor(TL.getUnderlyingExpr(), StmtParent, TU));
1617}
1618
1619bool CursorVisitor::VisitTypeOfTypeLoc(TypeOfTypeLoc TL) {
1620 if (TypeSourceInfo *TSInfo = TL.getUnderlyingTInfo())
1621 return Visit(TSInfo->getTypeLoc());
1622
1623 return false;
1624}
1625
1626bool CursorVisitor::VisitUnaryTransformTypeLoc(UnaryTransformTypeLoc TL) {
1627 if (TypeSourceInfo *TSInfo = TL.getUnderlyingTInfo())
1628 return Visit(TSInfo->getTypeLoc());
1629
1630 return false;
1631}
1632
1633bool CursorVisitor::VisitDependentNameTypeLoc(DependentNameTypeLoc TL) {
Hans Wennborg59dbe862015-09-29 20:56:43 +00001634 return VisitNestedNameSpecifierLoc(TL.getQualifierLoc());
Guy Benyei11169dd2012-12-18 14:30:41 +00001635}
1636
1637bool CursorVisitor::VisitDependentTemplateSpecializationTypeLoc(
1638 DependentTemplateSpecializationTypeLoc TL) {
1639 // Visit the nested-name-specifier, if there is one.
1640 if (TL.getQualifierLoc() &&
1641 VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
1642 return true;
1643
1644 // Visit the template arguments.
1645 for (unsigned I = 0, N = TL.getNumArgs(); I != N; ++I)
1646 if (VisitTemplateArgumentLoc(TL.getArgLoc(I)))
1647 return true;
1648
1649 return false;
1650}
1651
1652bool CursorVisitor::VisitElaboratedTypeLoc(ElaboratedTypeLoc TL) {
1653 if (VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
1654 return true;
1655
1656 return Visit(TL.getNamedTypeLoc());
1657}
1658
1659bool CursorVisitor::VisitPackExpansionTypeLoc(PackExpansionTypeLoc TL) {
1660 return Visit(TL.getPatternLoc());
1661}
1662
1663bool CursorVisitor::VisitDecltypeTypeLoc(DecltypeTypeLoc TL) {
1664 if (Expr *E = TL.getUnderlyingExpr())
1665 return Visit(MakeCXCursor(E, StmtParent, TU));
1666
1667 return false;
1668}
1669
1670bool CursorVisitor::VisitInjectedClassNameTypeLoc(InjectedClassNameTypeLoc TL) {
1671 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1672}
1673
1674bool CursorVisitor::VisitAtomicTypeLoc(AtomicTypeLoc TL) {
1675 return Visit(TL.getValueLoc());
1676}
1677
Xiuli Pan9c14e282016-01-09 12:53:17 +00001678bool CursorVisitor::VisitPipeTypeLoc(PipeTypeLoc TL) {
1679 return Visit(TL.getValueLoc());
1680}
1681
Guy Benyei11169dd2012-12-18 14:30:41 +00001682#define DEFAULT_TYPELOC_IMPL(CLASS, PARENT) \
1683bool CursorVisitor::Visit##CLASS##TypeLoc(CLASS##TypeLoc TL) { \
1684 return Visit##PARENT##Loc(TL); \
1685}
1686
1687DEFAULT_TYPELOC_IMPL(Complex, Type)
1688DEFAULT_TYPELOC_IMPL(ConstantArray, ArrayType)
1689DEFAULT_TYPELOC_IMPL(IncompleteArray, ArrayType)
1690DEFAULT_TYPELOC_IMPL(VariableArray, ArrayType)
1691DEFAULT_TYPELOC_IMPL(DependentSizedArray, ArrayType)
1692DEFAULT_TYPELOC_IMPL(DependentSizedExtVector, Type)
1693DEFAULT_TYPELOC_IMPL(Vector, Type)
1694DEFAULT_TYPELOC_IMPL(ExtVector, VectorType)
1695DEFAULT_TYPELOC_IMPL(FunctionProto, FunctionType)
1696DEFAULT_TYPELOC_IMPL(FunctionNoProto, FunctionType)
1697DEFAULT_TYPELOC_IMPL(Record, TagType)
1698DEFAULT_TYPELOC_IMPL(Enum, TagType)
1699DEFAULT_TYPELOC_IMPL(SubstTemplateTypeParm, Type)
1700DEFAULT_TYPELOC_IMPL(SubstTemplateTypeParmPack, Type)
1701DEFAULT_TYPELOC_IMPL(Auto, Type)
1702
1703bool CursorVisitor::VisitCXXRecordDecl(CXXRecordDecl *D) {
1704 // Visit the nested-name-specifier, if present.
1705 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1706 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1707 return true;
1708
1709 if (D->isCompleteDefinition()) {
Aaron Ballman574705e2014-03-13 15:41:46 +00001710 for (const auto &I : D->bases()) {
1711 if (Visit(cxcursor::MakeCursorCXXBaseSpecifier(&I, TU)))
Guy Benyei11169dd2012-12-18 14:30:41 +00001712 return true;
1713 }
1714 }
1715
1716 return VisitTagDecl(D);
1717}
1718
1719bool CursorVisitor::VisitAttributes(Decl *D) {
Aaron Ballmanb97112e2014-03-08 22:19:01 +00001720 for (const auto *I : D->attrs())
1721 if (Visit(MakeCXCursor(I, D, TU)))
Guy Benyei11169dd2012-12-18 14:30:41 +00001722 return true;
1723
1724 return false;
1725}
1726
1727//===----------------------------------------------------------------------===//
1728// Data-recursive visitor methods.
1729//===----------------------------------------------------------------------===//
1730
1731namespace {
1732#define DEF_JOB(NAME, DATA, KIND)\
1733class NAME : public VisitorJob {\
1734public:\
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001735 NAME(const DATA *d, CXCursor parent) : \
1736 VisitorJob(parent, VisitorJob::KIND, d) {} \
Guy Benyei11169dd2012-12-18 14:30:41 +00001737 static bool classof(const VisitorJob *VJ) { return VJ->getKind() == KIND; }\
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001738 const DATA *get() const { return static_cast<const DATA*>(data[0]); }\
Guy Benyei11169dd2012-12-18 14:30:41 +00001739};
1740
1741DEF_JOB(StmtVisit, Stmt, StmtVisitKind)
1742DEF_JOB(MemberExprParts, MemberExpr, MemberExprPartsKind)
1743DEF_JOB(DeclRefExprParts, DeclRefExpr, DeclRefExprPartsKind)
1744DEF_JOB(OverloadExprParts, OverloadExpr, OverloadExprPartsKind)
Guy Benyei11169dd2012-12-18 14:30:41 +00001745DEF_JOB(SizeOfPackExprParts, SizeOfPackExpr, SizeOfPackExprPartsKind)
1746DEF_JOB(LambdaExprParts, LambdaExpr, LambdaExprPartsKind)
1747DEF_JOB(PostChildrenVisit, void, PostChildrenVisitKind)
1748#undef DEF_JOB
1749
James Y Knight04ec5bf2015-12-24 02:59:37 +00001750class ExplicitTemplateArgsVisit : public VisitorJob {
1751public:
1752 ExplicitTemplateArgsVisit(const TemplateArgumentLoc *Begin,
1753 const TemplateArgumentLoc *End, CXCursor parent)
1754 : VisitorJob(parent, VisitorJob::ExplicitTemplateArgsVisitKind, Begin,
1755 End) {}
1756 static bool classof(const VisitorJob *VJ) {
1757 return VJ->getKind() == ExplicitTemplateArgsVisitKind;
1758 }
1759 const TemplateArgumentLoc *begin() const {
1760 return static_cast<const TemplateArgumentLoc *>(data[0]);
1761 }
1762 const TemplateArgumentLoc *end() {
1763 return static_cast<const TemplateArgumentLoc *>(data[1]);
1764 }
1765};
Guy Benyei11169dd2012-12-18 14:30:41 +00001766class DeclVisit : public VisitorJob {
1767public:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001768 DeclVisit(const Decl *D, CXCursor parent, bool isFirst) :
Guy Benyei11169dd2012-12-18 14:30:41 +00001769 VisitorJob(parent, VisitorJob::DeclVisitKind,
Craig Topper69186e72014-06-08 08:38:04 +00001770 D, isFirst ? (void*) 1 : (void*) nullptr) {}
Guy Benyei11169dd2012-12-18 14:30:41 +00001771 static bool classof(const VisitorJob *VJ) {
1772 return VJ->getKind() == DeclVisitKind;
1773 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001774 const Decl *get() const { return static_cast<const Decl *>(data[0]); }
Dmitri Gribenkoe5423a72015-03-23 19:23:50 +00001775 bool isFirst() const { return data[1] != nullptr; }
Guy Benyei11169dd2012-12-18 14:30:41 +00001776};
1777class TypeLocVisit : public VisitorJob {
1778public:
1779 TypeLocVisit(TypeLoc tl, CXCursor parent) :
1780 VisitorJob(parent, VisitorJob::TypeLocVisitKind,
1781 tl.getType().getAsOpaquePtr(), tl.getOpaqueData()) {}
1782
1783 static bool classof(const VisitorJob *VJ) {
1784 return VJ->getKind() == TypeLocVisitKind;
1785 }
1786
1787 TypeLoc get() const {
1788 QualType T = QualType::getFromOpaquePtr(data[0]);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001789 return TypeLoc(T, const_cast<void *>(data[1]));
Guy Benyei11169dd2012-12-18 14:30:41 +00001790 }
1791};
1792
1793class LabelRefVisit : public VisitorJob {
1794public:
1795 LabelRefVisit(LabelDecl *LD, SourceLocation labelLoc, CXCursor parent)
1796 : VisitorJob(parent, VisitorJob::LabelRefVisitKind, LD,
1797 labelLoc.getPtrEncoding()) {}
1798
1799 static bool classof(const VisitorJob *VJ) {
1800 return VJ->getKind() == VisitorJob::LabelRefVisitKind;
1801 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001802 const LabelDecl *get() const {
1803 return static_cast<const LabelDecl *>(data[0]);
1804 }
Guy Benyei11169dd2012-12-18 14:30:41 +00001805 SourceLocation getLoc() const {
1806 return SourceLocation::getFromPtrEncoding(data[1]); }
1807};
1808
1809class NestedNameSpecifierLocVisit : public VisitorJob {
1810public:
1811 NestedNameSpecifierLocVisit(NestedNameSpecifierLoc Qualifier, CXCursor parent)
1812 : VisitorJob(parent, VisitorJob::NestedNameSpecifierLocVisitKind,
1813 Qualifier.getNestedNameSpecifier(),
1814 Qualifier.getOpaqueData()) { }
1815
1816 static bool classof(const VisitorJob *VJ) {
1817 return VJ->getKind() == VisitorJob::NestedNameSpecifierLocVisitKind;
1818 }
1819
1820 NestedNameSpecifierLoc get() const {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001821 return NestedNameSpecifierLoc(
1822 const_cast<NestedNameSpecifier *>(
1823 static_cast<const NestedNameSpecifier *>(data[0])),
1824 const_cast<void *>(data[1]));
Guy Benyei11169dd2012-12-18 14:30:41 +00001825 }
1826};
1827
1828class DeclarationNameInfoVisit : public VisitorJob {
1829public:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001830 DeclarationNameInfoVisit(const Stmt *S, CXCursor parent)
Dmitri Gribenkodd7dacf2013-02-03 13:19:54 +00001831 : VisitorJob(parent, VisitorJob::DeclarationNameInfoVisitKind, S) {}
Guy Benyei11169dd2012-12-18 14:30:41 +00001832 static bool classof(const VisitorJob *VJ) {
1833 return VJ->getKind() == VisitorJob::DeclarationNameInfoVisitKind;
1834 }
1835 DeclarationNameInfo get() const {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001836 const Stmt *S = static_cast<const Stmt *>(data[0]);
Guy Benyei11169dd2012-12-18 14:30:41 +00001837 switch (S->getStmtClass()) {
1838 default:
1839 llvm_unreachable("Unhandled Stmt");
1840 case clang::Stmt::MSDependentExistsStmtClass:
1841 return cast<MSDependentExistsStmt>(S)->getNameInfo();
1842 case Stmt::CXXDependentScopeMemberExprClass:
1843 return cast<CXXDependentScopeMemberExpr>(S)->getMemberNameInfo();
1844 case Stmt::DependentScopeDeclRefExprClass:
1845 return cast<DependentScopeDeclRefExpr>(S)->getNameInfo();
Alexander Musmand9ed09f2014-07-21 09:42:05 +00001846 case Stmt::OMPCriticalDirectiveClass:
1847 return cast<OMPCriticalDirective>(S)->getDirectiveName();
Guy Benyei11169dd2012-12-18 14:30:41 +00001848 }
1849 }
1850};
1851class MemberRefVisit : public VisitorJob {
1852public:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001853 MemberRefVisit(const FieldDecl *D, SourceLocation L, CXCursor parent)
Guy Benyei11169dd2012-12-18 14:30:41 +00001854 : VisitorJob(parent, VisitorJob::MemberRefVisitKind, D,
1855 L.getPtrEncoding()) {}
1856 static bool classof(const VisitorJob *VJ) {
1857 return VJ->getKind() == VisitorJob::MemberRefVisitKind;
1858 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001859 const FieldDecl *get() const {
1860 return static_cast<const FieldDecl *>(data[0]);
Guy Benyei11169dd2012-12-18 14:30:41 +00001861 }
1862 SourceLocation getLoc() const {
1863 return SourceLocation::getFromRawEncoding((unsigned)(uintptr_t) data[1]);
1864 }
1865};
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001866class EnqueueVisitor : public ConstStmtVisitor<EnqueueVisitor, void> {
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001867 friend class OMPClauseEnqueue;
Guy Benyei11169dd2012-12-18 14:30:41 +00001868 VisitorWorkList &WL;
1869 CXCursor Parent;
1870public:
1871 EnqueueVisitor(VisitorWorkList &wl, CXCursor parent)
1872 : WL(wl), Parent(parent) {}
1873
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001874 void VisitAddrLabelExpr(const AddrLabelExpr *E);
1875 void VisitBlockExpr(const BlockExpr *B);
1876 void VisitCompoundLiteralExpr(const CompoundLiteralExpr *E);
1877 void VisitCompoundStmt(const CompoundStmt *S);
1878 void VisitCXXDefaultArgExpr(const CXXDefaultArgExpr *E) { /* Do nothing. */ }
1879 void VisitMSDependentExistsStmt(const MSDependentExistsStmt *S);
1880 void VisitCXXDependentScopeMemberExpr(const CXXDependentScopeMemberExpr *E);
1881 void VisitCXXNewExpr(const CXXNewExpr *E);
1882 void VisitCXXScalarValueInitExpr(const CXXScalarValueInitExpr *E);
1883 void VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *E);
1884 void VisitCXXPseudoDestructorExpr(const CXXPseudoDestructorExpr *E);
1885 void VisitCXXTemporaryObjectExpr(const CXXTemporaryObjectExpr *E);
1886 void VisitCXXTypeidExpr(const CXXTypeidExpr *E);
1887 void VisitCXXUnresolvedConstructExpr(const CXXUnresolvedConstructExpr *E);
1888 void VisitCXXUuidofExpr(const CXXUuidofExpr *E);
1889 void VisitCXXCatchStmt(const CXXCatchStmt *S);
Argyrios Kyrtzidis99891242014-11-13 09:03:21 +00001890 void VisitCXXForRangeStmt(const CXXForRangeStmt *S);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001891 void VisitDeclRefExpr(const DeclRefExpr *D);
1892 void VisitDeclStmt(const DeclStmt *S);
1893 void VisitDependentScopeDeclRefExpr(const DependentScopeDeclRefExpr *E);
1894 void VisitDesignatedInitExpr(const DesignatedInitExpr *E);
1895 void VisitExplicitCastExpr(const ExplicitCastExpr *E);
1896 void VisitForStmt(const ForStmt *FS);
1897 void VisitGotoStmt(const GotoStmt *GS);
1898 void VisitIfStmt(const IfStmt *If);
1899 void VisitInitListExpr(const InitListExpr *IE);
1900 void VisitMemberExpr(const MemberExpr *M);
1901 void VisitOffsetOfExpr(const OffsetOfExpr *E);
1902 void VisitObjCEncodeExpr(const ObjCEncodeExpr *E);
1903 void VisitObjCMessageExpr(const ObjCMessageExpr *M);
1904 void VisitOverloadExpr(const OverloadExpr *E);
1905 void VisitUnaryExprOrTypeTraitExpr(const UnaryExprOrTypeTraitExpr *E);
1906 void VisitStmt(const Stmt *S);
1907 void VisitSwitchStmt(const SwitchStmt *S);
1908 void VisitWhileStmt(const WhileStmt *W);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001909 void VisitTypeTraitExpr(const TypeTraitExpr *E);
1910 void VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *E);
1911 void VisitExpressionTraitExpr(const ExpressionTraitExpr *E);
1912 void VisitUnresolvedMemberExpr(const UnresolvedMemberExpr *U);
1913 void VisitVAArgExpr(const VAArgExpr *E);
1914 void VisitSizeOfPackExpr(const SizeOfPackExpr *E);
1915 void VisitPseudoObjectExpr(const PseudoObjectExpr *E);
1916 void VisitOpaqueValueExpr(const OpaqueValueExpr *E);
1917 void VisitLambdaExpr(const LambdaExpr *E);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001918 void VisitOMPExecutableDirective(const OMPExecutableDirective *D);
Alexander Musman3aaab662014-08-19 11:27:13 +00001919 void VisitOMPLoopDirective(const OMPLoopDirective *D);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001920 void VisitOMPParallelDirective(const OMPParallelDirective *D);
Alexey Bataev1b59ab52014-02-27 08:29:12 +00001921 void VisitOMPSimdDirective(const OMPSimdDirective *D);
Alexey Bataevf29276e2014-06-18 04:14:57 +00001922 void VisitOMPForDirective(const OMPForDirective *D);
Alexander Musmanf82886e2014-09-18 05:12:34 +00001923 void VisitOMPForSimdDirective(const OMPForSimdDirective *D);
Alexey Bataevd3f8dd22014-06-25 11:44:49 +00001924 void VisitOMPSectionsDirective(const OMPSectionsDirective *D);
Alexey Bataev1e0498a2014-06-26 08:21:58 +00001925 void VisitOMPSectionDirective(const OMPSectionDirective *D);
Alexey Bataevd1e40fb2014-06-26 12:05:45 +00001926 void VisitOMPSingleDirective(const OMPSingleDirective *D);
Alexander Musman80c22892014-07-17 08:54:58 +00001927 void VisitOMPMasterDirective(const OMPMasterDirective *D);
Alexander Musmand9ed09f2014-07-21 09:42:05 +00001928 void VisitOMPCriticalDirective(const OMPCriticalDirective *D);
Alexey Bataev4acb8592014-07-07 13:01:15 +00001929 void VisitOMPParallelForDirective(const OMPParallelForDirective *D);
Alexander Musmane4e893b2014-09-23 09:33:00 +00001930 void VisitOMPParallelForSimdDirective(const OMPParallelForSimdDirective *D);
Alexey Bataev84d0b3e2014-07-08 08:12:03 +00001931 void VisitOMPParallelSectionsDirective(const OMPParallelSectionsDirective *D);
Alexey Bataev9c2e8ee2014-07-11 11:25:16 +00001932 void VisitOMPTaskDirective(const OMPTaskDirective *D);
Alexey Bataev68446b72014-07-18 07:47:19 +00001933 void VisitOMPTaskyieldDirective(const OMPTaskyieldDirective *D);
Alexey Bataev4d1dfea2014-07-18 09:11:51 +00001934 void VisitOMPBarrierDirective(const OMPBarrierDirective *D);
Alexey Bataev2df347a2014-07-18 10:17:07 +00001935 void VisitOMPTaskwaitDirective(const OMPTaskwaitDirective *D);
Alexey Bataevc30dd2d2015-06-18 12:14:09 +00001936 void VisitOMPTaskgroupDirective(const OMPTaskgroupDirective *D);
Alexey Bataev6d4ed052015-07-01 06:57:41 +00001937 void
1938 VisitOMPCancellationPointDirective(const OMPCancellationPointDirective *D);
Alexey Bataev80909872015-07-02 11:25:17 +00001939 void VisitOMPCancelDirective(const OMPCancelDirective *D);
Alexey Bataev6125da92014-07-21 11:26:11 +00001940 void VisitOMPFlushDirective(const OMPFlushDirective *D);
Alexey Bataev9fb6e642014-07-22 06:45:04 +00001941 void VisitOMPOrderedDirective(const OMPOrderedDirective *D);
Alexey Bataev0162e452014-07-22 10:10:35 +00001942 void VisitOMPAtomicDirective(const OMPAtomicDirective *D);
Alexey Bataev0bd520b2014-09-19 08:19:49 +00001943 void VisitOMPTargetDirective(const OMPTargetDirective *D);
Michael Wong65f367f2015-07-21 13:44:28 +00001944 void VisitOMPTargetDataDirective(const OMPTargetDataDirective *D);
Samuel Antaodf67fc42016-01-19 19:15:56 +00001945 void VisitOMPTargetEnterDataDirective(const OMPTargetEnterDataDirective *D);
Samuel Antao72590762016-01-19 20:04:50 +00001946 void VisitOMPTargetExitDataDirective(const OMPTargetExitDataDirective *D);
Arpith Chacko Jacobe955b3d2016-01-26 18:48:41 +00001947 void VisitOMPTargetParallelDirective(const OMPTargetParallelDirective *D);
Arpith Chacko Jacob05bebb52016-02-03 15:46:42 +00001948 void
1949 VisitOMPTargetParallelForDirective(const OMPTargetParallelForDirective *D);
Alexey Bataev13314bf2014-10-09 04:18:56 +00001950 void VisitOMPTeamsDirective(const OMPTeamsDirective *D);
Alexey Bataev49f6e782015-12-01 04:18:41 +00001951 void VisitOMPTaskLoopDirective(const OMPTaskLoopDirective *D);
Alexey Bataev0a6ed842015-12-03 09:40:15 +00001952 void VisitOMPTaskLoopSimdDirective(const OMPTaskLoopSimdDirective *D);
Carlo Bertolli6200a3d2015-12-14 14:51:25 +00001953 void VisitOMPDistributeDirective(const OMPDistributeDirective *D);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001954
Guy Benyei11169dd2012-12-18 14:30:41 +00001955private:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001956 void AddDeclarationNameInfo(const Stmt *S);
Guy Benyei11169dd2012-12-18 14:30:41 +00001957 void AddNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier);
James Y Knight04ec5bf2015-12-24 02:59:37 +00001958 void AddExplicitTemplateArgs(const TemplateArgumentLoc *A,
1959 unsigned NumTemplateArgs);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001960 void AddMemberRef(const FieldDecl *D, SourceLocation L);
1961 void AddStmt(const Stmt *S);
1962 void AddDecl(const Decl *D, bool isFirst = true);
Guy Benyei11169dd2012-12-18 14:30:41 +00001963 void AddTypeLoc(TypeSourceInfo *TI);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001964 void EnqueueChildren(const Stmt *S);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001965 void EnqueueChildren(const OMPClause *S);
Guy Benyei11169dd2012-12-18 14:30:41 +00001966};
Alexander Kornienkoab9db512015-06-22 23:07:51 +00001967} // end anonyous namespace
Guy Benyei11169dd2012-12-18 14:30:41 +00001968
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001969void EnqueueVisitor::AddDeclarationNameInfo(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001970 // 'S' should always be non-null, since it comes from the
1971 // statement we are visiting.
1972 WL.push_back(DeclarationNameInfoVisit(S, Parent));
1973}
1974
1975void
1976EnqueueVisitor::AddNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier) {
1977 if (Qualifier)
1978 WL.push_back(NestedNameSpecifierLocVisit(Qualifier, Parent));
1979}
1980
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001981void EnqueueVisitor::AddStmt(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001982 if (S)
1983 WL.push_back(StmtVisit(S, Parent));
1984}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001985void EnqueueVisitor::AddDecl(const Decl *D, bool isFirst) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001986 if (D)
1987 WL.push_back(DeclVisit(D, Parent, isFirst));
1988}
James Y Knight04ec5bf2015-12-24 02:59:37 +00001989void EnqueueVisitor::AddExplicitTemplateArgs(const TemplateArgumentLoc *A,
1990 unsigned NumTemplateArgs) {
1991 WL.push_back(ExplicitTemplateArgsVisit(A, A + NumTemplateArgs, Parent));
Guy Benyei11169dd2012-12-18 14:30:41 +00001992}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001993void EnqueueVisitor::AddMemberRef(const FieldDecl *D, SourceLocation L) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001994 if (D)
1995 WL.push_back(MemberRefVisit(D, L, Parent));
1996}
1997void EnqueueVisitor::AddTypeLoc(TypeSourceInfo *TI) {
1998 if (TI)
1999 WL.push_back(TypeLocVisit(TI->getTypeLoc(), Parent));
2000 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002001void EnqueueVisitor::EnqueueChildren(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002002 unsigned size = WL.size();
Benjamin Kramer642f1732015-07-02 21:03:14 +00002003 for (const Stmt *SubStmt : S->children()) {
2004 AddStmt(SubStmt);
Guy Benyei11169dd2012-12-18 14:30:41 +00002005 }
2006 if (size == WL.size())
2007 return;
2008 // Now reverse the entries we just added. This will match the DFS
2009 // ordering performed by the worklist.
2010 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
2011 std::reverse(I, E);
2012}
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002013namespace {
2014class OMPClauseEnqueue : public ConstOMPClauseVisitor<OMPClauseEnqueue> {
2015 EnqueueVisitor *Visitor;
Alexey Bataev756c1962013-09-24 03:17:45 +00002016 /// \brief Process clauses with list of variables.
2017 template <typename T>
2018 void VisitOMPClauseList(T *Node);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002019public:
2020 OMPClauseEnqueue(EnqueueVisitor *Visitor) : Visitor(Visitor) { }
2021#define OPENMP_CLAUSE(Name, Class) \
2022 void Visit##Class(const Class *C);
2023#include "clang/Basic/OpenMPKinds.def"
Alexey Bataev3392d762016-02-16 11:18:12 +00002024 void VisitOMPClauseWithPreInit(const OMPClauseWithPreInit *C);
Alexey Bataev005248a2016-02-25 05:25:57 +00002025 void VisitOMPClauseWithPostUpdate(const OMPClauseWithPostUpdate *C);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002026};
2027
Alexey Bataev3392d762016-02-16 11:18:12 +00002028void OMPClauseEnqueue::VisitOMPClauseWithPreInit(
2029 const OMPClauseWithPreInit *C) {
2030 Visitor->AddStmt(C->getPreInitStmt());
2031}
2032
Alexey Bataev005248a2016-02-25 05:25:57 +00002033void OMPClauseEnqueue::VisitOMPClauseWithPostUpdate(
2034 const OMPClauseWithPostUpdate *C) {
Alexey Bataev37e594c2016-03-04 07:21:16 +00002035 VisitOMPClauseWithPreInit(C);
Alexey Bataev005248a2016-02-25 05:25:57 +00002036 Visitor->AddStmt(C->getPostUpdateExpr());
2037}
2038
Alexey Bataevaadd52e2014-02-13 05:29:23 +00002039void OMPClauseEnqueue::VisitOMPIfClause(const OMPIfClause *C) {
2040 Visitor->AddStmt(C->getCondition());
2041}
2042
Alexey Bataev3778b602014-07-17 07:32:53 +00002043void OMPClauseEnqueue::VisitOMPFinalClause(const OMPFinalClause *C) {
2044 Visitor->AddStmt(C->getCondition());
2045}
2046
Alexey Bataev568a8332014-03-06 06:15:19 +00002047void OMPClauseEnqueue::VisitOMPNumThreadsClause(const OMPNumThreadsClause *C) {
2048 Visitor->AddStmt(C->getNumThreads());
2049}
2050
Alexey Bataev62c87d22014-03-21 04:51:18 +00002051void OMPClauseEnqueue::VisitOMPSafelenClause(const OMPSafelenClause *C) {
2052 Visitor->AddStmt(C->getSafelen());
2053}
2054
Alexey Bataev66b15b52015-08-21 11:14:16 +00002055void OMPClauseEnqueue::VisitOMPSimdlenClause(const OMPSimdlenClause *C) {
2056 Visitor->AddStmt(C->getSimdlen());
2057}
2058
Alexander Musman8bd31e62014-05-27 15:12:19 +00002059void OMPClauseEnqueue::VisitOMPCollapseClause(const OMPCollapseClause *C) {
2060 Visitor->AddStmt(C->getNumForLoops());
2061}
2062
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002063void OMPClauseEnqueue::VisitOMPDefaultClause(const OMPDefaultClause *C) { }
Alexey Bataev756c1962013-09-24 03:17:45 +00002064
Alexey Bataevbcbadb62014-05-06 06:04:14 +00002065void OMPClauseEnqueue::VisitOMPProcBindClause(const OMPProcBindClause *C) { }
2066
Alexey Bataev56dafe82014-06-20 07:16:17 +00002067void OMPClauseEnqueue::VisitOMPScheduleClause(const OMPScheduleClause *C) {
Alexey Bataev3392d762016-02-16 11:18:12 +00002068 VisitOMPClauseWithPreInit(C);
Alexey Bataev56dafe82014-06-20 07:16:17 +00002069 Visitor->AddStmt(C->getChunkSize());
2070}
2071
Alexey Bataev10e775f2015-07-30 11:36:16 +00002072void OMPClauseEnqueue::VisitOMPOrderedClause(const OMPOrderedClause *C) {
2073 Visitor->AddStmt(C->getNumForLoops());
2074}
Alexey Bataev142e1fc2014-06-20 09:44:06 +00002075
Alexey Bataev236070f2014-06-20 11:19:47 +00002076void OMPClauseEnqueue::VisitOMPNowaitClause(const OMPNowaitClause *) {}
2077
Alexey Bataev7aea99a2014-07-17 12:19:31 +00002078void OMPClauseEnqueue::VisitOMPUntiedClause(const OMPUntiedClause *) {}
2079
Alexey Bataev74ba3a52014-07-17 12:47:03 +00002080void OMPClauseEnqueue::VisitOMPMergeableClause(const OMPMergeableClause *) {}
2081
Alexey Bataevf98b00c2014-07-23 02:27:21 +00002082void OMPClauseEnqueue::VisitOMPReadClause(const OMPReadClause *) {}
2083
Alexey Bataevdea47612014-07-23 07:46:59 +00002084void OMPClauseEnqueue::VisitOMPWriteClause(const OMPWriteClause *) {}
2085
Alexey Bataev67a4f222014-07-23 10:25:33 +00002086void OMPClauseEnqueue::VisitOMPUpdateClause(const OMPUpdateClause *) {}
2087
Alexey Bataev459dec02014-07-24 06:46:57 +00002088void OMPClauseEnqueue::VisitOMPCaptureClause(const OMPCaptureClause *) {}
2089
Alexey Bataev82bad8b2014-07-24 08:55:34 +00002090void OMPClauseEnqueue::VisitOMPSeqCstClause(const OMPSeqCstClause *) {}
2091
Alexey Bataev346265e2015-09-25 10:37:12 +00002092void OMPClauseEnqueue::VisitOMPThreadsClause(const OMPThreadsClause *) {}
2093
Alexey Bataevd14d1e62015-09-28 06:39:35 +00002094void OMPClauseEnqueue::VisitOMPSIMDClause(const OMPSIMDClause *) {}
2095
Alexey Bataevb825de12015-12-07 10:51:44 +00002096void OMPClauseEnqueue::VisitOMPNogroupClause(const OMPNogroupClause *) {}
2097
Michael Wonge710d542015-08-07 16:16:36 +00002098void OMPClauseEnqueue::VisitOMPDeviceClause(const OMPDeviceClause *C) {
2099 Visitor->AddStmt(C->getDevice());
2100}
2101
Kelvin Li099bb8c2015-11-24 20:50:12 +00002102void OMPClauseEnqueue::VisitOMPNumTeamsClause(const OMPNumTeamsClause *C) {
2103 Visitor->AddStmt(C->getNumTeams());
2104}
2105
Kelvin Lia15fb1a2015-11-27 18:47:36 +00002106void OMPClauseEnqueue::VisitOMPThreadLimitClause(const OMPThreadLimitClause *C) {
2107 Visitor->AddStmt(C->getThreadLimit());
2108}
2109
Alexey Bataeva0569352015-12-01 10:17:31 +00002110void OMPClauseEnqueue::VisitOMPPriorityClause(const OMPPriorityClause *C) {
2111 Visitor->AddStmt(C->getPriority());
2112}
2113
Alexey Bataev1fd4aed2015-12-07 12:52:51 +00002114void OMPClauseEnqueue::VisitOMPGrainsizeClause(const OMPGrainsizeClause *C) {
2115 Visitor->AddStmt(C->getGrainsize());
2116}
2117
Alexey Bataev382967a2015-12-08 12:06:20 +00002118void OMPClauseEnqueue::VisitOMPNumTasksClause(const OMPNumTasksClause *C) {
2119 Visitor->AddStmt(C->getNumTasks());
2120}
2121
Alexey Bataev28c75412015-12-15 08:19:24 +00002122void OMPClauseEnqueue::VisitOMPHintClause(const OMPHintClause *C) {
2123 Visitor->AddStmt(C->getHint());
2124}
2125
Alexey Bataev756c1962013-09-24 03:17:45 +00002126template<typename T>
2127void OMPClauseEnqueue::VisitOMPClauseList(T *Node) {
Alexey Bataev03b340a2014-10-21 03:16:40 +00002128 for (const auto *I : Node->varlists()) {
Aaron Ballman2205d2a2014-03-14 15:55:35 +00002129 Visitor->AddStmt(I);
Alexey Bataev03b340a2014-10-21 03:16:40 +00002130 }
Alexey Bataev756c1962013-09-24 03:17:45 +00002131}
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002132
2133void OMPClauseEnqueue::VisitOMPPrivateClause(const OMPPrivateClause *C) {
Alexey Bataev756c1962013-09-24 03:17:45 +00002134 VisitOMPClauseList(C);
Alexey Bataev03b340a2014-10-21 03:16:40 +00002135 for (const auto *E : C->private_copies()) {
2136 Visitor->AddStmt(E);
2137 }
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002138}
Alexey Bataevd5af8e42013-10-01 05:32:34 +00002139void OMPClauseEnqueue::VisitOMPFirstprivateClause(
2140 const OMPFirstprivateClause *C) {
2141 VisitOMPClauseList(C);
Alexey Bataev417089f2016-02-17 13:19:37 +00002142 VisitOMPClauseWithPreInit(C);
2143 for (const auto *E : C->private_copies()) {
2144 Visitor->AddStmt(E);
2145 }
2146 for (const auto *E : C->inits()) {
2147 Visitor->AddStmt(E);
2148 }
Alexey Bataevd5af8e42013-10-01 05:32:34 +00002149}
Alexander Musman1bb328c2014-06-04 13:06:39 +00002150void OMPClauseEnqueue::VisitOMPLastprivateClause(
2151 const OMPLastprivateClause *C) {
2152 VisitOMPClauseList(C);
Alexey Bataev005248a2016-02-25 05:25:57 +00002153 VisitOMPClauseWithPostUpdate(C);
Alexey Bataev38e89532015-04-16 04:54:05 +00002154 for (auto *E : C->private_copies()) {
2155 Visitor->AddStmt(E);
2156 }
2157 for (auto *E : C->source_exprs()) {
2158 Visitor->AddStmt(E);
2159 }
2160 for (auto *E : C->destination_exprs()) {
2161 Visitor->AddStmt(E);
2162 }
2163 for (auto *E : C->assignment_ops()) {
2164 Visitor->AddStmt(E);
2165 }
Alexander Musman1bb328c2014-06-04 13:06:39 +00002166}
Alexey Bataev758e55e2013-09-06 18:03:48 +00002167void OMPClauseEnqueue::VisitOMPSharedClause(const OMPSharedClause *C) {
Alexey Bataev756c1962013-09-24 03:17:45 +00002168 VisitOMPClauseList(C);
Alexey Bataev758e55e2013-09-06 18:03:48 +00002169}
Alexey Bataevc5e02582014-06-16 07:08:35 +00002170void OMPClauseEnqueue::VisitOMPReductionClause(const OMPReductionClause *C) {
2171 VisitOMPClauseList(C);
Alexey Bataev61205072016-03-02 04:57:40 +00002172 VisitOMPClauseWithPostUpdate(C);
Alexey Bataevf24e7b12015-10-08 09:10:53 +00002173 for (auto *E : C->privates()) {
2174 Visitor->AddStmt(E);
2175 }
Alexey Bataev794ba0d2015-04-10 10:43:45 +00002176 for (auto *E : C->lhs_exprs()) {
2177 Visitor->AddStmt(E);
2178 }
2179 for (auto *E : C->rhs_exprs()) {
2180 Visitor->AddStmt(E);
2181 }
2182 for (auto *E : C->reduction_ops()) {
2183 Visitor->AddStmt(E);
2184 }
Alexey Bataevc5e02582014-06-16 07:08:35 +00002185}
Alexander Musman8dba6642014-04-22 13:09:42 +00002186void OMPClauseEnqueue::VisitOMPLinearClause(const OMPLinearClause *C) {
2187 VisitOMPClauseList(C);
Alexey Bataev78849fb2016-03-09 09:49:00 +00002188 VisitOMPClauseWithPostUpdate(C);
Alexey Bataevbd9fec12015-08-18 06:47:21 +00002189 for (const auto *E : C->privates()) {
2190 Visitor->AddStmt(E);
2191 }
Alexander Musman3276a272015-03-21 10:12:56 +00002192 for (const auto *E : C->inits()) {
2193 Visitor->AddStmt(E);
2194 }
2195 for (const auto *E : C->updates()) {
2196 Visitor->AddStmt(E);
2197 }
2198 for (const auto *E : C->finals()) {
2199 Visitor->AddStmt(E);
2200 }
Alexander Musman8dba6642014-04-22 13:09:42 +00002201 Visitor->AddStmt(C->getStep());
Alexander Musman3276a272015-03-21 10:12:56 +00002202 Visitor->AddStmt(C->getCalcStep());
Alexander Musman8dba6642014-04-22 13:09:42 +00002203}
Alexander Musmanf0d76e72014-05-29 14:36:25 +00002204void OMPClauseEnqueue::VisitOMPAlignedClause(const OMPAlignedClause *C) {
2205 VisitOMPClauseList(C);
2206 Visitor->AddStmt(C->getAlignment());
2207}
Alexey Bataevd48bcd82014-03-31 03:36:38 +00002208void OMPClauseEnqueue::VisitOMPCopyinClause(const OMPCopyinClause *C) {
2209 VisitOMPClauseList(C);
Alexey Bataevf56f98c2015-04-16 05:39:01 +00002210 for (auto *E : C->source_exprs()) {
2211 Visitor->AddStmt(E);
2212 }
2213 for (auto *E : C->destination_exprs()) {
2214 Visitor->AddStmt(E);
2215 }
2216 for (auto *E : C->assignment_ops()) {
2217 Visitor->AddStmt(E);
2218 }
Alexey Bataevd48bcd82014-03-31 03:36:38 +00002219}
Alexey Bataevbae9a792014-06-27 10:37:06 +00002220void
2221OMPClauseEnqueue::VisitOMPCopyprivateClause(const OMPCopyprivateClause *C) {
2222 VisitOMPClauseList(C);
Alexey Bataeva63048e2015-03-23 06:18:07 +00002223 for (auto *E : C->source_exprs()) {
2224 Visitor->AddStmt(E);
2225 }
2226 for (auto *E : C->destination_exprs()) {
2227 Visitor->AddStmt(E);
2228 }
2229 for (auto *E : C->assignment_ops()) {
2230 Visitor->AddStmt(E);
2231 }
Alexey Bataevbae9a792014-06-27 10:37:06 +00002232}
Alexey Bataev6125da92014-07-21 11:26:11 +00002233void OMPClauseEnqueue::VisitOMPFlushClause(const OMPFlushClause *C) {
2234 VisitOMPClauseList(C);
2235}
Alexey Bataev1c2cfbc2015-06-23 14:25:19 +00002236void OMPClauseEnqueue::VisitOMPDependClause(const OMPDependClause *C) {
2237 VisitOMPClauseList(C);
2238}
Kelvin Li0bff7af2015-11-23 05:32:03 +00002239void OMPClauseEnqueue::VisitOMPMapClause(const OMPMapClause *C) {
2240 VisitOMPClauseList(C);
2241}
Carlo Bertollib4adf552016-01-15 18:50:31 +00002242void OMPClauseEnqueue::VisitOMPDistScheduleClause(
2243 const OMPDistScheduleClause *C) {
Alexey Bataev3392d762016-02-16 11:18:12 +00002244 VisitOMPClauseWithPreInit(C);
Carlo Bertollib4adf552016-01-15 18:50:31 +00002245 Visitor->AddStmt(C->getChunkSize());
Carlo Bertollib4adf552016-01-15 18:50:31 +00002246}
Alexey Bataev3392d762016-02-16 11:18:12 +00002247void OMPClauseEnqueue::VisitOMPDefaultmapClause(
2248 const OMPDefaultmapClause * /*C*/) {}
Samuel Antao661c0902016-05-26 17:39:58 +00002249void OMPClauseEnqueue::VisitOMPToClause(const OMPToClause *C) {
2250 VisitOMPClauseList(C);
2251}
Samuel Antaoec172c62016-05-26 17:49:04 +00002252void OMPClauseEnqueue::VisitOMPFromClause(const OMPFromClause *C) {
2253 VisitOMPClauseList(C);
2254}
Alexander Kornienkoab9db512015-06-22 23:07:51 +00002255}
Alexey Bataev756c1962013-09-24 03:17:45 +00002256
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002257void EnqueueVisitor::EnqueueChildren(const OMPClause *S) {
2258 unsigned size = WL.size();
2259 OMPClauseEnqueue Visitor(this);
2260 Visitor.Visit(S);
2261 if (size == WL.size())
2262 return;
2263 // Now reverse the entries we just added. This will match the DFS
2264 // ordering performed by the worklist.
2265 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
2266 std::reverse(I, E);
2267}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002268void EnqueueVisitor::VisitAddrLabelExpr(const AddrLabelExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002269 WL.push_back(LabelRefVisit(E->getLabel(), E->getLabelLoc(), Parent));
2270}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002271void EnqueueVisitor::VisitBlockExpr(const BlockExpr *B) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002272 AddDecl(B->getBlockDecl());
2273}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002274void EnqueueVisitor::VisitCompoundLiteralExpr(const CompoundLiteralExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002275 EnqueueChildren(E);
2276 AddTypeLoc(E->getTypeSourceInfo());
2277}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002278void EnqueueVisitor::VisitCompoundStmt(const CompoundStmt *S) {
Pete Cooper57d3f142015-07-30 17:22:52 +00002279 for (auto &I : llvm::reverse(S->body()))
2280 AddStmt(I);
Guy Benyei11169dd2012-12-18 14:30:41 +00002281}
2282void EnqueueVisitor::
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002283VisitMSDependentExistsStmt(const MSDependentExistsStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002284 AddStmt(S->getSubStmt());
2285 AddDeclarationNameInfo(S);
2286 if (NestedNameSpecifierLoc QualifierLoc = S->getQualifierLoc())
2287 AddNestedNameSpecifierLoc(QualifierLoc);
2288}
2289
2290void EnqueueVisitor::
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002291VisitCXXDependentScopeMemberExpr(const CXXDependentScopeMemberExpr *E) {
James Y Knight04ec5bf2015-12-24 02:59:37 +00002292 if (E->hasExplicitTemplateArgs())
2293 AddExplicitTemplateArgs(E->getTemplateArgs(), E->getNumTemplateArgs());
Guy Benyei11169dd2012-12-18 14:30:41 +00002294 AddDeclarationNameInfo(E);
2295 if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
2296 AddNestedNameSpecifierLoc(QualifierLoc);
2297 if (!E->isImplicitAccess())
2298 AddStmt(E->getBase());
2299}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002300void EnqueueVisitor::VisitCXXNewExpr(const CXXNewExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002301 // Enqueue the initializer , if any.
2302 AddStmt(E->getInitializer());
2303 // Enqueue the array size, if any.
2304 AddStmt(E->getArraySize());
2305 // Enqueue the allocated type.
2306 AddTypeLoc(E->getAllocatedTypeSourceInfo());
2307 // Enqueue the placement arguments.
2308 for (unsigned I = E->getNumPlacementArgs(); I > 0; --I)
2309 AddStmt(E->getPlacementArg(I-1));
2310}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002311void EnqueueVisitor::VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *CE) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002312 for (unsigned I = CE->getNumArgs(); I > 1 /* Yes, this is 1 */; --I)
2313 AddStmt(CE->getArg(I-1));
2314 AddStmt(CE->getCallee());
2315 AddStmt(CE->getArg(0));
2316}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002317void EnqueueVisitor::VisitCXXPseudoDestructorExpr(
2318 const CXXPseudoDestructorExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002319 // Visit the name of the type being destroyed.
2320 AddTypeLoc(E->getDestroyedTypeInfo());
2321 // Visit the scope type that looks disturbingly like the nested-name-specifier
2322 // but isn't.
2323 AddTypeLoc(E->getScopeTypeInfo());
2324 // Visit the nested-name-specifier.
2325 if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
2326 AddNestedNameSpecifierLoc(QualifierLoc);
2327 // Visit base expression.
2328 AddStmt(E->getBase());
2329}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002330void EnqueueVisitor::VisitCXXScalarValueInitExpr(
2331 const CXXScalarValueInitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002332 AddTypeLoc(E->getTypeSourceInfo());
2333}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002334void EnqueueVisitor::VisitCXXTemporaryObjectExpr(
2335 const CXXTemporaryObjectExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002336 EnqueueChildren(E);
2337 AddTypeLoc(E->getTypeSourceInfo());
2338}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002339void EnqueueVisitor::VisitCXXTypeidExpr(const CXXTypeidExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002340 EnqueueChildren(E);
2341 if (E->isTypeOperand())
2342 AddTypeLoc(E->getTypeOperandSourceInfo());
2343}
2344
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002345void EnqueueVisitor::VisitCXXUnresolvedConstructExpr(
2346 const CXXUnresolvedConstructExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002347 EnqueueChildren(E);
2348 AddTypeLoc(E->getTypeSourceInfo());
2349}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002350void EnqueueVisitor::VisitCXXUuidofExpr(const CXXUuidofExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002351 EnqueueChildren(E);
2352 if (E->isTypeOperand())
2353 AddTypeLoc(E->getTypeOperandSourceInfo());
2354}
2355
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002356void EnqueueVisitor::VisitCXXCatchStmt(const CXXCatchStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002357 EnqueueChildren(S);
2358 AddDecl(S->getExceptionDecl());
2359}
2360
Argyrios Kyrtzidis99891242014-11-13 09:03:21 +00002361void EnqueueVisitor::VisitCXXForRangeStmt(const CXXForRangeStmt *S) {
Argyrios Kyrtzidiscde70692014-11-13 09:50:19 +00002362 AddStmt(S->getBody());
Argyrios Kyrtzidis99891242014-11-13 09:03:21 +00002363 AddStmt(S->getRangeInit());
Argyrios Kyrtzidiscde70692014-11-13 09:50:19 +00002364 AddDecl(S->getLoopVariable());
Argyrios Kyrtzidis99891242014-11-13 09:03:21 +00002365}
2366
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002367void EnqueueVisitor::VisitDeclRefExpr(const DeclRefExpr *DR) {
James Y Knight04ec5bf2015-12-24 02:59:37 +00002368 if (DR->hasExplicitTemplateArgs())
2369 AddExplicitTemplateArgs(DR->getTemplateArgs(), DR->getNumTemplateArgs());
Guy Benyei11169dd2012-12-18 14:30:41 +00002370 WL.push_back(DeclRefExprParts(DR, Parent));
2371}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002372void EnqueueVisitor::VisitDependentScopeDeclRefExpr(
2373 const DependentScopeDeclRefExpr *E) {
James Y Knight04ec5bf2015-12-24 02:59:37 +00002374 if (E->hasExplicitTemplateArgs())
2375 AddExplicitTemplateArgs(E->getTemplateArgs(), E->getNumTemplateArgs());
Guy Benyei11169dd2012-12-18 14:30:41 +00002376 AddDeclarationNameInfo(E);
2377 AddNestedNameSpecifierLoc(E->getQualifierLoc());
2378}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002379void EnqueueVisitor::VisitDeclStmt(const DeclStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002380 unsigned size = WL.size();
2381 bool isFirst = true;
Aaron Ballman535bbcc2014-03-14 17:01:24 +00002382 for (const auto *D : S->decls()) {
2383 AddDecl(D, isFirst);
Guy Benyei11169dd2012-12-18 14:30:41 +00002384 isFirst = false;
2385 }
2386 if (size == WL.size())
2387 return;
2388 // Now reverse the entries we just added. This will match the DFS
2389 // ordering performed by the worklist.
2390 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
2391 std::reverse(I, E);
2392}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002393void EnqueueVisitor::VisitDesignatedInitExpr(const DesignatedInitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002394 AddStmt(E->getInit());
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002395 for (DesignatedInitExpr::const_reverse_designators_iterator
Guy Benyei11169dd2012-12-18 14:30:41 +00002396 D = E->designators_rbegin(), DEnd = E->designators_rend();
2397 D != DEnd; ++D) {
2398 if (D->isFieldDesignator()) {
2399 if (FieldDecl *Field = D->getField())
2400 AddMemberRef(Field, D->getFieldLoc());
2401 continue;
2402 }
2403 if (D->isArrayDesignator()) {
2404 AddStmt(E->getArrayIndex(*D));
2405 continue;
2406 }
2407 assert(D->isArrayRangeDesignator() && "Unknown designator kind");
2408 AddStmt(E->getArrayRangeEnd(*D));
2409 AddStmt(E->getArrayRangeStart(*D));
2410 }
2411}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002412void EnqueueVisitor::VisitExplicitCastExpr(const ExplicitCastExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002413 EnqueueChildren(E);
2414 AddTypeLoc(E->getTypeInfoAsWritten());
2415}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002416void EnqueueVisitor::VisitForStmt(const ForStmt *FS) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002417 AddStmt(FS->getBody());
2418 AddStmt(FS->getInc());
2419 AddStmt(FS->getCond());
2420 AddDecl(FS->getConditionVariable());
2421 AddStmt(FS->getInit());
2422}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002423void EnqueueVisitor::VisitGotoStmt(const GotoStmt *GS) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002424 WL.push_back(LabelRefVisit(GS->getLabel(), GS->getLabelLoc(), Parent));
2425}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002426void EnqueueVisitor::VisitIfStmt(const IfStmt *If) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002427 AddStmt(If->getElse());
2428 AddStmt(If->getThen());
2429 AddStmt(If->getCond());
2430 AddDecl(If->getConditionVariable());
2431}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002432void EnqueueVisitor::VisitInitListExpr(const InitListExpr *IE) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002433 // We care about the syntactic form of the initializer list, only.
2434 if (InitListExpr *Syntactic = IE->getSyntacticForm())
2435 IE = Syntactic;
2436 EnqueueChildren(IE);
2437}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002438void EnqueueVisitor::VisitMemberExpr(const MemberExpr *M) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002439 WL.push_back(MemberExprParts(M, Parent));
2440
2441 // If the base of the member access expression is an implicit 'this', don't
2442 // visit it.
2443 // FIXME: If we ever want to show these implicit accesses, this will be
2444 // unfortunate. However, clang_getCursor() relies on this behavior.
Argyrios Kyrtzidis58d0e7a2015-03-13 04:40:07 +00002445 if (M->isImplicitAccess())
2446 return;
2447
2448 // Ignore base anonymous struct/union fields, otherwise they will shadow the
2449 // real field that that we are interested in.
2450 if (auto *SubME = dyn_cast<MemberExpr>(M->getBase())) {
2451 if (auto *FD = dyn_cast_or_null<FieldDecl>(SubME->getMemberDecl())) {
2452 if (FD->isAnonymousStructOrUnion()) {
2453 AddStmt(SubME->getBase());
2454 return;
2455 }
2456 }
2457 }
2458
2459 AddStmt(M->getBase());
Guy Benyei11169dd2012-12-18 14:30:41 +00002460}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002461void EnqueueVisitor::VisitObjCEncodeExpr(const ObjCEncodeExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002462 AddTypeLoc(E->getEncodedTypeSourceInfo());
2463}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002464void EnqueueVisitor::VisitObjCMessageExpr(const ObjCMessageExpr *M) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002465 EnqueueChildren(M);
2466 AddTypeLoc(M->getClassReceiverTypeInfo());
2467}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002468void EnqueueVisitor::VisitOffsetOfExpr(const OffsetOfExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002469 // Visit the components of the offsetof expression.
2470 for (unsigned N = E->getNumComponents(), I = N; I > 0; --I) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002471 const OffsetOfNode &Node = E->getComponent(I-1);
2472 switch (Node.getKind()) {
2473 case OffsetOfNode::Array:
2474 AddStmt(E->getIndexExpr(Node.getArrayExprIndex()));
2475 break;
2476 case OffsetOfNode::Field:
2477 AddMemberRef(Node.getField(), Node.getSourceRange().getEnd());
2478 break;
2479 case OffsetOfNode::Identifier:
2480 case OffsetOfNode::Base:
2481 continue;
2482 }
2483 }
2484 // Visit the type into which we're computing the offset.
2485 AddTypeLoc(E->getTypeSourceInfo());
2486}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002487void EnqueueVisitor::VisitOverloadExpr(const OverloadExpr *E) {
James Y Knight04ec5bf2015-12-24 02:59:37 +00002488 if (E->hasExplicitTemplateArgs())
2489 AddExplicitTemplateArgs(E->getTemplateArgs(), E->getNumTemplateArgs());
Guy Benyei11169dd2012-12-18 14:30:41 +00002490 WL.push_back(OverloadExprParts(E, Parent));
2491}
2492void EnqueueVisitor::VisitUnaryExprOrTypeTraitExpr(
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002493 const UnaryExprOrTypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002494 EnqueueChildren(E);
2495 if (E->isArgumentType())
2496 AddTypeLoc(E->getArgumentTypeInfo());
2497}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002498void EnqueueVisitor::VisitStmt(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002499 EnqueueChildren(S);
2500}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002501void EnqueueVisitor::VisitSwitchStmt(const SwitchStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002502 AddStmt(S->getBody());
2503 AddStmt(S->getCond());
2504 AddDecl(S->getConditionVariable());
2505}
2506
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002507void EnqueueVisitor::VisitWhileStmt(const WhileStmt *W) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002508 AddStmt(W->getBody());
2509 AddStmt(W->getCond());
2510 AddDecl(W->getConditionVariable());
2511}
2512
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002513void EnqueueVisitor::VisitTypeTraitExpr(const TypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002514 for (unsigned I = E->getNumArgs(); I > 0; --I)
2515 AddTypeLoc(E->getArg(I-1));
2516}
2517
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002518void EnqueueVisitor::VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002519 AddTypeLoc(E->getQueriedTypeSourceInfo());
2520}
2521
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002522void EnqueueVisitor::VisitExpressionTraitExpr(const ExpressionTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002523 EnqueueChildren(E);
2524}
2525
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002526void EnqueueVisitor::VisitUnresolvedMemberExpr(const UnresolvedMemberExpr *U) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002527 VisitOverloadExpr(U);
2528 if (!U->isImplicitAccess())
2529 AddStmt(U->getBase());
2530}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002531void EnqueueVisitor::VisitVAArgExpr(const VAArgExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002532 AddStmt(E->getSubExpr());
2533 AddTypeLoc(E->getWrittenTypeInfo());
2534}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002535void EnqueueVisitor::VisitSizeOfPackExpr(const SizeOfPackExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002536 WL.push_back(SizeOfPackExprParts(E, Parent));
2537}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002538void EnqueueVisitor::VisitOpaqueValueExpr(const OpaqueValueExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002539 // If the opaque value has a source expression, just transparently
2540 // visit that. This is useful for (e.g.) pseudo-object expressions.
2541 if (Expr *SourceExpr = E->getSourceExpr())
2542 return Visit(SourceExpr);
2543}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002544void EnqueueVisitor::VisitLambdaExpr(const LambdaExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002545 AddStmt(E->getBody());
2546 WL.push_back(LambdaExprParts(E, Parent));
2547}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002548void EnqueueVisitor::VisitPseudoObjectExpr(const PseudoObjectExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002549 // Treat the expression like its syntactic form.
2550 Visit(E->getSyntacticForm());
2551}
2552
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002553void EnqueueVisitor::VisitOMPExecutableDirective(
2554 const OMPExecutableDirective *D) {
2555 EnqueueChildren(D);
2556 for (ArrayRef<OMPClause *>::iterator I = D->clauses().begin(),
2557 E = D->clauses().end();
2558 I != E; ++I)
2559 EnqueueChildren(*I);
2560}
2561
Alexander Musman3aaab662014-08-19 11:27:13 +00002562void EnqueueVisitor::VisitOMPLoopDirective(const OMPLoopDirective *D) {
2563 VisitOMPExecutableDirective(D);
2564}
2565
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002566void EnqueueVisitor::VisitOMPParallelDirective(const OMPParallelDirective *D) {
2567 VisitOMPExecutableDirective(D);
2568}
2569
Alexey Bataev1b59ab52014-02-27 08:29:12 +00002570void EnqueueVisitor::VisitOMPSimdDirective(const OMPSimdDirective *D) {
Alexander Musman3aaab662014-08-19 11:27:13 +00002571 VisitOMPLoopDirective(D);
Alexey Bataev1b59ab52014-02-27 08:29:12 +00002572}
2573
Alexey Bataevf29276e2014-06-18 04:14:57 +00002574void EnqueueVisitor::VisitOMPForDirective(const OMPForDirective *D) {
Alexander Musman3aaab662014-08-19 11:27:13 +00002575 VisitOMPLoopDirective(D);
Alexey Bataevf29276e2014-06-18 04:14:57 +00002576}
2577
Alexander Musmanf82886e2014-09-18 05:12:34 +00002578void EnqueueVisitor::VisitOMPForSimdDirective(const OMPForSimdDirective *D) {
2579 VisitOMPLoopDirective(D);
2580}
2581
Alexey Bataevd3f8dd22014-06-25 11:44:49 +00002582void EnqueueVisitor::VisitOMPSectionsDirective(const OMPSectionsDirective *D) {
2583 VisitOMPExecutableDirective(D);
2584}
2585
Alexey Bataev1e0498a2014-06-26 08:21:58 +00002586void EnqueueVisitor::VisitOMPSectionDirective(const OMPSectionDirective *D) {
2587 VisitOMPExecutableDirective(D);
2588}
2589
Alexey Bataevd1e40fb2014-06-26 12:05:45 +00002590void EnqueueVisitor::VisitOMPSingleDirective(const OMPSingleDirective *D) {
2591 VisitOMPExecutableDirective(D);
2592}
2593
Alexander Musman80c22892014-07-17 08:54:58 +00002594void EnqueueVisitor::VisitOMPMasterDirective(const OMPMasterDirective *D) {
2595 VisitOMPExecutableDirective(D);
2596}
2597
Alexander Musmand9ed09f2014-07-21 09:42:05 +00002598void EnqueueVisitor::VisitOMPCriticalDirective(const OMPCriticalDirective *D) {
2599 VisitOMPExecutableDirective(D);
2600 AddDeclarationNameInfo(D);
2601}
2602
Alexey Bataev4acb8592014-07-07 13:01:15 +00002603void
2604EnqueueVisitor::VisitOMPParallelForDirective(const OMPParallelForDirective *D) {
Alexander Musman3aaab662014-08-19 11:27:13 +00002605 VisitOMPLoopDirective(D);
Alexey Bataev4acb8592014-07-07 13:01:15 +00002606}
2607
Alexander Musmane4e893b2014-09-23 09:33:00 +00002608void EnqueueVisitor::VisitOMPParallelForSimdDirective(
2609 const OMPParallelForSimdDirective *D) {
2610 VisitOMPLoopDirective(D);
2611}
2612
Alexey Bataev84d0b3e2014-07-08 08:12:03 +00002613void EnqueueVisitor::VisitOMPParallelSectionsDirective(
2614 const OMPParallelSectionsDirective *D) {
2615 VisitOMPExecutableDirective(D);
2616}
2617
Alexey Bataev9c2e8ee2014-07-11 11:25:16 +00002618void EnqueueVisitor::VisitOMPTaskDirective(const OMPTaskDirective *D) {
2619 VisitOMPExecutableDirective(D);
2620}
2621
Alexey Bataev68446b72014-07-18 07:47:19 +00002622void
2623EnqueueVisitor::VisitOMPTaskyieldDirective(const OMPTaskyieldDirective *D) {
2624 VisitOMPExecutableDirective(D);
2625}
2626
Alexey Bataev4d1dfea2014-07-18 09:11:51 +00002627void EnqueueVisitor::VisitOMPBarrierDirective(const OMPBarrierDirective *D) {
2628 VisitOMPExecutableDirective(D);
2629}
2630
Alexey Bataev2df347a2014-07-18 10:17:07 +00002631void EnqueueVisitor::VisitOMPTaskwaitDirective(const OMPTaskwaitDirective *D) {
2632 VisitOMPExecutableDirective(D);
2633}
2634
Alexey Bataevc30dd2d2015-06-18 12:14:09 +00002635void EnqueueVisitor::VisitOMPTaskgroupDirective(
2636 const OMPTaskgroupDirective *D) {
2637 VisitOMPExecutableDirective(D);
2638}
2639
Alexey Bataev6125da92014-07-21 11:26:11 +00002640void EnqueueVisitor::VisitOMPFlushDirective(const OMPFlushDirective *D) {
2641 VisitOMPExecutableDirective(D);
2642}
2643
Alexey Bataev9fb6e642014-07-22 06:45:04 +00002644void EnqueueVisitor::VisitOMPOrderedDirective(const OMPOrderedDirective *D) {
2645 VisitOMPExecutableDirective(D);
2646}
2647
Alexey Bataev0162e452014-07-22 10:10:35 +00002648void EnqueueVisitor::VisitOMPAtomicDirective(const OMPAtomicDirective *D) {
2649 VisitOMPExecutableDirective(D);
2650}
2651
Alexey Bataev0bd520b2014-09-19 08:19:49 +00002652void EnqueueVisitor::VisitOMPTargetDirective(const OMPTargetDirective *D) {
2653 VisitOMPExecutableDirective(D);
2654}
2655
Michael Wong65f367f2015-07-21 13:44:28 +00002656void EnqueueVisitor::VisitOMPTargetDataDirective(const
2657 OMPTargetDataDirective *D) {
2658 VisitOMPExecutableDirective(D);
2659}
2660
Samuel Antaodf67fc42016-01-19 19:15:56 +00002661void EnqueueVisitor::VisitOMPTargetEnterDataDirective(
2662 const OMPTargetEnterDataDirective *D) {
2663 VisitOMPExecutableDirective(D);
2664}
2665
Samuel Antao72590762016-01-19 20:04:50 +00002666void EnqueueVisitor::VisitOMPTargetExitDataDirective(
2667 const OMPTargetExitDataDirective *D) {
2668 VisitOMPExecutableDirective(D);
2669}
2670
Arpith Chacko Jacobe955b3d2016-01-26 18:48:41 +00002671void EnqueueVisitor::VisitOMPTargetParallelDirective(
2672 const OMPTargetParallelDirective *D) {
2673 VisitOMPExecutableDirective(D);
2674}
2675
Arpith Chacko Jacob05bebb52016-02-03 15:46:42 +00002676void EnqueueVisitor::VisitOMPTargetParallelForDirective(
2677 const OMPTargetParallelForDirective *D) {
2678 VisitOMPLoopDirective(D);
2679}
2680
Alexey Bataev13314bf2014-10-09 04:18:56 +00002681void EnqueueVisitor::VisitOMPTeamsDirective(const OMPTeamsDirective *D) {
2682 VisitOMPExecutableDirective(D);
2683}
2684
Alexey Bataev6d4ed052015-07-01 06:57:41 +00002685void EnqueueVisitor::VisitOMPCancellationPointDirective(
2686 const OMPCancellationPointDirective *D) {
2687 VisitOMPExecutableDirective(D);
2688}
2689
Alexey Bataev80909872015-07-02 11:25:17 +00002690void EnqueueVisitor::VisitOMPCancelDirective(const OMPCancelDirective *D) {
2691 VisitOMPExecutableDirective(D);
2692}
2693
Alexey Bataev49f6e782015-12-01 04:18:41 +00002694void EnqueueVisitor::VisitOMPTaskLoopDirective(const OMPTaskLoopDirective *D) {
2695 VisitOMPLoopDirective(D);
2696}
2697
Alexey Bataev0a6ed842015-12-03 09:40:15 +00002698void EnqueueVisitor::VisitOMPTaskLoopSimdDirective(
2699 const OMPTaskLoopSimdDirective *D) {
2700 VisitOMPLoopDirective(D);
2701}
2702
Carlo Bertolli6200a3d2015-12-14 14:51:25 +00002703void EnqueueVisitor::VisitOMPDistributeDirective(
2704 const OMPDistributeDirective *D) {
2705 VisitOMPLoopDirective(D);
2706}
2707
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002708void CursorVisitor::EnqueueWorkList(VisitorWorkList &WL, const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002709 EnqueueVisitor(WL, MakeCXCursor(S, StmtParent, TU,RegionOfInterest)).Visit(S);
2710}
2711
2712bool CursorVisitor::IsInRegionOfInterest(CXCursor C) {
2713 if (RegionOfInterest.isValid()) {
2714 SourceRange Range = getRawCursorExtent(C);
2715 if (Range.isInvalid() || CompareRegionOfInterest(Range))
2716 return false;
2717 }
2718 return true;
2719}
2720
2721bool CursorVisitor::RunVisitorWorkList(VisitorWorkList &WL) {
2722 while (!WL.empty()) {
2723 // Dequeue the worklist item.
Robert Wilhelm25284cc2013-08-23 16:11:15 +00002724 VisitorJob LI = WL.pop_back_val();
Guy Benyei11169dd2012-12-18 14:30:41 +00002725
2726 // Set the Parent field, then back to its old value once we're done.
2727 SetParentRAII SetParent(Parent, StmtParent, LI.getParent());
2728
2729 switch (LI.getKind()) {
2730 case VisitorJob::DeclVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002731 const Decl *D = cast<DeclVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002732 if (!D)
2733 continue;
2734
2735 // For now, perform default visitation for Decls.
2736 if (Visit(MakeCXCursor(D, TU, RegionOfInterest,
2737 cast<DeclVisit>(&LI)->isFirst())))
2738 return true;
2739
2740 continue;
2741 }
2742 case VisitorJob::ExplicitTemplateArgsVisitKind: {
James Y Knight04ec5bf2015-12-24 02:59:37 +00002743 for (const TemplateArgumentLoc &Arg :
2744 *cast<ExplicitTemplateArgsVisit>(&LI)) {
2745 if (VisitTemplateArgumentLoc(Arg))
Guy Benyei11169dd2012-12-18 14:30:41 +00002746 return true;
2747 }
2748 continue;
2749 }
2750 case VisitorJob::TypeLocVisitKind: {
2751 // Perform default visitation for TypeLocs.
2752 if (Visit(cast<TypeLocVisit>(&LI)->get()))
2753 return true;
2754 continue;
2755 }
2756 case VisitorJob::LabelRefVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002757 const LabelDecl *LS = cast<LabelRefVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002758 if (LabelStmt *stmt = LS->getStmt()) {
2759 if (Visit(MakeCursorLabelRef(stmt, cast<LabelRefVisit>(&LI)->getLoc(),
2760 TU))) {
2761 return true;
2762 }
2763 }
2764 continue;
2765 }
2766
2767 case VisitorJob::NestedNameSpecifierLocVisitKind: {
2768 NestedNameSpecifierLocVisit *V = cast<NestedNameSpecifierLocVisit>(&LI);
2769 if (VisitNestedNameSpecifierLoc(V->get()))
2770 return true;
2771 continue;
2772 }
2773
2774 case VisitorJob::DeclarationNameInfoVisitKind: {
2775 if (VisitDeclarationNameInfo(cast<DeclarationNameInfoVisit>(&LI)
2776 ->get()))
2777 return true;
2778 continue;
2779 }
2780 case VisitorJob::MemberRefVisitKind: {
2781 MemberRefVisit *V = cast<MemberRefVisit>(&LI);
2782 if (Visit(MakeCursorMemberRef(V->get(), V->getLoc(), TU)))
2783 return true;
2784 continue;
2785 }
2786 case VisitorJob::StmtVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002787 const Stmt *S = cast<StmtVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002788 if (!S)
2789 continue;
2790
2791 // Update the current cursor.
2792 CXCursor Cursor = MakeCXCursor(S, StmtParent, TU, RegionOfInterest);
2793 if (!IsInRegionOfInterest(Cursor))
2794 continue;
2795 switch (Visitor(Cursor, Parent, ClientData)) {
2796 case CXChildVisit_Break: return true;
2797 case CXChildVisit_Continue: break;
2798 case CXChildVisit_Recurse:
2799 if (PostChildrenVisitor)
Craig Topper69186e72014-06-08 08:38:04 +00002800 WL.push_back(PostChildrenVisit(nullptr, Cursor));
Guy Benyei11169dd2012-12-18 14:30:41 +00002801 EnqueueWorkList(WL, S);
2802 break;
2803 }
2804 continue;
2805 }
2806 case VisitorJob::MemberExprPartsKind: {
2807 // Handle the other pieces in the MemberExpr besides the base.
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002808 const MemberExpr *M = cast<MemberExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002809
2810 // Visit the nested-name-specifier
2811 if (NestedNameSpecifierLoc QualifierLoc = M->getQualifierLoc())
2812 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2813 return true;
2814
2815 // Visit the declaration name.
2816 if (VisitDeclarationNameInfo(M->getMemberNameInfo()))
2817 return true;
2818
2819 // Visit the explicitly-specified template arguments, if any.
2820 if (M->hasExplicitTemplateArgs()) {
2821 for (const TemplateArgumentLoc *Arg = M->getTemplateArgs(),
2822 *ArgEnd = Arg + M->getNumTemplateArgs();
2823 Arg != ArgEnd; ++Arg) {
2824 if (VisitTemplateArgumentLoc(*Arg))
2825 return true;
2826 }
2827 }
2828 continue;
2829 }
2830 case VisitorJob::DeclRefExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002831 const DeclRefExpr *DR = cast<DeclRefExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002832 // Visit nested-name-specifier, if present.
2833 if (NestedNameSpecifierLoc QualifierLoc = DR->getQualifierLoc())
2834 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2835 return true;
2836 // Visit declaration name.
2837 if (VisitDeclarationNameInfo(DR->getNameInfo()))
2838 return true;
2839 continue;
2840 }
2841 case VisitorJob::OverloadExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002842 const OverloadExpr *O = cast<OverloadExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002843 // Visit the nested-name-specifier.
2844 if (NestedNameSpecifierLoc QualifierLoc = O->getQualifierLoc())
2845 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2846 return true;
2847 // Visit the declaration name.
2848 if (VisitDeclarationNameInfo(O->getNameInfo()))
2849 return true;
2850 // Visit the overloaded declaration reference.
2851 if (Visit(MakeCursorOverloadedDeclRef(O, TU)))
2852 return true;
2853 continue;
2854 }
2855 case VisitorJob::SizeOfPackExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002856 const SizeOfPackExpr *E = cast<SizeOfPackExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002857 NamedDecl *Pack = E->getPack();
2858 if (isa<TemplateTypeParmDecl>(Pack)) {
2859 if (Visit(MakeCursorTypeRef(cast<TemplateTypeParmDecl>(Pack),
2860 E->getPackLoc(), TU)))
2861 return true;
2862
2863 continue;
2864 }
2865
2866 if (isa<TemplateTemplateParmDecl>(Pack)) {
2867 if (Visit(MakeCursorTemplateRef(cast<TemplateTemplateParmDecl>(Pack),
2868 E->getPackLoc(), TU)))
2869 return true;
2870
2871 continue;
2872 }
2873
2874 // Non-type template parameter packs and function parameter packs are
2875 // treated like DeclRefExpr cursors.
2876 continue;
2877 }
2878
2879 case VisitorJob::LambdaExprPartsKind: {
2880 // Visit captures.
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002881 const LambdaExpr *E = cast<LambdaExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002882 for (LambdaExpr::capture_iterator C = E->explicit_capture_begin(),
2883 CEnd = E->explicit_capture_end();
2884 C != CEnd; ++C) {
Richard Smithba71c082013-05-16 06:20:58 +00002885 // FIXME: Lambda init-captures.
2886 if (!C->capturesVariable())
Guy Benyei11169dd2012-12-18 14:30:41 +00002887 continue;
Richard Smithba71c082013-05-16 06:20:58 +00002888
Guy Benyei11169dd2012-12-18 14:30:41 +00002889 if (Visit(MakeCursorVariableRef(C->getCapturedVar(),
2890 C->getLocation(),
2891 TU)))
2892 return true;
2893 }
2894
2895 // Visit parameters and return type, if present.
2896 if (E->hasExplicitParameters() || E->hasExplicitResultType()) {
2897 TypeLoc TL = E->getCallOperator()->getTypeSourceInfo()->getTypeLoc();
2898 if (E->hasExplicitParameters() && E->hasExplicitResultType()) {
2899 // Visit the whole type.
2900 if (Visit(TL))
2901 return true;
David Blaikie6adc78e2013-02-18 22:06:02 +00002902 } else if (FunctionProtoTypeLoc Proto =
2903 TL.getAs<FunctionProtoTypeLoc>()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002904 if (E->hasExplicitParameters()) {
2905 // Visit parameters.
Alp Tokerb3fd5cf2014-01-21 00:32:38 +00002906 for (unsigned I = 0, N = Proto.getNumParams(); I != N; ++I)
2907 if (Visit(MakeCXCursor(Proto.getParam(I), TU)))
Guy Benyei11169dd2012-12-18 14:30:41 +00002908 return true;
2909 } else {
2910 // Visit result type.
Alp Toker42a16a62014-01-25 23:51:36 +00002911 if (Visit(Proto.getReturnLoc()))
Guy Benyei11169dd2012-12-18 14:30:41 +00002912 return true;
2913 }
2914 }
2915 }
2916 break;
2917 }
2918
2919 case VisitorJob::PostChildrenVisitKind:
2920 if (PostChildrenVisitor(Parent, ClientData))
2921 return true;
2922 break;
2923 }
2924 }
2925 return false;
2926}
2927
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002928bool CursorVisitor::Visit(const Stmt *S) {
Craig Topper69186e72014-06-08 08:38:04 +00002929 VisitorWorkList *WL = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00002930 if (!WorkListFreeList.empty()) {
2931 WL = WorkListFreeList.back();
2932 WL->clear();
2933 WorkListFreeList.pop_back();
2934 }
2935 else {
2936 WL = new VisitorWorkList();
2937 WorkListCache.push_back(WL);
2938 }
2939 EnqueueWorkList(*WL, S);
2940 bool result = RunVisitorWorkList(*WL);
2941 WorkListFreeList.push_back(WL);
2942 return result;
2943}
2944
2945namespace {
Dmitri Gribenkof8579502013-01-12 19:30:44 +00002946typedef SmallVector<SourceRange, 4> RefNamePieces;
James Y Knight04ec5bf2015-12-24 02:59:37 +00002947RefNamePieces buildPieces(unsigned NameFlags, bool IsMemberRefExpr,
2948 const DeclarationNameInfo &NI, SourceRange QLoc,
2949 const SourceRange *TemplateArgsLoc = nullptr) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002950 const bool WantQualifier = NameFlags & CXNameRange_WantQualifier;
2951 const bool WantTemplateArgs = NameFlags & CXNameRange_WantTemplateArgs;
2952 const bool WantSinglePiece = NameFlags & CXNameRange_WantSinglePiece;
2953
2954 const DeclarationName::NameKind Kind = NI.getName().getNameKind();
2955
2956 RefNamePieces Pieces;
2957
2958 if (WantQualifier && QLoc.isValid())
2959 Pieces.push_back(QLoc);
2960
2961 if (Kind != DeclarationName::CXXOperatorName || IsMemberRefExpr)
2962 Pieces.push_back(NI.getLoc());
James Y Knight04ec5bf2015-12-24 02:59:37 +00002963
2964 if (WantTemplateArgs && TemplateArgsLoc && TemplateArgsLoc->isValid())
2965 Pieces.push_back(*TemplateArgsLoc);
2966
Guy Benyei11169dd2012-12-18 14:30:41 +00002967 if (Kind == DeclarationName::CXXOperatorName) {
2968 Pieces.push_back(SourceLocation::getFromRawEncoding(
2969 NI.getInfo().CXXOperatorName.BeginOpNameLoc));
2970 Pieces.push_back(SourceLocation::getFromRawEncoding(
2971 NI.getInfo().CXXOperatorName.EndOpNameLoc));
2972 }
2973
2974 if (WantSinglePiece) {
2975 SourceRange R(Pieces.front().getBegin(), Pieces.back().getEnd());
2976 Pieces.clear();
2977 Pieces.push_back(R);
2978 }
2979
2980 return Pieces;
2981}
Alexander Kornienkoab9db512015-06-22 23:07:51 +00002982}
Guy Benyei11169dd2012-12-18 14:30:41 +00002983
2984//===----------------------------------------------------------------------===//
2985// Misc. API hooks.
2986//===----------------------------------------------------------------------===//
2987
Chad Rosier05c71aa2013-03-27 18:28:23 +00002988static void fatal_error_handler(void *user_data, const std::string& reason,
2989 bool gen_crash_diag) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002990 // Write the result out to stderr avoiding errs() because raw_ostreams can
2991 // call report_fatal_error.
2992 fprintf(stderr, "LIBCLANG FATAL ERROR: %s\n", reason.c_str());
2993 ::abort();
2994}
2995
Chandler Carruth66660742014-06-27 16:37:27 +00002996namespace {
2997struct RegisterFatalErrorHandler {
2998 RegisterFatalErrorHandler() {
2999 llvm::install_fatal_error_handler(fatal_error_handler, nullptr);
3000 }
3001};
3002}
3003
3004static llvm::ManagedStatic<RegisterFatalErrorHandler> RegisterFatalErrorHandlerOnce;
3005
Guy Benyei11169dd2012-12-18 14:30:41 +00003006extern "C" {
3007CXIndex clang_createIndex(int excludeDeclarationsFromPCH,
3008 int displayDiagnostics) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003009 // We use crash recovery to make some of our APIs more reliable, implicitly
3010 // enable it.
Argyrios Kyrtzidis3701f542013-11-27 08:58:09 +00003011 if (!getenv("LIBCLANG_DISABLE_CRASH_RECOVERY"))
3012 llvm::CrashRecoveryContext::Enable();
Guy Benyei11169dd2012-12-18 14:30:41 +00003013
Chandler Carruth66660742014-06-27 16:37:27 +00003014 // Look through the managed static to trigger construction of the managed
3015 // static which registers our fatal error handler. This ensures it is only
3016 // registered once.
3017 (void)*RegisterFatalErrorHandlerOnce;
Guy Benyei11169dd2012-12-18 14:30:41 +00003018
Adrian Prantlbc068582015-07-08 01:00:30 +00003019 // Initialize targets for clang module support.
3020 llvm::InitializeAllTargets();
3021 llvm::InitializeAllTargetMCs();
3022 llvm::InitializeAllAsmPrinters();
3023 llvm::InitializeAllAsmParsers();
3024
Adrian Prantlfb2398d2015-07-17 01:19:54 +00003025 CIndexer *CIdxr = new CIndexer();
3026
Guy Benyei11169dd2012-12-18 14:30:41 +00003027 if (excludeDeclarationsFromPCH)
3028 CIdxr->setOnlyLocalDecls();
3029 if (displayDiagnostics)
3030 CIdxr->setDisplayDiagnostics();
3031
3032 if (getenv("LIBCLANG_BGPRIO_INDEX"))
3033 CIdxr->setCXGlobalOptFlags(CIdxr->getCXGlobalOptFlags() |
3034 CXGlobalOpt_ThreadBackgroundPriorityForIndexing);
3035 if (getenv("LIBCLANG_BGPRIO_EDIT"))
3036 CIdxr->setCXGlobalOptFlags(CIdxr->getCXGlobalOptFlags() |
3037 CXGlobalOpt_ThreadBackgroundPriorityForEditing);
3038
3039 return CIdxr;
3040}
3041
3042void clang_disposeIndex(CXIndex CIdx) {
3043 if (CIdx)
3044 delete static_cast<CIndexer *>(CIdx);
3045}
3046
3047void clang_CXIndex_setGlobalOptions(CXIndex CIdx, unsigned options) {
3048 if (CIdx)
3049 static_cast<CIndexer *>(CIdx)->setCXGlobalOptFlags(options);
3050}
3051
3052unsigned clang_CXIndex_getGlobalOptions(CXIndex CIdx) {
3053 if (CIdx)
3054 return static_cast<CIndexer *>(CIdx)->getCXGlobalOptFlags();
3055 return 0;
3056}
3057
3058void clang_toggleCrashRecovery(unsigned isEnabled) {
3059 if (isEnabled)
3060 llvm::CrashRecoveryContext::Enable();
3061 else
3062 llvm::CrashRecoveryContext::Disable();
3063}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003064
Guy Benyei11169dd2012-12-18 14:30:41 +00003065CXTranslationUnit clang_createTranslationUnit(CXIndex CIdx,
3066 const char *ast_filename) {
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00003067 CXTranslationUnit TU;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003068 enum CXErrorCode Result =
3069 clang_createTranslationUnit2(CIdx, ast_filename, &TU);
Reid Klecknerfd48fc62014-02-12 23:56:20 +00003070 (void)Result;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003071 assert((TU && Result == CXError_Success) ||
3072 (!TU && Result != CXError_Success));
3073 return TU;
3074}
3075
3076enum CXErrorCode clang_createTranslationUnit2(CXIndex CIdx,
3077 const char *ast_filename,
3078 CXTranslationUnit *out_TU) {
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00003079 if (out_TU)
Craig Topper69186e72014-06-08 08:38:04 +00003080 *out_TU = nullptr;
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00003081
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003082 if (!CIdx || !ast_filename || !out_TU)
3083 return CXError_InvalidArguments;
Guy Benyei11169dd2012-12-18 14:30:41 +00003084
Argyrios Kyrtzidis27021012013-05-24 22:24:07 +00003085 LOG_FUNC_SECTION {
3086 *Log << ast_filename;
3087 }
3088
Guy Benyei11169dd2012-12-18 14:30:41 +00003089 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
3090 FileSystemOptions FileSystemOpts;
3091
Justin Bognerd512c1e2014-10-15 00:33:06 +00003092 IntrusiveRefCntPtr<DiagnosticsEngine> Diags =
3093 CompilerInstance::createDiagnostics(new DiagnosticOptions());
David Blaikie6f7382d2014-08-10 19:08:04 +00003094 std::unique_ptr<ASTUnit> AU = ASTUnit::LoadFromASTFile(
Adrian Prantlfb2398d2015-07-17 01:19:54 +00003095 ast_filename, CXXIdx->getPCHContainerOperations()->getRawReader(), Diags,
Adrian Prantl6b21ab22015-08-27 19:46:20 +00003096 FileSystemOpts, /*UseDebugInfo=*/false,
3097 CXXIdx->getOnlyLocalDecls(), None,
David Blaikie6f7382d2014-08-10 19:08:04 +00003098 /*CaptureDiagnostics=*/true,
3099 /*AllowPCHWithCompilerErrors=*/true,
3100 /*UserFilesAreVolatile=*/true);
3101 *out_TU = MakeCXTranslationUnit(CXXIdx, AU.release());
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003102 return *out_TU ? CXError_Success : CXError_Failure;
Guy Benyei11169dd2012-12-18 14:30:41 +00003103}
3104
3105unsigned clang_defaultEditingTranslationUnitOptions() {
3106 return CXTranslationUnit_PrecompiledPreamble |
3107 CXTranslationUnit_CacheCompletionResults;
3108}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003109
Guy Benyei11169dd2012-12-18 14:30:41 +00003110CXTranslationUnit
3111clang_createTranslationUnitFromSourceFile(CXIndex CIdx,
3112 const char *source_filename,
3113 int num_command_line_args,
3114 const char * const *command_line_args,
3115 unsigned num_unsaved_files,
3116 struct CXUnsavedFile *unsaved_files) {
3117 unsigned Options = CXTranslationUnit_DetailedPreprocessingRecord;
3118 return clang_parseTranslationUnit(CIdx, source_filename,
3119 command_line_args, num_command_line_args,
3120 unsaved_files, num_unsaved_files,
3121 Options);
3122}
3123
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003124static CXErrorCode
3125clang_parseTranslationUnit_Impl(CXIndex CIdx, const char *source_filename,
3126 const char *const *command_line_args,
3127 int num_command_line_args,
3128 ArrayRef<CXUnsavedFile> unsaved_files,
3129 unsigned options, CXTranslationUnit *out_TU) {
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00003130 // Set up the initial return values.
3131 if (out_TU)
Craig Topper69186e72014-06-08 08:38:04 +00003132 *out_TU = nullptr;
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00003133
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003134 // Check arguments.
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003135 if (!CIdx || !out_TU)
3136 return CXError_InvalidArguments;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003137
Guy Benyei11169dd2012-12-18 14:30:41 +00003138 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
3139
3140 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
3141 setThreadBackgroundPriority();
3142
3143 bool PrecompilePreamble = options & CXTranslationUnit_PrecompiledPreamble;
Benjamin Kramer5c248d82015-12-15 09:30:31 +00003144 bool CreatePreambleOnFirstParse =
3145 options & CXTranslationUnit_CreatePreambleOnFirstParse;
Guy Benyei11169dd2012-12-18 14:30:41 +00003146 // FIXME: Add a flag for modules.
3147 TranslationUnitKind TUKind
3148 = (options & CXTranslationUnit_Incomplete)? TU_Prefix : TU_Complete;
Alp Toker8c8a8752013-12-03 06:53:35 +00003149 bool CacheCodeCompletionResults
Guy Benyei11169dd2012-12-18 14:30:41 +00003150 = options & CXTranslationUnit_CacheCompletionResults;
3151 bool IncludeBriefCommentsInCodeCompletion
3152 = options & CXTranslationUnit_IncludeBriefCommentsInCodeCompletion;
3153 bool SkipFunctionBodies = options & CXTranslationUnit_SkipFunctionBodies;
3154 bool ForSerialization = options & CXTranslationUnit_ForSerialization;
3155
3156 // Configure the diagnostics.
3157 IntrusiveRefCntPtr<DiagnosticsEngine>
Sean Silvaf1b49e22013-01-20 01:58:28 +00003158 Diags(CompilerInstance::createDiagnostics(new DiagnosticOptions));
Guy Benyei11169dd2012-12-18 14:30:41 +00003159
Manuel Klimek016c0242016-03-01 10:56:19 +00003160 if (options & CXTranslationUnit_KeepGoing)
3161 Diags->setFatalsAsError(true);
3162
Guy Benyei11169dd2012-12-18 14:30:41 +00003163 // Recover resources if we crash before exiting this function.
3164 llvm::CrashRecoveryContextCleanupRegistrar<DiagnosticsEngine,
3165 llvm::CrashRecoveryContextReleaseRefCleanup<DiagnosticsEngine> >
Alp Tokerf994cef2014-07-05 03:08:06 +00003166 DiagCleanup(Diags.get());
Guy Benyei11169dd2012-12-18 14:30:41 +00003167
Ahmed Charlesb8984322014-03-07 20:03:18 +00003168 std::unique_ptr<std::vector<ASTUnit::RemappedFile>> RemappedFiles(
3169 new std::vector<ASTUnit::RemappedFile>());
Guy Benyei11169dd2012-12-18 14:30:41 +00003170
3171 // Recover resources if we crash before exiting this function.
3172 llvm::CrashRecoveryContextCleanupRegistrar<
3173 std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
3174
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003175 for (auto &UF : unsaved_files) {
Rafael Espindolad87f8d72014-08-27 20:03:29 +00003176 std::unique_ptr<llvm::MemoryBuffer> MB =
Alp Toker9d85b182014-07-07 01:23:14 +00003177 llvm::MemoryBuffer::getMemBufferCopy(getContents(UF), UF.Filename);
Rafael Espindolad87f8d72014-08-27 20:03:29 +00003178 RemappedFiles->push_back(std::make_pair(UF.Filename, MB.release()));
Guy Benyei11169dd2012-12-18 14:30:41 +00003179 }
3180
Ahmed Charlesb8984322014-03-07 20:03:18 +00003181 std::unique_ptr<std::vector<const char *>> Args(
3182 new std::vector<const char *>());
Guy Benyei11169dd2012-12-18 14:30:41 +00003183
3184 // Recover resources if we crash before exiting this method.
3185 llvm::CrashRecoveryContextCleanupRegistrar<std::vector<const char*> >
3186 ArgsCleanup(Args.get());
3187
3188 // Since the Clang C library is primarily used by batch tools dealing with
3189 // (often very broken) source code, where spell-checking can have a
3190 // significant negative impact on performance (particularly when
3191 // precompiled headers are involved), we disable it by default.
3192 // Only do this if we haven't found a spell-checking-related argument.
3193 bool FoundSpellCheckingArgument = false;
3194 for (int I = 0; I != num_command_line_args; ++I) {
3195 if (strcmp(command_line_args[I], "-fno-spell-checking") == 0 ||
3196 strcmp(command_line_args[I], "-fspell-checking") == 0) {
3197 FoundSpellCheckingArgument = true;
3198 break;
3199 }
3200 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003201 Args->insert(Args->end(), command_line_args,
3202 command_line_args + num_command_line_args);
3203
Benjamin Kramerc02670e2015-11-18 16:14:27 +00003204 if (!FoundSpellCheckingArgument)
3205 Args->insert(Args->begin() + 1, "-fno-spell-checking");
3206
Guy Benyei11169dd2012-12-18 14:30:41 +00003207 // The 'source_filename' argument is optional. If the caller does not
3208 // specify it then it is assumed that the source file is specified
3209 // in the actual argument list.
3210 // Put the source file after command_line_args otherwise if '-x' flag is
3211 // present it will be unused.
3212 if (source_filename)
3213 Args->push_back(source_filename);
3214
3215 // Do we need the detailed preprocessing record?
3216 if (options & CXTranslationUnit_DetailedPreprocessingRecord) {
3217 Args->push_back("-Xclang");
3218 Args->push_back("-detailed-preprocessing-record");
3219 }
3220
3221 unsigned NumErrors = Diags->getClient()->getNumErrors();
Ahmed Charlesb8984322014-03-07 20:03:18 +00003222 std::unique_ptr<ASTUnit> ErrUnit;
Benjamin Kramer5c248d82015-12-15 09:30:31 +00003223 // Unless the user specified that they want the preamble on the first parse
3224 // set it up to be created on the first reparse. This makes the first parse
3225 // faster, trading for a slower (first) reparse.
3226 unsigned PrecompilePreambleAfterNParses =
3227 !PrecompilePreamble ? 0 : 2 - CreatePreambleOnFirstParse;
Ahmed Charlesb8984322014-03-07 20:03:18 +00003228 std::unique_ptr<ASTUnit> Unit(ASTUnit::LoadFromCommandLine(
Adrian Prantlbb165fb2015-06-20 18:53:08 +00003229 Args->data(), Args->data() + Args->size(),
3230 CXXIdx->getPCHContainerOperations(), Diags,
Ahmed Charlesb8984322014-03-07 20:03:18 +00003231 CXXIdx->getClangResourcesPath(), CXXIdx->getOnlyLocalDecls(),
3232 /*CaptureDiagnostics=*/true, *RemappedFiles.get(),
Benjamin Kramer5c248d82015-12-15 09:30:31 +00003233 /*RemappedFilesKeepOriginalName=*/true, PrecompilePreambleAfterNParses,
3234 TUKind, CacheCodeCompletionResults, IncludeBriefCommentsInCodeCompletion,
Ahmed Charlesb8984322014-03-07 20:03:18 +00003235 /*AllowPCHWithCompilerErrors=*/true, SkipFunctionBodies,
Argyrios Kyrtzidisa3e2ff12015-11-20 03:36:21 +00003236 /*UserFilesAreVolatile=*/true, ForSerialization,
3237 CXXIdx->getPCHContainerOperations()->getRawReader().getFormat(),
3238 &ErrUnit));
Guy Benyei11169dd2012-12-18 14:30:41 +00003239
Artem Belevich0ff05cd2015-07-13 23:27:56 +00003240 // Early failures in LoadFromCommandLine may return with ErrUnit unset.
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003241 if (!Unit && !ErrUnit)
3242 return CXError_ASTReadError;
Artem Belevich0ff05cd2015-07-13 23:27:56 +00003243
Guy Benyei11169dd2012-12-18 14:30:41 +00003244 if (NumErrors != Diags->getClient()->getNumErrors()) {
3245 // Make sure to check that 'Unit' is non-NULL.
3246 if (CXXIdx->getDisplayDiagnostics())
3247 printDiagsToStderr(Unit ? Unit.get() : ErrUnit.get());
3248 }
3249
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003250 if (isASTReadError(Unit ? Unit.get() : ErrUnit.get()))
3251 return CXError_ASTReadError;
3252
3253 *out_TU = MakeCXTranslationUnit(CXXIdx, Unit.release());
3254 return *out_TU ? CXError_Success : CXError_Failure;
Guy Benyei11169dd2012-12-18 14:30:41 +00003255}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003256
3257CXTranslationUnit
3258clang_parseTranslationUnit(CXIndex CIdx,
3259 const char *source_filename,
3260 const char *const *command_line_args,
3261 int num_command_line_args,
3262 struct CXUnsavedFile *unsaved_files,
3263 unsigned num_unsaved_files,
3264 unsigned options) {
3265 CXTranslationUnit TU;
3266 enum CXErrorCode Result = clang_parseTranslationUnit2(
3267 CIdx, source_filename, command_line_args, num_command_line_args,
3268 unsaved_files, num_unsaved_files, options, &TU);
Reid Kleckner6eaf05a2014-02-13 01:19:59 +00003269 (void)Result;
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00003270 assert((TU && Result == CXError_Success) ||
3271 (!TU && Result != CXError_Success));
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003272 return TU;
3273}
3274
3275enum CXErrorCode clang_parseTranslationUnit2(
Benjamin Kramerc02670e2015-11-18 16:14:27 +00003276 CXIndex CIdx, const char *source_filename,
3277 const char *const *command_line_args, int num_command_line_args,
3278 struct CXUnsavedFile *unsaved_files, unsigned num_unsaved_files,
3279 unsigned options, CXTranslationUnit *out_TU) {
3280 SmallVector<const char *, 4> Args;
3281 Args.push_back("clang");
3282 Args.append(command_line_args, command_line_args + num_command_line_args);
3283 return clang_parseTranslationUnit2FullArgv(
3284 CIdx, source_filename, Args.data(), Args.size(), unsaved_files,
3285 num_unsaved_files, options, out_TU);
3286}
3287
3288enum CXErrorCode clang_parseTranslationUnit2FullArgv(
3289 CXIndex CIdx, const char *source_filename,
3290 const char *const *command_line_args, int num_command_line_args,
3291 struct CXUnsavedFile *unsaved_files, unsigned num_unsaved_files,
3292 unsigned options, CXTranslationUnit *out_TU) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00003293 LOG_FUNC_SECTION {
3294 *Log << source_filename << ": ";
3295 for (int i = 0; i != num_command_line_args; ++i)
3296 *Log << command_line_args[i] << " ";
3297 }
3298
Alp Toker9d85b182014-07-07 01:23:14 +00003299 if (num_unsaved_files && !unsaved_files)
3300 return CXError_InvalidArguments;
3301
Alp Toker5c532982014-07-07 22:42:03 +00003302 CXErrorCode result = CXError_Failure;
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003303 auto ParseTranslationUnitImpl = [=, &result] {
3304 result = clang_parseTranslationUnit_Impl(
3305 CIdx, source_filename, command_line_args, num_command_line_args,
3306 llvm::makeArrayRef(unsaved_files, num_unsaved_files), options, out_TU);
3307 };
Guy Benyei11169dd2012-12-18 14:30:41 +00003308 llvm::CrashRecoveryContext CRC;
3309
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003310 if (!RunSafely(CRC, ParseTranslationUnitImpl)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003311 fprintf(stderr, "libclang: crash detected during parsing: {\n");
3312 fprintf(stderr, " 'source_filename' : '%s'\n", source_filename);
3313 fprintf(stderr, " 'command_line_args' : [");
3314 for (int i = 0; i != num_command_line_args; ++i) {
3315 if (i)
3316 fprintf(stderr, ", ");
3317 fprintf(stderr, "'%s'", command_line_args[i]);
3318 }
3319 fprintf(stderr, "],\n");
3320 fprintf(stderr, " 'unsaved_files' : [");
3321 for (unsigned i = 0; i != num_unsaved_files; ++i) {
3322 if (i)
3323 fprintf(stderr, ", ");
3324 fprintf(stderr, "('%s', '...', %ld)", unsaved_files[i].Filename,
3325 unsaved_files[i].Length);
3326 }
3327 fprintf(stderr, "],\n");
3328 fprintf(stderr, " 'options' : %d,\n", options);
3329 fprintf(stderr, "}\n");
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003330
3331 return CXError_Crashed;
Guy Benyei11169dd2012-12-18 14:30:41 +00003332 } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003333 if (CXTranslationUnit *TU = out_TU)
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003334 PrintLibclangResourceUsage(*TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003335 }
Alp Toker5c532982014-07-07 22:42:03 +00003336
3337 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003338}
3339
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003340CXString clang_Type_getObjCEncoding(CXType CT) {
3341 CXTranslationUnit tu = static_cast<CXTranslationUnit>(CT.data[1]);
3342 ASTContext &Ctx = getASTUnit(tu)->getASTContext();
3343 std::string encoding;
3344 Ctx.getObjCEncodingForType(QualType::getFromOpaquePtr(CT.data[0]),
3345 encoding);
3346
3347 return cxstring::createDup(encoding);
3348}
3349
3350static const IdentifierInfo *getMacroIdentifier(CXCursor C) {
3351 if (C.kind == CXCursor_MacroDefinition) {
3352 if (const MacroDefinitionRecord *MDR = getCursorMacroDefinition(C))
3353 return MDR->getName();
3354 } else if (C.kind == CXCursor_MacroExpansion) {
3355 MacroExpansionCursor ME = getCursorMacroExpansion(C);
3356 return ME.getName();
3357 }
3358 return nullptr;
3359}
3360
3361unsigned clang_Cursor_isMacroFunctionLike(CXCursor C) {
3362 const IdentifierInfo *II = getMacroIdentifier(C);
3363 if (!II) {
3364 return false;
3365 }
3366 ASTUnit *ASTU = getCursorASTUnit(C);
3367 Preprocessor &PP = ASTU->getPreprocessor();
3368 if (const MacroInfo *MI = PP.getMacroInfo(II))
3369 return MI->isFunctionLike();
3370 return false;
3371}
3372
3373unsigned clang_Cursor_isMacroBuiltin(CXCursor C) {
3374 const IdentifierInfo *II = getMacroIdentifier(C);
3375 if (!II) {
3376 return false;
3377 }
3378 ASTUnit *ASTU = getCursorASTUnit(C);
3379 Preprocessor &PP = ASTU->getPreprocessor();
3380 if (const MacroInfo *MI = PP.getMacroInfo(II))
3381 return MI->isBuiltinMacro();
3382 return false;
3383}
3384
3385unsigned clang_Cursor_isFunctionInlined(CXCursor C) {
3386 const Decl *D = getCursorDecl(C);
3387 const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(D);
3388 if (!FD) {
3389 return false;
3390 }
3391 return FD->isInlined();
3392}
3393
3394static StringLiteral* getCFSTR_value(CallExpr *callExpr) {
3395 if (callExpr->getNumArgs() != 1) {
3396 return nullptr;
3397 }
3398
3399 StringLiteral *S = nullptr;
3400 auto *arg = callExpr->getArg(0);
3401 if (arg->getStmtClass() == Stmt::ImplicitCastExprClass) {
3402 ImplicitCastExpr *I = static_cast<ImplicitCastExpr *>(arg);
3403 auto *subExpr = I->getSubExprAsWritten();
3404
3405 if(subExpr->getStmtClass() != Stmt::StringLiteralClass){
3406 return nullptr;
3407 }
3408
3409 S = static_cast<StringLiteral *>(I->getSubExprAsWritten());
3410 } else if (arg->getStmtClass() == Stmt::StringLiteralClass) {
3411 S = static_cast<StringLiteral *>(callExpr->getArg(0));
3412 } else {
3413 return nullptr;
3414 }
3415 return S;
3416}
3417
David Blaikie59272572016-04-13 18:23:33 +00003418struct ExprEvalResult {
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003419 CXEvalResultKind EvalType;
3420 union {
3421 int intVal;
3422 double floatVal;
3423 char *stringVal;
3424 } EvalData;
David Blaikie59272572016-04-13 18:23:33 +00003425 ~ExprEvalResult() {
3426 if (EvalType != CXEval_UnExposed && EvalType != CXEval_Float &&
3427 EvalType != CXEval_Int) {
3428 delete EvalData.stringVal;
3429 }
3430 }
3431};
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003432
3433void clang_EvalResult_dispose(CXEvalResult E) {
David Blaikie59272572016-04-13 18:23:33 +00003434 delete static_cast<ExprEvalResult *>(E);
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003435}
3436
3437CXEvalResultKind clang_EvalResult_getKind(CXEvalResult E) {
3438 if (!E) {
3439 return CXEval_UnExposed;
3440 }
3441 return ((ExprEvalResult *)E)->EvalType;
3442}
3443
3444int clang_EvalResult_getAsInt(CXEvalResult E) {
3445 if (!E) {
3446 return 0;
3447 }
3448 return ((ExprEvalResult *)E)->EvalData.intVal;
3449}
3450
3451double clang_EvalResult_getAsDouble(CXEvalResult E) {
3452 if (!E) {
3453 return 0;
3454 }
3455 return ((ExprEvalResult *)E)->EvalData.floatVal;
3456}
3457
3458const char* clang_EvalResult_getAsStr(CXEvalResult E) {
3459 if (!E) {
3460 return nullptr;
3461 }
3462 return ((ExprEvalResult *)E)->EvalData.stringVal;
3463}
3464
3465static const ExprEvalResult* evaluateExpr(Expr *expr, CXCursor C) {
3466 Expr::EvalResult ER;
3467 ASTContext &ctx = getCursorContext(C);
David Blaikiebbc00882016-04-13 18:36:19 +00003468 if (!expr)
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003469 return nullptr;
David Blaikiebbc00882016-04-13 18:36:19 +00003470
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003471 expr = expr->IgnoreParens();
David Blaikiebbc00882016-04-13 18:36:19 +00003472 if (!expr->EvaluateAsRValue(ER, ctx))
3473 return nullptr;
3474
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003475 QualType rettype;
3476 CallExpr *callExpr;
David Blaikie59272572016-04-13 18:23:33 +00003477 auto result = llvm::make_unique<ExprEvalResult>();
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003478 result->EvalType = CXEval_UnExposed;
3479
David Blaikiebbc00882016-04-13 18:36:19 +00003480 if (ER.Val.isInt()) {
3481 result->EvalType = CXEval_Int;
3482 result->EvalData.intVal = ER.Val.getInt().getExtValue();
3483 return result.release();
3484 }
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003485
David Blaikiebbc00882016-04-13 18:36:19 +00003486 if (ER.Val.isFloat()) {
3487 llvm::SmallVector<char, 100> Buffer;
3488 ER.Val.getFloat().toString(Buffer);
3489 std::string floatStr(Buffer.data(), Buffer.size());
3490 result->EvalType = CXEval_Float;
3491 bool ignored;
3492 llvm::APFloat apFloat = ER.Val.getFloat();
3493 apFloat.convert(llvm::APFloat::IEEEdouble,
3494 llvm::APFloat::rmNearestTiesToEven, &ignored);
3495 result->EvalData.floatVal = apFloat.convertToDouble();
3496 return result.release();
3497 }
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003498
David Blaikiebbc00882016-04-13 18:36:19 +00003499 if (expr->getStmtClass() == Stmt::ImplicitCastExprClass) {
3500 const ImplicitCastExpr *I = dyn_cast<ImplicitCastExpr>(expr);
3501 auto *subExpr = I->getSubExprAsWritten();
3502 if (subExpr->getStmtClass() == Stmt::StringLiteralClass ||
3503 subExpr->getStmtClass() == Stmt::ObjCStringLiteralClass) {
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003504 const StringLiteral *StrE = nullptr;
3505 const ObjCStringLiteral *ObjCExpr;
David Blaikiebbc00882016-04-13 18:36:19 +00003506 ObjCExpr = dyn_cast<ObjCStringLiteral>(subExpr);
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003507
3508 if (ObjCExpr) {
3509 StrE = ObjCExpr->getString();
3510 result->EvalType = CXEval_ObjCStrLiteral;
3511 } else {
David Blaikiebbc00882016-04-13 18:36:19 +00003512 StrE = cast<StringLiteral>(I->getSubExprAsWritten());
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003513 result->EvalType = CXEval_StrLiteral;
3514 }
3515
3516 std::string strRef(StrE->getString().str());
David Blaikie59272572016-04-13 18:23:33 +00003517 result->EvalData.stringVal = new char[strRef.size() + 1];
David Blaikiebbc00882016-04-13 18:36:19 +00003518 strncpy((char *)result->EvalData.stringVal, strRef.c_str(),
3519 strRef.size());
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003520 result->EvalData.stringVal[strRef.size()] = '\0';
David Blaikie59272572016-04-13 18:23:33 +00003521 return result.release();
David Blaikiebbc00882016-04-13 18:36:19 +00003522 }
3523 } else if (expr->getStmtClass() == Stmt::ObjCStringLiteralClass ||
3524 expr->getStmtClass() == Stmt::StringLiteralClass) {
3525 const StringLiteral *StrE = nullptr;
3526 const ObjCStringLiteral *ObjCExpr;
3527 ObjCExpr = dyn_cast<ObjCStringLiteral>(expr);
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003528
David Blaikiebbc00882016-04-13 18:36:19 +00003529 if (ObjCExpr) {
3530 StrE = ObjCExpr->getString();
3531 result->EvalType = CXEval_ObjCStrLiteral;
3532 } else {
3533 StrE = cast<StringLiteral>(expr);
3534 result->EvalType = CXEval_StrLiteral;
3535 }
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003536
David Blaikiebbc00882016-04-13 18:36:19 +00003537 std::string strRef(StrE->getString().str());
3538 result->EvalData.stringVal = new char[strRef.size() + 1];
3539 strncpy((char *)result->EvalData.stringVal, strRef.c_str(), strRef.size());
3540 result->EvalData.stringVal[strRef.size()] = '\0';
3541 return result.release();
3542 }
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003543
David Blaikiebbc00882016-04-13 18:36:19 +00003544 if (expr->getStmtClass() == Stmt::CStyleCastExprClass) {
3545 CStyleCastExpr *CC = static_cast<CStyleCastExpr *>(expr);
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003546
David Blaikiebbc00882016-04-13 18:36:19 +00003547 rettype = CC->getType();
3548 if (rettype.getAsString() == "CFStringRef" &&
3549 CC->getSubExpr()->getStmtClass() == Stmt::CallExprClass) {
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003550
David Blaikiebbc00882016-04-13 18:36:19 +00003551 callExpr = static_cast<CallExpr *>(CC->getSubExpr());
3552 StringLiteral *S = getCFSTR_value(callExpr);
3553 if (S) {
3554 std::string strLiteral(S->getString().str());
3555 result->EvalType = CXEval_CFStr;
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003556
David Blaikiebbc00882016-04-13 18:36:19 +00003557 result->EvalData.stringVal = new char[strLiteral.size() + 1];
3558 strncpy((char *)result->EvalData.stringVal, strLiteral.c_str(),
3559 strLiteral.size());
3560 result->EvalData.stringVal[strLiteral.size()] = '\0';
David Blaikie59272572016-04-13 18:23:33 +00003561 return result.release();
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003562 }
3563 }
3564
David Blaikiebbc00882016-04-13 18:36:19 +00003565 } else if (expr->getStmtClass() == Stmt::CallExprClass) {
3566 callExpr = static_cast<CallExpr *>(expr);
3567 rettype = callExpr->getCallReturnType(ctx);
3568
3569 if (rettype->isVectorType() || callExpr->getNumArgs() > 1)
3570 return nullptr;
3571
3572 if (rettype->isIntegralType(ctx) || rettype->isRealFloatingType()) {
3573 if (callExpr->getNumArgs() == 1 &&
3574 !callExpr->getArg(0)->getType()->isIntegralType(ctx))
3575 return nullptr;
3576 } else if (rettype.getAsString() == "CFStringRef") {
3577
3578 StringLiteral *S = getCFSTR_value(callExpr);
3579 if (S) {
3580 std::string strLiteral(S->getString().str());
3581 result->EvalType = CXEval_CFStr;
3582 result->EvalData.stringVal = new char[strLiteral.size() + 1];
3583 strncpy((char *)result->EvalData.stringVal, strLiteral.c_str(),
3584 strLiteral.size());
3585 result->EvalData.stringVal[strLiteral.size()] = '\0';
3586 return result.release();
3587 }
3588 }
3589 } else if (expr->getStmtClass() == Stmt::DeclRefExprClass) {
3590 DeclRefExpr *D = static_cast<DeclRefExpr *>(expr);
3591 ValueDecl *V = D->getDecl();
3592 if (V->getKind() == Decl::Function) {
3593 std::string strName = V->getNameAsString();
3594 result->EvalType = CXEval_Other;
3595 result->EvalData.stringVal = new char[strName.size() + 1];
3596 strncpy(result->EvalData.stringVal, strName.c_str(), strName.size());
3597 result->EvalData.stringVal[strName.size()] = '\0';
3598 return result.release();
3599 }
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003600 }
3601
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003602 return nullptr;
3603}
3604
3605CXEvalResult clang_Cursor_Evaluate(CXCursor C) {
3606 const Decl *D = getCursorDecl(C);
3607 if (D) {
3608 const Expr *expr = nullptr;
3609 if (auto *Var = dyn_cast<VarDecl>(D)) {
3610 expr = Var->getInit();
3611 } else if (auto *Field = dyn_cast<FieldDecl>(D)) {
3612 expr = Field->getInClassInitializer();
3613 }
3614 if (expr)
Aaron Ballman01dc1572016-01-20 15:25:30 +00003615 return const_cast<CXEvalResult>(reinterpret_cast<const void *>(
3616 evaluateExpr(const_cast<Expr *>(expr), C)));
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003617 return nullptr;
3618 }
3619
3620 const CompoundStmt *compoundStmt = dyn_cast_or_null<CompoundStmt>(getCursorStmt(C));
3621 if (compoundStmt) {
3622 Expr *expr = nullptr;
3623 for (auto *bodyIterator : compoundStmt->body()) {
3624 if ((expr = dyn_cast<Expr>(bodyIterator))) {
3625 break;
3626 }
3627 }
3628 if (expr)
Aaron Ballman01dc1572016-01-20 15:25:30 +00003629 return const_cast<CXEvalResult>(
3630 reinterpret_cast<const void *>(evaluateExpr(expr, C)));
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003631 }
3632 return nullptr;
3633}
3634
3635unsigned clang_Cursor_hasAttrs(CXCursor C) {
3636 const Decl *D = getCursorDecl(C);
3637 if (!D) {
3638 return 0;
3639 }
3640
3641 if (D->hasAttrs()) {
3642 return 1;
3643 }
3644
3645 return 0;
3646}
Guy Benyei11169dd2012-12-18 14:30:41 +00003647unsigned clang_defaultSaveOptions(CXTranslationUnit TU) {
3648 return CXSaveTranslationUnit_None;
3649}
3650
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003651static CXSaveError clang_saveTranslationUnit_Impl(CXTranslationUnit TU,
3652 const char *FileName,
3653 unsigned options) {
3654 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00003655 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
3656 setThreadBackgroundPriority();
3657
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003658 bool hadError = cxtu::getASTUnit(TU)->Save(FileName);
3659 return hadError ? CXSaveError_Unknown : CXSaveError_None;
Guy Benyei11169dd2012-12-18 14:30:41 +00003660}
3661
3662int clang_saveTranslationUnit(CXTranslationUnit TU, const char *FileName,
3663 unsigned options) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00003664 LOG_FUNC_SECTION {
3665 *Log << TU << ' ' << FileName;
3666 }
3667
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003668 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003669 LOG_BAD_TU(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003670 return CXSaveError_InvalidTU;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003671 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003672
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003673 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003674 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
3675 if (!CXXUnit->hasSema())
3676 return CXSaveError_InvalidTU;
3677
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003678 CXSaveError result;
3679 auto SaveTranslationUnitImpl = [=, &result]() {
3680 result = clang_saveTranslationUnit_Impl(TU, FileName, options);
3681 };
Guy Benyei11169dd2012-12-18 14:30:41 +00003682
3683 if (!CXXUnit->getDiagnostics().hasUnrecoverableErrorOccurred() ||
3684 getenv("LIBCLANG_NOTHREADS")) {
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003685 SaveTranslationUnitImpl();
Guy Benyei11169dd2012-12-18 14:30:41 +00003686
3687 if (getenv("LIBCLANG_RESOURCE_USAGE"))
3688 PrintLibclangResourceUsage(TU);
3689
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003690 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003691 }
3692
3693 // We have an AST that has invalid nodes due to compiler errors.
3694 // Use a crash recovery thread for protection.
3695
3696 llvm::CrashRecoveryContext CRC;
3697
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003698 if (!RunSafely(CRC, SaveTranslationUnitImpl)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003699 fprintf(stderr, "libclang: crash detected during AST saving: {\n");
3700 fprintf(stderr, " 'filename' : '%s'\n", FileName);
3701 fprintf(stderr, " 'options' : %d,\n", options);
3702 fprintf(stderr, "}\n");
3703
3704 return CXSaveError_Unknown;
3705
3706 } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
3707 PrintLibclangResourceUsage(TU);
3708 }
3709
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003710 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003711}
3712
3713void clang_disposeTranslationUnit(CXTranslationUnit CTUnit) {
3714 if (CTUnit) {
3715 // If the translation unit has been marked as unsafe to free, just discard
3716 // it.
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003717 ASTUnit *Unit = cxtu::getASTUnit(CTUnit);
3718 if (Unit && Unit->isUnsafeToFree())
Guy Benyei11169dd2012-12-18 14:30:41 +00003719 return;
3720
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003721 delete cxtu::getASTUnit(CTUnit);
Dmitri Gribenkob95b3f12013-01-26 22:44:19 +00003722 delete CTUnit->StringPool;
Guy Benyei11169dd2012-12-18 14:30:41 +00003723 delete static_cast<CXDiagnosticSetImpl *>(CTUnit->Diagnostics);
3724 disposeOverridenCXCursorsPool(CTUnit->OverridenCursorsPool);
Dmitri Gribenko9e605112013-11-13 22:16:51 +00003725 delete CTUnit->CommentToXML;
Guy Benyei11169dd2012-12-18 14:30:41 +00003726 delete CTUnit;
3727 }
3728}
3729
3730unsigned clang_defaultReparseOptions(CXTranslationUnit TU) {
3731 return CXReparse_None;
3732}
3733
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003734static CXErrorCode
3735clang_reparseTranslationUnit_Impl(CXTranslationUnit TU,
3736 ArrayRef<CXUnsavedFile> unsaved_files,
3737 unsigned options) {
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003738 // Check arguments.
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003739 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003740 LOG_BAD_TU(TU);
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003741 return CXError_InvalidArguments;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003742 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003743
3744 // Reset the associated diagnostics.
3745 delete static_cast<CXDiagnosticSetImpl*>(TU->Diagnostics);
Craig Topper69186e72014-06-08 08:38:04 +00003746 TU->Diagnostics = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00003747
Dmitri Gribenko183436e2013-01-26 21:49:50 +00003748 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00003749 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
3750 setThreadBackgroundPriority();
3751
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003752 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003753 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
Ahmed Charlesb8984322014-03-07 20:03:18 +00003754
3755 std::unique_ptr<std::vector<ASTUnit::RemappedFile>> RemappedFiles(
3756 new std::vector<ASTUnit::RemappedFile>());
3757
Guy Benyei11169dd2012-12-18 14:30:41 +00003758 // Recover resources if we crash before exiting this function.
3759 llvm::CrashRecoveryContextCleanupRegistrar<
3760 std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
Alp Toker9d85b182014-07-07 01:23:14 +00003761
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003762 for (auto &UF : unsaved_files) {
Rafael Espindolad87f8d72014-08-27 20:03:29 +00003763 std::unique_ptr<llvm::MemoryBuffer> MB =
Alp Toker9d85b182014-07-07 01:23:14 +00003764 llvm::MemoryBuffer::getMemBufferCopy(getContents(UF), UF.Filename);
Rafael Espindolad87f8d72014-08-27 20:03:29 +00003765 RemappedFiles->push_back(std::make_pair(UF.Filename, MB.release()));
Guy Benyei11169dd2012-12-18 14:30:41 +00003766 }
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003767
Adrian Prantlbb165fb2015-06-20 18:53:08 +00003768 if (!CXXUnit->Reparse(CXXIdx->getPCHContainerOperations(),
3769 *RemappedFiles.get()))
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003770 return CXError_Success;
3771 if (isASTReadError(CXXUnit))
3772 return CXError_ASTReadError;
3773 return CXError_Failure;
Guy Benyei11169dd2012-12-18 14:30:41 +00003774}
3775
3776int clang_reparseTranslationUnit(CXTranslationUnit TU,
3777 unsigned num_unsaved_files,
3778 struct CXUnsavedFile *unsaved_files,
3779 unsigned options) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00003780 LOG_FUNC_SECTION {
3781 *Log << TU;
3782 }
3783
Alp Toker9d85b182014-07-07 01:23:14 +00003784 if (num_unsaved_files && !unsaved_files)
3785 return CXError_InvalidArguments;
3786
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003787 CXErrorCode result;
3788 auto ReparseTranslationUnitImpl = [=, &result]() {
3789 result = clang_reparseTranslationUnit_Impl(
3790 TU, llvm::makeArrayRef(unsaved_files, num_unsaved_files), options);
3791 };
Guy Benyei11169dd2012-12-18 14:30:41 +00003792
3793 if (getenv("LIBCLANG_NOTHREADS")) {
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003794 ReparseTranslationUnitImpl();
Alp Toker5c532982014-07-07 22:42:03 +00003795 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003796 }
3797
3798 llvm::CrashRecoveryContext CRC;
3799
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003800 if (!RunSafely(CRC, ReparseTranslationUnitImpl)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003801 fprintf(stderr, "libclang: crash detected during reparsing\n");
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003802 cxtu::getASTUnit(TU)->setUnsafeToFree(true);
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003803 return CXError_Crashed;
Guy Benyei11169dd2012-12-18 14:30:41 +00003804 } else if (getenv("LIBCLANG_RESOURCE_USAGE"))
3805 PrintLibclangResourceUsage(TU);
3806
Alp Toker5c532982014-07-07 22:42:03 +00003807 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003808}
3809
3810
3811CXString clang_getTranslationUnitSpelling(CXTranslationUnit CTUnit) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003812 if (isNotUsableTU(CTUnit)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003813 LOG_BAD_TU(CTUnit);
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003814 return cxstring::createEmpty();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003815 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003816
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003817 ASTUnit *CXXUnit = cxtu::getASTUnit(CTUnit);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003818 return cxstring::createDup(CXXUnit->getOriginalSourceFileName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003819}
3820
3821CXCursor clang_getTranslationUnitCursor(CXTranslationUnit TU) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003822 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003823 LOG_BAD_TU(TU);
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00003824 return clang_getNullCursor();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003825 }
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00003826
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003827 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003828 return MakeCXCursor(CXXUnit->getASTContext().getTranslationUnitDecl(), TU);
3829}
3830
3831} // end: extern "C"
3832
3833//===----------------------------------------------------------------------===//
3834// CXFile Operations.
3835//===----------------------------------------------------------------------===//
3836
3837extern "C" {
3838CXString clang_getFileName(CXFile SFile) {
3839 if (!SFile)
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00003840 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00003841
3842 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003843 return cxstring::createRef(FEnt->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003844}
3845
3846time_t clang_getFileTime(CXFile SFile) {
3847 if (!SFile)
3848 return 0;
3849
3850 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
3851 return FEnt->getModificationTime();
3852}
3853
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003854CXFile clang_getFile(CXTranslationUnit TU, const char *file_name) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003855 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003856 LOG_BAD_TU(TU);
Craig Topper69186e72014-06-08 08:38:04 +00003857 return nullptr;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003858 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003859
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003860 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003861
3862 FileManager &FMgr = CXXUnit->getFileManager();
3863 return const_cast<FileEntry *>(FMgr.getFile(file_name));
3864}
3865
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003866unsigned clang_isFileMultipleIncludeGuarded(CXTranslationUnit TU,
3867 CXFile file) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003868 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003869 LOG_BAD_TU(TU);
3870 return 0;
3871 }
3872
3873 if (!file)
Guy Benyei11169dd2012-12-18 14:30:41 +00003874 return 0;
3875
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003876 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003877 FileEntry *FEnt = static_cast<FileEntry *>(file);
3878 return CXXUnit->getPreprocessor().getHeaderSearchInfo()
3879 .isFileMultipleIncludeGuarded(FEnt);
3880}
3881
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003882int clang_getFileUniqueID(CXFile file, CXFileUniqueID *outID) {
3883 if (!file || !outID)
3884 return 1;
3885
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003886 FileEntry *FEnt = static_cast<FileEntry *>(file);
Rafael Espindolaf8f91b82013-08-01 21:42:11 +00003887 const llvm::sys::fs::UniqueID &ID = FEnt->getUniqueID();
3888 outID->data[0] = ID.getDevice();
3889 outID->data[1] = ID.getFile();
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003890 outID->data[2] = FEnt->getModificationTime();
3891 return 0;
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003892}
3893
Argyrios Kyrtzidisac3997e2014-08-16 00:26:19 +00003894int clang_File_isEqual(CXFile file1, CXFile file2) {
3895 if (file1 == file2)
3896 return true;
3897
3898 if (!file1 || !file2)
3899 return false;
3900
3901 FileEntry *FEnt1 = static_cast<FileEntry *>(file1);
3902 FileEntry *FEnt2 = static_cast<FileEntry *>(file2);
3903 return FEnt1->getUniqueID() == FEnt2->getUniqueID();
3904}
3905
Guy Benyei11169dd2012-12-18 14:30:41 +00003906} // end: extern "C"
3907
3908//===----------------------------------------------------------------------===//
3909// CXCursor Operations.
3910//===----------------------------------------------------------------------===//
3911
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003912static const Decl *getDeclFromExpr(const Stmt *E) {
3913 if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003914 return getDeclFromExpr(CE->getSubExpr());
3915
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003916 if (const DeclRefExpr *RefExpr = dyn_cast<DeclRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003917 return RefExpr->getDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003918 if (const MemberExpr *ME = dyn_cast<MemberExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003919 return ME->getMemberDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003920 if (const ObjCIvarRefExpr *RE = dyn_cast<ObjCIvarRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003921 return RE->getDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003922 if (const ObjCPropertyRefExpr *PRE = dyn_cast<ObjCPropertyRefExpr>(E)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003923 if (PRE->isExplicitProperty())
3924 return PRE->getExplicitProperty();
3925 // It could be messaging both getter and setter as in:
3926 // ++myobj.myprop;
3927 // in which case prefer to associate the setter since it is less obvious
3928 // from inspecting the source that the setter is going to get called.
3929 if (PRE->isMessagingSetter())
3930 return PRE->getImplicitPropertySetter();
3931 return PRE->getImplicitPropertyGetter();
3932 }
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003933 if (const PseudoObjectExpr *POE = dyn_cast<PseudoObjectExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003934 return getDeclFromExpr(POE->getSyntacticForm());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003935 if (const OpaqueValueExpr *OVE = dyn_cast<OpaqueValueExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003936 if (Expr *Src = OVE->getSourceExpr())
3937 return getDeclFromExpr(Src);
3938
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003939 if (const CallExpr *CE = dyn_cast<CallExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003940 return getDeclFromExpr(CE->getCallee());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003941 if (const CXXConstructExpr *CE = dyn_cast<CXXConstructExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003942 if (!CE->isElidable())
3943 return CE->getConstructor();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003944 if (const ObjCMessageExpr *OME = dyn_cast<ObjCMessageExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003945 return OME->getMethodDecl();
3946
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003947 if (const ObjCProtocolExpr *PE = dyn_cast<ObjCProtocolExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003948 return PE->getProtocol();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003949 if (const SubstNonTypeTemplateParmPackExpr *NTTP
Guy Benyei11169dd2012-12-18 14:30:41 +00003950 = dyn_cast<SubstNonTypeTemplateParmPackExpr>(E))
3951 return NTTP->getParameterPack();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003952 if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003953 if (isa<NonTypeTemplateParmDecl>(SizeOfPack->getPack()) ||
3954 isa<ParmVarDecl>(SizeOfPack->getPack()))
3955 return SizeOfPack->getPack();
Craig Topper69186e72014-06-08 08:38:04 +00003956
3957 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00003958}
3959
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003960static SourceLocation getLocationFromExpr(const Expr *E) {
3961 if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003962 return getLocationFromExpr(CE->getSubExpr());
3963
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003964 if (const ObjCMessageExpr *Msg = dyn_cast<ObjCMessageExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003965 return /*FIXME:*/Msg->getLeftLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003966 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003967 return DRE->getLocation();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003968 if (const MemberExpr *Member = dyn_cast<MemberExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003969 return Member->getMemberLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003970 if (const ObjCIvarRefExpr *Ivar = dyn_cast<ObjCIvarRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003971 return Ivar->getLocation();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003972 if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003973 return SizeOfPack->getPackLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003974 if (const ObjCPropertyRefExpr *PropRef = dyn_cast<ObjCPropertyRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003975 return PropRef->getLocation();
3976
3977 return E->getLocStart();
3978}
3979
3980extern "C" {
3981
3982unsigned clang_visitChildren(CXCursor parent,
3983 CXCursorVisitor visitor,
3984 CXClientData client_data) {
3985 CursorVisitor CursorVis(getCursorTU(parent), visitor, client_data,
3986 /*VisitPreprocessorLast=*/false);
3987 return CursorVis.VisitChildren(parent);
3988}
3989
3990#ifndef __has_feature
3991#define __has_feature(x) 0
3992#endif
3993#if __has_feature(blocks)
3994typedef enum CXChildVisitResult
3995 (^CXCursorVisitorBlock)(CXCursor cursor, CXCursor parent);
3996
3997static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
3998 CXClientData client_data) {
3999 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
4000 return block(cursor, parent);
4001}
4002#else
4003// If we are compiled with a compiler that doesn't have native blocks support,
4004// define and call the block manually, so the
4005typedef struct _CXChildVisitResult
4006{
4007 void *isa;
4008 int flags;
4009 int reserved;
4010 enum CXChildVisitResult(*invoke)(struct _CXChildVisitResult*, CXCursor,
4011 CXCursor);
4012} *CXCursorVisitorBlock;
4013
4014static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
4015 CXClientData client_data) {
4016 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
4017 return block->invoke(block, cursor, parent);
4018}
4019#endif
4020
4021
4022unsigned clang_visitChildrenWithBlock(CXCursor parent,
4023 CXCursorVisitorBlock block) {
4024 return clang_visitChildren(parent, visitWithBlock, block);
4025}
4026
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004027static CXString getDeclSpelling(const Decl *D) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004028 if (!D)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00004029 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00004030
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004031 const NamedDecl *ND = dyn_cast<NamedDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00004032 if (!ND) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004033 if (const ObjCPropertyImplDecl *PropImpl =
4034 dyn_cast<ObjCPropertyImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004035 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004036 return cxstring::createDup(Property->getIdentifier()->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00004037
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004038 if (const ImportDecl *ImportD = dyn_cast<ImportDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004039 if (Module *Mod = ImportD->getImportedModule())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004040 return cxstring::createDup(Mod->getFullModuleName());
Guy Benyei11169dd2012-12-18 14:30:41 +00004041
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00004042 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00004043 }
4044
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004045 if (const ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(ND))
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004046 return cxstring::createDup(OMD->getSelector().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00004047
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004048 if (const ObjCCategoryImplDecl *CIMP = dyn_cast<ObjCCategoryImplDecl>(ND))
Guy Benyei11169dd2012-12-18 14:30:41 +00004049 // No, this isn't the same as the code below. getIdentifier() is non-virtual
4050 // and returns different names. NamedDecl returns the class name and
4051 // ObjCCategoryImplDecl returns the category name.
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004052 return cxstring::createRef(CIMP->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00004053
4054 if (isa<UsingDirectiveDecl>(D))
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00004055 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00004056
4057 SmallString<1024> S;
4058 llvm::raw_svector_ostream os(S);
4059 ND->printName(os);
4060
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004061 return cxstring::createDup(os.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00004062}
4063
4064CXString clang_getCursorSpelling(CXCursor C) {
4065 if (clang_isTranslationUnit(C.kind))
Dmitri Gribenko2c173b42013-01-11 19:28:44 +00004066 return clang_getTranslationUnitSpelling(getCursorTU(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00004067
4068 if (clang_isReference(C.kind)) {
4069 switch (C.kind) {
4070 case CXCursor_ObjCSuperClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004071 const ObjCInterfaceDecl *Super = getCursorObjCSuperClassRef(C).first;
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004072 return cxstring::createRef(Super->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00004073 }
4074 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004075 const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004076 return cxstring::createRef(Class->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00004077 }
4078 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004079 const ObjCProtocolDecl *OID = getCursorObjCProtocolRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00004080 assert(OID && "getCursorSpelling(): Missing protocol decl");
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004081 return cxstring::createRef(OID->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00004082 }
4083 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004084 const CXXBaseSpecifier *B = getCursorCXXBaseSpecifier(C);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004085 return cxstring::createDup(B->getType().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00004086 }
4087 case CXCursor_TypeRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004088 const TypeDecl *Type = getCursorTypeRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00004089 assert(Type && "Missing type decl");
4090
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004091 return cxstring::createDup(getCursorContext(C).getTypeDeclType(Type).
Guy Benyei11169dd2012-12-18 14:30:41 +00004092 getAsString());
4093 }
4094 case CXCursor_TemplateRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004095 const TemplateDecl *Template = getCursorTemplateRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00004096 assert(Template && "Missing template decl");
4097
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004098 return cxstring::createDup(Template->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00004099 }
4100
4101 case CXCursor_NamespaceRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004102 const NamedDecl *NS = getCursorNamespaceRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00004103 assert(NS && "Missing namespace decl");
4104
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004105 return cxstring::createDup(NS->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00004106 }
4107
4108 case CXCursor_MemberRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004109 const FieldDecl *Field = getCursorMemberRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00004110 assert(Field && "Missing member decl");
4111
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004112 return cxstring::createDup(Field->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00004113 }
4114
4115 case CXCursor_LabelRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004116 const LabelStmt *Label = getCursorLabelRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00004117 assert(Label && "Missing label");
4118
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004119 return cxstring::createRef(Label->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00004120 }
4121
4122 case CXCursor_OverloadedDeclRef: {
4123 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004124 if (const Decl *D = Storage.dyn_cast<const Decl *>()) {
4125 if (const NamedDecl *ND = dyn_cast<NamedDecl>(D))
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004126 return cxstring::createDup(ND->getNameAsString());
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00004127 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00004128 }
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004129 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004130 return cxstring::createDup(E->getName().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00004131 OverloadedTemplateStorage *Ovl
4132 = Storage.get<OverloadedTemplateStorage*>();
4133 if (Ovl->size() == 0)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00004134 return cxstring::createEmpty();
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004135 return cxstring::createDup((*Ovl->begin())->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00004136 }
4137
4138 case CXCursor_VariableRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004139 const VarDecl *Var = getCursorVariableRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00004140 assert(Var && "Missing variable decl");
4141
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004142 return cxstring::createDup(Var->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00004143 }
4144
4145 default:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004146 return cxstring::createRef("<not implemented>");
Guy Benyei11169dd2012-12-18 14:30:41 +00004147 }
4148 }
4149
4150 if (clang_isExpression(C.kind)) {
Argyrios Kyrtzidis3227d862014-03-03 19:40:52 +00004151 const Expr *E = getCursorExpr(C);
4152
4153 if (C.kind == CXCursor_ObjCStringLiteral ||
4154 C.kind == CXCursor_StringLiteral) {
4155 const StringLiteral *SLit;
4156 if (const ObjCStringLiteral *OSL = dyn_cast<ObjCStringLiteral>(E)) {
4157 SLit = OSL->getString();
4158 } else {
4159 SLit = cast<StringLiteral>(E);
4160 }
4161 SmallString<256> Buf;
4162 llvm::raw_svector_ostream OS(Buf);
4163 SLit->outputString(OS);
4164 return cxstring::createDup(OS.str());
4165 }
4166
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004167 const Decl *D = getDeclFromExpr(getCursorExpr(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00004168 if (D)
4169 return getDeclSpelling(D);
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00004170 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00004171 }
4172
4173 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004174 const Stmt *S = getCursorStmt(C);
4175 if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S))
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004176 return cxstring::createRef(Label->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00004177
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00004178 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00004179 }
4180
4181 if (C.kind == CXCursor_MacroExpansion)
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004182 return cxstring::createRef(getCursorMacroExpansion(C).getName()
Guy Benyei11169dd2012-12-18 14:30:41 +00004183 ->getNameStart());
4184
4185 if (C.kind == CXCursor_MacroDefinition)
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004186 return cxstring::createRef(getCursorMacroDefinition(C)->getName()
Guy Benyei11169dd2012-12-18 14:30:41 +00004187 ->getNameStart());
4188
4189 if (C.kind == CXCursor_InclusionDirective)
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004190 return cxstring::createDup(getCursorInclusionDirective(C)->getFileName());
Guy Benyei11169dd2012-12-18 14:30:41 +00004191
4192 if (clang_isDeclaration(C.kind))
4193 return getDeclSpelling(getCursorDecl(C));
4194
4195 if (C.kind == CXCursor_AnnotateAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00004196 const AnnotateAttr *AA = cast<AnnotateAttr>(cxcursor::getCursorAttr(C));
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004197 return cxstring::createDup(AA->getAnnotation());
Guy Benyei11169dd2012-12-18 14:30:41 +00004198 }
4199
4200 if (C.kind == CXCursor_AsmLabelAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00004201 const AsmLabelAttr *AA = cast<AsmLabelAttr>(cxcursor::getCursorAttr(C));
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004202 return cxstring::createDup(AA->getLabel());
Guy Benyei11169dd2012-12-18 14:30:41 +00004203 }
4204
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00004205 if (C.kind == CXCursor_PackedAttr) {
4206 return cxstring::createRef("packed");
4207 }
4208
Saleem Abdulrasool79c69712015-09-05 18:53:43 +00004209 if (C.kind == CXCursor_VisibilityAttr) {
4210 const VisibilityAttr *AA = cast<VisibilityAttr>(cxcursor::getCursorAttr(C));
4211 switch (AA->getVisibility()) {
4212 case VisibilityAttr::VisibilityType::Default:
4213 return cxstring::createRef("default");
4214 case VisibilityAttr::VisibilityType::Hidden:
4215 return cxstring::createRef("hidden");
4216 case VisibilityAttr::VisibilityType::Protected:
4217 return cxstring::createRef("protected");
4218 }
4219 llvm_unreachable("unknown visibility type");
4220 }
4221
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00004222 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00004223}
4224
4225CXSourceRange clang_Cursor_getSpellingNameRange(CXCursor C,
4226 unsigned pieceIndex,
4227 unsigned options) {
4228 if (clang_Cursor_isNull(C))
4229 return clang_getNullRange();
4230
4231 ASTContext &Ctx = getCursorContext(C);
4232
4233 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004234 const Stmt *S = getCursorStmt(C);
4235 if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004236 if (pieceIndex > 0)
4237 return clang_getNullRange();
4238 return cxloc::translateSourceRange(Ctx, Label->getIdentLoc());
4239 }
4240
4241 return clang_getNullRange();
4242 }
4243
4244 if (C.kind == CXCursor_ObjCMessageExpr) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004245 if (const ObjCMessageExpr *
Guy Benyei11169dd2012-12-18 14:30:41 +00004246 ME = dyn_cast_or_null<ObjCMessageExpr>(getCursorExpr(C))) {
4247 if (pieceIndex >= ME->getNumSelectorLocs())
4248 return clang_getNullRange();
4249 return cxloc::translateSourceRange(Ctx, ME->getSelectorLoc(pieceIndex));
4250 }
4251 }
4252
4253 if (C.kind == CXCursor_ObjCInstanceMethodDecl ||
4254 C.kind == CXCursor_ObjCClassMethodDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004255 if (const ObjCMethodDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00004256 MD = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(C))) {
4257 if (pieceIndex >= MD->getNumSelectorLocs())
4258 return clang_getNullRange();
4259 return cxloc::translateSourceRange(Ctx, MD->getSelectorLoc(pieceIndex));
4260 }
4261 }
4262
4263 if (C.kind == CXCursor_ObjCCategoryDecl ||
4264 C.kind == CXCursor_ObjCCategoryImplDecl) {
4265 if (pieceIndex > 0)
4266 return clang_getNullRange();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004267 if (const ObjCCategoryDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00004268 CD = dyn_cast_or_null<ObjCCategoryDecl>(getCursorDecl(C)))
4269 return cxloc::translateSourceRange(Ctx, CD->getCategoryNameLoc());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004270 if (const ObjCCategoryImplDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00004271 CID = dyn_cast_or_null<ObjCCategoryImplDecl>(getCursorDecl(C)))
4272 return cxloc::translateSourceRange(Ctx, CID->getCategoryNameLoc());
4273 }
4274
4275 if (C.kind == CXCursor_ModuleImportDecl) {
4276 if (pieceIndex > 0)
4277 return clang_getNullRange();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004278 if (const ImportDecl *ImportD =
4279 dyn_cast_or_null<ImportDecl>(getCursorDecl(C))) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004280 ArrayRef<SourceLocation> Locs = ImportD->getIdentifierLocs();
4281 if (!Locs.empty())
4282 return cxloc::translateSourceRange(Ctx,
4283 SourceRange(Locs.front(), Locs.back()));
4284 }
4285 return clang_getNullRange();
4286 }
4287
Argyrios Kyrtzidisa2a1e532014-08-26 20:23:26 +00004288 if (C.kind == CXCursor_CXXMethod || C.kind == CXCursor_Destructor ||
4289 C.kind == CXCursor_ConversionFunction) {
4290 if (pieceIndex > 0)
4291 return clang_getNullRange();
4292 if (const FunctionDecl *FD =
4293 dyn_cast_or_null<FunctionDecl>(getCursorDecl(C))) {
4294 DeclarationNameInfo FunctionName = FD->getNameInfo();
4295 return cxloc::translateSourceRange(Ctx, FunctionName.getSourceRange());
4296 }
4297 return clang_getNullRange();
4298 }
4299
Guy Benyei11169dd2012-12-18 14:30:41 +00004300 // FIXME: A CXCursor_InclusionDirective should give the location of the
4301 // filename, but we don't keep track of this.
4302
4303 // FIXME: A CXCursor_AnnotateAttr should give the location of the annotation
4304 // but we don't keep track of this.
4305
4306 // FIXME: A CXCursor_AsmLabelAttr should give the location of the label
4307 // but we don't keep track of this.
4308
4309 // Default handling, give the location of the cursor.
4310
4311 if (pieceIndex > 0)
4312 return clang_getNullRange();
4313
4314 CXSourceLocation CXLoc = clang_getCursorLocation(C);
4315 SourceLocation Loc = cxloc::translateSourceLocation(CXLoc);
4316 return cxloc::translateSourceRange(Ctx, Loc);
4317}
4318
Eli Bendersky44a206f2014-07-31 18:04:56 +00004319CXString clang_Cursor_getMangling(CXCursor C) {
4320 if (clang_isInvalid(C.kind) || !clang_isDeclaration(C.kind))
4321 return cxstring::createEmpty();
4322
Eli Bendersky44a206f2014-07-31 18:04:56 +00004323 // Mangling only works for functions and variables.
Eli Bendersky79759592014-08-01 15:01:10 +00004324 const Decl *D = getCursorDecl(C);
Eli Bendersky44a206f2014-07-31 18:04:56 +00004325 if (!D || !(isa<FunctionDecl>(D) || isa<VarDecl>(D)))
4326 return cxstring::createEmpty();
4327
Argyrios Kyrtzidisca741ce2016-02-14 22:30:14 +00004328 ASTContext &Ctx = D->getASTContext();
4329 index::CodegenNameGenerator CGNameGen(Ctx);
4330 return cxstring::createDup(CGNameGen.getName(D));
Eli Bendersky44a206f2014-07-31 18:04:56 +00004331}
4332
Saleem Abdulrasool60034432015-11-12 03:57:22 +00004333CXStringSet *clang_Cursor_getCXXManglings(CXCursor C) {
4334 if (clang_isInvalid(C.kind) || !clang_isDeclaration(C.kind))
4335 return nullptr;
4336
4337 const Decl *D = getCursorDecl(C);
4338 if (!(isa<CXXRecordDecl>(D) || isa<CXXMethodDecl>(D)))
4339 return nullptr;
4340
Argyrios Kyrtzidisca741ce2016-02-14 22:30:14 +00004341 ASTContext &Ctx = D->getASTContext();
4342 index::CodegenNameGenerator CGNameGen(Ctx);
4343 std::vector<std::string> Manglings = CGNameGen.getAllManglings(D);
Saleem Abdulrasool60034432015-11-12 03:57:22 +00004344 return cxstring::createSet(Manglings);
4345}
4346
Guy Benyei11169dd2012-12-18 14:30:41 +00004347CXString clang_getCursorDisplayName(CXCursor C) {
4348 if (!clang_isDeclaration(C.kind))
4349 return clang_getCursorSpelling(C);
4350
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004351 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004352 if (!D)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00004353 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00004354
4355 PrintingPolicy Policy = getCursorContext(C).getPrintingPolicy();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004356 if (const FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004357 D = FunTmpl->getTemplatedDecl();
4358
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004359 if (const FunctionDecl *Function = dyn_cast<FunctionDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004360 SmallString<64> Str;
4361 llvm::raw_svector_ostream OS(Str);
4362 OS << *Function;
4363 if (Function->getPrimaryTemplate())
4364 OS << "<>";
4365 OS << "(";
4366 for (unsigned I = 0, N = Function->getNumParams(); I != N; ++I) {
4367 if (I)
4368 OS << ", ";
4369 OS << Function->getParamDecl(I)->getType().getAsString(Policy);
4370 }
4371
4372 if (Function->isVariadic()) {
4373 if (Function->getNumParams())
4374 OS << ", ";
4375 OS << "...";
4376 }
4377 OS << ")";
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004378 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00004379 }
4380
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004381 if (const ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004382 SmallString<64> Str;
4383 llvm::raw_svector_ostream OS(Str);
4384 OS << *ClassTemplate;
4385 OS << "<";
4386 TemplateParameterList *Params = ClassTemplate->getTemplateParameters();
4387 for (unsigned I = 0, N = Params->size(); I != N; ++I) {
4388 if (I)
4389 OS << ", ";
4390
4391 NamedDecl *Param = Params->getParam(I);
4392 if (Param->getIdentifier()) {
4393 OS << Param->getIdentifier()->getName();
4394 continue;
4395 }
4396
4397 // There is no parameter name, which makes this tricky. Try to come up
4398 // with something useful that isn't too long.
4399 if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(Param))
4400 OS << (TTP->wasDeclaredWithTypename()? "typename" : "class");
4401 else if (NonTypeTemplateParmDecl *NTTP
4402 = dyn_cast<NonTypeTemplateParmDecl>(Param))
4403 OS << NTTP->getType().getAsString(Policy);
4404 else
4405 OS << "template<...> class";
4406 }
4407
4408 OS << ">";
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004409 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00004410 }
4411
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004412 if (const ClassTemplateSpecializationDecl *ClassSpec
Guy Benyei11169dd2012-12-18 14:30:41 +00004413 = dyn_cast<ClassTemplateSpecializationDecl>(D)) {
4414 // If the type was explicitly written, use that.
4415 if (TypeSourceInfo *TSInfo = ClassSpec->getTypeAsWritten())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004416 return cxstring::createDup(TSInfo->getType().getAsString(Policy));
Guy Benyei11169dd2012-12-18 14:30:41 +00004417
Benjamin Kramer9170e912013-02-22 15:46:01 +00004418 SmallString<128> Str;
Guy Benyei11169dd2012-12-18 14:30:41 +00004419 llvm::raw_svector_ostream OS(Str);
4420 OS << *ClassSpec;
Benjamin Kramer9170e912013-02-22 15:46:01 +00004421 TemplateSpecializationType::PrintTemplateArgumentList(OS,
Guy Benyei11169dd2012-12-18 14:30:41 +00004422 ClassSpec->getTemplateArgs().data(),
4423 ClassSpec->getTemplateArgs().size(),
4424 Policy);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004425 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00004426 }
4427
4428 return clang_getCursorSpelling(C);
4429}
4430
4431CXString clang_getCursorKindSpelling(enum CXCursorKind Kind) {
4432 switch (Kind) {
4433 case CXCursor_FunctionDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004434 return cxstring::createRef("FunctionDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004435 case CXCursor_TypedefDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004436 return cxstring::createRef("TypedefDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004437 case CXCursor_EnumDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004438 return cxstring::createRef("EnumDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004439 case CXCursor_EnumConstantDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004440 return cxstring::createRef("EnumConstantDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004441 case CXCursor_StructDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004442 return cxstring::createRef("StructDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004443 case CXCursor_UnionDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004444 return cxstring::createRef("UnionDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004445 case CXCursor_ClassDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004446 return cxstring::createRef("ClassDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004447 case CXCursor_FieldDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004448 return cxstring::createRef("FieldDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004449 case CXCursor_VarDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004450 return cxstring::createRef("VarDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004451 case CXCursor_ParmDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004452 return cxstring::createRef("ParmDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004453 case CXCursor_ObjCInterfaceDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004454 return cxstring::createRef("ObjCInterfaceDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004455 case CXCursor_ObjCCategoryDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004456 return cxstring::createRef("ObjCCategoryDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004457 case CXCursor_ObjCProtocolDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004458 return cxstring::createRef("ObjCProtocolDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004459 case CXCursor_ObjCPropertyDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004460 return cxstring::createRef("ObjCPropertyDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004461 case CXCursor_ObjCIvarDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004462 return cxstring::createRef("ObjCIvarDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004463 case CXCursor_ObjCInstanceMethodDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004464 return cxstring::createRef("ObjCInstanceMethodDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004465 case CXCursor_ObjCClassMethodDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004466 return cxstring::createRef("ObjCClassMethodDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004467 case CXCursor_ObjCImplementationDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004468 return cxstring::createRef("ObjCImplementationDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004469 case CXCursor_ObjCCategoryImplDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004470 return cxstring::createRef("ObjCCategoryImplDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004471 case CXCursor_CXXMethod:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004472 return cxstring::createRef("CXXMethod");
Guy Benyei11169dd2012-12-18 14:30:41 +00004473 case CXCursor_UnexposedDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004474 return cxstring::createRef("UnexposedDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004475 case CXCursor_ObjCSuperClassRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004476 return cxstring::createRef("ObjCSuperClassRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004477 case CXCursor_ObjCProtocolRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004478 return cxstring::createRef("ObjCProtocolRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004479 case CXCursor_ObjCClassRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004480 return cxstring::createRef("ObjCClassRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004481 case CXCursor_TypeRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004482 return cxstring::createRef("TypeRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004483 case CXCursor_TemplateRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004484 return cxstring::createRef("TemplateRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004485 case CXCursor_NamespaceRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004486 return cxstring::createRef("NamespaceRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004487 case CXCursor_MemberRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004488 return cxstring::createRef("MemberRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004489 case CXCursor_LabelRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004490 return cxstring::createRef("LabelRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004491 case CXCursor_OverloadedDeclRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004492 return cxstring::createRef("OverloadedDeclRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004493 case CXCursor_VariableRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004494 return cxstring::createRef("VariableRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004495 case CXCursor_IntegerLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004496 return cxstring::createRef("IntegerLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00004497 case CXCursor_FloatingLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004498 return cxstring::createRef("FloatingLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00004499 case CXCursor_ImaginaryLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004500 return cxstring::createRef("ImaginaryLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00004501 case CXCursor_StringLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004502 return cxstring::createRef("StringLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00004503 case CXCursor_CharacterLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004504 return cxstring::createRef("CharacterLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00004505 case CXCursor_ParenExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004506 return cxstring::createRef("ParenExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004507 case CXCursor_UnaryOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004508 return cxstring::createRef("UnaryOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00004509 case CXCursor_ArraySubscriptExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004510 return cxstring::createRef("ArraySubscriptExpr");
Alexey Bataev1a3320e2015-08-25 14:24:04 +00004511 case CXCursor_OMPArraySectionExpr:
4512 return cxstring::createRef("OMPArraySectionExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004513 case CXCursor_BinaryOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004514 return cxstring::createRef("BinaryOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00004515 case CXCursor_CompoundAssignOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004516 return cxstring::createRef("CompoundAssignOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00004517 case CXCursor_ConditionalOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004518 return cxstring::createRef("ConditionalOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00004519 case CXCursor_CStyleCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004520 return cxstring::createRef("CStyleCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004521 case CXCursor_CompoundLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004522 return cxstring::createRef("CompoundLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004523 case CXCursor_InitListExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004524 return cxstring::createRef("InitListExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004525 case CXCursor_AddrLabelExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004526 return cxstring::createRef("AddrLabelExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004527 case CXCursor_StmtExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004528 return cxstring::createRef("StmtExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004529 case CXCursor_GenericSelectionExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004530 return cxstring::createRef("GenericSelectionExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004531 case CXCursor_GNUNullExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004532 return cxstring::createRef("GNUNullExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004533 case CXCursor_CXXStaticCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004534 return cxstring::createRef("CXXStaticCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004535 case CXCursor_CXXDynamicCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004536 return cxstring::createRef("CXXDynamicCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004537 case CXCursor_CXXReinterpretCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004538 return cxstring::createRef("CXXReinterpretCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004539 case CXCursor_CXXConstCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004540 return cxstring::createRef("CXXConstCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004541 case CXCursor_CXXFunctionalCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004542 return cxstring::createRef("CXXFunctionalCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004543 case CXCursor_CXXTypeidExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004544 return cxstring::createRef("CXXTypeidExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004545 case CXCursor_CXXBoolLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004546 return cxstring::createRef("CXXBoolLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004547 case CXCursor_CXXNullPtrLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004548 return cxstring::createRef("CXXNullPtrLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004549 case CXCursor_CXXThisExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004550 return cxstring::createRef("CXXThisExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004551 case CXCursor_CXXThrowExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004552 return cxstring::createRef("CXXThrowExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004553 case CXCursor_CXXNewExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004554 return cxstring::createRef("CXXNewExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004555 case CXCursor_CXXDeleteExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004556 return cxstring::createRef("CXXDeleteExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004557 case CXCursor_UnaryExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004558 return cxstring::createRef("UnaryExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004559 case CXCursor_ObjCStringLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004560 return cxstring::createRef("ObjCStringLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00004561 case CXCursor_ObjCBoolLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004562 return cxstring::createRef("ObjCBoolLiteralExpr");
Argyrios Kyrtzidisc2233be2013-04-23 17:57:17 +00004563 case CXCursor_ObjCSelfExpr:
4564 return cxstring::createRef("ObjCSelfExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004565 case CXCursor_ObjCEncodeExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004566 return cxstring::createRef("ObjCEncodeExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004567 case CXCursor_ObjCSelectorExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004568 return cxstring::createRef("ObjCSelectorExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004569 case CXCursor_ObjCProtocolExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004570 return cxstring::createRef("ObjCProtocolExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004571 case CXCursor_ObjCBridgedCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004572 return cxstring::createRef("ObjCBridgedCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004573 case CXCursor_BlockExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004574 return cxstring::createRef("BlockExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004575 case CXCursor_PackExpansionExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004576 return cxstring::createRef("PackExpansionExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004577 case CXCursor_SizeOfPackExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004578 return cxstring::createRef("SizeOfPackExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004579 case CXCursor_LambdaExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004580 return cxstring::createRef("LambdaExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004581 case CXCursor_UnexposedExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004582 return cxstring::createRef("UnexposedExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004583 case CXCursor_DeclRefExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004584 return cxstring::createRef("DeclRefExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004585 case CXCursor_MemberRefExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004586 return cxstring::createRef("MemberRefExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004587 case CXCursor_CallExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004588 return cxstring::createRef("CallExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004589 case CXCursor_ObjCMessageExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004590 return cxstring::createRef("ObjCMessageExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004591 case CXCursor_UnexposedStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004592 return cxstring::createRef("UnexposedStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004593 case CXCursor_DeclStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004594 return cxstring::createRef("DeclStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004595 case CXCursor_LabelStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004596 return cxstring::createRef("LabelStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004597 case CXCursor_CompoundStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004598 return cxstring::createRef("CompoundStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004599 case CXCursor_CaseStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004600 return cxstring::createRef("CaseStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004601 case CXCursor_DefaultStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004602 return cxstring::createRef("DefaultStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004603 case CXCursor_IfStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004604 return cxstring::createRef("IfStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004605 case CXCursor_SwitchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004606 return cxstring::createRef("SwitchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004607 case CXCursor_WhileStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004608 return cxstring::createRef("WhileStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004609 case CXCursor_DoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004610 return cxstring::createRef("DoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004611 case CXCursor_ForStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004612 return cxstring::createRef("ForStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004613 case CXCursor_GotoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004614 return cxstring::createRef("GotoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004615 case CXCursor_IndirectGotoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004616 return cxstring::createRef("IndirectGotoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004617 case CXCursor_ContinueStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004618 return cxstring::createRef("ContinueStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004619 case CXCursor_BreakStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004620 return cxstring::createRef("BreakStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004621 case CXCursor_ReturnStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004622 return cxstring::createRef("ReturnStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004623 case CXCursor_GCCAsmStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004624 return cxstring::createRef("GCCAsmStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004625 case CXCursor_MSAsmStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004626 return cxstring::createRef("MSAsmStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004627 case CXCursor_ObjCAtTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004628 return cxstring::createRef("ObjCAtTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004629 case CXCursor_ObjCAtCatchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004630 return cxstring::createRef("ObjCAtCatchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004631 case CXCursor_ObjCAtFinallyStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004632 return cxstring::createRef("ObjCAtFinallyStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004633 case CXCursor_ObjCAtThrowStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004634 return cxstring::createRef("ObjCAtThrowStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004635 case CXCursor_ObjCAtSynchronizedStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004636 return cxstring::createRef("ObjCAtSynchronizedStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004637 case CXCursor_ObjCAutoreleasePoolStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004638 return cxstring::createRef("ObjCAutoreleasePoolStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004639 case CXCursor_ObjCForCollectionStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004640 return cxstring::createRef("ObjCForCollectionStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004641 case CXCursor_CXXCatchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004642 return cxstring::createRef("CXXCatchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004643 case CXCursor_CXXTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004644 return cxstring::createRef("CXXTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004645 case CXCursor_CXXForRangeStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004646 return cxstring::createRef("CXXForRangeStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004647 case CXCursor_SEHTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004648 return cxstring::createRef("SEHTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004649 case CXCursor_SEHExceptStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004650 return cxstring::createRef("SEHExceptStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004651 case CXCursor_SEHFinallyStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004652 return cxstring::createRef("SEHFinallyStmt");
Nico Weber9b982072014-07-07 00:12:30 +00004653 case CXCursor_SEHLeaveStmt:
4654 return cxstring::createRef("SEHLeaveStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004655 case CXCursor_NullStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004656 return cxstring::createRef("NullStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004657 case CXCursor_InvalidFile:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004658 return cxstring::createRef("InvalidFile");
Guy Benyei11169dd2012-12-18 14:30:41 +00004659 case CXCursor_InvalidCode:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004660 return cxstring::createRef("InvalidCode");
Guy Benyei11169dd2012-12-18 14:30:41 +00004661 case CXCursor_NoDeclFound:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004662 return cxstring::createRef("NoDeclFound");
Guy Benyei11169dd2012-12-18 14:30:41 +00004663 case CXCursor_NotImplemented:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004664 return cxstring::createRef("NotImplemented");
Guy Benyei11169dd2012-12-18 14:30:41 +00004665 case CXCursor_TranslationUnit:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004666 return cxstring::createRef("TranslationUnit");
Guy Benyei11169dd2012-12-18 14:30:41 +00004667 case CXCursor_UnexposedAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004668 return cxstring::createRef("UnexposedAttr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004669 case CXCursor_IBActionAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004670 return cxstring::createRef("attribute(ibaction)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004671 case CXCursor_IBOutletAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004672 return cxstring::createRef("attribute(iboutlet)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004673 case CXCursor_IBOutletCollectionAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004674 return cxstring::createRef("attribute(iboutletcollection)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004675 case CXCursor_CXXFinalAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004676 return cxstring::createRef("attribute(final)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004677 case CXCursor_CXXOverrideAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004678 return cxstring::createRef("attribute(override)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004679 case CXCursor_AnnotateAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004680 return cxstring::createRef("attribute(annotate)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004681 case CXCursor_AsmLabelAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004682 return cxstring::createRef("asm label");
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00004683 case CXCursor_PackedAttr:
4684 return cxstring::createRef("attribute(packed)");
Joey Gouly81228382014-05-01 15:41:58 +00004685 case CXCursor_PureAttr:
4686 return cxstring::createRef("attribute(pure)");
4687 case CXCursor_ConstAttr:
4688 return cxstring::createRef("attribute(const)");
4689 case CXCursor_NoDuplicateAttr:
4690 return cxstring::createRef("attribute(noduplicate)");
Eli Bendersky2581e662014-05-28 19:29:58 +00004691 case CXCursor_CUDAConstantAttr:
4692 return cxstring::createRef("attribute(constant)");
4693 case CXCursor_CUDADeviceAttr:
4694 return cxstring::createRef("attribute(device)");
4695 case CXCursor_CUDAGlobalAttr:
4696 return cxstring::createRef("attribute(global)");
4697 case CXCursor_CUDAHostAttr:
4698 return cxstring::createRef("attribute(host)");
Eli Bendersky9b071472014-08-08 14:59:00 +00004699 case CXCursor_CUDASharedAttr:
4700 return cxstring::createRef("attribute(shared)");
Saleem Abdulrasool79c69712015-09-05 18:53:43 +00004701 case CXCursor_VisibilityAttr:
4702 return cxstring::createRef("attribute(visibility)");
Saleem Abdulrasool8aa0b802015-12-10 18:45:18 +00004703 case CXCursor_DLLExport:
4704 return cxstring::createRef("attribute(dllexport)");
4705 case CXCursor_DLLImport:
4706 return cxstring::createRef("attribute(dllimport)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004707 case CXCursor_PreprocessingDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004708 return cxstring::createRef("preprocessing directive");
Guy Benyei11169dd2012-12-18 14:30:41 +00004709 case CXCursor_MacroDefinition:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004710 return cxstring::createRef("macro definition");
Guy Benyei11169dd2012-12-18 14:30:41 +00004711 case CXCursor_MacroExpansion:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004712 return cxstring::createRef("macro expansion");
Guy Benyei11169dd2012-12-18 14:30:41 +00004713 case CXCursor_InclusionDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004714 return cxstring::createRef("inclusion directive");
Guy Benyei11169dd2012-12-18 14:30:41 +00004715 case CXCursor_Namespace:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004716 return cxstring::createRef("Namespace");
Guy Benyei11169dd2012-12-18 14:30:41 +00004717 case CXCursor_LinkageSpec:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004718 return cxstring::createRef("LinkageSpec");
Guy Benyei11169dd2012-12-18 14:30:41 +00004719 case CXCursor_CXXBaseSpecifier:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004720 return cxstring::createRef("C++ base class specifier");
Guy Benyei11169dd2012-12-18 14:30:41 +00004721 case CXCursor_Constructor:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004722 return cxstring::createRef("CXXConstructor");
Guy Benyei11169dd2012-12-18 14:30:41 +00004723 case CXCursor_Destructor:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004724 return cxstring::createRef("CXXDestructor");
Guy Benyei11169dd2012-12-18 14:30:41 +00004725 case CXCursor_ConversionFunction:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004726 return cxstring::createRef("CXXConversion");
Guy Benyei11169dd2012-12-18 14:30:41 +00004727 case CXCursor_TemplateTypeParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004728 return cxstring::createRef("TemplateTypeParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00004729 case CXCursor_NonTypeTemplateParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004730 return cxstring::createRef("NonTypeTemplateParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00004731 case CXCursor_TemplateTemplateParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004732 return cxstring::createRef("TemplateTemplateParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00004733 case CXCursor_FunctionTemplate:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004734 return cxstring::createRef("FunctionTemplate");
Guy Benyei11169dd2012-12-18 14:30:41 +00004735 case CXCursor_ClassTemplate:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004736 return cxstring::createRef("ClassTemplate");
Guy Benyei11169dd2012-12-18 14:30:41 +00004737 case CXCursor_ClassTemplatePartialSpecialization:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004738 return cxstring::createRef("ClassTemplatePartialSpecialization");
Guy Benyei11169dd2012-12-18 14:30:41 +00004739 case CXCursor_NamespaceAlias:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004740 return cxstring::createRef("NamespaceAlias");
Guy Benyei11169dd2012-12-18 14:30:41 +00004741 case CXCursor_UsingDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004742 return cxstring::createRef("UsingDirective");
Guy Benyei11169dd2012-12-18 14:30:41 +00004743 case CXCursor_UsingDeclaration:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004744 return cxstring::createRef("UsingDeclaration");
Guy Benyei11169dd2012-12-18 14:30:41 +00004745 case CXCursor_TypeAliasDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004746 return cxstring::createRef("TypeAliasDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004747 case CXCursor_ObjCSynthesizeDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004748 return cxstring::createRef("ObjCSynthesizeDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004749 case CXCursor_ObjCDynamicDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004750 return cxstring::createRef("ObjCDynamicDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004751 case CXCursor_CXXAccessSpecifier:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004752 return cxstring::createRef("CXXAccessSpecifier");
Guy Benyei11169dd2012-12-18 14:30:41 +00004753 case CXCursor_ModuleImportDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004754 return cxstring::createRef("ModuleImport");
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00004755 case CXCursor_OMPParallelDirective:
Alexey Bataev1b59ab52014-02-27 08:29:12 +00004756 return cxstring::createRef("OMPParallelDirective");
4757 case CXCursor_OMPSimdDirective:
4758 return cxstring::createRef("OMPSimdDirective");
Alexey Bataevf29276e2014-06-18 04:14:57 +00004759 case CXCursor_OMPForDirective:
4760 return cxstring::createRef("OMPForDirective");
Alexander Musmanf82886e2014-09-18 05:12:34 +00004761 case CXCursor_OMPForSimdDirective:
4762 return cxstring::createRef("OMPForSimdDirective");
Alexey Bataevd3f8dd22014-06-25 11:44:49 +00004763 case CXCursor_OMPSectionsDirective:
4764 return cxstring::createRef("OMPSectionsDirective");
Alexey Bataev1e0498a2014-06-26 08:21:58 +00004765 case CXCursor_OMPSectionDirective:
4766 return cxstring::createRef("OMPSectionDirective");
Alexey Bataevd1e40fb2014-06-26 12:05:45 +00004767 case CXCursor_OMPSingleDirective:
4768 return cxstring::createRef("OMPSingleDirective");
Alexander Musman80c22892014-07-17 08:54:58 +00004769 case CXCursor_OMPMasterDirective:
4770 return cxstring::createRef("OMPMasterDirective");
Alexander Musmand9ed09f2014-07-21 09:42:05 +00004771 case CXCursor_OMPCriticalDirective:
4772 return cxstring::createRef("OMPCriticalDirective");
Alexey Bataev4acb8592014-07-07 13:01:15 +00004773 case CXCursor_OMPParallelForDirective:
4774 return cxstring::createRef("OMPParallelForDirective");
Alexander Musmane4e893b2014-09-23 09:33:00 +00004775 case CXCursor_OMPParallelForSimdDirective:
4776 return cxstring::createRef("OMPParallelForSimdDirective");
Alexey Bataev84d0b3e2014-07-08 08:12:03 +00004777 case CXCursor_OMPParallelSectionsDirective:
4778 return cxstring::createRef("OMPParallelSectionsDirective");
Alexey Bataev9c2e8ee2014-07-11 11:25:16 +00004779 case CXCursor_OMPTaskDirective:
4780 return cxstring::createRef("OMPTaskDirective");
Alexey Bataev68446b72014-07-18 07:47:19 +00004781 case CXCursor_OMPTaskyieldDirective:
4782 return cxstring::createRef("OMPTaskyieldDirective");
Alexey Bataev4d1dfea2014-07-18 09:11:51 +00004783 case CXCursor_OMPBarrierDirective:
4784 return cxstring::createRef("OMPBarrierDirective");
Alexey Bataev2df347a2014-07-18 10:17:07 +00004785 case CXCursor_OMPTaskwaitDirective:
4786 return cxstring::createRef("OMPTaskwaitDirective");
Alexey Bataevc30dd2d2015-06-18 12:14:09 +00004787 case CXCursor_OMPTaskgroupDirective:
4788 return cxstring::createRef("OMPTaskgroupDirective");
Alexey Bataev6125da92014-07-21 11:26:11 +00004789 case CXCursor_OMPFlushDirective:
4790 return cxstring::createRef("OMPFlushDirective");
Alexey Bataev9fb6e642014-07-22 06:45:04 +00004791 case CXCursor_OMPOrderedDirective:
4792 return cxstring::createRef("OMPOrderedDirective");
Alexey Bataev0162e452014-07-22 10:10:35 +00004793 case CXCursor_OMPAtomicDirective:
4794 return cxstring::createRef("OMPAtomicDirective");
Alexey Bataev0bd520b2014-09-19 08:19:49 +00004795 case CXCursor_OMPTargetDirective:
4796 return cxstring::createRef("OMPTargetDirective");
Michael Wong65f367f2015-07-21 13:44:28 +00004797 case CXCursor_OMPTargetDataDirective:
4798 return cxstring::createRef("OMPTargetDataDirective");
Samuel Antaodf67fc42016-01-19 19:15:56 +00004799 case CXCursor_OMPTargetEnterDataDirective:
4800 return cxstring::createRef("OMPTargetEnterDataDirective");
Samuel Antao72590762016-01-19 20:04:50 +00004801 case CXCursor_OMPTargetExitDataDirective:
4802 return cxstring::createRef("OMPTargetExitDataDirective");
Arpith Chacko Jacobe955b3d2016-01-26 18:48:41 +00004803 case CXCursor_OMPTargetParallelDirective:
4804 return cxstring::createRef("OMPTargetParallelDirective");
Arpith Chacko Jacob05bebb52016-02-03 15:46:42 +00004805 case CXCursor_OMPTargetParallelForDirective:
4806 return cxstring::createRef("OMPTargetParallelForDirective");
Samuel Antao686c70c2016-05-26 17:30:50 +00004807 case CXCursor_OMPTargetUpdateDirective:
4808 return cxstring::createRef("OMPTargetUpdateDirective");
Alexey Bataev13314bf2014-10-09 04:18:56 +00004809 case CXCursor_OMPTeamsDirective:
4810 return cxstring::createRef("OMPTeamsDirective");
Alexey Bataev6d4ed052015-07-01 06:57:41 +00004811 case CXCursor_OMPCancellationPointDirective:
4812 return cxstring::createRef("OMPCancellationPointDirective");
Alexey Bataev80909872015-07-02 11:25:17 +00004813 case CXCursor_OMPCancelDirective:
4814 return cxstring::createRef("OMPCancelDirective");
Alexey Bataev49f6e782015-12-01 04:18:41 +00004815 case CXCursor_OMPTaskLoopDirective:
4816 return cxstring::createRef("OMPTaskLoopDirective");
Alexey Bataev0a6ed842015-12-03 09:40:15 +00004817 case CXCursor_OMPTaskLoopSimdDirective:
4818 return cxstring::createRef("OMPTaskLoopSimdDirective");
Carlo Bertolli6200a3d2015-12-14 14:51:25 +00004819 case CXCursor_OMPDistributeDirective:
4820 return cxstring::createRef("OMPDistributeDirective");
Francisco Lopes da Silva975a9f62015-01-21 16:24:11 +00004821 case CXCursor_OverloadCandidate:
4822 return cxstring::createRef("OverloadCandidate");
Sergey Kalinichev8f3b1872015-11-15 13:48:32 +00004823 case CXCursor_TypeAliasTemplateDecl:
4824 return cxstring::createRef("TypeAliasTemplateDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004825 }
4826
4827 llvm_unreachable("Unhandled CXCursorKind");
4828}
4829
4830struct GetCursorData {
4831 SourceLocation TokenBeginLoc;
4832 bool PointsAtMacroArgExpansion;
4833 bool VisitedObjCPropertyImplDecl;
4834 SourceLocation VisitedDeclaratorDeclStartLoc;
4835 CXCursor &BestCursor;
4836
4837 GetCursorData(SourceManager &SM,
4838 SourceLocation tokenBegin, CXCursor &outputCursor)
4839 : TokenBeginLoc(tokenBegin), BestCursor(outputCursor) {
4840 PointsAtMacroArgExpansion = SM.isMacroArgExpansion(tokenBegin);
4841 VisitedObjCPropertyImplDecl = false;
4842 }
4843};
4844
4845static enum CXChildVisitResult GetCursorVisitor(CXCursor cursor,
4846 CXCursor parent,
4847 CXClientData client_data) {
4848 GetCursorData *Data = static_cast<GetCursorData *>(client_data);
4849 CXCursor *BestCursor = &Data->BestCursor;
4850
4851 // If we point inside a macro argument we should provide info of what the
4852 // token is so use the actual cursor, don't replace it with a macro expansion
4853 // cursor.
4854 if (cursor.kind == CXCursor_MacroExpansion && Data->PointsAtMacroArgExpansion)
4855 return CXChildVisit_Recurse;
4856
4857 if (clang_isDeclaration(cursor.kind)) {
4858 // Avoid having the implicit methods override the property decls.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004859 if (const ObjCMethodDecl *MD
Guy Benyei11169dd2012-12-18 14:30:41 +00004860 = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
4861 if (MD->isImplicit())
4862 return CXChildVisit_Break;
4863
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004864 } else if (const ObjCInterfaceDecl *ID
Guy Benyei11169dd2012-12-18 14:30:41 +00004865 = dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(cursor))) {
4866 // Check that when we have multiple @class references in the same line,
4867 // that later ones do not override the previous ones.
4868 // If we have:
4869 // @class Foo, Bar;
4870 // source ranges for both start at '@', so 'Bar' will end up overriding
4871 // 'Foo' even though the cursor location was at 'Foo'.
4872 if (BestCursor->kind == CXCursor_ObjCInterfaceDecl ||
4873 BestCursor->kind == CXCursor_ObjCClassRef)
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004874 if (const ObjCInterfaceDecl *PrevID
Guy Benyei11169dd2012-12-18 14:30:41 +00004875 = dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(*BestCursor))){
4876 if (PrevID != ID &&
4877 !PrevID->isThisDeclarationADefinition() &&
4878 !ID->isThisDeclarationADefinition())
4879 return CXChildVisit_Break;
4880 }
4881
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004882 } else if (const DeclaratorDecl *DD
Guy Benyei11169dd2012-12-18 14:30:41 +00004883 = dyn_cast_or_null<DeclaratorDecl>(getCursorDecl(cursor))) {
4884 SourceLocation StartLoc = DD->getSourceRange().getBegin();
4885 // Check that when we have multiple declarators in the same line,
4886 // that later ones do not override the previous ones.
4887 // If we have:
4888 // int Foo, Bar;
4889 // source ranges for both start at 'int', so 'Bar' will end up overriding
4890 // 'Foo' even though the cursor location was at 'Foo'.
4891 if (Data->VisitedDeclaratorDeclStartLoc == StartLoc)
4892 return CXChildVisit_Break;
4893 Data->VisitedDeclaratorDeclStartLoc = StartLoc;
4894
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004895 } else if (const ObjCPropertyImplDecl *PropImp
Guy Benyei11169dd2012-12-18 14:30:41 +00004896 = dyn_cast_or_null<ObjCPropertyImplDecl>(getCursorDecl(cursor))) {
4897 (void)PropImp;
4898 // Check that when we have multiple @synthesize in the same line,
4899 // that later ones do not override the previous ones.
4900 // If we have:
4901 // @synthesize Foo, Bar;
4902 // source ranges for both start at '@', so 'Bar' will end up overriding
4903 // 'Foo' even though the cursor location was at 'Foo'.
4904 if (Data->VisitedObjCPropertyImplDecl)
4905 return CXChildVisit_Break;
4906 Data->VisitedObjCPropertyImplDecl = true;
4907 }
4908 }
4909
4910 if (clang_isExpression(cursor.kind) &&
4911 clang_isDeclaration(BestCursor->kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004912 if (const Decl *D = getCursorDecl(*BestCursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004913 // Avoid having the cursor of an expression replace the declaration cursor
4914 // when the expression source range overlaps the declaration range.
4915 // This can happen for C++ constructor expressions whose range generally
4916 // include the variable declaration, e.g.:
4917 // MyCXXClass foo; // Make sure pointing at 'foo' returns a VarDecl cursor.
4918 if (D->getLocation().isValid() && Data->TokenBeginLoc.isValid() &&
4919 D->getLocation() == Data->TokenBeginLoc)
4920 return CXChildVisit_Break;
4921 }
4922 }
4923
4924 // If our current best cursor is the construction of a temporary object,
4925 // don't replace that cursor with a type reference, because we want
4926 // clang_getCursor() to point at the constructor.
4927 if (clang_isExpression(BestCursor->kind) &&
4928 isa<CXXTemporaryObjectExpr>(getCursorExpr(*BestCursor)) &&
4929 cursor.kind == CXCursor_TypeRef) {
4930 // Keep the cursor pointing at CXXTemporaryObjectExpr but also mark it
4931 // as having the actual point on the type reference.
4932 *BestCursor = getTypeRefedCallExprCursor(*BestCursor);
4933 return CXChildVisit_Recurse;
4934 }
Douglas Gregore9d95f12015-07-07 03:57:35 +00004935
4936 // If we already have an Objective-C superclass reference, don't
4937 // update it further.
4938 if (BestCursor->kind == CXCursor_ObjCSuperClassRef)
4939 return CXChildVisit_Break;
4940
Guy Benyei11169dd2012-12-18 14:30:41 +00004941 *BestCursor = cursor;
4942 return CXChildVisit_Recurse;
4943}
4944
4945CXCursor clang_getCursor(CXTranslationUnit TU, CXSourceLocation Loc) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00004946 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004947 LOG_BAD_TU(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004948 return clang_getNullCursor();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004949 }
Guy Benyei11169dd2012-12-18 14:30:41 +00004950
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004951 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004952 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
4953
4954 SourceLocation SLoc = cxloc::translateSourceLocation(Loc);
4955 CXCursor Result = cxcursor::getCursor(TU, SLoc);
4956
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004957 LOG_FUNC_SECTION {
Guy Benyei11169dd2012-12-18 14:30:41 +00004958 CXFile SearchFile;
4959 unsigned SearchLine, SearchColumn;
4960 CXFile ResultFile;
4961 unsigned ResultLine, ResultColumn;
4962 CXString SearchFileName, ResultFileName, KindSpelling, USR;
4963 const char *IsDef = clang_isCursorDefinition(Result)? " (Definition)" : "";
4964 CXSourceLocation ResultLoc = clang_getCursorLocation(Result);
Craig Topper69186e72014-06-08 08:38:04 +00004965
4966 clang_getFileLocation(Loc, &SearchFile, &SearchLine, &SearchColumn,
4967 nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004968 clang_getFileLocation(ResultLoc, &ResultFile, &ResultLine,
Craig Topper69186e72014-06-08 08:38:04 +00004969 &ResultColumn, nullptr);
Guy Benyei11169dd2012-12-18 14:30:41 +00004970 SearchFileName = clang_getFileName(SearchFile);
4971 ResultFileName = clang_getFileName(ResultFile);
4972 KindSpelling = clang_getCursorKindSpelling(Result.kind);
4973 USR = clang_getCursorUSR(Result);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004974 *Log << llvm::format("(%s:%d:%d) = %s",
4975 clang_getCString(SearchFileName), SearchLine, SearchColumn,
4976 clang_getCString(KindSpelling))
4977 << llvm::format("(%s:%d:%d):%s%s",
4978 clang_getCString(ResultFileName), ResultLine, ResultColumn,
4979 clang_getCString(USR), IsDef);
Guy Benyei11169dd2012-12-18 14:30:41 +00004980 clang_disposeString(SearchFileName);
4981 clang_disposeString(ResultFileName);
4982 clang_disposeString(KindSpelling);
4983 clang_disposeString(USR);
4984
4985 CXCursor Definition = clang_getCursorDefinition(Result);
4986 if (!clang_equalCursors(Definition, clang_getNullCursor())) {
4987 CXSourceLocation DefinitionLoc = clang_getCursorLocation(Definition);
4988 CXString DefinitionKindSpelling
4989 = clang_getCursorKindSpelling(Definition.kind);
4990 CXFile DefinitionFile;
4991 unsigned DefinitionLine, DefinitionColumn;
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004992 clang_getFileLocation(DefinitionLoc, &DefinitionFile,
Craig Topper69186e72014-06-08 08:38:04 +00004993 &DefinitionLine, &DefinitionColumn, nullptr);
Guy Benyei11169dd2012-12-18 14:30:41 +00004994 CXString DefinitionFileName = clang_getFileName(DefinitionFile);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004995 *Log << llvm::format(" -> %s(%s:%d:%d)",
4996 clang_getCString(DefinitionKindSpelling),
4997 clang_getCString(DefinitionFileName),
4998 DefinitionLine, DefinitionColumn);
Guy Benyei11169dd2012-12-18 14:30:41 +00004999 clang_disposeString(DefinitionFileName);
5000 clang_disposeString(DefinitionKindSpelling);
5001 }
5002 }
5003
5004 return Result;
5005}
5006
5007CXCursor clang_getNullCursor(void) {
5008 return MakeCXCursorInvalid(CXCursor_InvalidFile);
5009}
5010
5011unsigned clang_equalCursors(CXCursor X, CXCursor Y) {
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00005012 // Clear out the "FirstInDeclGroup" part in a declaration cursor, since we
5013 // can't set consistently. For example, when visiting a DeclStmt we will set
5014 // it but we don't set it on the result of clang_getCursorDefinition for
5015 // a reference of the same declaration.
5016 // FIXME: Setting "FirstInDeclGroup" in CXCursors is a hack that only works
5017 // when visiting a DeclStmt currently, the AST should be enhanced to be able
5018 // to provide that kind of info.
5019 if (clang_isDeclaration(X.kind))
Craig Topper69186e72014-06-08 08:38:04 +00005020 X.data[1] = nullptr;
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00005021 if (clang_isDeclaration(Y.kind))
Craig Topper69186e72014-06-08 08:38:04 +00005022 Y.data[1] = nullptr;
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00005023
Guy Benyei11169dd2012-12-18 14:30:41 +00005024 return X == Y;
5025}
5026
5027unsigned clang_hashCursor(CXCursor C) {
5028 unsigned Index = 0;
5029 if (clang_isExpression(C.kind) || clang_isStatement(C.kind))
5030 Index = 1;
5031
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005032 return llvm::DenseMapInfo<std::pair<unsigned, const void*> >::getHashValue(
Guy Benyei11169dd2012-12-18 14:30:41 +00005033 std::make_pair(C.kind, C.data[Index]));
5034}
5035
5036unsigned clang_isInvalid(enum CXCursorKind K) {
5037 return K >= CXCursor_FirstInvalid && K <= CXCursor_LastInvalid;
5038}
5039
5040unsigned clang_isDeclaration(enum CXCursorKind K) {
5041 return (K >= CXCursor_FirstDecl && K <= CXCursor_LastDecl) ||
5042 (K >= CXCursor_FirstExtraDecl && K <= CXCursor_LastExtraDecl);
5043}
5044
5045unsigned clang_isReference(enum CXCursorKind K) {
5046 return K >= CXCursor_FirstRef && K <= CXCursor_LastRef;
5047}
5048
5049unsigned clang_isExpression(enum CXCursorKind K) {
5050 return K >= CXCursor_FirstExpr && K <= CXCursor_LastExpr;
5051}
5052
5053unsigned clang_isStatement(enum CXCursorKind K) {
5054 return K >= CXCursor_FirstStmt && K <= CXCursor_LastStmt;
5055}
5056
5057unsigned clang_isAttribute(enum CXCursorKind K) {
5058 return K >= CXCursor_FirstAttr && K <= CXCursor_LastAttr;
5059}
5060
5061unsigned clang_isTranslationUnit(enum CXCursorKind K) {
5062 return K == CXCursor_TranslationUnit;
5063}
5064
5065unsigned clang_isPreprocessing(enum CXCursorKind K) {
5066 return K >= CXCursor_FirstPreprocessing && K <= CXCursor_LastPreprocessing;
5067}
5068
5069unsigned clang_isUnexposed(enum CXCursorKind K) {
5070 switch (K) {
5071 case CXCursor_UnexposedDecl:
5072 case CXCursor_UnexposedExpr:
5073 case CXCursor_UnexposedStmt:
5074 case CXCursor_UnexposedAttr:
5075 return true;
5076 default:
5077 return false;
5078 }
5079}
5080
5081CXCursorKind clang_getCursorKind(CXCursor C) {
5082 return C.kind;
5083}
5084
5085CXSourceLocation clang_getCursorLocation(CXCursor C) {
5086 if (clang_isReference(C.kind)) {
5087 switch (C.kind) {
5088 case CXCursor_ObjCSuperClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005089 std::pair<const ObjCInterfaceDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00005090 = getCursorObjCSuperClassRef(C);
5091 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
5092 }
5093
5094 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005095 std::pair<const ObjCProtocolDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00005096 = getCursorObjCProtocolRef(C);
5097 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
5098 }
5099
5100 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005101 std::pair<const ObjCInterfaceDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00005102 = getCursorObjCClassRef(C);
5103 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
5104 }
5105
5106 case CXCursor_TypeRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005107 std::pair<const TypeDecl *, SourceLocation> P = getCursorTypeRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005108 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
5109 }
5110
5111 case CXCursor_TemplateRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005112 std::pair<const TemplateDecl *, SourceLocation> P =
5113 getCursorTemplateRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005114 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
5115 }
5116
5117 case CXCursor_NamespaceRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005118 std::pair<const NamedDecl *, SourceLocation> P = getCursorNamespaceRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005119 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
5120 }
5121
5122 case CXCursor_MemberRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005123 std::pair<const FieldDecl *, SourceLocation> P = getCursorMemberRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005124 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
5125 }
5126
5127 case CXCursor_VariableRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005128 std::pair<const VarDecl *, SourceLocation> P = getCursorVariableRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005129 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
5130 }
5131
5132 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005133 const CXXBaseSpecifier *BaseSpec = getCursorCXXBaseSpecifier(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005134 if (!BaseSpec)
5135 return clang_getNullLocation();
5136
5137 if (TypeSourceInfo *TSInfo = BaseSpec->getTypeSourceInfo())
5138 return cxloc::translateSourceLocation(getCursorContext(C),
5139 TSInfo->getTypeLoc().getBeginLoc());
5140
5141 return cxloc::translateSourceLocation(getCursorContext(C),
5142 BaseSpec->getLocStart());
5143 }
5144
5145 case CXCursor_LabelRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005146 std::pair<const LabelStmt *, SourceLocation> P = getCursorLabelRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005147 return cxloc::translateSourceLocation(getCursorContext(C), P.second);
5148 }
5149
5150 case CXCursor_OverloadedDeclRef:
5151 return cxloc::translateSourceLocation(getCursorContext(C),
5152 getCursorOverloadedDeclRef(C).second);
5153
5154 default:
5155 // FIXME: Need a way to enumerate all non-reference cases.
5156 llvm_unreachable("Missed a reference kind");
5157 }
5158 }
5159
5160 if (clang_isExpression(C.kind))
5161 return cxloc::translateSourceLocation(getCursorContext(C),
5162 getLocationFromExpr(getCursorExpr(C)));
5163
5164 if (clang_isStatement(C.kind))
5165 return cxloc::translateSourceLocation(getCursorContext(C),
5166 getCursorStmt(C)->getLocStart());
5167
5168 if (C.kind == CXCursor_PreprocessingDirective) {
5169 SourceLocation L = cxcursor::getCursorPreprocessingDirective(C).getBegin();
5170 return cxloc::translateSourceLocation(getCursorContext(C), L);
5171 }
5172
5173 if (C.kind == CXCursor_MacroExpansion) {
5174 SourceLocation L
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00005175 = cxcursor::getCursorMacroExpansion(C).getSourceRange().getBegin();
Guy Benyei11169dd2012-12-18 14:30:41 +00005176 return cxloc::translateSourceLocation(getCursorContext(C), L);
5177 }
5178
5179 if (C.kind == CXCursor_MacroDefinition) {
5180 SourceLocation L = cxcursor::getCursorMacroDefinition(C)->getLocation();
5181 return cxloc::translateSourceLocation(getCursorContext(C), L);
5182 }
5183
5184 if (C.kind == CXCursor_InclusionDirective) {
5185 SourceLocation L
5186 = cxcursor::getCursorInclusionDirective(C)->getSourceRange().getBegin();
5187 return cxloc::translateSourceLocation(getCursorContext(C), L);
5188 }
5189
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00005190 if (clang_isAttribute(C.kind)) {
5191 SourceLocation L
5192 = cxcursor::getCursorAttr(C)->getLocation();
5193 return cxloc::translateSourceLocation(getCursorContext(C), L);
5194 }
5195
Guy Benyei11169dd2012-12-18 14:30:41 +00005196 if (!clang_isDeclaration(C.kind))
5197 return clang_getNullLocation();
5198
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005199 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005200 if (!D)
5201 return clang_getNullLocation();
5202
5203 SourceLocation Loc = D->getLocation();
5204 // FIXME: Multiple variables declared in a single declaration
5205 // currently lack the information needed to correctly determine their
5206 // ranges when accounting for the type-specifier. We use context
5207 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
5208 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005209 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005210 if (!cxcursor::isFirstInDeclGroup(C))
5211 Loc = VD->getLocation();
5212 }
5213
5214 // For ObjC methods, give the start location of the method name.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005215 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00005216 Loc = MD->getSelectorStartLoc();
5217
5218 return cxloc::translateSourceLocation(getCursorContext(C), Loc);
5219}
5220
5221} // end extern "C"
5222
5223CXCursor cxcursor::getCursor(CXTranslationUnit TU, SourceLocation SLoc) {
5224 assert(TU);
5225
5226 // Guard against an invalid SourceLocation, or we may assert in one
5227 // of the following calls.
5228 if (SLoc.isInvalid())
5229 return clang_getNullCursor();
5230
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005231 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005232
5233 // Translate the given source location to make it point at the beginning of
5234 // the token under the cursor.
5235 SLoc = Lexer::GetBeginningOfToken(SLoc, CXXUnit->getSourceManager(),
5236 CXXUnit->getASTContext().getLangOpts());
5237
5238 CXCursor Result = MakeCXCursorInvalid(CXCursor_NoDeclFound);
5239 if (SLoc.isValid()) {
5240 GetCursorData ResultData(CXXUnit->getSourceManager(), SLoc, Result);
5241 CursorVisitor CursorVis(TU, GetCursorVisitor, &ResultData,
5242 /*VisitPreprocessorLast=*/true,
5243 /*VisitIncludedEntities=*/false,
5244 SourceLocation(SLoc));
5245 CursorVis.visitFileRegion();
5246 }
5247
5248 return Result;
5249}
5250
5251static SourceRange getRawCursorExtent(CXCursor C) {
5252 if (clang_isReference(C.kind)) {
5253 switch (C.kind) {
5254 case CXCursor_ObjCSuperClassRef:
5255 return getCursorObjCSuperClassRef(C).second;
5256
5257 case CXCursor_ObjCProtocolRef:
5258 return getCursorObjCProtocolRef(C).second;
5259
5260 case CXCursor_ObjCClassRef:
5261 return getCursorObjCClassRef(C).second;
5262
5263 case CXCursor_TypeRef:
5264 return getCursorTypeRef(C).second;
5265
5266 case CXCursor_TemplateRef:
5267 return getCursorTemplateRef(C).second;
5268
5269 case CXCursor_NamespaceRef:
5270 return getCursorNamespaceRef(C).second;
5271
5272 case CXCursor_MemberRef:
5273 return getCursorMemberRef(C).second;
5274
5275 case CXCursor_CXXBaseSpecifier:
5276 return getCursorCXXBaseSpecifier(C)->getSourceRange();
5277
5278 case CXCursor_LabelRef:
5279 return getCursorLabelRef(C).second;
5280
5281 case CXCursor_OverloadedDeclRef:
5282 return getCursorOverloadedDeclRef(C).second;
5283
5284 case CXCursor_VariableRef:
5285 return getCursorVariableRef(C).second;
5286
5287 default:
5288 // FIXME: Need a way to enumerate all non-reference cases.
5289 llvm_unreachable("Missed a reference kind");
5290 }
5291 }
5292
5293 if (clang_isExpression(C.kind))
5294 return getCursorExpr(C)->getSourceRange();
5295
5296 if (clang_isStatement(C.kind))
5297 return getCursorStmt(C)->getSourceRange();
5298
5299 if (clang_isAttribute(C.kind))
5300 return getCursorAttr(C)->getRange();
5301
5302 if (C.kind == CXCursor_PreprocessingDirective)
5303 return cxcursor::getCursorPreprocessingDirective(C);
5304
5305 if (C.kind == CXCursor_MacroExpansion) {
5306 ASTUnit *TU = getCursorASTUnit(C);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00005307 SourceRange Range = cxcursor::getCursorMacroExpansion(C).getSourceRange();
Guy Benyei11169dd2012-12-18 14:30:41 +00005308 return TU->mapRangeFromPreamble(Range);
5309 }
5310
5311 if (C.kind == CXCursor_MacroDefinition) {
5312 ASTUnit *TU = getCursorASTUnit(C);
5313 SourceRange Range = cxcursor::getCursorMacroDefinition(C)->getSourceRange();
5314 return TU->mapRangeFromPreamble(Range);
5315 }
5316
5317 if (C.kind == CXCursor_InclusionDirective) {
5318 ASTUnit *TU = getCursorASTUnit(C);
5319 SourceRange Range = cxcursor::getCursorInclusionDirective(C)->getSourceRange();
5320 return TU->mapRangeFromPreamble(Range);
5321 }
5322
5323 if (C.kind == CXCursor_TranslationUnit) {
5324 ASTUnit *TU = getCursorASTUnit(C);
5325 FileID MainID = TU->getSourceManager().getMainFileID();
5326 SourceLocation Start = TU->getSourceManager().getLocForStartOfFile(MainID);
5327 SourceLocation End = TU->getSourceManager().getLocForEndOfFile(MainID);
5328 return SourceRange(Start, End);
5329 }
5330
5331 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005332 const Decl *D = cxcursor::getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005333 if (!D)
5334 return SourceRange();
5335
5336 SourceRange R = D->getSourceRange();
5337 // FIXME: Multiple variables declared in a single declaration
5338 // currently lack the information needed to correctly determine their
5339 // ranges when accounting for the type-specifier. We use context
5340 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
5341 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005342 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005343 if (!cxcursor::isFirstInDeclGroup(C))
5344 R.setBegin(VD->getLocation());
5345 }
5346 return R;
5347 }
5348 return SourceRange();
5349}
5350
5351/// \brief Retrieves the "raw" cursor extent, which is then extended to include
5352/// the decl-specifier-seq for declarations.
5353static SourceRange getFullCursorExtent(CXCursor C, SourceManager &SrcMgr) {
5354 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005355 const Decl *D = cxcursor::getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005356 if (!D)
5357 return SourceRange();
5358
5359 SourceRange R = D->getSourceRange();
5360
5361 // Adjust the start of the location for declarations preceded by
5362 // declaration specifiers.
5363 SourceLocation StartLoc;
5364 if (const DeclaratorDecl *DD = dyn_cast<DeclaratorDecl>(D)) {
5365 if (TypeSourceInfo *TI = DD->getTypeSourceInfo())
5366 StartLoc = TI->getTypeLoc().getLocStart();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005367 } else if (const TypedefDecl *Typedef = dyn_cast<TypedefDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005368 if (TypeSourceInfo *TI = Typedef->getTypeSourceInfo())
5369 StartLoc = TI->getTypeLoc().getLocStart();
5370 }
5371
5372 if (StartLoc.isValid() && R.getBegin().isValid() &&
5373 SrcMgr.isBeforeInTranslationUnit(StartLoc, R.getBegin()))
5374 R.setBegin(StartLoc);
5375
5376 // FIXME: Multiple variables declared in a single declaration
5377 // currently lack the information needed to correctly determine their
5378 // ranges when accounting for the type-specifier. We use context
5379 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
5380 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005381 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005382 if (!cxcursor::isFirstInDeclGroup(C))
5383 R.setBegin(VD->getLocation());
5384 }
5385
5386 return R;
5387 }
5388
5389 return getRawCursorExtent(C);
5390}
5391
5392extern "C" {
5393
5394CXSourceRange clang_getCursorExtent(CXCursor C) {
5395 SourceRange R = getRawCursorExtent(C);
5396 if (R.isInvalid())
5397 return clang_getNullRange();
5398
5399 return cxloc::translateSourceRange(getCursorContext(C), R);
5400}
5401
5402CXCursor clang_getCursorReferenced(CXCursor C) {
5403 if (clang_isInvalid(C.kind))
5404 return clang_getNullCursor();
5405
5406 CXTranslationUnit tu = getCursorTU(C);
5407 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005408 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005409 if (!D)
5410 return clang_getNullCursor();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005411 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00005412 return MakeCursorOverloadedDeclRef(Using, D->getLocation(), tu);
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005413 if (const ObjCPropertyImplDecl *PropImpl =
5414 dyn_cast<ObjCPropertyImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00005415 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
5416 return MakeCXCursor(Property, tu);
5417
5418 return C;
5419 }
5420
5421 if (clang_isExpression(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005422 const Expr *E = getCursorExpr(C);
5423 const Decl *D = getDeclFromExpr(E);
Guy Benyei11169dd2012-12-18 14:30:41 +00005424 if (D) {
5425 CXCursor declCursor = MakeCXCursor(D, tu);
5426 declCursor = getSelectorIdentifierCursor(getSelectorIdentifierIndex(C),
5427 declCursor);
5428 return declCursor;
5429 }
5430
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005431 if (const OverloadExpr *Ovl = dyn_cast_or_null<OverloadExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00005432 return MakeCursorOverloadedDeclRef(Ovl, tu);
5433
5434 return clang_getNullCursor();
5435 }
5436
5437 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005438 const Stmt *S = getCursorStmt(C);
5439 if (const GotoStmt *Goto = dyn_cast_or_null<GotoStmt>(S))
Guy Benyei11169dd2012-12-18 14:30:41 +00005440 if (LabelDecl *label = Goto->getLabel())
5441 if (LabelStmt *labelS = label->getStmt())
5442 return MakeCXCursor(labelS, getCursorDecl(C), tu);
5443
5444 return clang_getNullCursor();
5445 }
Richard Smith66a81862015-05-04 02:25:31 +00005446
Guy Benyei11169dd2012-12-18 14:30:41 +00005447 if (C.kind == CXCursor_MacroExpansion) {
Richard Smith66a81862015-05-04 02:25:31 +00005448 if (const MacroDefinitionRecord *Def =
5449 getCursorMacroExpansion(C).getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005450 return MakeMacroDefinitionCursor(Def, tu);
5451 }
5452
5453 if (!clang_isReference(C.kind))
5454 return clang_getNullCursor();
5455
5456 switch (C.kind) {
5457 case CXCursor_ObjCSuperClassRef:
5458 return MakeCXCursor(getCursorObjCSuperClassRef(C).first, tu);
5459
5460 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005461 const ObjCProtocolDecl *Prot = getCursorObjCProtocolRef(C).first;
5462 if (const ObjCProtocolDecl *Def = Prot->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005463 return MakeCXCursor(Def, tu);
5464
5465 return MakeCXCursor(Prot, tu);
5466 }
5467
5468 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005469 const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
5470 if (const ObjCInterfaceDecl *Def = Class->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005471 return MakeCXCursor(Def, tu);
5472
5473 return MakeCXCursor(Class, tu);
5474 }
5475
5476 case CXCursor_TypeRef:
5477 return MakeCXCursor(getCursorTypeRef(C).first, tu );
5478
5479 case CXCursor_TemplateRef:
5480 return MakeCXCursor(getCursorTemplateRef(C).first, tu );
5481
5482 case CXCursor_NamespaceRef:
5483 return MakeCXCursor(getCursorNamespaceRef(C).first, tu );
5484
5485 case CXCursor_MemberRef:
5486 return MakeCXCursor(getCursorMemberRef(C).first, tu );
5487
5488 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005489 const CXXBaseSpecifier *B = cxcursor::getCursorCXXBaseSpecifier(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005490 return clang_getTypeDeclaration(cxtype::MakeCXType(B->getType(),
5491 tu ));
5492 }
5493
5494 case CXCursor_LabelRef:
5495 // FIXME: We end up faking the "parent" declaration here because we
5496 // don't want to make CXCursor larger.
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005497 return MakeCXCursor(getCursorLabelRef(C).first,
5498 cxtu::getASTUnit(tu)->getASTContext()
5499 .getTranslationUnitDecl(),
Guy Benyei11169dd2012-12-18 14:30:41 +00005500 tu);
5501
5502 case CXCursor_OverloadedDeclRef:
5503 return C;
5504
5505 case CXCursor_VariableRef:
5506 return MakeCXCursor(getCursorVariableRef(C).first, tu);
5507
5508 default:
5509 // We would prefer to enumerate all non-reference cursor kinds here.
5510 llvm_unreachable("Unhandled reference cursor kind");
5511 }
5512}
5513
5514CXCursor clang_getCursorDefinition(CXCursor C) {
5515 if (clang_isInvalid(C.kind))
5516 return clang_getNullCursor();
5517
5518 CXTranslationUnit TU = getCursorTU(C);
5519
5520 bool WasReference = false;
5521 if (clang_isReference(C.kind) || clang_isExpression(C.kind)) {
5522 C = clang_getCursorReferenced(C);
5523 WasReference = true;
5524 }
5525
5526 if (C.kind == CXCursor_MacroExpansion)
5527 return clang_getCursorReferenced(C);
5528
5529 if (!clang_isDeclaration(C.kind))
5530 return clang_getNullCursor();
5531
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005532 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005533 if (!D)
5534 return clang_getNullCursor();
5535
5536 switch (D->getKind()) {
5537 // Declaration kinds that don't really separate the notions of
5538 // declaration and definition.
5539 case Decl::Namespace:
5540 case Decl::Typedef:
5541 case Decl::TypeAlias:
5542 case Decl::TypeAliasTemplate:
5543 case Decl::TemplateTypeParm:
5544 case Decl::EnumConstant:
5545 case Decl::Field:
John McCall5e77d762013-04-16 07:28:30 +00005546 case Decl::MSProperty:
Guy Benyei11169dd2012-12-18 14:30:41 +00005547 case Decl::IndirectField:
5548 case Decl::ObjCIvar:
5549 case Decl::ObjCAtDefsField:
5550 case Decl::ImplicitParam:
5551 case Decl::ParmVar:
5552 case Decl::NonTypeTemplateParm:
5553 case Decl::TemplateTemplateParm:
5554 case Decl::ObjCCategoryImpl:
5555 case Decl::ObjCImplementation:
5556 case Decl::AccessSpec:
5557 case Decl::LinkageSpec:
5558 case Decl::ObjCPropertyImpl:
5559 case Decl::FileScopeAsm:
5560 case Decl::StaticAssert:
5561 case Decl::Block:
Tareq A. Siraj6dfa25a2013-04-16 19:37:38 +00005562 case Decl::Captured:
Alexey Bataev4244be22016-02-11 05:35:55 +00005563 case Decl::OMPCapturedExpr:
Guy Benyei11169dd2012-12-18 14:30:41 +00005564 case Decl::Label: // FIXME: Is this right??
5565 case Decl::ClassScopeFunctionSpecialization:
5566 case Decl::Import:
Alexey Bataeva769e072013-03-22 06:34:35 +00005567 case Decl::OMPThreadPrivate:
Alexey Bataev94a4f0c2016-03-03 05:21:39 +00005568 case Decl::OMPDeclareReduction:
Douglas Gregor85f3f952015-07-07 03:57:15 +00005569 case Decl::ObjCTypeParam:
David Majnemerd9b1a4f2015-11-04 03:40:30 +00005570 case Decl::BuiltinTemplate:
Nico Weber66220292016-03-02 17:28:48 +00005571 case Decl::PragmaComment:
Nico Webercbbaeb12016-03-02 19:28:54 +00005572 case Decl::PragmaDetectMismatch:
Guy Benyei11169dd2012-12-18 14:30:41 +00005573 return C;
5574
5575 // Declaration kinds that don't make any sense here, but are
5576 // nonetheless harmless.
David Blaikief005d3c2013-02-22 17:44:58 +00005577 case Decl::Empty:
Guy Benyei11169dd2012-12-18 14:30:41 +00005578 case Decl::TranslationUnit:
Richard Smithf19e1272015-03-07 00:04:49 +00005579 case Decl::ExternCContext:
Guy Benyei11169dd2012-12-18 14:30:41 +00005580 break;
5581
5582 // Declaration kinds for which the definition is not resolvable.
5583 case Decl::UnresolvedUsingTypename:
5584 case Decl::UnresolvedUsingValue:
5585 break;
5586
5587 case Decl::UsingDirective:
5588 return MakeCXCursor(cast<UsingDirectiveDecl>(D)->getNominatedNamespace(),
5589 TU);
5590
5591 case Decl::NamespaceAlias:
5592 return MakeCXCursor(cast<NamespaceAliasDecl>(D)->getNamespace(), TU);
5593
5594 case Decl::Enum:
5595 case Decl::Record:
5596 case Decl::CXXRecord:
5597 case Decl::ClassTemplateSpecialization:
5598 case Decl::ClassTemplatePartialSpecialization:
5599 if (TagDecl *Def = cast<TagDecl>(D)->getDefinition())
5600 return MakeCXCursor(Def, TU);
5601 return clang_getNullCursor();
5602
5603 case Decl::Function:
5604 case Decl::CXXMethod:
5605 case Decl::CXXConstructor:
5606 case Decl::CXXDestructor:
5607 case Decl::CXXConversion: {
Craig Topper69186e72014-06-08 08:38:04 +00005608 const FunctionDecl *Def = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005609 if (cast<FunctionDecl>(D)->getBody(Def))
Dmitri Gribenko9c256e32013-01-14 00:46:27 +00005610 return MakeCXCursor(Def, TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005611 return clang_getNullCursor();
5612 }
5613
Larisse Voufo39a1e502013-08-06 01:03:05 +00005614 case Decl::Var:
5615 case Decl::VarTemplateSpecialization:
5616 case Decl::VarTemplatePartialSpecialization: {
Guy Benyei11169dd2012-12-18 14:30:41 +00005617 // Ask the variable if it has a definition.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005618 if (const VarDecl *Def = cast<VarDecl>(D)->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005619 return MakeCXCursor(Def, TU);
5620 return clang_getNullCursor();
5621 }
5622
5623 case Decl::FunctionTemplate: {
Craig Topper69186e72014-06-08 08:38:04 +00005624 const FunctionDecl *Def = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005625 if (cast<FunctionTemplateDecl>(D)->getTemplatedDecl()->getBody(Def))
5626 return MakeCXCursor(Def->getDescribedFunctionTemplate(), TU);
5627 return clang_getNullCursor();
5628 }
5629
5630 case Decl::ClassTemplate: {
5631 if (RecordDecl *Def = cast<ClassTemplateDecl>(D)->getTemplatedDecl()
5632 ->getDefinition())
5633 return MakeCXCursor(cast<CXXRecordDecl>(Def)->getDescribedClassTemplate(),
5634 TU);
5635 return clang_getNullCursor();
5636 }
5637
Larisse Voufo39a1e502013-08-06 01:03:05 +00005638 case Decl::VarTemplate: {
5639 if (VarDecl *Def =
5640 cast<VarTemplateDecl>(D)->getTemplatedDecl()->getDefinition())
5641 return MakeCXCursor(cast<VarDecl>(Def)->getDescribedVarTemplate(), TU);
5642 return clang_getNullCursor();
5643 }
5644
Guy Benyei11169dd2012-12-18 14:30:41 +00005645 case Decl::Using:
5646 return MakeCursorOverloadedDeclRef(cast<UsingDecl>(D),
5647 D->getLocation(), TU);
5648
5649 case Decl::UsingShadow:
5650 return clang_getCursorDefinition(
5651 MakeCXCursor(cast<UsingShadowDecl>(D)->getTargetDecl(),
5652 TU));
5653
5654 case Decl::ObjCMethod: {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005655 const ObjCMethodDecl *Method = cast<ObjCMethodDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00005656 if (Method->isThisDeclarationADefinition())
5657 return C;
5658
5659 // Dig out the method definition in the associated
5660 // @implementation, if we have it.
5661 // FIXME: The ASTs should make finding the definition easier.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005662 if (const ObjCInterfaceDecl *Class
Guy Benyei11169dd2012-12-18 14:30:41 +00005663 = dyn_cast<ObjCInterfaceDecl>(Method->getDeclContext()))
5664 if (ObjCImplementationDecl *ClassImpl = Class->getImplementation())
5665 if (ObjCMethodDecl *Def = ClassImpl->getMethod(Method->getSelector(),
5666 Method->isInstanceMethod()))
5667 if (Def->isThisDeclarationADefinition())
5668 return MakeCXCursor(Def, TU);
5669
5670 return clang_getNullCursor();
5671 }
5672
5673 case Decl::ObjCCategory:
5674 if (ObjCCategoryImplDecl *Impl
5675 = cast<ObjCCategoryDecl>(D)->getImplementation())
5676 return MakeCXCursor(Impl, TU);
5677 return clang_getNullCursor();
5678
5679 case Decl::ObjCProtocol:
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005680 if (const ObjCProtocolDecl *Def = cast<ObjCProtocolDecl>(D)->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005681 return MakeCXCursor(Def, TU);
5682 return clang_getNullCursor();
5683
5684 case Decl::ObjCInterface: {
5685 // There are two notions of a "definition" for an Objective-C
5686 // class: the interface and its implementation. When we resolved a
5687 // reference to an Objective-C class, produce the @interface as
5688 // the definition; when we were provided with the interface,
5689 // produce the @implementation as the definition.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005690 const ObjCInterfaceDecl *IFace = cast<ObjCInterfaceDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00005691 if (WasReference) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005692 if (const ObjCInterfaceDecl *Def = IFace->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005693 return MakeCXCursor(Def, TU);
5694 } else if (ObjCImplementationDecl *Impl = IFace->getImplementation())
5695 return MakeCXCursor(Impl, TU);
5696 return clang_getNullCursor();
5697 }
5698
5699 case Decl::ObjCProperty:
5700 // FIXME: We don't really know where to find the
5701 // ObjCPropertyImplDecls that implement this property.
5702 return clang_getNullCursor();
5703
5704 case Decl::ObjCCompatibleAlias:
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005705 if (const ObjCInterfaceDecl *Class
Guy Benyei11169dd2012-12-18 14:30:41 +00005706 = cast<ObjCCompatibleAliasDecl>(D)->getClassInterface())
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005707 if (const ObjCInterfaceDecl *Def = Class->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005708 return MakeCXCursor(Def, TU);
5709
5710 return clang_getNullCursor();
5711
5712 case Decl::Friend:
5713 if (NamedDecl *Friend = cast<FriendDecl>(D)->getFriendDecl())
5714 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
5715 return clang_getNullCursor();
5716
5717 case Decl::FriendTemplate:
5718 if (NamedDecl *Friend = cast<FriendTemplateDecl>(D)->getFriendDecl())
5719 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
5720 return clang_getNullCursor();
5721 }
5722
5723 return clang_getNullCursor();
5724}
5725
5726unsigned clang_isCursorDefinition(CXCursor C) {
5727 if (!clang_isDeclaration(C.kind))
5728 return 0;
5729
5730 return clang_getCursorDefinition(C) == C;
5731}
5732
5733CXCursor clang_getCanonicalCursor(CXCursor C) {
5734 if (!clang_isDeclaration(C.kind))
5735 return C;
5736
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005737 if (const Decl *D = getCursorDecl(C)) {
5738 if (const ObjCCategoryImplDecl *CatImplD = dyn_cast<ObjCCategoryImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00005739 if (ObjCCategoryDecl *CatD = CatImplD->getCategoryDecl())
5740 return MakeCXCursor(CatD, getCursorTU(C));
5741
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005742 if (const ObjCImplDecl *ImplD = dyn_cast<ObjCImplDecl>(D))
5743 if (const ObjCInterfaceDecl *IFD = ImplD->getClassInterface())
Guy Benyei11169dd2012-12-18 14:30:41 +00005744 return MakeCXCursor(IFD, getCursorTU(C));
5745
5746 return MakeCXCursor(D->getCanonicalDecl(), getCursorTU(C));
5747 }
5748
5749 return C;
5750}
5751
5752int clang_Cursor_getObjCSelectorIndex(CXCursor cursor) {
5753 return cxcursor::getSelectorIdentifierIndexAndLoc(cursor).first;
5754}
5755
5756unsigned clang_getNumOverloadedDecls(CXCursor C) {
5757 if (C.kind != CXCursor_OverloadedDeclRef)
5758 return 0;
5759
5760 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005761 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Guy Benyei11169dd2012-12-18 14:30:41 +00005762 return E->getNumDecls();
5763
5764 if (OverloadedTemplateStorage *S
5765 = Storage.dyn_cast<OverloadedTemplateStorage*>())
5766 return S->size();
5767
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005768 const Decl *D = Storage.get<const Decl *>();
5769 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00005770 return Using->shadow_size();
5771
5772 return 0;
5773}
5774
5775CXCursor clang_getOverloadedDecl(CXCursor cursor, unsigned index) {
5776 if (cursor.kind != CXCursor_OverloadedDeclRef)
5777 return clang_getNullCursor();
5778
5779 if (index >= clang_getNumOverloadedDecls(cursor))
5780 return clang_getNullCursor();
5781
5782 CXTranslationUnit TU = getCursorTU(cursor);
5783 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(cursor).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005784 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Guy Benyei11169dd2012-12-18 14:30:41 +00005785 return MakeCXCursor(E->decls_begin()[index], TU);
5786
5787 if (OverloadedTemplateStorage *S
5788 = Storage.dyn_cast<OverloadedTemplateStorage*>())
5789 return MakeCXCursor(S->begin()[index], TU);
5790
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005791 const Decl *D = Storage.get<const Decl *>();
5792 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005793 // FIXME: This is, unfortunately, linear time.
5794 UsingDecl::shadow_iterator Pos = Using->shadow_begin();
5795 std::advance(Pos, index);
5796 return MakeCXCursor(cast<UsingShadowDecl>(*Pos)->getTargetDecl(), TU);
5797 }
5798
5799 return clang_getNullCursor();
5800}
5801
5802void clang_getDefinitionSpellingAndExtent(CXCursor C,
5803 const char **startBuf,
5804 const char **endBuf,
5805 unsigned *startLine,
5806 unsigned *startColumn,
5807 unsigned *endLine,
5808 unsigned *endColumn) {
5809 assert(getCursorDecl(C) && "CXCursor has null decl");
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005810 const FunctionDecl *FD = dyn_cast<FunctionDecl>(getCursorDecl(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00005811 CompoundStmt *Body = dyn_cast<CompoundStmt>(FD->getBody());
5812
5813 SourceManager &SM = FD->getASTContext().getSourceManager();
5814 *startBuf = SM.getCharacterData(Body->getLBracLoc());
5815 *endBuf = SM.getCharacterData(Body->getRBracLoc());
5816 *startLine = SM.getSpellingLineNumber(Body->getLBracLoc());
5817 *startColumn = SM.getSpellingColumnNumber(Body->getLBracLoc());
5818 *endLine = SM.getSpellingLineNumber(Body->getRBracLoc());
5819 *endColumn = SM.getSpellingColumnNumber(Body->getRBracLoc());
5820}
5821
5822
5823CXSourceRange clang_getCursorReferenceNameRange(CXCursor C, unsigned NameFlags,
5824 unsigned PieceIndex) {
5825 RefNamePieces Pieces;
5826
5827 switch (C.kind) {
5828 case CXCursor_MemberRefExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005829 if (const MemberExpr *E = dyn_cast<MemberExpr>(getCursorExpr(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00005830 Pieces = buildPieces(NameFlags, true, E->getMemberNameInfo(),
5831 E->getQualifierLoc().getSourceRange());
5832 break;
5833
5834 case CXCursor_DeclRefExpr:
James Y Knight04ec5bf2015-12-24 02:59:37 +00005835 if (const DeclRefExpr *E = dyn_cast<DeclRefExpr>(getCursorExpr(C))) {
5836 SourceRange TemplateArgLoc(E->getLAngleLoc(), E->getRAngleLoc());
5837 Pieces =
5838 buildPieces(NameFlags, false, E->getNameInfo(),
5839 E->getQualifierLoc().getSourceRange(), &TemplateArgLoc);
5840 }
Guy Benyei11169dd2012-12-18 14:30:41 +00005841 break;
5842
5843 case CXCursor_CallExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005844 if (const CXXOperatorCallExpr *OCE =
Guy Benyei11169dd2012-12-18 14:30:41 +00005845 dyn_cast<CXXOperatorCallExpr>(getCursorExpr(C))) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005846 const Expr *Callee = OCE->getCallee();
5847 if (const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Callee))
Guy Benyei11169dd2012-12-18 14:30:41 +00005848 Callee = ICE->getSubExpr();
5849
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005850 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(Callee))
Guy Benyei11169dd2012-12-18 14:30:41 +00005851 Pieces = buildPieces(NameFlags, false, DRE->getNameInfo(),
5852 DRE->getQualifierLoc().getSourceRange());
5853 }
5854 break;
5855
5856 default:
5857 break;
5858 }
5859
5860 if (Pieces.empty()) {
5861 if (PieceIndex == 0)
5862 return clang_getCursorExtent(C);
5863 } else if (PieceIndex < Pieces.size()) {
5864 SourceRange R = Pieces[PieceIndex];
5865 if (R.isValid())
5866 return cxloc::translateSourceRange(getCursorContext(C), R);
5867 }
5868
5869 return clang_getNullRange();
5870}
5871
5872void clang_enableStackTraces(void) {
5873 llvm::sys::PrintStackTraceOnErrorSignal();
5874}
5875
5876void clang_executeOnThread(void (*fn)(void*), void *user_data,
5877 unsigned stack_size) {
5878 llvm::llvm_execute_on_thread(fn, user_data, stack_size);
5879}
5880
5881} // end: extern "C"
5882
5883//===----------------------------------------------------------------------===//
5884// Token-based Operations.
5885//===----------------------------------------------------------------------===//
5886
5887/* CXToken layout:
5888 * int_data[0]: a CXTokenKind
5889 * int_data[1]: starting token location
5890 * int_data[2]: token length
5891 * int_data[3]: reserved
5892 * ptr_data: for identifiers and keywords, an IdentifierInfo*.
5893 * otherwise unused.
5894 */
5895extern "C" {
5896
5897CXTokenKind clang_getTokenKind(CXToken CXTok) {
5898 return static_cast<CXTokenKind>(CXTok.int_data[0]);
5899}
5900
5901CXString clang_getTokenSpelling(CXTranslationUnit TU, CXToken CXTok) {
5902 switch (clang_getTokenKind(CXTok)) {
5903 case CXToken_Identifier:
5904 case CXToken_Keyword:
5905 // We know we have an IdentifierInfo*, so use that.
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005906 return cxstring::createRef(static_cast<IdentifierInfo *>(CXTok.ptr_data)
Guy Benyei11169dd2012-12-18 14:30:41 +00005907 ->getNameStart());
5908
5909 case CXToken_Literal: {
5910 // We have stashed the starting pointer in the ptr_data field. Use it.
5911 const char *Text = static_cast<const char *>(CXTok.ptr_data);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00005912 return cxstring::createDup(StringRef(Text, CXTok.int_data[2]));
Guy Benyei11169dd2012-12-18 14:30:41 +00005913 }
5914
5915 case CXToken_Punctuation:
5916 case CXToken_Comment:
5917 break;
5918 }
5919
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005920 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005921 LOG_BAD_TU(TU);
5922 return cxstring::createEmpty();
5923 }
5924
Guy Benyei11169dd2012-12-18 14:30:41 +00005925 // We have to find the starting buffer pointer the hard way, by
5926 // deconstructing the source location.
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005927 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005928 if (!CXXUnit)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00005929 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00005930
5931 SourceLocation Loc = SourceLocation::getFromRawEncoding(CXTok.int_data[1]);
5932 std::pair<FileID, unsigned> LocInfo
5933 = CXXUnit->getSourceManager().getDecomposedSpellingLoc(Loc);
5934 bool Invalid = false;
5935 StringRef Buffer
5936 = CXXUnit->getSourceManager().getBufferData(LocInfo.first, &Invalid);
5937 if (Invalid)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00005938 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00005939
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00005940 return cxstring::createDup(Buffer.substr(LocInfo.second, CXTok.int_data[2]));
Guy Benyei11169dd2012-12-18 14:30:41 +00005941}
5942
5943CXSourceLocation clang_getTokenLocation(CXTranslationUnit TU, CXToken CXTok) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005944 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005945 LOG_BAD_TU(TU);
5946 return clang_getNullLocation();
5947 }
5948
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005949 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005950 if (!CXXUnit)
5951 return clang_getNullLocation();
5952
5953 return cxloc::translateSourceLocation(CXXUnit->getASTContext(),
5954 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
5955}
5956
5957CXSourceRange clang_getTokenExtent(CXTranslationUnit TU, CXToken CXTok) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005958 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005959 LOG_BAD_TU(TU);
5960 return clang_getNullRange();
5961 }
5962
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005963 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005964 if (!CXXUnit)
5965 return clang_getNullRange();
5966
5967 return cxloc::translateSourceRange(CXXUnit->getASTContext(),
5968 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
5969}
5970
5971static void getTokens(ASTUnit *CXXUnit, SourceRange Range,
5972 SmallVectorImpl<CXToken> &CXTokens) {
5973 SourceManager &SourceMgr = CXXUnit->getSourceManager();
5974 std::pair<FileID, unsigned> BeginLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005975 = SourceMgr.getDecomposedSpellingLoc(Range.getBegin());
Guy Benyei11169dd2012-12-18 14:30:41 +00005976 std::pair<FileID, unsigned> EndLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005977 = SourceMgr.getDecomposedSpellingLoc(Range.getEnd());
Guy Benyei11169dd2012-12-18 14:30:41 +00005978
5979 // Cannot tokenize across files.
5980 if (BeginLocInfo.first != EndLocInfo.first)
5981 return;
5982
5983 // Create a lexer
5984 bool Invalid = false;
5985 StringRef Buffer
5986 = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
5987 if (Invalid)
5988 return;
5989
5990 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
5991 CXXUnit->getASTContext().getLangOpts(),
5992 Buffer.begin(), Buffer.data() + BeginLocInfo.second, Buffer.end());
5993 Lex.SetCommentRetentionState(true);
5994
5995 // Lex tokens until we hit the end of the range.
5996 const char *EffectiveBufferEnd = Buffer.data() + EndLocInfo.second;
5997 Token Tok;
5998 bool previousWasAt = false;
5999 do {
6000 // Lex the next token
6001 Lex.LexFromRawLexer(Tok);
6002 if (Tok.is(tok::eof))
6003 break;
6004
6005 // Initialize the CXToken.
6006 CXToken CXTok;
6007
6008 // - Common fields
6009 CXTok.int_data[1] = Tok.getLocation().getRawEncoding();
6010 CXTok.int_data[2] = Tok.getLength();
6011 CXTok.int_data[3] = 0;
6012
6013 // - Kind-specific fields
6014 if (Tok.isLiteral()) {
6015 CXTok.int_data[0] = CXToken_Literal;
Dmitri Gribenkof9304482013-01-23 15:56:07 +00006016 CXTok.ptr_data = const_cast<char *>(Tok.getLiteralData());
Guy Benyei11169dd2012-12-18 14:30:41 +00006017 } else if (Tok.is(tok::raw_identifier)) {
6018 // Lookup the identifier to determine whether we have a keyword.
6019 IdentifierInfo *II
6020 = CXXUnit->getPreprocessor().LookUpIdentifierInfo(Tok);
6021
6022 if ((II->getObjCKeywordID() != tok::objc_not_keyword) && previousWasAt) {
6023 CXTok.int_data[0] = CXToken_Keyword;
6024 }
6025 else {
6026 CXTok.int_data[0] = Tok.is(tok::identifier)
6027 ? CXToken_Identifier
6028 : CXToken_Keyword;
6029 }
6030 CXTok.ptr_data = II;
6031 } else if (Tok.is(tok::comment)) {
6032 CXTok.int_data[0] = CXToken_Comment;
Craig Topper69186e72014-06-08 08:38:04 +00006033 CXTok.ptr_data = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006034 } else {
6035 CXTok.int_data[0] = CXToken_Punctuation;
Craig Topper69186e72014-06-08 08:38:04 +00006036 CXTok.ptr_data = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006037 }
6038 CXTokens.push_back(CXTok);
6039 previousWasAt = Tok.is(tok::at);
6040 } while (Lex.getBufferLocation() <= EffectiveBufferEnd);
6041}
6042
6043void clang_tokenize(CXTranslationUnit TU, CXSourceRange Range,
6044 CXToken **Tokens, unsigned *NumTokens) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006045 LOG_FUNC_SECTION {
6046 *Log << TU << ' ' << Range;
6047 }
6048
Guy Benyei11169dd2012-12-18 14:30:41 +00006049 if (Tokens)
Craig Topper69186e72014-06-08 08:38:04 +00006050 *Tokens = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006051 if (NumTokens)
6052 *NumTokens = 0;
6053
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006054 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006055 LOG_BAD_TU(TU);
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00006056 return;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006057 }
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00006058
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006059 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00006060 if (!CXXUnit || !Tokens || !NumTokens)
6061 return;
6062
6063 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
6064
6065 SourceRange R = cxloc::translateCXSourceRange(Range);
6066 if (R.isInvalid())
6067 return;
6068
6069 SmallVector<CXToken, 32> CXTokens;
6070 getTokens(CXXUnit, R, CXTokens);
6071
6072 if (CXTokens.empty())
6073 return;
6074
6075 *Tokens = (CXToken *)malloc(sizeof(CXToken) * CXTokens.size());
6076 memmove(*Tokens, CXTokens.data(), sizeof(CXToken) * CXTokens.size());
6077 *NumTokens = CXTokens.size();
6078}
6079
6080void clang_disposeTokens(CXTranslationUnit TU,
6081 CXToken *Tokens, unsigned NumTokens) {
6082 free(Tokens);
6083}
6084
6085} // end: extern "C"
6086
6087//===----------------------------------------------------------------------===//
6088// Token annotation APIs.
6089//===----------------------------------------------------------------------===//
6090
Guy Benyei11169dd2012-12-18 14:30:41 +00006091static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
6092 CXCursor parent,
6093 CXClientData client_data);
6094static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
6095 CXClientData client_data);
6096
6097namespace {
6098class AnnotateTokensWorker {
Guy Benyei11169dd2012-12-18 14:30:41 +00006099 CXToken *Tokens;
6100 CXCursor *Cursors;
6101 unsigned NumTokens;
6102 unsigned TokIdx;
6103 unsigned PreprocessingTokIdx;
6104 CursorVisitor AnnotateVis;
6105 SourceManager &SrcMgr;
6106 bool HasContextSensitiveKeywords;
6107
6108 struct PostChildrenInfo {
6109 CXCursor Cursor;
6110 SourceRange CursorRange;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00006111 unsigned BeforeReachingCursorIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00006112 unsigned BeforeChildrenTokenIdx;
6113 };
Dmitri Gribenkof8579502013-01-12 19:30:44 +00006114 SmallVector<PostChildrenInfo, 8> PostChildrenInfos;
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00006115
6116 CXToken &getTok(unsigned Idx) {
6117 assert(Idx < NumTokens);
6118 return Tokens[Idx];
6119 }
6120 const CXToken &getTok(unsigned Idx) const {
6121 assert(Idx < NumTokens);
6122 return Tokens[Idx];
6123 }
Guy Benyei11169dd2012-12-18 14:30:41 +00006124 bool MoreTokens() const { return TokIdx < NumTokens; }
6125 unsigned NextToken() const { return TokIdx; }
6126 void AdvanceToken() { ++TokIdx; }
6127 SourceLocation GetTokenLoc(unsigned tokI) {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00006128 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[1]);
Guy Benyei11169dd2012-12-18 14:30:41 +00006129 }
6130 bool isFunctionMacroToken(unsigned tokI) const {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00006131 return getTok(tokI).int_data[3] != 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00006132 }
6133 SourceLocation getFunctionMacroTokenLoc(unsigned tokI) const {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00006134 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[3]);
Guy Benyei11169dd2012-12-18 14:30:41 +00006135 }
6136
6137 void annotateAndAdvanceTokens(CXCursor, RangeComparisonResult, SourceRange);
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00006138 bool annotateAndAdvanceFunctionMacroTokens(CXCursor, RangeComparisonResult,
Guy Benyei11169dd2012-12-18 14:30:41 +00006139 SourceRange);
6140
6141public:
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006142 AnnotateTokensWorker(CXToken *tokens, CXCursor *cursors, unsigned numTokens,
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006143 CXTranslationUnit TU, SourceRange RegionOfInterest)
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006144 : Tokens(tokens), Cursors(cursors),
Guy Benyei11169dd2012-12-18 14:30:41 +00006145 NumTokens(numTokens), TokIdx(0), PreprocessingTokIdx(0),
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006146 AnnotateVis(TU,
Guy Benyei11169dd2012-12-18 14:30:41 +00006147 AnnotateTokensVisitor, this,
6148 /*VisitPreprocessorLast=*/true,
6149 /*VisitIncludedEntities=*/false,
6150 RegionOfInterest,
6151 /*VisitDeclsOnly=*/false,
6152 AnnotateTokensPostChildrenVisitor),
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006153 SrcMgr(cxtu::getASTUnit(TU)->getSourceManager()),
Guy Benyei11169dd2012-12-18 14:30:41 +00006154 HasContextSensitiveKeywords(false) { }
6155
6156 void VisitChildren(CXCursor C) { AnnotateVis.VisitChildren(C); }
6157 enum CXChildVisitResult Visit(CXCursor cursor, CXCursor parent);
6158 bool postVisitChildren(CXCursor cursor);
6159 void AnnotateTokens();
6160
6161 /// \brief Determine whether the annotator saw any cursors that have
6162 /// context-sensitive keywords.
6163 bool hasContextSensitiveKeywords() const {
6164 return HasContextSensitiveKeywords;
6165 }
6166
6167 ~AnnotateTokensWorker() {
6168 assert(PostChildrenInfos.empty());
6169 }
6170};
Alexander Kornienkoab9db512015-06-22 23:07:51 +00006171}
Guy Benyei11169dd2012-12-18 14:30:41 +00006172
6173void AnnotateTokensWorker::AnnotateTokens() {
6174 // Walk the AST within the region of interest, annotating tokens
6175 // along the way.
6176 AnnotateVis.visitFileRegion();
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006177}
Guy Benyei11169dd2012-12-18 14:30:41 +00006178
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006179static inline void updateCursorAnnotation(CXCursor &Cursor,
6180 const CXCursor &updateC) {
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00006181 if (clang_isInvalid(updateC.kind) || !clang_isInvalid(Cursor.kind))
Guy Benyei11169dd2012-12-18 14:30:41 +00006182 return;
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006183 Cursor = updateC;
Guy Benyei11169dd2012-12-18 14:30:41 +00006184}
6185
6186/// \brief It annotates and advances tokens with a cursor until the comparison
6187//// between the cursor location and the source range is the same as
6188/// \arg compResult.
6189///
6190/// Pass RangeBefore to annotate tokens with a cursor until a range is reached.
6191/// Pass RangeOverlap to annotate tokens inside a range.
6192void AnnotateTokensWorker::annotateAndAdvanceTokens(CXCursor updateC,
6193 RangeComparisonResult compResult,
6194 SourceRange range) {
6195 while (MoreTokens()) {
6196 const unsigned I = NextToken();
6197 if (isFunctionMacroToken(I))
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00006198 if (!annotateAndAdvanceFunctionMacroTokens(updateC, compResult, range))
6199 return;
Guy Benyei11169dd2012-12-18 14:30:41 +00006200
6201 SourceLocation TokLoc = GetTokenLoc(I);
6202 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006203 updateCursorAnnotation(Cursors[I], updateC);
Guy Benyei11169dd2012-12-18 14:30:41 +00006204 AdvanceToken();
6205 continue;
6206 }
6207 break;
6208 }
6209}
6210
6211/// \brief Special annotation handling for macro argument tokens.
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00006212/// \returns true if it advanced beyond all macro tokens, false otherwise.
6213bool AnnotateTokensWorker::annotateAndAdvanceFunctionMacroTokens(
Guy Benyei11169dd2012-12-18 14:30:41 +00006214 CXCursor updateC,
6215 RangeComparisonResult compResult,
6216 SourceRange range) {
6217 assert(MoreTokens());
6218 assert(isFunctionMacroToken(NextToken()) &&
6219 "Should be called only for macro arg tokens");
6220
6221 // This works differently than annotateAndAdvanceTokens; because expanded
6222 // macro arguments can have arbitrary translation-unit source order, we do not
6223 // advance the token index one by one until a token fails the range test.
6224 // We only advance once past all of the macro arg tokens if all of them
6225 // pass the range test. If one of them fails we keep the token index pointing
6226 // at the start of the macro arg tokens so that the failing token will be
6227 // annotated by a subsequent annotation try.
6228
6229 bool atLeastOneCompFail = false;
6230
6231 unsigned I = NextToken();
6232 for (; I < NumTokens && isFunctionMacroToken(I); ++I) {
6233 SourceLocation TokLoc = getFunctionMacroTokenLoc(I);
6234 if (TokLoc.isFileID())
6235 continue; // not macro arg token, it's parens or comma.
6236 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
6237 if (clang_isInvalid(clang_getCursorKind(Cursors[I])))
6238 Cursors[I] = updateC;
6239 } else
6240 atLeastOneCompFail = true;
6241 }
6242
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00006243 if (atLeastOneCompFail)
6244 return false;
6245
6246 TokIdx = I; // All of the tokens were handled, advance beyond all of them.
6247 return true;
Guy Benyei11169dd2012-12-18 14:30:41 +00006248}
6249
6250enum CXChildVisitResult
6251AnnotateTokensWorker::Visit(CXCursor cursor, CXCursor parent) {
Guy Benyei11169dd2012-12-18 14:30:41 +00006252 SourceRange cursorRange = getRawCursorExtent(cursor);
6253 if (cursorRange.isInvalid())
6254 return CXChildVisit_Recurse;
6255
6256 if (!HasContextSensitiveKeywords) {
6257 // Objective-C properties can have context-sensitive keywords.
6258 if (cursor.kind == CXCursor_ObjCPropertyDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006259 if (const ObjCPropertyDecl *Property
Guy Benyei11169dd2012-12-18 14:30:41 +00006260 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(cursor)))
6261 HasContextSensitiveKeywords = Property->getPropertyAttributesAsWritten() != 0;
6262 }
6263 // Objective-C methods can have context-sensitive keywords.
6264 else if (cursor.kind == CXCursor_ObjCInstanceMethodDecl ||
6265 cursor.kind == CXCursor_ObjCClassMethodDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006266 if (const ObjCMethodDecl *Method
Guy Benyei11169dd2012-12-18 14:30:41 +00006267 = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
6268 if (Method->getObjCDeclQualifier())
6269 HasContextSensitiveKeywords = true;
6270 else {
Aaron Ballman43b68be2014-03-07 17:50:17 +00006271 for (const auto *P : Method->params()) {
6272 if (P->getObjCDeclQualifier()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00006273 HasContextSensitiveKeywords = true;
6274 break;
6275 }
6276 }
6277 }
6278 }
6279 }
6280 // C++ methods can have context-sensitive keywords.
6281 else if (cursor.kind == CXCursor_CXXMethod) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006282 if (const CXXMethodDecl *Method
Guy Benyei11169dd2012-12-18 14:30:41 +00006283 = dyn_cast_or_null<CXXMethodDecl>(getCursorDecl(cursor))) {
6284 if (Method->hasAttr<FinalAttr>() || Method->hasAttr<OverrideAttr>())
6285 HasContextSensitiveKeywords = true;
6286 }
6287 }
6288 // C++ classes can have context-sensitive keywords.
6289 else if (cursor.kind == CXCursor_StructDecl ||
6290 cursor.kind == CXCursor_ClassDecl ||
6291 cursor.kind == CXCursor_ClassTemplate ||
6292 cursor.kind == CXCursor_ClassTemplatePartialSpecialization) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006293 if (const Decl *D = getCursorDecl(cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +00006294 if (D->hasAttr<FinalAttr>())
6295 HasContextSensitiveKeywords = true;
6296 }
6297 }
Argyrios Kyrtzidis990b3862013-06-04 18:24:30 +00006298
6299 // Don't override a property annotation with its getter/setter method.
6300 if (cursor.kind == CXCursor_ObjCInstanceMethodDecl &&
6301 parent.kind == CXCursor_ObjCPropertyDecl)
6302 return CXChildVisit_Continue;
Guy Benyei11169dd2012-12-18 14:30:41 +00006303
6304 if (clang_isPreprocessing(cursor.kind)) {
6305 // Items in the preprocessing record are kept separate from items in
6306 // declarations, so we keep a separate token index.
6307 unsigned SavedTokIdx = TokIdx;
6308 TokIdx = PreprocessingTokIdx;
6309
6310 // Skip tokens up until we catch up to the beginning of the preprocessing
6311 // entry.
6312 while (MoreTokens()) {
6313 const unsigned I = NextToken();
6314 SourceLocation TokLoc = GetTokenLoc(I);
6315 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
6316 case RangeBefore:
6317 AdvanceToken();
6318 continue;
6319 case RangeAfter:
6320 case RangeOverlap:
6321 break;
6322 }
6323 break;
6324 }
6325
6326 // Look at all of the tokens within this range.
6327 while (MoreTokens()) {
6328 const unsigned I = NextToken();
6329 SourceLocation TokLoc = GetTokenLoc(I);
6330 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
6331 case RangeBefore:
6332 llvm_unreachable("Infeasible");
6333 case RangeAfter:
6334 break;
6335 case RangeOverlap:
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00006336 // For macro expansions, just note where the beginning of the macro
6337 // expansion occurs.
6338 if (cursor.kind == CXCursor_MacroExpansion) {
6339 if (TokLoc == cursorRange.getBegin())
6340 Cursors[I] = cursor;
6341 AdvanceToken();
6342 break;
6343 }
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006344 // We may have already annotated macro names inside macro definitions.
6345 if (Cursors[I].kind != CXCursor_MacroExpansion)
6346 Cursors[I] = cursor;
Guy Benyei11169dd2012-12-18 14:30:41 +00006347 AdvanceToken();
Guy Benyei11169dd2012-12-18 14:30:41 +00006348 continue;
6349 }
6350 break;
6351 }
6352
6353 // Save the preprocessing token index; restore the non-preprocessing
6354 // token index.
6355 PreprocessingTokIdx = TokIdx;
6356 TokIdx = SavedTokIdx;
6357 return CXChildVisit_Recurse;
6358 }
6359
6360 if (cursorRange.isInvalid())
6361 return CXChildVisit_Continue;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00006362
6363 unsigned BeforeReachingCursorIdx = NextToken();
Guy Benyei11169dd2012-12-18 14:30:41 +00006364 const enum CXCursorKind cursorK = clang_getCursorKind(cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00006365 const enum CXCursorKind K = clang_getCursorKind(parent);
6366 const CXCursor updateC =
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00006367 (clang_isInvalid(K) || K == CXCursor_TranslationUnit ||
6368 // Attributes are annotated out-of-order, skip tokens until we reach it.
6369 clang_isAttribute(cursor.kind))
Guy Benyei11169dd2012-12-18 14:30:41 +00006370 ? clang_getNullCursor() : parent;
6371
6372 annotateAndAdvanceTokens(updateC, RangeBefore, cursorRange);
6373
6374 // Avoid having the cursor of an expression "overwrite" the annotation of the
6375 // variable declaration that it belongs to.
6376 // This can happen for C++ constructor expressions whose range generally
6377 // include the variable declaration, e.g.:
6378 // MyCXXClass foo; // Make sure we don't annotate 'foo' as a CallExpr cursor.
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00006379 if (clang_isExpression(cursorK) && MoreTokens()) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00006380 const Expr *E = getCursorExpr(cursor);
Dmitri Gribenkoa1691182013-01-26 18:12:08 +00006381 if (const Decl *D = getCursorParentDecl(cursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00006382 const unsigned I = NextToken();
6383 if (E->getLocStart().isValid() && D->getLocation().isValid() &&
6384 E->getLocStart() == D->getLocation() &&
6385 E->getLocStart() == GetTokenLoc(I)) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006386 updateCursorAnnotation(Cursors[I], updateC);
Guy Benyei11169dd2012-12-18 14:30:41 +00006387 AdvanceToken();
6388 }
6389 }
6390 }
6391
6392 // Before recursing into the children keep some state that we are going
6393 // to use in the AnnotateTokensWorker::postVisitChildren callback to do some
6394 // extra work after the child nodes are visited.
6395 // Note that we don't call VisitChildren here to avoid traversing statements
6396 // code-recursively which can blow the stack.
6397
6398 PostChildrenInfo Info;
6399 Info.Cursor = cursor;
6400 Info.CursorRange = cursorRange;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00006401 Info.BeforeReachingCursorIdx = BeforeReachingCursorIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00006402 Info.BeforeChildrenTokenIdx = NextToken();
6403 PostChildrenInfos.push_back(Info);
6404
6405 return CXChildVisit_Recurse;
6406}
6407
6408bool AnnotateTokensWorker::postVisitChildren(CXCursor cursor) {
6409 if (PostChildrenInfos.empty())
6410 return false;
6411 const PostChildrenInfo &Info = PostChildrenInfos.back();
6412 if (!clang_equalCursors(Info.Cursor, cursor))
6413 return false;
6414
6415 const unsigned BeforeChildren = Info.BeforeChildrenTokenIdx;
6416 const unsigned AfterChildren = NextToken();
6417 SourceRange cursorRange = Info.CursorRange;
6418
6419 // Scan the tokens that are at the end of the cursor, but are not captured
6420 // but the child cursors.
6421 annotateAndAdvanceTokens(cursor, RangeOverlap, cursorRange);
6422
6423 // Scan the tokens that are at the beginning of the cursor, but are not
6424 // capture by the child cursors.
6425 for (unsigned I = BeforeChildren; I != AfterChildren; ++I) {
6426 if (!clang_isInvalid(clang_getCursorKind(Cursors[I])))
6427 break;
6428
6429 Cursors[I] = cursor;
6430 }
6431
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00006432 // Attributes are annotated out-of-order, rewind TokIdx to when we first
6433 // encountered the attribute cursor.
6434 if (clang_isAttribute(cursor.kind))
6435 TokIdx = Info.BeforeReachingCursorIdx;
6436
Guy Benyei11169dd2012-12-18 14:30:41 +00006437 PostChildrenInfos.pop_back();
6438 return false;
6439}
6440
6441static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
6442 CXCursor parent,
6443 CXClientData client_data) {
6444 return static_cast<AnnotateTokensWorker*>(client_data)->Visit(cursor, parent);
6445}
6446
6447static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
6448 CXClientData client_data) {
6449 return static_cast<AnnotateTokensWorker*>(client_data)->
6450 postVisitChildren(cursor);
6451}
6452
6453namespace {
6454
6455/// \brief Uses the macro expansions in the preprocessing record to find
6456/// and mark tokens that are macro arguments. This info is used by the
6457/// AnnotateTokensWorker.
6458class MarkMacroArgTokensVisitor {
6459 SourceManager &SM;
6460 CXToken *Tokens;
6461 unsigned NumTokens;
6462 unsigned CurIdx;
6463
6464public:
6465 MarkMacroArgTokensVisitor(SourceManager &SM,
6466 CXToken *tokens, unsigned numTokens)
6467 : SM(SM), Tokens(tokens), NumTokens(numTokens), CurIdx(0) { }
6468
6469 CXChildVisitResult visit(CXCursor cursor, CXCursor parent) {
6470 if (cursor.kind != CXCursor_MacroExpansion)
6471 return CXChildVisit_Continue;
6472
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006473 SourceRange macroRange = getCursorMacroExpansion(cursor).getSourceRange();
Guy Benyei11169dd2012-12-18 14:30:41 +00006474 if (macroRange.getBegin() == macroRange.getEnd())
6475 return CXChildVisit_Continue; // it's not a function macro.
6476
6477 for (; CurIdx < NumTokens; ++CurIdx) {
6478 if (!SM.isBeforeInTranslationUnit(getTokenLoc(CurIdx),
6479 macroRange.getBegin()))
6480 break;
6481 }
6482
6483 if (CurIdx == NumTokens)
6484 return CXChildVisit_Break;
6485
6486 for (; CurIdx < NumTokens; ++CurIdx) {
6487 SourceLocation tokLoc = getTokenLoc(CurIdx);
6488 if (!SM.isBeforeInTranslationUnit(tokLoc, macroRange.getEnd()))
6489 break;
6490
6491 setFunctionMacroTokenLoc(CurIdx, SM.getMacroArgExpandedLocation(tokLoc));
6492 }
6493
6494 if (CurIdx == NumTokens)
6495 return CXChildVisit_Break;
6496
6497 return CXChildVisit_Continue;
6498 }
6499
6500private:
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00006501 CXToken &getTok(unsigned Idx) {
6502 assert(Idx < NumTokens);
6503 return Tokens[Idx];
6504 }
6505 const CXToken &getTok(unsigned Idx) const {
6506 assert(Idx < NumTokens);
6507 return Tokens[Idx];
6508 }
6509
Guy Benyei11169dd2012-12-18 14:30:41 +00006510 SourceLocation getTokenLoc(unsigned tokI) {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00006511 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[1]);
Guy Benyei11169dd2012-12-18 14:30:41 +00006512 }
6513
6514 void setFunctionMacroTokenLoc(unsigned tokI, SourceLocation loc) {
6515 // The third field is reserved and currently not used. Use it here
6516 // to mark macro arg expanded tokens with their expanded locations.
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00006517 getTok(tokI).int_data[3] = loc.getRawEncoding();
Guy Benyei11169dd2012-12-18 14:30:41 +00006518 }
6519};
6520
6521} // end anonymous namespace
6522
6523static CXChildVisitResult
6524MarkMacroArgTokensVisitorDelegate(CXCursor cursor, CXCursor parent,
6525 CXClientData client_data) {
6526 return static_cast<MarkMacroArgTokensVisitor*>(client_data)->visit(cursor,
6527 parent);
6528}
6529
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006530/// \brief Used by \c annotatePreprocessorTokens.
6531/// \returns true if lexing was finished, false otherwise.
6532static bool lexNext(Lexer &Lex, Token &Tok,
6533 unsigned &NextIdx, unsigned NumTokens) {
6534 if (NextIdx >= NumTokens)
6535 return true;
6536
6537 ++NextIdx;
6538 Lex.LexFromRawLexer(Tok);
Alexander Kornienko1a9f1842015-12-28 15:24:08 +00006539 return Tok.is(tok::eof);
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006540}
6541
Guy Benyei11169dd2012-12-18 14:30:41 +00006542static void annotatePreprocessorTokens(CXTranslationUnit TU,
6543 SourceRange RegionOfInterest,
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006544 CXCursor *Cursors,
6545 CXToken *Tokens,
6546 unsigned NumTokens) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006547 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00006548
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006549 Preprocessor &PP = CXXUnit->getPreprocessor();
Guy Benyei11169dd2012-12-18 14:30:41 +00006550 SourceManager &SourceMgr = CXXUnit->getSourceManager();
6551 std::pair<FileID, unsigned> BeginLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00006552 = SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getBegin());
Guy Benyei11169dd2012-12-18 14:30:41 +00006553 std::pair<FileID, unsigned> EndLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00006554 = SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getEnd());
Guy Benyei11169dd2012-12-18 14:30:41 +00006555
6556 if (BeginLocInfo.first != EndLocInfo.first)
6557 return;
6558
6559 StringRef Buffer;
6560 bool Invalid = false;
6561 Buffer = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
6562 if (Buffer.empty() || Invalid)
6563 return;
6564
6565 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
6566 CXXUnit->getASTContext().getLangOpts(),
6567 Buffer.begin(), Buffer.data() + BeginLocInfo.second,
6568 Buffer.end());
6569 Lex.SetCommentRetentionState(true);
6570
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006571 unsigned NextIdx = 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00006572 // Lex tokens in raw mode until we hit the end of the range, to avoid
6573 // entering #includes or expanding macros.
6574 while (true) {
6575 Token Tok;
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006576 if (lexNext(Lex, Tok, NextIdx, NumTokens))
6577 break;
6578 unsigned TokIdx = NextIdx-1;
6579 assert(Tok.getLocation() ==
6580 SourceLocation::getFromRawEncoding(Tokens[TokIdx].int_data[1]));
Guy Benyei11169dd2012-12-18 14:30:41 +00006581
6582 reprocess:
6583 if (Tok.is(tok::hash) && Tok.isAtStartOfLine()) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006584 // We have found a preprocessing directive. Annotate the tokens
6585 // appropriately.
Guy Benyei11169dd2012-12-18 14:30:41 +00006586 //
6587 // FIXME: Some simple tests here could identify macro definitions and
6588 // #undefs, to provide specific cursor kinds for those.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006589
6590 SourceLocation BeginLoc = Tok.getLocation();
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006591 if (lexNext(Lex, Tok, NextIdx, NumTokens))
6592 break;
6593
Craig Topper69186e72014-06-08 08:38:04 +00006594 MacroInfo *MI = nullptr;
Alp Toker2d57cea2014-05-17 04:53:25 +00006595 if (Tok.is(tok::raw_identifier) && Tok.getRawIdentifier() == "define") {
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006596 if (lexNext(Lex, Tok, NextIdx, NumTokens))
6597 break;
6598
6599 if (Tok.is(tok::raw_identifier)) {
Alp Toker2d57cea2014-05-17 04:53:25 +00006600 IdentifierInfo &II =
6601 PP.getIdentifierTable().get(Tok.getRawIdentifier());
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006602 SourceLocation MappedTokLoc =
6603 CXXUnit->mapLocationToPreamble(Tok.getLocation());
6604 MI = getMacroInfo(II, MappedTokLoc, TU);
6605 }
6606 }
6607
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006608 bool finished = false;
Guy Benyei11169dd2012-12-18 14:30:41 +00006609 do {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006610 if (lexNext(Lex, Tok, NextIdx, NumTokens)) {
6611 finished = true;
6612 break;
6613 }
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006614 // If we are in a macro definition, check if the token was ever a
6615 // macro name and annotate it if that's the case.
6616 if (MI) {
6617 SourceLocation SaveLoc = Tok.getLocation();
6618 Tok.setLocation(CXXUnit->mapLocationToPreamble(SaveLoc));
Richard Smith66a81862015-05-04 02:25:31 +00006619 MacroDefinitionRecord *MacroDef =
6620 checkForMacroInMacroDefinition(MI, Tok, TU);
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006621 Tok.setLocation(SaveLoc);
6622 if (MacroDef)
Richard Smith66a81862015-05-04 02:25:31 +00006623 Cursors[NextIdx - 1] =
6624 MakeMacroExpansionCursor(MacroDef, Tok.getLocation(), TU);
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006625 }
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006626 } while (!Tok.isAtStartOfLine());
6627
6628 unsigned LastIdx = finished ? NextIdx-1 : NextIdx-2;
6629 assert(TokIdx <= LastIdx);
6630 SourceLocation EndLoc =
6631 SourceLocation::getFromRawEncoding(Tokens[LastIdx].int_data[1]);
6632 CXCursor Cursor =
6633 MakePreprocessingDirectiveCursor(SourceRange(BeginLoc, EndLoc), TU);
6634
6635 for (; TokIdx <= LastIdx; ++TokIdx)
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006636 updateCursorAnnotation(Cursors[TokIdx], Cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00006637
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006638 if (finished)
6639 break;
6640 goto reprocess;
Guy Benyei11169dd2012-12-18 14:30:41 +00006641 }
Guy Benyei11169dd2012-12-18 14:30:41 +00006642 }
6643}
6644
6645// This gets run a separate thread to avoid stack blowout.
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00006646static void clang_annotateTokensImpl(CXTranslationUnit TU, ASTUnit *CXXUnit,
6647 CXToken *Tokens, unsigned NumTokens,
6648 CXCursor *Cursors) {
Dmitri Gribenko183436e2013-01-26 21:49:50 +00006649 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00006650 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
6651 setThreadBackgroundPriority();
6652
6653 // Determine the region of interest, which contains all of the tokens.
6654 SourceRange RegionOfInterest;
6655 RegionOfInterest.setBegin(
6656 cxloc::translateSourceLocation(clang_getTokenLocation(TU, Tokens[0])));
6657 RegionOfInterest.setEnd(
6658 cxloc::translateSourceLocation(clang_getTokenLocation(TU,
6659 Tokens[NumTokens-1])));
6660
Guy Benyei11169dd2012-12-18 14:30:41 +00006661 // Relex the tokens within the source range to look for preprocessing
6662 // directives.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006663 annotatePreprocessorTokens(TU, RegionOfInterest, Cursors, Tokens, NumTokens);
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00006664
6665 // If begin location points inside a macro argument, set it to the expansion
6666 // location so we can have the full context when annotating semantically.
6667 {
6668 SourceManager &SM = CXXUnit->getSourceManager();
6669 SourceLocation Loc =
6670 SM.getMacroArgExpandedLocation(RegionOfInterest.getBegin());
6671 if (Loc.isMacroID())
6672 RegionOfInterest.setBegin(SM.getExpansionLoc(Loc));
6673 }
6674
Guy Benyei11169dd2012-12-18 14:30:41 +00006675 if (CXXUnit->getPreprocessor().getPreprocessingRecord()) {
6676 // Search and mark tokens that are macro argument expansions.
6677 MarkMacroArgTokensVisitor Visitor(CXXUnit->getSourceManager(),
6678 Tokens, NumTokens);
6679 CursorVisitor MacroArgMarker(TU,
6680 MarkMacroArgTokensVisitorDelegate, &Visitor,
6681 /*VisitPreprocessorLast=*/true,
6682 /*VisitIncludedEntities=*/false,
6683 RegionOfInterest);
6684 MacroArgMarker.visitPreprocessedEntitiesInRegion();
6685 }
6686
6687 // Annotate all of the source locations in the region of interest that map to
6688 // a specific cursor.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006689 AnnotateTokensWorker W(Tokens, Cursors, NumTokens, TU, RegionOfInterest);
Guy Benyei11169dd2012-12-18 14:30:41 +00006690
6691 // FIXME: We use a ridiculous stack size here because the data-recursion
6692 // algorithm uses a large stack frame than the non-data recursive version,
6693 // and AnnotationTokensWorker currently transforms the data-recursion
6694 // algorithm back into a traditional recursion by explicitly calling
6695 // VisitChildren(). We will need to remove this explicit recursive call.
6696 W.AnnotateTokens();
6697
6698 // If we ran into any entities that involve context-sensitive keywords,
6699 // take another pass through the tokens to mark them as such.
6700 if (W.hasContextSensitiveKeywords()) {
6701 for (unsigned I = 0; I != NumTokens; ++I) {
6702 if (clang_getTokenKind(Tokens[I]) != CXToken_Identifier)
6703 continue;
6704
6705 if (Cursors[I].kind == CXCursor_ObjCPropertyDecl) {
6706 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006707 if (const ObjCPropertyDecl *Property
Guy Benyei11169dd2012-12-18 14:30:41 +00006708 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(Cursors[I]))) {
6709 if (Property->getPropertyAttributesAsWritten() != 0 &&
6710 llvm::StringSwitch<bool>(II->getName())
6711 .Case("readonly", true)
6712 .Case("assign", true)
6713 .Case("unsafe_unretained", true)
6714 .Case("readwrite", true)
6715 .Case("retain", true)
6716 .Case("copy", true)
6717 .Case("nonatomic", true)
6718 .Case("atomic", true)
6719 .Case("getter", true)
6720 .Case("setter", true)
6721 .Case("strong", true)
6722 .Case("weak", true)
6723 .Default(false))
6724 Tokens[I].int_data[0] = CXToken_Keyword;
6725 }
6726 continue;
6727 }
6728
6729 if (Cursors[I].kind == CXCursor_ObjCInstanceMethodDecl ||
6730 Cursors[I].kind == CXCursor_ObjCClassMethodDecl) {
6731 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
6732 if (llvm::StringSwitch<bool>(II->getName())
6733 .Case("in", true)
6734 .Case("out", true)
6735 .Case("inout", true)
6736 .Case("oneway", true)
6737 .Case("bycopy", true)
6738 .Case("byref", true)
6739 .Default(false))
6740 Tokens[I].int_data[0] = CXToken_Keyword;
6741 continue;
6742 }
6743
6744 if (Cursors[I].kind == CXCursor_CXXFinalAttr ||
6745 Cursors[I].kind == CXCursor_CXXOverrideAttr) {
6746 Tokens[I].int_data[0] = CXToken_Keyword;
6747 continue;
6748 }
6749 }
6750 }
6751}
6752
6753extern "C" {
6754
6755void clang_annotateTokens(CXTranslationUnit TU,
6756 CXToken *Tokens, unsigned NumTokens,
6757 CXCursor *Cursors) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006758 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006759 LOG_BAD_TU(TU);
6760 return;
6761 }
6762 if (NumTokens == 0 || !Tokens || !Cursors) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006763 LOG_FUNC_SECTION { *Log << "<null input>"; }
Guy Benyei11169dd2012-12-18 14:30:41 +00006764 return;
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006765 }
6766
6767 LOG_FUNC_SECTION {
6768 *Log << TU << ' ';
6769 CXSourceLocation bloc = clang_getTokenLocation(TU, Tokens[0]);
6770 CXSourceLocation eloc = clang_getTokenLocation(TU, Tokens[NumTokens-1]);
6771 *Log << clang_getRange(bloc, eloc);
6772 }
Guy Benyei11169dd2012-12-18 14:30:41 +00006773
6774 // Any token we don't specifically annotate will have a NULL cursor.
6775 CXCursor C = clang_getNullCursor();
6776 for (unsigned I = 0; I != NumTokens; ++I)
6777 Cursors[I] = C;
6778
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006779 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00006780 if (!CXXUnit)
6781 return;
6782
6783 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00006784
6785 auto AnnotateTokensImpl = [=]() {
6786 clang_annotateTokensImpl(TU, CXXUnit, Tokens, NumTokens, Cursors);
6787 };
Guy Benyei11169dd2012-12-18 14:30:41 +00006788 llvm::CrashRecoveryContext CRC;
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00006789 if (!RunSafely(CRC, AnnotateTokensImpl, GetSafetyThreadStackSize() * 2)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00006790 fprintf(stderr, "libclang: crash detected while annotating tokens\n");
6791 }
6792}
6793
6794} // end: extern "C"
6795
6796//===----------------------------------------------------------------------===//
6797// Operations for querying linkage of a cursor.
6798//===----------------------------------------------------------------------===//
6799
6800extern "C" {
6801CXLinkageKind clang_getCursorLinkage(CXCursor cursor) {
6802 if (!clang_isDeclaration(cursor.kind))
6803 return CXLinkage_Invalid;
6804
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006805 const Decl *D = cxcursor::getCursorDecl(cursor);
6806 if (const NamedDecl *ND = dyn_cast_or_null<NamedDecl>(D))
Rafael Espindola3ae00052013-05-13 00:12:11 +00006807 switch (ND->getLinkageInternal()) {
Rafael Espindola50df3a02013-05-25 17:16:20 +00006808 case NoLinkage:
6809 case VisibleNoLinkage: return CXLinkage_NoLinkage;
Guy Benyei11169dd2012-12-18 14:30:41 +00006810 case InternalLinkage: return CXLinkage_Internal;
6811 case UniqueExternalLinkage: return CXLinkage_UniqueExternal;
6812 case ExternalLinkage: return CXLinkage_External;
6813 };
6814
6815 return CXLinkage_Invalid;
6816}
6817} // end: extern "C"
6818
6819//===----------------------------------------------------------------------===//
Ehsan Akhgarib743de72016-05-31 15:55:51 +00006820// Operations for querying visibility of a cursor.
6821//===----------------------------------------------------------------------===//
6822
6823extern "C" {
6824CXVisibilityKind clang_getCursorVisibility(CXCursor cursor) {
6825 if (!clang_isDeclaration(cursor.kind))
6826 return CXVisibility_Invalid;
6827
6828 const Decl *D = cxcursor::getCursorDecl(cursor);
6829 if (const NamedDecl *ND = dyn_cast_or_null<NamedDecl>(D))
6830 switch (ND->getVisibility()) {
6831 case HiddenVisibility: return CXVisibility_Hidden;
6832 case ProtectedVisibility: return CXVisibility_Protected;
6833 case DefaultVisibility: return CXVisibility_Default;
6834 };
6835
6836 return CXVisibility_Invalid;
6837}
6838} // end: extern "C"
6839
6840//===----------------------------------------------------------------------===//
Guy Benyei11169dd2012-12-18 14:30:41 +00006841// Operations for querying language of a cursor.
6842//===----------------------------------------------------------------------===//
6843
6844static CXLanguageKind getDeclLanguage(const Decl *D) {
6845 if (!D)
6846 return CXLanguage_C;
6847
6848 switch (D->getKind()) {
6849 default:
6850 break;
6851 case Decl::ImplicitParam:
6852 case Decl::ObjCAtDefsField:
6853 case Decl::ObjCCategory:
6854 case Decl::ObjCCategoryImpl:
6855 case Decl::ObjCCompatibleAlias:
6856 case Decl::ObjCImplementation:
6857 case Decl::ObjCInterface:
6858 case Decl::ObjCIvar:
6859 case Decl::ObjCMethod:
6860 case Decl::ObjCProperty:
6861 case Decl::ObjCPropertyImpl:
6862 case Decl::ObjCProtocol:
Douglas Gregor85f3f952015-07-07 03:57:15 +00006863 case Decl::ObjCTypeParam:
Guy Benyei11169dd2012-12-18 14:30:41 +00006864 return CXLanguage_ObjC;
6865 case Decl::CXXConstructor:
6866 case Decl::CXXConversion:
6867 case Decl::CXXDestructor:
6868 case Decl::CXXMethod:
6869 case Decl::CXXRecord:
6870 case Decl::ClassTemplate:
6871 case Decl::ClassTemplatePartialSpecialization:
6872 case Decl::ClassTemplateSpecialization:
6873 case Decl::Friend:
6874 case Decl::FriendTemplate:
6875 case Decl::FunctionTemplate:
6876 case Decl::LinkageSpec:
6877 case Decl::Namespace:
6878 case Decl::NamespaceAlias:
6879 case Decl::NonTypeTemplateParm:
6880 case Decl::StaticAssert:
6881 case Decl::TemplateTemplateParm:
6882 case Decl::TemplateTypeParm:
6883 case Decl::UnresolvedUsingTypename:
6884 case Decl::UnresolvedUsingValue:
6885 case Decl::Using:
6886 case Decl::UsingDirective:
6887 case Decl::UsingShadow:
6888 return CXLanguage_CPlusPlus;
6889 }
6890
6891 return CXLanguage_C;
6892}
6893
6894extern "C" {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006895
6896static CXAvailabilityKind getCursorAvailabilityForDecl(const Decl *D) {
6897 if (isa<FunctionDecl>(D) && cast<FunctionDecl>(D)->isDeleted())
Manuel Klimek8e3a7ed2015-09-25 17:53:16 +00006898 return CXAvailability_NotAvailable;
Guy Benyei11169dd2012-12-18 14:30:41 +00006899
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006900 switch (D->getAvailability()) {
6901 case AR_Available:
6902 case AR_NotYetIntroduced:
6903 if (const EnumConstantDecl *EnumConst = dyn_cast<EnumConstantDecl>(D))
Benjamin Kramer656363d2013-10-15 18:53:18 +00006904 return getCursorAvailabilityForDecl(
6905 cast<Decl>(EnumConst->getDeclContext()));
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006906 return CXAvailability_Available;
6907
6908 case AR_Deprecated:
6909 return CXAvailability_Deprecated;
6910
6911 case AR_Unavailable:
6912 return CXAvailability_NotAvailable;
6913 }
Benjamin Kramer656363d2013-10-15 18:53:18 +00006914
6915 llvm_unreachable("Unknown availability kind!");
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006916}
6917
Guy Benyei11169dd2012-12-18 14:30:41 +00006918enum CXAvailabilityKind clang_getCursorAvailability(CXCursor cursor) {
6919 if (clang_isDeclaration(cursor.kind))
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006920 if (const Decl *D = cxcursor::getCursorDecl(cursor))
6921 return getCursorAvailabilityForDecl(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00006922
6923 return CXAvailability_Available;
6924}
6925
6926static CXVersion convertVersion(VersionTuple In) {
6927 CXVersion Out = { -1, -1, -1 };
6928 if (In.empty())
6929 return Out;
6930
6931 Out.Major = In.getMajor();
6932
NAKAMURA Takumic2b5d1f2013-02-21 02:32:34 +00006933 Optional<unsigned> Minor = In.getMinor();
6934 if (Minor.hasValue())
Guy Benyei11169dd2012-12-18 14:30:41 +00006935 Out.Minor = *Minor;
6936 else
6937 return Out;
6938
NAKAMURA Takumic2b5d1f2013-02-21 02:32:34 +00006939 Optional<unsigned> Subminor = In.getSubminor();
6940 if (Subminor.hasValue())
Guy Benyei11169dd2012-12-18 14:30:41 +00006941 Out.Subminor = *Subminor;
6942
6943 return Out;
6944}
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006945
6946static int getCursorPlatformAvailabilityForDecl(const Decl *D,
6947 int *always_deprecated,
6948 CXString *deprecated_message,
6949 int *always_unavailable,
6950 CXString *unavailable_message,
6951 CXPlatformAvailability *availability,
6952 int availability_size) {
6953 bool HadAvailAttr = false;
6954 int N = 0;
Aaron Ballmanb97112e2014-03-08 22:19:01 +00006955 for (auto A : D->attrs()) {
6956 if (DeprecatedAttr *Deprecated = dyn_cast<DeprecatedAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006957 HadAvailAttr = true;
6958 if (always_deprecated)
6959 *always_deprecated = 1;
Nico Weberaacf0312014-04-24 05:16:45 +00006960 if (deprecated_message) {
Argyrios Kyrtzidisedfe07f2014-04-24 06:05:40 +00006961 clang_disposeString(*deprecated_message);
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006962 *deprecated_message = cxstring::createDup(Deprecated->getMessage());
Nico Weberaacf0312014-04-24 05:16:45 +00006963 }
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006964 continue;
6965 }
6966
Aaron Ballmanb97112e2014-03-08 22:19:01 +00006967 if (UnavailableAttr *Unavailable = dyn_cast<UnavailableAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006968 HadAvailAttr = true;
6969 if (always_unavailable)
6970 *always_unavailable = 1;
6971 if (unavailable_message) {
Argyrios Kyrtzidisedfe07f2014-04-24 06:05:40 +00006972 clang_disposeString(*unavailable_message);
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006973 *unavailable_message = cxstring::createDup(Unavailable->getMessage());
6974 }
6975 continue;
6976 }
6977
Aaron Ballmanb97112e2014-03-08 22:19:01 +00006978 if (AvailabilityAttr *Avail = dyn_cast<AvailabilityAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006979 HadAvailAttr = true;
6980 if (N < availability_size) {
6981 availability[N].Platform
6982 = cxstring::createDup(Avail->getPlatform()->getName());
6983 availability[N].Introduced = convertVersion(Avail->getIntroduced());
6984 availability[N].Deprecated = convertVersion(Avail->getDeprecated());
6985 availability[N].Obsoleted = convertVersion(Avail->getObsoleted());
6986 availability[N].Unavailable = Avail->getUnavailable();
6987 availability[N].Message = cxstring::createDup(Avail->getMessage());
6988 }
6989 ++N;
6990 }
6991 }
6992
6993 if (!HadAvailAttr)
6994 if (const EnumConstantDecl *EnumConst = dyn_cast<EnumConstantDecl>(D))
6995 return getCursorPlatformAvailabilityForDecl(
6996 cast<Decl>(EnumConst->getDeclContext()),
6997 always_deprecated,
6998 deprecated_message,
6999 always_unavailable,
7000 unavailable_message,
7001 availability,
7002 availability_size);
Guy Benyei11169dd2012-12-18 14:30:41 +00007003
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00007004 return N;
7005}
7006
Guy Benyei11169dd2012-12-18 14:30:41 +00007007int clang_getCursorPlatformAvailability(CXCursor cursor,
7008 int *always_deprecated,
7009 CXString *deprecated_message,
7010 int *always_unavailable,
7011 CXString *unavailable_message,
7012 CXPlatformAvailability *availability,
7013 int availability_size) {
7014 if (always_deprecated)
7015 *always_deprecated = 0;
7016 if (deprecated_message)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00007017 *deprecated_message = cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00007018 if (always_unavailable)
7019 *always_unavailable = 0;
7020 if (unavailable_message)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00007021 *unavailable_message = cxstring::createEmpty();
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00007022
Guy Benyei11169dd2012-12-18 14:30:41 +00007023 if (!clang_isDeclaration(cursor.kind))
7024 return 0;
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00007025
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00007026 const Decl *D = cxcursor::getCursorDecl(cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00007027 if (!D)
7028 return 0;
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00007029
7030 return getCursorPlatformAvailabilityForDecl(D, always_deprecated,
7031 deprecated_message,
7032 always_unavailable,
7033 unavailable_message,
7034 availability,
7035 availability_size);
Guy Benyei11169dd2012-12-18 14:30:41 +00007036}
7037
7038void clang_disposeCXPlatformAvailability(CXPlatformAvailability *availability) {
7039 clang_disposeString(availability->Platform);
7040 clang_disposeString(availability->Message);
7041}
7042
7043CXLanguageKind clang_getCursorLanguage(CXCursor cursor) {
7044 if (clang_isDeclaration(cursor.kind))
7045 return getDeclLanguage(cxcursor::getCursorDecl(cursor));
7046
7047 return CXLanguage_Invalid;
7048}
7049
7050 /// \brief If the given cursor is the "templated" declaration
7051 /// descibing a class or function template, return the class or
7052 /// function template.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00007053static const Decl *maybeGetTemplateCursor(const Decl *D) {
Guy Benyei11169dd2012-12-18 14:30:41 +00007054 if (!D)
Craig Topper69186e72014-06-08 08:38:04 +00007055 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00007056
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00007057 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00007058 if (FunctionTemplateDecl *FunTmpl = FD->getDescribedFunctionTemplate())
7059 return FunTmpl;
7060
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00007061 if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00007062 if (ClassTemplateDecl *ClassTmpl = RD->getDescribedClassTemplate())
7063 return ClassTmpl;
7064
7065 return D;
7066}
7067
Argyrios Kyrtzidis4e0854f2014-10-15 17:05:31 +00007068
7069enum CX_StorageClass clang_Cursor_getStorageClass(CXCursor C) {
7070 StorageClass sc = SC_None;
7071 const Decl *D = getCursorDecl(C);
7072 if (D) {
7073 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
7074 sc = FD->getStorageClass();
7075 } else if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
7076 sc = VD->getStorageClass();
7077 } else {
7078 return CX_SC_Invalid;
7079 }
7080 } else {
7081 return CX_SC_Invalid;
7082 }
7083 switch (sc) {
7084 case SC_None:
7085 return CX_SC_None;
7086 case SC_Extern:
7087 return CX_SC_Extern;
7088 case SC_Static:
7089 return CX_SC_Static;
7090 case SC_PrivateExtern:
7091 return CX_SC_PrivateExtern;
Argyrios Kyrtzidis4e0854f2014-10-15 17:05:31 +00007092 case SC_Auto:
7093 return CX_SC_Auto;
7094 case SC_Register:
7095 return CX_SC_Register;
Argyrios Kyrtzidis4e0854f2014-10-15 17:05:31 +00007096 }
Kaelyn Takataab61e702014-10-15 18:03:26 +00007097 llvm_unreachable("Unhandled storage class!");
Argyrios Kyrtzidis4e0854f2014-10-15 17:05:31 +00007098}
7099
Guy Benyei11169dd2012-12-18 14:30:41 +00007100CXCursor clang_getCursorSemanticParent(CXCursor cursor) {
7101 if (clang_isDeclaration(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00007102 if (const Decl *D = getCursorDecl(cursor)) {
7103 const DeclContext *DC = D->getDeclContext();
Guy Benyei11169dd2012-12-18 14:30:41 +00007104 if (!DC)
7105 return clang_getNullCursor();
7106
7107 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
7108 getCursorTU(cursor));
7109 }
7110 }
7111
7112 if (clang_isStatement(cursor.kind) || clang_isExpression(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00007113 if (const Decl *D = getCursorDecl(cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +00007114 return MakeCXCursor(D, getCursorTU(cursor));
7115 }
7116
7117 return clang_getNullCursor();
7118}
7119
7120CXCursor clang_getCursorLexicalParent(CXCursor cursor) {
7121 if (clang_isDeclaration(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00007122 if (const Decl *D = getCursorDecl(cursor)) {
7123 const DeclContext *DC = D->getLexicalDeclContext();
Guy Benyei11169dd2012-12-18 14:30:41 +00007124 if (!DC)
7125 return clang_getNullCursor();
7126
7127 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
7128 getCursorTU(cursor));
7129 }
7130 }
7131
7132 // FIXME: Note that we can't easily compute the lexical context of a
7133 // statement or expression, so we return nothing.
7134 return clang_getNullCursor();
7135}
7136
7137CXFile clang_getIncludedFile(CXCursor cursor) {
7138 if (cursor.kind != CXCursor_InclusionDirective)
Craig Topper69186e72014-06-08 08:38:04 +00007139 return nullptr;
7140
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00007141 const InclusionDirective *ID = getCursorInclusionDirective(cursor);
Dmitri Gribenkof9304482013-01-23 15:56:07 +00007142 return const_cast<FileEntry *>(ID->getFile());
Guy Benyei11169dd2012-12-18 14:30:41 +00007143}
7144
Argyrios Kyrtzidis9adfd8a2013-04-18 22:15:49 +00007145unsigned clang_Cursor_getObjCPropertyAttributes(CXCursor C, unsigned reserved) {
7146 if (C.kind != CXCursor_ObjCPropertyDecl)
7147 return CXObjCPropertyAttr_noattr;
7148
7149 unsigned Result = CXObjCPropertyAttr_noattr;
7150 const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(getCursorDecl(C));
7151 ObjCPropertyDecl::PropertyAttributeKind Attr =
7152 PD->getPropertyAttributesAsWritten();
7153
7154#define SET_CXOBJCPROP_ATTR(A) \
7155 if (Attr & ObjCPropertyDecl::OBJC_PR_##A) \
7156 Result |= CXObjCPropertyAttr_##A
7157 SET_CXOBJCPROP_ATTR(readonly);
7158 SET_CXOBJCPROP_ATTR(getter);
7159 SET_CXOBJCPROP_ATTR(assign);
7160 SET_CXOBJCPROP_ATTR(readwrite);
7161 SET_CXOBJCPROP_ATTR(retain);
7162 SET_CXOBJCPROP_ATTR(copy);
7163 SET_CXOBJCPROP_ATTR(nonatomic);
7164 SET_CXOBJCPROP_ATTR(setter);
7165 SET_CXOBJCPROP_ATTR(atomic);
7166 SET_CXOBJCPROP_ATTR(weak);
7167 SET_CXOBJCPROP_ATTR(strong);
7168 SET_CXOBJCPROP_ATTR(unsafe_unretained);
7169#undef SET_CXOBJCPROP_ATTR
7170
7171 return Result;
7172}
7173
Argyrios Kyrtzidis9d9bc012013-04-18 23:29:12 +00007174unsigned clang_Cursor_getObjCDeclQualifiers(CXCursor C) {
7175 if (!clang_isDeclaration(C.kind))
7176 return CXObjCDeclQualifier_None;
7177
7178 Decl::ObjCDeclQualifier QT = Decl::OBJC_TQ_None;
7179 const Decl *D = getCursorDecl(C);
7180 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
7181 QT = MD->getObjCDeclQualifier();
7182 else if (const ParmVarDecl *PD = dyn_cast<ParmVarDecl>(D))
7183 QT = PD->getObjCDeclQualifier();
7184 if (QT == Decl::OBJC_TQ_None)
7185 return CXObjCDeclQualifier_None;
7186
7187 unsigned Result = CXObjCDeclQualifier_None;
7188 if (QT & Decl::OBJC_TQ_In) Result |= CXObjCDeclQualifier_In;
7189 if (QT & Decl::OBJC_TQ_Inout) Result |= CXObjCDeclQualifier_Inout;
7190 if (QT & Decl::OBJC_TQ_Out) Result |= CXObjCDeclQualifier_Out;
7191 if (QT & Decl::OBJC_TQ_Bycopy) Result |= CXObjCDeclQualifier_Bycopy;
7192 if (QT & Decl::OBJC_TQ_Byref) Result |= CXObjCDeclQualifier_Byref;
7193 if (QT & Decl::OBJC_TQ_Oneway) Result |= CXObjCDeclQualifier_Oneway;
7194
7195 return Result;
7196}
7197
Argyrios Kyrtzidis7b50fc52013-07-05 20:44:37 +00007198unsigned clang_Cursor_isObjCOptional(CXCursor C) {
7199 if (!clang_isDeclaration(C.kind))
7200 return 0;
7201
7202 const Decl *D = getCursorDecl(C);
7203 if (const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(D))
7204 return PD->getPropertyImplementation() == ObjCPropertyDecl::Optional;
7205 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
7206 return MD->getImplementationControl() == ObjCMethodDecl::Optional;
7207
7208 return 0;
7209}
7210
Argyrios Kyrtzidis23814e42013-04-18 23:53:05 +00007211unsigned clang_Cursor_isVariadic(CXCursor C) {
7212 if (!clang_isDeclaration(C.kind))
7213 return 0;
7214
7215 const Decl *D = getCursorDecl(C);
7216 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
7217 return FD->isVariadic();
7218 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
7219 return MD->isVariadic();
7220
7221 return 0;
7222}
7223
Guy Benyei11169dd2012-12-18 14:30:41 +00007224CXSourceRange clang_Cursor_getCommentRange(CXCursor C) {
7225 if (!clang_isDeclaration(C.kind))
7226 return clang_getNullRange();
7227
7228 const Decl *D = getCursorDecl(C);
7229 ASTContext &Context = getCursorContext(C);
7230 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
7231 if (!RC)
7232 return clang_getNullRange();
7233
7234 return cxloc::translateSourceRange(Context, RC->getSourceRange());
7235}
7236
7237CXString clang_Cursor_getRawCommentText(CXCursor C) {
7238 if (!clang_isDeclaration(C.kind))
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00007239 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00007240
7241 const Decl *D = getCursorDecl(C);
7242 ASTContext &Context = getCursorContext(C);
7243 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
7244 StringRef RawText = RC ? RC->getRawText(Context.getSourceManager()) :
7245 StringRef();
7246
7247 // Don't duplicate the string because RawText points directly into source
7248 // code.
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00007249 return cxstring::createRef(RawText);
Guy Benyei11169dd2012-12-18 14:30:41 +00007250}
7251
7252CXString clang_Cursor_getBriefCommentText(CXCursor C) {
7253 if (!clang_isDeclaration(C.kind))
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00007254 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00007255
7256 const Decl *D = getCursorDecl(C);
7257 const ASTContext &Context = getCursorContext(C);
7258 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
7259
7260 if (RC) {
7261 StringRef BriefText = RC->getBriefText(Context);
7262
7263 // Don't duplicate the string because RawComment ensures that this memory
7264 // will not go away.
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00007265 return cxstring::createRef(BriefText);
Guy Benyei11169dd2012-12-18 14:30:41 +00007266 }
7267
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00007268 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00007269}
7270
Guy Benyei11169dd2012-12-18 14:30:41 +00007271CXModule clang_Cursor_getModule(CXCursor C) {
7272 if (C.kind == CXCursor_ModuleImportDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00007273 if (const ImportDecl *ImportD =
7274 dyn_cast_or_null<ImportDecl>(getCursorDecl(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00007275 return ImportD->getImportedModule();
7276 }
7277
Craig Topper69186e72014-06-08 08:38:04 +00007278 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00007279}
7280
Argyrios Kyrtzidisf6d49c32014-05-14 23:14:37 +00007281CXModule clang_getModuleForFile(CXTranslationUnit TU, CXFile File) {
7282 if (isNotUsableTU(TU)) {
7283 LOG_BAD_TU(TU);
7284 return nullptr;
7285 }
7286 if (!File)
7287 return nullptr;
7288 FileEntry *FE = static_cast<FileEntry *>(File);
7289
7290 ASTUnit &Unit = *cxtu::getASTUnit(TU);
7291 HeaderSearch &HS = Unit.getPreprocessor().getHeaderSearchInfo();
7292 ModuleMap::KnownHeader Header = HS.findModuleForHeader(FE);
7293
Richard Smithfeb54b62014-10-23 02:01:19 +00007294 return Header.getModule();
Argyrios Kyrtzidisf6d49c32014-05-14 23:14:37 +00007295}
7296
Argyrios Kyrtzidis12fdb9e2013-04-26 22:47:49 +00007297CXFile clang_Module_getASTFile(CXModule CXMod) {
7298 if (!CXMod)
Craig Topper69186e72014-06-08 08:38:04 +00007299 return nullptr;
Argyrios Kyrtzidis12fdb9e2013-04-26 22:47:49 +00007300 Module *Mod = static_cast<Module*>(CXMod);
7301 return const_cast<FileEntry *>(Mod->getASTFile());
7302}
7303
Guy Benyei11169dd2012-12-18 14:30:41 +00007304CXModule clang_Module_getParent(CXModule CXMod) {
7305 if (!CXMod)
Craig Topper69186e72014-06-08 08:38:04 +00007306 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00007307 Module *Mod = static_cast<Module*>(CXMod);
7308 return Mod->Parent;
7309}
7310
7311CXString clang_Module_getName(CXModule CXMod) {
7312 if (!CXMod)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00007313 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00007314 Module *Mod = static_cast<Module*>(CXMod);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00007315 return cxstring::createDup(Mod->Name);
Guy Benyei11169dd2012-12-18 14:30:41 +00007316}
7317
7318CXString clang_Module_getFullName(CXModule CXMod) {
7319 if (!CXMod)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00007320 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00007321 Module *Mod = static_cast<Module*>(CXMod);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00007322 return cxstring::createDup(Mod->getFullModuleName());
Guy Benyei11169dd2012-12-18 14:30:41 +00007323}
7324
Argyrios Kyrtzidis884337f2014-05-15 04:44:25 +00007325int clang_Module_isSystem(CXModule CXMod) {
7326 if (!CXMod)
7327 return 0;
7328 Module *Mod = static_cast<Module*>(CXMod);
7329 return Mod->IsSystem;
7330}
7331
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00007332unsigned clang_Module_getNumTopLevelHeaders(CXTranslationUnit TU,
7333 CXModule CXMod) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00007334 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00007335 LOG_BAD_TU(TU);
7336 return 0;
7337 }
7338 if (!CXMod)
Guy Benyei11169dd2012-12-18 14:30:41 +00007339 return 0;
7340 Module *Mod = static_cast<Module*>(CXMod);
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00007341 FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
7342 ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
7343 return TopHeaders.size();
Guy Benyei11169dd2012-12-18 14:30:41 +00007344}
7345
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00007346CXFile clang_Module_getTopLevelHeader(CXTranslationUnit TU,
7347 CXModule CXMod, unsigned Index) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00007348 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00007349 LOG_BAD_TU(TU);
Craig Topper69186e72014-06-08 08:38:04 +00007350 return nullptr;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00007351 }
7352 if (!CXMod)
Craig Topper69186e72014-06-08 08:38:04 +00007353 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00007354 Module *Mod = static_cast<Module*>(CXMod);
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00007355 FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
Guy Benyei11169dd2012-12-18 14:30:41 +00007356
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00007357 ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
7358 if (Index < TopHeaders.size())
7359 return const_cast<FileEntry *>(TopHeaders[Index]);
Guy Benyei11169dd2012-12-18 14:30:41 +00007360
Craig Topper69186e72014-06-08 08:38:04 +00007361 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00007362}
7363
7364} // end: extern "C"
7365
7366//===----------------------------------------------------------------------===//
7367// C++ AST instrospection.
7368//===----------------------------------------------------------------------===//
7369
7370extern "C" {
Jonathan Coe29565352016-04-27 12:48:25 +00007371
7372unsigned clang_CXXConstructor_isDefaultConstructor(CXCursor C) {
7373 if (!clang_isDeclaration(C.kind))
7374 return 0;
7375
7376 const Decl *D = cxcursor::getCursorDecl(C);
7377 const CXXConstructorDecl *Constructor =
7378 D ? dyn_cast_or_null<CXXConstructorDecl>(D->getAsFunction()) : nullptr;
7379 return (Constructor && Constructor->isDefaultConstructor()) ? 1 : 0;
7380}
7381
7382unsigned clang_CXXConstructor_isCopyConstructor(CXCursor C) {
7383 if (!clang_isDeclaration(C.kind))
7384 return 0;
7385
7386 const Decl *D = cxcursor::getCursorDecl(C);
7387 const CXXConstructorDecl *Constructor =
7388 D ? dyn_cast_or_null<CXXConstructorDecl>(D->getAsFunction()) : nullptr;
7389 return (Constructor && Constructor->isCopyConstructor()) ? 1 : 0;
7390}
7391
7392unsigned clang_CXXConstructor_isMoveConstructor(CXCursor C) {
7393 if (!clang_isDeclaration(C.kind))
7394 return 0;
7395
7396 const Decl *D = cxcursor::getCursorDecl(C);
7397 const CXXConstructorDecl *Constructor =
7398 D ? dyn_cast_or_null<CXXConstructorDecl>(D->getAsFunction()) : nullptr;
7399 return (Constructor && Constructor->isMoveConstructor()) ? 1 : 0;
7400}
7401
7402unsigned clang_CXXConstructor_isConvertingConstructor(CXCursor C) {
7403 if (!clang_isDeclaration(C.kind))
7404 return 0;
7405
7406 const Decl *D = cxcursor::getCursorDecl(C);
7407 const CXXConstructorDecl *Constructor =
7408 D ? dyn_cast_or_null<CXXConstructorDecl>(D->getAsFunction()) : nullptr;
7409 // Passing 'false' excludes constructors marked 'explicit'.
7410 return (Constructor && Constructor->isConvertingConstructor(false)) ? 1 : 0;
7411}
7412
Saleem Abdulrasool6ea75db2015-10-27 15:50:22 +00007413unsigned clang_CXXField_isMutable(CXCursor C) {
7414 if (!clang_isDeclaration(C.kind))
7415 return 0;
7416
7417 if (const auto D = cxcursor::getCursorDecl(C))
7418 if (const auto FD = dyn_cast_or_null<FieldDecl>(D))
7419 return FD->isMutable() ? 1 : 0;
7420 return 0;
7421}
7422
Dmitri Gribenko62770be2013-05-17 18:38:35 +00007423unsigned clang_CXXMethod_isPureVirtual(CXCursor C) {
7424 if (!clang_isDeclaration(C.kind))
7425 return 0;
7426
Dmitri Gribenko62770be2013-05-17 18:38:35 +00007427 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00007428 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00007429 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Dmitri Gribenko62770be2013-05-17 18:38:35 +00007430 return (Method && Method->isVirtual() && Method->isPure()) ? 1 : 0;
7431}
7432
Dmitri Gribenkoe570ede2014-04-07 14:59:13 +00007433unsigned clang_CXXMethod_isConst(CXCursor C) {
7434 if (!clang_isDeclaration(C.kind))
7435 return 0;
7436
7437 const Decl *D = cxcursor::getCursorDecl(C);
7438 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00007439 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Dmitri Gribenkoe570ede2014-04-07 14:59:13 +00007440 return (Method && (Method->getTypeQualifiers() & Qualifiers::Const)) ? 1 : 0;
7441}
7442
Jonathan Coe29565352016-04-27 12:48:25 +00007443unsigned clang_CXXMethod_isDefaulted(CXCursor C) {
7444 if (!clang_isDeclaration(C.kind))
7445 return 0;
7446
7447 const Decl *D = cxcursor::getCursorDecl(C);
7448 const CXXMethodDecl *Method =
7449 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
7450 return (Method && Method->isDefaulted()) ? 1 : 0;
7451}
7452
Guy Benyei11169dd2012-12-18 14:30:41 +00007453unsigned clang_CXXMethod_isStatic(CXCursor C) {
7454 if (!clang_isDeclaration(C.kind))
7455 return 0;
7456
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00007457 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00007458 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00007459 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00007460 return (Method && Method->isStatic()) ? 1 : 0;
7461}
7462
7463unsigned clang_CXXMethod_isVirtual(CXCursor C) {
7464 if (!clang_isDeclaration(C.kind))
7465 return 0;
7466
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00007467 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00007468 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00007469 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00007470 return (Method && Method->isVirtual()) ? 1 : 0;
7471}
7472} // end: extern "C"
7473
7474//===----------------------------------------------------------------------===//
7475// Attribute introspection.
7476//===----------------------------------------------------------------------===//
7477
7478extern "C" {
7479CXType clang_getIBOutletCollectionType(CXCursor C) {
7480 if (C.kind != CXCursor_IBOutletCollectionAttr)
7481 return cxtype::MakeCXType(QualType(), cxcursor::getCursorTU(C));
7482
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00007483 const IBOutletCollectionAttr *A =
Guy Benyei11169dd2012-12-18 14:30:41 +00007484 cast<IBOutletCollectionAttr>(cxcursor::getCursorAttr(C));
7485
7486 return cxtype::MakeCXType(A->getInterface(), cxcursor::getCursorTU(C));
7487}
7488} // end: extern "C"
7489
7490//===----------------------------------------------------------------------===//
7491// Inspecting memory usage.
7492//===----------------------------------------------------------------------===//
7493
7494typedef std::vector<CXTUResourceUsageEntry> MemUsageEntries;
7495
7496static inline void createCXTUResourceUsageEntry(MemUsageEntries &entries,
7497 enum CXTUResourceUsageKind k,
7498 unsigned long amount) {
7499 CXTUResourceUsageEntry entry = { k, amount };
7500 entries.push_back(entry);
7501}
7502
7503extern "C" {
7504
7505const char *clang_getTUResourceUsageName(CXTUResourceUsageKind kind) {
7506 const char *str = "";
7507 switch (kind) {
7508 case CXTUResourceUsage_AST:
7509 str = "ASTContext: expressions, declarations, and types";
7510 break;
7511 case CXTUResourceUsage_Identifiers:
7512 str = "ASTContext: identifiers";
7513 break;
7514 case CXTUResourceUsage_Selectors:
7515 str = "ASTContext: selectors";
7516 break;
7517 case CXTUResourceUsage_GlobalCompletionResults:
7518 str = "Code completion: cached global results";
7519 break;
7520 case CXTUResourceUsage_SourceManagerContentCache:
7521 str = "SourceManager: content cache allocator";
7522 break;
7523 case CXTUResourceUsage_AST_SideTables:
7524 str = "ASTContext: side tables";
7525 break;
7526 case CXTUResourceUsage_SourceManager_Membuffer_Malloc:
7527 str = "SourceManager: malloc'ed memory buffers";
7528 break;
7529 case CXTUResourceUsage_SourceManager_Membuffer_MMap:
7530 str = "SourceManager: mmap'ed memory buffers";
7531 break;
7532 case CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc:
7533 str = "ExternalASTSource: malloc'ed memory buffers";
7534 break;
7535 case CXTUResourceUsage_ExternalASTSource_Membuffer_MMap:
7536 str = "ExternalASTSource: mmap'ed memory buffers";
7537 break;
7538 case CXTUResourceUsage_Preprocessor:
7539 str = "Preprocessor: malloc'ed memory";
7540 break;
7541 case CXTUResourceUsage_PreprocessingRecord:
7542 str = "Preprocessor: PreprocessingRecord";
7543 break;
7544 case CXTUResourceUsage_SourceManager_DataStructures:
7545 str = "SourceManager: data structures and tables";
7546 break;
7547 case CXTUResourceUsage_Preprocessor_HeaderSearch:
7548 str = "Preprocessor: header search tables";
7549 break;
7550 }
7551 return str;
7552}
7553
7554CXTUResourceUsage clang_getCXTUResourceUsage(CXTranslationUnit TU) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00007555 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00007556 LOG_BAD_TU(TU);
Craig Topper69186e72014-06-08 08:38:04 +00007557 CXTUResourceUsage usage = { (void*) nullptr, 0, nullptr };
Guy Benyei11169dd2012-12-18 14:30:41 +00007558 return usage;
7559 }
7560
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007561 ASTUnit *astUnit = cxtu::getASTUnit(TU);
Ahmed Charlesb8984322014-03-07 20:03:18 +00007562 std::unique_ptr<MemUsageEntries> entries(new MemUsageEntries());
Guy Benyei11169dd2012-12-18 14:30:41 +00007563 ASTContext &astContext = astUnit->getASTContext();
7564
7565 // How much memory is used by AST nodes and types?
7566 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST,
7567 (unsigned long) astContext.getASTAllocatedMemory());
7568
7569 // How much memory is used by identifiers?
7570 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Identifiers,
7571 (unsigned long) astContext.Idents.getAllocator().getTotalMemory());
7572
7573 // How much memory is used for selectors?
7574 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Selectors,
7575 (unsigned long) astContext.Selectors.getTotalMemory());
7576
7577 // How much memory is used by ASTContext's side tables?
7578 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST_SideTables,
7579 (unsigned long) astContext.getSideTableAllocatedMemory());
7580
7581 // How much memory is used for caching global code completion results?
7582 unsigned long completionBytes = 0;
7583 if (GlobalCodeCompletionAllocator *completionAllocator =
Alp Tokerf994cef2014-07-05 03:08:06 +00007584 astUnit->getCachedCompletionAllocator().get()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00007585 completionBytes = completionAllocator->getTotalMemory();
7586 }
7587 createCXTUResourceUsageEntry(*entries,
7588 CXTUResourceUsage_GlobalCompletionResults,
7589 completionBytes);
7590
7591 // How much memory is being used by SourceManager's content cache?
7592 createCXTUResourceUsageEntry(*entries,
7593 CXTUResourceUsage_SourceManagerContentCache,
7594 (unsigned long) astContext.getSourceManager().getContentCacheSize());
7595
7596 // How much memory is being used by the MemoryBuffer's in SourceManager?
7597 const SourceManager::MemoryBufferSizes &srcBufs =
7598 astUnit->getSourceManager().getMemoryBufferSizes();
7599
7600 createCXTUResourceUsageEntry(*entries,
7601 CXTUResourceUsage_SourceManager_Membuffer_Malloc,
7602 (unsigned long) srcBufs.malloc_bytes);
7603 createCXTUResourceUsageEntry(*entries,
7604 CXTUResourceUsage_SourceManager_Membuffer_MMap,
7605 (unsigned long) srcBufs.mmap_bytes);
7606 createCXTUResourceUsageEntry(*entries,
7607 CXTUResourceUsage_SourceManager_DataStructures,
7608 (unsigned long) astContext.getSourceManager()
7609 .getDataStructureSizes());
7610
7611 // How much memory is being used by the ExternalASTSource?
7612 if (ExternalASTSource *esrc = astContext.getExternalSource()) {
7613 const ExternalASTSource::MemoryBufferSizes &sizes =
7614 esrc->getMemoryBufferSizes();
7615
7616 createCXTUResourceUsageEntry(*entries,
7617 CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc,
7618 (unsigned long) sizes.malloc_bytes);
7619 createCXTUResourceUsageEntry(*entries,
7620 CXTUResourceUsage_ExternalASTSource_Membuffer_MMap,
7621 (unsigned long) sizes.mmap_bytes);
7622 }
7623
7624 // How much memory is being used by the Preprocessor?
7625 Preprocessor &pp = astUnit->getPreprocessor();
7626 createCXTUResourceUsageEntry(*entries,
7627 CXTUResourceUsage_Preprocessor,
7628 pp.getTotalMemory());
7629
7630 if (PreprocessingRecord *pRec = pp.getPreprocessingRecord()) {
7631 createCXTUResourceUsageEntry(*entries,
7632 CXTUResourceUsage_PreprocessingRecord,
7633 pRec->getTotalMemory());
7634 }
7635
7636 createCXTUResourceUsageEntry(*entries,
7637 CXTUResourceUsage_Preprocessor_HeaderSearch,
7638 pp.getHeaderSearchInfo().getTotalMemory());
Craig Topper69186e72014-06-08 08:38:04 +00007639
Guy Benyei11169dd2012-12-18 14:30:41 +00007640 CXTUResourceUsage usage = { (void*) entries.get(),
7641 (unsigned) entries->size(),
Alexander Kornienko6ee521c2015-01-23 15:36:10 +00007642 !entries->empty() ? &(*entries)[0] : nullptr };
Ahmed Charles9a16beb2014-03-07 19:33:25 +00007643 entries.release();
Guy Benyei11169dd2012-12-18 14:30:41 +00007644 return usage;
7645}
7646
7647void clang_disposeCXTUResourceUsage(CXTUResourceUsage usage) {
7648 if (usage.data)
7649 delete (MemUsageEntries*) usage.data;
7650}
7651
Argyrios Kyrtzidis0e282ef2013-12-06 18:55:45 +00007652CXSourceRangeList *clang_getSkippedRanges(CXTranslationUnit TU, CXFile file) {
7653 CXSourceRangeList *skipped = new CXSourceRangeList;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00007654 skipped->count = 0;
Craig Topper69186e72014-06-08 08:38:04 +00007655 skipped->ranges = nullptr;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00007656
Dmitri Gribenko852d6222014-02-11 15:02:48 +00007657 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00007658 LOG_BAD_TU(TU);
7659 return skipped;
7660 }
7661
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00007662 if (!file)
7663 return skipped;
7664
7665 ASTUnit *astUnit = cxtu::getASTUnit(TU);
7666 PreprocessingRecord *ppRec = astUnit->getPreprocessor().getPreprocessingRecord();
7667 if (!ppRec)
7668 return skipped;
7669
7670 ASTContext &Ctx = astUnit->getASTContext();
7671 SourceManager &sm = Ctx.getSourceManager();
7672 FileEntry *fileEntry = static_cast<FileEntry *>(file);
7673 FileID wantedFileID = sm.translateFile(fileEntry);
7674
7675 const std::vector<SourceRange> &SkippedRanges = ppRec->getSkippedRanges();
7676 std::vector<SourceRange> wantedRanges;
7677 for (std::vector<SourceRange>::const_iterator i = SkippedRanges.begin(), ei = SkippedRanges.end();
7678 i != ei; ++i) {
7679 if (sm.getFileID(i->getBegin()) == wantedFileID || sm.getFileID(i->getEnd()) == wantedFileID)
7680 wantedRanges.push_back(*i);
7681 }
7682
7683 skipped->count = wantedRanges.size();
7684 skipped->ranges = new CXSourceRange[skipped->count];
7685 for (unsigned i = 0, ei = skipped->count; i != ei; ++i)
7686 skipped->ranges[i] = cxloc::translateSourceRange(Ctx, wantedRanges[i]);
7687
7688 return skipped;
7689}
7690
Argyrios Kyrtzidis0e282ef2013-12-06 18:55:45 +00007691void clang_disposeSourceRangeList(CXSourceRangeList *ranges) {
7692 if (ranges) {
7693 delete[] ranges->ranges;
7694 delete ranges;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00007695 }
7696}
7697
Guy Benyei11169dd2012-12-18 14:30:41 +00007698} // end extern "C"
7699
7700void clang::PrintLibclangResourceUsage(CXTranslationUnit TU) {
7701 CXTUResourceUsage Usage = clang_getCXTUResourceUsage(TU);
7702 for (unsigned I = 0; I != Usage.numEntries; ++I)
7703 fprintf(stderr, " %s: %lu\n",
7704 clang_getTUResourceUsageName(Usage.entries[I].kind),
7705 Usage.entries[I].amount);
7706
7707 clang_disposeCXTUResourceUsage(Usage);
7708}
7709
7710//===----------------------------------------------------------------------===//
7711// Misc. utility functions.
7712//===----------------------------------------------------------------------===//
7713
7714/// Default to using an 8 MB stack size on "safety" threads.
7715static unsigned SafetyStackThreadSize = 8 << 20;
7716
7717namespace clang {
7718
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00007719bool RunSafely(llvm::CrashRecoveryContext &CRC, llvm::function_ref<void()> Fn,
Guy Benyei11169dd2012-12-18 14:30:41 +00007720 unsigned Size) {
7721 if (!Size)
7722 Size = GetSafetyThreadStackSize();
7723 if (Size)
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00007724 return CRC.RunSafelyOnThread(Fn, Size);
7725 return CRC.RunSafely(Fn);
Guy Benyei11169dd2012-12-18 14:30:41 +00007726}
7727
7728unsigned GetSafetyThreadStackSize() {
7729 return SafetyStackThreadSize;
7730}
7731
7732void SetSafetyThreadStackSize(unsigned Value) {
7733 SafetyStackThreadSize = Value;
7734}
7735
Alexander Kornienkoab9db512015-06-22 23:07:51 +00007736}
Guy Benyei11169dd2012-12-18 14:30:41 +00007737
7738void clang::setThreadBackgroundPriority() {
7739 if (getenv("LIBCLANG_BGPRIO_DISABLE"))
7740 return;
7741
Alp Toker1a86ad22014-07-06 06:24:00 +00007742#ifdef USE_DARWIN_THREADS
Guy Benyei11169dd2012-12-18 14:30:41 +00007743 setpriority(PRIO_DARWIN_THREAD, 0, PRIO_DARWIN_BG);
7744#endif
7745}
7746
7747void cxindex::printDiagsToStderr(ASTUnit *Unit) {
7748 if (!Unit)
7749 return;
7750
7751 for (ASTUnit::stored_diag_iterator D = Unit->stored_diag_begin(),
7752 DEnd = Unit->stored_diag_end();
7753 D != DEnd; ++D) {
Ben Langmuir749323f2014-04-22 17:40:12 +00007754 CXStoredDiagnostic Diag(*D, Unit->getLangOpts());
Guy Benyei11169dd2012-12-18 14:30:41 +00007755 CXString Msg = clang_formatDiagnostic(&Diag,
7756 clang_defaultDiagnosticDisplayOptions());
7757 fprintf(stderr, "%s\n", clang_getCString(Msg));
7758 clang_disposeString(Msg);
7759 }
7760#ifdef LLVM_ON_WIN32
7761 // On Windows, force a flush, since there may be multiple copies of
7762 // stderr and stdout in the file system, all with different buffers
7763 // but writing to the same device.
7764 fflush(stderr);
7765#endif
7766}
7767
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007768MacroInfo *cxindex::getMacroInfo(const IdentifierInfo &II,
7769 SourceLocation MacroDefLoc,
7770 CXTranslationUnit TU){
7771 if (MacroDefLoc.isInvalid() || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00007772 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007773 if (!II.hadMacroDefinition())
Craig Topper69186e72014-06-08 08:38:04 +00007774 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007775
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007776 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00007777 Preprocessor &PP = Unit->getPreprocessor();
Richard Smith20e883e2015-04-29 23:20:19 +00007778 MacroDirective *MD = PP.getLocalMacroDirectiveHistory(&II);
Argyrios Kyrtzidisb6210df2013-03-26 17:17:01 +00007779 if (MD) {
7780 for (MacroDirective::DefInfo
7781 Def = MD->getDefinition(); Def; Def = Def.getPreviousDefinition()) {
7782 if (MacroDefLoc == Def.getMacroInfo()->getDefinitionLoc())
7783 return Def.getMacroInfo();
7784 }
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007785 }
7786
Craig Topper69186e72014-06-08 08:38:04 +00007787 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007788}
7789
Richard Smith66a81862015-05-04 02:25:31 +00007790const MacroInfo *cxindex::getMacroInfo(const MacroDefinitionRecord *MacroDef,
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00007791 CXTranslationUnit TU) {
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007792 if (!MacroDef || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00007793 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007794 const IdentifierInfo *II = MacroDef->getName();
7795 if (!II)
Craig Topper69186e72014-06-08 08:38:04 +00007796 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007797
7798 return getMacroInfo(*II, MacroDef->getLocation(), TU);
7799}
7800
Richard Smith66a81862015-05-04 02:25:31 +00007801MacroDefinitionRecord *
7802cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI, const Token &Tok,
7803 CXTranslationUnit TU) {
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007804 if (!MI || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00007805 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007806 if (Tok.isNot(tok::raw_identifier))
Craig Topper69186e72014-06-08 08:38:04 +00007807 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007808
7809 if (MI->getNumTokens() == 0)
Craig Topper69186e72014-06-08 08:38:04 +00007810 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007811 SourceRange DefRange(MI->getReplacementToken(0).getLocation(),
7812 MI->getDefinitionEndLoc());
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007813 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007814
7815 // Check that the token is inside the definition and not its argument list.
7816 SourceManager &SM = Unit->getSourceManager();
7817 if (SM.isBeforeInTranslationUnit(Tok.getLocation(), DefRange.getBegin()))
Craig Topper69186e72014-06-08 08:38:04 +00007818 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007819 if (SM.isBeforeInTranslationUnit(DefRange.getEnd(), Tok.getLocation()))
Craig Topper69186e72014-06-08 08:38:04 +00007820 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007821
7822 Preprocessor &PP = Unit->getPreprocessor();
7823 PreprocessingRecord *PPRec = PP.getPreprocessingRecord();
7824 if (!PPRec)
Craig Topper69186e72014-06-08 08:38:04 +00007825 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007826
Alp Toker2d57cea2014-05-17 04:53:25 +00007827 IdentifierInfo &II = PP.getIdentifierTable().get(Tok.getRawIdentifier());
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007828 if (!II.hadMacroDefinition())
Craig Topper69186e72014-06-08 08:38:04 +00007829 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007830
7831 // Check that the identifier is not one of the macro arguments.
7832 if (std::find(MI->arg_begin(), MI->arg_end(), &II) != MI->arg_end())
Craig Topper69186e72014-06-08 08:38:04 +00007833 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007834
Richard Smith20e883e2015-04-29 23:20:19 +00007835 MacroDirective *InnerMD = PP.getLocalMacroDirectiveHistory(&II);
Argyrios Kyrtzidis09c9e812013-02-20 00:54:57 +00007836 if (!InnerMD)
Craig Topper69186e72014-06-08 08:38:04 +00007837 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007838
Argyrios Kyrtzidisb6210df2013-03-26 17:17:01 +00007839 return PPRec->findMacroDefinition(InnerMD->getMacroInfo());
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007840}
7841
Richard Smith66a81862015-05-04 02:25:31 +00007842MacroDefinitionRecord *
7843cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI, SourceLocation Loc,
7844 CXTranslationUnit TU) {
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007845 if (Loc.isInvalid() || !MI || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00007846 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007847
7848 if (MI->getNumTokens() == 0)
Craig Topper69186e72014-06-08 08:38:04 +00007849 return nullptr;
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007850 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007851 Preprocessor &PP = Unit->getPreprocessor();
7852 if (!PP.getPreprocessingRecord())
Craig Topper69186e72014-06-08 08:38:04 +00007853 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007854 Loc = Unit->getSourceManager().getSpellingLoc(Loc);
7855 Token Tok;
7856 if (PP.getRawToken(Loc, Tok))
Craig Topper69186e72014-06-08 08:38:04 +00007857 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007858
7859 return checkForMacroInMacroDefinition(MI, Tok, TU);
7860}
7861
Guy Benyei11169dd2012-12-18 14:30:41 +00007862extern "C" {
7863
7864CXString clang_getClangVersion() {
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00007865 return cxstring::createDup(getClangFullVersion());
Guy Benyei11169dd2012-12-18 14:30:41 +00007866}
7867
7868} // end: extern "C"
7869
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007870Logger &cxindex::Logger::operator<<(CXTranslationUnit TU) {
7871 if (TU) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007872 if (ASTUnit *Unit = cxtu::getASTUnit(TU)) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007873 LogOS << '<' << Unit->getMainFileName() << '>';
Argyrios Kyrtzidis37f2ab42013-03-05 20:21:14 +00007874 if (Unit->isMainFileAST())
7875 LogOS << " (" << Unit->getASTFileName() << ')';
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007876 return *this;
7877 }
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00007878 } else {
7879 LogOS << "<NULL TU>";
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007880 }
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007881 return *this;
7882}
7883
Argyrios Kyrtzidisba4b5f82013-03-08 02:32:26 +00007884Logger &cxindex::Logger::operator<<(const FileEntry *FE) {
7885 *this << FE->getName();
7886 return *this;
7887}
7888
7889Logger &cxindex::Logger::operator<<(CXCursor cursor) {
7890 CXString cursorName = clang_getCursorDisplayName(cursor);
7891 *this << cursorName << "@" << clang_getCursorLocation(cursor);
7892 clang_disposeString(cursorName);
7893 return *this;
7894}
7895
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007896Logger &cxindex::Logger::operator<<(CXSourceLocation Loc) {
7897 CXFile File;
7898 unsigned Line, Column;
Craig Topper69186e72014-06-08 08:38:04 +00007899 clang_getFileLocation(Loc, &File, &Line, &Column, nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007900 CXString FileName = clang_getFileName(File);
7901 *this << llvm::format("(%s:%d:%d)", clang_getCString(FileName), Line, Column);
7902 clang_disposeString(FileName);
7903 return *this;
7904}
7905
7906Logger &cxindex::Logger::operator<<(CXSourceRange range) {
7907 CXSourceLocation BLoc = clang_getRangeStart(range);
7908 CXSourceLocation ELoc = clang_getRangeEnd(range);
7909
7910 CXFile BFile;
7911 unsigned BLine, BColumn;
Craig Topper69186e72014-06-08 08:38:04 +00007912 clang_getFileLocation(BLoc, &BFile, &BLine, &BColumn, nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007913
7914 CXFile EFile;
7915 unsigned ELine, EColumn;
Craig Topper69186e72014-06-08 08:38:04 +00007916 clang_getFileLocation(ELoc, &EFile, &ELine, &EColumn, nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007917
7918 CXString BFileName = clang_getFileName(BFile);
7919 if (BFile == EFile) {
7920 *this << llvm::format("[%s %d:%d-%d:%d]", clang_getCString(BFileName),
7921 BLine, BColumn, ELine, EColumn);
7922 } else {
7923 CXString EFileName = clang_getFileName(EFile);
7924 *this << llvm::format("[%s:%d:%d - ", clang_getCString(BFileName),
7925 BLine, BColumn)
7926 << llvm::format("%s:%d:%d]", clang_getCString(EFileName),
7927 ELine, EColumn);
7928 clang_disposeString(EFileName);
7929 }
7930 clang_disposeString(BFileName);
7931 return *this;
7932}
7933
7934Logger &cxindex::Logger::operator<<(CXString Str) {
7935 *this << clang_getCString(Str);
7936 return *this;
7937}
7938
7939Logger &cxindex::Logger::operator<<(const llvm::format_object_base &Fmt) {
7940 LogOS << Fmt;
7941 return *this;
7942}
7943
Chandler Carruth37ad2582014-06-27 15:14:39 +00007944static llvm::ManagedStatic<llvm::sys::Mutex> LoggingMutex;
7945
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007946cxindex::Logger::~Logger() {
Chandler Carruth37ad2582014-06-27 15:14:39 +00007947 llvm::sys::ScopedLock L(*LoggingMutex);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007948
7949 static llvm::TimeRecord sBeginTR = llvm::TimeRecord::getCurrentTime();
7950
Dmitri Gribenkof8579502013-01-12 19:30:44 +00007951 raw_ostream &OS = llvm::errs();
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007952 OS << "[libclang:" << Name << ':';
7953
Alp Toker1a86ad22014-07-06 06:24:00 +00007954#ifdef USE_DARWIN_THREADS
7955 // TODO: Portability.
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007956 mach_port_t tid = pthread_mach_thread_np(pthread_self());
7957 OS << tid << ':';
7958#endif
7959
7960 llvm::TimeRecord TR = llvm::TimeRecord::getCurrentTime();
7961 OS << llvm::format("%7.4f] ", TR.getWallTime() - sBeginTR.getWallTime());
Yaron Keren09fb7c62015-03-10 07:33:23 +00007962 OS << Msg << '\n';
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007963
7964 if (Trace) {
Zachary Turner1fe2a8d2015-03-05 19:15:09 +00007965 llvm::sys::PrintStackTrace(OS);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007966 OS << "--------------------------------------------------\n";
7967 }
7968}
Benjamin Kramerc1ffdab2016-03-03 08:58:18 +00007969
7970#ifdef CLANG_TOOL_EXTRA_BUILD
7971// This anchor is used to force the linker to link the clang-tidy plugin.
7972extern volatile int ClangTidyPluginAnchorSource;
7973static int LLVM_ATTRIBUTE_UNUSED ClangTidyPluginAnchorDestination =
7974 ClangTidyPluginAnchorSource;
7975#endif