blob: 29e47fc66006e428830c9840a1b392e8b183e73d [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}
Alexander Kornienkoab9db512015-06-22 23:07:51 +00002252}
Alexey Bataev756c1962013-09-24 03:17:45 +00002253
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002254void EnqueueVisitor::EnqueueChildren(const OMPClause *S) {
2255 unsigned size = WL.size();
2256 OMPClauseEnqueue Visitor(this);
2257 Visitor.Visit(S);
2258 if (size == WL.size())
2259 return;
2260 // Now reverse the entries we just added. This will match the DFS
2261 // ordering performed by the worklist.
2262 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
2263 std::reverse(I, E);
2264}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002265void EnqueueVisitor::VisitAddrLabelExpr(const AddrLabelExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002266 WL.push_back(LabelRefVisit(E->getLabel(), E->getLabelLoc(), Parent));
2267}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002268void EnqueueVisitor::VisitBlockExpr(const BlockExpr *B) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002269 AddDecl(B->getBlockDecl());
2270}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002271void EnqueueVisitor::VisitCompoundLiteralExpr(const CompoundLiteralExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002272 EnqueueChildren(E);
2273 AddTypeLoc(E->getTypeSourceInfo());
2274}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002275void EnqueueVisitor::VisitCompoundStmt(const CompoundStmt *S) {
Pete Cooper57d3f142015-07-30 17:22:52 +00002276 for (auto &I : llvm::reverse(S->body()))
2277 AddStmt(I);
Guy Benyei11169dd2012-12-18 14:30:41 +00002278}
2279void EnqueueVisitor::
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002280VisitMSDependentExistsStmt(const MSDependentExistsStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002281 AddStmt(S->getSubStmt());
2282 AddDeclarationNameInfo(S);
2283 if (NestedNameSpecifierLoc QualifierLoc = S->getQualifierLoc())
2284 AddNestedNameSpecifierLoc(QualifierLoc);
2285}
2286
2287void EnqueueVisitor::
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002288VisitCXXDependentScopeMemberExpr(const CXXDependentScopeMemberExpr *E) {
James Y Knight04ec5bf2015-12-24 02:59:37 +00002289 if (E->hasExplicitTemplateArgs())
2290 AddExplicitTemplateArgs(E->getTemplateArgs(), E->getNumTemplateArgs());
Guy Benyei11169dd2012-12-18 14:30:41 +00002291 AddDeclarationNameInfo(E);
2292 if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
2293 AddNestedNameSpecifierLoc(QualifierLoc);
2294 if (!E->isImplicitAccess())
2295 AddStmt(E->getBase());
2296}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002297void EnqueueVisitor::VisitCXXNewExpr(const CXXNewExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002298 // Enqueue the initializer , if any.
2299 AddStmt(E->getInitializer());
2300 // Enqueue the array size, if any.
2301 AddStmt(E->getArraySize());
2302 // Enqueue the allocated type.
2303 AddTypeLoc(E->getAllocatedTypeSourceInfo());
2304 // Enqueue the placement arguments.
2305 for (unsigned I = E->getNumPlacementArgs(); I > 0; --I)
2306 AddStmt(E->getPlacementArg(I-1));
2307}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002308void EnqueueVisitor::VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *CE) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002309 for (unsigned I = CE->getNumArgs(); I > 1 /* Yes, this is 1 */; --I)
2310 AddStmt(CE->getArg(I-1));
2311 AddStmt(CE->getCallee());
2312 AddStmt(CE->getArg(0));
2313}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002314void EnqueueVisitor::VisitCXXPseudoDestructorExpr(
2315 const CXXPseudoDestructorExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002316 // Visit the name of the type being destroyed.
2317 AddTypeLoc(E->getDestroyedTypeInfo());
2318 // Visit the scope type that looks disturbingly like the nested-name-specifier
2319 // but isn't.
2320 AddTypeLoc(E->getScopeTypeInfo());
2321 // Visit the nested-name-specifier.
2322 if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
2323 AddNestedNameSpecifierLoc(QualifierLoc);
2324 // Visit base expression.
2325 AddStmt(E->getBase());
2326}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002327void EnqueueVisitor::VisitCXXScalarValueInitExpr(
2328 const CXXScalarValueInitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002329 AddTypeLoc(E->getTypeSourceInfo());
2330}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002331void EnqueueVisitor::VisitCXXTemporaryObjectExpr(
2332 const CXXTemporaryObjectExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002333 EnqueueChildren(E);
2334 AddTypeLoc(E->getTypeSourceInfo());
2335}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002336void EnqueueVisitor::VisitCXXTypeidExpr(const CXXTypeidExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002337 EnqueueChildren(E);
2338 if (E->isTypeOperand())
2339 AddTypeLoc(E->getTypeOperandSourceInfo());
2340}
2341
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002342void EnqueueVisitor::VisitCXXUnresolvedConstructExpr(
2343 const CXXUnresolvedConstructExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002344 EnqueueChildren(E);
2345 AddTypeLoc(E->getTypeSourceInfo());
2346}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002347void EnqueueVisitor::VisitCXXUuidofExpr(const CXXUuidofExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002348 EnqueueChildren(E);
2349 if (E->isTypeOperand())
2350 AddTypeLoc(E->getTypeOperandSourceInfo());
2351}
2352
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002353void EnqueueVisitor::VisitCXXCatchStmt(const CXXCatchStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002354 EnqueueChildren(S);
2355 AddDecl(S->getExceptionDecl());
2356}
2357
Argyrios Kyrtzidis99891242014-11-13 09:03:21 +00002358void EnqueueVisitor::VisitCXXForRangeStmt(const CXXForRangeStmt *S) {
Argyrios Kyrtzidiscde70692014-11-13 09:50:19 +00002359 AddStmt(S->getBody());
Argyrios Kyrtzidis99891242014-11-13 09:03:21 +00002360 AddStmt(S->getRangeInit());
Argyrios Kyrtzidiscde70692014-11-13 09:50:19 +00002361 AddDecl(S->getLoopVariable());
Argyrios Kyrtzidis99891242014-11-13 09:03:21 +00002362}
2363
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002364void EnqueueVisitor::VisitDeclRefExpr(const DeclRefExpr *DR) {
James Y Knight04ec5bf2015-12-24 02:59:37 +00002365 if (DR->hasExplicitTemplateArgs())
2366 AddExplicitTemplateArgs(DR->getTemplateArgs(), DR->getNumTemplateArgs());
Guy Benyei11169dd2012-12-18 14:30:41 +00002367 WL.push_back(DeclRefExprParts(DR, Parent));
2368}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002369void EnqueueVisitor::VisitDependentScopeDeclRefExpr(
2370 const DependentScopeDeclRefExpr *E) {
James Y Knight04ec5bf2015-12-24 02:59:37 +00002371 if (E->hasExplicitTemplateArgs())
2372 AddExplicitTemplateArgs(E->getTemplateArgs(), E->getNumTemplateArgs());
Guy Benyei11169dd2012-12-18 14:30:41 +00002373 AddDeclarationNameInfo(E);
2374 AddNestedNameSpecifierLoc(E->getQualifierLoc());
2375}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002376void EnqueueVisitor::VisitDeclStmt(const DeclStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002377 unsigned size = WL.size();
2378 bool isFirst = true;
Aaron Ballman535bbcc2014-03-14 17:01:24 +00002379 for (const auto *D : S->decls()) {
2380 AddDecl(D, isFirst);
Guy Benyei11169dd2012-12-18 14:30:41 +00002381 isFirst = false;
2382 }
2383 if (size == WL.size())
2384 return;
2385 // Now reverse the entries we just added. This will match the DFS
2386 // ordering performed by the worklist.
2387 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
2388 std::reverse(I, E);
2389}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002390void EnqueueVisitor::VisitDesignatedInitExpr(const DesignatedInitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002391 AddStmt(E->getInit());
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002392 for (DesignatedInitExpr::const_reverse_designators_iterator
Guy Benyei11169dd2012-12-18 14:30:41 +00002393 D = E->designators_rbegin(), DEnd = E->designators_rend();
2394 D != DEnd; ++D) {
2395 if (D->isFieldDesignator()) {
2396 if (FieldDecl *Field = D->getField())
2397 AddMemberRef(Field, D->getFieldLoc());
2398 continue;
2399 }
2400 if (D->isArrayDesignator()) {
2401 AddStmt(E->getArrayIndex(*D));
2402 continue;
2403 }
2404 assert(D->isArrayRangeDesignator() && "Unknown designator kind");
2405 AddStmt(E->getArrayRangeEnd(*D));
2406 AddStmt(E->getArrayRangeStart(*D));
2407 }
2408}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002409void EnqueueVisitor::VisitExplicitCastExpr(const ExplicitCastExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002410 EnqueueChildren(E);
2411 AddTypeLoc(E->getTypeInfoAsWritten());
2412}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002413void EnqueueVisitor::VisitForStmt(const ForStmt *FS) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002414 AddStmt(FS->getBody());
2415 AddStmt(FS->getInc());
2416 AddStmt(FS->getCond());
2417 AddDecl(FS->getConditionVariable());
2418 AddStmt(FS->getInit());
2419}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002420void EnqueueVisitor::VisitGotoStmt(const GotoStmt *GS) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002421 WL.push_back(LabelRefVisit(GS->getLabel(), GS->getLabelLoc(), Parent));
2422}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002423void EnqueueVisitor::VisitIfStmt(const IfStmt *If) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002424 AddStmt(If->getElse());
2425 AddStmt(If->getThen());
2426 AddStmt(If->getCond());
2427 AddDecl(If->getConditionVariable());
2428}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002429void EnqueueVisitor::VisitInitListExpr(const InitListExpr *IE) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002430 // We care about the syntactic form of the initializer list, only.
2431 if (InitListExpr *Syntactic = IE->getSyntacticForm())
2432 IE = Syntactic;
2433 EnqueueChildren(IE);
2434}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002435void EnqueueVisitor::VisitMemberExpr(const MemberExpr *M) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002436 WL.push_back(MemberExprParts(M, Parent));
2437
2438 // If the base of the member access expression is an implicit 'this', don't
2439 // visit it.
2440 // FIXME: If we ever want to show these implicit accesses, this will be
2441 // unfortunate. However, clang_getCursor() relies on this behavior.
Argyrios Kyrtzidis58d0e7a2015-03-13 04:40:07 +00002442 if (M->isImplicitAccess())
2443 return;
2444
2445 // Ignore base anonymous struct/union fields, otherwise they will shadow the
2446 // real field that that we are interested in.
2447 if (auto *SubME = dyn_cast<MemberExpr>(M->getBase())) {
2448 if (auto *FD = dyn_cast_or_null<FieldDecl>(SubME->getMemberDecl())) {
2449 if (FD->isAnonymousStructOrUnion()) {
2450 AddStmt(SubME->getBase());
2451 return;
2452 }
2453 }
2454 }
2455
2456 AddStmt(M->getBase());
Guy Benyei11169dd2012-12-18 14:30:41 +00002457}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002458void EnqueueVisitor::VisitObjCEncodeExpr(const ObjCEncodeExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002459 AddTypeLoc(E->getEncodedTypeSourceInfo());
2460}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002461void EnqueueVisitor::VisitObjCMessageExpr(const ObjCMessageExpr *M) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002462 EnqueueChildren(M);
2463 AddTypeLoc(M->getClassReceiverTypeInfo());
2464}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002465void EnqueueVisitor::VisitOffsetOfExpr(const OffsetOfExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002466 // Visit the components of the offsetof expression.
2467 for (unsigned N = E->getNumComponents(), I = N; I > 0; --I) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002468 const OffsetOfNode &Node = E->getComponent(I-1);
2469 switch (Node.getKind()) {
2470 case OffsetOfNode::Array:
2471 AddStmt(E->getIndexExpr(Node.getArrayExprIndex()));
2472 break;
2473 case OffsetOfNode::Field:
2474 AddMemberRef(Node.getField(), Node.getSourceRange().getEnd());
2475 break;
2476 case OffsetOfNode::Identifier:
2477 case OffsetOfNode::Base:
2478 continue;
2479 }
2480 }
2481 // Visit the type into which we're computing the offset.
2482 AddTypeLoc(E->getTypeSourceInfo());
2483}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002484void EnqueueVisitor::VisitOverloadExpr(const OverloadExpr *E) {
James Y Knight04ec5bf2015-12-24 02:59:37 +00002485 if (E->hasExplicitTemplateArgs())
2486 AddExplicitTemplateArgs(E->getTemplateArgs(), E->getNumTemplateArgs());
Guy Benyei11169dd2012-12-18 14:30:41 +00002487 WL.push_back(OverloadExprParts(E, Parent));
2488}
2489void EnqueueVisitor::VisitUnaryExprOrTypeTraitExpr(
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002490 const UnaryExprOrTypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002491 EnqueueChildren(E);
2492 if (E->isArgumentType())
2493 AddTypeLoc(E->getArgumentTypeInfo());
2494}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002495void EnqueueVisitor::VisitStmt(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002496 EnqueueChildren(S);
2497}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002498void EnqueueVisitor::VisitSwitchStmt(const SwitchStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002499 AddStmt(S->getBody());
2500 AddStmt(S->getCond());
2501 AddDecl(S->getConditionVariable());
2502}
2503
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002504void EnqueueVisitor::VisitWhileStmt(const WhileStmt *W) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002505 AddStmt(W->getBody());
2506 AddStmt(W->getCond());
2507 AddDecl(W->getConditionVariable());
2508}
2509
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002510void EnqueueVisitor::VisitTypeTraitExpr(const TypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002511 for (unsigned I = E->getNumArgs(); I > 0; --I)
2512 AddTypeLoc(E->getArg(I-1));
2513}
2514
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002515void EnqueueVisitor::VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002516 AddTypeLoc(E->getQueriedTypeSourceInfo());
2517}
2518
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002519void EnqueueVisitor::VisitExpressionTraitExpr(const ExpressionTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002520 EnqueueChildren(E);
2521}
2522
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002523void EnqueueVisitor::VisitUnresolvedMemberExpr(const UnresolvedMemberExpr *U) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002524 VisitOverloadExpr(U);
2525 if (!U->isImplicitAccess())
2526 AddStmt(U->getBase());
2527}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002528void EnqueueVisitor::VisitVAArgExpr(const VAArgExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002529 AddStmt(E->getSubExpr());
2530 AddTypeLoc(E->getWrittenTypeInfo());
2531}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002532void EnqueueVisitor::VisitSizeOfPackExpr(const SizeOfPackExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002533 WL.push_back(SizeOfPackExprParts(E, Parent));
2534}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002535void EnqueueVisitor::VisitOpaqueValueExpr(const OpaqueValueExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002536 // If the opaque value has a source expression, just transparently
2537 // visit that. This is useful for (e.g.) pseudo-object expressions.
2538 if (Expr *SourceExpr = E->getSourceExpr())
2539 return Visit(SourceExpr);
2540}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002541void EnqueueVisitor::VisitLambdaExpr(const LambdaExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002542 AddStmt(E->getBody());
2543 WL.push_back(LambdaExprParts(E, Parent));
2544}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002545void EnqueueVisitor::VisitPseudoObjectExpr(const PseudoObjectExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002546 // Treat the expression like its syntactic form.
2547 Visit(E->getSyntacticForm());
2548}
2549
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002550void EnqueueVisitor::VisitOMPExecutableDirective(
2551 const OMPExecutableDirective *D) {
2552 EnqueueChildren(D);
2553 for (ArrayRef<OMPClause *>::iterator I = D->clauses().begin(),
2554 E = D->clauses().end();
2555 I != E; ++I)
2556 EnqueueChildren(*I);
2557}
2558
Alexander Musman3aaab662014-08-19 11:27:13 +00002559void EnqueueVisitor::VisitOMPLoopDirective(const OMPLoopDirective *D) {
2560 VisitOMPExecutableDirective(D);
2561}
2562
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002563void EnqueueVisitor::VisitOMPParallelDirective(const OMPParallelDirective *D) {
2564 VisitOMPExecutableDirective(D);
2565}
2566
Alexey Bataev1b59ab52014-02-27 08:29:12 +00002567void EnqueueVisitor::VisitOMPSimdDirective(const OMPSimdDirective *D) {
Alexander Musman3aaab662014-08-19 11:27:13 +00002568 VisitOMPLoopDirective(D);
Alexey Bataev1b59ab52014-02-27 08:29:12 +00002569}
2570
Alexey Bataevf29276e2014-06-18 04:14:57 +00002571void EnqueueVisitor::VisitOMPForDirective(const OMPForDirective *D) {
Alexander Musman3aaab662014-08-19 11:27:13 +00002572 VisitOMPLoopDirective(D);
Alexey Bataevf29276e2014-06-18 04:14:57 +00002573}
2574
Alexander Musmanf82886e2014-09-18 05:12:34 +00002575void EnqueueVisitor::VisitOMPForSimdDirective(const OMPForSimdDirective *D) {
2576 VisitOMPLoopDirective(D);
2577}
2578
Alexey Bataevd3f8dd22014-06-25 11:44:49 +00002579void EnqueueVisitor::VisitOMPSectionsDirective(const OMPSectionsDirective *D) {
2580 VisitOMPExecutableDirective(D);
2581}
2582
Alexey Bataev1e0498a2014-06-26 08:21:58 +00002583void EnqueueVisitor::VisitOMPSectionDirective(const OMPSectionDirective *D) {
2584 VisitOMPExecutableDirective(D);
2585}
2586
Alexey Bataevd1e40fb2014-06-26 12:05:45 +00002587void EnqueueVisitor::VisitOMPSingleDirective(const OMPSingleDirective *D) {
2588 VisitOMPExecutableDirective(D);
2589}
2590
Alexander Musman80c22892014-07-17 08:54:58 +00002591void EnqueueVisitor::VisitOMPMasterDirective(const OMPMasterDirective *D) {
2592 VisitOMPExecutableDirective(D);
2593}
2594
Alexander Musmand9ed09f2014-07-21 09:42:05 +00002595void EnqueueVisitor::VisitOMPCriticalDirective(const OMPCriticalDirective *D) {
2596 VisitOMPExecutableDirective(D);
2597 AddDeclarationNameInfo(D);
2598}
2599
Alexey Bataev4acb8592014-07-07 13:01:15 +00002600void
2601EnqueueVisitor::VisitOMPParallelForDirective(const OMPParallelForDirective *D) {
Alexander Musman3aaab662014-08-19 11:27:13 +00002602 VisitOMPLoopDirective(D);
Alexey Bataev4acb8592014-07-07 13:01:15 +00002603}
2604
Alexander Musmane4e893b2014-09-23 09:33:00 +00002605void EnqueueVisitor::VisitOMPParallelForSimdDirective(
2606 const OMPParallelForSimdDirective *D) {
2607 VisitOMPLoopDirective(D);
2608}
2609
Alexey Bataev84d0b3e2014-07-08 08:12:03 +00002610void EnqueueVisitor::VisitOMPParallelSectionsDirective(
2611 const OMPParallelSectionsDirective *D) {
2612 VisitOMPExecutableDirective(D);
2613}
2614
Alexey Bataev9c2e8ee2014-07-11 11:25:16 +00002615void EnqueueVisitor::VisitOMPTaskDirective(const OMPTaskDirective *D) {
2616 VisitOMPExecutableDirective(D);
2617}
2618
Alexey Bataev68446b72014-07-18 07:47:19 +00002619void
2620EnqueueVisitor::VisitOMPTaskyieldDirective(const OMPTaskyieldDirective *D) {
2621 VisitOMPExecutableDirective(D);
2622}
2623
Alexey Bataev4d1dfea2014-07-18 09:11:51 +00002624void EnqueueVisitor::VisitOMPBarrierDirective(const OMPBarrierDirective *D) {
2625 VisitOMPExecutableDirective(D);
2626}
2627
Alexey Bataev2df347a2014-07-18 10:17:07 +00002628void EnqueueVisitor::VisitOMPTaskwaitDirective(const OMPTaskwaitDirective *D) {
2629 VisitOMPExecutableDirective(D);
2630}
2631
Alexey Bataevc30dd2d2015-06-18 12:14:09 +00002632void EnqueueVisitor::VisitOMPTaskgroupDirective(
2633 const OMPTaskgroupDirective *D) {
2634 VisitOMPExecutableDirective(D);
2635}
2636
Alexey Bataev6125da92014-07-21 11:26:11 +00002637void EnqueueVisitor::VisitOMPFlushDirective(const OMPFlushDirective *D) {
2638 VisitOMPExecutableDirective(D);
2639}
2640
Alexey Bataev9fb6e642014-07-22 06:45:04 +00002641void EnqueueVisitor::VisitOMPOrderedDirective(const OMPOrderedDirective *D) {
2642 VisitOMPExecutableDirective(D);
2643}
2644
Alexey Bataev0162e452014-07-22 10:10:35 +00002645void EnqueueVisitor::VisitOMPAtomicDirective(const OMPAtomicDirective *D) {
2646 VisitOMPExecutableDirective(D);
2647}
2648
Alexey Bataev0bd520b2014-09-19 08:19:49 +00002649void EnqueueVisitor::VisitOMPTargetDirective(const OMPTargetDirective *D) {
2650 VisitOMPExecutableDirective(D);
2651}
2652
Michael Wong65f367f2015-07-21 13:44:28 +00002653void EnqueueVisitor::VisitOMPTargetDataDirective(const
2654 OMPTargetDataDirective *D) {
2655 VisitOMPExecutableDirective(D);
2656}
2657
Samuel Antaodf67fc42016-01-19 19:15:56 +00002658void EnqueueVisitor::VisitOMPTargetEnterDataDirective(
2659 const OMPTargetEnterDataDirective *D) {
2660 VisitOMPExecutableDirective(D);
2661}
2662
Samuel Antao72590762016-01-19 20:04:50 +00002663void EnqueueVisitor::VisitOMPTargetExitDataDirective(
2664 const OMPTargetExitDataDirective *D) {
2665 VisitOMPExecutableDirective(D);
2666}
2667
Arpith Chacko Jacobe955b3d2016-01-26 18:48:41 +00002668void EnqueueVisitor::VisitOMPTargetParallelDirective(
2669 const OMPTargetParallelDirective *D) {
2670 VisitOMPExecutableDirective(D);
2671}
2672
Arpith Chacko Jacob05bebb52016-02-03 15:46:42 +00002673void EnqueueVisitor::VisitOMPTargetParallelForDirective(
2674 const OMPTargetParallelForDirective *D) {
2675 VisitOMPLoopDirective(D);
2676}
2677
Alexey Bataev13314bf2014-10-09 04:18:56 +00002678void EnqueueVisitor::VisitOMPTeamsDirective(const OMPTeamsDirective *D) {
2679 VisitOMPExecutableDirective(D);
2680}
2681
Alexey Bataev6d4ed052015-07-01 06:57:41 +00002682void EnqueueVisitor::VisitOMPCancellationPointDirective(
2683 const OMPCancellationPointDirective *D) {
2684 VisitOMPExecutableDirective(D);
2685}
2686
Alexey Bataev80909872015-07-02 11:25:17 +00002687void EnqueueVisitor::VisitOMPCancelDirective(const OMPCancelDirective *D) {
2688 VisitOMPExecutableDirective(D);
2689}
2690
Alexey Bataev49f6e782015-12-01 04:18:41 +00002691void EnqueueVisitor::VisitOMPTaskLoopDirective(const OMPTaskLoopDirective *D) {
2692 VisitOMPLoopDirective(D);
2693}
2694
Alexey Bataev0a6ed842015-12-03 09:40:15 +00002695void EnqueueVisitor::VisitOMPTaskLoopSimdDirective(
2696 const OMPTaskLoopSimdDirective *D) {
2697 VisitOMPLoopDirective(D);
2698}
2699
Carlo Bertolli6200a3d2015-12-14 14:51:25 +00002700void EnqueueVisitor::VisitOMPDistributeDirective(
2701 const OMPDistributeDirective *D) {
2702 VisitOMPLoopDirective(D);
2703}
2704
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002705void CursorVisitor::EnqueueWorkList(VisitorWorkList &WL, const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002706 EnqueueVisitor(WL, MakeCXCursor(S, StmtParent, TU,RegionOfInterest)).Visit(S);
2707}
2708
2709bool CursorVisitor::IsInRegionOfInterest(CXCursor C) {
2710 if (RegionOfInterest.isValid()) {
2711 SourceRange Range = getRawCursorExtent(C);
2712 if (Range.isInvalid() || CompareRegionOfInterest(Range))
2713 return false;
2714 }
2715 return true;
2716}
2717
2718bool CursorVisitor::RunVisitorWorkList(VisitorWorkList &WL) {
2719 while (!WL.empty()) {
2720 // Dequeue the worklist item.
Robert Wilhelm25284cc2013-08-23 16:11:15 +00002721 VisitorJob LI = WL.pop_back_val();
Guy Benyei11169dd2012-12-18 14:30:41 +00002722
2723 // Set the Parent field, then back to its old value once we're done.
2724 SetParentRAII SetParent(Parent, StmtParent, LI.getParent());
2725
2726 switch (LI.getKind()) {
2727 case VisitorJob::DeclVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002728 const Decl *D = cast<DeclVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002729 if (!D)
2730 continue;
2731
2732 // For now, perform default visitation for Decls.
2733 if (Visit(MakeCXCursor(D, TU, RegionOfInterest,
2734 cast<DeclVisit>(&LI)->isFirst())))
2735 return true;
2736
2737 continue;
2738 }
2739 case VisitorJob::ExplicitTemplateArgsVisitKind: {
James Y Knight04ec5bf2015-12-24 02:59:37 +00002740 for (const TemplateArgumentLoc &Arg :
2741 *cast<ExplicitTemplateArgsVisit>(&LI)) {
2742 if (VisitTemplateArgumentLoc(Arg))
Guy Benyei11169dd2012-12-18 14:30:41 +00002743 return true;
2744 }
2745 continue;
2746 }
2747 case VisitorJob::TypeLocVisitKind: {
2748 // Perform default visitation for TypeLocs.
2749 if (Visit(cast<TypeLocVisit>(&LI)->get()))
2750 return true;
2751 continue;
2752 }
2753 case VisitorJob::LabelRefVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002754 const LabelDecl *LS = cast<LabelRefVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002755 if (LabelStmt *stmt = LS->getStmt()) {
2756 if (Visit(MakeCursorLabelRef(stmt, cast<LabelRefVisit>(&LI)->getLoc(),
2757 TU))) {
2758 return true;
2759 }
2760 }
2761 continue;
2762 }
2763
2764 case VisitorJob::NestedNameSpecifierLocVisitKind: {
2765 NestedNameSpecifierLocVisit *V = cast<NestedNameSpecifierLocVisit>(&LI);
2766 if (VisitNestedNameSpecifierLoc(V->get()))
2767 return true;
2768 continue;
2769 }
2770
2771 case VisitorJob::DeclarationNameInfoVisitKind: {
2772 if (VisitDeclarationNameInfo(cast<DeclarationNameInfoVisit>(&LI)
2773 ->get()))
2774 return true;
2775 continue;
2776 }
2777 case VisitorJob::MemberRefVisitKind: {
2778 MemberRefVisit *V = cast<MemberRefVisit>(&LI);
2779 if (Visit(MakeCursorMemberRef(V->get(), V->getLoc(), TU)))
2780 return true;
2781 continue;
2782 }
2783 case VisitorJob::StmtVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002784 const Stmt *S = cast<StmtVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002785 if (!S)
2786 continue;
2787
2788 // Update the current cursor.
2789 CXCursor Cursor = MakeCXCursor(S, StmtParent, TU, RegionOfInterest);
2790 if (!IsInRegionOfInterest(Cursor))
2791 continue;
2792 switch (Visitor(Cursor, Parent, ClientData)) {
2793 case CXChildVisit_Break: return true;
2794 case CXChildVisit_Continue: break;
2795 case CXChildVisit_Recurse:
2796 if (PostChildrenVisitor)
Craig Topper69186e72014-06-08 08:38:04 +00002797 WL.push_back(PostChildrenVisit(nullptr, Cursor));
Guy Benyei11169dd2012-12-18 14:30:41 +00002798 EnqueueWorkList(WL, S);
2799 break;
2800 }
2801 continue;
2802 }
2803 case VisitorJob::MemberExprPartsKind: {
2804 // Handle the other pieces in the MemberExpr besides the base.
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002805 const MemberExpr *M = cast<MemberExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002806
2807 // Visit the nested-name-specifier
2808 if (NestedNameSpecifierLoc QualifierLoc = M->getQualifierLoc())
2809 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2810 return true;
2811
2812 // Visit the declaration name.
2813 if (VisitDeclarationNameInfo(M->getMemberNameInfo()))
2814 return true;
2815
2816 // Visit the explicitly-specified template arguments, if any.
2817 if (M->hasExplicitTemplateArgs()) {
2818 for (const TemplateArgumentLoc *Arg = M->getTemplateArgs(),
2819 *ArgEnd = Arg + M->getNumTemplateArgs();
2820 Arg != ArgEnd; ++Arg) {
2821 if (VisitTemplateArgumentLoc(*Arg))
2822 return true;
2823 }
2824 }
2825 continue;
2826 }
2827 case VisitorJob::DeclRefExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002828 const DeclRefExpr *DR = cast<DeclRefExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002829 // Visit nested-name-specifier, if present.
2830 if (NestedNameSpecifierLoc QualifierLoc = DR->getQualifierLoc())
2831 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2832 return true;
2833 // Visit declaration name.
2834 if (VisitDeclarationNameInfo(DR->getNameInfo()))
2835 return true;
2836 continue;
2837 }
2838 case VisitorJob::OverloadExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002839 const OverloadExpr *O = cast<OverloadExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002840 // Visit the nested-name-specifier.
2841 if (NestedNameSpecifierLoc QualifierLoc = O->getQualifierLoc())
2842 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2843 return true;
2844 // Visit the declaration name.
2845 if (VisitDeclarationNameInfo(O->getNameInfo()))
2846 return true;
2847 // Visit the overloaded declaration reference.
2848 if (Visit(MakeCursorOverloadedDeclRef(O, TU)))
2849 return true;
2850 continue;
2851 }
2852 case VisitorJob::SizeOfPackExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002853 const SizeOfPackExpr *E = cast<SizeOfPackExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002854 NamedDecl *Pack = E->getPack();
2855 if (isa<TemplateTypeParmDecl>(Pack)) {
2856 if (Visit(MakeCursorTypeRef(cast<TemplateTypeParmDecl>(Pack),
2857 E->getPackLoc(), TU)))
2858 return true;
2859
2860 continue;
2861 }
2862
2863 if (isa<TemplateTemplateParmDecl>(Pack)) {
2864 if (Visit(MakeCursorTemplateRef(cast<TemplateTemplateParmDecl>(Pack),
2865 E->getPackLoc(), TU)))
2866 return true;
2867
2868 continue;
2869 }
2870
2871 // Non-type template parameter packs and function parameter packs are
2872 // treated like DeclRefExpr cursors.
2873 continue;
2874 }
2875
2876 case VisitorJob::LambdaExprPartsKind: {
2877 // Visit captures.
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002878 const LambdaExpr *E = cast<LambdaExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002879 for (LambdaExpr::capture_iterator C = E->explicit_capture_begin(),
2880 CEnd = E->explicit_capture_end();
2881 C != CEnd; ++C) {
Richard Smithba71c082013-05-16 06:20:58 +00002882 // FIXME: Lambda init-captures.
2883 if (!C->capturesVariable())
Guy Benyei11169dd2012-12-18 14:30:41 +00002884 continue;
Richard Smithba71c082013-05-16 06:20:58 +00002885
Guy Benyei11169dd2012-12-18 14:30:41 +00002886 if (Visit(MakeCursorVariableRef(C->getCapturedVar(),
2887 C->getLocation(),
2888 TU)))
2889 return true;
2890 }
2891
2892 // Visit parameters and return type, if present.
2893 if (E->hasExplicitParameters() || E->hasExplicitResultType()) {
2894 TypeLoc TL = E->getCallOperator()->getTypeSourceInfo()->getTypeLoc();
2895 if (E->hasExplicitParameters() && E->hasExplicitResultType()) {
2896 // Visit the whole type.
2897 if (Visit(TL))
2898 return true;
David Blaikie6adc78e2013-02-18 22:06:02 +00002899 } else if (FunctionProtoTypeLoc Proto =
2900 TL.getAs<FunctionProtoTypeLoc>()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002901 if (E->hasExplicitParameters()) {
2902 // Visit parameters.
Alp Tokerb3fd5cf2014-01-21 00:32:38 +00002903 for (unsigned I = 0, N = Proto.getNumParams(); I != N; ++I)
2904 if (Visit(MakeCXCursor(Proto.getParam(I), TU)))
Guy Benyei11169dd2012-12-18 14:30:41 +00002905 return true;
2906 } else {
2907 // Visit result type.
Alp Toker42a16a62014-01-25 23:51:36 +00002908 if (Visit(Proto.getReturnLoc()))
Guy Benyei11169dd2012-12-18 14:30:41 +00002909 return true;
2910 }
2911 }
2912 }
2913 break;
2914 }
2915
2916 case VisitorJob::PostChildrenVisitKind:
2917 if (PostChildrenVisitor(Parent, ClientData))
2918 return true;
2919 break;
2920 }
2921 }
2922 return false;
2923}
2924
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002925bool CursorVisitor::Visit(const Stmt *S) {
Craig Topper69186e72014-06-08 08:38:04 +00002926 VisitorWorkList *WL = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00002927 if (!WorkListFreeList.empty()) {
2928 WL = WorkListFreeList.back();
2929 WL->clear();
2930 WorkListFreeList.pop_back();
2931 }
2932 else {
2933 WL = new VisitorWorkList();
2934 WorkListCache.push_back(WL);
2935 }
2936 EnqueueWorkList(*WL, S);
2937 bool result = RunVisitorWorkList(*WL);
2938 WorkListFreeList.push_back(WL);
2939 return result;
2940}
2941
2942namespace {
Dmitri Gribenkof8579502013-01-12 19:30:44 +00002943typedef SmallVector<SourceRange, 4> RefNamePieces;
James Y Knight04ec5bf2015-12-24 02:59:37 +00002944RefNamePieces buildPieces(unsigned NameFlags, bool IsMemberRefExpr,
2945 const DeclarationNameInfo &NI, SourceRange QLoc,
2946 const SourceRange *TemplateArgsLoc = nullptr) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002947 const bool WantQualifier = NameFlags & CXNameRange_WantQualifier;
2948 const bool WantTemplateArgs = NameFlags & CXNameRange_WantTemplateArgs;
2949 const bool WantSinglePiece = NameFlags & CXNameRange_WantSinglePiece;
2950
2951 const DeclarationName::NameKind Kind = NI.getName().getNameKind();
2952
2953 RefNamePieces Pieces;
2954
2955 if (WantQualifier && QLoc.isValid())
2956 Pieces.push_back(QLoc);
2957
2958 if (Kind != DeclarationName::CXXOperatorName || IsMemberRefExpr)
2959 Pieces.push_back(NI.getLoc());
James Y Knight04ec5bf2015-12-24 02:59:37 +00002960
2961 if (WantTemplateArgs && TemplateArgsLoc && TemplateArgsLoc->isValid())
2962 Pieces.push_back(*TemplateArgsLoc);
2963
Guy Benyei11169dd2012-12-18 14:30:41 +00002964 if (Kind == DeclarationName::CXXOperatorName) {
2965 Pieces.push_back(SourceLocation::getFromRawEncoding(
2966 NI.getInfo().CXXOperatorName.BeginOpNameLoc));
2967 Pieces.push_back(SourceLocation::getFromRawEncoding(
2968 NI.getInfo().CXXOperatorName.EndOpNameLoc));
2969 }
2970
2971 if (WantSinglePiece) {
2972 SourceRange R(Pieces.front().getBegin(), Pieces.back().getEnd());
2973 Pieces.clear();
2974 Pieces.push_back(R);
2975 }
2976
2977 return Pieces;
2978}
Alexander Kornienkoab9db512015-06-22 23:07:51 +00002979}
Guy Benyei11169dd2012-12-18 14:30:41 +00002980
2981//===----------------------------------------------------------------------===//
2982// Misc. API hooks.
2983//===----------------------------------------------------------------------===//
2984
Chad Rosier05c71aa2013-03-27 18:28:23 +00002985static void fatal_error_handler(void *user_data, const std::string& reason,
2986 bool gen_crash_diag) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002987 // Write the result out to stderr avoiding errs() because raw_ostreams can
2988 // call report_fatal_error.
2989 fprintf(stderr, "LIBCLANG FATAL ERROR: %s\n", reason.c_str());
2990 ::abort();
2991}
2992
Chandler Carruth66660742014-06-27 16:37:27 +00002993namespace {
2994struct RegisterFatalErrorHandler {
2995 RegisterFatalErrorHandler() {
2996 llvm::install_fatal_error_handler(fatal_error_handler, nullptr);
2997 }
2998};
2999}
3000
3001static llvm::ManagedStatic<RegisterFatalErrorHandler> RegisterFatalErrorHandlerOnce;
3002
Guy Benyei11169dd2012-12-18 14:30:41 +00003003extern "C" {
3004CXIndex clang_createIndex(int excludeDeclarationsFromPCH,
3005 int displayDiagnostics) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003006 // We use crash recovery to make some of our APIs more reliable, implicitly
3007 // enable it.
Argyrios Kyrtzidis3701f542013-11-27 08:58:09 +00003008 if (!getenv("LIBCLANG_DISABLE_CRASH_RECOVERY"))
3009 llvm::CrashRecoveryContext::Enable();
Guy Benyei11169dd2012-12-18 14:30:41 +00003010
Chandler Carruth66660742014-06-27 16:37:27 +00003011 // Look through the managed static to trigger construction of the managed
3012 // static which registers our fatal error handler. This ensures it is only
3013 // registered once.
3014 (void)*RegisterFatalErrorHandlerOnce;
Guy Benyei11169dd2012-12-18 14:30:41 +00003015
Adrian Prantlbc068582015-07-08 01:00:30 +00003016 // Initialize targets for clang module support.
3017 llvm::InitializeAllTargets();
3018 llvm::InitializeAllTargetMCs();
3019 llvm::InitializeAllAsmPrinters();
3020 llvm::InitializeAllAsmParsers();
3021
Adrian Prantlfb2398d2015-07-17 01:19:54 +00003022 CIndexer *CIdxr = new CIndexer();
3023
Guy Benyei11169dd2012-12-18 14:30:41 +00003024 if (excludeDeclarationsFromPCH)
3025 CIdxr->setOnlyLocalDecls();
3026 if (displayDiagnostics)
3027 CIdxr->setDisplayDiagnostics();
3028
3029 if (getenv("LIBCLANG_BGPRIO_INDEX"))
3030 CIdxr->setCXGlobalOptFlags(CIdxr->getCXGlobalOptFlags() |
3031 CXGlobalOpt_ThreadBackgroundPriorityForIndexing);
3032 if (getenv("LIBCLANG_BGPRIO_EDIT"))
3033 CIdxr->setCXGlobalOptFlags(CIdxr->getCXGlobalOptFlags() |
3034 CXGlobalOpt_ThreadBackgroundPriorityForEditing);
3035
3036 return CIdxr;
3037}
3038
3039void clang_disposeIndex(CXIndex CIdx) {
3040 if (CIdx)
3041 delete static_cast<CIndexer *>(CIdx);
3042}
3043
3044void clang_CXIndex_setGlobalOptions(CXIndex CIdx, unsigned options) {
3045 if (CIdx)
3046 static_cast<CIndexer *>(CIdx)->setCXGlobalOptFlags(options);
3047}
3048
3049unsigned clang_CXIndex_getGlobalOptions(CXIndex CIdx) {
3050 if (CIdx)
3051 return static_cast<CIndexer *>(CIdx)->getCXGlobalOptFlags();
3052 return 0;
3053}
3054
3055void clang_toggleCrashRecovery(unsigned isEnabled) {
3056 if (isEnabled)
3057 llvm::CrashRecoveryContext::Enable();
3058 else
3059 llvm::CrashRecoveryContext::Disable();
3060}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003061
Guy Benyei11169dd2012-12-18 14:30:41 +00003062CXTranslationUnit clang_createTranslationUnit(CXIndex CIdx,
3063 const char *ast_filename) {
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00003064 CXTranslationUnit TU;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003065 enum CXErrorCode Result =
3066 clang_createTranslationUnit2(CIdx, ast_filename, &TU);
Reid Klecknerfd48fc62014-02-12 23:56:20 +00003067 (void)Result;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003068 assert((TU && Result == CXError_Success) ||
3069 (!TU && Result != CXError_Success));
3070 return TU;
3071}
3072
3073enum CXErrorCode clang_createTranslationUnit2(CXIndex CIdx,
3074 const char *ast_filename,
3075 CXTranslationUnit *out_TU) {
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00003076 if (out_TU)
Craig Topper69186e72014-06-08 08:38:04 +00003077 *out_TU = nullptr;
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00003078
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003079 if (!CIdx || !ast_filename || !out_TU)
3080 return CXError_InvalidArguments;
Guy Benyei11169dd2012-12-18 14:30:41 +00003081
Argyrios Kyrtzidis27021012013-05-24 22:24:07 +00003082 LOG_FUNC_SECTION {
3083 *Log << ast_filename;
3084 }
3085
Guy Benyei11169dd2012-12-18 14:30:41 +00003086 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
3087 FileSystemOptions FileSystemOpts;
3088
Justin Bognerd512c1e2014-10-15 00:33:06 +00003089 IntrusiveRefCntPtr<DiagnosticsEngine> Diags =
3090 CompilerInstance::createDiagnostics(new DiagnosticOptions());
David Blaikie6f7382d2014-08-10 19:08:04 +00003091 std::unique_ptr<ASTUnit> AU = ASTUnit::LoadFromASTFile(
Adrian Prantlfb2398d2015-07-17 01:19:54 +00003092 ast_filename, CXXIdx->getPCHContainerOperations()->getRawReader(), Diags,
Adrian Prantl6b21ab22015-08-27 19:46:20 +00003093 FileSystemOpts, /*UseDebugInfo=*/false,
3094 CXXIdx->getOnlyLocalDecls(), None,
David Blaikie6f7382d2014-08-10 19:08:04 +00003095 /*CaptureDiagnostics=*/true,
3096 /*AllowPCHWithCompilerErrors=*/true,
3097 /*UserFilesAreVolatile=*/true);
3098 *out_TU = MakeCXTranslationUnit(CXXIdx, AU.release());
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003099 return *out_TU ? CXError_Success : CXError_Failure;
Guy Benyei11169dd2012-12-18 14:30:41 +00003100}
3101
3102unsigned clang_defaultEditingTranslationUnitOptions() {
3103 return CXTranslationUnit_PrecompiledPreamble |
3104 CXTranslationUnit_CacheCompletionResults;
3105}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003106
Guy Benyei11169dd2012-12-18 14:30:41 +00003107CXTranslationUnit
3108clang_createTranslationUnitFromSourceFile(CXIndex CIdx,
3109 const char *source_filename,
3110 int num_command_line_args,
3111 const char * const *command_line_args,
3112 unsigned num_unsaved_files,
3113 struct CXUnsavedFile *unsaved_files) {
3114 unsigned Options = CXTranslationUnit_DetailedPreprocessingRecord;
3115 return clang_parseTranslationUnit(CIdx, source_filename,
3116 command_line_args, num_command_line_args,
3117 unsaved_files, num_unsaved_files,
3118 Options);
3119}
3120
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003121static CXErrorCode
3122clang_parseTranslationUnit_Impl(CXIndex CIdx, const char *source_filename,
3123 const char *const *command_line_args,
3124 int num_command_line_args,
3125 ArrayRef<CXUnsavedFile> unsaved_files,
3126 unsigned options, CXTranslationUnit *out_TU) {
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00003127 // Set up the initial return values.
3128 if (out_TU)
Craig Topper69186e72014-06-08 08:38:04 +00003129 *out_TU = nullptr;
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00003130
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003131 // Check arguments.
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003132 if (!CIdx || !out_TU)
3133 return CXError_InvalidArguments;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003134
Guy Benyei11169dd2012-12-18 14:30:41 +00003135 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
3136
3137 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
3138 setThreadBackgroundPriority();
3139
3140 bool PrecompilePreamble = options & CXTranslationUnit_PrecompiledPreamble;
Benjamin Kramer5c248d82015-12-15 09:30:31 +00003141 bool CreatePreambleOnFirstParse =
3142 options & CXTranslationUnit_CreatePreambleOnFirstParse;
Guy Benyei11169dd2012-12-18 14:30:41 +00003143 // FIXME: Add a flag for modules.
3144 TranslationUnitKind TUKind
3145 = (options & CXTranslationUnit_Incomplete)? TU_Prefix : TU_Complete;
Alp Toker8c8a8752013-12-03 06:53:35 +00003146 bool CacheCodeCompletionResults
Guy Benyei11169dd2012-12-18 14:30:41 +00003147 = options & CXTranslationUnit_CacheCompletionResults;
3148 bool IncludeBriefCommentsInCodeCompletion
3149 = options & CXTranslationUnit_IncludeBriefCommentsInCodeCompletion;
3150 bool SkipFunctionBodies = options & CXTranslationUnit_SkipFunctionBodies;
3151 bool ForSerialization = options & CXTranslationUnit_ForSerialization;
3152
3153 // Configure the diagnostics.
3154 IntrusiveRefCntPtr<DiagnosticsEngine>
Sean Silvaf1b49e22013-01-20 01:58:28 +00003155 Diags(CompilerInstance::createDiagnostics(new DiagnosticOptions));
Guy Benyei11169dd2012-12-18 14:30:41 +00003156
Manuel Klimek016c0242016-03-01 10:56:19 +00003157 if (options & CXTranslationUnit_KeepGoing)
3158 Diags->setFatalsAsError(true);
3159
Guy Benyei11169dd2012-12-18 14:30:41 +00003160 // Recover resources if we crash before exiting this function.
3161 llvm::CrashRecoveryContextCleanupRegistrar<DiagnosticsEngine,
3162 llvm::CrashRecoveryContextReleaseRefCleanup<DiagnosticsEngine> >
Alp Tokerf994cef2014-07-05 03:08:06 +00003163 DiagCleanup(Diags.get());
Guy Benyei11169dd2012-12-18 14:30:41 +00003164
Ahmed Charlesb8984322014-03-07 20:03:18 +00003165 std::unique_ptr<std::vector<ASTUnit::RemappedFile>> RemappedFiles(
3166 new std::vector<ASTUnit::RemappedFile>());
Guy Benyei11169dd2012-12-18 14:30:41 +00003167
3168 // Recover resources if we crash before exiting this function.
3169 llvm::CrashRecoveryContextCleanupRegistrar<
3170 std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
3171
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003172 for (auto &UF : unsaved_files) {
Rafael Espindolad87f8d72014-08-27 20:03:29 +00003173 std::unique_ptr<llvm::MemoryBuffer> MB =
Alp Toker9d85b182014-07-07 01:23:14 +00003174 llvm::MemoryBuffer::getMemBufferCopy(getContents(UF), UF.Filename);
Rafael Espindolad87f8d72014-08-27 20:03:29 +00003175 RemappedFiles->push_back(std::make_pair(UF.Filename, MB.release()));
Guy Benyei11169dd2012-12-18 14:30:41 +00003176 }
3177
Ahmed Charlesb8984322014-03-07 20:03:18 +00003178 std::unique_ptr<std::vector<const char *>> Args(
3179 new std::vector<const char *>());
Guy Benyei11169dd2012-12-18 14:30:41 +00003180
3181 // Recover resources if we crash before exiting this method.
3182 llvm::CrashRecoveryContextCleanupRegistrar<std::vector<const char*> >
3183 ArgsCleanup(Args.get());
3184
3185 // Since the Clang C library is primarily used by batch tools dealing with
3186 // (often very broken) source code, where spell-checking can have a
3187 // significant negative impact on performance (particularly when
3188 // precompiled headers are involved), we disable it by default.
3189 // Only do this if we haven't found a spell-checking-related argument.
3190 bool FoundSpellCheckingArgument = false;
3191 for (int I = 0; I != num_command_line_args; ++I) {
3192 if (strcmp(command_line_args[I], "-fno-spell-checking") == 0 ||
3193 strcmp(command_line_args[I], "-fspell-checking") == 0) {
3194 FoundSpellCheckingArgument = true;
3195 break;
3196 }
3197 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003198 Args->insert(Args->end(), command_line_args,
3199 command_line_args + num_command_line_args);
3200
Benjamin Kramerc02670e2015-11-18 16:14:27 +00003201 if (!FoundSpellCheckingArgument)
3202 Args->insert(Args->begin() + 1, "-fno-spell-checking");
3203
Guy Benyei11169dd2012-12-18 14:30:41 +00003204 // The 'source_filename' argument is optional. If the caller does not
3205 // specify it then it is assumed that the source file is specified
3206 // in the actual argument list.
3207 // Put the source file after command_line_args otherwise if '-x' flag is
3208 // present it will be unused.
3209 if (source_filename)
3210 Args->push_back(source_filename);
3211
3212 // Do we need the detailed preprocessing record?
3213 if (options & CXTranslationUnit_DetailedPreprocessingRecord) {
3214 Args->push_back("-Xclang");
3215 Args->push_back("-detailed-preprocessing-record");
3216 }
3217
3218 unsigned NumErrors = Diags->getClient()->getNumErrors();
Ahmed Charlesb8984322014-03-07 20:03:18 +00003219 std::unique_ptr<ASTUnit> ErrUnit;
Benjamin Kramer5c248d82015-12-15 09:30:31 +00003220 // Unless the user specified that they want the preamble on the first parse
3221 // set it up to be created on the first reparse. This makes the first parse
3222 // faster, trading for a slower (first) reparse.
3223 unsigned PrecompilePreambleAfterNParses =
3224 !PrecompilePreamble ? 0 : 2 - CreatePreambleOnFirstParse;
Ahmed Charlesb8984322014-03-07 20:03:18 +00003225 std::unique_ptr<ASTUnit> Unit(ASTUnit::LoadFromCommandLine(
Adrian Prantlbb165fb2015-06-20 18:53:08 +00003226 Args->data(), Args->data() + Args->size(),
3227 CXXIdx->getPCHContainerOperations(), Diags,
Ahmed Charlesb8984322014-03-07 20:03:18 +00003228 CXXIdx->getClangResourcesPath(), CXXIdx->getOnlyLocalDecls(),
3229 /*CaptureDiagnostics=*/true, *RemappedFiles.get(),
Benjamin Kramer5c248d82015-12-15 09:30:31 +00003230 /*RemappedFilesKeepOriginalName=*/true, PrecompilePreambleAfterNParses,
3231 TUKind, CacheCodeCompletionResults, IncludeBriefCommentsInCodeCompletion,
Ahmed Charlesb8984322014-03-07 20:03:18 +00003232 /*AllowPCHWithCompilerErrors=*/true, SkipFunctionBodies,
Argyrios Kyrtzidisa3e2ff12015-11-20 03:36:21 +00003233 /*UserFilesAreVolatile=*/true, ForSerialization,
3234 CXXIdx->getPCHContainerOperations()->getRawReader().getFormat(),
3235 &ErrUnit));
Guy Benyei11169dd2012-12-18 14:30:41 +00003236
Artem Belevich0ff05cd2015-07-13 23:27:56 +00003237 // Early failures in LoadFromCommandLine may return with ErrUnit unset.
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003238 if (!Unit && !ErrUnit)
3239 return CXError_ASTReadError;
Artem Belevich0ff05cd2015-07-13 23:27:56 +00003240
Guy Benyei11169dd2012-12-18 14:30:41 +00003241 if (NumErrors != Diags->getClient()->getNumErrors()) {
3242 // Make sure to check that 'Unit' is non-NULL.
3243 if (CXXIdx->getDisplayDiagnostics())
3244 printDiagsToStderr(Unit ? Unit.get() : ErrUnit.get());
3245 }
3246
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003247 if (isASTReadError(Unit ? Unit.get() : ErrUnit.get()))
3248 return CXError_ASTReadError;
3249
3250 *out_TU = MakeCXTranslationUnit(CXXIdx, Unit.release());
3251 return *out_TU ? CXError_Success : CXError_Failure;
Guy Benyei11169dd2012-12-18 14:30:41 +00003252}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003253
3254CXTranslationUnit
3255clang_parseTranslationUnit(CXIndex CIdx,
3256 const char *source_filename,
3257 const char *const *command_line_args,
3258 int num_command_line_args,
3259 struct CXUnsavedFile *unsaved_files,
3260 unsigned num_unsaved_files,
3261 unsigned options) {
3262 CXTranslationUnit TU;
3263 enum CXErrorCode Result = clang_parseTranslationUnit2(
3264 CIdx, source_filename, command_line_args, num_command_line_args,
3265 unsaved_files, num_unsaved_files, options, &TU);
Reid Kleckner6eaf05a2014-02-13 01:19:59 +00003266 (void)Result;
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00003267 assert((TU && Result == CXError_Success) ||
3268 (!TU && Result != CXError_Success));
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003269 return TU;
3270}
3271
3272enum CXErrorCode clang_parseTranslationUnit2(
Benjamin Kramerc02670e2015-11-18 16:14:27 +00003273 CXIndex CIdx, const char *source_filename,
3274 const char *const *command_line_args, int num_command_line_args,
3275 struct CXUnsavedFile *unsaved_files, unsigned num_unsaved_files,
3276 unsigned options, CXTranslationUnit *out_TU) {
3277 SmallVector<const char *, 4> Args;
3278 Args.push_back("clang");
3279 Args.append(command_line_args, command_line_args + num_command_line_args);
3280 return clang_parseTranslationUnit2FullArgv(
3281 CIdx, source_filename, Args.data(), Args.size(), unsaved_files,
3282 num_unsaved_files, options, out_TU);
3283}
3284
3285enum CXErrorCode clang_parseTranslationUnit2FullArgv(
3286 CXIndex CIdx, const char *source_filename,
3287 const char *const *command_line_args, int num_command_line_args,
3288 struct CXUnsavedFile *unsaved_files, unsigned num_unsaved_files,
3289 unsigned options, CXTranslationUnit *out_TU) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00003290 LOG_FUNC_SECTION {
3291 *Log << source_filename << ": ";
3292 for (int i = 0; i != num_command_line_args; ++i)
3293 *Log << command_line_args[i] << " ";
3294 }
3295
Alp Toker9d85b182014-07-07 01:23:14 +00003296 if (num_unsaved_files && !unsaved_files)
3297 return CXError_InvalidArguments;
3298
Alp Toker5c532982014-07-07 22:42:03 +00003299 CXErrorCode result = CXError_Failure;
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003300 auto ParseTranslationUnitImpl = [=, &result] {
3301 result = clang_parseTranslationUnit_Impl(
3302 CIdx, source_filename, command_line_args, num_command_line_args,
3303 llvm::makeArrayRef(unsaved_files, num_unsaved_files), options, out_TU);
3304 };
Guy Benyei11169dd2012-12-18 14:30:41 +00003305 llvm::CrashRecoveryContext CRC;
3306
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003307 if (!RunSafely(CRC, ParseTranslationUnitImpl)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003308 fprintf(stderr, "libclang: crash detected during parsing: {\n");
3309 fprintf(stderr, " 'source_filename' : '%s'\n", source_filename);
3310 fprintf(stderr, " 'command_line_args' : [");
3311 for (int i = 0; i != num_command_line_args; ++i) {
3312 if (i)
3313 fprintf(stderr, ", ");
3314 fprintf(stderr, "'%s'", command_line_args[i]);
3315 }
3316 fprintf(stderr, "],\n");
3317 fprintf(stderr, " 'unsaved_files' : [");
3318 for (unsigned i = 0; i != num_unsaved_files; ++i) {
3319 if (i)
3320 fprintf(stderr, ", ");
3321 fprintf(stderr, "('%s', '...', %ld)", unsaved_files[i].Filename,
3322 unsaved_files[i].Length);
3323 }
3324 fprintf(stderr, "],\n");
3325 fprintf(stderr, " 'options' : %d,\n", options);
3326 fprintf(stderr, "}\n");
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003327
3328 return CXError_Crashed;
Guy Benyei11169dd2012-12-18 14:30:41 +00003329 } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003330 if (CXTranslationUnit *TU = out_TU)
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003331 PrintLibclangResourceUsage(*TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003332 }
Alp Toker5c532982014-07-07 22:42:03 +00003333
3334 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003335}
3336
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003337CXString clang_Type_getObjCEncoding(CXType CT) {
3338 CXTranslationUnit tu = static_cast<CXTranslationUnit>(CT.data[1]);
3339 ASTContext &Ctx = getASTUnit(tu)->getASTContext();
3340 std::string encoding;
3341 Ctx.getObjCEncodingForType(QualType::getFromOpaquePtr(CT.data[0]),
3342 encoding);
3343
3344 return cxstring::createDup(encoding);
3345}
3346
3347static const IdentifierInfo *getMacroIdentifier(CXCursor C) {
3348 if (C.kind == CXCursor_MacroDefinition) {
3349 if (const MacroDefinitionRecord *MDR = getCursorMacroDefinition(C))
3350 return MDR->getName();
3351 } else if (C.kind == CXCursor_MacroExpansion) {
3352 MacroExpansionCursor ME = getCursorMacroExpansion(C);
3353 return ME.getName();
3354 }
3355 return nullptr;
3356}
3357
3358unsigned clang_Cursor_isMacroFunctionLike(CXCursor C) {
3359 const IdentifierInfo *II = getMacroIdentifier(C);
3360 if (!II) {
3361 return false;
3362 }
3363 ASTUnit *ASTU = getCursorASTUnit(C);
3364 Preprocessor &PP = ASTU->getPreprocessor();
3365 if (const MacroInfo *MI = PP.getMacroInfo(II))
3366 return MI->isFunctionLike();
3367 return false;
3368}
3369
3370unsigned clang_Cursor_isMacroBuiltin(CXCursor C) {
3371 const IdentifierInfo *II = getMacroIdentifier(C);
3372 if (!II) {
3373 return false;
3374 }
3375 ASTUnit *ASTU = getCursorASTUnit(C);
3376 Preprocessor &PP = ASTU->getPreprocessor();
3377 if (const MacroInfo *MI = PP.getMacroInfo(II))
3378 return MI->isBuiltinMacro();
3379 return false;
3380}
3381
3382unsigned clang_Cursor_isFunctionInlined(CXCursor C) {
3383 const Decl *D = getCursorDecl(C);
3384 const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(D);
3385 if (!FD) {
3386 return false;
3387 }
3388 return FD->isInlined();
3389}
3390
3391static StringLiteral* getCFSTR_value(CallExpr *callExpr) {
3392 if (callExpr->getNumArgs() != 1) {
3393 return nullptr;
3394 }
3395
3396 StringLiteral *S = nullptr;
3397 auto *arg = callExpr->getArg(0);
3398 if (arg->getStmtClass() == Stmt::ImplicitCastExprClass) {
3399 ImplicitCastExpr *I = static_cast<ImplicitCastExpr *>(arg);
3400 auto *subExpr = I->getSubExprAsWritten();
3401
3402 if(subExpr->getStmtClass() != Stmt::StringLiteralClass){
3403 return nullptr;
3404 }
3405
3406 S = static_cast<StringLiteral *>(I->getSubExprAsWritten());
3407 } else if (arg->getStmtClass() == Stmt::StringLiteralClass) {
3408 S = static_cast<StringLiteral *>(callExpr->getArg(0));
3409 } else {
3410 return nullptr;
3411 }
3412 return S;
3413}
3414
David Blaikie59272572016-04-13 18:23:33 +00003415struct ExprEvalResult {
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003416 CXEvalResultKind EvalType;
3417 union {
3418 int intVal;
3419 double floatVal;
3420 char *stringVal;
3421 } EvalData;
David Blaikie59272572016-04-13 18:23:33 +00003422 ~ExprEvalResult() {
3423 if (EvalType != CXEval_UnExposed && EvalType != CXEval_Float &&
3424 EvalType != CXEval_Int) {
3425 delete EvalData.stringVal;
3426 }
3427 }
3428};
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003429
3430void clang_EvalResult_dispose(CXEvalResult E) {
David Blaikie59272572016-04-13 18:23:33 +00003431 delete static_cast<ExprEvalResult *>(E);
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003432}
3433
3434CXEvalResultKind clang_EvalResult_getKind(CXEvalResult E) {
3435 if (!E) {
3436 return CXEval_UnExposed;
3437 }
3438 return ((ExprEvalResult *)E)->EvalType;
3439}
3440
3441int clang_EvalResult_getAsInt(CXEvalResult E) {
3442 if (!E) {
3443 return 0;
3444 }
3445 return ((ExprEvalResult *)E)->EvalData.intVal;
3446}
3447
3448double clang_EvalResult_getAsDouble(CXEvalResult E) {
3449 if (!E) {
3450 return 0;
3451 }
3452 return ((ExprEvalResult *)E)->EvalData.floatVal;
3453}
3454
3455const char* clang_EvalResult_getAsStr(CXEvalResult E) {
3456 if (!E) {
3457 return nullptr;
3458 }
3459 return ((ExprEvalResult *)E)->EvalData.stringVal;
3460}
3461
3462static const ExprEvalResult* evaluateExpr(Expr *expr, CXCursor C) {
3463 Expr::EvalResult ER;
3464 ASTContext &ctx = getCursorContext(C);
David Blaikiebbc00882016-04-13 18:36:19 +00003465 if (!expr)
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003466 return nullptr;
David Blaikiebbc00882016-04-13 18:36:19 +00003467
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003468 expr = expr->IgnoreParens();
David Blaikiebbc00882016-04-13 18:36:19 +00003469 if (!expr->EvaluateAsRValue(ER, ctx))
3470 return nullptr;
3471
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003472 QualType rettype;
3473 CallExpr *callExpr;
David Blaikie59272572016-04-13 18:23:33 +00003474 auto result = llvm::make_unique<ExprEvalResult>();
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003475 result->EvalType = CXEval_UnExposed;
3476
David Blaikiebbc00882016-04-13 18:36:19 +00003477 if (ER.Val.isInt()) {
3478 result->EvalType = CXEval_Int;
3479 result->EvalData.intVal = ER.Val.getInt().getExtValue();
3480 return result.release();
3481 }
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003482
David Blaikiebbc00882016-04-13 18:36:19 +00003483 if (ER.Val.isFloat()) {
3484 llvm::SmallVector<char, 100> Buffer;
3485 ER.Val.getFloat().toString(Buffer);
3486 std::string floatStr(Buffer.data(), Buffer.size());
3487 result->EvalType = CXEval_Float;
3488 bool ignored;
3489 llvm::APFloat apFloat = ER.Val.getFloat();
3490 apFloat.convert(llvm::APFloat::IEEEdouble,
3491 llvm::APFloat::rmNearestTiesToEven, &ignored);
3492 result->EvalData.floatVal = apFloat.convertToDouble();
3493 return result.release();
3494 }
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003495
David Blaikiebbc00882016-04-13 18:36:19 +00003496 if (expr->getStmtClass() == Stmt::ImplicitCastExprClass) {
3497 const ImplicitCastExpr *I = dyn_cast<ImplicitCastExpr>(expr);
3498 auto *subExpr = I->getSubExprAsWritten();
3499 if (subExpr->getStmtClass() == Stmt::StringLiteralClass ||
3500 subExpr->getStmtClass() == Stmt::ObjCStringLiteralClass) {
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003501 const StringLiteral *StrE = nullptr;
3502 const ObjCStringLiteral *ObjCExpr;
David Blaikiebbc00882016-04-13 18:36:19 +00003503 ObjCExpr = dyn_cast<ObjCStringLiteral>(subExpr);
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003504
3505 if (ObjCExpr) {
3506 StrE = ObjCExpr->getString();
3507 result->EvalType = CXEval_ObjCStrLiteral;
3508 } else {
David Blaikiebbc00882016-04-13 18:36:19 +00003509 StrE = cast<StringLiteral>(I->getSubExprAsWritten());
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003510 result->EvalType = CXEval_StrLiteral;
3511 }
3512
3513 std::string strRef(StrE->getString().str());
David Blaikie59272572016-04-13 18:23:33 +00003514 result->EvalData.stringVal = new char[strRef.size() + 1];
David Blaikiebbc00882016-04-13 18:36:19 +00003515 strncpy((char *)result->EvalData.stringVal, strRef.c_str(),
3516 strRef.size());
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003517 result->EvalData.stringVal[strRef.size()] = '\0';
David Blaikie59272572016-04-13 18:23:33 +00003518 return result.release();
David Blaikiebbc00882016-04-13 18:36:19 +00003519 }
3520 } else if (expr->getStmtClass() == Stmt::ObjCStringLiteralClass ||
3521 expr->getStmtClass() == Stmt::StringLiteralClass) {
3522 const StringLiteral *StrE = nullptr;
3523 const ObjCStringLiteral *ObjCExpr;
3524 ObjCExpr = dyn_cast<ObjCStringLiteral>(expr);
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003525
David Blaikiebbc00882016-04-13 18:36:19 +00003526 if (ObjCExpr) {
3527 StrE = ObjCExpr->getString();
3528 result->EvalType = CXEval_ObjCStrLiteral;
3529 } else {
3530 StrE = cast<StringLiteral>(expr);
3531 result->EvalType = CXEval_StrLiteral;
3532 }
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003533
David Blaikiebbc00882016-04-13 18:36:19 +00003534 std::string strRef(StrE->getString().str());
3535 result->EvalData.stringVal = new char[strRef.size() + 1];
3536 strncpy((char *)result->EvalData.stringVal, strRef.c_str(), strRef.size());
3537 result->EvalData.stringVal[strRef.size()] = '\0';
3538 return result.release();
3539 }
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003540
David Blaikiebbc00882016-04-13 18:36:19 +00003541 if (expr->getStmtClass() == Stmt::CStyleCastExprClass) {
3542 CStyleCastExpr *CC = static_cast<CStyleCastExpr *>(expr);
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003543
David Blaikiebbc00882016-04-13 18:36:19 +00003544 rettype = CC->getType();
3545 if (rettype.getAsString() == "CFStringRef" &&
3546 CC->getSubExpr()->getStmtClass() == Stmt::CallExprClass) {
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003547
David Blaikiebbc00882016-04-13 18:36:19 +00003548 callExpr = static_cast<CallExpr *>(CC->getSubExpr());
3549 StringLiteral *S = getCFSTR_value(callExpr);
3550 if (S) {
3551 std::string strLiteral(S->getString().str());
3552 result->EvalType = CXEval_CFStr;
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003553
David Blaikiebbc00882016-04-13 18:36:19 +00003554 result->EvalData.stringVal = new char[strLiteral.size() + 1];
3555 strncpy((char *)result->EvalData.stringVal, strLiteral.c_str(),
3556 strLiteral.size());
3557 result->EvalData.stringVal[strLiteral.size()] = '\0';
David Blaikie59272572016-04-13 18:23:33 +00003558 return result.release();
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003559 }
3560 }
3561
David Blaikiebbc00882016-04-13 18:36:19 +00003562 } else if (expr->getStmtClass() == Stmt::CallExprClass) {
3563 callExpr = static_cast<CallExpr *>(expr);
3564 rettype = callExpr->getCallReturnType(ctx);
3565
3566 if (rettype->isVectorType() || callExpr->getNumArgs() > 1)
3567 return nullptr;
3568
3569 if (rettype->isIntegralType(ctx) || rettype->isRealFloatingType()) {
3570 if (callExpr->getNumArgs() == 1 &&
3571 !callExpr->getArg(0)->getType()->isIntegralType(ctx))
3572 return nullptr;
3573 } else if (rettype.getAsString() == "CFStringRef") {
3574
3575 StringLiteral *S = getCFSTR_value(callExpr);
3576 if (S) {
3577 std::string strLiteral(S->getString().str());
3578 result->EvalType = CXEval_CFStr;
3579 result->EvalData.stringVal = new char[strLiteral.size() + 1];
3580 strncpy((char *)result->EvalData.stringVal, strLiteral.c_str(),
3581 strLiteral.size());
3582 result->EvalData.stringVal[strLiteral.size()] = '\0';
3583 return result.release();
3584 }
3585 }
3586 } else if (expr->getStmtClass() == Stmt::DeclRefExprClass) {
3587 DeclRefExpr *D = static_cast<DeclRefExpr *>(expr);
3588 ValueDecl *V = D->getDecl();
3589 if (V->getKind() == Decl::Function) {
3590 std::string strName = V->getNameAsString();
3591 result->EvalType = CXEval_Other;
3592 result->EvalData.stringVal = new char[strName.size() + 1];
3593 strncpy(result->EvalData.stringVal, strName.c_str(), strName.size());
3594 result->EvalData.stringVal[strName.size()] = '\0';
3595 return result.release();
3596 }
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003597 }
3598
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003599 return nullptr;
3600}
3601
3602CXEvalResult clang_Cursor_Evaluate(CXCursor C) {
3603 const Decl *D = getCursorDecl(C);
3604 if (D) {
3605 const Expr *expr = nullptr;
3606 if (auto *Var = dyn_cast<VarDecl>(D)) {
3607 expr = Var->getInit();
3608 } else if (auto *Field = dyn_cast<FieldDecl>(D)) {
3609 expr = Field->getInClassInitializer();
3610 }
3611 if (expr)
Aaron Ballman01dc1572016-01-20 15:25:30 +00003612 return const_cast<CXEvalResult>(reinterpret_cast<const void *>(
3613 evaluateExpr(const_cast<Expr *>(expr), C)));
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003614 return nullptr;
3615 }
3616
3617 const CompoundStmt *compoundStmt = dyn_cast_or_null<CompoundStmt>(getCursorStmt(C));
3618 if (compoundStmt) {
3619 Expr *expr = nullptr;
3620 for (auto *bodyIterator : compoundStmt->body()) {
3621 if ((expr = dyn_cast<Expr>(bodyIterator))) {
3622 break;
3623 }
3624 }
3625 if (expr)
Aaron Ballman01dc1572016-01-20 15:25:30 +00003626 return const_cast<CXEvalResult>(
3627 reinterpret_cast<const void *>(evaluateExpr(expr, C)));
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003628 }
3629 return nullptr;
3630}
3631
3632unsigned clang_Cursor_hasAttrs(CXCursor C) {
3633 const Decl *D = getCursorDecl(C);
3634 if (!D) {
3635 return 0;
3636 }
3637
3638 if (D->hasAttrs()) {
3639 return 1;
3640 }
3641
3642 return 0;
3643}
Guy Benyei11169dd2012-12-18 14:30:41 +00003644unsigned clang_defaultSaveOptions(CXTranslationUnit TU) {
3645 return CXSaveTranslationUnit_None;
3646}
3647
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003648static CXSaveError clang_saveTranslationUnit_Impl(CXTranslationUnit TU,
3649 const char *FileName,
3650 unsigned options) {
3651 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00003652 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
3653 setThreadBackgroundPriority();
3654
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003655 bool hadError = cxtu::getASTUnit(TU)->Save(FileName);
3656 return hadError ? CXSaveError_Unknown : CXSaveError_None;
Guy Benyei11169dd2012-12-18 14:30:41 +00003657}
3658
3659int clang_saveTranslationUnit(CXTranslationUnit TU, const char *FileName,
3660 unsigned options) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00003661 LOG_FUNC_SECTION {
3662 *Log << TU << ' ' << FileName;
3663 }
3664
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003665 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003666 LOG_BAD_TU(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003667 return CXSaveError_InvalidTU;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003668 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003669
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003670 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003671 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
3672 if (!CXXUnit->hasSema())
3673 return CXSaveError_InvalidTU;
3674
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003675 CXSaveError result;
3676 auto SaveTranslationUnitImpl = [=, &result]() {
3677 result = clang_saveTranslationUnit_Impl(TU, FileName, options);
3678 };
Guy Benyei11169dd2012-12-18 14:30:41 +00003679
3680 if (!CXXUnit->getDiagnostics().hasUnrecoverableErrorOccurred() ||
3681 getenv("LIBCLANG_NOTHREADS")) {
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003682 SaveTranslationUnitImpl();
Guy Benyei11169dd2012-12-18 14:30:41 +00003683
3684 if (getenv("LIBCLANG_RESOURCE_USAGE"))
3685 PrintLibclangResourceUsage(TU);
3686
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003687 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003688 }
3689
3690 // We have an AST that has invalid nodes due to compiler errors.
3691 // Use a crash recovery thread for protection.
3692
3693 llvm::CrashRecoveryContext CRC;
3694
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003695 if (!RunSafely(CRC, SaveTranslationUnitImpl)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003696 fprintf(stderr, "libclang: crash detected during AST saving: {\n");
3697 fprintf(stderr, " 'filename' : '%s'\n", FileName);
3698 fprintf(stderr, " 'options' : %d,\n", options);
3699 fprintf(stderr, "}\n");
3700
3701 return CXSaveError_Unknown;
3702
3703 } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
3704 PrintLibclangResourceUsage(TU);
3705 }
3706
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003707 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003708}
3709
3710void clang_disposeTranslationUnit(CXTranslationUnit CTUnit) {
3711 if (CTUnit) {
3712 // If the translation unit has been marked as unsafe to free, just discard
3713 // it.
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003714 ASTUnit *Unit = cxtu::getASTUnit(CTUnit);
3715 if (Unit && Unit->isUnsafeToFree())
Guy Benyei11169dd2012-12-18 14:30:41 +00003716 return;
3717
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003718 delete cxtu::getASTUnit(CTUnit);
Dmitri Gribenkob95b3f12013-01-26 22:44:19 +00003719 delete CTUnit->StringPool;
Guy Benyei11169dd2012-12-18 14:30:41 +00003720 delete static_cast<CXDiagnosticSetImpl *>(CTUnit->Diagnostics);
3721 disposeOverridenCXCursorsPool(CTUnit->OverridenCursorsPool);
Dmitri Gribenko9e605112013-11-13 22:16:51 +00003722 delete CTUnit->CommentToXML;
Guy Benyei11169dd2012-12-18 14:30:41 +00003723 delete CTUnit;
3724 }
3725}
3726
3727unsigned clang_defaultReparseOptions(CXTranslationUnit TU) {
3728 return CXReparse_None;
3729}
3730
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003731static CXErrorCode
3732clang_reparseTranslationUnit_Impl(CXTranslationUnit TU,
3733 ArrayRef<CXUnsavedFile> unsaved_files,
3734 unsigned options) {
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003735 // Check arguments.
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003736 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003737 LOG_BAD_TU(TU);
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003738 return CXError_InvalidArguments;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003739 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003740
3741 // Reset the associated diagnostics.
3742 delete static_cast<CXDiagnosticSetImpl*>(TU->Diagnostics);
Craig Topper69186e72014-06-08 08:38:04 +00003743 TU->Diagnostics = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00003744
Dmitri Gribenko183436e2013-01-26 21:49:50 +00003745 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00003746 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
3747 setThreadBackgroundPriority();
3748
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003749 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003750 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
Ahmed Charlesb8984322014-03-07 20:03:18 +00003751
3752 std::unique_ptr<std::vector<ASTUnit::RemappedFile>> RemappedFiles(
3753 new std::vector<ASTUnit::RemappedFile>());
3754
Guy Benyei11169dd2012-12-18 14:30:41 +00003755 // Recover resources if we crash before exiting this function.
3756 llvm::CrashRecoveryContextCleanupRegistrar<
3757 std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
Alp Toker9d85b182014-07-07 01:23:14 +00003758
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003759 for (auto &UF : unsaved_files) {
Rafael Espindolad87f8d72014-08-27 20:03:29 +00003760 std::unique_ptr<llvm::MemoryBuffer> MB =
Alp Toker9d85b182014-07-07 01:23:14 +00003761 llvm::MemoryBuffer::getMemBufferCopy(getContents(UF), UF.Filename);
Rafael Espindolad87f8d72014-08-27 20:03:29 +00003762 RemappedFiles->push_back(std::make_pair(UF.Filename, MB.release()));
Guy Benyei11169dd2012-12-18 14:30:41 +00003763 }
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003764
Adrian Prantlbb165fb2015-06-20 18:53:08 +00003765 if (!CXXUnit->Reparse(CXXIdx->getPCHContainerOperations(),
3766 *RemappedFiles.get()))
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003767 return CXError_Success;
3768 if (isASTReadError(CXXUnit))
3769 return CXError_ASTReadError;
3770 return CXError_Failure;
Guy Benyei11169dd2012-12-18 14:30:41 +00003771}
3772
3773int clang_reparseTranslationUnit(CXTranslationUnit TU,
3774 unsigned num_unsaved_files,
3775 struct CXUnsavedFile *unsaved_files,
3776 unsigned options) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00003777 LOG_FUNC_SECTION {
3778 *Log << TU;
3779 }
3780
Alp Toker9d85b182014-07-07 01:23:14 +00003781 if (num_unsaved_files && !unsaved_files)
3782 return CXError_InvalidArguments;
3783
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003784 CXErrorCode result;
3785 auto ReparseTranslationUnitImpl = [=, &result]() {
3786 result = clang_reparseTranslationUnit_Impl(
3787 TU, llvm::makeArrayRef(unsaved_files, num_unsaved_files), options);
3788 };
Guy Benyei11169dd2012-12-18 14:30:41 +00003789
3790 if (getenv("LIBCLANG_NOTHREADS")) {
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003791 ReparseTranslationUnitImpl();
Alp Toker5c532982014-07-07 22:42:03 +00003792 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003793 }
3794
3795 llvm::CrashRecoveryContext CRC;
3796
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003797 if (!RunSafely(CRC, ReparseTranslationUnitImpl)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003798 fprintf(stderr, "libclang: crash detected during reparsing\n");
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003799 cxtu::getASTUnit(TU)->setUnsafeToFree(true);
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003800 return CXError_Crashed;
Guy Benyei11169dd2012-12-18 14:30:41 +00003801 } else if (getenv("LIBCLANG_RESOURCE_USAGE"))
3802 PrintLibclangResourceUsage(TU);
3803
Alp Toker5c532982014-07-07 22:42:03 +00003804 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003805}
3806
3807
3808CXString clang_getTranslationUnitSpelling(CXTranslationUnit CTUnit) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003809 if (isNotUsableTU(CTUnit)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003810 LOG_BAD_TU(CTUnit);
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003811 return cxstring::createEmpty();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003812 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003813
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003814 ASTUnit *CXXUnit = cxtu::getASTUnit(CTUnit);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003815 return cxstring::createDup(CXXUnit->getOriginalSourceFileName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003816}
3817
3818CXCursor clang_getTranslationUnitCursor(CXTranslationUnit TU) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003819 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003820 LOG_BAD_TU(TU);
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00003821 return clang_getNullCursor();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003822 }
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00003823
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003824 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003825 return MakeCXCursor(CXXUnit->getASTContext().getTranslationUnitDecl(), TU);
3826}
3827
3828} // end: extern "C"
3829
3830//===----------------------------------------------------------------------===//
3831// CXFile Operations.
3832//===----------------------------------------------------------------------===//
3833
3834extern "C" {
3835CXString clang_getFileName(CXFile SFile) {
3836 if (!SFile)
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00003837 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00003838
3839 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003840 return cxstring::createRef(FEnt->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003841}
3842
3843time_t clang_getFileTime(CXFile SFile) {
3844 if (!SFile)
3845 return 0;
3846
3847 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
3848 return FEnt->getModificationTime();
3849}
3850
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003851CXFile clang_getFile(CXTranslationUnit TU, const char *file_name) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003852 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003853 LOG_BAD_TU(TU);
Craig Topper69186e72014-06-08 08:38:04 +00003854 return nullptr;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003855 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003856
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003857 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003858
3859 FileManager &FMgr = CXXUnit->getFileManager();
3860 return const_cast<FileEntry *>(FMgr.getFile(file_name));
3861}
3862
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003863unsigned clang_isFileMultipleIncludeGuarded(CXTranslationUnit TU,
3864 CXFile file) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003865 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003866 LOG_BAD_TU(TU);
3867 return 0;
3868 }
3869
3870 if (!file)
Guy Benyei11169dd2012-12-18 14:30:41 +00003871 return 0;
3872
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003873 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003874 FileEntry *FEnt = static_cast<FileEntry *>(file);
3875 return CXXUnit->getPreprocessor().getHeaderSearchInfo()
3876 .isFileMultipleIncludeGuarded(FEnt);
3877}
3878
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003879int clang_getFileUniqueID(CXFile file, CXFileUniqueID *outID) {
3880 if (!file || !outID)
3881 return 1;
3882
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003883 FileEntry *FEnt = static_cast<FileEntry *>(file);
Rafael Espindolaf8f91b82013-08-01 21:42:11 +00003884 const llvm::sys::fs::UniqueID &ID = FEnt->getUniqueID();
3885 outID->data[0] = ID.getDevice();
3886 outID->data[1] = ID.getFile();
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003887 outID->data[2] = FEnt->getModificationTime();
3888 return 0;
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003889}
3890
Argyrios Kyrtzidisac3997e2014-08-16 00:26:19 +00003891int clang_File_isEqual(CXFile file1, CXFile file2) {
3892 if (file1 == file2)
3893 return true;
3894
3895 if (!file1 || !file2)
3896 return false;
3897
3898 FileEntry *FEnt1 = static_cast<FileEntry *>(file1);
3899 FileEntry *FEnt2 = static_cast<FileEntry *>(file2);
3900 return FEnt1->getUniqueID() == FEnt2->getUniqueID();
3901}
3902
Guy Benyei11169dd2012-12-18 14:30:41 +00003903} // end: extern "C"
3904
3905//===----------------------------------------------------------------------===//
3906// CXCursor Operations.
3907//===----------------------------------------------------------------------===//
3908
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003909static const Decl *getDeclFromExpr(const Stmt *E) {
3910 if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003911 return getDeclFromExpr(CE->getSubExpr());
3912
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003913 if (const DeclRefExpr *RefExpr = dyn_cast<DeclRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003914 return RefExpr->getDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003915 if (const MemberExpr *ME = dyn_cast<MemberExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003916 return ME->getMemberDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003917 if (const ObjCIvarRefExpr *RE = dyn_cast<ObjCIvarRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003918 return RE->getDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003919 if (const ObjCPropertyRefExpr *PRE = dyn_cast<ObjCPropertyRefExpr>(E)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003920 if (PRE->isExplicitProperty())
3921 return PRE->getExplicitProperty();
3922 // It could be messaging both getter and setter as in:
3923 // ++myobj.myprop;
3924 // in which case prefer to associate the setter since it is less obvious
3925 // from inspecting the source that the setter is going to get called.
3926 if (PRE->isMessagingSetter())
3927 return PRE->getImplicitPropertySetter();
3928 return PRE->getImplicitPropertyGetter();
3929 }
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003930 if (const PseudoObjectExpr *POE = dyn_cast<PseudoObjectExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003931 return getDeclFromExpr(POE->getSyntacticForm());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003932 if (const OpaqueValueExpr *OVE = dyn_cast<OpaqueValueExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003933 if (Expr *Src = OVE->getSourceExpr())
3934 return getDeclFromExpr(Src);
3935
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003936 if (const CallExpr *CE = dyn_cast<CallExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003937 return getDeclFromExpr(CE->getCallee());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003938 if (const CXXConstructExpr *CE = dyn_cast<CXXConstructExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003939 if (!CE->isElidable())
3940 return CE->getConstructor();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003941 if (const ObjCMessageExpr *OME = dyn_cast<ObjCMessageExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003942 return OME->getMethodDecl();
3943
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003944 if (const ObjCProtocolExpr *PE = dyn_cast<ObjCProtocolExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003945 return PE->getProtocol();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003946 if (const SubstNonTypeTemplateParmPackExpr *NTTP
Guy Benyei11169dd2012-12-18 14:30:41 +00003947 = dyn_cast<SubstNonTypeTemplateParmPackExpr>(E))
3948 return NTTP->getParameterPack();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003949 if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003950 if (isa<NonTypeTemplateParmDecl>(SizeOfPack->getPack()) ||
3951 isa<ParmVarDecl>(SizeOfPack->getPack()))
3952 return SizeOfPack->getPack();
Craig Topper69186e72014-06-08 08:38:04 +00003953
3954 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00003955}
3956
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003957static SourceLocation getLocationFromExpr(const Expr *E) {
3958 if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003959 return getLocationFromExpr(CE->getSubExpr());
3960
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003961 if (const ObjCMessageExpr *Msg = dyn_cast<ObjCMessageExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003962 return /*FIXME:*/Msg->getLeftLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003963 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003964 return DRE->getLocation();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003965 if (const MemberExpr *Member = dyn_cast<MemberExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003966 return Member->getMemberLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003967 if (const ObjCIvarRefExpr *Ivar = dyn_cast<ObjCIvarRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003968 return Ivar->getLocation();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003969 if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003970 return SizeOfPack->getPackLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003971 if (const ObjCPropertyRefExpr *PropRef = dyn_cast<ObjCPropertyRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003972 return PropRef->getLocation();
3973
3974 return E->getLocStart();
3975}
3976
3977extern "C" {
3978
3979unsigned clang_visitChildren(CXCursor parent,
3980 CXCursorVisitor visitor,
3981 CXClientData client_data) {
3982 CursorVisitor CursorVis(getCursorTU(parent), visitor, client_data,
3983 /*VisitPreprocessorLast=*/false);
3984 return CursorVis.VisitChildren(parent);
3985}
3986
3987#ifndef __has_feature
3988#define __has_feature(x) 0
3989#endif
3990#if __has_feature(blocks)
3991typedef enum CXChildVisitResult
3992 (^CXCursorVisitorBlock)(CXCursor cursor, CXCursor parent);
3993
3994static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
3995 CXClientData client_data) {
3996 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
3997 return block(cursor, parent);
3998}
3999#else
4000// If we are compiled with a compiler that doesn't have native blocks support,
4001// define and call the block manually, so the
4002typedef struct _CXChildVisitResult
4003{
4004 void *isa;
4005 int flags;
4006 int reserved;
4007 enum CXChildVisitResult(*invoke)(struct _CXChildVisitResult*, CXCursor,
4008 CXCursor);
4009} *CXCursorVisitorBlock;
4010
4011static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
4012 CXClientData client_data) {
4013 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
4014 return block->invoke(block, cursor, parent);
4015}
4016#endif
4017
4018
4019unsigned clang_visitChildrenWithBlock(CXCursor parent,
4020 CXCursorVisitorBlock block) {
4021 return clang_visitChildren(parent, visitWithBlock, block);
4022}
4023
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004024static CXString getDeclSpelling(const Decl *D) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004025 if (!D)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00004026 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00004027
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004028 const NamedDecl *ND = dyn_cast<NamedDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00004029 if (!ND) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004030 if (const ObjCPropertyImplDecl *PropImpl =
4031 dyn_cast<ObjCPropertyImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004032 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004033 return cxstring::createDup(Property->getIdentifier()->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00004034
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004035 if (const ImportDecl *ImportD = dyn_cast<ImportDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004036 if (Module *Mod = ImportD->getImportedModule())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004037 return cxstring::createDup(Mod->getFullModuleName());
Guy Benyei11169dd2012-12-18 14:30:41 +00004038
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00004039 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00004040 }
4041
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004042 if (const ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(ND))
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004043 return cxstring::createDup(OMD->getSelector().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00004044
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004045 if (const ObjCCategoryImplDecl *CIMP = dyn_cast<ObjCCategoryImplDecl>(ND))
Guy Benyei11169dd2012-12-18 14:30:41 +00004046 // No, this isn't the same as the code below. getIdentifier() is non-virtual
4047 // and returns different names. NamedDecl returns the class name and
4048 // ObjCCategoryImplDecl returns the category name.
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004049 return cxstring::createRef(CIMP->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00004050
4051 if (isa<UsingDirectiveDecl>(D))
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00004052 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00004053
4054 SmallString<1024> S;
4055 llvm::raw_svector_ostream os(S);
4056 ND->printName(os);
4057
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004058 return cxstring::createDup(os.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00004059}
4060
4061CXString clang_getCursorSpelling(CXCursor C) {
4062 if (clang_isTranslationUnit(C.kind))
Dmitri Gribenko2c173b42013-01-11 19:28:44 +00004063 return clang_getTranslationUnitSpelling(getCursorTU(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00004064
4065 if (clang_isReference(C.kind)) {
4066 switch (C.kind) {
4067 case CXCursor_ObjCSuperClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004068 const ObjCInterfaceDecl *Super = getCursorObjCSuperClassRef(C).first;
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004069 return cxstring::createRef(Super->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00004070 }
4071 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004072 const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004073 return cxstring::createRef(Class->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00004074 }
4075 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004076 const ObjCProtocolDecl *OID = getCursorObjCProtocolRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00004077 assert(OID && "getCursorSpelling(): Missing protocol decl");
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004078 return cxstring::createRef(OID->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00004079 }
4080 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004081 const CXXBaseSpecifier *B = getCursorCXXBaseSpecifier(C);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004082 return cxstring::createDup(B->getType().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00004083 }
4084 case CXCursor_TypeRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004085 const TypeDecl *Type = getCursorTypeRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00004086 assert(Type && "Missing type decl");
4087
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004088 return cxstring::createDup(getCursorContext(C).getTypeDeclType(Type).
Guy Benyei11169dd2012-12-18 14:30:41 +00004089 getAsString());
4090 }
4091 case CXCursor_TemplateRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004092 const TemplateDecl *Template = getCursorTemplateRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00004093 assert(Template && "Missing template decl");
4094
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004095 return cxstring::createDup(Template->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00004096 }
4097
4098 case CXCursor_NamespaceRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004099 const NamedDecl *NS = getCursorNamespaceRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00004100 assert(NS && "Missing namespace decl");
4101
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004102 return cxstring::createDup(NS->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00004103 }
4104
4105 case CXCursor_MemberRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004106 const FieldDecl *Field = getCursorMemberRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00004107 assert(Field && "Missing member decl");
4108
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004109 return cxstring::createDup(Field->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00004110 }
4111
4112 case CXCursor_LabelRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004113 const LabelStmt *Label = getCursorLabelRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00004114 assert(Label && "Missing label");
4115
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004116 return cxstring::createRef(Label->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00004117 }
4118
4119 case CXCursor_OverloadedDeclRef: {
4120 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004121 if (const Decl *D = Storage.dyn_cast<const Decl *>()) {
4122 if (const NamedDecl *ND = dyn_cast<NamedDecl>(D))
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004123 return cxstring::createDup(ND->getNameAsString());
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00004124 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00004125 }
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004126 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004127 return cxstring::createDup(E->getName().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00004128 OverloadedTemplateStorage *Ovl
4129 = Storage.get<OverloadedTemplateStorage*>();
4130 if (Ovl->size() == 0)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00004131 return cxstring::createEmpty();
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004132 return cxstring::createDup((*Ovl->begin())->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00004133 }
4134
4135 case CXCursor_VariableRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004136 const VarDecl *Var = getCursorVariableRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00004137 assert(Var && "Missing variable decl");
4138
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004139 return cxstring::createDup(Var->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00004140 }
4141
4142 default:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004143 return cxstring::createRef("<not implemented>");
Guy Benyei11169dd2012-12-18 14:30:41 +00004144 }
4145 }
4146
4147 if (clang_isExpression(C.kind)) {
Argyrios Kyrtzidis3227d862014-03-03 19:40:52 +00004148 const Expr *E = getCursorExpr(C);
4149
4150 if (C.kind == CXCursor_ObjCStringLiteral ||
4151 C.kind == CXCursor_StringLiteral) {
4152 const StringLiteral *SLit;
4153 if (const ObjCStringLiteral *OSL = dyn_cast<ObjCStringLiteral>(E)) {
4154 SLit = OSL->getString();
4155 } else {
4156 SLit = cast<StringLiteral>(E);
4157 }
4158 SmallString<256> Buf;
4159 llvm::raw_svector_ostream OS(Buf);
4160 SLit->outputString(OS);
4161 return cxstring::createDup(OS.str());
4162 }
4163
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004164 const Decl *D = getDeclFromExpr(getCursorExpr(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00004165 if (D)
4166 return getDeclSpelling(D);
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00004167 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00004168 }
4169
4170 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004171 const Stmt *S = getCursorStmt(C);
4172 if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S))
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004173 return cxstring::createRef(Label->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00004174
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00004175 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00004176 }
4177
4178 if (C.kind == CXCursor_MacroExpansion)
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004179 return cxstring::createRef(getCursorMacroExpansion(C).getName()
Guy Benyei11169dd2012-12-18 14:30:41 +00004180 ->getNameStart());
4181
4182 if (C.kind == CXCursor_MacroDefinition)
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004183 return cxstring::createRef(getCursorMacroDefinition(C)->getName()
Guy Benyei11169dd2012-12-18 14:30:41 +00004184 ->getNameStart());
4185
4186 if (C.kind == CXCursor_InclusionDirective)
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004187 return cxstring::createDup(getCursorInclusionDirective(C)->getFileName());
Guy Benyei11169dd2012-12-18 14:30:41 +00004188
4189 if (clang_isDeclaration(C.kind))
4190 return getDeclSpelling(getCursorDecl(C));
4191
4192 if (C.kind == CXCursor_AnnotateAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00004193 const AnnotateAttr *AA = cast<AnnotateAttr>(cxcursor::getCursorAttr(C));
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004194 return cxstring::createDup(AA->getAnnotation());
Guy Benyei11169dd2012-12-18 14:30:41 +00004195 }
4196
4197 if (C.kind == CXCursor_AsmLabelAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00004198 const AsmLabelAttr *AA = cast<AsmLabelAttr>(cxcursor::getCursorAttr(C));
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004199 return cxstring::createDup(AA->getLabel());
Guy Benyei11169dd2012-12-18 14:30:41 +00004200 }
4201
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00004202 if (C.kind == CXCursor_PackedAttr) {
4203 return cxstring::createRef("packed");
4204 }
4205
Saleem Abdulrasool79c69712015-09-05 18:53:43 +00004206 if (C.kind == CXCursor_VisibilityAttr) {
4207 const VisibilityAttr *AA = cast<VisibilityAttr>(cxcursor::getCursorAttr(C));
4208 switch (AA->getVisibility()) {
4209 case VisibilityAttr::VisibilityType::Default:
4210 return cxstring::createRef("default");
4211 case VisibilityAttr::VisibilityType::Hidden:
4212 return cxstring::createRef("hidden");
4213 case VisibilityAttr::VisibilityType::Protected:
4214 return cxstring::createRef("protected");
4215 }
4216 llvm_unreachable("unknown visibility type");
4217 }
4218
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00004219 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00004220}
4221
4222CXSourceRange clang_Cursor_getSpellingNameRange(CXCursor C,
4223 unsigned pieceIndex,
4224 unsigned options) {
4225 if (clang_Cursor_isNull(C))
4226 return clang_getNullRange();
4227
4228 ASTContext &Ctx = getCursorContext(C);
4229
4230 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004231 const Stmt *S = getCursorStmt(C);
4232 if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004233 if (pieceIndex > 0)
4234 return clang_getNullRange();
4235 return cxloc::translateSourceRange(Ctx, Label->getIdentLoc());
4236 }
4237
4238 return clang_getNullRange();
4239 }
4240
4241 if (C.kind == CXCursor_ObjCMessageExpr) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004242 if (const ObjCMessageExpr *
Guy Benyei11169dd2012-12-18 14:30:41 +00004243 ME = dyn_cast_or_null<ObjCMessageExpr>(getCursorExpr(C))) {
4244 if (pieceIndex >= ME->getNumSelectorLocs())
4245 return clang_getNullRange();
4246 return cxloc::translateSourceRange(Ctx, ME->getSelectorLoc(pieceIndex));
4247 }
4248 }
4249
4250 if (C.kind == CXCursor_ObjCInstanceMethodDecl ||
4251 C.kind == CXCursor_ObjCClassMethodDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004252 if (const ObjCMethodDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00004253 MD = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(C))) {
4254 if (pieceIndex >= MD->getNumSelectorLocs())
4255 return clang_getNullRange();
4256 return cxloc::translateSourceRange(Ctx, MD->getSelectorLoc(pieceIndex));
4257 }
4258 }
4259
4260 if (C.kind == CXCursor_ObjCCategoryDecl ||
4261 C.kind == CXCursor_ObjCCategoryImplDecl) {
4262 if (pieceIndex > 0)
4263 return clang_getNullRange();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004264 if (const ObjCCategoryDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00004265 CD = dyn_cast_or_null<ObjCCategoryDecl>(getCursorDecl(C)))
4266 return cxloc::translateSourceRange(Ctx, CD->getCategoryNameLoc());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004267 if (const ObjCCategoryImplDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00004268 CID = dyn_cast_or_null<ObjCCategoryImplDecl>(getCursorDecl(C)))
4269 return cxloc::translateSourceRange(Ctx, CID->getCategoryNameLoc());
4270 }
4271
4272 if (C.kind == CXCursor_ModuleImportDecl) {
4273 if (pieceIndex > 0)
4274 return clang_getNullRange();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004275 if (const ImportDecl *ImportD =
4276 dyn_cast_or_null<ImportDecl>(getCursorDecl(C))) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004277 ArrayRef<SourceLocation> Locs = ImportD->getIdentifierLocs();
4278 if (!Locs.empty())
4279 return cxloc::translateSourceRange(Ctx,
4280 SourceRange(Locs.front(), Locs.back()));
4281 }
4282 return clang_getNullRange();
4283 }
4284
Argyrios Kyrtzidisa2a1e532014-08-26 20:23:26 +00004285 if (C.kind == CXCursor_CXXMethod || C.kind == CXCursor_Destructor ||
4286 C.kind == CXCursor_ConversionFunction) {
4287 if (pieceIndex > 0)
4288 return clang_getNullRange();
4289 if (const FunctionDecl *FD =
4290 dyn_cast_or_null<FunctionDecl>(getCursorDecl(C))) {
4291 DeclarationNameInfo FunctionName = FD->getNameInfo();
4292 return cxloc::translateSourceRange(Ctx, FunctionName.getSourceRange());
4293 }
4294 return clang_getNullRange();
4295 }
4296
Guy Benyei11169dd2012-12-18 14:30:41 +00004297 // FIXME: A CXCursor_InclusionDirective should give the location of the
4298 // filename, but we don't keep track of this.
4299
4300 // FIXME: A CXCursor_AnnotateAttr should give the location of the annotation
4301 // but we don't keep track of this.
4302
4303 // FIXME: A CXCursor_AsmLabelAttr should give the location of the label
4304 // but we don't keep track of this.
4305
4306 // Default handling, give the location of the cursor.
4307
4308 if (pieceIndex > 0)
4309 return clang_getNullRange();
4310
4311 CXSourceLocation CXLoc = clang_getCursorLocation(C);
4312 SourceLocation Loc = cxloc::translateSourceLocation(CXLoc);
4313 return cxloc::translateSourceRange(Ctx, Loc);
4314}
4315
Eli Bendersky44a206f2014-07-31 18:04:56 +00004316CXString clang_Cursor_getMangling(CXCursor C) {
4317 if (clang_isInvalid(C.kind) || !clang_isDeclaration(C.kind))
4318 return cxstring::createEmpty();
4319
Eli Bendersky44a206f2014-07-31 18:04:56 +00004320 // Mangling only works for functions and variables.
Eli Bendersky79759592014-08-01 15:01:10 +00004321 const Decl *D = getCursorDecl(C);
Eli Bendersky44a206f2014-07-31 18:04:56 +00004322 if (!D || !(isa<FunctionDecl>(D) || isa<VarDecl>(D)))
4323 return cxstring::createEmpty();
4324
Argyrios Kyrtzidisca741ce2016-02-14 22:30:14 +00004325 ASTContext &Ctx = D->getASTContext();
4326 index::CodegenNameGenerator CGNameGen(Ctx);
4327 return cxstring::createDup(CGNameGen.getName(D));
Eli Bendersky44a206f2014-07-31 18:04:56 +00004328}
4329
Saleem Abdulrasool60034432015-11-12 03:57:22 +00004330CXStringSet *clang_Cursor_getCXXManglings(CXCursor C) {
4331 if (clang_isInvalid(C.kind) || !clang_isDeclaration(C.kind))
4332 return nullptr;
4333
4334 const Decl *D = getCursorDecl(C);
4335 if (!(isa<CXXRecordDecl>(D) || isa<CXXMethodDecl>(D)))
4336 return nullptr;
4337
Argyrios Kyrtzidisca741ce2016-02-14 22:30:14 +00004338 ASTContext &Ctx = D->getASTContext();
4339 index::CodegenNameGenerator CGNameGen(Ctx);
4340 std::vector<std::string> Manglings = CGNameGen.getAllManglings(D);
Saleem Abdulrasool60034432015-11-12 03:57:22 +00004341 return cxstring::createSet(Manglings);
4342}
4343
Guy Benyei11169dd2012-12-18 14:30:41 +00004344CXString clang_getCursorDisplayName(CXCursor C) {
4345 if (!clang_isDeclaration(C.kind))
4346 return clang_getCursorSpelling(C);
4347
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004348 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004349 if (!D)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00004350 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00004351
4352 PrintingPolicy Policy = getCursorContext(C).getPrintingPolicy();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004353 if (const FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004354 D = FunTmpl->getTemplatedDecl();
4355
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004356 if (const FunctionDecl *Function = dyn_cast<FunctionDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004357 SmallString<64> Str;
4358 llvm::raw_svector_ostream OS(Str);
4359 OS << *Function;
4360 if (Function->getPrimaryTemplate())
4361 OS << "<>";
4362 OS << "(";
4363 for (unsigned I = 0, N = Function->getNumParams(); I != N; ++I) {
4364 if (I)
4365 OS << ", ";
4366 OS << Function->getParamDecl(I)->getType().getAsString(Policy);
4367 }
4368
4369 if (Function->isVariadic()) {
4370 if (Function->getNumParams())
4371 OS << ", ";
4372 OS << "...";
4373 }
4374 OS << ")";
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004375 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00004376 }
4377
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004378 if (const ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004379 SmallString<64> Str;
4380 llvm::raw_svector_ostream OS(Str);
4381 OS << *ClassTemplate;
4382 OS << "<";
4383 TemplateParameterList *Params = ClassTemplate->getTemplateParameters();
4384 for (unsigned I = 0, N = Params->size(); I != N; ++I) {
4385 if (I)
4386 OS << ", ";
4387
4388 NamedDecl *Param = Params->getParam(I);
4389 if (Param->getIdentifier()) {
4390 OS << Param->getIdentifier()->getName();
4391 continue;
4392 }
4393
4394 // There is no parameter name, which makes this tricky. Try to come up
4395 // with something useful that isn't too long.
4396 if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(Param))
4397 OS << (TTP->wasDeclaredWithTypename()? "typename" : "class");
4398 else if (NonTypeTemplateParmDecl *NTTP
4399 = dyn_cast<NonTypeTemplateParmDecl>(Param))
4400 OS << NTTP->getType().getAsString(Policy);
4401 else
4402 OS << "template<...> class";
4403 }
4404
4405 OS << ">";
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004406 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00004407 }
4408
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004409 if (const ClassTemplateSpecializationDecl *ClassSpec
Guy Benyei11169dd2012-12-18 14:30:41 +00004410 = dyn_cast<ClassTemplateSpecializationDecl>(D)) {
4411 // If the type was explicitly written, use that.
4412 if (TypeSourceInfo *TSInfo = ClassSpec->getTypeAsWritten())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004413 return cxstring::createDup(TSInfo->getType().getAsString(Policy));
Guy Benyei11169dd2012-12-18 14:30:41 +00004414
Benjamin Kramer9170e912013-02-22 15:46:01 +00004415 SmallString<128> Str;
Guy Benyei11169dd2012-12-18 14:30:41 +00004416 llvm::raw_svector_ostream OS(Str);
4417 OS << *ClassSpec;
Benjamin Kramer9170e912013-02-22 15:46:01 +00004418 TemplateSpecializationType::PrintTemplateArgumentList(OS,
Guy Benyei11169dd2012-12-18 14:30:41 +00004419 ClassSpec->getTemplateArgs().data(),
4420 ClassSpec->getTemplateArgs().size(),
4421 Policy);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004422 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00004423 }
4424
4425 return clang_getCursorSpelling(C);
4426}
4427
4428CXString clang_getCursorKindSpelling(enum CXCursorKind Kind) {
4429 switch (Kind) {
4430 case CXCursor_FunctionDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004431 return cxstring::createRef("FunctionDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004432 case CXCursor_TypedefDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004433 return cxstring::createRef("TypedefDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004434 case CXCursor_EnumDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004435 return cxstring::createRef("EnumDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004436 case CXCursor_EnumConstantDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004437 return cxstring::createRef("EnumConstantDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004438 case CXCursor_StructDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004439 return cxstring::createRef("StructDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004440 case CXCursor_UnionDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004441 return cxstring::createRef("UnionDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004442 case CXCursor_ClassDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004443 return cxstring::createRef("ClassDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004444 case CXCursor_FieldDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004445 return cxstring::createRef("FieldDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004446 case CXCursor_VarDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004447 return cxstring::createRef("VarDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004448 case CXCursor_ParmDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004449 return cxstring::createRef("ParmDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004450 case CXCursor_ObjCInterfaceDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004451 return cxstring::createRef("ObjCInterfaceDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004452 case CXCursor_ObjCCategoryDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004453 return cxstring::createRef("ObjCCategoryDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004454 case CXCursor_ObjCProtocolDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004455 return cxstring::createRef("ObjCProtocolDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004456 case CXCursor_ObjCPropertyDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004457 return cxstring::createRef("ObjCPropertyDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004458 case CXCursor_ObjCIvarDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004459 return cxstring::createRef("ObjCIvarDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004460 case CXCursor_ObjCInstanceMethodDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004461 return cxstring::createRef("ObjCInstanceMethodDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004462 case CXCursor_ObjCClassMethodDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004463 return cxstring::createRef("ObjCClassMethodDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004464 case CXCursor_ObjCImplementationDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004465 return cxstring::createRef("ObjCImplementationDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004466 case CXCursor_ObjCCategoryImplDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004467 return cxstring::createRef("ObjCCategoryImplDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004468 case CXCursor_CXXMethod:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004469 return cxstring::createRef("CXXMethod");
Guy Benyei11169dd2012-12-18 14:30:41 +00004470 case CXCursor_UnexposedDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004471 return cxstring::createRef("UnexposedDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004472 case CXCursor_ObjCSuperClassRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004473 return cxstring::createRef("ObjCSuperClassRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004474 case CXCursor_ObjCProtocolRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004475 return cxstring::createRef("ObjCProtocolRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004476 case CXCursor_ObjCClassRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004477 return cxstring::createRef("ObjCClassRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004478 case CXCursor_TypeRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004479 return cxstring::createRef("TypeRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004480 case CXCursor_TemplateRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004481 return cxstring::createRef("TemplateRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004482 case CXCursor_NamespaceRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004483 return cxstring::createRef("NamespaceRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004484 case CXCursor_MemberRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004485 return cxstring::createRef("MemberRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004486 case CXCursor_LabelRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004487 return cxstring::createRef("LabelRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004488 case CXCursor_OverloadedDeclRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004489 return cxstring::createRef("OverloadedDeclRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004490 case CXCursor_VariableRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004491 return cxstring::createRef("VariableRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004492 case CXCursor_IntegerLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004493 return cxstring::createRef("IntegerLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00004494 case CXCursor_FloatingLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004495 return cxstring::createRef("FloatingLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00004496 case CXCursor_ImaginaryLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004497 return cxstring::createRef("ImaginaryLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00004498 case CXCursor_StringLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004499 return cxstring::createRef("StringLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00004500 case CXCursor_CharacterLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004501 return cxstring::createRef("CharacterLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00004502 case CXCursor_ParenExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004503 return cxstring::createRef("ParenExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004504 case CXCursor_UnaryOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004505 return cxstring::createRef("UnaryOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00004506 case CXCursor_ArraySubscriptExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004507 return cxstring::createRef("ArraySubscriptExpr");
Alexey Bataev1a3320e2015-08-25 14:24:04 +00004508 case CXCursor_OMPArraySectionExpr:
4509 return cxstring::createRef("OMPArraySectionExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004510 case CXCursor_BinaryOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004511 return cxstring::createRef("BinaryOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00004512 case CXCursor_CompoundAssignOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004513 return cxstring::createRef("CompoundAssignOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00004514 case CXCursor_ConditionalOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004515 return cxstring::createRef("ConditionalOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00004516 case CXCursor_CStyleCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004517 return cxstring::createRef("CStyleCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004518 case CXCursor_CompoundLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004519 return cxstring::createRef("CompoundLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004520 case CXCursor_InitListExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004521 return cxstring::createRef("InitListExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004522 case CXCursor_AddrLabelExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004523 return cxstring::createRef("AddrLabelExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004524 case CXCursor_StmtExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004525 return cxstring::createRef("StmtExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004526 case CXCursor_GenericSelectionExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004527 return cxstring::createRef("GenericSelectionExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004528 case CXCursor_GNUNullExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004529 return cxstring::createRef("GNUNullExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004530 case CXCursor_CXXStaticCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004531 return cxstring::createRef("CXXStaticCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004532 case CXCursor_CXXDynamicCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004533 return cxstring::createRef("CXXDynamicCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004534 case CXCursor_CXXReinterpretCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004535 return cxstring::createRef("CXXReinterpretCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004536 case CXCursor_CXXConstCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004537 return cxstring::createRef("CXXConstCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004538 case CXCursor_CXXFunctionalCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004539 return cxstring::createRef("CXXFunctionalCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004540 case CXCursor_CXXTypeidExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004541 return cxstring::createRef("CXXTypeidExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004542 case CXCursor_CXXBoolLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004543 return cxstring::createRef("CXXBoolLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004544 case CXCursor_CXXNullPtrLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004545 return cxstring::createRef("CXXNullPtrLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004546 case CXCursor_CXXThisExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004547 return cxstring::createRef("CXXThisExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004548 case CXCursor_CXXThrowExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004549 return cxstring::createRef("CXXThrowExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004550 case CXCursor_CXXNewExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004551 return cxstring::createRef("CXXNewExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004552 case CXCursor_CXXDeleteExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004553 return cxstring::createRef("CXXDeleteExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004554 case CXCursor_UnaryExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004555 return cxstring::createRef("UnaryExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004556 case CXCursor_ObjCStringLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004557 return cxstring::createRef("ObjCStringLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00004558 case CXCursor_ObjCBoolLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004559 return cxstring::createRef("ObjCBoolLiteralExpr");
Argyrios Kyrtzidisc2233be2013-04-23 17:57:17 +00004560 case CXCursor_ObjCSelfExpr:
4561 return cxstring::createRef("ObjCSelfExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004562 case CXCursor_ObjCEncodeExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004563 return cxstring::createRef("ObjCEncodeExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004564 case CXCursor_ObjCSelectorExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004565 return cxstring::createRef("ObjCSelectorExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004566 case CXCursor_ObjCProtocolExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004567 return cxstring::createRef("ObjCProtocolExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004568 case CXCursor_ObjCBridgedCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004569 return cxstring::createRef("ObjCBridgedCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004570 case CXCursor_BlockExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004571 return cxstring::createRef("BlockExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004572 case CXCursor_PackExpansionExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004573 return cxstring::createRef("PackExpansionExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004574 case CXCursor_SizeOfPackExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004575 return cxstring::createRef("SizeOfPackExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004576 case CXCursor_LambdaExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004577 return cxstring::createRef("LambdaExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004578 case CXCursor_UnexposedExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004579 return cxstring::createRef("UnexposedExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004580 case CXCursor_DeclRefExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004581 return cxstring::createRef("DeclRefExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004582 case CXCursor_MemberRefExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004583 return cxstring::createRef("MemberRefExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004584 case CXCursor_CallExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004585 return cxstring::createRef("CallExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004586 case CXCursor_ObjCMessageExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004587 return cxstring::createRef("ObjCMessageExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004588 case CXCursor_UnexposedStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004589 return cxstring::createRef("UnexposedStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004590 case CXCursor_DeclStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004591 return cxstring::createRef("DeclStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004592 case CXCursor_LabelStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004593 return cxstring::createRef("LabelStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004594 case CXCursor_CompoundStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004595 return cxstring::createRef("CompoundStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004596 case CXCursor_CaseStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004597 return cxstring::createRef("CaseStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004598 case CXCursor_DefaultStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004599 return cxstring::createRef("DefaultStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004600 case CXCursor_IfStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004601 return cxstring::createRef("IfStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004602 case CXCursor_SwitchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004603 return cxstring::createRef("SwitchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004604 case CXCursor_WhileStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004605 return cxstring::createRef("WhileStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004606 case CXCursor_DoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004607 return cxstring::createRef("DoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004608 case CXCursor_ForStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004609 return cxstring::createRef("ForStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004610 case CXCursor_GotoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004611 return cxstring::createRef("GotoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004612 case CXCursor_IndirectGotoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004613 return cxstring::createRef("IndirectGotoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004614 case CXCursor_ContinueStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004615 return cxstring::createRef("ContinueStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004616 case CXCursor_BreakStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004617 return cxstring::createRef("BreakStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004618 case CXCursor_ReturnStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004619 return cxstring::createRef("ReturnStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004620 case CXCursor_GCCAsmStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004621 return cxstring::createRef("GCCAsmStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004622 case CXCursor_MSAsmStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004623 return cxstring::createRef("MSAsmStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004624 case CXCursor_ObjCAtTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004625 return cxstring::createRef("ObjCAtTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004626 case CXCursor_ObjCAtCatchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004627 return cxstring::createRef("ObjCAtCatchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004628 case CXCursor_ObjCAtFinallyStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004629 return cxstring::createRef("ObjCAtFinallyStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004630 case CXCursor_ObjCAtThrowStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004631 return cxstring::createRef("ObjCAtThrowStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004632 case CXCursor_ObjCAtSynchronizedStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004633 return cxstring::createRef("ObjCAtSynchronizedStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004634 case CXCursor_ObjCAutoreleasePoolStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004635 return cxstring::createRef("ObjCAutoreleasePoolStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004636 case CXCursor_ObjCForCollectionStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004637 return cxstring::createRef("ObjCForCollectionStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004638 case CXCursor_CXXCatchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004639 return cxstring::createRef("CXXCatchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004640 case CXCursor_CXXTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004641 return cxstring::createRef("CXXTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004642 case CXCursor_CXXForRangeStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004643 return cxstring::createRef("CXXForRangeStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004644 case CXCursor_SEHTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004645 return cxstring::createRef("SEHTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004646 case CXCursor_SEHExceptStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004647 return cxstring::createRef("SEHExceptStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004648 case CXCursor_SEHFinallyStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004649 return cxstring::createRef("SEHFinallyStmt");
Nico Weber9b982072014-07-07 00:12:30 +00004650 case CXCursor_SEHLeaveStmt:
4651 return cxstring::createRef("SEHLeaveStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004652 case CXCursor_NullStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004653 return cxstring::createRef("NullStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004654 case CXCursor_InvalidFile:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004655 return cxstring::createRef("InvalidFile");
Guy Benyei11169dd2012-12-18 14:30:41 +00004656 case CXCursor_InvalidCode:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004657 return cxstring::createRef("InvalidCode");
Guy Benyei11169dd2012-12-18 14:30:41 +00004658 case CXCursor_NoDeclFound:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004659 return cxstring::createRef("NoDeclFound");
Guy Benyei11169dd2012-12-18 14:30:41 +00004660 case CXCursor_NotImplemented:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004661 return cxstring::createRef("NotImplemented");
Guy Benyei11169dd2012-12-18 14:30:41 +00004662 case CXCursor_TranslationUnit:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004663 return cxstring::createRef("TranslationUnit");
Guy Benyei11169dd2012-12-18 14:30:41 +00004664 case CXCursor_UnexposedAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004665 return cxstring::createRef("UnexposedAttr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004666 case CXCursor_IBActionAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004667 return cxstring::createRef("attribute(ibaction)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004668 case CXCursor_IBOutletAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004669 return cxstring::createRef("attribute(iboutlet)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004670 case CXCursor_IBOutletCollectionAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004671 return cxstring::createRef("attribute(iboutletcollection)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004672 case CXCursor_CXXFinalAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004673 return cxstring::createRef("attribute(final)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004674 case CXCursor_CXXOverrideAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004675 return cxstring::createRef("attribute(override)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004676 case CXCursor_AnnotateAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004677 return cxstring::createRef("attribute(annotate)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004678 case CXCursor_AsmLabelAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004679 return cxstring::createRef("asm label");
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00004680 case CXCursor_PackedAttr:
4681 return cxstring::createRef("attribute(packed)");
Joey Gouly81228382014-05-01 15:41:58 +00004682 case CXCursor_PureAttr:
4683 return cxstring::createRef("attribute(pure)");
4684 case CXCursor_ConstAttr:
4685 return cxstring::createRef("attribute(const)");
4686 case CXCursor_NoDuplicateAttr:
4687 return cxstring::createRef("attribute(noduplicate)");
Eli Bendersky2581e662014-05-28 19:29:58 +00004688 case CXCursor_CUDAConstantAttr:
4689 return cxstring::createRef("attribute(constant)");
4690 case CXCursor_CUDADeviceAttr:
4691 return cxstring::createRef("attribute(device)");
4692 case CXCursor_CUDAGlobalAttr:
4693 return cxstring::createRef("attribute(global)");
4694 case CXCursor_CUDAHostAttr:
4695 return cxstring::createRef("attribute(host)");
Eli Bendersky9b071472014-08-08 14:59:00 +00004696 case CXCursor_CUDASharedAttr:
4697 return cxstring::createRef("attribute(shared)");
Saleem Abdulrasool79c69712015-09-05 18:53:43 +00004698 case CXCursor_VisibilityAttr:
4699 return cxstring::createRef("attribute(visibility)");
Saleem Abdulrasool8aa0b802015-12-10 18:45:18 +00004700 case CXCursor_DLLExport:
4701 return cxstring::createRef("attribute(dllexport)");
4702 case CXCursor_DLLImport:
4703 return cxstring::createRef("attribute(dllimport)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004704 case CXCursor_PreprocessingDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004705 return cxstring::createRef("preprocessing directive");
Guy Benyei11169dd2012-12-18 14:30:41 +00004706 case CXCursor_MacroDefinition:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004707 return cxstring::createRef("macro definition");
Guy Benyei11169dd2012-12-18 14:30:41 +00004708 case CXCursor_MacroExpansion:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004709 return cxstring::createRef("macro expansion");
Guy Benyei11169dd2012-12-18 14:30:41 +00004710 case CXCursor_InclusionDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004711 return cxstring::createRef("inclusion directive");
Guy Benyei11169dd2012-12-18 14:30:41 +00004712 case CXCursor_Namespace:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004713 return cxstring::createRef("Namespace");
Guy Benyei11169dd2012-12-18 14:30:41 +00004714 case CXCursor_LinkageSpec:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004715 return cxstring::createRef("LinkageSpec");
Guy Benyei11169dd2012-12-18 14:30:41 +00004716 case CXCursor_CXXBaseSpecifier:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004717 return cxstring::createRef("C++ base class specifier");
Guy Benyei11169dd2012-12-18 14:30:41 +00004718 case CXCursor_Constructor:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004719 return cxstring::createRef("CXXConstructor");
Guy Benyei11169dd2012-12-18 14:30:41 +00004720 case CXCursor_Destructor:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004721 return cxstring::createRef("CXXDestructor");
Guy Benyei11169dd2012-12-18 14:30:41 +00004722 case CXCursor_ConversionFunction:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004723 return cxstring::createRef("CXXConversion");
Guy Benyei11169dd2012-12-18 14:30:41 +00004724 case CXCursor_TemplateTypeParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004725 return cxstring::createRef("TemplateTypeParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00004726 case CXCursor_NonTypeTemplateParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004727 return cxstring::createRef("NonTypeTemplateParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00004728 case CXCursor_TemplateTemplateParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004729 return cxstring::createRef("TemplateTemplateParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00004730 case CXCursor_FunctionTemplate:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004731 return cxstring::createRef("FunctionTemplate");
Guy Benyei11169dd2012-12-18 14:30:41 +00004732 case CXCursor_ClassTemplate:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004733 return cxstring::createRef("ClassTemplate");
Guy Benyei11169dd2012-12-18 14:30:41 +00004734 case CXCursor_ClassTemplatePartialSpecialization:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004735 return cxstring::createRef("ClassTemplatePartialSpecialization");
Guy Benyei11169dd2012-12-18 14:30:41 +00004736 case CXCursor_NamespaceAlias:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004737 return cxstring::createRef("NamespaceAlias");
Guy Benyei11169dd2012-12-18 14:30:41 +00004738 case CXCursor_UsingDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004739 return cxstring::createRef("UsingDirective");
Guy Benyei11169dd2012-12-18 14:30:41 +00004740 case CXCursor_UsingDeclaration:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004741 return cxstring::createRef("UsingDeclaration");
Guy Benyei11169dd2012-12-18 14:30:41 +00004742 case CXCursor_TypeAliasDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004743 return cxstring::createRef("TypeAliasDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004744 case CXCursor_ObjCSynthesizeDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004745 return cxstring::createRef("ObjCSynthesizeDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004746 case CXCursor_ObjCDynamicDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004747 return cxstring::createRef("ObjCDynamicDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004748 case CXCursor_CXXAccessSpecifier:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004749 return cxstring::createRef("CXXAccessSpecifier");
Guy Benyei11169dd2012-12-18 14:30:41 +00004750 case CXCursor_ModuleImportDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004751 return cxstring::createRef("ModuleImport");
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00004752 case CXCursor_OMPParallelDirective:
Alexey Bataev1b59ab52014-02-27 08:29:12 +00004753 return cxstring::createRef("OMPParallelDirective");
4754 case CXCursor_OMPSimdDirective:
4755 return cxstring::createRef("OMPSimdDirective");
Alexey Bataevf29276e2014-06-18 04:14:57 +00004756 case CXCursor_OMPForDirective:
4757 return cxstring::createRef("OMPForDirective");
Alexander Musmanf82886e2014-09-18 05:12:34 +00004758 case CXCursor_OMPForSimdDirective:
4759 return cxstring::createRef("OMPForSimdDirective");
Alexey Bataevd3f8dd22014-06-25 11:44:49 +00004760 case CXCursor_OMPSectionsDirective:
4761 return cxstring::createRef("OMPSectionsDirective");
Alexey Bataev1e0498a2014-06-26 08:21:58 +00004762 case CXCursor_OMPSectionDirective:
4763 return cxstring::createRef("OMPSectionDirective");
Alexey Bataevd1e40fb2014-06-26 12:05:45 +00004764 case CXCursor_OMPSingleDirective:
4765 return cxstring::createRef("OMPSingleDirective");
Alexander Musman80c22892014-07-17 08:54:58 +00004766 case CXCursor_OMPMasterDirective:
4767 return cxstring::createRef("OMPMasterDirective");
Alexander Musmand9ed09f2014-07-21 09:42:05 +00004768 case CXCursor_OMPCriticalDirective:
4769 return cxstring::createRef("OMPCriticalDirective");
Alexey Bataev4acb8592014-07-07 13:01:15 +00004770 case CXCursor_OMPParallelForDirective:
4771 return cxstring::createRef("OMPParallelForDirective");
Alexander Musmane4e893b2014-09-23 09:33:00 +00004772 case CXCursor_OMPParallelForSimdDirective:
4773 return cxstring::createRef("OMPParallelForSimdDirective");
Alexey Bataev84d0b3e2014-07-08 08:12:03 +00004774 case CXCursor_OMPParallelSectionsDirective:
4775 return cxstring::createRef("OMPParallelSectionsDirective");
Alexey Bataev9c2e8ee2014-07-11 11:25:16 +00004776 case CXCursor_OMPTaskDirective:
4777 return cxstring::createRef("OMPTaskDirective");
Alexey Bataev68446b72014-07-18 07:47:19 +00004778 case CXCursor_OMPTaskyieldDirective:
4779 return cxstring::createRef("OMPTaskyieldDirective");
Alexey Bataev4d1dfea2014-07-18 09:11:51 +00004780 case CXCursor_OMPBarrierDirective:
4781 return cxstring::createRef("OMPBarrierDirective");
Alexey Bataev2df347a2014-07-18 10:17:07 +00004782 case CXCursor_OMPTaskwaitDirective:
4783 return cxstring::createRef("OMPTaskwaitDirective");
Alexey Bataevc30dd2d2015-06-18 12:14:09 +00004784 case CXCursor_OMPTaskgroupDirective:
4785 return cxstring::createRef("OMPTaskgroupDirective");
Alexey Bataev6125da92014-07-21 11:26:11 +00004786 case CXCursor_OMPFlushDirective:
4787 return cxstring::createRef("OMPFlushDirective");
Alexey Bataev9fb6e642014-07-22 06:45:04 +00004788 case CXCursor_OMPOrderedDirective:
4789 return cxstring::createRef("OMPOrderedDirective");
Alexey Bataev0162e452014-07-22 10:10:35 +00004790 case CXCursor_OMPAtomicDirective:
4791 return cxstring::createRef("OMPAtomicDirective");
Alexey Bataev0bd520b2014-09-19 08:19:49 +00004792 case CXCursor_OMPTargetDirective:
4793 return cxstring::createRef("OMPTargetDirective");
Michael Wong65f367f2015-07-21 13:44:28 +00004794 case CXCursor_OMPTargetDataDirective:
4795 return cxstring::createRef("OMPTargetDataDirective");
Samuel Antaodf67fc42016-01-19 19:15:56 +00004796 case CXCursor_OMPTargetEnterDataDirective:
4797 return cxstring::createRef("OMPTargetEnterDataDirective");
Samuel Antao72590762016-01-19 20:04:50 +00004798 case CXCursor_OMPTargetExitDataDirective:
4799 return cxstring::createRef("OMPTargetExitDataDirective");
Arpith Chacko Jacobe955b3d2016-01-26 18:48:41 +00004800 case CXCursor_OMPTargetParallelDirective:
4801 return cxstring::createRef("OMPTargetParallelDirective");
Arpith Chacko Jacob05bebb52016-02-03 15:46:42 +00004802 case CXCursor_OMPTargetParallelForDirective:
4803 return cxstring::createRef("OMPTargetParallelForDirective");
Samuel Antao686c70c2016-05-26 17:30:50 +00004804 case CXCursor_OMPTargetUpdateDirective:
4805 return cxstring::createRef("OMPTargetUpdateDirective");
Alexey Bataev13314bf2014-10-09 04:18:56 +00004806 case CXCursor_OMPTeamsDirective:
4807 return cxstring::createRef("OMPTeamsDirective");
Alexey Bataev6d4ed052015-07-01 06:57:41 +00004808 case CXCursor_OMPCancellationPointDirective:
4809 return cxstring::createRef("OMPCancellationPointDirective");
Alexey Bataev80909872015-07-02 11:25:17 +00004810 case CXCursor_OMPCancelDirective:
4811 return cxstring::createRef("OMPCancelDirective");
Alexey Bataev49f6e782015-12-01 04:18:41 +00004812 case CXCursor_OMPTaskLoopDirective:
4813 return cxstring::createRef("OMPTaskLoopDirective");
Alexey Bataev0a6ed842015-12-03 09:40:15 +00004814 case CXCursor_OMPTaskLoopSimdDirective:
4815 return cxstring::createRef("OMPTaskLoopSimdDirective");
Carlo Bertolli6200a3d2015-12-14 14:51:25 +00004816 case CXCursor_OMPDistributeDirective:
4817 return cxstring::createRef("OMPDistributeDirective");
Francisco Lopes da Silva975a9f62015-01-21 16:24:11 +00004818 case CXCursor_OverloadCandidate:
4819 return cxstring::createRef("OverloadCandidate");
Sergey Kalinichev8f3b1872015-11-15 13:48:32 +00004820 case CXCursor_TypeAliasTemplateDecl:
4821 return cxstring::createRef("TypeAliasTemplateDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004822 }
4823
4824 llvm_unreachable("Unhandled CXCursorKind");
4825}
4826
4827struct GetCursorData {
4828 SourceLocation TokenBeginLoc;
4829 bool PointsAtMacroArgExpansion;
4830 bool VisitedObjCPropertyImplDecl;
4831 SourceLocation VisitedDeclaratorDeclStartLoc;
4832 CXCursor &BestCursor;
4833
4834 GetCursorData(SourceManager &SM,
4835 SourceLocation tokenBegin, CXCursor &outputCursor)
4836 : TokenBeginLoc(tokenBegin), BestCursor(outputCursor) {
4837 PointsAtMacroArgExpansion = SM.isMacroArgExpansion(tokenBegin);
4838 VisitedObjCPropertyImplDecl = false;
4839 }
4840};
4841
4842static enum CXChildVisitResult GetCursorVisitor(CXCursor cursor,
4843 CXCursor parent,
4844 CXClientData client_data) {
4845 GetCursorData *Data = static_cast<GetCursorData *>(client_data);
4846 CXCursor *BestCursor = &Data->BestCursor;
4847
4848 // If we point inside a macro argument we should provide info of what the
4849 // token is so use the actual cursor, don't replace it with a macro expansion
4850 // cursor.
4851 if (cursor.kind == CXCursor_MacroExpansion && Data->PointsAtMacroArgExpansion)
4852 return CXChildVisit_Recurse;
4853
4854 if (clang_isDeclaration(cursor.kind)) {
4855 // Avoid having the implicit methods override the property decls.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004856 if (const ObjCMethodDecl *MD
Guy Benyei11169dd2012-12-18 14:30:41 +00004857 = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
4858 if (MD->isImplicit())
4859 return CXChildVisit_Break;
4860
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004861 } else if (const ObjCInterfaceDecl *ID
Guy Benyei11169dd2012-12-18 14:30:41 +00004862 = dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(cursor))) {
4863 // Check that when we have multiple @class references in the same line,
4864 // that later ones do not override the previous ones.
4865 // If we have:
4866 // @class Foo, Bar;
4867 // source ranges for both start at '@', so 'Bar' will end up overriding
4868 // 'Foo' even though the cursor location was at 'Foo'.
4869 if (BestCursor->kind == CXCursor_ObjCInterfaceDecl ||
4870 BestCursor->kind == CXCursor_ObjCClassRef)
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004871 if (const ObjCInterfaceDecl *PrevID
Guy Benyei11169dd2012-12-18 14:30:41 +00004872 = dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(*BestCursor))){
4873 if (PrevID != ID &&
4874 !PrevID->isThisDeclarationADefinition() &&
4875 !ID->isThisDeclarationADefinition())
4876 return CXChildVisit_Break;
4877 }
4878
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004879 } else if (const DeclaratorDecl *DD
Guy Benyei11169dd2012-12-18 14:30:41 +00004880 = dyn_cast_or_null<DeclaratorDecl>(getCursorDecl(cursor))) {
4881 SourceLocation StartLoc = DD->getSourceRange().getBegin();
4882 // Check that when we have multiple declarators in the same line,
4883 // that later ones do not override the previous ones.
4884 // If we have:
4885 // int Foo, Bar;
4886 // source ranges for both start at 'int', so 'Bar' will end up overriding
4887 // 'Foo' even though the cursor location was at 'Foo'.
4888 if (Data->VisitedDeclaratorDeclStartLoc == StartLoc)
4889 return CXChildVisit_Break;
4890 Data->VisitedDeclaratorDeclStartLoc = StartLoc;
4891
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004892 } else if (const ObjCPropertyImplDecl *PropImp
Guy Benyei11169dd2012-12-18 14:30:41 +00004893 = dyn_cast_or_null<ObjCPropertyImplDecl>(getCursorDecl(cursor))) {
4894 (void)PropImp;
4895 // Check that when we have multiple @synthesize in the same line,
4896 // that later ones do not override the previous ones.
4897 // If we have:
4898 // @synthesize Foo, Bar;
4899 // source ranges for both start at '@', so 'Bar' will end up overriding
4900 // 'Foo' even though the cursor location was at 'Foo'.
4901 if (Data->VisitedObjCPropertyImplDecl)
4902 return CXChildVisit_Break;
4903 Data->VisitedObjCPropertyImplDecl = true;
4904 }
4905 }
4906
4907 if (clang_isExpression(cursor.kind) &&
4908 clang_isDeclaration(BestCursor->kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004909 if (const Decl *D = getCursorDecl(*BestCursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004910 // Avoid having the cursor of an expression replace the declaration cursor
4911 // when the expression source range overlaps the declaration range.
4912 // This can happen for C++ constructor expressions whose range generally
4913 // include the variable declaration, e.g.:
4914 // MyCXXClass foo; // Make sure pointing at 'foo' returns a VarDecl cursor.
4915 if (D->getLocation().isValid() && Data->TokenBeginLoc.isValid() &&
4916 D->getLocation() == Data->TokenBeginLoc)
4917 return CXChildVisit_Break;
4918 }
4919 }
4920
4921 // If our current best cursor is the construction of a temporary object,
4922 // don't replace that cursor with a type reference, because we want
4923 // clang_getCursor() to point at the constructor.
4924 if (clang_isExpression(BestCursor->kind) &&
4925 isa<CXXTemporaryObjectExpr>(getCursorExpr(*BestCursor)) &&
4926 cursor.kind == CXCursor_TypeRef) {
4927 // Keep the cursor pointing at CXXTemporaryObjectExpr but also mark it
4928 // as having the actual point on the type reference.
4929 *BestCursor = getTypeRefedCallExprCursor(*BestCursor);
4930 return CXChildVisit_Recurse;
4931 }
Douglas Gregore9d95f12015-07-07 03:57:35 +00004932
4933 // If we already have an Objective-C superclass reference, don't
4934 // update it further.
4935 if (BestCursor->kind == CXCursor_ObjCSuperClassRef)
4936 return CXChildVisit_Break;
4937
Guy Benyei11169dd2012-12-18 14:30:41 +00004938 *BestCursor = cursor;
4939 return CXChildVisit_Recurse;
4940}
4941
4942CXCursor clang_getCursor(CXTranslationUnit TU, CXSourceLocation Loc) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00004943 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004944 LOG_BAD_TU(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004945 return clang_getNullCursor();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004946 }
Guy Benyei11169dd2012-12-18 14:30:41 +00004947
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004948 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004949 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
4950
4951 SourceLocation SLoc = cxloc::translateSourceLocation(Loc);
4952 CXCursor Result = cxcursor::getCursor(TU, SLoc);
4953
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004954 LOG_FUNC_SECTION {
Guy Benyei11169dd2012-12-18 14:30:41 +00004955 CXFile SearchFile;
4956 unsigned SearchLine, SearchColumn;
4957 CXFile ResultFile;
4958 unsigned ResultLine, ResultColumn;
4959 CXString SearchFileName, ResultFileName, KindSpelling, USR;
4960 const char *IsDef = clang_isCursorDefinition(Result)? " (Definition)" : "";
4961 CXSourceLocation ResultLoc = clang_getCursorLocation(Result);
Craig Topper69186e72014-06-08 08:38:04 +00004962
4963 clang_getFileLocation(Loc, &SearchFile, &SearchLine, &SearchColumn,
4964 nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004965 clang_getFileLocation(ResultLoc, &ResultFile, &ResultLine,
Craig Topper69186e72014-06-08 08:38:04 +00004966 &ResultColumn, nullptr);
Guy Benyei11169dd2012-12-18 14:30:41 +00004967 SearchFileName = clang_getFileName(SearchFile);
4968 ResultFileName = clang_getFileName(ResultFile);
4969 KindSpelling = clang_getCursorKindSpelling(Result.kind);
4970 USR = clang_getCursorUSR(Result);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004971 *Log << llvm::format("(%s:%d:%d) = %s",
4972 clang_getCString(SearchFileName), SearchLine, SearchColumn,
4973 clang_getCString(KindSpelling))
4974 << llvm::format("(%s:%d:%d):%s%s",
4975 clang_getCString(ResultFileName), ResultLine, ResultColumn,
4976 clang_getCString(USR), IsDef);
Guy Benyei11169dd2012-12-18 14:30:41 +00004977 clang_disposeString(SearchFileName);
4978 clang_disposeString(ResultFileName);
4979 clang_disposeString(KindSpelling);
4980 clang_disposeString(USR);
4981
4982 CXCursor Definition = clang_getCursorDefinition(Result);
4983 if (!clang_equalCursors(Definition, clang_getNullCursor())) {
4984 CXSourceLocation DefinitionLoc = clang_getCursorLocation(Definition);
4985 CXString DefinitionKindSpelling
4986 = clang_getCursorKindSpelling(Definition.kind);
4987 CXFile DefinitionFile;
4988 unsigned DefinitionLine, DefinitionColumn;
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004989 clang_getFileLocation(DefinitionLoc, &DefinitionFile,
Craig Topper69186e72014-06-08 08:38:04 +00004990 &DefinitionLine, &DefinitionColumn, nullptr);
Guy Benyei11169dd2012-12-18 14:30:41 +00004991 CXString DefinitionFileName = clang_getFileName(DefinitionFile);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004992 *Log << llvm::format(" -> %s(%s:%d:%d)",
4993 clang_getCString(DefinitionKindSpelling),
4994 clang_getCString(DefinitionFileName),
4995 DefinitionLine, DefinitionColumn);
Guy Benyei11169dd2012-12-18 14:30:41 +00004996 clang_disposeString(DefinitionFileName);
4997 clang_disposeString(DefinitionKindSpelling);
4998 }
4999 }
5000
5001 return Result;
5002}
5003
5004CXCursor clang_getNullCursor(void) {
5005 return MakeCXCursorInvalid(CXCursor_InvalidFile);
5006}
5007
5008unsigned clang_equalCursors(CXCursor X, CXCursor Y) {
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00005009 // Clear out the "FirstInDeclGroup" part in a declaration cursor, since we
5010 // can't set consistently. For example, when visiting a DeclStmt we will set
5011 // it but we don't set it on the result of clang_getCursorDefinition for
5012 // a reference of the same declaration.
5013 // FIXME: Setting "FirstInDeclGroup" in CXCursors is a hack that only works
5014 // when visiting a DeclStmt currently, the AST should be enhanced to be able
5015 // to provide that kind of info.
5016 if (clang_isDeclaration(X.kind))
Craig Topper69186e72014-06-08 08:38:04 +00005017 X.data[1] = nullptr;
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00005018 if (clang_isDeclaration(Y.kind))
Craig Topper69186e72014-06-08 08:38:04 +00005019 Y.data[1] = nullptr;
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00005020
Guy Benyei11169dd2012-12-18 14:30:41 +00005021 return X == Y;
5022}
5023
5024unsigned clang_hashCursor(CXCursor C) {
5025 unsigned Index = 0;
5026 if (clang_isExpression(C.kind) || clang_isStatement(C.kind))
5027 Index = 1;
5028
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005029 return llvm::DenseMapInfo<std::pair<unsigned, const void*> >::getHashValue(
Guy Benyei11169dd2012-12-18 14:30:41 +00005030 std::make_pair(C.kind, C.data[Index]));
5031}
5032
5033unsigned clang_isInvalid(enum CXCursorKind K) {
5034 return K >= CXCursor_FirstInvalid && K <= CXCursor_LastInvalid;
5035}
5036
5037unsigned clang_isDeclaration(enum CXCursorKind K) {
5038 return (K >= CXCursor_FirstDecl && K <= CXCursor_LastDecl) ||
5039 (K >= CXCursor_FirstExtraDecl && K <= CXCursor_LastExtraDecl);
5040}
5041
5042unsigned clang_isReference(enum CXCursorKind K) {
5043 return K >= CXCursor_FirstRef && K <= CXCursor_LastRef;
5044}
5045
5046unsigned clang_isExpression(enum CXCursorKind K) {
5047 return K >= CXCursor_FirstExpr && K <= CXCursor_LastExpr;
5048}
5049
5050unsigned clang_isStatement(enum CXCursorKind K) {
5051 return K >= CXCursor_FirstStmt && K <= CXCursor_LastStmt;
5052}
5053
5054unsigned clang_isAttribute(enum CXCursorKind K) {
5055 return K >= CXCursor_FirstAttr && K <= CXCursor_LastAttr;
5056}
5057
5058unsigned clang_isTranslationUnit(enum CXCursorKind K) {
5059 return K == CXCursor_TranslationUnit;
5060}
5061
5062unsigned clang_isPreprocessing(enum CXCursorKind K) {
5063 return K >= CXCursor_FirstPreprocessing && K <= CXCursor_LastPreprocessing;
5064}
5065
5066unsigned clang_isUnexposed(enum CXCursorKind K) {
5067 switch (K) {
5068 case CXCursor_UnexposedDecl:
5069 case CXCursor_UnexposedExpr:
5070 case CXCursor_UnexposedStmt:
5071 case CXCursor_UnexposedAttr:
5072 return true;
5073 default:
5074 return false;
5075 }
5076}
5077
5078CXCursorKind clang_getCursorKind(CXCursor C) {
5079 return C.kind;
5080}
5081
5082CXSourceLocation clang_getCursorLocation(CXCursor C) {
5083 if (clang_isReference(C.kind)) {
5084 switch (C.kind) {
5085 case CXCursor_ObjCSuperClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005086 std::pair<const ObjCInterfaceDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00005087 = getCursorObjCSuperClassRef(C);
5088 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
5089 }
5090
5091 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005092 std::pair<const ObjCProtocolDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00005093 = getCursorObjCProtocolRef(C);
5094 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
5095 }
5096
5097 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005098 std::pair<const ObjCInterfaceDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00005099 = getCursorObjCClassRef(C);
5100 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
5101 }
5102
5103 case CXCursor_TypeRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005104 std::pair<const TypeDecl *, SourceLocation> P = getCursorTypeRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005105 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
5106 }
5107
5108 case CXCursor_TemplateRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005109 std::pair<const TemplateDecl *, SourceLocation> P =
5110 getCursorTemplateRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005111 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
5112 }
5113
5114 case CXCursor_NamespaceRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005115 std::pair<const NamedDecl *, SourceLocation> P = getCursorNamespaceRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005116 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
5117 }
5118
5119 case CXCursor_MemberRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005120 std::pair<const FieldDecl *, SourceLocation> P = getCursorMemberRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005121 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
5122 }
5123
5124 case CXCursor_VariableRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005125 std::pair<const VarDecl *, SourceLocation> P = getCursorVariableRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005126 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
5127 }
5128
5129 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005130 const CXXBaseSpecifier *BaseSpec = getCursorCXXBaseSpecifier(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005131 if (!BaseSpec)
5132 return clang_getNullLocation();
5133
5134 if (TypeSourceInfo *TSInfo = BaseSpec->getTypeSourceInfo())
5135 return cxloc::translateSourceLocation(getCursorContext(C),
5136 TSInfo->getTypeLoc().getBeginLoc());
5137
5138 return cxloc::translateSourceLocation(getCursorContext(C),
5139 BaseSpec->getLocStart());
5140 }
5141
5142 case CXCursor_LabelRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005143 std::pair<const LabelStmt *, SourceLocation> P = getCursorLabelRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005144 return cxloc::translateSourceLocation(getCursorContext(C), P.second);
5145 }
5146
5147 case CXCursor_OverloadedDeclRef:
5148 return cxloc::translateSourceLocation(getCursorContext(C),
5149 getCursorOverloadedDeclRef(C).second);
5150
5151 default:
5152 // FIXME: Need a way to enumerate all non-reference cases.
5153 llvm_unreachable("Missed a reference kind");
5154 }
5155 }
5156
5157 if (clang_isExpression(C.kind))
5158 return cxloc::translateSourceLocation(getCursorContext(C),
5159 getLocationFromExpr(getCursorExpr(C)));
5160
5161 if (clang_isStatement(C.kind))
5162 return cxloc::translateSourceLocation(getCursorContext(C),
5163 getCursorStmt(C)->getLocStart());
5164
5165 if (C.kind == CXCursor_PreprocessingDirective) {
5166 SourceLocation L = cxcursor::getCursorPreprocessingDirective(C).getBegin();
5167 return cxloc::translateSourceLocation(getCursorContext(C), L);
5168 }
5169
5170 if (C.kind == CXCursor_MacroExpansion) {
5171 SourceLocation L
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00005172 = cxcursor::getCursorMacroExpansion(C).getSourceRange().getBegin();
Guy Benyei11169dd2012-12-18 14:30:41 +00005173 return cxloc::translateSourceLocation(getCursorContext(C), L);
5174 }
5175
5176 if (C.kind == CXCursor_MacroDefinition) {
5177 SourceLocation L = cxcursor::getCursorMacroDefinition(C)->getLocation();
5178 return cxloc::translateSourceLocation(getCursorContext(C), L);
5179 }
5180
5181 if (C.kind == CXCursor_InclusionDirective) {
5182 SourceLocation L
5183 = cxcursor::getCursorInclusionDirective(C)->getSourceRange().getBegin();
5184 return cxloc::translateSourceLocation(getCursorContext(C), L);
5185 }
5186
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00005187 if (clang_isAttribute(C.kind)) {
5188 SourceLocation L
5189 = cxcursor::getCursorAttr(C)->getLocation();
5190 return cxloc::translateSourceLocation(getCursorContext(C), L);
5191 }
5192
Guy Benyei11169dd2012-12-18 14:30:41 +00005193 if (!clang_isDeclaration(C.kind))
5194 return clang_getNullLocation();
5195
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005196 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005197 if (!D)
5198 return clang_getNullLocation();
5199
5200 SourceLocation Loc = D->getLocation();
5201 // FIXME: Multiple variables declared in a single declaration
5202 // currently lack the information needed to correctly determine their
5203 // ranges when accounting for the type-specifier. We use context
5204 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
5205 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005206 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005207 if (!cxcursor::isFirstInDeclGroup(C))
5208 Loc = VD->getLocation();
5209 }
5210
5211 // For ObjC methods, give the start location of the method name.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005212 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00005213 Loc = MD->getSelectorStartLoc();
5214
5215 return cxloc::translateSourceLocation(getCursorContext(C), Loc);
5216}
5217
5218} // end extern "C"
5219
5220CXCursor cxcursor::getCursor(CXTranslationUnit TU, SourceLocation SLoc) {
5221 assert(TU);
5222
5223 // Guard against an invalid SourceLocation, or we may assert in one
5224 // of the following calls.
5225 if (SLoc.isInvalid())
5226 return clang_getNullCursor();
5227
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005228 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005229
5230 // Translate the given source location to make it point at the beginning of
5231 // the token under the cursor.
5232 SLoc = Lexer::GetBeginningOfToken(SLoc, CXXUnit->getSourceManager(),
5233 CXXUnit->getASTContext().getLangOpts());
5234
5235 CXCursor Result = MakeCXCursorInvalid(CXCursor_NoDeclFound);
5236 if (SLoc.isValid()) {
5237 GetCursorData ResultData(CXXUnit->getSourceManager(), SLoc, Result);
5238 CursorVisitor CursorVis(TU, GetCursorVisitor, &ResultData,
5239 /*VisitPreprocessorLast=*/true,
5240 /*VisitIncludedEntities=*/false,
5241 SourceLocation(SLoc));
5242 CursorVis.visitFileRegion();
5243 }
5244
5245 return Result;
5246}
5247
5248static SourceRange getRawCursorExtent(CXCursor C) {
5249 if (clang_isReference(C.kind)) {
5250 switch (C.kind) {
5251 case CXCursor_ObjCSuperClassRef:
5252 return getCursorObjCSuperClassRef(C).second;
5253
5254 case CXCursor_ObjCProtocolRef:
5255 return getCursorObjCProtocolRef(C).second;
5256
5257 case CXCursor_ObjCClassRef:
5258 return getCursorObjCClassRef(C).second;
5259
5260 case CXCursor_TypeRef:
5261 return getCursorTypeRef(C).second;
5262
5263 case CXCursor_TemplateRef:
5264 return getCursorTemplateRef(C).second;
5265
5266 case CXCursor_NamespaceRef:
5267 return getCursorNamespaceRef(C).second;
5268
5269 case CXCursor_MemberRef:
5270 return getCursorMemberRef(C).second;
5271
5272 case CXCursor_CXXBaseSpecifier:
5273 return getCursorCXXBaseSpecifier(C)->getSourceRange();
5274
5275 case CXCursor_LabelRef:
5276 return getCursorLabelRef(C).second;
5277
5278 case CXCursor_OverloadedDeclRef:
5279 return getCursorOverloadedDeclRef(C).second;
5280
5281 case CXCursor_VariableRef:
5282 return getCursorVariableRef(C).second;
5283
5284 default:
5285 // FIXME: Need a way to enumerate all non-reference cases.
5286 llvm_unreachable("Missed a reference kind");
5287 }
5288 }
5289
5290 if (clang_isExpression(C.kind))
5291 return getCursorExpr(C)->getSourceRange();
5292
5293 if (clang_isStatement(C.kind))
5294 return getCursorStmt(C)->getSourceRange();
5295
5296 if (clang_isAttribute(C.kind))
5297 return getCursorAttr(C)->getRange();
5298
5299 if (C.kind == CXCursor_PreprocessingDirective)
5300 return cxcursor::getCursorPreprocessingDirective(C);
5301
5302 if (C.kind == CXCursor_MacroExpansion) {
5303 ASTUnit *TU = getCursorASTUnit(C);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00005304 SourceRange Range = cxcursor::getCursorMacroExpansion(C).getSourceRange();
Guy Benyei11169dd2012-12-18 14:30:41 +00005305 return TU->mapRangeFromPreamble(Range);
5306 }
5307
5308 if (C.kind == CXCursor_MacroDefinition) {
5309 ASTUnit *TU = getCursorASTUnit(C);
5310 SourceRange Range = cxcursor::getCursorMacroDefinition(C)->getSourceRange();
5311 return TU->mapRangeFromPreamble(Range);
5312 }
5313
5314 if (C.kind == CXCursor_InclusionDirective) {
5315 ASTUnit *TU = getCursorASTUnit(C);
5316 SourceRange Range = cxcursor::getCursorInclusionDirective(C)->getSourceRange();
5317 return TU->mapRangeFromPreamble(Range);
5318 }
5319
5320 if (C.kind == CXCursor_TranslationUnit) {
5321 ASTUnit *TU = getCursorASTUnit(C);
5322 FileID MainID = TU->getSourceManager().getMainFileID();
5323 SourceLocation Start = TU->getSourceManager().getLocForStartOfFile(MainID);
5324 SourceLocation End = TU->getSourceManager().getLocForEndOfFile(MainID);
5325 return SourceRange(Start, End);
5326 }
5327
5328 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005329 const Decl *D = cxcursor::getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005330 if (!D)
5331 return SourceRange();
5332
5333 SourceRange R = D->getSourceRange();
5334 // FIXME: Multiple variables declared in a single declaration
5335 // currently lack the information needed to correctly determine their
5336 // ranges when accounting for the type-specifier. We use context
5337 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
5338 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005339 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005340 if (!cxcursor::isFirstInDeclGroup(C))
5341 R.setBegin(VD->getLocation());
5342 }
5343 return R;
5344 }
5345 return SourceRange();
5346}
5347
5348/// \brief Retrieves the "raw" cursor extent, which is then extended to include
5349/// the decl-specifier-seq for declarations.
5350static SourceRange getFullCursorExtent(CXCursor C, SourceManager &SrcMgr) {
5351 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005352 const Decl *D = cxcursor::getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005353 if (!D)
5354 return SourceRange();
5355
5356 SourceRange R = D->getSourceRange();
5357
5358 // Adjust the start of the location for declarations preceded by
5359 // declaration specifiers.
5360 SourceLocation StartLoc;
5361 if (const DeclaratorDecl *DD = dyn_cast<DeclaratorDecl>(D)) {
5362 if (TypeSourceInfo *TI = DD->getTypeSourceInfo())
5363 StartLoc = TI->getTypeLoc().getLocStart();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005364 } else if (const TypedefDecl *Typedef = dyn_cast<TypedefDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005365 if (TypeSourceInfo *TI = Typedef->getTypeSourceInfo())
5366 StartLoc = TI->getTypeLoc().getLocStart();
5367 }
5368
5369 if (StartLoc.isValid() && R.getBegin().isValid() &&
5370 SrcMgr.isBeforeInTranslationUnit(StartLoc, R.getBegin()))
5371 R.setBegin(StartLoc);
5372
5373 // FIXME: Multiple variables declared in a single declaration
5374 // currently lack the information needed to correctly determine their
5375 // ranges when accounting for the type-specifier. We use context
5376 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
5377 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005378 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005379 if (!cxcursor::isFirstInDeclGroup(C))
5380 R.setBegin(VD->getLocation());
5381 }
5382
5383 return R;
5384 }
5385
5386 return getRawCursorExtent(C);
5387}
5388
5389extern "C" {
5390
5391CXSourceRange clang_getCursorExtent(CXCursor C) {
5392 SourceRange R = getRawCursorExtent(C);
5393 if (R.isInvalid())
5394 return clang_getNullRange();
5395
5396 return cxloc::translateSourceRange(getCursorContext(C), R);
5397}
5398
5399CXCursor clang_getCursorReferenced(CXCursor C) {
5400 if (clang_isInvalid(C.kind))
5401 return clang_getNullCursor();
5402
5403 CXTranslationUnit tu = getCursorTU(C);
5404 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005405 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005406 if (!D)
5407 return clang_getNullCursor();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005408 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00005409 return MakeCursorOverloadedDeclRef(Using, D->getLocation(), tu);
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005410 if (const ObjCPropertyImplDecl *PropImpl =
5411 dyn_cast<ObjCPropertyImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00005412 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
5413 return MakeCXCursor(Property, tu);
5414
5415 return C;
5416 }
5417
5418 if (clang_isExpression(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005419 const Expr *E = getCursorExpr(C);
5420 const Decl *D = getDeclFromExpr(E);
Guy Benyei11169dd2012-12-18 14:30:41 +00005421 if (D) {
5422 CXCursor declCursor = MakeCXCursor(D, tu);
5423 declCursor = getSelectorIdentifierCursor(getSelectorIdentifierIndex(C),
5424 declCursor);
5425 return declCursor;
5426 }
5427
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005428 if (const OverloadExpr *Ovl = dyn_cast_or_null<OverloadExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00005429 return MakeCursorOverloadedDeclRef(Ovl, tu);
5430
5431 return clang_getNullCursor();
5432 }
5433
5434 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005435 const Stmt *S = getCursorStmt(C);
5436 if (const GotoStmt *Goto = dyn_cast_or_null<GotoStmt>(S))
Guy Benyei11169dd2012-12-18 14:30:41 +00005437 if (LabelDecl *label = Goto->getLabel())
5438 if (LabelStmt *labelS = label->getStmt())
5439 return MakeCXCursor(labelS, getCursorDecl(C), tu);
5440
5441 return clang_getNullCursor();
5442 }
Richard Smith66a81862015-05-04 02:25:31 +00005443
Guy Benyei11169dd2012-12-18 14:30:41 +00005444 if (C.kind == CXCursor_MacroExpansion) {
Richard Smith66a81862015-05-04 02:25:31 +00005445 if (const MacroDefinitionRecord *Def =
5446 getCursorMacroExpansion(C).getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005447 return MakeMacroDefinitionCursor(Def, tu);
5448 }
5449
5450 if (!clang_isReference(C.kind))
5451 return clang_getNullCursor();
5452
5453 switch (C.kind) {
5454 case CXCursor_ObjCSuperClassRef:
5455 return MakeCXCursor(getCursorObjCSuperClassRef(C).first, tu);
5456
5457 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005458 const ObjCProtocolDecl *Prot = getCursorObjCProtocolRef(C).first;
5459 if (const ObjCProtocolDecl *Def = Prot->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005460 return MakeCXCursor(Def, tu);
5461
5462 return MakeCXCursor(Prot, tu);
5463 }
5464
5465 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005466 const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
5467 if (const ObjCInterfaceDecl *Def = Class->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005468 return MakeCXCursor(Def, tu);
5469
5470 return MakeCXCursor(Class, tu);
5471 }
5472
5473 case CXCursor_TypeRef:
5474 return MakeCXCursor(getCursorTypeRef(C).first, tu );
5475
5476 case CXCursor_TemplateRef:
5477 return MakeCXCursor(getCursorTemplateRef(C).first, tu );
5478
5479 case CXCursor_NamespaceRef:
5480 return MakeCXCursor(getCursorNamespaceRef(C).first, tu );
5481
5482 case CXCursor_MemberRef:
5483 return MakeCXCursor(getCursorMemberRef(C).first, tu );
5484
5485 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005486 const CXXBaseSpecifier *B = cxcursor::getCursorCXXBaseSpecifier(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005487 return clang_getTypeDeclaration(cxtype::MakeCXType(B->getType(),
5488 tu ));
5489 }
5490
5491 case CXCursor_LabelRef:
5492 // FIXME: We end up faking the "parent" declaration here because we
5493 // don't want to make CXCursor larger.
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005494 return MakeCXCursor(getCursorLabelRef(C).first,
5495 cxtu::getASTUnit(tu)->getASTContext()
5496 .getTranslationUnitDecl(),
Guy Benyei11169dd2012-12-18 14:30:41 +00005497 tu);
5498
5499 case CXCursor_OverloadedDeclRef:
5500 return C;
5501
5502 case CXCursor_VariableRef:
5503 return MakeCXCursor(getCursorVariableRef(C).first, tu);
5504
5505 default:
5506 // We would prefer to enumerate all non-reference cursor kinds here.
5507 llvm_unreachable("Unhandled reference cursor kind");
5508 }
5509}
5510
5511CXCursor clang_getCursorDefinition(CXCursor C) {
5512 if (clang_isInvalid(C.kind))
5513 return clang_getNullCursor();
5514
5515 CXTranslationUnit TU = getCursorTU(C);
5516
5517 bool WasReference = false;
5518 if (clang_isReference(C.kind) || clang_isExpression(C.kind)) {
5519 C = clang_getCursorReferenced(C);
5520 WasReference = true;
5521 }
5522
5523 if (C.kind == CXCursor_MacroExpansion)
5524 return clang_getCursorReferenced(C);
5525
5526 if (!clang_isDeclaration(C.kind))
5527 return clang_getNullCursor();
5528
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005529 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005530 if (!D)
5531 return clang_getNullCursor();
5532
5533 switch (D->getKind()) {
5534 // Declaration kinds that don't really separate the notions of
5535 // declaration and definition.
5536 case Decl::Namespace:
5537 case Decl::Typedef:
5538 case Decl::TypeAlias:
5539 case Decl::TypeAliasTemplate:
5540 case Decl::TemplateTypeParm:
5541 case Decl::EnumConstant:
5542 case Decl::Field:
John McCall5e77d762013-04-16 07:28:30 +00005543 case Decl::MSProperty:
Guy Benyei11169dd2012-12-18 14:30:41 +00005544 case Decl::IndirectField:
5545 case Decl::ObjCIvar:
5546 case Decl::ObjCAtDefsField:
5547 case Decl::ImplicitParam:
5548 case Decl::ParmVar:
5549 case Decl::NonTypeTemplateParm:
5550 case Decl::TemplateTemplateParm:
5551 case Decl::ObjCCategoryImpl:
5552 case Decl::ObjCImplementation:
5553 case Decl::AccessSpec:
5554 case Decl::LinkageSpec:
5555 case Decl::ObjCPropertyImpl:
5556 case Decl::FileScopeAsm:
5557 case Decl::StaticAssert:
5558 case Decl::Block:
Tareq A. Siraj6dfa25a2013-04-16 19:37:38 +00005559 case Decl::Captured:
Alexey Bataev4244be22016-02-11 05:35:55 +00005560 case Decl::OMPCapturedExpr:
Guy Benyei11169dd2012-12-18 14:30:41 +00005561 case Decl::Label: // FIXME: Is this right??
5562 case Decl::ClassScopeFunctionSpecialization:
5563 case Decl::Import:
Alexey Bataeva769e072013-03-22 06:34:35 +00005564 case Decl::OMPThreadPrivate:
Alexey Bataev94a4f0c2016-03-03 05:21:39 +00005565 case Decl::OMPDeclareReduction:
Douglas Gregor85f3f952015-07-07 03:57:15 +00005566 case Decl::ObjCTypeParam:
David Majnemerd9b1a4f2015-11-04 03:40:30 +00005567 case Decl::BuiltinTemplate:
Nico Weber66220292016-03-02 17:28:48 +00005568 case Decl::PragmaComment:
Nico Webercbbaeb12016-03-02 19:28:54 +00005569 case Decl::PragmaDetectMismatch:
Guy Benyei11169dd2012-12-18 14:30:41 +00005570 return C;
5571
5572 // Declaration kinds that don't make any sense here, but are
5573 // nonetheless harmless.
David Blaikief005d3c2013-02-22 17:44:58 +00005574 case Decl::Empty:
Guy Benyei11169dd2012-12-18 14:30:41 +00005575 case Decl::TranslationUnit:
Richard Smithf19e1272015-03-07 00:04:49 +00005576 case Decl::ExternCContext:
Guy Benyei11169dd2012-12-18 14:30:41 +00005577 break;
5578
5579 // Declaration kinds for which the definition is not resolvable.
5580 case Decl::UnresolvedUsingTypename:
5581 case Decl::UnresolvedUsingValue:
5582 break;
5583
5584 case Decl::UsingDirective:
5585 return MakeCXCursor(cast<UsingDirectiveDecl>(D)->getNominatedNamespace(),
5586 TU);
5587
5588 case Decl::NamespaceAlias:
5589 return MakeCXCursor(cast<NamespaceAliasDecl>(D)->getNamespace(), TU);
5590
5591 case Decl::Enum:
5592 case Decl::Record:
5593 case Decl::CXXRecord:
5594 case Decl::ClassTemplateSpecialization:
5595 case Decl::ClassTemplatePartialSpecialization:
5596 if (TagDecl *Def = cast<TagDecl>(D)->getDefinition())
5597 return MakeCXCursor(Def, TU);
5598 return clang_getNullCursor();
5599
5600 case Decl::Function:
5601 case Decl::CXXMethod:
5602 case Decl::CXXConstructor:
5603 case Decl::CXXDestructor:
5604 case Decl::CXXConversion: {
Craig Topper69186e72014-06-08 08:38:04 +00005605 const FunctionDecl *Def = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005606 if (cast<FunctionDecl>(D)->getBody(Def))
Dmitri Gribenko9c256e32013-01-14 00:46:27 +00005607 return MakeCXCursor(Def, TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005608 return clang_getNullCursor();
5609 }
5610
Larisse Voufo39a1e502013-08-06 01:03:05 +00005611 case Decl::Var:
5612 case Decl::VarTemplateSpecialization:
5613 case Decl::VarTemplatePartialSpecialization: {
Guy Benyei11169dd2012-12-18 14:30:41 +00005614 // Ask the variable if it has a definition.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005615 if (const VarDecl *Def = cast<VarDecl>(D)->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005616 return MakeCXCursor(Def, TU);
5617 return clang_getNullCursor();
5618 }
5619
5620 case Decl::FunctionTemplate: {
Craig Topper69186e72014-06-08 08:38:04 +00005621 const FunctionDecl *Def = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005622 if (cast<FunctionTemplateDecl>(D)->getTemplatedDecl()->getBody(Def))
5623 return MakeCXCursor(Def->getDescribedFunctionTemplate(), TU);
5624 return clang_getNullCursor();
5625 }
5626
5627 case Decl::ClassTemplate: {
5628 if (RecordDecl *Def = cast<ClassTemplateDecl>(D)->getTemplatedDecl()
5629 ->getDefinition())
5630 return MakeCXCursor(cast<CXXRecordDecl>(Def)->getDescribedClassTemplate(),
5631 TU);
5632 return clang_getNullCursor();
5633 }
5634
Larisse Voufo39a1e502013-08-06 01:03:05 +00005635 case Decl::VarTemplate: {
5636 if (VarDecl *Def =
5637 cast<VarTemplateDecl>(D)->getTemplatedDecl()->getDefinition())
5638 return MakeCXCursor(cast<VarDecl>(Def)->getDescribedVarTemplate(), TU);
5639 return clang_getNullCursor();
5640 }
5641
Guy Benyei11169dd2012-12-18 14:30:41 +00005642 case Decl::Using:
5643 return MakeCursorOverloadedDeclRef(cast<UsingDecl>(D),
5644 D->getLocation(), TU);
5645
5646 case Decl::UsingShadow:
5647 return clang_getCursorDefinition(
5648 MakeCXCursor(cast<UsingShadowDecl>(D)->getTargetDecl(),
5649 TU));
5650
5651 case Decl::ObjCMethod: {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005652 const ObjCMethodDecl *Method = cast<ObjCMethodDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00005653 if (Method->isThisDeclarationADefinition())
5654 return C;
5655
5656 // Dig out the method definition in the associated
5657 // @implementation, if we have it.
5658 // FIXME: The ASTs should make finding the definition easier.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005659 if (const ObjCInterfaceDecl *Class
Guy Benyei11169dd2012-12-18 14:30:41 +00005660 = dyn_cast<ObjCInterfaceDecl>(Method->getDeclContext()))
5661 if (ObjCImplementationDecl *ClassImpl = Class->getImplementation())
5662 if (ObjCMethodDecl *Def = ClassImpl->getMethod(Method->getSelector(),
5663 Method->isInstanceMethod()))
5664 if (Def->isThisDeclarationADefinition())
5665 return MakeCXCursor(Def, TU);
5666
5667 return clang_getNullCursor();
5668 }
5669
5670 case Decl::ObjCCategory:
5671 if (ObjCCategoryImplDecl *Impl
5672 = cast<ObjCCategoryDecl>(D)->getImplementation())
5673 return MakeCXCursor(Impl, TU);
5674 return clang_getNullCursor();
5675
5676 case Decl::ObjCProtocol:
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005677 if (const ObjCProtocolDecl *Def = cast<ObjCProtocolDecl>(D)->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005678 return MakeCXCursor(Def, TU);
5679 return clang_getNullCursor();
5680
5681 case Decl::ObjCInterface: {
5682 // There are two notions of a "definition" for an Objective-C
5683 // class: the interface and its implementation. When we resolved a
5684 // reference to an Objective-C class, produce the @interface as
5685 // the definition; when we were provided with the interface,
5686 // produce the @implementation as the definition.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005687 const ObjCInterfaceDecl *IFace = cast<ObjCInterfaceDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00005688 if (WasReference) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005689 if (const ObjCInterfaceDecl *Def = IFace->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005690 return MakeCXCursor(Def, TU);
5691 } else if (ObjCImplementationDecl *Impl = IFace->getImplementation())
5692 return MakeCXCursor(Impl, TU);
5693 return clang_getNullCursor();
5694 }
5695
5696 case Decl::ObjCProperty:
5697 // FIXME: We don't really know where to find the
5698 // ObjCPropertyImplDecls that implement this property.
5699 return clang_getNullCursor();
5700
5701 case Decl::ObjCCompatibleAlias:
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005702 if (const ObjCInterfaceDecl *Class
Guy Benyei11169dd2012-12-18 14:30:41 +00005703 = cast<ObjCCompatibleAliasDecl>(D)->getClassInterface())
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005704 if (const ObjCInterfaceDecl *Def = Class->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005705 return MakeCXCursor(Def, TU);
5706
5707 return clang_getNullCursor();
5708
5709 case Decl::Friend:
5710 if (NamedDecl *Friend = cast<FriendDecl>(D)->getFriendDecl())
5711 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
5712 return clang_getNullCursor();
5713
5714 case Decl::FriendTemplate:
5715 if (NamedDecl *Friend = cast<FriendTemplateDecl>(D)->getFriendDecl())
5716 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
5717 return clang_getNullCursor();
5718 }
5719
5720 return clang_getNullCursor();
5721}
5722
5723unsigned clang_isCursorDefinition(CXCursor C) {
5724 if (!clang_isDeclaration(C.kind))
5725 return 0;
5726
5727 return clang_getCursorDefinition(C) == C;
5728}
5729
5730CXCursor clang_getCanonicalCursor(CXCursor C) {
5731 if (!clang_isDeclaration(C.kind))
5732 return C;
5733
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005734 if (const Decl *D = getCursorDecl(C)) {
5735 if (const ObjCCategoryImplDecl *CatImplD = dyn_cast<ObjCCategoryImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00005736 if (ObjCCategoryDecl *CatD = CatImplD->getCategoryDecl())
5737 return MakeCXCursor(CatD, getCursorTU(C));
5738
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005739 if (const ObjCImplDecl *ImplD = dyn_cast<ObjCImplDecl>(D))
5740 if (const ObjCInterfaceDecl *IFD = ImplD->getClassInterface())
Guy Benyei11169dd2012-12-18 14:30:41 +00005741 return MakeCXCursor(IFD, getCursorTU(C));
5742
5743 return MakeCXCursor(D->getCanonicalDecl(), getCursorTU(C));
5744 }
5745
5746 return C;
5747}
5748
5749int clang_Cursor_getObjCSelectorIndex(CXCursor cursor) {
5750 return cxcursor::getSelectorIdentifierIndexAndLoc(cursor).first;
5751}
5752
5753unsigned clang_getNumOverloadedDecls(CXCursor C) {
5754 if (C.kind != CXCursor_OverloadedDeclRef)
5755 return 0;
5756
5757 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005758 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Guy Benyei11169dd2012-12-18 14:30:41 +00005759 return E->getNumDecls();
5760
5761 if (OverloadedTemplateStorage *S
5762 = Storage.dyn_cast<OverloadedTemplateStorage*>())
5763 return S->size();
5764
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005765 const Decl *D = Storage.get<const Decl *>();
5766 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00005767 return Using->shadow_size();
5768
5769 return 0;
5770}
5771
5772CXCursor clang_getOverloadedDecl(CXCursor cursor, unsigned index) {
5773 if (cursor.kind != CXCursor_OverloadedDeclRef)
5774 return clang_getNullCursor();
5775
5776 if (index >= clang_getNumOverloadedDecls(cursor))
5777 return clang_getNullCursor();
5778
5779 CXTranslationUnit TU = getCursorTU(cursor);
5780 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(cursor).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005781 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Guy Benyei11169dd2012-12-18 14:30:41 +00005782 return MakeCXCursor(E->decls_begin()[index], TU);
5783
5784 if (OverloadedTemplateStorage *S
5785 = Storage.dyn_cast<OverloadedTemplateStorage*>())
5786 return MakeCXCursor(S->begin()[index], TU);
5787
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005788 const Decl *D = Storage.get<const Decl *>();
5789 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005790 // FIXME: This is, unfortunately, linear time.
5791 UsingDecl::shadow_iterator Pos = Using->shadow_begin();
5792 std::advance(Pos, index);
5793 return MakeCXCursor(cast<UsingShadowDecl>(*Pos)->getTargetDecl(), TU);
5794 }
5795
5796 return clang_getNullCursor();
5797}
5798
5799void clang_getDefinitionSpellingAndExtent(CXCursor C,
5800 const char **startBuf,
5801 const char **endBuf,
5802 unsigned *startLine,
5803 unsigned *startColumn,
5804 unsigned *endLine,
5805 unsigned *endColumn) {
5806 assert(getCursorDecl(C) && "CXCursor has null decl");
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005807 const FunctionDecl *FD = dyn_cast<FunctionDecl>(getCursorDecl(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00005808 CompoundStmt *Body = dyn_cast<CompoundStmt>(FD->getBody());
5809
5810 SourceManager &SM = FD->getASTContext().getSourceManager();
5811 *startBuf = SM.getCharacterData(Body->getLBracLoc());
5812 *endBuf = SM.getCharacterData(Body->getRBracLoc());
5813 *startLine = SM.getSpellingLineNumber(Body->getLBracLoc());
5814 *startColumn = SM.getSpellingColumnNumber(Body->getLBracLoc());
5815 *endLine = SM.getSpellingLineNumber(Body->getRBracLoc());
5816 *endColumn = SM.getSpellingColumnNumber(Body->getRBracLoc());
5817}
5818
5819
5820CXSourceRange clang_getCursorReferenceNameRange(CXCursor C, unsigned NameFlags,
5821 unsigned PieceIndex) {
5822 RefNamePieces Pieces;
5823
5824 switch (C.kind) {
5825 case CXCursor_MemberRefExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005826 if (const MemberExpr *E = dyn_cast<MemberExpr>(getCursorExpr(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00005827 Pieces = buildPieces(NameFlags, true, E->getMemberNameInfo(),
5828 E->getQualifierLoc().getSourceRange());
5829 break;
5830
5831 case CXCursor_DeclRefExpr:
James Y Knight04ec5bf2015-12-24 02:59:37 +00005832 if (const DeclRefExpr *E = dyn_cast<DeclRefExpr>(getCursorExpr(C))) {
5833 SourceRange TemplateArgLoc(E->getLAngleLoc(), E->getRAngleLoc());
5834 Pieces =
5835 buildPieces(NameFlags, false, E->getNameInfo(),
5836 E->getQualifierLoc().getSourceRange(), &TemplateArgLoc);
5837 }
Guy Benyei11169dd2012-12-18 14:30:41 +00005838 break;
5839
5840 case CXCursor_CallExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005841 if (const CXXOperatorCallExpr *OCE =
Guy Benyei11169dd2012-12-18 14:30:41 +00005842 dyn_cast<CXXOperatorCallExpr>(getCursorExpr(C))) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005843 const Expr *Callee = OCE->getCallee();
5844 if (const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Callee))
Guy Benyei11169dd2012-12-18 14:30:41 +00005845 Callee = ICE->getSubExpr();
5846
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005847 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(Callee))
Guy Benyei11169dd2012-12-18 14:30:41 +00005848 Pieces = buildPieces(NameFlags, false, DRE->getNameInfo(),
5849 DRE->getQualifierLoc().getSourceRange());
5850 }
5851 break;
5852
5853 default:
5854 break;
5855 }
5856
5857 if (Pieces.empty()) {
5858 if (PieceIndex == 0)
5859 return clang_getCursorExtent(C);
5860 } else if (PieceIndex < Pieces.size()) {
5861 SourceRange R = Pieces[PieceIndex];
5862 if (R.isValid())
5863 return cxloc::translateSourceRange(getCursorContext(C), R);
5864 }
5865
5866 return clang_getNullRange();
5867}
5868
5869void clang_enableStackTraces(void) {
5870 llvm::sys::PrintStackTraceOnErrorSignal();
5871}
5872
5873void clang_executeOnThread(void (*fn)(void*), void *user_data,
5874 unsigned stack_size) {
5875 llvm::llvm_execute_on_thread(fn, user_data, stack_size);
5876}
5877
5878} // end: extern "C"
5879
5880//===----------------------------------------------------------------------===//
5881// Token-based Operations.
5882//===----------------------------------------------------------------------===//
5883
5884/* CXToken layout:
5885 * int_data[0]: a CXTokenKind
5886 * int_data[1]: starting token location
5887 * int_data[2]: token length
5888 * int_data[3]: reserved
5889 * ptr_data: for identifiers and keywords, an IdentifierInfo*.
5890 * otherwise unused.
5891 */
5892extern "C" {
5893
5894CXTokenKind clang_getTokenKind(CXToken CXTok) {
5895 return static_cast<CXTokenKind>(CXTok.int_data[0]);
5896}
5897
5898CXString clang_getTokenSpelling(CXTranslationUnit TU, CXToken CXTok) {
5899 switch (clang_getTokenKind(CXTok)) {
5900 case CXToken_Identifier:
5901 case CXToken_Keyword:
5902 // We know we have an IdentifierInfo*, so use that.
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005903 return cxstring::createRef(static_cast<IdentifierInfo *>(CXTok.ptr_data)
Guy Benyei11169dd2012-12-18 14:30:41 +00005904 ->getNameStart());
5905
5906 case CXToken_Literal: {
5907 // We have stashed the starting pointer in the ptr_data field. Use it.
5908 const char *Text = static_cast<const char *>(CXTok.ptr_data);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00005909 return cxstring::createDup(StringRef(Text, CXTok.int_data[2]));
Guy Benyei11169dd2012-12-18 14:30:41 +00005910 }
5911
5912 case CXToken_Punctuation:
5913 case CXToken_Comment:
5914 break;
5915 }
5916
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005917 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005918 LOG_BAD_TU(TU);
5919 return cxstring::createEmpty();
5920 }
5921
Guy Benyei11169dd2012-12-18 14:30:41 +00005922 // We have to find the starting buffer pointer the hard way, by
5923 // deconstructing the source location.
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005924 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005925 if (!CXXUnit)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00005926 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00005927
5928 SourceLocation Loc = SourceLocation::getFromRawEncoding(CXTok.int_data[1]);
5929 std::pair<FileID, unsigned> LocInfo
5930 = CXXUnit->getSourceManager().getDecomposedSpellingLoc(Loc);
5931 bool Invalid = false;
5932 StringRef Buffer
5933 = CXXUnit->getSourceManager().getBufferData(LocInfo.first, &Invalid);
5934 if (Invalid)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00005935 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00005936
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00005937 return cxstring::createDup(Buffer.substr(LocInfo.second, CXTok.int_data[2]));
Guy Benyei11169dd2012-12-18 14:30:41 +00005938}
5939
5940CXSourceLocation clang_getTokenLocation(CXTranslationUnit TU, CXToken CXTok) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005941 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005942 LOG_BAD_TU(TU);
5943 return clang_getNullLocation();
5944 }
5945
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005946 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005947 if (!CXXUnit)
5948 return clang_getNullLocation();
5949
5950 return cxloc::translateSourceLocation(CXXUnit->getASTContext(),
5951 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
5952}
5953
5954CXSourceRange clang_getTokenExtent(CXTranslationUnit TU, CXToken CXTok) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005955 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005956 LOG_BAD_TU(TU);
5957 return clang_getNullRange();
5958 }
5959
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005960 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005961 if (!CXXUnit)
5962 return clang_getNullRange();
5963
5964 return cxloc::translateSourceRange(CXXUnit->getASTContext(),
5965 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
5966}
5967
5968static void getTokens(ASTUnit *CXXUnit, SourceRange Range,
5969 SmallVectorImpl<CXToken> &CXTokens) {
5970 SourceManager &SourceMgr = CXXUnit->getSourceManager();
5971 std::pair<FileID, unsigned> BeginLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005972 = SourceMgr.getDecomposedSpellingLoc(Range.getBegin());
Guy Benyei11169dd2012-12-18 14:30:41 +00005973 std::pair<FileID, unsigned> EndLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005974 = SourceMgr.getDecomposedSpellingLoc(Range.getEnd());
Guy Benyei11169dd2012-12-18 14:30:41 +00005975
5976 // Cannot tokenize across files.
5977 if (BeginLocInfo.first != EndLocInfo.first)
5978 return;
5979
5980 // Create a lexer
5981 bool Invalid = false;
5982 StringRef Buffer
5983 = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
5984 if (Invalid)
5985 return;
5986
5987 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
5988 CXXUnit->getASTContext().getLangOpts(),
5989 Buffer.begin(), Buffer.data() + BeginLocInfo.second, Buffer.end());
5990 Lex.SetCommentRetentionState(true);
5991
5992 // Lex tokens until we hit the end of the range.
5993 const char *EffectiveBufferEnd = Buffer.data() + EndLocInfo.second;
5994 Token Tok;
5995 bool previousWasAt = false;
5996 do {
5997 // Lex the next token
5998 Lex.LexFromRawLexer(Tok);
5999 if (Tok.is(tok::eof))
6000 break;
6001
6002 // Initialize the CXToken.
6003 CXToken CXTok;
6004
6005 // - Common fields
6006 CXTok.int_data[1] = Tok.getLocation().getRawEncoding();
6007 CXTok.int_data[2] = Tok.getLength();
6008 CXTok.int_data[3] = 0;
6009
6010 // - Kind-specific fields
6011 if (Tok.isLiteral()) {
6012 CXTok.int_data[0] = CXToken_Literal;
Dmitri Gribenkof9304482013-01-23 15:56:07 +00006013 CXTok.ptr_data = const_cast<char *>(Tok.getLiteralData());
Guy Benyei11169dd2012-12-18 14:30:41 +00006014 } else if (Tok.is(tok::raw_identifier)) {
6015 // Lookup the identifier to determine whether we have a keyword.
6016 IdentifierInfo *II
6017 = CXXUnit->getPreprocessor().LookUpIdentifierInfo(Tok);
6018
6019 if ((II->getObjCKeywordID() != tok::objc_not_keyword) && previousWasAt) {
6020 CXTok.int_data[0] = CXToken_Keyword;
6021 }
6022 else {
6023 CXTok.int_data[0] = Tok.is(tok::identifier)
6024 ? CXToken_Identifier
6025 : CXToken_Keyword;
6026 }
6027 CXTok.ptr_data = II;
6028 } else if (Tok.is(tok::comment)) {
6029 CXTok.int_data[0] = CXToken_Comment;
Craig Topper69186e72014-06-08 08:38:04 +00006030 CXTok.ptr_data = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006031 } else {
6032 CXTok.int_data[0] = CXToken_Punctuation;
Craig Topper69186e72014-06-08 08:38:04 +00006033 CXTok.ptr_data = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006034 }
6035 CXTokens.push_back(CXTok);
6036 previousWasAt = Tok.is(tok::at);
6037 } while (Lex.getBufferLocation() <= EffectiveBufferEnd);
6038}
6039
6040void clang_tokenize(CXTranslationUnit TU, CXSourceRange Range,
6041 CXToken **Tokens, unsigned *NumTokens) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006042 LOG_FUNC_SECTION {
6043 *Log << TU << ' ' << Range;
6044 }
6045
Guy Benyei11169dd2012-12-18 14:30:41 +00006046 if (Tokens)
Craig Topper69186e72014-06-08 08:38:04 +00006047 *Tokens = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006048 if (NumTokens)
6049 *NumTokens = 0;
6050
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006051 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006052 LOG_BAD_TU(TU);
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00006053 return;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006054 }
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00006055
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006056 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00006057 if (!CXXUnit || !Tokens || !NumTokens)
6058 return;
6059
6060 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
6061
6062 SourceRange R = cxloc::translateCXSourceRange(Range);
6063 if (R.isInvalid())
6064 return;
6065
6066 SmallVector<CXToken, 32> CXTokens;
6067 getTokens(CXXUnit, R, CXTokens);
6068
6069 if (CXTokens.empty())
6070 return;
6071
6072 *Tokens = (CXToken *)malloc(sizeof(CXToken) * CXTokens.size());
6073 memmove(*Tokens, CXTokens.data(), sizeof(CXToken) * CXTokens.size());
6074 *NumTokens = CXTokens.size();
6075}
6076
6077void clang_disposeTokens(CXTranslationUnit TU,
6078 CXToken *Tokens, unsigned NumTokens) {
6079 free(Tokens);
6080}
6081
6082} // end: extern "C"
6083
6084//===----------------------------------------------------------------------===//
6085// Token annotation APIs.
6086//===----------------------------------------------------------------------===//
6087
Guy Benyei11169dd2012-12-18 14:30:41 +00006088static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
6089 CXCursor parent,
6090 CXClientData client_data);
6091static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
6092 CXClientData client_data);
6093
6094namespace {
6095class AnnotateTokensWorker {
Guy Benyei11169dd2012-12-18 14:30:41 +00006096 CXToken *Tokens;
6097 CXCursor *Cursors;
6098 unsigned NumTokens;
6099 unsigned TokIdx;
6100 unsigned PreprocessingTokIdx;
6101 CursorVisitor AnnotateVis;
6102 SourceManager &SrcMgr;
6103 bool HasContextSensitiveKeywords;
6104
6105 struct PostChildrenInfo {
6106 CXCursor Cursor;
6107 SourceRange CursorRange;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00006108 unsigned BeforeReachingCursorIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00006109 unsigned BeforeChildrenTokenIdx;
6110 };
Dmitri Gribenkof8579502013-01-12 19:30:44 +00006111 SmallVector<PostChildrenInfo, 8> PostChildrenInfos;
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00006112
6113 CXToken &getTok(unsigned Idx) {
6114 assert(Idx < NumTokens);
6115 return Tokens[Idx];
6116 }
6117 const CXToken &getTok(unsigned Idx) const {
6118 assert(Idx < NumTokens);
6119 return Tokens[Idx];
6120 }
Guy Benyei11169dd2012-12-18 14:30:41 +00006121 bool MoreTokens() const { return TokIdx < NumTokens; }
6122 unsigned NextToken() const { return TokIdx; }
6123 void AdvanceToken() { ++TokIdx; }
6124 SourceLocation GetTokenLoc(unsigned tokI) {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00006125 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[1]);
Guy Benyei11169dd2012-12-18 14:30:41 +00006126 }
6127 bool isFunctionMacroToken(unsigned tokI) const {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00006128 return getTok(tokI).int_data[3] != 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00006129 }
6130 SourceLocation getFunctionMacroTokenLoc(unsigned tokI) const {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00006131 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[3]);
Guy Benyei11169dd2012-12-18 14:30:41 +00006132 }
6133
6134 void annotateAndAdvanceTokens(CXCursor, RangeComparisonResult, SourceRange);
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00006135 bool annotateAndAdvanceFunctionMacroTokens(CXCursor, RangeComparisonResult,
Guy Benyei11169dd2012-12-18 14:30:41 +00006136 SourceRange);
6137
6138public:
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006139 AnnotateTokensWorker(CXToken *tokens, CXCursor *cursors, unsigned numTokens,
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006140 CXTranslationUnit TU, SourceRange RegionOfInterest)
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006141 : Tokens(tokens), Cursors(cursors),
Guy Benyei11169dd2012-12-18 14:30:41 +00006142 NumTokens(numTokens), TokIdx(0), PreprocessingTokIdx(0),
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006143 AnnotateVis(TU,
Guy Benyei11169dd2012-12-18 14:30:41 +00006144 AnnotateTokensVisitor, this,
6145 /*VisitPreprocessorLast=*/true,
6146 /*VisitIncludedEntities=*/false,
6147 RegionOfInterest,
6148 /*VisitDeclsOnly=*/false,
6149 AnnotateTokensPostChildrenVisitor),
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006150 SrcMgr(cxtu::getASTUnit(TU)->getSourceManager()),
Guy Benyei11169dd2012-12-18 14:30:41 +00006151 HasContextSensitiveKeywords(false) { }
6152
6153 void VisitChildren(CXCursor C) { AnnotateVis.VisitChildren(C); }
6154 enum CXChildVisitResult Visit(CXCursor cursor, CXCursor parent);
6155 bool postVisitChildren(CXCursor cursor);
6156 void AnnotateTokens();
6157
6158 /// \brief Determine whether the annotator saw any cursors that have
6159 /// context-sensitive keywords.
6160 bool hasContextSensitiveKeywords() const {
6161 return HasContextSensitiveKeywords;
6162 }
6163
6164 ~AnnotateTokensWorker() {
6165 assert(PostChildrenInfos.empty());
6166 }
6167};
Alexander Kornienkoab9db512015-06-22 23:07:51 +00006168}
Guy Benyei11169dd2012-12-18 14:30:41 +00006169
6170void AnnotateTokensWorker::AnnotateTokens() {
6171 // Walk the AST within the region of interest, annotating tokens
6172 // along the way.
6173 AnnotateVis.visitFileRegion();
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006174}
Guy Benyei11169dd2012-12-18 14:30:41 +00006175
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006176static inline void updateCursorAnnotation(CXCursor &Cursor,
6177 const CXCursor &updateC) {
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00006178 if (clang_isInvalid(updateC.kind) || !clang_isInvalid(Cursor.kind))
Guy Benyei11169dd2012-12-18 14:30:41 +00006179 return;
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006180 Cursor = updateC;
Guy Benyei11169dd2012-12-18 14:30:41 +00006181}
6182
6183/// \brief It annotates and advances tokens with a cursor until the comparison
6184//// between the cursor location and the source range is the same as
6185/// \arg compResult.
6186///
6187/// Pass RangeBefore to annotate tokens with a cursor until a range is reached.
6188/// Pass RangeOverlap to annotate tokens inside a range.
6189void AnnotateTokensWorker::annotateAndAdvanceTokens(CXCursor updateC,
6190 RangeComparisonResult compResult,
6191 SourceRange range) {
6192 while (MoreTokens()) {
6193 const unsigned I = NextToken();
6194 if (isFunctionMacroToken(I))
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00006195 if (!annotateAndAdvanceFunctionMacroTokens(updateC, compResult, range))
6196 return;
Guy Benyei11169dd2012-12-18 14:30:41 +00006197
6198 SourceLocation TokLoc = GetTokenLoc(I);
6199 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006200 updateCursorAnnotation(Cursors[I], updateC);
Guy Benyei11169dd2012-12-18 14:30:41 +00006201 AdvanceToken();
6202 continue;
6203 }
6204 break;
6205 }
6206}
6207
6208/// \brief Special annotation handling for macro argument tokens.
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00006209/// \returns true if it advanced beyond all macro tokens, false otherwise.
6210bool AnnotateTokensWorker::annotateAndAdvanceFunctionMacroTokens(
Guy Benyei11169dd2012-12-18 14:30:41 +00006211 CXCursor updateC,
6212 RangeComparisonResult compResult,
6213 SourceRange range) {
6214 assert(MoreTokens());
6215 assert(isFunctionMacroToken(NextToken()) &&
6216 "Should be called only for macro arg tokens");
6217
6218 // This works differently than annotateAndAdvanceTokens; because expanded
6219 // macro arguments can have arbitrary translation-unit source order, we do not
6220 // advance the token index one by one until a token fails the range test.
6221 // We only advance once past all of the macro arg tokens if all of them
6222 // pass the range test. If one of them fails we keep the token index pointing
6223 // at the start of the macro arg tokens so that the failing token will be
6224 // annotated by a subsequent annotation try.
6225
6226 bool atLeastOneCompFail = false;
6227
6228 unsigned I = NextToken();
6229 for (; I < NumTokens && isFunctionMacroToken(I); ++I) {
6230 SourceLocation TokLoc = getFunctionMacroTokenLoc(I);
6231 if (TokLoc.isFileID())
6232 continue; // not macro arg token, it's parens or comma.
6233 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
6234 if (clang_isInvalid(clang_getCursorKind(Cursors[I])))
6235 Cursors[I] = updateC;
6236 } else
6237 atLeastOneCompFail = true;
6238 }
6239
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00006240 if (atLeastOneCompFail)
6241 return false;
6242
6243 TokIdx = I; // All of the tokens were handled, advance beyond all of them.
6244 return true;
Guy Benyei11169dd2012-12-18 14:30:41 +00006245}
6246
6247enum CXChildVisitResult
6248AnnotateTokensWorker::Visit(CXCursor cursor, CXCursor parent) {
Guy Benyei11169dd2012-12-18 14:30:41 +00006249 SourceRange cursorRange = getRawCursorExtent(cursor);
6250 if (cursorRange.isInvalid())
6251 return CXChildVisit_Recurse;
6252
6253 if (!HasContextSensitiveKeywords) {
6254 // Objective-C properties can have context-sensitive keywords.
6255 if (cursor.kind == CXCursor_ObjCPropertyDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006256 if (const ObjCPropertyDecl *Property
Guy Benyei11169dd2012-12-18 14:30:41 +00006257 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(cursor)))
6258 HasContextSensitiveKeywords = Property->getPropertyAttributesAsWritten() != 0;
6259 }
6260 // Objective-C methods can have context-sensitive keywords.
6261 else if (cursor.kind == CXCursor_ObjCInstanceMethodDecl ||
6262 cursor.kind == CXCursor_ObjCClassMethodDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006263 if (const ObjCMethodDecl *Method
Guy Benyei11169dd2012-12-18 14:30:41 +00006264 = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
6265 if (Method->getObjCDeclQualifier())
6266 HasContextSensitiveKeywords = true;
6267 else {
Aaron Ballman43b68be2014-03-07 17:50:17 +00006268 for (const auto *P : Method->params()) {
6269 if (P->getObjCDeclQualifier()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00006270 HasContextSensitiveKeywords = true;
6271 break;
6272 }
6273 }
6274 }
6275 }
6276 }
6277 // C++ methods can have context-sensitive keywords.
6278 else if (cursor.kind == CXCursor_CXXMethod) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006279 if (const CXXMethodDecl *Method
Guy Benyei11169dd2012-12-18 14:30:41 +00006280 = dyn_cast_or_null<CXXMethodDecl>(getCursorDecl(cursor))) {
6281 if (Method->hasAttr<FinalAttr>() || Method->hasAttr<OverrideAttr>())
6282 HasContextSensitiveKeywords = true;
6283 }
6284 }
6285 // C++ classes can have context-sensitive keywords.
6286 else if (cursor.kind == CXCursor_StructDecl ||
6287 cursor.kind == CXCursor_ClassDecl ||
6288 cursor.kind == CXCursor_ClassTemplate ||
6289 cursor.kind == CXCursor_ClassTemplatePartialSpecialization) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006290 if (const Decl *D = getCursorDecl(cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +00006291 if (D->hasAttr<FinalAttr>())
6292 HasContextSensitiveKeywords = true;
6293 }
6294 }
Argyrios Kyrtzidis990b3862013-06-04 18:24:30 +00006295
6296 // Don't override a property annotation with its getter/setter method.
6297 if (cursor.kind == CXCursor_ObjCInstanceMethodDecl &&
6298 parent.kind == CXCursor_ObjCPropertyDecl)
6299 return CXChildVisit_Continue;
Guy Benyei11169dd2012-12-18 14:30:41 +00006300
6301 if (clang_isPreprocessing(cursor.kind)) {
6302 // Items in the preprocessing record are kept separate from items in
6303 // declarations, so we keep a separate token index.
6304 unsigned SavedTokIdx = TokIdx;
6305 TokIdx = PreprocessingTokIdx;
6306
6307 // Skip tokens up until we catch up to the beginning of the preprocessing
6308 // entry.
6309 while (MoreTokens()) {
6310 const unsigned I = NextToken();
6311 SourceLocation TokLoc = GetTokenLoc(I);
6312 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
6313 case RangeBefore:
6314 AdvanceToken();
6315 continue;
6316 case RangeAfter:
6317 case RangeOverlap:
6318 break;
6319 }
6320 break;
6321 }
6322
6323 // Look at all of the tokens within this range.
6324 while (MoreTokens()) {
6325 const unsigned I = NextToken();
6326 SourceLocation TokLoc = GetTokenLoc(I);
6327 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
6328 case RangeBefore:
6329 llvm_unreachable("Infeasible");
6330 case RangeAfter:
6331 break;
6332 case RangeOverlap:
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00006333 // For macro expansions, just note where the beginning of the macro
6334 // expansion occurs.
6335 if (cursor.kind == CXCursor_MacroExpansion) {
6336 if (TokLoc == cursorRange.getBegin())
6337 Cursors[I] = cursor;
6338 AdvanceToken();
6339 break;
6340 }
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006341 // We may have already annotated macro names inside macro definitions.
6342 if (Cursors[I].kind != CXCursor_MacroExpansion)
6343 Cursors[I] = cursor;
Guy Benyei11169dd2012-12-18 14:30:41 +00006344 AdvanceToken();
Guy Benyei11169dd2012-12-18 14:30:41 +00006345 continue;
6346 }
6347 break;
6348 }
6349
6350 // Save the preprocessing token index; restore the non-preprocessing
6351 // token index.
6352 PreprocessingTokIdx = TokIdx;
6353 TokIdx = SavedTokIdx;
6354 return CXChildVisit_Recurse;
6355 }
6356
6357 if (cursorRange.isInvalid())
6358 return CXChildVisit_Continue;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00006359
6360 unsigned BeforeReachingCursorIdx = NextToken();
Guy Benyei11169dd2012-12-18 14:30:41 +00006361 const enum CXCursorKind cursorK = clang_getCursorKind(cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00006362 const enum CXCursorKind K = clang_getCursorKind(parent);
6363 const CXCursor updateC =
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00006364 (clang_isInvalid(K) || K == CXCursor_TranslationUnit ||
6365 // Attributes are annotated out-of-order, skip tokens until we reach it.
6366 clang_isAttribute(cursor.kind))
Guy Benyei11169dd2012-12-18 14:30:41 +00006367 ? clang_getNullCursor() : parent;
6368
6369 annotateAndAdvanceTokens(updateC, RangeBefore, cursorRange);
6370
6371 // Avoid having the cursor of an expression "overwrite" the annotation of the
6372 // variable declaration that it belongs to.
6373 // This can happen for C++ constructor expressions whose range generally
6374 // include the variable declaration, e.g.:
6375 // MyCXXClass foo; // Make sure we don't annotate 'foo' as a CallExpr cursor.
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00006376 if (clang_isExpression(cursorK) && MoreTokens()) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00006377 const Expr *E = getCursorExpr(cursor);
Dmitri Gribenkoa1691182013-01-26 18:12:08 +00006378 if (const Decl *D = getCursorParentDecl(cursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00006379 const unsigned I = NextToken();
6380 if (E->getLocStart().isValid() && D->getLocation().isValid() &&
6381 E->getLocStart() == D->getLocation() &&
6382 E->getLocStart() == GetTokenLoc(I)) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006383 updateCursorAnnotation(Cursors[I], updateC);
Guy Benyei11169dd2012-12-18 14:30:41 +00006384 AdvanceToken();
6385 }
6386 }
6387 }
6388
6389 // Before recursing into the children keep some state that we are going
6390 // to use in the AnnotateTokensWorker::postVisitChildren callback to do some
6391 // extra work after the child nodes are visited.
6392 // Note that we don't call VisitChildren here to avoid traversing statements
6393 // code-recursively which can blow the stack.
6394
6395 PostChildrenInfo Info;
6396 Info.Cursor = cursor;
6397 Info.CursorRange = cursorRange;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00006398 Info.BeforeReachingCursorIdx = BeforeReachingCursorIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00006399 Info.BeforeChildrenTokenIdx = NextToken();
6400 PostChildrenInfos.push_back(Info);
6401
6402 return CXChildVisit_Recurse;
6403}
6404
6405bool AnnotateTokensWorker::postVisitChildren(CXCursor cursor) {
6406 if (PostChildrenInfos.empty())
6407 return false;
6408 const PostChildrenInfo &Info = PostChildrenInfos.back();
6409 if (!clang_equalCursors(Info.Cursor, cursor))
6410 return false;
6411
6412 const unsigned BeforeChildren = Info.BeforeChildrenTokenIdx;
6413 const unsigned AfterChildren = NextToken();
6414 SourceRange cursorRange = Info.CursorRange;
6415
6416 // Scan the tokens that are at the end of the cursor, but are not captured
6417 // but the child cursors.
6418 annotateAndAdvanceTokens(cursor, RangeOverlap, cursorRange);
6419
6420 // Scan the tokens that are at the beginning of the cursor, but are not
6421 // capture by the child cursors.
6422 for (unsigned I = BeforeChildren; I != AfterChildren; ++I) {
6423 if (!clang_isInvalid(clang_getCursorKind(Cursors[I])))
6424 break;
6425
6426 Cursors[I] = cursor;
6427 }
6428
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00006429 // Attributes are annotated out-of-order, rewind TokIdx to when we first
6430 // encountered the attribute cursor.
6431 if (clang_isAttribute(cursor.kind))
6432 TokIdx = Info.BeforeReachingCursorIdx;
6433
Guy Benyei11169dd2012-12-18 14:30:41 +00006434 PostChildrenInfos.pop_back();
6435 return false;
6436}
6437
6438static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
6439 CXCursor parent,
6440 CXClientData client_data) {
6441 return static_cast<AnnotateTokensWorker*>(client_data)->Visit(cursor, parent);
6442}
6443
6444static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
6445 CXClientData client_data) {
6446 return static_cast<AnnotateTokensWorker*>(client_data)->
6447 postVisitChildren(cursor);
6448}
6449
6450namespace {
6451
6452/// \brief Uses the macro expansions in the preprocessing record to find
6453/// and mark tokens that are macro arguments. This info is used by the
6454/// AnnotateTokensWorker.
6455class MarkMacroArgTokensVisitor {
6456 SourceManager &SM;
6457 CXToken *Tokens;
6458 unsigned NumTokens;
6459 unsigned CurIdx;
6460
6461public:
6462 MarkMacroArgTokensVisitor(SourceManager &SM,
6463 CXToken *tokens, unsigned numTokens)
6464 : SM(SM), Tokens(tokens), NumTokens(numTokens), CurIdx(0) { }
6465
6466 CXChildVisitResult visit(CXCursor cursor, CXCursor parent) {
6467 if (cursor.kind != CXCursor_MacroExpansion)
6468 return CXChildVisit_Continue;
6469
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006470 SourceRange macroRange = getCursorMacroExpansion(cursor).getSourceRange();
Guy Benyei11169dd2012-12-18 14:30:41 +00006471 if (macroRange.getBegin() == macroRange.getEnd())
6472 return CXChildVisit_Continue; // it's not a function macro.
6473
6474 for (; CurIdx < NumTokens; ++CurIdx) {
6475 if (!SM.isBeforeInTranslationUnit(getTokenLoc(CurIdx),
6476 macroRange.getBegin()))
6477 break;
6478 }
6479
6480 if (CurIdx == NumTokens)
6481 return CXChildVisit_Break;
6482
6483 for (; CurIdx < NumTokens; ++CurIdx) {
6484 SourceLocation tokLoc = getTokenLoc(CurIdx);
6485 if (!SM.isBeforeInTranslationUnit(tokLoc, macroRange.getEnd()))
6486 break;
6487
6488 setFunctionMacroTokenLoc(CurIdx, SM.getMacroArgExpandedLocation(tokLoc));
6489 }
6490
6491 if (CurIdx == NumTokens)
6492 return CXChildVisit_Break;
6493
6494 return CXChildVisit_Continue;
6495 }
6496
6497private:
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00006498 CXToken &getTok(unsigned Idx) {
6499 assert(Idx < NumTokens);
6500 return Tokens[Idx];
6501 }
6502 const CXToken &getTok(unsigned Idx) const {
6503 assert(Idx < NumTokens);
6504 return Tokens[Idx];
6505 }
6506
Guy Benyei11169dd2012-12-18 14:30:41 +00006507 SourceLocation getTokenLoc(unsigned tokI) {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00006508 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[1]);
Guy Benyei11169dd2012-12-18 14:30:41 +00006509 }
6510
6511 void setFunctionMacroTokenLoc(unsigned tokI, SourceLocation loc) {
6512 // The third field is reserved and currently not used. Use it here
6513 // to mark macro arg expanded tokens with their expanded locations.
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00006514 getTok(tokI).int_data[3] = loc.getRawEncoding();
Guy Benyei11169dd2012-12-18 14:30:41 +00006515 }
6516};
6517
6518} // end anonymous namespace
6519
6520static CXChildVisitResult
6521MarkMacroArgTokensVisitorDelegate(CXCursor cursor, CXCursor parent,
6522 CXClientData client_data) {
6523 return static_cast<MarkMacroArgTokensVisitor*>(client_data)->visit(cursor,
6524 parent);
6525}
6526
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006527/// \brief Used by \c annotatePreprocessorTokens.
6528/// \returns true if lexing was finished, false otherwise.
6529static bool lexNext(Lexer &Lex, Token &Tok,
6530 unsigned &NextIdx, unsigned NumTokens) {
6531 if (NextIdx >= NumTokens)
6532 return true;
6533
6534 ++NextIdx;
6535 Lex.LexFromRawLexer(Tok);
Alexander Kornienko1a9f1842015-12-28 15:24:08 +00006536 return Tok.is(tok::eof);
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006537}
6538
Guy Benyei11169dd2012-12-18 14:30:41 +00006539static void annotatePreprocessorTokens(CXTranslationUnit TU,
6540 SourceRange RegionOfInterest,
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006541 CXCursor *Cursors,
6542 CXToken *Tokens,
6543 unsigned NumTokens) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006544 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00006545
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006546 Preprocessor &PP = CXXUnit->getPreprocessor();
Guy Benyei11169dd2012-12-18 14:30:41 +00006547 SourceManager &SourceMgr = CXXUnit->getSourceManager();
6548 std::pair<FileID, unsigned> BeginLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00006549 = SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getBegin());
Guy Benyei11169dd2012-12-18 14:30:41 +00006550 std::pair<FileID, unsigned> EndLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00006551 = SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getEnd());
Guy Benyei11169dd2012-12-18 14:30:41 +00006552
6553 if (BeginLocInfo.first != EndLocInfo.first)
6554 return;
6555
6556 StringRef Buffer;
6557 bool Invalid = false;
6558 Buffer = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
6559 if (Buffer.empty() || Invalid)
6560 return;
6561
6562 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
6563 CXXUnit->getASTContext().getLangOpts(),
6564 Buffer.begin(), Buffer.data() + BeginLocInfo.second,
6565 Buffer.end());
6566 Lex.SetCommentRetentionState(true);
6567
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006568 unsigned NextIdx = 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00006569 // Lex tokens in raw mode until we hit the end of the range, to avoid
6570 // entering #includes or expanding macros.
6571 while (true) {
6572 Token Tok;
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006573 if (lexNext(Lex, Tok, NextIdx, NumTokens))
6574 break;
6575 unsigned TokIdx = NextIdx-1;
6576 assert(Tok.getLocation() ==
6577 SourceLocation::getFromRawEncoding(Tokens[TokIdx].int_data[1]));
Guy Benyei11169dd2012-12-18 14:30:41 +00006578
6579 reprocess:
6580 if (Tok.is(tok::hash) && Tok.isAtStartOfLine()) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006581 // We have found a preprocessing directive. Annotate the tokens
6582 // appropriately.
Guy Benyei11169dd2012-12-18 14:30:41 +00006583 //
6584 // FIXME: Some simple tests here could identify macro definitions and
6585 // #undefs, to provide specific cursor kinds for those.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006586
6587 SourceLocation BeginLoc = Tok.getLocation();
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006588 if (lexNext(Lex, Tok, NextIdx, NumTokens))
6589 break;
6590
Craig Topper69186e72014-06-08 08:38:04 +00006591 MacroInfo *MI = nullptr;
Alp Toker2d57cea2014-05-17 04:53:25 +00006592 if (Tok.is(tok::raw_identifier) && Tok.getRawIdentifier() == "define") {
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006593 if (lexNext(Lex, Tok, NextIdx, NumTokens))
6594 break;
6595
6596 if (Tok.is(tok::raw_identifier)) {
Alp Toker2d57cea2014-05-17 04:53:25 +00006597 IdentifierInfo &II =
6598 PP.getIdentifierTable().get(Tok.getRawIdentifier());
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006599 SourceLocation MappedTokLoc =
6600 CXXUnit->mapLocationToPreamble(Tok.getLocation());
6601 MI = getMacroInfo(II, MappedTokLoc, TU);
6602 }
6603 }
6604
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006605 bool finished = false;
Guy Benyei11169dd2012-12-18 14:30:41 +00006606 do {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006607 if (lexNext(Lex, Tok, NextIdx, NumTokens)) {
6608 finished = true;
6609 break;
6610 }
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006611 // If we are in a macro definition, check if the token was ever a
6612 // macro name and annotate it if that's the case.
6613 if (MI) {
6614 SourceLocation SaveLoc = Tok.getLocation();
6615 Tok.setLocation(CXXUnit->mapLocationToPreamble(SaveLoc));
Richard Smith66a81862015-05-04 02:25:31 +00006616 MacroDefinitionRecord *MacroDef =
6617 checkForMacroInMacroDefinition(MI, Tok, TU);
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006618 Tok.setLocation(SaveLoc);
6619 if (MacroDef)
Richard Smith66a81862015-05-04 02:25:31 +00006620 Cursors[NextIdx - 1] =
6621 MakeMacroExpansionCursor(MacroDef, Tok.getLocation(), TU);
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006622 }
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006623 } while (!Tok.isAtStartOfLine());
6624
6625 unsigned LastIdx = finished ? NextIdx-1 : NextIdx-2;
6626 assert(TokIdx <= LastIdx);
6627 SourceLocation EndLoc =
6628 SourceLocation::getFromRawEncoding(Tokens[LastIdx].int_data[1]);
6629 CXCursor Cursor =
6630 MakePreprocessingDirectiveCursor(SourceRange(BeginLoc, EndLoc), TU);
6631
6632 for (; TokIdx <= LastIdx; ++TokIdx)
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006633 updateCursorAnnotation(Cursors[TokIdx], Cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00006634
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006635 if (finished)
6636 break;
6637 goto reprocess;
Guy Benyei11169dd2012-12-18 14:30:41 +00006638 }
Guy Benyei11169dd2012-12-18 14:30:41 +00006639 }
6640}
6641
6642// This gets run a separate thread to avoid stack blowout.
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00006643static void clang_annotateTokensImpl(CXTranslationUnit TU, ASTUnit *CXXUnit,
6644 CXToken *Tokens, unsigned NumTokens,
6645 CXCursor *Cursors) {
Dmitri Gribenko183436e2013-01-26 21:49:50 +00006646 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00006647 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
6648 setThreadBackgroundPriority();
6649
6650 // Determine the region of interest, which contains all of the tokens.
6651 SourceRange RegionOfInterest;
6652 RegionOfInterest.setBegin(
6653 cxloc::translateSourceLocation(clang_getTokenLocation(TU, Tokens[0])));
6654 RegionOfInterest.setEnd(
6655 cxloc::translateSourceLocation(clang_getTokenLocation(TU,
6656 Tokens[NumTokens-1])));
6657
Guy Benyei11169dd2012-12-18 14:30:41 +00006658 // Relex the tokens within the source range to look for preprocessing
6659 // directives.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006660 annotatePreprocessorTokens(TU, RegionOfInterest, Cursors, Tokens, NumTokens);
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00006661
6662 // If begin location points inside a macro argument, set it to the expansion
6663 // location so we can have the full context when annotating semantically.
6664 {
6665 SourceManager &SM = CXXUnit->getSourceManager();
6666 SourceLocation Loc =
6667 SM.getMacroArgExpandedLocation(RegionOfInterest.getBegin());
6668 if (Loc.isMacroID())
6669 RegionOfInterest.setBegin(SM.getExpansionLoc(Loc));
6670 }
6671
Guy Benyei11169dd2012-12-18 14:30:41 +00006672 if (CXXUnit->getPreprocessor().getPreprocessingRecord()) {
6673 // Search and mark tokens that are macro argument expansions.
6674 MarkMacroArgTokensVisitor Visitor(CXXUnit->getSourceManager(),
6675 Tokens, NumTokens);
6676 CursorVisitor MacroArgMarker(TU,
6677 MarkMacroArgTokensVisitorDelegate, &Visitor,
6678 /*VisitPreprocessorLast=*/true,
6679 /*VisitIncludedEntities=*/false,
6680 RegionOfInterest);
6681 MacroArgMarker.visitPreprocessedEntitiesInRegion();
6682 }
6683
6684 // Annotate all of the source locations in the region of interest that map to
6685 // a specific cursor.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006686 AnnotateTokensWorker W(Tokens, Cursors, NumTokens, TU, RegionOfInterest);
Guy Benyei11169dd2012-12-18 14:30:41 +00006687
6688 // FIXME: We use a ridiculous stack size here because the data-recursion
6689 // algorithm uses a large stack frame than the non-data recursive version,
6690 // and AnnotationTokensWorker currently transforms the data-recursion
6691 // algorithm back into a traditional recursion by explicitly calling
6692 // VisitChildren(). We will need to remove this explicit recursive call.
6693 W.AnnotateTokens();
6694
6695 // If we ran into any entities that involve context-sensitive keywords,
6696 // take another pass through the tokens to mark them as such.
6697 if (W.hasContextSensitiveKeywords()) {
6698 for (unsigned I = 0; I != NumTokens; ++I) {
6699 if (clang_getTokenKind(Tokens[I]) != CXToken_Identifier)
6700 continue;
6701
6702 if (Cursors[I].kind == CXCursor_ObjCPropertyDecl) {
6703 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006704 if (const ObjCPropertyDecl *Property
Guy Benyei11169dd2012-12-18 14:30:41 +00006705 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(Cursors[I]))) {
6706 if (Property->getPropertyAttributesAsWritten() != 0 &&
6707 llvm::StringSwitch<bool>(II->getName())
6708 .Case("readonly", true)
6709 .Case("assign", true)
6710 .Case("unsafe_unretained", true)
6711 .Case("readwrite", true)
6712 .Case("retain", true)
6713 .Case("copy", true)
6714 .Case("nonatomic", true)
6715 .Case("atomic", true)
6716 .Case("getter", true)
6717 .Case("setter", true)
6718 .Case("strong", true)
6719 .Case("weak", true)
6720 .Default(false))
6721 Tokens[I].int_data[0] = CXToken_Keyword;
6722 }
6723 continue;
6724 }
6725
6726 if (Cursors[I].kind == CXCursor_ObjCInstanceMethodDecl ||
6727 Cursors[I].kind == CXCursor_ObjCClassMethodDecl) {
6728 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
6729 if (llvm::StringSwitch<bool>(II->getName())
6730 .Case("in", true)
6731 .Case("out", true)
6732 .Case("inout", true)
6733 .Case("oneway", true)
6734 .Case("bycopy", true)
6735 .Case("byref", true)
6736 .Default(false))
6737 Tokens[I].int_data[0] = CXToken_Keyword;
6738 continue;
6739 }
6740
6741 if (Cursors[I].kind == CXCursor_CXXFinalAttr ||
6742 Cursors[I].kind == CXCursor_CXXOverrideAttr) {
6743 Tokens[I].int_data[0] = CXToken_Keyword;
6744 continue;
6745 }
6746 }
6747 }
6748}
6749
6750extern "C" {
6751
6752void clang_annotateTokens(CXTranslationUnit TU,
6753 CXToken *Tokens, unsigned NumTokens,
6754 CXCursor *Cursors) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006755 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006756 LOG_BAD_TU(TU);
6757 return;
6758 }
6759 if (NumTokens == 0 || !Tokens || !Cursors) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006760 LOG_FUNC_SECTION { *Log << "<null input>"; }
Guy Benyei11169dd2012-12-18 14:30:41 +00006761 return;
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006762 }
6763
6764 LOG_FUNC_SECTION {
6765 *Log << TU << ' ';
6766 CXSourceLocation bloc = clang_getTokenLocation(TU, Tokens[0]);
6767 CXSourceLocation eloc = clang_getTokenLocation(TU, Tokens[NumTokens-1]);
6768 *Log << clang_getRange(bloc, eloc);
6769 }
Guy Benyei11169dd2012-12-18 14:30:41 +00006770
6771 // Any token we don't specifically annotate will have a NULL cursor.
6772 CXCursor C = clang_getNullCursor();
6773 for (unsigned I = 0; I != NumTokens; ++I)
6774 Cursors[I] = C;
6775
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006776 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00006777 if (!CXXUnit)
6778 return;
6779
6780 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00006781
6782 auto AnnotateTokensImpl = [=]() {
6783 clang_annotateTokensImpl(TU, CXXUnit, Tokens, NumTokens, Cursors);
6784 };
Guy Benyei11169dd2012-12-18 14:30:41 +00006785 llvm::CrashRecoveryContext CRC;
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00006786 if (!RunSafely(CRC, AnnotateTokensImpl, GetSafetyThreadStackSize() * 2)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00006787 fprintf(stderr, "libclang: crash detected while annotating tokens\n");
6788 }
6789}
6790
6791} // end: extern "C"
6792
6793//===----------------------------------------------------------------------===//
6794// Operations for querying linkage of a cursor.
6795//===----------------------------------------------------------------------===//
6796
6797extern "C" {
6798CXLinkageKind clang_getCursorLinkage(CXCursor cursor) {
6799 if (!clang_isDeclaration(cursor.kind))
6800 return CXLinkage_Invalid;
6801
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006802 const Decl *D = cxcursor::getCursorDecl(cursor);
6803 if (const NamedDecl *ND = dyn_cast_or_null<NamedDecl>(D))
Rafael Espindola3ae00052013-05-13 00:12:11 +00006804 switch (ND->getLinkageInternal()) {
Rafael Espindola50df3a02013-05-25 17:16:20 +00006805 case NoLinkage:
6806 case VisibleNoLinkage: return CXLinkage_NoLinkage;
Guy Benyei11169dd2012-12-18 14:30:41 +00006807 case InternalLinkage: return CXLinkage_Internal;
6808 case UniqueExternalLinkage: return CXLinkage_UniqueExternal;
6809 case ExternalLinkage: return CXLinkage_External;
6810 };
6811
6812 return CXLinkage_Invalid;
6813}
6814} // end: extern "C"
6815
6816//===----------------------------------------------------------------------===//
Ehsan Akhgari93697fa2015-11-23 19:56:46 +00006817// Operations for querying visibility of a cursor.
6818//===----------------------------------------------------------------------===//
6819
6820extern "C" {
6821CXVisibilityKind clang_getCursorVisibility(CXCursor cursor) {
6822 if (!clang_isDeclaration(cursor.kind))
6823 return CXVisibility_Invalid;
6824
6825 const Decl *D = cxcursor::getCursorDecl(cursor);
6826 if (const NamedDecl *ND = dyn_cast_or_null<NamedDecl>(D))
6827 switch (ND->getVisibility()) {
6828 case HiddenVisibility: return CXVisibility_Hidden;
6829 case ProtectedVisibility: return CXVisibility_Protected;
6830 case DefaultVisibility: return CXVisibility_Default;
6831 };
6832
6833 return CXVisibility_Invalid;
6834}
6835} // end: extern "C"
6836
6837//===----------------------------------------------------------------------===//
Guy Benyei11169dd2012-12-18 14:30:41 +00006838// Operations for querying language of a cursor.
6839//===----------------------------------------------------------------------===//
6840
6841static CXLanguageKind getDeclLanguage(const Decl *D) {
6842 if (!D)
6843 return CXLanguage_C;
6844
6845 switch (D->getKind()) {
6846 default:
6847 break;
6848 case Decl::ImplicitParam:
6849 case Decl::ObjCAtDefsField:
6850 case Decl::ObjCCategory:
6851 case Decl::ObjCCategoryImpl:
6852 case Decl::ObjCCompatibleAlias:
6853 case Decl::ObjCImplementation:
6854 case Decl::ObjCInterface:
6855 case Decl::ObjCIvar:
6856 case Decl::ObjCMethod:
6857 case Decl::ObjCProperty:
6858 case Decl::ObjCPropertyImpl:
6859 case Decl::ObjCProtocol:
Douglas Gregor85f3f952015-07-07 03:57:15 +00006860 case Decl::ObjCTypeParam:
Guy Benyei11169dd2012-12-18 14:30:41 +00006861 return CXLanguage_ObjC;
6862 case Decl::CXXConstructor:
6863 case Decl::CXXConversion:
6864 case Decl::CXXDestructor:
6865 case Decl::CXXMethod:
6866 case Decl::CXXRecord:
6867 case Decl::ClassTemplate:
6868 case Decl::ClassTemplatePartialSpecialization:
6869 case Decl::ClassTemplateSpecialization:
6870 case Decl::Friend:
6871 case Decl::FriendTemplate:
6872 case Decl::FunctionTemplate:
6873 case Decl::LinkageSpec:
6874 case Decl::Namespace:
6875 case Decl::NamespaceAlias:
6876 case Decl::NonTypeTemplateParm:
6877 case Decl::StaticAssert:
6878 case Decl::TemplateTemplateParm:
6879 case Decl::TemplateTypeParm:
6880 case Decl::UnresolvedUsingTypename:
6881 case Decl::UnresolvedUsingValue:
6882 case Decl::Using:
6883 case Decl::UsingDirective:
6884 case Decl::UsingShadow:
6885 return CXLanguage_CPlusPlus;
6886 }
6887
6888 return CXLanguage_C;
6889}
6890
6891extern "C" {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006892
6893static CXAvailabilityKind getCursorAvailabilityForDecl(const Decl *D) {
6894 if (isa<FunctionDecl>(D) && cast<FunctionDecl>(D)->isDeleted())
Manuel Klimek8e3a7ed2015-09-25 17:53:16 +00006895 return CXAvailability_NotAvailable;
Guy Benyei11169dd2012-12-18 14:30:41 +00006896
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006897 switch (D->getAvailability()) {
6898 case AR_Available:
6899 case AR_NotYetIntroduced:
6900 if (const EnumConstantDecl *EnumConst = dyn_cast<EnumConstantDecl>(D))
Benjamin Kramer656363d2013-10-15 18:53:18 +00006901 return getCursorAvailabilityForDecl(
6902 cast<Decl>(EnumConst->getDeclContext()));
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006903 return CXAvailability_Available;
6904
6905 case AR_Deprecated:
6906 return CXAvailability_Deprecated;
6907
6908 case AR_Unavailable:
6909 return CXAvailability_NotAvailable;
6910 }
Benjamin Kramer656363d2013-10-15 18:53:18 +00006911
6912 llvm_unreachable("Unknown availability kind!");
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006913}
6914
Guy Benyei11169dd2012-12-18 14:30:41 +00006915enum CXAvailabilityKind clang_getCursorAvailability(CXCursor cursor) {
6916 if (clang_isDeclaration(cursor.kind))
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006917 if (const Decl *D = cxcursor::getCursorDecl(cursor))
6918 return getCursorAvailabilityForDecl(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00006919
6920 return CXAvailability_Available;
6921}
6922
6923static CXVersion convertVersion(VersionTuple In) {
6924 CXVersion Out = { -1, -1, -1 };
6925 if (In.empty())
6926 return Out;
6927
6928 Out.Major = In.getMajor();
6929
NAKAMURA Takumic2b5d1f2013-02-21 02:32:34 +00006930 Optional<unsigned> Minor = In.getMinor();
6931 if (Minor.hasValue())
Guy Benyei11169dd2012-12-18 14:30:41 +00006932 Out.Minor = *Minor;
6933 else
6934 return Out;
6935
NAKAMURA Takumic2b5d1f2013-02-21 02:32:34 +00006936 Optional<unsigned> Subminor = In.getSubminor();
6937 if (Subminor.hasValue())
Guy Benyei11169dd2012-12-18 14:30:41 +00006938 Out.Subminor = *Subminor;
6939
6940 return Out;
6941}
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006942
6943static int getCursorPlatformAvailabilityForDecl(const Decl *D,
6944 int *always_deprecated,
6945 CXString *deprecated_message,
6946 int *always_unavailable,
6947 CXString *unavailable_message,
6948 CXPlatformAvailability *availability,
6949 int availability_size) {
6950 bool HadAvailAttr = false;
6951 int N = 0;
Aaron Ballmanb97112e2014-03-08 22:19:01 +00006952 for (auto A : D->attrs()) {
6953 if (DeprecatedAttr *Deprecated = dyn_cast<DeprecatedAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006954 HadAvailAttr = true;
6955 if (always_deprecated)
6956 *always_deprecated = 1;
Nico Weberaacf0312014-04-24 05:16:45 +00006957 if (deprecated_message) {
Argyrios Kyrtzidisedfe07f2014-04-24 06:05:40 +00006958 clang_disposeString(*deprecated_message);
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006959 *deprecated_message = cxstring::createDup(Deprecated->getMessage());
Nico Weberaacf0312014-04-24 05:16:45 +00006960 }
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006961 continue;
6962 }
6963
Aaron Ballmanb97112e2014-03-08 22:19:01 +00006964 if (UnavailableAttr *Unavailable = dyn_cast<UnavailableAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006965 HadAvailAttr = true;
6966 if (always_unavailable)
6967 *always_unavailable = 1;
6968 if (unavailable_message) {
Argyrios Kyrtzidisedfe07f2014-04-24 06:05:40 +00006969 clang_disposeString(*unavailable_message);
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006970 *unavailable_message = cxstring::createDup(Unavailable->getMessage());
6971 }
6972 continue;
6973 }
6974
Aaron Ballmanb97112e2014-03-08 22:19:01 +00006975 if (AvailabilityAttr *Avail = dyn_cast<AvailabilityAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006976 HadAvailAttr = true;
6977 if (N < availability_size) {
6978 availability[N].Platform
6979 = cxstring::createDup(Avail->getPlatform()->getName());
6980 availability[N].Introduced = convertVersion(Avail->getIntroduced());
6981 availability[N].Deprecated = convertVersion(Avail->getDeprecated());
6982 availability[N].Obsoleted = convertVersion(Avail->getObsoleted());
6983 availability[N].Unavailable = Avail->getUnavailable();
6984 availability[N].Message = cxstring::createDup(Avail->getMessage());
6985 }
6986 ++N;
6987 }
6988 }
6989
6990 if (!HadAvailAttr)
6991 if (const EnumConstantDecl *EnumConst = dyn_cast<EnumConstantDecl>(D))
6992 return getCursorPlatformAvailabilityForDecl(
6993 cast<Decl>(EnumConst->getDeclContext()),
6994 always_deprecated,
6995 deprecated_message,
6996 always_unavailable,
6997 unavailable_message,
6998 availability,
6999 availability_size);
Guy Benyei11169dd2012-12-18 14:30:41 +00007000
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00007001 return N;
7002}
7003
Guy Benyei11169dd2012-12-18 14:30:41 +00007004int clang_getCursorPlatformAvailability(CXCursor cursor,
7005 int *always_deprecated,
7006 CXString *deprecated_message,
7007 int *always_unavailable,
7008 CXString *unavailable_message,
7009 CXPlatformAvailability *availability,
7010 int availability_size) {
7011 if (always_deprecated)
7012 *always_deprecated = 0;
7013 if (deprecated_message)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00007014 *deprecated_message = cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00007015 if (always_unavailable)
7016 *always_unavailable = 0;
7017 if (unavailable_message)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00007018 *unavailable_message = cxstring::createEmpty();
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00007019
Guy Benyei11169dd2012-12-18 14:30:41 +00007020 if (!clang_isDeclaration(cursor.kind))
7021 return 0;
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00007022
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00007023 const Decl *D = cxcursor::getCursorDecl(cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00007024 if (!D)
7025 return 0;
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00007026
7027 return getCursorPlatformAvailabilityForDecl(D, always_deprecated,
7028 deprecated_message,
7029 always_unavailable,
7030 unavailable_message,
7031 availability,
7032 availability_size);
Guy Benyei11169dd2012-12-18 14:30:41 +00007033}
7034
7035void clang_disposeCXPlatformAvailability(CXPlatformAvailability *availability) {
7036 clang_disposeString(availability->Platform);
7037 clang_disposeString(availability->Message);
7038}
7039
7040CXLanguageKind clang_getCursorLanguage(CXCursor cursor) {
7041 if (clang_isDeclaration(cursor.kind))
7042 return getDeclLanguage(cxcursor::getCursorDecl(cursor));
7043
7044 return CXLanguage_Invalid;
7045}
7046
7047 /// \brief If the given cursor is the "templated" declaration
7048 /// descibing a class or function template, return the class or
7049 /// function template.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00007050static const Decl *maybeGetTemplateCursor(const Decl *D) {
Guy Benyei11169dd2012-12-18 14:30:41 +00007051 if (!D)
Craig Topper69186e72014-06-08 08:38:04 +00007052 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00007053
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00007054 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00007055 if (FunctionTemplateDecl *FunTmpl = FD->getDescribedFunctionTemplate())
7056 return FunTmpl;
7057
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00007058 if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00007059 if (ClassTemplateDecl *ClassTmpl = RD->getDescribedClassTemplate())
7060 return ClassTmpl;
7061
7062 return D;
7063}
7064
Argyrios Kyrtzidis4e0854f2014-10-15 17:05:31 +00007065
7066enum CX_StorageClass clang_Cursor_getStorageClass(CXCursor C) {
7067 StorageClass sc = SC_None;
7068 const Decl *D = getCursorDecl(C);
7069 if (D) {
7070 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
7071 sc = FD->getStorageClass();
7072 } else if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
7073 sc = VD->getStorageClass();
7074 } else {
7075 return CX_SC_Invalid;
7076 }
7077 } else {
7078 return CX_SC_Invalid;
7079 }
7080 switch (sc) {
7081 case SC_None:
7082 return CX_SC_None;
7083 case SC_Extern:
7084 return CX_SC_Extern;
7085 case SC_Static:
7086 return CX_SC_Static;
7087 case SC_PrivateExtern:
7088 return CX_SC_PrivateExtern;
Argyrios Kyrtzidis4e0854f2014-10-15 17:05:31 +00007089 case SC_Auto:
7090 return CX_SC_Auto;
7091 case SC_Register:
7092 return CX_SC_Register;
Argyrios Kyrtzidis4e0854f2014-10-15 17:05:31 +00007093 }
Kaelyn Takataab61e702014-10-15 18:03:26 +00007094 llvm_unreachable("Unhandled storage class!");
Argyrios Kyrtzidis4e0854f2014-10-15 17:05:31 +00007095}
7096
Guy Benyei11169dd2012-12-18 14:30:41 +00007097CXCursor clang_getCursorSemanticParent(CXCursor cursor) {
7098 if (clang_isDeclaration(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00007099 if (const Decl *D = getCursorDecl(cursor)) {
7100 const DeclContext *DC = D->getDeclContext();
Guy Benyei11169dd2012-12-18 14:30:41 +00007101 if (!DC)
7102 return clang_getNullCursor();
7103
7104 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
7105 getCursorTU(cursor));
7106 }
7107 }
7108
7109 if (clang_isStatement(cursor.kind) || clang_isExpression(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00007110 if (const Decl *D = getCursorDecl(cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +00007111 return MakeCXCursor(D, getCursorTU(cursor));
7112 }
7113
7114 return clang_getNullCursor();
7115}
7116
7117CXCursor clang_getCursorLexicalParent(CXCursor cursor) {
7118 if (clang_isDeclaration(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00007119 if (const Decl *D = getCursorDecl(cursor)) {
7120 const DeclContext *DC = D->getLexicalDeclContext();
Guy Benyei11169dd2012-12-18 14:30:41 +00007121 if (!DC)
7122 return clang_getNullCursor();
7123
7124 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
7125 getCursorTU(cursor));
7126 }
7127 }
7128
7129 // FIXME: Note that we can't easily compute the lexical context of a
7130 // statement or expression, so we return nothing.
7131 return clang_getNullCursor();
7132}
7133
7134CXFile clang_getIncludedFile(CXCursor cursor) {
7135 if (cursor.kind != CXCursor_InclusionDirective)
Craig Topper69186e72014-06-08 08:38:04 +00007136 return nullptr;
7137
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00007138 const InclusionDirective *ID = getCursorInclusionDirective(cursor);
Dmitri Gribenkof9304482013-01-23 15:56:07 +00007139 return const_cast<FileEntry *>(ID->getFile());
Guy Benyei11169dd2012-12-18 14:30:41 +00007140}
7141
Argyrios Kyrtzidis9adfd8a2013-04-18 22:15:49 +00007142unsigned clang_Cursor_getObjCPropertyAttributes(CXCursor C, unsigned reserved) {
7143 if (C.kind != CXCursor_ObjCPropertyDecl)
7144 return CXObjCPropertyAttr_noattr;
7145
7146 unsigned Result = CXObjCPropertyAttr_noattr;
7147 const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(getCursorDecl(C));
7148 ObjCPropertyDecl::PropertyAttributeKind Attr =
7149 PD->getPropertyAttributesAsWritten();
7150
7151#define SET_CXOBJCPROP_ATTR(A) \
7152 if (Attr & ObjCPropertyDecl::OBJC_PR_##A) \
7153 Result |= CXObjCPropertyAttr_##A
7154 SET_CXOBJCPROP_ATTR(readonly);
7155 SET_CXOBJCPROP_ATTR(getter);
7156 SET_CXOBJCPROP_ATTR(assign);
7157 SET_CXOBJCPROP_ATTR(readwrite);
7158 SET_CXOBJCPROP_ATTR(retain);
7159 SET_CXOBJCPROP_ATTR(copy);
7160 SET_CXOBJCPROP_ATTR(nonatomic);
7161 SET_CXOBJCPROP_ATTR(setter);
7162 SET_CXOBJCPROP_ATTR(atomic);
7163 SET_CXOBJCPROP_ATTR(weak);
7164 SET_CXOBJCPROP_ATTR(strong);
7165 SET_CXOBJCPROP_ATTR(unsafe_unretained);
7166#undef SET_CXOBJCPROP_ATTR
7167
7168 return Result;
7169}
7170
Argyrios Kyrtzidis9d9bc012013-04-18 23:29:12 +00007171unsigned clang_Cursor_getObjCDeclQualifiers(CXCursor C) {
7172 if (!clang_isDeclaration(C.kind))
7173 return CXObjCDeclQualifier_None;
7174
7175 Decl::ObjCDeclQualifier QT = Decl::OBJC_TQ_None;
7176 const Decl *D = getCursorDecl(C);
7177 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
7178 QT = MD->getObjCDeclQualifier();
7179 else if (const ParmVarDecl *PD = dyn_cast<ParmVarDecl>(D))
7180 QT = PD->getObjCDeclQualifier();
7181 if (QT == Decl::OBJC_TQ_None)
7182 return CXObjCDeclQualifier_None;
7183
7184 unsigned Result = CXObjCDeclQualifier_None;
7185 if (QT & Decl::OBJC_TQ_In) Result |= CXObjCDeclQualifier_In;
7186 if (QT & Decl::OBJC_TQ_Inout) Result |= CXObjCDeclQualifier_Inout;
7187 if (QT & Decl::OBJC_TQ_Out) Result |= CXObjCDeclQualifier_Out;
7188 if (QT & Decl::OBJC_TQ_Bycopy) Result |= CXObjCDeclQualifier_Bycopy;
7189 if (QT & Decl::OBJC_TQ_Byref) Result |= CXObjCDeclQualifier_Byref;
7190 if (QT & Decl::OBJC_TQ_Oneway) Result |= CXObjCDeclQualifier_Oneway;
7191
7192 return Result;
7193}
7194
Argyrios Kyrtzidis7b50fc52013-07-05 20:44:37 +00007195unsigned clang_Cursor_isObjCOptional(CXCursor C) {
7196 if (!clang_isDeclaration(C.kind))
7197 return 0;
7198
7199 const Decl *D = getCursorDecl(C);
7200 if (const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(D))
7201 return PD->getPropertyImplementation() == ObjCPropertyDecl::Optional;
7202 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
7203 return MD->getImplementationControl() == ObjCMethodDecl::Optional;
7204
7205 return 0;
7206}
7207
Argyrios Kyrtzidis23814e42013-04-18 23:53:05 +00007208unsigned clang_Cursor_isVariadic(CXCursor C) {
7209 if (!clang_isDeclaration(C.kind))
7210 return 0;
7211
7212 const Decl *D = getCursorDecl(C);
7213 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
7214 return FD->isVariadic();
7215 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
7216 return MD->isVariadic();
7217
7218 return 0;
7219}
7220
Guy Benyei11169dd2012-12-18 14:30:41 +00007221CXSourceRange clang_Cursor_getCommentRange(CXCursor C) {
7222 if (!clang_isDeclaration(C.kind))
7223 return clang_getNullRange();
7224
7225 const Decl *D = getCursorDecl(C);
7226 ASTContext &Context = getCursorContext(C);
7227 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
7228 if (!RC)
7229 return clang_getNullRange();
7230
7231 return cxloc::translateSourceRange(Context, RC->getSourceRange());
7232}
7233
7234CXString clang_Cursor_getRawCommentText(CXCursor C) {
7235 if (!clang_isDeclaration(C.kind))
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00007236 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00007237
7238 const Decl *D = getCursorDecl(C);
7239 ASTContext &Context = getCursorContext(C);
7240 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
7241 StringRef RawText = RC ? RC->getRawText(Context.getSourceManager()) :
7242 StringRef();
7243
7244 // Don't duplicate the string because RawText points directly into source
7245 // code.
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00007246 return cxstring::createRef(RawText);
Guy Benyei11169dd2012-12-18 14:30:41 +00007247}
7248
7249CXString clang_Cursor_getBriefCommentText(CXCursor C) {
7250 if (!clang_isDeclaration(C.kind))
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00007251 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00007252
7253 const Decl *D = getCursorDecl(C);
7254 const ASTContext &Context = getCursorContext(C);
7255 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
7256
7257 if (RC) {
7258 StringRef BriefText = RC->getBriefText(Context);
7259
7260 // Don't duplicate the string because RawComment ensures that this memory
7261 // will not go away.
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00007262 return cxstring::createRef(BriefText);
Guy Benyei11169dd2012-12-18 14:30:41 +00007263 }
7264
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00007265 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00007266}
7267
Guy Benyei11169dd2012-12-18 14:30:41 +00007268CXModule clang_Cursor_getModule(CXCursor C) {
7269 if (C.kind == CXCursor_ModuleImportDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00007270 if (const ImportDecl *ImportD =
7271 dyn_cast_or_null<ImportDecl>(getCursorDecl(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00007272 return ImportD->getImportedModule();
7273 }
7274
Craig Topper69186e72014-06-08 08:38:04 +00007275 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00007276}
7277
Argyrios Kyrtzidisf6d49c32014-05-14 23:14:37 +00007278CXModule clang_getModuleForFile(CXTranslationUnit TU, CXFile File) {
7279 if (isNotUsableTU(TU)) {
7280 LOG_BAD_TU(TU);
7281 return nullptr;
7282 }
7283 if (!File)
7284 return nullptr;
7285 FileEntry *FE = static_cast<FileEntry *>(File);
7286
7287 ASTUnit &Unit = *cxtu::getASTUnit(TU);
7288 HeaderSearch &HS = Unit.getPreprocessor().getHeaderSearchInfo();
7289 ModuleMap::KnownHeader Header = HS.findModuleForHeader(FE);
7290
Richard Smithfeb54b62014-10-23 02:01:19 +00007291 return Header.getModule();
Argyrios Kyrtzidisf6d49c32014-05-14 23:14:37 +00007292}
7293
Argyrios Kyrtzidis12fdb9e2013-04-26 22:47:49 +00007294CXFile clang_Module_getASTFile(CXModule CXMod) {
7295 if (!CXMod)
Craig Topper69186e72014-06-08 08:38:04 +00007296 return nullptr;
Argyrios Kyrtzidis12fdb9e2013-04-26 22:47:49 +00007297 Module *Mod = static_cast<Module*>(CXMod);
7298 return const_cast<FileEntry *>(Mod->getASTFile());
7299}
7300
Guy Benyei11169dd2012-12-18 14:30:41 +00007301CXModule clang_Module_getParent(CXModule CXMod) {
7302 if (!CXMod)
Craig Topper69186e72014-06-08 08:38:04 +00007303 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00007304 Module *Mod = static_cast<Module*>(CXMod);
7305 return Mod->Parent;
7306}
7307
7308CXString clang_Module_getName(CXModule CXMod) {
7309 if (!CXMod)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00007310 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00007311 Module *Mod = static_cast<Module*>(CXMod);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00007312 return cxstring::createDup(Mod->Name);
Guy Benyei11169dd2012-12-18 14:30:41 +00007313}
7314
7315CXString clang_Module_getFullName(CXModule CXMod) {
7316 if (!CXMod)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00007317 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00007318 Module *Mod = static_cast<Module*>(CXMod);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00007319 return cxstring::createDup(Mod->getFullModuleName());
Guy Benyei11169dd2012-12-18 14:30:41 +00007320}
7321
Argyrios Kyrtzidis884337f2014-05-15 04:44:25 +00007322int clang_Module_isSystem(CXModule CXMod) {
7323 if (!CXMod)
7324 return 0;
7325 Module *Mod = static_cast<Module*>(CXMod);
7326 return Mod->IsSystem;
7327}
7328
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00007329unsigned clang_Module_getNumTopLevelHeaders(CXTranslationUnit TU,
7330 CXModule CXMod) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00007331 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00007332 LOG_BAD_TU(TU);
7333 return 0;
7334 }
7335 if (!CXMod)
Guy Benyei11169dd2012-12-18 14:30:41 +00007336 return 0;
7337 Module *Mod = static_cast<Module*>(CXMod);
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00007338 FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
7339 ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
7340 return TopHeaders.size();
Guy Benyei11169dd2012-12-18 14:30:41 +00007341}
7342
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00007343CXFile clang_Module_getTopLevelHeader(CXTranslationUnit TU,
7344 CXModule CXMod, unsigned Index) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00007345 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00007346 LOG_BAD_TU(TU);
Craig Topper69186e72014-06-08 08:38:04 +00007347 return nullptr;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00007348 }
7349 if (!CXMod)
Craig Topper69186e72014-06-08 08:38:04 +00007350 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00007351 Module *Mod = static_cast<Module*>(CXMod);
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00007352 FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
Guy Benyei11169dd2012-12-18 14:30:41 +00007353
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00007354 ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
7355 if (Index < TopHeaders.size())
7356 return const_cast<FileEntry *>(TopHeaders[Index]);
Guy Benyei11169dd2012-12-18 14:30:41 +00007357
Craig Topper69186e72014-06-08 08:38:04 +00007358 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00007359}
7360
7361} // end: extern "C"
7362
7363//===----------------------------------------------------------------------===//
7364// C++ AST instrospection.
7365//===----------------------------------------------------------------------===//
7366
7367extern "C" {
Jonathan Coe29565352016-04-27 12:48:25 +00007368
7369unsigned clang_CXXConstructor_isDefaultConstructor(CXCursor C) {
7370 if (!clang_isDeclaration(C.kind))
7371 return 0;
7372
7373 const Decl *D = cxcursor::getCursorDecl(C);
7374 const CXXConstructorDecl *Constructor =
7375 D ? dyn_cast_or_null<CXXConstructorDecl>(D->getAsFunction()) : nullptr;
7376 return (Constructor && Constructor->isDefaultConstructor()) ? 1 : 0;
7377}
7378
7379unsigned clang_CXXConstructor_isCopyConstructor(CXCursor C) {
7380 if (!clang_isDeclaration(C.kind))
7381 return 0;
7382
7383 const Decl *D = cxcursor::getCursorDecl(C);
7384 const CXXConstructorDecl *Constructor =
7385 D ? dyn_cast_or_null<CXXConstructorDecl>(D->getAsFunction()) : nullptr;
7386 return (Constructor && Constructor->isCopyConstructor()) ? 1 : 0;
7387}
7388
7389unsigned clang_CXXConstructor_isMoveConstructor(CXCursor C) {
7390 if (!clang_isDeclaration(C.kind))
7391 return 0;
7392
7393 const Decl *D = cxcursor::getCursorDecl(C);
7394 const CXXConstructorDecl *Constructor =
7395 D ? dyn_cast_or_null<CXXConstructorDecl>(D->getAsFunction()) : nullptr;
7396 return (Constructor && Constructor->isMoveConstructor()) ? 1 : 0;
7397}
7398
7399unsigned clang_CXXConstructor_isConvertingConstructor(CXCursor C) {
7400 if (!clang_isDeclaration(C.kind))
7401 return 0;
7402
7403 const Decl *D = cxcursor::getCursorDecl(C);
7404 const CXXConstructorDecl *Constructor =
7405 D ? dyn_cast_or_null<CXXConstructorDecl>(D->getAsFunction()) : nullptr;
7406 // Passing 'false' excludes constructors marked 'explicit'.
7407 return (Constructor && Constructor->isConvertingConstructor(false)) ? 1 : 0;
7408}
7409
Saleem Abdulrasool6ea75db2015-10-27 15:50:22 +00007410unsigned clang_CXXField_isMutable(CXCursor C) {
7411 if (!clang_isDeclaration(C.kind))
7412 return 0;
7413
7414 if (const auto D = cxcursor::getCursorDecl(C))
7415 if (const auto FD = dyn_cast_or_null<FieldDecl>(D))
7416 return FD->isMutable() ? 1 : 0;
7417 return 0;
7418}
7419
Dmitri Gribenko62770be2013-05-17 18:38:35 +00007420unsigned clang_CXXMethod_isPureVirtual(CXCursor C) {
7421 if (!clang_isDeclaration(C.kind))
7422 return 0;
7423
Dmitri Gribenko62770be2013-05-17 18:38:35 +00007424 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00007425 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00007426 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Dmitri Gribenko62770be2013-05-17 18:38:35 +00007427 return (Method && Method->isVirtual() && Method->isPure()) ? 1 : 0;
7428}
7429
Dmitri Gribenkoe570ede2014-04-07 14:59:13 +00007430unsigned clang_CXXMethod_isConst(CXCursor C) {
7431 if (!clang_isDeclaration(C.kind))
7432 return 0;
7433
7434 const Decl *D = cxcursor::getCursorDecl(C);
7435 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00007436 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Dmitri Gribenkoe570ede2014-04-07 14:59:13 +00007437 return (Method && (Method->getTypeQualifiers() & Qualifiers::Const)) ? 1 : 0;
7438}
7439
Jonathan Coe29565352016-04-27 12:48:25 +00007440unsigned clang_CXXMethod_isDefaulted(CXCursor C) {
7441 if (!clang_isDeclaration(C.kind))
7442 return 0;
7443
7444 const Decl *D = cxcursor::getCursorDecl(C);
7445 const CXXMethodDecl *Method =
7446 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
7447 return (Method && Method->isDefaulted()) ? 1 : 0;
7448}
7449
Guy Benyei11169dd2012-12-18 14:30:41 +00007450unsigned clang_CXXMethod_isStatic(CXCursor C) {
7451 if (!clang_isDeclaration(C.kind))
7452 return 0;
7453
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00007454 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00007455 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00007456 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00007457 return (Method && Method->isStatic()) ? 1 : 0;
7458}
7459
7460unsigned clang_CXXMethod_isVirtual(CXCursor C) {
7461 if (!clang_isDeclaration(C.kind))
7462 return 0;
7463
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00007464 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00007465 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00007466 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00007467 return (Method && Method->isVirtual()) ? 1 : 0;
7468}
7469} // end: extern "C"
7470
7471//===----------------------------------------------------------------------===//
7472// Attribute introspection.
7473//===----------------------------------------------------------------------===//
7474
7475extern "C" {
7476CXType clang_getIBOutletCollectionType(CXCursor C) {
7477 if (C.kind != CXCursor_IBOutletCollectionAttr)
7478 return cxtype::MakeCXType(QualType(), cxcursor::getCursorTU(C));
7479
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00007480 const IBOutletCollectionAttr *A =
Guy Benyei11169dd2012-12-18 14:30:41 +00007481 cast<IBOutletCollectionAttr>(cxcursor::getCursorAttr(C));
7482
7483 return cxtype::MakeCXType(A->getInterface(), cxcursor::getCursorTU(C));
7484}
7485} // end: extern "C"
7486
7487//===----------------------------------------------------------------------===//
7488// Inspecting memory usage.
7489//===----------------------------------------------------------------------===//
7490
7491typedef std::vector<CXTUResourceUsageEntry> MemUsageEntries;
7492
7493static inline void createCXTUResourceUsageEntry(MemUsageEntries &entries,
7494 enum CXTUResourceUsageKind k,
7495 unsigned long amount) {
7496 CXTUResourceUsageEntry entry = { k, amount };
7497 entries.push_back(entry);
7498}
7499
7500extern "C" {
7501
7502const char *clang_getTUResourceUsageName(CXTUResourceUsageKind kind) {
7503 const char *str = "";
7504 switch (kind) {
7505 case CXTUResourceUsage_AST:
7506 str = "ASTContext: expressions, declarations, and types";
7507 break;
7508 case CXTUResourceUsage_Identifiers:
7509 str = "ASTContext: identifiers";
7510 break;
7511 case CXTUResourceUsage_Selectors:
7512 str = "ASTContext: selectors";
7513 break;
7514 case CXTUResourceUsage_GlobalCompletionResults:
7515 str = "Code completion: cached global results";
7516 break;
7517 case CXTUResourceUsage_SourceManagerContentCache:
7518 str = "SourceManager: content cache allocator";
7519 break;
7520 case CXTUResourceUsage_AST_SideTables:
7521 str = "ASTContext: side tables";
7522 break;
7523 case CXTUResourceUsage_SourceManager_Membuffer_Malloc:
7524 str = "SourceManager: malloc'ed memory buffers";
7525 break;
7526 case CXTUResourceUsage_SourceManager_Membuffer_MMap:
7527 str = "SourceManager: mmap'ed memory buffers";
7528 break;
7529 case CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc:
7530 str = "ExternalASTSource: malloc'ed memory buffers";
7531 break;
7532 case CXTUResourceUsage_ExternalASTSource_Membuffer_MMap:
7533 str = "ExternalASTSource: mmap'ed memory buffers";
7534 break;
7535 case CXTUResourceUsage_Preprocessor:
7536 str = "Preprocessor: malloc'ed memory";
7537 break;
7538 case CXTUResourceUsage_PreprocessingRecord:
7539 str = "Preprocessor: PreprocessingRecord";
7540 break;
7541 case CXTUResourceUsage_SourceManager_DataStructures:
7542 str = "SourceManager: data structures and tables";
7543 break;
7544 case CXTUResourceUsage_Preprocessor_HeaderSearch:
7545 str = "Preprocessor: header search tables";
7546 break;
7547 }
7548 return str;
7549}
7550
7551CXTUResourceUsage clang_getCXTUResourceUsage(CXTranslationUnit TU) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00007552 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00007553 LOG_BAD_TU(TU);
Craig Topper69186e72014-06-08 08:38:04 +00007554 CXTUResourceUsage usage = { (void*) nullptr, 0, nullptr };
Guy Benyei11169dd2012-12-18 14:30:41 +00007555 return usage;
7556 }
7557
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007558 ASTUnit *astUnit = cxtu::getASTUnit(TU);
Ahmed Charlesb8984322014-03-07 20:03:18 +00007559 std::unique_ptr<MemUsageEntries> entries(new MemUsageEntries());
Guy Benyei11169dd2012-12-18 14:30:41 +00007560 ASTContext &astContext = astUnit->getASTContext();
7561
7562 // How much memory is used by AST nodes and types?
7563 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST,
7564 (unsigned long) astContext.getASTAllocatedMemory());
7565
7566 // How much memory is used by identifiers?
7567 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Identifiers,
7568 (unsigned long) astContext.Idents.getAllocator().getTotalMemory());
7569
7570 // How much memory is used for selectors?
7571 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Selectors,
7572 (unsigned long) astContext.Selectors.getTotalMemory());
7573
7574 // How much memory is used by ASTContext's side tables?
7575 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST_SideTables,
7576 (unsigned long) astContext.getSideTableAllocatedMemory());
7577
7578 // How much memory is used for caching global code completion results?
7579 unsigned long completionBytes = 0;
7580 if (GlobalCodeCompletionAllocator *completionAllocator =
Alp Tokerf994cef2014-07-05 03:08:06 +00007581 astUnit->getCachedCompletionAllocator().get()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00007582 completionBytes = completionAllocator->getTotalMemory();
7583 }
7584 createCXTUResourceUsageEntry(*entries,
7585 CXTUResourceUsage_GlobalCompletionResults,
7586 completionBytes);
7587
7588 // How much memory is being used by SourceManager's content cache?
7589 createCXTUResourceUsageEntry(*entries,
7590 CXTUResourceUsage_SourceManagerContentCache,
7591 (unsigned long) astContext.getSourceManager().getContentCacheSize());
7592
7593 // How much memory is being used by the MemoryBuffer's in SourceManager?
7594 const SourceManager::MemoryBufferSizes &srcBufs =
7595 astUnit->getSourceManager().getMemoryBufferSizes();
7596
7597 createCXTUResourceUsageEntry(*entries,
7598 CXTUResourceUsage_SourceManager_Membuffer_Malloc,
7599 (unsigned long) srcBufs.malloc_bytes);
7600 createCXTUResourceUsageEntry(*entries,
7601 CXTUResourceUsage_SourceManager_Membuffer_MMap,
7602 (unsigned long) srcBufs.mmap_bytes);
7603 createCXTUResourceUsageEntry(*entries,
7604 CXTUResourceUsage_SourceManager_DataStructures,
7605 (unsigned long) astContext.getSourceManager()
7606 .getDataStructureSizes());
7607
7608 // How much memory is being used by the ExternalASTSource?
7609 if (ExternalASTSource *esrc = astContext.getExternalSource()) {
7610 const ExternalASTSource::MemoryBufferSizes &sizes =
7611 esrc->getMemoryBufferSizes();
7612
7613 createCXTUResourceUsageEntry(*entries,
7614 CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc,
7615 (unsigned long) sizes.malloc_bytes);
7616 createCXTUResourceUsageEntry(*entries,
7617 CXTUResourceUsage_ExternalASTSource_Membuffer_MMap,
7618 (unsigned long) sizes.mmap_bytes);
7619 }
7620
7621 // How much memory is being used by the Preprocessor?
7622 Preprocessor &pp = astUnit->getPreprocessor();
7623 createCXTUResourceUsageEntry(*entries,
7624 CXTUResourceUsage_Preprocessor,
7625 pp.getTotalMemory());
7626
7627 if (PreprocessingRecord *pRec = pp.getPreprocessingRecord()) {
7628 createCXTUResourceUsageEntry(*entries,
7629 CXTUResourceUsage_PreprocessingRecord,
7630 pRec->getTotalMemory());
7631 }
7632
7633 createCXTUResourceUsageEntry(*entries,
7634 CXTUResourceUsage_Preprocessor_HeaderSearch,
7635 pp.getHeaderSearchInfo().getTotalMemory());
Craig Topper69186e72014-06-08 08:38:04 +00007636
Guy Benyei11169dd2012-12-18 14:30:41 +00007637 CXTUResourceUsage usage = { (void*) entries.get(),
7638 (unsigned) entries->size(),
Alexander Kornienko6ee521c2015-01-23 15:36:10 +00007639 !entries->empty() ? &(*entries)[0] : nullptr };
Ahmed Charles9a16beb2014-03-07 19:33:25 +00007640 entries.release();
Guy Benyei11169dd2012-12-18 14:30:41 +00007641 return usage;
7642}
7643
7644void clang_disposeCXTUResourceUsage(CXTUResourceUsage usage) {
7645 if (usage.data)
7646 delete (MemUsageEntries*) usage.data;
7647}
7648
Argyrios Kyrtzidis0e282ef2013-12-06 18:55:45 +00007649CXSourceRangeList *clang_getSkippedRanges(CXTranslationUnit TU, CXFile file) {
7650 CXSourceRangeList *skipped = new CXSourceRangeList;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00007651 skipped->count = 0;
Craig Topper69186e72014-06-08 08:38:04 +00007652 skipped->ranges = nullptr;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00007653
Dmitri Gribenko852d6222014-02-11 15:02:48 +00007654 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00007655 LOG_BAD_TU(TU);
7656 return skipped;
7657 }
7658
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00007659 if (!file)
7660 return skipped;
7661
7662 ASTUnit *astUnit = cxtu::getASTUnit(TU);
7663 PreprocessingRecord *ppRec = astUnit->getPreprocessor().getPreprocessingRecord();
7664 if (!ppRec)
7665 return skipped;
7666
7667 ASTContext &Ctx = astUnit->getASTContext();
7668 SourceManager &sm = Ctx.getSourceManager();
7669 FileEntry *fileEntry = static_cast<FileEntry *>(file);
7670 FileID wantedFileID = sm.translateFile(fileEntry);
7671
7672 const std::vector<SourceRange> &SkippedRanges = ppRec->getSkippedRanges();
7673 std::vector<SourceRange> wantedRanges;
7674 for (std::vector<SourceRange>::const_iterator i = SkippedRanges.begin(), ei = SkippedRanges.end();
7675 i != ei; ++i) {
7676 if (sm.getFileID(i->getBegin()) == wantedFileID || sm.getFileID(i->getEnd()) == wantedFileID)
7677 wantedRanges.push_back(*i);
7678 }
7679
7680 skipped->count = wantedRanges.size();
7681 skipped->ranges = new CXSourceRange[skipped->count];
7682 for (unsigned i = 0, ei = skipped->count; i != ei; ++i)
7683 skipped->ranges[i] = cxloc::translateSourceRange(Ctx, wantedRanges[i]);
7684
7685 return skipped;
7686}
7687
Argyrios Kyrtzidis0e282ef2013-12-06 18:55:45 +00007688void clang_disposeSourceRangeList(CXSourceRangeList *ranges) {
7689 if (ranges) {
7690 delete[] ranges->ranges;
7691 delete ranges;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00007692 }
7693}
7694
Guy Benyei11169dd2012-12-18 14:30:41 +00007695} // end extern "C"
7696
7697void clang::PrintLibclangResourceUsage(CXTranslationUnit TU) {
7698 CXTUResourceUsage Usage = clang_getCXTUResourceUsage(TU);
7699 for (unsigned I = 0; I != Usage.numEntries; ++I)
7700 fprintf(stderr, " %s: %lu\n",
7701 clang_getTUResourceUsageName(Usage.entries[I].kind),
7702 Usage.entries[I].amount);
7703
7704 clang_disposeCXTUResourceUsage(Usage);
7705}
7706
7707//===----------------------------------------------------------------------===//
7708// Misc. utility functions.
7709//===----------------------------------------------------------------------===//
7710
7711/// Default to using an 8 MB stack size on "safety" threads.
7712static unsigned SafetyStackThreadSize = 8 << 20;
7713
7714namespace clang {
7715
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00007716bool RunSafely(llvm::CrashRecoveryContext &CRC, llvm::function_ref<void()> Fn,
Guy Benyei11169dd2012-12-18 14:30:41 +00007717 unsigned Size) {
7718 if (!Size)
7719 Size = GetSafetyThreadStackSize();
7720 if (Size)
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00007721 return CRC.RunSafelyOnThread(Fn, Size);
7722 return CRC.RunSafely(Fn);
Guy Benyei11169dd2012-12-18 14:30:41 +00007723}
7724
7725unsigned GetSafetyThreadStackSize() {
7726 return SafetyStackThreadSize;
7727}
7728
7729void SetSafetyThreadStackSize(unsigned Value) {
7730 SafetyStackThreadSize = Value;
7731}
7732
Alexander Kornienkoab9db512015-06-22 23:07:51 +00007733}
Guy Benyei11169dd2012-12-18 14:30:41 +00007734
7735void clang::setThreadBackgroundPriority() {
7736 if (getenv("LIBCLANG_BGPRIO_DISABLE"))
7737 return;
7738
Alp Toker1a86ad22014-07-06 06:24:00 +00007739#ifdef USE_DARWIN_THREADS
Guy Benyei11169dd2012-12-18 14:30:41 +00007740 setpriority(PRIO_DARWIN_THREAD, 0, PRIO_DARWIN_BG);
7741#endif
7742}
7743
7744void cxindex::printDiagsToStderr(ASTUnit *Unit) {
7745 if (!Unit)
7746 return;
7747
7748 for (ASTUnit::stored_diag_iterator D = Unit->stored_diag_begin(),
7749 DEnd = Unit->stored_diag_end();
7750 D != DEnd; ++D) {
Ben Langmuir749323f2014-04-22 17:40:12 +00007751 CXStoredDiagnostic Diag(*D, Unit->getLangOpts());
Guy Benyei11169dd2012-12-18 14:30:41 +00007752 CXString Msg = clang_formatDiagnostic(&Diag,
7753 clang_defaultDiagnosticDisplayOptions());
7754 fprintf(stderr, "%s\n", clang_getCString(Msg));
7755 clang_disposeString(Msg);
7756 }
7757#ifdef LLVM_ON_WIN32
7758 // On Windows, force a flush, since there may be multiple copies of
7759 // stderr and stdout in the file system, all with different buffers
7760 // but writing to the same device.
7761 fflush(stderr);
7762#endif
7763}
7764
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007765MacroInfo *cxindex::getMacroInfo(const IdentifierInfo &II,
7766 SourceLocation MacroDefLoc,
7767 CXTranslationUnit TU){
7768 if (MacroDefLoc.isInvalid() || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00007769 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007770 if (!II.hadMacroDefinition())
Craig Topper69186e72014-06-08 08:38:04 +00007771 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007772
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007773 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00007774 Preprocessor &PP = Unit->getPreprocessor();
Richard Smith20e883e2015-04-29 23:20:19 +00007775 MacroDirective *MD = PP.getLocalMacroDirectiveHistory(&II);
Argyrios Kyrtzidisb6210df2013-03-26 17:17:01 +00007776 if (MD) {
7777 for (MacroDirective::DefInfo
7778 Def = MD->getDefinition(); Def; Def = Def.getPreviousDefinition()) {
7779 if (MacroDefLoc == Def.getMacroInfo()->getDefinitionLoc())
7780 return Def.getMacroInfo();
7781 }
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007782 }
7783
Craig Topper69186e72014-06-08 08:38:04 +00007784 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007785}
7786
Richard Smith66a81862015-05-04 02:25:31 +00007787const MacroInfo *cxindex::getMacroInfo(const MacroDefinitionRecord *MacroDef,
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00007788 CXTranslationUnit TU) {
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007789 if (!MacroDef || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00007790 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007791 const IdentifierInfo *II = MacroDef->getName();
7792 if (!II)
Craig Topper69186e72014-06-08 08:38:04 +00007793 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007794
7795 return getMacroInfo(*II, MacroDef->getLocation(), TU);
7796}
7797
Richard Smith66a81862015-05-04 02:25:31 +00007798MacroDefinitionRecord *
7799cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI, const Token &Tok,
7800 CXTranslationUnit TU) {
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007801 if (!MI || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00007802 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007803 if (Tok.isNot(tok::raw_identifier))
Craig Topper69186e72014-06-08 08:38:04 +00007804 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007805
7806 if (MI->getNumTokens() == 0)
Craig Topper69186e72014-06-08 08:38:04 +00007807 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007808 SourceRange DefRange(MI->getReplacementToken(0).getLocation(),
7809 MI->getDefinitionEndLoc());
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007810 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007811
7812 // Check that the token is inside the definition and not its argument list.
7813 SourceManager &SM = Unit->getSourceManager();
7814 if (SM.isBeforeInTranslationUnit(Tok.getLocation(), DefRange.getBegin()))
Craig Topper69186e72014-06-08 08:38:04 +00007815 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007816 if (SM.isBeforeInTranslationUnit(DefRange.getEnd(), Tok.getLocation()))
Craig Topper69186e72014-06-08 08:38:04 +00007817 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007818
7819 Preprocessor &PP = Unit->getPreprocessor();
7820 PreprocessingRecord *PPRec = PP.getPreprocessingRecord();
7821 if (!PPRec)
Craig Topper69186e72014-06-08 08:38:04 +00007822 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007823
Alp Toker2d57cea2014-05-17 04:53:25 +00007824 IdentifierInfo &II = PP.getIdentifierTable().get(Tok.getRawIdentifier());
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007825 if (!II.hadMacroDefinition())
Craig Topper69186e72014-06-08 08:38:04 +00007826 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007827
7828 // Check that the identifier is not one of the macro arguments.
7829 if (std::find(MI->arg_begin(), MI->arg_end(), &II) != MI->arg_end())
Craig Topper69186e72014-06-08 08:38:04 +00007830 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007831
Richard Smith20e883e2015-04-29 23:20:19 +00007832 MacroDirective *InnerMD = PP.getLocalMacroDirectiveHistory(&II);
Argyrios Kyrtzidis09c9e812013-02-20 00:54:57 +00007833 if (!InnerMD)
Craig Topper69186e72014-06-08 08:38:04 +00007834 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007835
Argyrios Kyrtzidisb6210df2013-03-26 17:17:01 +00007836 return PPRec->findMacroDefinition(InnerMD->getMacroInfo());
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007837}
7838
Richard Smith66a81862015-05-04 02:25:31 +00007839MacroDefinitionRecord *
7840cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI, SourceLocation Loc,
7841 CXTranslationUnit TU) {
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007842 if (Loc.isInvalid() || !MI || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00007843 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007844
7845 if (MI->getNumTokens() == 0)
Craig Topper69186e72014-06-08 08:38:04 +00007846 return nullptr;
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007847 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007848 Preprocessor &PP = Unit->getPreprocessor();
7849 if (!PP.getPreprocessingRecord())
Craig Topper69186e72014-06-08 08:38:04 +00007850 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007851 Loc = Unit->getSourceManager().getSpellingLoc(Loc);
7852 Token Tok;
7853 if (PP.getRawToken(Loc, Tok))
Craig Topper69186e72014-06-08 08:38:04 +00007854 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007855
7856 return checkForMacroInMacroDefinition(MI, Tok, TU);
7857}
7858
Guy Benyei11169dd2012-12-18 14:30:41 +00007859extern "C" {
7860
7861CXString clang_getClangVersion() {
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00007862 return cxstring::createDup(getClangFullVersion());
Guy Benyei11169dd2012-12-18 14:30:41 +00007863}
7864
7865} // end: extern "C"
7866
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007867Logger &cxindex::Logger::operator<<(CXTranslationUnit TU) {
7868 if (TU) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007869 if (ASTUnit *Unit = cxtu::getASTUnit(TU)) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007870 LogOS << '<' << Unit->getMainFileName() << '>';
Argyrios Kyrtzidis37f2ab42013-03-05 20:21:14 +00007871 if (Unit->isMainFileAST())
7872 LogOS << " (" << Unit->getASTFileName() << ')';
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007873 return *this;
7874 }
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00007875 } else {
7876 LogOS << "<NULL TU>";
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007877 }
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007878 return *this;
7879}
7880
Argyrios Kyrtzidisba4b5f82013-03-08 02:32:26 +00007881Logger &cxindex::Logger::operator<<(const FileEntry *FE) {
7882 *this << FE->getName();
7883 return *this;
7884}
7885
7886Logger &cxindex::Logger::operator<<(CXCursor cursor) {
7887 CXString cursorName = clang_getCursorDisplayName(cursor);
7888 *this << cursorName << "@" << clang_getCursorLocation(cursor);
7889 clang_disposeString(cursorName);
7890 return *this;
7891}
7892
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007893Logger &cxindex::Logger::operator<<(CXSourceLocation Loc) {
7894 CXFile File;
7895 unsigned Line, Column;
Craig Topper69186e72014-06-08 08:38:04 +00007896 clang_getFileLocation(Loc, &File, &Line, &Column, nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007897 CXString FileName = clang_getFileName(File);
7898 *this << llvm::format("(%s:%d:%d)", clang_getCString(FileName), Line, Column);
7899 clang_disposeString(FileName);
7900 return *this;
7901}
7902
7903Logger &cxindex::Logger::operator<<(CXSourceRange range) {
7904 CXSourceLocation BLoc = clang_getRangeStart(range);
7905 CXSourceLocation ELoc = clang_getRangeEnd(range);
7906
7907 CXFile BFile;
7908 unsigned BLine, BColumn;
Craig Topper69186e72014-06-08 08:38:04 +00007909 clang_getFileLocation(BLoc, &BFile, &BLine, &BColumn, nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007910
7911 CXFile EFile;
7912 unsigned ELine, EColumn;
Craig Topper69186e72014-06-08 08:38:04 +00007913 clang_getFileLocation(ELoc, &EFile, &ELine, &EColumn, nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007914
7915 CXString BFileName = clang_getFileName(BFile);
7916 if (BFile == EFile) {
7917 *this << llvm::format("[%s %d:%d-%d:%d]", clang_getCString(BFileName),
7918 BLine, BColumn, ELine, EColumn);
7919 } else {
7920 CXString EFileName = clang_getFileName(EFile);
7921 *this << llvm::format("[%s:%d:%d - ", clang_getCString(BFileName),
7922 BLine, BColumn)
7923 << llvm::format("%s:%d:%d]", clang_getCString(EFileName),
7924 ELine, EColumn);
7925 clang_disposeString(EFileName);
7926 }
7927 clang_disposeString(BFileName);
7928 return *this;
7929}
7930
7931Logger &cxindex::Logger::operator<<(CXString Str) {
7932 *this << clang_getCString(Str);
7933 return *this;
7934}
7935
7936Logger &cxindex::Logger::operator<<(const llvm::format_object_base &Fmt) {
7937 LogOS << Fmt;
7938 return *this;
7939}
7940
Chandler Carruth37ad2582014-06-27 15:14:39 +00007941static llvm::ManagedStatic<llvm::sys::Mutex> LoggingMutex;
7942
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007943cxindex::Logger::~Logger() {
Chandler Carruth37ad2582014-06-27 15:14:39 +00007944 llvm::sys::ScopedLock L(*LoggingMutex);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007945
7946 static llvm::TimeRecord sBeginTR = llvm::TimeRecord::getCurrentTime();
7947
Dmitri Gribenkof8579502013-01-12 19:30:44 +00007948 raw_ostream &OS = llvm::errs();
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007949 OS << "[libclang:" << Name << ':';
7950
Alp Toker1a86ad22014-07-06 06:24:00 +00007951#ifdef USE_DARWIN_THREADS
7952 // TODO: Portability.
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007953 mach_port_t tid = pthread_mach_thread_np(pthread_self());
7954 OS << tid << ':';
7955#endif
7956
7957 llvm::TimeRecord TR = llvm::TimeRecord::getCurrentTime();
7958 OS << llvm::format("%7.4f] ", TR.getWallTime() - sBeginTR.getWallTime());
Yaron Keren09fb7c62015-03-10 07:33:23 +00007959 OS << Msg << '\n';
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007960
7961 if (Trace) {
Zachary Turner1fe2a8d2015-03-05 19:15:09 +00007962 llvm::sys::PrintStackTrace(OS);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007963 OS << "--------------------------------------------------\n";
7964 }
7965}
Benjamin Kramerc1ffdab2016-03-03 08:58:18 +00007966
7967#ifdef CLANG_TOOL_EXTRA_BUILD
7968// This anchor is used to force the linker to link the clang-tidy plugin.
7969extern volatile int ClangTidyPluginAnchorSource;
7970static int LLVM_ATTRIBUTE_UNUSED ClangTidyPluginAnchorDestination =
7971 ClangTidyPluginAnchorSource;
7972#endif