blob: f558daec23598214a0158b3c8e8b71779f1642c4 [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*/) {}
Alexander Kornienkoab9db512015-06-22 23:07:51 +00002249}
Alexey Bataev756c1962013-09-24 03:17:45 +00002250
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002251void EnqueueVisitor::EnqueueChildren(const OMPClause *S) {
2252 unsigned size = WL.size();
2253 OMPClauseEnqueue Visitor(this);
2254 Visitor.Visit(S);
2255 if (size == WL.size())
2256 return;
2257 // Now reverse the entries we just added. This will match the DFS
2258 // ordering performed by the worklist.
2259 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
2260 std::reverse(I, E);
2261}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002262void EnqueueVisitor::VisitAddrLabelExpr(const AddrLabelExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002263 WL.push_back(LabelRefVisit(E->getLabel(), E->getLabelLoc(), Parent));
2264}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002265void EnqueueVisitor::VisitBlockExpr(const BlockExpr *B) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002266 AddDecl(B->getBlockDecl());
2267}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002268void EnqueueVisitor::VisitCompoundLiteralExpr(const CompoundLiteralExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002269 EnqueueChildren(E);
2270 AddTypeLoc(E->getTypeSourceInfo());
2271}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002272void EnqueueVisitor::VisitCompoundStmt(const CompoundStmt *S) {
Pete Cooper57d3f142015-07-30 17:22:52 +00002273 for (auto &I : llvm::reverse(S->body()))
2274 AddStmt(I);
Guy Benyei11169dd2012-12-18 14:30:41 +00002275}
2276void EnqueueVisitor::
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002277VisitMSDependentExistsStmt(const MSDependentExistsStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002278 AddStmt(S->getSubStmt());
2279 AddDeclarationNameInfo(S);
2280 if (NestedNameSpecifierLoc QualifierLoc = S->getQualifierLoc())
2281 AddNestedNameSpecifierLoc(QualifierLoc);
2282}
2283
2284void EnqueueVisitor::
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002285VisitCXXDependentScopeMemberExpr(const CXXDependentScopeMemberExpr *E) {
James Y Knight04ec5bf2015-12-24 02:59:37 +00002286 if (E->hasExplicitTemplateArgs())
2287 AddExplicitTemplateArgs(E->getTemplateArgs(), E->getNumTemplateArgs());
Guy Benyei11169dd2012-12-18 14:30:41 +00002288 AddDeclarationNameInfo(E);
2289 if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
2290 AddNestedNameSpecifierLoc(QualifierLoc);
2291 if (!E->isImplicitAccess())
2292 AddStmt(E->getBase());
2293}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002294void EnqueueVisitor::VisitCXXNewExpr(const CXXNewExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002295 // Enqueue the initializer , if any.
2296 AddStmt(E->getInitializer());
2297 // Enqueue the array size, if any.
2298 AddStmt(E->getArraySize());
2299 // Enqueue the allocated type.
2300 AddTypeLoc(E->getAllocatedTypeSourceInfo());
2301 // Enqueue the placement arguments.
2302 for (unsigned I = E->getNumPlacementArgs(); I > 0; --I)
2303 AddStmt(E->getPlacementArg(I-1));
2304}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002305void EnqueueVisitor::VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *CE) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002306 for (unsigned I = CE->getNumArgs(); I > 1 /* Yes, this is 1 */; --I)
2307 AddStmt(CE->getArg(I-1));
2308 AddStmt(CE->getCallee());
2309 AddStmt(CE->getArg(0));
2310}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002311void EnqueueVisitor::VisitCXXPseudoDestructorExpr(
2312 const CXXPseudoDestructorExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002313 // Visit the name of the type being destroyed.
2314 AddTypeLoc(E->getDestroyedTypeInfo());
2315 // Visit the scope type that looks disturbingly like the nested-name-specifier
2316 // but isn't.
2317 AddTypeLoc(E->getScopeTypeInfo());
2318 // Visit the nested-name-specifier.
2319 if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
2320 AddNestedNameSpecifierLoc(QualifierLoc);
2321 // Visit base expression.
2322 AddStmt(E->getBase());
2323}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002324void EnqueueVisitor::VisitCXXScalarValueInitExpr(
2325 const CXXScalarValueInitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002326 AddTypeLoc(E->getTypeSourceInfo());
2327}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002328void EnqueueVisitor::VisitCXXTemporaryObjectExpr(
2329 const CXXTemporaryObjectExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002330 EnqueueChildren(E);
2331 AddTypeLoc(E->getTypeSourceInfo());
2332}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002333void EnqueueVisitor::VisitCXXTypeidExpr(const CXXTypeidExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002334 EnqueueChildren(E);
2335 if (E->isTypeOperand())
2336 AddTypeLoc(E->getTypeOperandSourceInfo());
2337}
2338
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002339void EnqueueVisitor::VisitCXXUnresolvedConstructExpr(
2340 const CXXUnresolvedConstructExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002341 EnqueueChildren(E);
2342 AddTypeLoc(E->getTypeSourceInfo());
2343}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002344void EnqueueVisitor::VisitCXXUuidofExpr(const CXXUuidofExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002345 EnqueueChildren(E);
2346 if (E->isTypeOperand())
2347 AddTypeLoc(E->getTypeOperandSourceInfo());
2348}
2349
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002350void EnqueueVisitor::VisitCXXCatchStmt(const CXXCatchStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002351 EnqueueChildren(S);
2352 AddDecl(S->getExceptionDecl());
2353}
2354
Argyrios Kyrtzidis99891242014-11-13 09:03:21 +00002355void EnqueueVisitor::VisitCXXForRangeStmt(const CXXForRangeStmt *S) {
Argyrios Kyrtzidiscde70692014-11-13 09:50:19 +00002356 AddStmt(S->getBody());
Argyrios Kyrtzidis99891242014-11-13 09:03:21 +00002357 AddStmt(S->getRangeInit());
Argyrios Kyrtzidiscde70692014-11-13 09:50:19 +00002358 AddDecl(S->getLoopVariable());
Argyrios Kyrtzidis99891242014-11-13 09:03:21 +00002359}
2360
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002361void EnqueueVisitor::VisitDeclRefExpr(const DeclRefExpr *DR) {
James Y Knight04ec5bf2015-12-24 02:59:37 +00002362 if (DR->hasExplicitTemplateArgs())
2363 AddExplicitTemplateArgs(DR->getTemplateArgs(), DR->getNumTemplateArgs());
Guy Benyei11169dd2012-12-18 14:30:41 +00002364 WL.push_back(DeclRefExprParts(DR, Parent));
2365}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002366void EnqueueVisitor::VisitDependentScopeDeclRefExpr(
2367 const DependentScopeDeclRefExpr *E) {
James Y Knight04ec5bf2015-12-24 02:59:37 +00002368 if (E->hasExplicitTemplateArgs())
2369 AddExplicitTemplateArgs(E->getTemplateArgs(), E->getNumTemplateArgs());
Guy Benyei11169dd2012-12-18 14:30:41 +00002370 AddDeclarationNameInfo(E);
2371 AddNestedNameSpecifierLoc(E->getQualifierLoc());
2372}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002373void EnqueueVisitor::VisitDeclStmt(const DeclStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002374 unsigned size = WL.size();
2375 bool isFirst = true;
Aaron Ballman535bbcc2014-03-14 17:01:24 +00002376 for (const auto *D : S->decls()) {
2377 AddDecl(D, isFirst);
Guy Benyei11169dd2012-12-18 14:30:41 +00002378 isFirst = false;
2379 }
2380 if (size == WL.size())
2381 return;
2382 // Now reverse the entries we just added. This will match the DFS
2383 // ordering performed by the worklist.
2384 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
2385 std::reverse(I, E);
2386}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002387void EnqueueVisitor::VisitDesignatedInitExpr(const DesignatedInitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002388 AddStmt(E->getInit());
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002389 for (DesignatedInitExpr::const_reverse_designators_iterator
Guy Benyei11169dd2012-12-18 14:30:41 +00002390 D = E->designators_rbegin(), DEnd = E->designators_rend();
2391 D != DEnd; ++D) {
2392 if (D->isFieldDesignator()) {
2393 if (FieldDecl *Field = D->getField())
2394 AddMemberRef(Field, D->getFieldLoc());
2395 continue;
2396 }
2397 if (D->isArrayDesignator()) {
2398 AddStmt(E->getArrayIndex(*D));
2399 continue;
2400 }
2401 assert(D->isArrayRangeDesignator() && "Unknown designator kind");
2402 AddStmt(E->getArrayRangeEnd(*D));
2403 AddStmt(E->getArrayRangeStart(*D));
2404 }
2405}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002406void EnqueueVisitor::VisitExplicitCastExpr(const ExplicitCastExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002407 EnqueueChildren(E);
2408 AddTypeLoc(E->getTypeInfoAsWritten());
2409}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002410void EnqueueVisitor::VisitForStmt(const ForStmt *FS) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002411 AddStmt(FS->getBody());
2412 AddStmt(FS->getInc());
2413 AddStmt(FS->getCond());
2414 AddDecl(FS->getConditionVariable());
2415 AddStmt(FS->getInit());
2416}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002417void EnqueueVisitor::VisitGotoStmt(const GotoStmt *GS) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002418 WL.push_back(LabelRefVisit(GS->getLabel(), GS->getLabelLoc(), Parent));
2419}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002420void EnqueueVisitor::VisitIfStmt(const IfStmt *If) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002421 AddStmt(If->getElse());
2422 AddStmt(If->getThen());
2423 AddStmt(If->getCond());
2424 AddDecl(If->getConditionVariable());
2425}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002426void EnqueueVisitor::VisitInitListExpr(const InitListExpr *IE) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002427 // We care about the syntactic form of the initializer list, only.
2428 if (InitListExpr *Syntactic = IE->getSyntacticForm())
2429 IE = Syntactic;
2430 EnqueueChildren(IE);
2431}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002432void EnqueueVisitor::VisitMemberExpr(const MemberExpr *M) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002433 WL.push_back(MemberExprParts(M, Parent));
2434
2435 // If the base of the member access expression is an implicit 'this', don't
2436 // visit it.
2437 // FIXME: If we ever want to show these implicit accesses, this will be
2438 // unfortunate. However, clang_getCursor() relies on this behavior.
Argyrios Kyrtzidis58d0e7a2015-03-13 04:40:07 +00002439 if (M->isImplicitAccess())
2440 return;
2441
2442 // Ignore base anonymous struct/union fields, otherwise they will shadow the
2443 // real field that that we are interested in.
2444 if (auto *SubME = dyn_cast<MemberExpr>(M->getBase())) {
2445 if (auto *FD = dyn_cast_or_null<FieldDecl>(SubME->getMemberDecl())) {
2446 if (FD->isAnonymousStructOrUnion()) {
2447 AddStmt(SubME->getBase());
2448 return;
2449 }
2450 }
2451 }
2452
2453 AddStmt(M->getBase());
Guy Benyei11169dd2012-12-18 14:30:41 +00002454}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002455void EnqueueVisitor::VisitObjCEncodeExpr(const ObjCEncodeExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002456 AddTypeLoc(E->getEncodedTypeSourceInfo());
2457}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002458void EnqueueVisitor::VisitObjCMessageExpr(const ObjCMessageExpr *M) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002459 EnqueueChildren(M);
2460 AddTypeLoc(M->getClassReceiverTypeInfo());
2461}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002462void EnqueueVisitor::VisitOffsetOfExpr(const OffsetOfExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002463 // Visit the components of the offsetof expression.
2464 for (unsigned N = E->getNumComponents(), I = N; I > 0; --I) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002465 const OffsetOfNode &Node = E->getComponent(I-1);
2466 switch (Node.getKind()) {
2467 case OffsetOfNode::Array:
2468 AddStmt(E->getIndexExpr(Node.getArrayExprIndex()));
2469 break;
2470 case OffsetOfNode::Field:
2471 AddMemberRef(Node.getField(), Node.getSourceRange().getEnd());
2472 break;
2473 case OffsetOfNode::Identifier:
2474 case OffsetOfNode::Base:
2475 continue;
2476 }
2477 }
2478 // Visit the type into which we're computing the offset.
2479 AddTypeLoc(E->getTypeSourceInfo());
2480}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002481void EnqueueVisitor::VisitOverloadExpr(const OverloadExpr *E) {
James Y Knight04ec5bf2015-12-24 02:59:37 +00002482 if (E->hasExplicitTemplateArgs())
2483 AddExplicitTemplateArgs(E->getTemplateArgs(), E->getNumTemplateArgs());
Guy Benyei11169dd2012-12-18 14:30:41 +00002484 WL.push_back(OverloadExprParts(E, Parent));
2485}
2486void EnqueueVisitor::VisitUnaryExprOrTypeTraitExpr(
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002487 const UnaryExprOrTypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002488 EnqueueChildren(E);
2489 if (E->isArgumentType())
2490 AddTypeLoc(E->getArgumentTypeInfo());
2491}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002492void EnqueueVisitor::VisitStmt(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002493 EnqueueChildren(S);
2494}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002495void EnqueueVisitor::VisitSwitchStmt(const SwitchStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002496 AddStmt(S->getBody());
2497 AddStmt(S->getCond());
2498 AddDecl(S->getConditionVariable());
2499}
2500
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002501void EnqueueVisitor::VisitWhileStmt(const WhileStmt *W) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002502 AddStmt(W->getBody());
2503 AddStmt(W->getCond());
2504 AddDecl(W->getConditionVariable());
2505}
2506
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002507void EnqueueVisitor::VisitTypeTraitExpr(const TypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002508 for (unsigned I = E->getNumArgs(); I > 0; --I)
2509 AddTypeLoc(E->getArg(I-1));
2510}
2511
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002512void EnqueueVisitor::VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002513 AddTypeLoc(E->getQueriedTypeSourceInfo());
2514}
2515
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002516void EnqueueVisitor::VisitExpressionTraitExpr(const ExpressionTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002517 EnqueueChildren(E);
2518}
2519
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002520void EnqueueVisitor::VisitUnresolvedMemberExpr(const UnresolvedMemberExpr *U) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002521 VisitOverloadExpr(U);
2522 if (!U->isImplicitAccess())
2523 AddStmt(U->getBase());
2524}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002525void EnqueueVisitor::VisitVAArgExpr(const VAArgExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002526 AddStmt(E->getSubExpr());
2527 AddTypeLoc(E->getWrittenTypeInfo());
2528}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002529void EnqueueVisitor::VisitSizeOfPackExpr(const SizeOfPackExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002530 WL.push_back(SizeOfPackExprParts(E, Parent));
2531}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002532void EnqueueVisitor::VisitOpaqueValueExpr(const OpaqueValueExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002533 // If the opaque value has a source expression, just transparently
2534 // visit that. This is useful for (e.g.) pseudo-object expressions.
2535 if (Expr *SourceExpr = E->getSourceExpr())
2536 return Visit(SourceExpr);
2537}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002538void EnqueueVisitor::VisitLambdaExpr(const LambdaExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002539 AddStmt(E->getBody());
2540 WL.push_back(LambdaExprParts(E, Parent));
2541}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002542void EnqueueVisitor::VisitPseudoObjectExpr(const PseudoObjectExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002543 // Treat the expression like its syntactic form.
2544 Visit(E->getSyntacticForm());
2545}
2546
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002547void EnqueueVisitor::VisitOMPExecutableDirective(
2548 const OMPExecutableDirective *D) {
2549 EnqueueChildren(D);
2550 for (ArrayRef<OMPClause *>::iterator I = D->clauses().begin(),
2551 E = D->clauses().end();
2552 I != E; ++I)
2553 EnqueueChildren(*I);
2554}
2555
Alexander Musman3aaab662014-08-19 11:27:13 +00002556void EnqueueVisitor::VisitOMPLoopDirective(const OMPLoopDirective *D) {
2557 VisitOMPExecutableDirective(D);
2558}
2559
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002560void EnqueueVisitor::VisitOMPParallelDirective(const OMPParallelDirective *D) {
2561 VisitOMPExecutableDirective(D);
2562}
2563
Alexey Bataev1b59ab52014-02-27 08:29:12 +00002564void EnqueueVisitor::VisitOMPSimdDirective(const OMPSimdDirective *D) {
Alexander Musman3aaab662014-08-19 11:27:13 +00002565 VisitOMPLoopDirective(D);
Alexey Bataev1b59ab52014-02-27 08:29:12 +00002566}
2567
Alexey Bataevf29276e2014-06-18 04:14:57 +00002568void EnqueueVisitor::VisitOMPForDirective(const OMPForDirective *D) {
Alexander Musman3aaab662014-08-19 11:27:13 +00002569 VisitOMPLoopDirective(D);
Alexey Bataevf29276e2014-06-18 04:14:57 +00002570}
2571
Alexander Musmanf82886e2014-09-18 05:12:34 +00002572void EnqueueVisitor::VisitOMPForSimdDirective(const OMPForSimdDirective *D) {
2573 VisitOMPLoopDirective(D);
2574}
2575
Alexey Bataevd3f8dd22014-06-25 11:44:49 +00002576void EnqueueVisitor::VisitOMPSectionsDirective(const OMPSectionsDirective *D) {
2577 VisitOMPExecutableDirective(D);
2578}
2579
Alexey Bataev1e0498a2014-06-26 08:21:58 +00002580void EnqueueVisitor::VisitOMPSectionDirective(const OMPSectionDirective *D) {
2581 VisitOMPExecutableDirective(D);
2582}
2583
Alexey Bataevd1e40fb2014-06-26 12:05:45 +00002584void EnqueueVisitor::VisitOMPSingleDirective(const OMPSingleDirective *D) {
2585 VisitOMPExecutableDirective(D);
2586}
2587
Alexander Musman80c22892014-07-17 08:54:58 +00002588void EnqueueVisitor::VisitOMPMasterDirective(const OMPMasterDirective *D) {
2589 VisitOMPExecutableDirective(D);
2590}
2591
Alexander Musmand9ed09f2014-07-21 09:42:05 +00002592void EnqueueVisitor::VisitOMPCriticalDirective(const OMPCriticalDirective *D) {
2593 VisitOMPExecutableDirective(D);
2594 AddDeclarationNameInfo(D);
2595}
2596
Alexey Bataev4acb8592014-07-07 13:01:15 +00002597void
2598EnqueueVisitor::VisitOMPParallelForDirective(const OMPParallelForDirective *D) {
Alexander Musman3aaab662014-08-19 11:27:13 +00002599 VisitOMPLoopDirective(D);
Alexey Bataev4acb8592014-07-07 13:01:15 +00002600}
2601
Alexander Musmane4e893b2014-09-23 09:33:00 +00002602void EnqueueVisitor::VisitOMPParallelForSimdDirective(
2603 const OMPParallelForSimdDirective *D) {
2604 VisitOMPLoopDirective(D);
2605}
2606
Alexey Bataev84d0b3e2014-07-08 08:12:03 +00002607void EnqueueVisitor::VisitOMPParallelSectionsDirective(
2608 const OMPParallelSectionsDirective *D) {
2609 VisitOMPExecutableDirective(D);
2610}
2611
Alexey Bataev9c2e8ee2014-07-11 11:25:16 +00002612void EnqueueVisitor::VisitOMPTaskDirective(const OMPTaskDirective *D) {
2613 VisitOMPExecutableDirective(D);
2614}
2615
Alexey Bataev68446b72014-07-18 07:47:19 +00002616void
2617EnqueueVisitor::VisitOMPTaskyieldDirective(const OMPTaskyieldDirective *D) {
2618 VisitOMPExecutableDirective(D);
2619}
2620
Alexey Bataev4d1dfea2014-07-18 09:11:51 +00002621void EnqueueVisitor::VisitOMPBarrierDirective(const OMPBarrierDirective *D) {
2622 VisitOMPExecutableDirective(D);
2623}
2624
Alexey Bataev2df347a2014-07-18 10:17:07 +00002625void EnqueueVisitor::VisitOMPTaskwaitDirective(const OMPTaskwaitDirective *D) {
2626 VisitOMPExecutableDirective(D);
2627}
2628
Alexey Bataevc30dd2d2015-06-18 12:14:09 +00002629void EnqueueVisitor::VisitOMPTaskgroupDirective(
2630 const OMPTaskgroupDirective *D) {
2631 VisitOMPExecutableDirective(D);
2632}
2633
Alexey Bataev6125da92014-07-21 11:26:11 +00002634void EnqueueVisitor::VisitOMPFlushDirective(const OMPFlushDirective *D) {
2635 VisitOMPExecutableDirective(D);
2636}
2637
Alexey Bataev9fb6e642014-07-22 06:45:04 +00002638void EnqueueVisitor::VisitOMPOrderedDirective(const OMPOrderedDirective *D) {
2639 VisitOMPExecutableDirective(D);
2640}
2641
Alexey Bataev0162e452014-07-22 10:10:35 +00002642void EnqueueVisitor::VisitOMPAtomicDirective(const OMPAtomicDirective *D) {
2643 VisitOMPExecutableDirective(D);
2644}
2645
Alexey Bataev0bd520b2014-09-19 08:19:49 +00002646void EnqueueVisitor::VisitOMPTargetDirective(const OMPTargetDirective *D) {
2647 VisitOMPExecutableDirective(D);
2648}
2649
Michael Wong65f367f2015-07-21 13:44:28 +00002650void EnqueueVisitor::VisitOMPTargetDataDirective(const
2651 OMPTargetDataDirective *D) {
2652 VisitOMPExecutableDirective(D);
2653}
2654
Samuel Antaodf67fc42016-01-19 19:15:56 +00002655void EnqueueVisitor::VisitOMPTargetEnterDataDirective(
2656 const OMPTargetEnterDataDirective *D) {
2657 VisitOMPExecutableDirective(D);
2658}
2659
Samuel Antao72590762016-01-19 20:04:50 +00002660void EnqueueVisitor::VisitOMPTargetExitDataDirective(
2661 const OMPTargetExitDataDirective *D) {
2662 VisitOMPExecutableDirective(D);
2663}
2664
Arpith Chacko Jacobe955b3d2016-01-26 18:48:41 +00002665void EnqueueVisitor::VisitOMPTargetParallelDirective(
2666 const OMPTargetParallelDirective *D) {
2667 VisitOMPExecutableDirective(D);
2668}
2669
Arpith Chacko Jacob05bebb52016-02-03 15:46:42 +00002670void EnqueueVisitor::VisitOMPTargetParallelForDirective(
2671 const OMPTargetParallelForDirective *D) {
2672 VisitOMPLoopDirective(D);
2673}
2674
Alexey Bataev13314bf2014-10-09 04:18:56 +00002675void EnqueueVisitor::VisitOMPTeamsDirective(const OMPTeamsDirective *D) {
2676 VisitOMPExecutableDirective(D);
2677}
2678
Alexey Bataev6d4ed052015-07-01 06:57:41 +00002679void EnqueueVisitor::VisitOMPCancellationPointDirective(
2680 const OMPCancellationPointDirective *D) {
2681 VisitOMPExecutableDirective(D);
2682}
2683
Alexey Bataev80909872015-07-02 11:25:17 +00002684void EnqueueVisitor::VisitOMPCancelDirective(const OMPCancelDirective *D) {
2685 VisitOMPExecutableDirective(D);
2686}
2687
Alexey Bataev49f6e782015-12-01 04:18:41 +00002688void EnqueueVisitor::VisitOMPTaskLoopDirective(const OMPTaskLoopDirective *D) {
2689 VisitOMPLoopDirective(D);
2690}
2691
Alexey Bataev0a6ed842015-12-03 09:40:15 +00002692void EnqueueVisitor::VisitOMPTaskLoopSimdDirective(
2693 const OMPTaskLoopSimdDirective *D) {
2694 VisitOMPLoopDirective(D);
2695}
2696
Carlo Bertolli6200a3d2015-12-14 14:51:25 +00002697void EnqueueVisitor::VisitOMPDistributeDirective(
2698 const OMPDistributeDirective *D) {
2699 VisitOMPLoopDirective(D);
2700}
2701
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002702void CursorVisitor::EnqueueWorkList(VisitorWorkList &WL, const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002703 EnqueueVisitor(WL, MakeCXCursor(S, StmtParent, TU,RegionOfInterest)).Visit(S);
2704}
2705
2706bool CursorVisitor::IsInRegionOfInterest(CXCursor C) {
2707 if (RegionOfInterest.isValid()) {
2708 SourceRange Range = getRawCursorExtent(C);
2709 if (Range.isInvalid() || CompareRegionOfInterest(Range))
2710 return false;
2711 }
2712 return true;
2713}
2714
2715bool CursorVisitor::RunVisitorWorkList(VisitorWorkList &WL) {
2716 while (!WL.empty()) {
2717 // Dequeue the worklist item.
Robert Wilhelm25284cc2013-08-23 16:11:15 +00002718 VisitorJob LI = WL.pop_back_val();
Guy Benyei11169dd2012-12-18 14:30:41 +00002719
2720 // Set the Parent field, then back to its old value once we're done.
2721 SetParentRAII SetParent(Parent, StmtParent, LI.getParent());
2722
2723 switch (LI.getKind()) {
2724 case VisitorJob::DeclVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002725 const Decl *D = cast<DeclVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002726 if (!D)
2727 continue;
2728
2729 // For now, perform default visitation for Decls.
2730 if (Visit(MakeCXCursor(D, TU, RegionOfInterest,
2731 cast<DeclVisit>(&LI)->isFirst())))
2732 return true;
2733
2734 continue;
2735 }
2736 case VisitorJob::ExplicitTemplateArgsVisitKind: {
James Y Knight04ec5bf2015-12-24 02:59:37 +00002737 for (const TemplateArgumentLoc &Arg :
2738 *cast<ExplicitTemplateArgsVisit>(&LI)) {
2739 if (VisitTemplateArgumentLoc(Arg))
Guy Benyei11169dd2012-12-18 14:30:41 +00002740 return true;
2741 }
2742 continue;
2743 }
2744 case VisitorJob::TypeLocVisitKind: {
2745 // Perform default visitation for TypeLocs.
2746 if (Visit(cast<TypeLocVisit>(&LI)->get()))
2747 return true;
2748 continue;
2749 }
2750 case VisitorJob::LabelRefVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002751 const LabelDecl *LS = cast<LabelRefVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002752 if (LabelStmt *stmt = LS->getStmt()) {
2753 if (Visit(MakeCursorLabelRef(stmt, cast<LabelRefVisit>(&LI)->getLoc(),
2754 TU))) {
2755 return true;
2756 }
2757 }
2758 continue;
2759 }
2760
2761 case VisitorJob::NestedNameSpecifierLocVisitKind: {
2762 NestedNameSpecifierLocVisit *V = cast<NestedNameSpecifierLocVisit>(&LI);
2763 if (VisitNestedNameSpecifierLoc(V->get()))
2764 return true;
2765 continue;
2766 }
2767
2768 case VisitorJob::DeclarationNameInfoVisitKind: {
2769 if (VisitDeclarationNameInfo(cast<DeclarationNameInfoVisit>(&LI)
2770 ->get()))
2771 return true;
2772 continue;
2773 }
2774 case VisitorJob::MemberRefVisitKind: {
2775 MemberRefVisit *V = cast<MemberRefVisit>(&LI);
2776 if (Visit(MakeCursorMemberRef(V->get(), V->getLoc(), TU)))
2777 return true;
2778 continue;
2779 }
2780 case VisitorJob::StmtVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002781 const Stmt *S = cast<StmtVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002782 if (!S)
2783 continue;
2784
2785 // Update the current cursor.
2786 CXCursor Cursor = MakeCXCursor(S, StmtParent, TU, RegionOfInterest);
2787 if (!IsInRegionOfInterest(Cursor))
2788 continue;
2789 switch (Visitor(Cursor, Parent, ClientData)) {
2790 case CXChildVisit_Break: return true;
2791 case CXChildVisit_Continue: break;
2792 case CXChildVisit_Recurse:
2793 if (PostChildrenVisitor)
Craig Topper69186e72014-06-08 08:38:04 +00002794 WL.push_back(PostChildrenVisit(nullptr, Cursor));
Guy Benyei11169dd2012-12-18 14:30:41 +00002795 EnqueueWorkList(WL, S);
2796 break;
2797 }
2798 continue;
2799 }
2800 case VisitorJob::MemberExprPartsKind: {
2801 // Handle the other pieces in the MemberExpr besides the base.
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002802 const MemberExpr *M = cast<MemberExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002803
2804 // Visit the nested-name-specifier
2805 if (NestedNameSpecifierLoc QualifierLoc = M->getQualifierLoc())
2806 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2807 return true;
2808
2809 // Visit the declaration name.
2810 if (VisitDeclarationNameInfo(M->getMemberNameInfo()))
2811 return true;
2812
2813 // Visit the explicitly-specified template arguments, if any.
2814 if (M->hasExplicitTemplateArgs()) {
2815 for (const TemplateArgumentLoc *Arg = M->getTemplateArgs(),
2816 *ArgEnd = Arg + M->getNumTemplateArgs();
2817 Arg != ArgEnd; ++Arg) {
2818 if (VisitTemplateArgumentLoc(*Arg))
2819 return true;
2820 }
2821 }
2822 continue;
2823 }
2824 case VisitorJob::DeclRefExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002825 const DeclRefExpr *DR = cast<DeclRefExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002826 // Visit nested-name-specifier, if present.
2827 if (NestedNameSpecifierLoc QualifierLoc = DR->getQualifierLoc())
2828 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2829 return true;
2830 // Visit declaration name.
2831 if (VisitDeclarationNameInfo(DR->getNameInfo()))
2832 return true;
2833 continue;
2834 }
2835 case VisitorJob::OverloadExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002836 const OverloadExpr *O = cast<OverloadExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002837 // Visit the nested-name-specifier.
2838 if (NestedNameSpecifierLoc QualifierLoc = O->getQualifierLoc())
2839 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2840 return true;
2841 // Visit the declaration name.
2842 if (VisitDeclarationNameInfo(O->getNameInfo()))
2843 return true;
2844 // Visit the overloaded declaration reference.
2845 if (Visit(MakeCursorOverloadedDeclRef(O, TU)))
2846 return true;
2847 continue;
2848 }
2849 case VisitorJob::SizeOfPackExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002850 const SizeOfPackExpr *E = cast<SizeOfPackExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002851 NamedDecl *Pack = E->getPack();
2852 if (isa<TemplateTypeParmDecl>(Pack)) {
2853 if (Visit(MakeCursorTypeRef(cast<TemplateTypeParmDecl>(Pack),
2854 E->getPackLoc(), TU)))
2855 return true;
2856
2857 continue;
2858 }
2859
2860 if (isa<TemplateTemplateParmDecl>(Pack)) {
2861 if (Visit(MakeCursorTemplateRef(cast<TemplateTemplateParmDecl>(Pack),
2862 E->getPackLoc(), TU)))
2863 return true;
2864
2865 continue;
2866 }
2867
2868 // Non-type template parameter packs and function parameter packs are
2869 // treated like DeclRefExpr cursors.
2870 continue;
2871 }
2872
2873 case VisitorJob::LambdaExprPartsKind: {
2874 // Visit captures.
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002875 const LambdaExpr *E = cast<LambdaExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002876 for (LambdaExpr::capture_iterator C = E->explicit_capture_begin(),
2877 CEnd = E->explicit_capture_end();
2878 C != CEnd; ++C) {
Richard Smithba71c082013-05-16 06:20:58 +00002879 // FIXME: Lambda init-captures.
2880 if (!C->capturesVariable())
Guy Benyei11169dd2012-12-18 14:30:41 +00002881 continue;
Richard Smithba71c082013-05-16 06:20:58 +00002882
Guy Benyei11169dd2012-12-18 14:30:41 +00002883 if (Visit(MakeCursorVariableRef(C->getCapturedVar(),
2884 C->getLocation(),
2885 TU)))
2886 return true;
2887 }
2888
2889 // Visit parameters and return type, if present.
2890 if (E->hasExplicitParameters() || E->hasExplicitResultType()) {
2891 TypeLoc TL = E->getCallOperator()->getTypeSourceInfo()->getTypeLoc();
2892 if (E->hasExplicitParameters() && E->hasExplicitResultType()) {
2893 // Visit the whole type.
2894 if (Visit(TL))
2895 return true;
David Blaikie6adc78e2013-02-18 22:06:02 +00002896 } else if (FunctionProtoTypeLoc Proto =
2897 TL.getAs<FunctionProtoTypeLoc>()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002898 if (E->hasExplicitParameters()) {
2899 // Visit parameters.
Alp Tokerb3fd5cf2014-01-21 00:32:38 +00002900 for (unsigned I = 0, N = Proto.getNumParams(); I != N; ++I)
2901 if (Visit(MakeCXCursor(Proto.getParam(I), TU)))
Guy Benyei11169dd2012-12-18 14:30:41 +00002902 return true;
2903 } else {
2904 // Visit result type.
Alp Toker42a16a62014-01-25 23:51:36 +00002905 if (Visit(Proto.getReturnLoc()))
Guy Benyei11169dd2012-12-18 14:30:41 +00002906 return true;
2907 }
2908 }
2909 }
2910 break;
2911 }
2912
2913 case VisitorJob::PostChildrenVisitKind:
2914 if (PostChildrenVisitor(Parent, ClientData))
2915 return true;
2916 break;
2917 }
2918 }
2919 return false;
2920}
2921
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002922bool CursorVisitor::Visit(const Stmt *S) {
Craig Topper69186e72014-06-08 08:38:04 +00002923 VisitorWorkList *WL = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00002924 if (!WorkListFreeList.empty()) {
2925 WL = WorkListFreeList.back();
2926 WL->clear();
2927 WorkListFreeList.pop_back();
2928 }
2929 else {
2930 WL = new VisitorWorkList();
2931 WorkListCache.push_back(WL);
2932 }
2933 EnqueueWorkList(*WL, S);
2934 bool result = RunVisitorWorkList(*WL);
2935 WorkListFreeList.push_back(WL);
2936 return result;
2937}
2938
2939namespace {
Dmitri Gribenkof8579502013-01-12 19:30:44 +00002940typedef SmallVector<SourceRange, 4> RefNamePieces;
James Y Knight04ec5bf2015-12-24 02:59:37 +00002941RefNamePieces buildPieces(unsigned NameFlags, bool IsMemberRefExpr,
2942 const DeclarationNameInfo &NI, SourceRange QLoc,
2943 const SourceRange *TemplateArgsLoc = nullptr) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002944 const bool WantQualifier = NameFlags & CXNameRange_WantQualifier;
2945 const bool WantTemplateArgs = NameFlags & CXNameRange_WantTemplateArgs;
2946 const bool WantSinglePiece = NameFlags & CXNameRange_WantSinglePiece;
2947
2948 const DeclarationName::NameKind Kind = NI.getName().getNameKind();
2949
2950 RefNamePieces Pieces;
2951
2952 if (WantQualifier && QLoc.isValid())
2953 Pieces.push_back(QLoc);
2954
2955 if (Kind != DeclarationName::CXXOperatorName || IsMemberRefExpr)
2956 Pieces.push_back(NI.getLoc());
James Y Knight04ec5bf2015-12-24 02:59:37 +00002957
2958 if (WantTemplateArgs && TemplateArgsLoc && TemplateArgsLoc->isValid())
2959 Pieces.push_back(*TemplateArgsLoc);
2960
Guy Benyei11169dd2012-12-18 14:30:41 +00002961 if (Kind == DeclarationName::CXXOperatorName) {
2962 Pieces.push_back(SourceLocation::getFromRawEncoding(
2963 NI.getInfo().CXXOperatorName.BeginOpNameLoc));
2964 Pieces.push_back(SourceLocation::getFromRawEncoding(
2965 NI.getInfo().CXXOperatorName.EndOpNameLoc));
2966 }
2967
2968 if (WantSinglePiece) {
2969 SourceRange R(Pieces.front().getBegin(), Pieces.back().getEnd());
2970 Pieces.clear();
2971 Pieces.push_back(R);
2972 }
2973
2974 return Pieces;
2975}
Alexander Kornienkoab9db512015-06-22 23:07:51 +00002976}
Guy Benyei11169dd2012-12-18 14:30:41 +00002977
2978//===----------------------------------------------------------------------===//
2979// Misc. API hooks.
2980//===----------------------------------------------------------------------===//
2981
Chad Rosier05c71aa2013-03-27 18:28:23 +00002982static void fatal_error_handler(void *user_data, const std::string& reason,
2983 bool gen_crash_diag) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002984 // Write the result out to stderr avoiding errs() because raw_ostreams can
2985 // call report_fatal_error.
2986 fprintf(stderr, "LIBCLANG FATAL ERROR: %s\n", reason.c_str());
2987 ::abort();
2988}
2989
Chandler Carruth66660742014-06-27 16:37:27 +00002990namespace {
2991struct RegisterFatalErrorHandler {
2992 RegisterFatalErrorHandler() {
2993 llvm::install_fatal_error_handler(fatal_error_handler, nullptr);
2994 }
2995};
2996}
2997
2998static llvm::ManagedStatic<RegisterFatalErrorHandler> RegisterFatalErrorHandlerOnce;
2999
Guy Benyei11169dd2012-12-18 14:30:41 +00003000extern "C" {
3001CXIndex clang_createIndex(int excludeDeclarationsFromPCH,
3002 int displayDiagnostics) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003003 // We use crash recovery to make some of our APIs more reliable, implicitly
3004 // enable it.
Argyrios Kyrtzidis3701f542013-11-27 08:58:09 +00003005 if (!getenv("LIBCLANG_DISABLE_CRASH_RECOVERY"))
3006 llvm::CrashRecoveryContext::Enable();
Guy Benyei11169dd2012-12-18 14:30:41 +00003007
Chandler Carruth66660742014-06-27 16:37:27 +00003008 // Look through the managed static to trigger construction of the managed
3009 // static which registers our fatal error handler. This ensures it is only
3010 // registered once.
3011 (void)*RegisterFatalErrorHandlerOnce;
Guy Benyei11169dd2012-12-18 14:30:41 +00003012
Adrian Prantlbc068582015-07-08 01:00:30 +00003013 // Initialize targets for clang module support.
3014 llvm::InitializeAllTargets();
3015 llvm::InitializeAllTargetMCs();
3016 llvm::InitializeAllAsmPrinters();
3017 llvm::InitializeAllAsmParsers();
3018
Adrian Prantlfb2398d2015-07-17 01:19:54 +00003019 CIndexer *CIdxr = new CIndexer();
3020
Guy Benyei11169dd2012-12-18 14:30:41 +00003021 if (excludeDeclarationsFromPCH)
3022 CIdxr->setOnlyLocalDecls();
3023 if (displayDiagnostics)
3024 CIdxr->setDisplayDiagnostics();
3025
3026 if (getenv("LIBCLANG_BGPRIO_INDEX"))
3027 CIdxr->setCXGlobalOptFlags(CIdxr->getCXGlobalOptFlags() |
3028 CXGlobalOpt_ThreadBackgroundPriorityForIndexing);
3029 if (getenv("LIBCLANG_BGPRIO_EDIT"))
3030 CIdxr->setCXGlobalOptFlags(CIdxr->getCXGlobalOptFlags() |
3031 CXGlobalOpt_ThreadBackgroundPriorityForEditing);
3032
3033 return CIdxr;
3034}
3035
3036void clang_disposeIndex(CXIndex CIdx) {
3037 if (CIdx)
3038 delete static_cast<CIndexer *>(CIdx);
3039}
3040
3041void clang_CXIndex_setGlobalOptions(CXIndex CIdx, unsigned options) {
3042 if (CIdx)
3043 static_cast<CIndexer *>(CIdx)->setCXGlobalOptFlags(options);
3044}
3045
3046unsigned clang_CXIndex_getGlobalOptions(CXIndex CIdx) {
3047 if (CIdx)
3048 return static_cast<CIndexer *>(CIdx)->getCXGlobalOptFlags();
3049 return 0;
3050}
3051
3052void clang_toggleCrashRecovery(unsigned isEnabled) {
3053 if (isEnabled)
3054 llvm::CrashRecoveryContext::Enable();
3055 else
3056 llvm::CrashRecoveryContext::Disable();
3057}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003058
Guy Benyei11169dd2012-12-18 14:30:41 +00003059CXTranslationUnit clang_createTranslationUnit(CXIndex CIdx,
3060 const char *ast_filename) {
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00003061 CXTranslationUnit TU;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003062 enum CXErrorCode Result =
3063 clang_createTranslationUnit2(CIdx, ast_filename, &TU);
Reid Klecknerfd48fc62014-02-12 23:56:20 +00003064 (void)Result;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003065 assert((TU && Result == CXError_Success) ||
3066 (!TU && Result != CXError_Success));
3067 return TU;
3068}
3069
3070enum CXErrorCode clang_createTranslationUnit2(CXIndex CIdx,
3071 const char *ast_filename,
3072 CXTranslationUnit *out_TU) {
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00003073 if (out_TU)
Craig Topper69186e72014-06-08 08:38:04 +00003074 *out_TU = nullptr;
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00003075
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003076 if (!CIdx || !ast_filename || !out_TU)
3077 return CXError_InvalidArguments;
Guy Benyei11169dd2012-12-18 14:30:41 +00003078
Argyrios Kyrtzidis27021012013-05-24 22:24:07 +00003079 LOG_FUNC_SECTION {
3080 *Log << ast_filename;
3081 }
3082
Guy Benyei11169dd2012-12-18 14:30:41 +00003083 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
3084 FileSystemOptions FileSystemOpts;
3085
Justin Bognerd512c1e2014-10-15 00:33:06 +00003086 IntrusiveRefCntPtr<DiagnosticsEngine> Diags =
3087 CompilerInstance::createDiagnostics(new DiagnosticOptions());
David Blaikie6f7382d2014-08-10 19:08:04 +00003088 std::unique_ptr<ASTUnit> AU = ASTUnit::LoadFromASTFile(
Adrian Prantlfb2398d2015-07-17 01:19:54 +00003089 ast_filename, CXXIdx->getPCHContainerOperations()->getRawReader(), Diags,
Adrian Prantl6b21ab22015-08-27 19:46:20 +00003090 FileSystemOpts, /*UseDebugInfo=*/false,
3091 CXXIdx->getOnlyLocalDecls(), None,
David Blaikie6f7382d2014-08-10 19:08:04 +00003092 /*CaptureDiagnostics=*/true,
3093 /*AllowPCHWithCompilerErrors=*/true,
3094 /*UserFilesAreVolatile=*/true);
3095 *out_TU = MakeCXTranslationUnit(CXXIdx, AU.release());
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003096 return *out_TU ? CXError_Success : CXError_Failure;
Guy Benyei11169dd2012-12-18 14:30:41 +00003097}
3098
3099unsigned clang_defaultEditingTranslationUnitOptions() {
3100 return CXTranslationUnit_PrecompiledPreamble |
3101 CXTranslationUnit_CacheCompletionResults;
3102}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003103
Guy Benyei11169dd2012-12-18 14:30:41 +00003104CXTranslationUnit
3105clang_createTranslationUnitFromSourceFile(CXIndex CIdx,
3106 const char *source_filename,
3107 int num_command_line_args,
3108 const char * const *command_line_args,
3109 unsigned num_unsaved_files,
3110 struct CXUnsavedFile *unsaved_files) {
3111 unsigned Options = CXTranslationUnit_DetailedPreprocessingRecord;
3112 return clang_parseTranslationUnit(CIdx, source_filename,
3113 command_line_args, num_command_line_args,
3114 unsaved_files, num_unsaved_files,
3115 Options);
3116}
3117
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003118static CXErrorCode
3119clang_parseTranslationUnit_Impl(CXIndex CIdx, const char *source_filename,
3120 const char *const *command_line_args,
3121 int num_command_line_args,
3122 ArrayRef<CXUnsavedFile> unsaved_files,
3123 unsigned options, CXTranslationUnit *out_TU) {
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00003124 // Set up the initial return values.
3125 if (out_TU)
Craig Topper69186e72014-06-08 08:38:04 +00003126 *out_TU = nullptr;
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00003127
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003128 // Check arguments.
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003129 if (!CIdx || !out_TU)
3130 return CXError_InvalidArguments;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003131
Guy Benyei11169dd2012-12-18 14:30:41 +00003132 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
3133
3134 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
3135 setThreadBackgroundPriority();
3136
3137 bool PrecompilePreamble = options & CXTranslationUnit_PrecompiledPreamble;
Benjamin Kramer5c248d82015-12-15 09:30:31 +00003138 bool CreatePreambleOnFirstParse =
3139 options & CXTranslationUnit_CreatePreambleOnFirstParse;
Guy Benyei11169dd2012-12-18 14:30:41 +00003140 // FIXME: Add a flag for modules.
3141 TranslationUnitKind TUKind
3142 = (options & CXTranslationUnit_Incomplete)? TU_Prefix : TU_Complete;
Alp Toker8c8a8752013-12-03 06:53:35 +00003143 bool CacheCodeCompletionResults
Guy Benyei11169dd2012-12-18 14:30:41 +00003144 = options & CXTranslationUnit_CacheCompletionResults;
3145 bool IncludeBriefCommentsInCodeCompletion
3146 = options & CXTranslationUnit_IncludeBriefCommentsInCodeCompletion;
3147 bool SkipFunctionBodies = options & CXTranslationUnit_SkipFunctionBodies;
3148 bool ForSerialization = options & CXTranslationUnit_ForSerialization;
3149
3150 // Configure the diagnostics.
3151 IntrusiveRefCntPtr<DiagnosticsEngine>
Sean Silvaf1b49e22013-01-20 01:58:28 +00003152 Diags(CompilerInstance::createDiagnostics(new DiagnosticOptions));
Guy Benyei11169dd2012-12-18 14:30:41 +00003153
Manuel Klimek016c0242016-03-01 10:56:19 +00003154 if (options & CXTranslationUnit_KeepGoing)
3155 Diags->setFatalsAsError(true);
3156
Guy Benyei11169dd2012-12-18 14:30:41 +00003157 // Recover resources if we crash before exiting this function.
3158 llvm::CrashRecoveryContextCleanupRegistrar<DiagnosticsEngine,
3159 llvm::CrashRecoveryContextReleaseRefCleanup<DiagnosticsEngine> >
Alp Tokerf994cef2014-07-05 03:08:06 +00003160 DiagCleanup(Diags.get());
Guy Benyei11169dd2012-12-18 14:30:41 +00003161
Ahmed Charlesb8984322014-03-07 20:03:18 +00003162 std::unique_ptr<std::vector<ASTUnit::RemappedFile>> RemappedFiles(
3163 new std::vector<ASTUnit::RemappedFile>());
Guy Benyei11169dd2012-12-18 14:30:41 +00003164
3165 // Recover resources if we crash before exiting this function.
3166 llvm::CrashRecoveryContextCleanupRegistrar<
3167 std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
3168
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003169 for (auto &UF : unsaved_files) {
Rafael Espindolad87f8d72014-08-27 20:03:29 +00003170 std::unique_ptr<llvm::MemoryBuffer> MB =
Alp Toker9d85b182014-07-07 01:23:14 +00003171 llvm::MemoryBuffer::getMemBufferCopy(getContents(UF), UF.Filename);
Rafael Espindolad87f8d72014-08-27 20:03:29 +00003172 RemappedFiles->push_back(std::make_pair(UF.Filename, MB.release()));
Guy Benyei11169dd2012-12-18 14:30:41 +00003173 }
3174
Ahmed Charlesb8984322014-03-07 20:03:18 +00003175 std::unique_ptr<std::vector<const char *>> Args(
3176 new std::vector<const char *>());
Guy Benyei11169dd2012-12-18 14:30:41 +00003177
3178 // Recover resources if we crash before exiting this method.
3179 llvm::CrashRecoveryContextCleanupRegistrar<std::vector<const char*> >
3180 ArgsCleanup(Args.get());
3181
3182 // Since the Clang C library is primarily used by batch tools dealing with
3183 // (often very broken) source code, where spell-checking can have a
3184 // significant negative impact on performance (particularly when
3185 // precompiled headers are involved), we disable it by default.
3186 // Only do this if we haven't found a spell-checking-related argument.
3187 bool FoundSpellCheckingArgument = false;
3188 for (int I = 0; I != num_command_line_args; ++I) {
3189 if (strcmp(command_line_args[I], "-fno-spell-checking") == 0 ||
3190 strcmp(command_line_args[I], "-fspell-checking") == 0) {
3191 FoundSpellCheckingArgument = true;
3192 break;
3193 }
3194 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003195 Args->insert(Args->end(), command_line_args,
3196 command_line_args + num_command_line_args);
3197
Benjamin Kramerc02670e2015-11-18 16:14:27 +00003198 if (!FoundSpellCheckingArgument)
3199 Args->insert(Args->begin() + 1, "-fno-spell-checking");
3200
Guy Benyei11169dd2012-12-18 14:30:41 +00003201 // The 'source_filename' argument is optional. If the caller does not
3202 // specify it then it is assumed that the source file is specified
3203 // in the actual argument list.
3204 // Put the source file after command_line_args otherwise if '-x' flag is
3205 // present it will be unused.
3206 if (source_filename)
3207 Args->push_back(source_filename);
3208
3209 // Do we need the detailed preprocessing record?
3210 if (options & CXTranslationUnit_DetailedPreprocessingRecord) {
3211 Args->push_back("-Xclang");
3212 Args->push_back("-detailed-preprocessing-record");
3213 }
3214
3215 unsigned NumErrors = Diags->getClient()->getNumErrors();
Ahmed Charlesb8984322014-03-07 20:03:18 +00003216 std::unique_ptr<ASTUnit> ErrUnit;
Benjamin Kramer5c248d82015-12-15 09:30:31 +00003217 // Unless the user specified that they want the preamble on the first parse
3218 // set it up to be created on the first reparse. This makes the first parse
3219 // faster, trading for a slower (first) reparse.
3220 unsigned PrecompilePreambleAfterNParses =
3221 !PrecompilePreamble ? 0 : 2 - CreatePreambleOnFirstParse;
Ahmed Charlesb8984322014-03-07 20:03:18 +00003222 std::unique_ptr<ASTUnit> Unit(ASTUnit::LoadFromCommandLine(
Adrian Prantlbb165fb2015-06-20 18:53:08 +00003223 Args->data(), Args->data() + Args->size(),
3224 CXXIdx->getPCHContainerOperations(), Diags,
Ahmed Charlesb8984322014-03-07 20:03:18 +00003225 CXXIdx->getClangResourcesPath(), CXXIdx->getOnlyLocalDecls(),
3226 /*CaptureDiagnostics=*/true, *RemappedFiles.get(),
Benjamin Kramer5c248d82015-12-15 09:30:31 +00003227 /*RemappedFilesKeepOriginalName=*/true, PrecompilePreambleAfterNParses,
3228 TUKind, CacheCodeCompletionResults, IncludeBriefCommentsInCodeCompletion,
Ahmed Charlesb8984322014-03-07 20:03:18 +00003229 /*AllowPCHWithCompilerErrors=*/true, SkipFunctionBodies,
Argyrios Kyrtzidisa3e2ff12015-11-20 03:36:21 +00003230 /*UserFilesAreVolatile=*/true, ForSerialization,
3231 CXXIdx->getPCHContainerOperations()->getRawReader().getFormat(),
3232 &ErrUnit));
Guy Benyei11169dd2012-12-18 14:30:41 +00003233
Artem Belevich0ff05cd2015-07-13 23:27:56 +00003234 // Early failures in LoadFromCommandLine may return with ErrUnit unset.
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003235 if (!Unit && !ErrUnit)
3236 return CXError_ASTReadError;
Artem Belevich0ff05cd2015-07-13 23:27:56 +00003237
Guy Benyei11169dd2012-12-18 14:30:41 +00003238 if (NumErrors != Diags->getClient()->getNumErrors()) {
3239 // Make sure to check that 'Unit' is non-NULL.
3240 if (CXXIdx->getDisplayDiagnostics())
3241 printDiagsToStderr(Unit ? Unit.get() : ErrUnit.get());
3242 }
3243
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003244 if (isASTReadError(Unit ? Unit.get() : ErrUnit.get()))
3245 return CXError_ASTReadError;
3246
3247 *out_TU = MakeCXTranslationUnit(CXXIdx, Unit.release());
3248 return *out_TU ? CXError_Success : CXError_Failure;
Guy Benyei11169dd2012-12-18 14:30:41 +00003249}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003250
3251CXTranslationUnit
3252clang_parseTranslationUnit(CXIndex CIdx,
3253 const char *source_filename,
3254 const char *const *command_line_args,
3255 int num_command_line_args,
3256 struct CXUnsavedFile *unsaved_files,
3257 unsigned num_unsaved_files,
3258 unsigned options) {
3259 CXTranslationUnit TU;
3260 enum CXErrorCode Result = clang_parseTranslationUnit2(
3261 CIdx, source_filename, command_line_args, num_command_line_args,
3262 unsaved_files, num_unsaved_files, options, &TU);
Reid Kleckner6eaf05a2014-02-13 01:19:59 +00003263 (void)Result;
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00003264 assert((TU && Result == CXError_Success) ||
3265 (!TU && Result != CXError_Success));
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003266 return TU;
3267}
3268
3269enum CXErrorCode clang_parseTranslationUnit2(
Benjamin Kramerc02670e2015-11-18 16:14:27 +00003270 CXIndex CIdx, const char *source_filename,
3271 const char *const *command_line_args, int num_command_line_args,
3272 struct CXUnsavedFile *unsaved_files, unsigned num_unsaved_files,
3273 unsigned options, CXTranslationUnit *out_TU) {
3274 SmallVector<const char *, 4> Args;
3275 Args.push_back("clang");
3276 Args.append(command_line_args, command_line_args + num_command_line_args);
3277 return clang_parseTranslationUnit2FullArgv(
3278 CIdx, source_filename, Args.data(), Args.size(), unsaved_files,
3279 num_unsaved_files, options, out_TU);
3280}
3281
3282enum CXErrorCode clang_parseTranslationUnit2FullArgv(
3283 CXIndex CIdx, const char *source_filename,
3284 const char *const *command_line_args, int num_command_line_args,
3285 struct CXUnsavedFile *unsaved_files, unsigned num_unsaved_files,
3286 unsigned options, CXTranslationUnit *out_TU) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00003287 LOG_FUNC_SECTION {
3288 *Log << source_filename << ": ";
3289 for (int i = 0; i != num_command_line_args; ++i)
3290 *Log << command_line_args[i] << " ";
3291 }
3292
Alp Toker9d85b182014-07-07 01:23:14 +00003293 if (num_unsaved_files && !unsaved_files)
3294 return CXError_InvalidArguments;
3295
Alp Toker5c532982014-07-07 22:42:03 +00003296 CXErrorCode result = CXError_Failure;
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003297 auto ParseTranslationUnitImpl = [=, &result] {
3298 result = clang_parseTranslationUnit_Impl(
3299 CIdx, source_filename, command_line_args, num_command_line_args,
3300 llvm::makeArrayRef(unsaved_files, num_unsaved_files), options, out_TU);
3301 };
Guy Benyei11169dd2012-12-18 14:30:41 +00003302 llvm::CrashRecoveryContext CRC;
3303
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003304 if (!RunSafely(CRC, ParseTranslationUnitImpl)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003305 fprintf(stderr, "libclang: crash detected during parsing: {\n");
3306 fprintf(stderr, " 'source_filename' : '%s'\n", source_filename);
3307 fprintf(stderr, " 'command_line_args' : [");
3308 for (int i = 0; i != num_command_line_args; ++i) {
3309 if (i)
3310 fprintf(stderr, ", ");
3311 fprintf(stderr, "'%s'", command_line_args[i]);
3312 }
3313 fprintf(stderr, "],\n");
3314 fprintf(stderr, " 'unsaved_files' : [");
3315 for (unsigned i = 0; i != num_unsaved_files; ++i) {
3316 if (i)
3317 fprintf(stderr, ", ");
3318 fprintf(stderr, "('%s', '...', %ld)", unsaved_files[i].Filename,
3319 unsaved_files[i].Length);
3320 }
3321 fprintf(stderr, "],\n");
3322 fprintf(stderr, " 'options' : %d,\n", options);
3323 fprintf(stderr, "}\n");
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003324
3325 return CXError_Crashed;
Guy Benyei11169dd2012-12-18 14:30:41 +00003326 } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003327 if (CXTranslationUnit *TU = out_TU)
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003328 PrintLibclangResourceUsage(*TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003329 }
Alp Toker5c532982014-07-07 22:42:03 +00003330
3331 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003332}
3333
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003334CXString clang_Type_getObjCEncoding(CXType CT) {
3335 CXTranslationUnit tu = static_cast<CXTranslationUnit>(CT.data[1]);
3336 ASTContext &Ctx = getASTUnit(tu)->getASTContext();
3337 std::string encoding;
3338 Ctx.getObjCEncodingForType(QualType::getFromOpaquePtr(CT.data[0]),
3339 encoding);
3340
3341 return cxstring::createDup(encoding);
3342}
3343
3344static const IdentifierInfo *getMacroIdentifier(CXCursor C) {
3345 if (C.kind == CXCursor_MacroDefinition) {
3346 if (const MacroDefinitionRecord *MDR = getCursorMacroDefinition(C))
3347 return MDR->getName();
3348 } else if (C.kind == CXCursor_MacroExpansion) {
3349 MacroExpansionCursor ME = getCursorMacroExpansion(C);
3350 return ME.getName();
3351 }
3352 return nullptr;
3353}
3354
3355unsigned clang_Cursor_isMacroFunctionLike(CXCursor C) {
3356 const IdentifierInfo *II = getMacroIdentifier(C);
3357 if (!II) {
3358 return false;
3359 }
3360 ASTUnit *ASTU = getCursorASTUnit(C);
3361 Preprocessor &PP = ASTU->getPreprocessor();
3362 if (const MacroInfo *MI = PP.getMacroInfo(II))
3363 return MI->isFunctionLike();
3364 return false;
3365}
3366
3367unsigned clang_Cursor_isMacroBuiltin(CXCursor C) {
3368 const IdentifierInfo *II = getMacroIdentifier(C);
3369 if (!II) {
3370 return false;
3371 }
3372 ASTUnit *ASTU = getCursorASTUnit(C);
3373 Preprocessor &PP = ASTU->getPreprocessor();
3374 if (const MacroInfo *MI = PP.getMacroInfo(II))
3375 return MI->isBuiltinMacro();
3376 return false;
3377}
3378
3379unsigned clang_Cursor_isFunctionInlined(CXCursor C) {
3380 const Decl *D = getCursorDecl(C);
3381 const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(D);
3382 if (!FD) {
3383 return false;
3384 }
3385 return FD->isInlined();
3386}
3387
3388static StringLiteral* getCFSTR_value(CallExpr *callExpr) {
3389 if (callExpr->getNumArgs() != 1) {
3390 return nullptr;
3391 }
3392
3393 StringLiteral *S = nullptr;
3394 auto *arg = callExpr->getArg(0);
3395 if (arg->getStmtClass() == Stmt::ImplicitCastExprClass) {
3396 ImplicitCastExpr *I = static_cast<ImplicitCastExpr *>(arg);
3397 auto *subExpr = I->getSubExprAsWritten();
3398
3399 if(subExpr->getStmtClass() != Stmt::StringLiteralClass){
3400 return nullptr;
3401 }
3402
3403 S = static_cast<StringLiteral *>(I->getSubExprAsWritten());
3404 } else if (arg->getStmtClass() == Stmt::StringLiteralClass) {
3405 S = static_cast<StringLiteral *>(callExpr->getArg(0));
3406 } else {
3407 return nullptr;
3408 }
3409 return S;
3410}
3411
David Blaikie59272572016-04-13 18:23:33 +00003412struct ExprEvalResult {
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003413 CXEvalResultKind EvalType;
3414 union {
3415 int intVal;
3416 double floatVal;
3417 char *stringVal;
3418 } EvalData;
David Blaikie59272572016-04-13 18:23:33 +00003419 ~ExprEvalResult() {
3420 if (EvalType != CXEval_UnExposed && EvalType != CXEval_Float &&
3421 EvalType != CXEval_Int) {
3422 delete EvalData.stringVal;
3423 }
3424 }
3425};
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003426
3427void clang_EvalResult_dispose(CXEvalResult E) {
David Blaikie59272572016-04-13 18:23:33 +00003428 delete static_cast<ExprEvalResult *>(E);
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003429}
3430
3431CXEvalResultKind clang_EvalResult_getKind(CXEvalResult E) {
3432 if (!E) {
3433 return CXEval_UnExposed;
3434 }
3435 return ((ExprEvalResult *)E)->EvalType;
3436}
3437
3438int clang_EvalResult_getAsInt(CXEvalResult E) {
3439 if (!E) {
3440 return 0;
3441 }
3442 return ((ExprEvalResult *)E)->EvalData.intVal;
3443}
3444
3445double clang_EvalResult_getAsDouble(CXEvalResult E) {
3446 if (!E) {
3447 return 0;
3448 }
3449 return ((ExprEvalResult *)E)->EvalData.floatVal;
3450}
3451
3452const char* clang_EvalResult_getAsStr(CXEvalResult E) {
3453 if (!E) {
3454 return nullptr;
3455 }
3456 return ((ExprEvalResult *)E)->EvalData.stringVal;
3457}
3458
3459static const ExprEvalResult* evaluateExpr(Expr *expr, CXCursor C) {
3460 Expr::EvalResult ER;
3461 ASTContext &ctx = getCursorContext(C);
David Blaikiebbc00882016-04-13 18:36:19 +00003462 if (!expr)
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003463 return nullptr;
David Blaikiebbc00882016-04-13 18:36:19 +00003464
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003465 expr = expr->IgnoreParens();
David Blaikiebbc00882016-04-13 18:36:19 +00003466 if (!expr->EvaluateAsRValue(ER, ctx))
3467 return nullptr;
3468
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003469 QualType rettype;
3470 CallExpr *callExpr;
David Blaikie59272572016-04-13 18:23:33 +00003471 auto result = llvm::make_unique<ExprEvalResult>();
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003472 result->EvalType = CXEval_UnExposed;
3473
David Blaikiebbc00882016-04-13 18:36:19 +00003474 if (ER.Val.isInt()) {
3475 result->EvalType = CXEval_Int;
3476 result->EvalData.intVal = ER.Val.getInt().getExtValue();
3477 return result.release();
3478 }
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003479
David Blaikiebbc00882016-04-13 18:36:19 +00003480 if (ER.Val.isFloat()) {
3481 llvm::SmallVector<char, 100> Buffer;
3482 ER.Val.getFloat().toString(Buffer);
3483 std::string floatStr(Buffer.data(), Buffer.size());
3484 result->EvalType = CXEval_Float;
3485 bool ignored;
3486 llvm::APFloat apFloat = ER.Val.getFloat();
3487 apFloat.convert(llvm::APFloat::IEEEdouble,
3488 llvm::APFloat::rmNearestTiesToEven, &ignored);
3489 result->EvalData.floatVal = apFloat.convertToDouble();
3490 return result.release();
3491 }
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003492
David Blaikiebbc00882016-04-13 18:36:19 +00003493 if (expr->getStmtClass() == Stmt::ImplicitCastExprClass) {
3494 const ImplicitCastExpr *I = dyn_cast<ImplicitCastExpr>(expr);
3495 auto *subExpr = I->getSubExprAsWritten();
3496 if (subExpr->getStmtClass() == Stmt::StringLiteralClass ||
3497 subExpr->getStmtClass() == Stmt::ObjCStringLiteralClass) {
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003498 const StringLiteral *StrE = nullptr;
3499 const ObjCStringLiteral *ObjCExpr;
David Blaikiebbc00882016-04-13 18:36:19 +00003500 ObjCExpr = dyn_cast<ObjCStringLiteral>(subExpr);
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003501
3502 if (ObjCExpr) {
3503 StrE = ObjCExpr->getString();
3504 result->EvalType = CXEval_ObjCStrLiteral;
3505 } else {
David Blaikiebbc00882016-04-13 18:36:19 +00003506 StrE = cast<StringLiteral>(I->getSubExprAsWritten());
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003507 result->EvalType = CXEval_StrLiteral;
3508 }
3509
3510 std::string strRef(StrE->getString().str());
David Blaikie59272572016-04-13 18:23:33 +00003511 result->EvalData.stringVal = new char[strRef.size() + 1];
David Blaikiebbc00882016-04-13 18:36:19 +00003512 strncpy((char *)result->EvalData.stringVal, strRef.c_str(),
3513 strRef.size());
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003514 result->EvalData.stringVal[strRef.size()] = '\0';
David Blaikie59272572016-04-13 18:23:33 +00003515 return result.release();
David Blaikiebbc00882016-04-13 18:36:19 +00003516 }
3517 } else if (expr->getStmtClass() == Stmt::ObjCStringLiteralClass ||
3518 expr->getStmtClass() == Stmt::StringLiteralClass) {
3519 const StringLiteral *StrE = nullptr;
3520 const ObjCStringLiteral *ObjCExpr;
3521 ObjCExpr = dyn_cast<ObjCStringLiteral>(expr);
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003522
David Blaikiebbc00882016-04-13 18:36:19 +00003523 if (ObjCExpr) {
3524 StrE = ObjCExpr->getString();
3525 result->EvalType = CXEval_ObjCStrLiteral;
3526 } else {
3527 StrE = cast<StringLiteral>(expr);
3528 result->EvalType = CXEval_StrLiteral;
3529 }
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003530
David Blaikiebbc00882016-04-13 18:36:19 +00003531 std::string strRef(StrE->getString().str());
3532 result->EvalData.stringVal = new char[strRef.size() + 1];
3533 strncpy((char *)result->EvalData.stringVal, strRef.c_str(), strRef.size());
3534 result->EvalData.stringVal[strRef.size()] = '\0';
3535 return result.release();
3536 }
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003537
David Blaikiebbc00882016-04-13 18:36:19 +00003538 if (expr->getStmtClass() == Stmt::CStyleCastExprClass) {
3539 CStyleCastExpr *CC = static_cast<CStyleCastExpr *>(expr);
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003540
David Blaikiebbc00882016-04-13 18:36:19 +00003541 rettype = CC->getType();
3542 if (rettype.getAsString() == "CFStringRef" &&
3543 CC->getSubExpr()->getStmtClass() == Stmt::CallExprClass) {
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003544
David Blaikiebbc00882016-04-13 18:36:19 +00003545 callExpr = static_cast<CallExpr *>(CC->getSubExpr());
3546 StringLiteral *S = getCFSTR_value(callExpr);
3547 if (S) {
3548 std::string strLiteral(S->getString().str());
3549 result->EvalType = CXEval_CFStr;
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003550
David Blaikiebbc00882016-04-13 18:36:19 +00003551 result->EvalData.stringVal = new char[strLiteral.size() + 1];
3552 strncpy((char *)result->EvalData.stringVal, strLiteral.c_str(),
3553 strLiteral.size());
3554 result->EvalData.stringVal[strLiteral.size()] = '\0';
David Blaikie59272572016-04-13 18:23:33 +00003555 return result.release();
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003556 }
3557 }
3558
David Blaikiebbc00882016-04-13 18:36:19 +00003559 } else if (expr->getStmtClass() == Stmt::CallExprClass) {
3560 callExpr = static_cast<CallExpr *>(expr);
3561 rettype = callExpr->getCallReturnType(ctx);
3562
3563 if (rettype->isVectorType() || callExpr->getNumArgs() > 1)
3564 return nullptr;
3565
3566 if (rettype->isIntegralType(ctx) || rettype->isRealFloatingType()) {
3567 if (callExpr->getNumArgs() == 1 &&
3568 !callExpr->getArg(0)->getType()->isIntegralType(ctx))
3569 return nullptr;
3570 } else if (rettype.getAsString() == "CFStringRef") {
3571
3572 StringLiteral *S = getCFSTR_value(callExpr);
3573 if (S) {
3574 std::string strLiteral(S->getString().str());
3575 result->EvalType = CXEval_CFStr;
3576 result->EvalData.stringVal = new char[strLiteral.size() + 1];
3577 strncpy((char *)result->EvalData.stringVal, strLiteral.c_str(),
3578 strLiteral.size());
3579 result->EvalData.stringVal[strLiteral.size()] = '\0';
3580 return result.release();
3581 }
3582 }
3583 } else if (expr->getStmtClass() == Stmt::DeclRefExprClass) {
3584 DeclRefExpr *D = static_cast<DeclRefExpr *>(expr);
3585 ValueDecl *V = D->getDecl();
3586 if (V->getKind() == Decl::Function) {
3587 std::string strName = V->getNameAsString();
3588 result->EvalType = CXEval_Other;
3589 result->EvalData.stringVal = new char[strName.size() + 1];
3590 strncpy(result->EvalData.stringVal, strName.c_str(), strName.size());
3591 result->EvalData.stringVal[strName.size()] = '\0';
3592 return result.release();
3593 }
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003594 }
3595
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003596 return nullptr;
3597}
3598
3599CXEvalResult clang_Cursor_Evaluate(CXCursor C) {
3600 const Decl *D = getCursorDecl(C);
3601 if (D) {
3602 const Expr *expr = nullptr;
3603 if (auto *Var = dyn_cast<VarDecl>(D)) {
3604 expr = Var->getInit();
3605 } else if (auto *Field = dyn_cast<FieldDecl>(D)) {
3606 expr = Field->getInClassInitializer();
3607 }
3608 if (expr)
Aaron Ballman01dc1572016-01-20 15:25:30 +00003609 return const_cast<CXEvalResult>(reinterpret_cast<const void *>(
3610 evaluateExpr(const_cast<Expr *>(expr), C)));
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003611 return nullptr;
3612 }
3613
3614 const CompoundStmt *compoundStmt = dyn_cast_or_null<CompoundStmt>(getCursorStmt(C));
3615 if (compoundStmt) {
3616 Expr *expr = nullptr;
3617 for (auto *bodyIterator : compoundStmt->body()) {
3618 if ((expr = dyn_cast<Expr>(bodyIterator))) {
3619 break;
3620 }
3621 }
3622 if (expr)
Aaron Ballman01dc1572016-01-20 15:25:30 +00003623 return const_cast<CXEvalResult>(
3624 reinterpret_cast<const void *>(evaluateExpr(expr, C)));
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003625 }
3626 return nullptr;
3627}
3628
3629unsigned clang_Cursor_hasAttrs(CXCursor C) {
3630 const Decl *D = getCursorDecl(C);
3631 if (!D) {
3632 return 0;
3633 }
3634
3635 if (D->hasAttrs()) {
3636 return 1;
3637 }
3638
3639 return 0;
3640}
Guy Benyei11169dd2012-12-18 14:30:41 +00003641unsigned clang_defaultSaveOptions(CXTranslationUnit TU) {
3642 return CXSaveTranslationUnit_None;
3643}
3644
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003645static CXSaveError clang_saveTranslationUnit_Impl(CXTranslationUnit TU,
3646 const char *FileName,
3647 unsigned options) {
3648 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00003649 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
3650 setThreadBackgroundPriority();
3651
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003652 bool hadError = cxtu::getASTUnit(TU)->Save(FileName);
3653 return hadError ? CXSaveError_Unknown : CXSaveError_None;
Guy Benyei11169dd2012-12-18 14:30:41 +00003654}
3655
3656int clang_saveTranslationUnit(CXTranslationUnit TU, const char *FileName,
3657 unsigned options) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00003658 LOG_FUNC_SECTION {
3659 *Log << TU << ' ' << FileName;
3660 }
3661
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003662 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003663 LOG_BAD_TU(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003664 return CXSaveError_InvalidTU;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003665 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003666
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003667 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003668 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
3669 if (!CXXUnit->hasSema())
3670 return CXSaveError_InvalidTU;
3671
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003672 CXSaveError result;
3673 auto SaveTranslationUnitImpl = [=, &result]() {
3674 result = clang_saveTranslationUnit_Impl(TU, FileName, options);
3675 };
Guy Benyei11169dd2012-12-18 14:30:41 +00003676
3677 if (!CXXUnit->getDiagnostics().hasUnrecoverableErrorOccurred() ||
3678 getenv("LIBCLANG_NOTHREADS")) {
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003679 SaveTranslationUnitImpl();
Guy Benyei11169dd2012-12-18 14:30:41 +00003680
3681 if (getenv("LIBCLANG_RESOURCE_USAGE"))
3682 PrintLibclangResourceUsage(TU);
3683
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003684 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003685 }
3686
3687 // We have an AST that has invalid nodes due to compiler errors.
3688 // Use a crash recovery thread for protection.
3689
3690 llvm::CrashRecoveryContext CRC;
3691
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003692 if (!RunSafely(CRC, SaveTranslationUnitImpl)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003693 fprintf(stderr, "libclang: crash detected during AST saving: {\n");
3694 fprintf(stderr, " 'filename' : '%s'\n", FileName);
3695 fprintf(stderr, " 'options' : %d,\n", options);
3696 fprintf(stderr, "}\n");
3697
3698 return CXSaveError_Unknown;
3699
3700 } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
3701 PrintLibclangResourceUsage(TU);
3702 }
3703
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003704 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003705}
3706
3707void clang_disposeTranslationUnit(CXTranslationUnit CTUnit) {
3708 if (CTUnit) {
3709 // If the translation unit has been marked as unsafe to free, just discard
3710 // it.
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003711 ASTUnit *Unit = cxtu::getASTUnit(CTUnit);
3712 if (Unit && Unit->isUnsafeToFree())
Guy Benyei11169dd2012-12-18 14:30:41 +00003713 return;
3714
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003715 delete cxtu::getASTUnit(CTUnit);
Dmitri Gribenkob95b3f12013-01-26 22:44:19 +00003716 delete CTUnit->StringPool;
Guy Benyei11169dd2012-12-18 14:30:41 +00003717 delete static_cast<CXDiagnosticSetImpl *>(CTUnit->Diagnostics);
3718 disposeOverridenCXCursorsPool(CTUnit->OverridenCursorsPool);
Dmitri Gribenko9e605112013-11-13 22:16:51 +00003719 delete CTUnit->CommentToXML;
Guy Benyei11169dd2012-12-18 14:30:41 +00003720 delete CTUnit;
3721 }
3722}
3723
3724unsigned clang_defaultReparseOptions(CXTranslationUnit TU) {
3725 return CXReparse_None;
3726}
3727
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003728static CXErrorCode
3729clang_reparseTranslationUnit_Impl(CXTranslationUnit TU,
3730 ArrayRef<CXUnsavedFile> unsaved_files,
3731 unsigned options) {
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003732 // Check arguments.
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003733 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003734 LOG_BAD_TU(TU);
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003735 return CXError_InvalidArguments;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003736 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003737
3738 // Reset the associated diagnostics.
3739 delete static_cast<CXDiagnosticSetImpl*>(TU->Diagnostics);
Craig Topper69186e72014-06-08 08:38:04 +00003740 TU->Diagnostics = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00003741
Dmitri Gribenko183436e2013-01-26 21:49:50 +00003742 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00003743 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
3744 setThreadBackgroundPriority();
3745
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003746 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003747 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
Ahmed Charlesb8984322014-03-07 20:03:18 +00003748
3749 std::unique_ptr<std::vector<ASTUnit::RemappedFile>> RemappedFiles(
3750 new std::vector<ASTUnit::RemappedFile>());
3751
Guy Benyei11169dd2012-12-18 14:30:41 +00003752 // Recover resources if we crash before exiting this function.
3753 llvm::CrashRecoveryContextCleanupRegistrar<
3754 std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
Alp Toker9d85b182014-07-07 01:23:14 +00003755
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003756 for (auto &UF : unsaved_files) {
Rafael Espindolad87f8d72014-08-27 20:03:29 +00003757 std::unique_ptr<llvm::MemoryBuffer> MB =
Alp Toker9d85b182014-07-07 01:23:14 +00003758 llvm::MemoryBuffer::getMemBufferCopy(getContents(UF), UF.Filename);
Rafael Espindolad87f8d72014-08-27 20:03:29 +00003759 RemappedFiles->push_back(std::make_pair(UF.Filename, MB.release()));
Guy Benyei11169dd2012-12-18 14:30:41 +00003760 }
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003761
Adrian Prantlbb165fb2015-06-20 18:53:08 +00003762 if (!CXXUnit->Reparse(CXXIdx->getPCHContainerOperations(),
3763 *RemappedFiles.get()))
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003764 return CXError_Success;
3765 if (isASTReadError(CXXUnit))
3766 return CXError_ASTReadError;
3767 return CXError_Failure;
Guy Benyei11169dd2012-12-18 14:30:41 +00003768}
3769
3770int clang_reparseTranslationUnit(CXTranslationUnit TU,
3771 unsigned num_unsaved_files,
3772 struct CXUnsavedFile *unsaved_files,
3773 unsigned options) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00003774 LOG_FUNC_SECTION {
3775 *Log << TU;
3776 }
3777
Alp Toker9d85b182014-07-07 01:23:14 +00003778 if (num_unsaved_files && !unsaved_files)
3779 return CXError_InvalidArguments;
3780
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003781 CXErrorCode result;
3782 auto ReparseTranslationUnitImpl = [=, &result]() {
3783 result = clang_reparseTranslationUnit_Impl(
3784 TU, llvm::makeArrayRef(unsaved_files, num_unsaved_files), options);
3785 };
Guy Benyei11169dd2012-12-18 14:30:41 +00003786
3787 if (getenv("LIBCLANG_NOTHREADS")) {
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003788 ReparseTranslationUnitImpl();
Alp Toker5c532982014-07-07 22:42:03 +00003789 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003790 }
3791
3792 llvm::CrashRecoveryContext CRC;
3793
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003794 if (!RunSafely(CRC, ReparseTranslationUnitImpl)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003795 fprintf(stderr, "libclang: crash detected during reparsing\n");
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003796 cxtu::getASTUnit(TU)->setUnsafeToFree(true);
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003797 return CXError_Crashed;
Guy Benyei11169dd2012-12-18 14:30:41 +00003798 } else if (getenv("LIBCLANG_RESOURCE_USAGE"))
3799 PrintLibclangResourceUsage(TU);
3800
Alp Toker5c532982014-07-07 22:42:03 +00003801 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003802}
3803
3804
3805CXString clang_getTranslationUnitSpelling(CXTranslationUnit CTUnit) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003806 if (isNotUsableTU(CTUnit)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003807 LOG_BAD_TU(CTUnit);
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003808 return cxstring::createEmpty();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003809 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003810
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003811 ASTUnit *CXXUnit = cxtu::getASTUnit(CTUnit);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003812 return cxstring::createDup(CXXUnit->getOriginalSourceFileName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003813}
3814
3815CXCursor clang_getTranslationUnitCursor(CXTranslationUnit TU) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003816 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003817 LOG_BAD_TU(TU);
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00003818 return clang_getNullCursor();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003819 }
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00003820
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003821 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003822 return MakeCXCursor(CXXUnit->getASTContext().getTranslationUnitDecl(), TU);
3823}
3824
3825} // end: extern "C"
3826
3827//===----------------------------------------------------------------------===//
3828// CXFile Operations.
3829//===----------------------------------------------------------------------===//
3830
3831extern "C" {
3832CXString clang_getFileName(CXFile SFile) {
3833 if (!SFile)
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00003834 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00003835
3836 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003837 return cxstring::createRef(FEnt->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003838}
3839
3840time_t clang_getFileTime(CXFile SFile) {
3841 if (!SFile)
3842 return 0;
3843
3844 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
3845 return FEnt->getModificationTime();
3846}
3847
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003848CXFile clang_getFile(CXTranslationUnit TU, const char *file_name) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003849 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003850 LOG_BAD_TU(TU);
Craig Topper69186e72014-06-08 08:38:04 +00003851 return nullptr;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003852 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003853
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003854 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003855
3856 FileManager &FMgr = CXXUnit->getFileManager();
3857 return const_cast<FileEntry *>(FMgr.getFile(file_name));
3858}
3859
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003860unsigned clang_isFileMultipleIncludeGuarded(CXTranslationUnit TU,
3861 CXFile file) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003862 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003863 LOG_BAD_TU(TU);
3864 return 0;
3865 }
3866
3867 if (!file)
Guy Benyei11169dd2012-12-18 14:30:41 +00003868 return 0;
3869
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003870 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003871 FileEntry *FEnt = static_cast<FileEntry *>(file);
3872 return CXXUnit->getPreprocessor().getHeaderSearchInfo()
3873 .isFileMultipleIncludeGuarded(FEnt);
3874}
3875
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003876int clang_getFileUniqueID(CXFile file, CXFileUniqueID *outID) {
3877 if (!file || !outID)
3878 return 1;
3879
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003880 FileEntry *FEnt = static_cast<FileEntry *>(file);
Rafael Espindolaf8f91b82013-08-01 21:42:11 +00003881 const llvm::sys::fs::UniqueID &ID = FEnt->getUniqueID();
3882 outID->data[0] = ID.getDevice();
3883 outID->data[1] = ID.getFile();
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003884 outID->data[2] = FEnt->getModificationTime();
3885 return 0;
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003886}
3887
Argyrios Kyrtzidisac3997e2014-08-16 00:26:19 +00003888int clang_File_isEqual(CXFile file1, CXFile file2) {
3889 if (file1 == file2)
3890 return true;
3891
3892 if (!file1 || !file2)
3893 return false;
3894
3895 FileEntry *FEnt1 = static_cast<FileEntry *>(file1);
3896 FileEntry *FEnt2 = static_cast<FileEntry *>(file2);
3897 return FEnt1->getUniqueID() == FEnt2->getUniqueID();
3898}
3899
Guy Benyei11169dd2012-12-18 14:30:41 +00003900} // end: extern "C"
3901
3902//===----------------------------------------------------------------------===//
3903// CXCursor Operations.
3904//===----------------------------------------------------------------------===//
3905
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003906static const Decl *getDeclFromExpr(const Stmt *E) {
3907 if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003908 return getDeclFromExpr(CE->getSubExpr());
3909
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003910 if (const DeclRefExpr *RefExpr = dyn_cast<DeclRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003911 return RefExpr->getDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003912 if (const MemberExpr *ME = dyn_cast<MemberExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003913 return ME->getMemberDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003914 if (const ObjCIvarRefExpr *RE = dyn_cast<ObjCIvarRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003915 return RE->getDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003916 if (const ObjCPropertyRefExpr *PRE = dyn_cast<ObjCPropertyRefExpr>(E)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003917 if (PRE->isExplicitProperty())
3918 return PRE->getExplicitProperty();
3919 // It could be messaging both getter and setter as in:
3920 // ++myobj.myprop;
3921 // in which case prefer to associate the setter since it is less obvious
3922 // from inspecting the source that the setter is going to get called.
3923 if (PRE->isMessagingSetter())
3924 return PRE->getImplicitPropertySetter();
3925 return PRE->getImplicitPropertyGetter();
3926 }
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003927 if (const PseudoObjectExpr *POE = dyn_cast<PseudoObjectExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003928 return getDeclFromExpr(POE->getSyntacticForm());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003929 if (const OpaqueValueExpr *OVE = dyn_cast<OpaqueValueExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003930 if (Expr *Src = OVE->getSourceExpr())
3931 return getDeclFromExpr(Src);
3932
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003933 if (const CallExpr *CE = dyn_cast<CallExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003934 return getDeclFromExpr(CE->getCallee());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003935 if (const CXXConstructExpr *CE = dyn_cast<CXXConstructExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003936 if (!CE->isElidable())
3937 return CE->getConstructor();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003938 if (const ObjCMessageExpr *OME = dyn_cast<ObjCMessageExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003939 return OME->getMethodDecl();
3940
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003941 if (const ObjCProtocolExpr *PE = dyn_cast<ObjCProtocolExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003942 return PE->getProtocol();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003943 if (const SubstNonTypeTemplateParmPackExpr *NTTP
Guy Benyei11169dd2012-12-18 14:30:41 +00003944 = dyn_cast<SubstNonTypeTemplateParmPackExpr>(E))
3945 return NTTP->getParameterPack();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003946 if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003947 if (isa<NonTypeTemplateParmDecl>(SizeOfPack->getPack()) ||
3948 isa<ParmVarDecl>(SizeOfPack->getPack()))
3949 return SizeOfPack->getPack();
Craig Topper69186e72014-06-08 08:38:04 +00003950
3951 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00003952}
3953
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003954static SourceLocation getLocationFromExpr(const Expr *E) {
3955 if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003956 return getLocationFromExpr(CE->getSubExpr());
3957
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003958 if (const ObjCMessageExpr *Msg = dyn_cast<ObjCMessageExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003959 return /*FIXME:*/Msg->getLeftLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003960 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003961 return DRE->getLocation();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003962 if (const MemberExpr *Member = dyn_cast<MemberExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003963 return Member->getMemberLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003964 if (const ObjCIvarRefExpr *Ivar = dyn_cast<ObjCIvarRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003965 return Ivar->getLocation();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003966 if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003967 return SizeOfPack->getPackLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003968 if (const ObjCPropertyRefExpr *PropRef = dyn_cast<ObjCPropertyRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003969 return PropRef->getLocation();
3970
3971 return E->getLocStart();
3972}
3973
3974extern "C" {
3975
3976unsigned clang_visitChildren(CXCursor parent,
3977 CXCursorVisitor visitor,
3978 CXClientData client_data) {
3979 CursorVisitor CursorVis(getCursorTU(parent), visitor, client_data,
3980 /*VisitPreprocessorLast=*/false);
3981 return CursorVis.VisitChildren(parent);
3982}
3983
3984#ifndef __has_feature
3985#define __has_feature(x) 0
3986#endif
3987#if __has_feature(blocks)
3988typedef enum CXChildVisitResult
3989 (^CXCursorVisitorBlock)(CXCursor cursor, CXCursor parent);
3990
3991static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
3992 CXClientData client_data) {
3993 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
3994 return block(cursor, parent);
3995}
3996#else
3997// If we are compiled with a compiler that doesn't have native blocks support,
3998// define and call the block manually, so the
3999typedef struct _CXChildVisitResult
4000{
4001 void *isa;
4002 int flags;
4003 int reserved;
4004 enum CXChildVisitResult(*invoke)(struct _CXChildVisitResult*, CXCursor,
4005 CXCursor);
4006} *CXCursorVisitorBlock;
4007
4008static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
4009 CXClientData client_data) {
4010 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
4011 return block->invoke(block, cursor, parent);
4012}
4013#endif
4014
4015
4016unsigned clang_visitChildrenWithBlock(CXCursor parent,
4017 CXCursorVisitorBlock block) {
4018 return clang_visitChildren(parent, visitWithBlock, block);
4019}
4020
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004021static CXString getDeclSpelling(const Decl *D) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004022 if (!D)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00004023 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00004024
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004025 const NamedDecl *ND = dyn_cast<NamedDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00004026 if (!ND) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004027 if (const ObjCPropertyImplDecl *PropImpl =
4028 dyn_cast<ObjCPropertyImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004029 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004030 return cxstring::createDup(Property->getIdentifier()->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00004031
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004032 if (const ImportDecl *ImportD = dyn_cast<ImportDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004033 if (Module *Mod = ImportD->getImportedModule())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004034 return cxstring::createDup(Mod->getFullModuleName());
Guy Benyei11169dd2012-12-18 14:30:41 +00004035
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00004036 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00004037 }
4038
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004039 if (const ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(ND))
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004040 return cxstring::createDup(OMD->getSelector().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00004041
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004042 if (const ObjCCategoryImplDecl *CIMP = dyn_cast<ObjCCategoryImplDecl>(ND))
Guy Benyei11169dd2012-12-18 14:30:41 +00004043 // No, this isn't the same as the code below. getIdentifier() is non-virtual
4044 // and returns different names. NamedDecl returns the class name and
4045 // ObjCCategoryImplDecl returns the category name.
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004046 return cxstring::createRef(CIMP->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00004047
4048 if (isa<UsingDirectiveDecl>(D))
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00004049 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00004050
4051 SmallString<1024> S;
4052 llvm::raw_svector_ostream os(S);
4053 ND->printName(os);
4054
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004055 return cxstring::createDup(os.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00004056}
4057
4058CXString clang_getCursorSpelling(CXCursor C) {
4059 if (clang_isTranslationUnit(C.kind))
Dmitri Gribenko2c173b42013-01-11 19:28:44 +00004060 return clang_getTranslationUnitSpelling(getCursorTU(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00004061
4062 if (clang_isReference(C.kind)) {
4063 switch (C.kind) {
4064 case CXCursor_ObjCSuperClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004065 const ObjCInterfaceDecl *Super = getCursorObjCSuperClassRef(C).first;
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004066 return cxstring::createRef(Super->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00004067 }
4068 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004069 const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004070 return cxstring::createRef(Class->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00004071 }
4072 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004073 const ObjCProtocolDecl *OID = getCursorObjCProtocolRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00004074 assert(OID && "getCursorSpelling(): Missing protocol decl");
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004075 return cxstring::createRef(OID->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00004076 }
4077 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004078 const CXXBaseSpecifier *B = getCursorCXXBaseSpecifier(C);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004079 return cxstring::createDup(B->getType().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00004080 }
4081 case CXCursor_TypeRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004082 const TypeDecl *Type = getCursorTypeRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00004083 assert(Type && "Missing type decl");
4084
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004085 return cxstring::createDup(getCursorContext(C).getTypeDeclType(Type).
Guy Benyei11169dd2012-12-18 14:30:41 +00004086 getAsString());
4087 }
4088 case CXCursor_TemplateRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004089 const TemplateDecl *Template = getCursorTemplateRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00004090 assert(Template && "Missing template decl");
4091
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004092 return cxstring::createDup(Template->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00004093 }
4094
4095 case CXCursor_NamespaceRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004096 const NamedDecl *NS = getCursorNamespaceRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00004097 assert(NS && "Missing namespace decl");
4098
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004099 return cxstring::createDup(NS->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00004100 }
4101
4102 case CXCursor_MemberRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004103 const FieldDecl *Field = getCursorMemberRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00004104 assert(Field && "Missing member decl");
4105
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004106 return cxstring::createDup(Field->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00004107 }
4108
4109 case CXCursor_LabelRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004110 const LabelStmt *Label = getCursorLabelRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00004111 assert(Label && "Missing label");
4112
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004113 return cxstring::createRef(Label->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00004114 }
4115
4116 case CXCursor_OverloadedDeclRef: {
4117 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004118 if (const Decl *D = Storage.dyn_cast<const Decl *>()) {
4119 if (const NamedDecl *ND = dyn_cast<NamedDecl>(D))
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004120 return cxstring::createDup(ND->getNameAsString());
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00004121 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00004122 }
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004123 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004124 return cxstring::createDup(E->getName().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00004125 OverloadedTemplateStorage *Ovl
4126 = Storage.get<OverloadedTemplateStorage*>();
4127 if (Ovl->size() == 0)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00004128 return cxstring::createEmpty();
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004129 return cxstring::createDup((*Ovl->begin())->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00004130 }
4131
4132 case CXCursor_VariableRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004133 const VarDecl *Var = getCursorVariableRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00004134 assert(Var && "Missing variable decl");
4135
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004136 return cxstring::createDup(Var->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00004137 }
4138
4139 default:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004140 return cxstring::createRef("<not implemented>");
Guy Benyei11169dd2012-12-18 14:30:41 +00004141 }
4142 }
4143
4144 if (clang_isExpression(C.kind)) {
Argyrios Kyrtzidis3227d862014-03-03 19:40:52 +00004145 const Expr *E = getCursorExpr(C);
4146
4147 if (C.kind == CXCursor_ObjCStringLiteral ||
4148 C.kind == CXCursor_StringLiteral) {
4149 const StringLiteral *SLit;
4150 if (const ObjCStringLiteral *OSL = dyn_cast<ObjCStringLiteral>(E)) {
4151 SLit = OSL->getString();
4152 } else {
4153 SLit = cast<StringLiteral>(E);
4154 }
4155 SmallString<256> Buf;
4156 llvm::raw_svector_ostream OS(Buf);
4157 SLit->outputString(OS);
4158 return cxstring::createDup(OS.str());
4159 }
4160
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004161 const Decl *D = getDeclFromExpr(getCursorExpr(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00004162 if (D)
4163 return getDeclSpelling(D);
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00004164 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00004165 }
4166
4167 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004168 const Stmt *S = getCursorStmt(C);
4169 if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S))
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004170 return cxstring::createRef(Label->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00004171
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00004172 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00004173 }
4174
4175 if (C.kind == CXCursor_MacroExpansion)
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004176 return cxstring::createRef(getCursorMacroExpansion(C).getName()
Guy Benyei11169dd2012-12-18 14:30:41 +00004177 ->getNameStart());
4178
4179 if (C.kind == CXCursor_MacroDefinition)
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004180 return cxstring::createRef(getCursorMacroDefinition(C)->getName()
Guy Benyei11169dd2012-12-18 14:30:41 +00004181 ->getNameStart());
4182
4183 if (C.kind == CXCursor_InclusionDirective)
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004184 return cxstring::createDup(getCursorInclusionDirective(C)->getFileName());
Guy Benyei11169dd2012-12-18 14:30:41 +00004185
4186 if (clang_isDeclaration(C.kind))
4187 return getDeclSpelling(getCursorDecl(C));
4188
4189 if (C.kind == CXCursor_AnnotateAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00004190 const AnnotateAttr *AA = cast<AnnotateAttr>(cxcursor::getCursorAttr(C));
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004191 return cxstring::createDup(AA->getAnnotation());
Guy Benyei11169dd2012-12-18 14:30:41 +00004192 }
4193
4194 if (C.kind == CXCursor_AsmLabelAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00004195 const AsmLabelAttr *AA = cast<AsmLabelAttr>(cxcursor::getCursorAttr(C));
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004196 return cxstring::createDup(AA->getLabel());
Guy Benyei11169dd2012-12-18 14:30:41 +00004197 }
4198
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00004199 if (C.kind == CXCursor_PackedAttr) {
4200 return cxstring::createRef("packed");
4201 }
4202
Saleem Abdulrasool79c69712015-09-05 18:53:43 +00004203 if (C.kind == CXCursor_VisibilityAttr) {
4204 const VisibilityAttr *AA = cast<VisibilityAttr>(cxcursor::getCursorAttr(C));
4205 switch (AA->getVisibility()) {
4206 case VisibilityAttr::VisibilityType::Default:
4207 return cxstring::createRef("default");
4208 case VisibilityAttr::VisibilityType::Hidden:
4209 return cxstring::createRef("hidden");
4210 case VisibilityAttr::VisibilityType::Protected:
4211 return cxstring::createRef("protected");
4212 }
4213 llvm_unreachable("unknown visibility type");
4214 }
4215
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00004216 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00004217}
4218
4219CXSourceRange clang_Cursor_getSpellingNameRange(CXCursor C,
4220 unsigned pieceIndex,
4221 unsigned options) {
4222 if (clang_Cursor_isNull(C))
4223 return clang_getNullRange();
4224
4225 ASTContext &Ctx = getCursorContext(C);
4226
4227 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004228 const Stmt *S = getCursorStmt(C);
4229 if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004230 if (pieceIndex > 0)
4231 return clang_getNullRange();
4232 return cxloc::translateSourceRange(Ctx, Label->getIdentLoc());
4233 }
4234
4235 return clang_getNullRange();
4236 }
4237
4238 if (C.kind == CXCursor_ObjCMessageExpr) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004239 if (const ObjCMessageExpr *
Guy Benyei11169dd2012-12-18 14:30:41 +00004240 ME = dyn_cast_or_null<ObjCMessageExpr>(getCursorExpr(C))) {
4241 if (pieceIndex >= ME->getNumSelectorLocs())
4242 return clang_getNullRange();
4243 return cxloc::translateSourceRange(Ctx, ME->getSelectorLoc(pieceIndex));
4244 }
4245 }
4246
4247 if (C.kind == CXCursor_ObjCInstanceMethodDecl ||
4248 C.kind == CXCursor_ObjCClassMethodDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004249 if (const ObjCMethodDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00004250 MD = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(C))) {
4251 if (pieceIndex >= MD->getNumSelectorLocs())
4252 return clang_getNullRange();
4253 return cxloc::translateSourceRange(Ctx, MD->getSelectorLoc(pieceIndex));
4254 }
4255 }
4256
4257 if (C.kind == CXCursor_ObjCCategoryDecl ||
4258 C.kind == CXCursor_ObjCCategoryImplDecl) {
4259 if (pieceIndex > 0)
4260 return clang_getNullRange();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004261 if (const ObjCCategoryDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00004262 CD = dyn_cast_or_null<ObjCCategoryDecl>(getCursorDecl(C)))
4263 return cxloc::translateSourceRange(Ctx, CD->getCategoryNameLoc());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004264 if (const ObjCCategoryImplDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00004265 CID = dyn_cast_or_null<ObjCCategoryImplDecl>(getCursorDecl(C)))
4266 return cxloc::translateSourceRange(Ctx, CID->getCategoryNameLoc());
4267 }
4268
4269 if (C.kind == CXCursor_ModuleImportDecl) {
4270 if (pieceIndex > 0)
4271 return clang_getNullRange();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004272 if (const ImportDecl *ImportD =
4273 dyn_cast_or_null<ImportDecl>(getCursorDecl(C))) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004274 ArrayRef<SourceLocation> Locs = ImportD->getIdentifierLocs();
4275 if (!Locs.empty())
4276 return cxloc::translateSourceRange(Ctx,
4277 SourceRange(Locs.front(), Locs.back()));
4278 }
4279 return clang_getNullRange();
4280 }
4281
Argyrios Kyrtzidisa2a1e532014-08-26 20:23:26 +00004282 if (C.kind == CXCursor_CXXMethod || C.kind == CXCursor_Destructor ||
4283 C.kind == CXCursor_ConversionFunction) {
4284 if (pieceIndex > 0)
4285 return clang_getNullRange();
4286 if (const FunctionDecl *FD =
4287 dyn_cast_or_null<FunctionDecl>(getCursorDecl(C))) {
4288 DeclarationNameInfo FunctionName = FD->getNameInfo();
4289 return cxloc::translateSourceRange(Ctx, FunctionName.getSourceRange());
4290 }
4291 return clang_getNullRange();
4292 }
4293
Guy Benyei11169dd2012-12-18 14:30:41 +00004294 // FIXME: A CXCursor_InclusionDirective should give the location of the
4295 // filename, but we don't keep track of this.
4296
4297 // FIXME: A CXCursor_AnnotateAttr should give the location of the annotation
4298 // but we don't keep track of this.
4299
4300 // FIXME: A CXCursor_AsmLabelAttr should give the location of the label
4301 // but we don't keep track of this.
4302
4303 // Default handling, give the location of the cursor.
4304
4305 if (pieceIndex > 0)
4306 return clang_getNullRange();
4307
4308 CXSourceLocation CXLoc = clang_getCursorLocation(C);
4309 SourceLocation Loc = cxloc::translateSourceLocation(CXLoc);
4310 return cxloc::translateSourceRange(Ctx, Loc);
4311}
4312
Eli Bendersky44a206f2014-07-31 18:04:56 +00004313CXString clang_Cursor_getMangling(CXCursor C) {
4314 if (clang_isInvalid(C.kind) || !clang_isDeclaration(C.kind))
4315 return cxstring::createEmpty();
4316
Eli Bendersky44a206f2014-07-31 18:04:56 +00004317 // Mangling only works for functions and variables.
Eli Bendersky79759592014-08-01 15:01:10 +00004318 const Decl *D = getCursorDecl(C);
Eli Bendersky44a206f2014-07-31 18:04:56 +00004319 if (!D || !(isa<FunctionDecl>(D) || isa<VarDecl>(D)))
4320 return cxstring::createEmpty();
4321
Argyrios Kyrtzidisca741ce2016-02-14 22:30:14 +00004322 ASTContext &Ctx = D->getASTContext();
4323 index::CodegenNameGenerator CGNameGen(Ctx);
4324 return cxstring::createDup(CGNameGen.getName(D));
Eli Bendersky44a206f2014-07-31 18:04:56 +00004325}
4326
Saleem Abdulrasool60034432015-11-12 03:57:22 +00004327CXStringSet *clang_Cursor_getCXXManglings(CXCursor C) {
4328 if (clang_isInvalid(C.kind) || !clang_isDeclaration(C.kind))
4329 return nullptr;
4330
4331 const Decl *D = getCursorDecl(C);
4332 if (!(isa<CXXRecordDecl>(D) || isa<CXXMethodDecl>(D)))
4333 return nullptr;
4334
Argyrios Kyrtzidisca741ce2016-02-14 22:30:14 +00004335 ASTContext &Ctx = D->getASTContext();
4336 index::CodegenNameGenerator CGNameGen(Ctx);
4337 std::vector<std::string> Manglings = CGNameGen.getAllManglings(D);
Saleem Abdulrasool60034432015-11-12 03:57:22 +00004338 return cxstring::createSet(Manglings);
4339}
4340
Guy Benyei11169dd2012-12-18 14:30:41 +00004341CXString clang_getCursorDisplayName(CXCursor C) {
4342 if (!clang_isDeclaration(C.kind))
4343 return clang_getCursorSpelling(C);
4344
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004345 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004346 if (!D)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00004347 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00004348
4349 PrintingPolicy Policy = getCursorContext(C).getPrintingPolicy();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004350 if (const FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004351 D = FunTmpl->getTemplatedDecl();
4352
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004353 if (const FunctionDecl *Function = dyn_cast<FunctionDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004354 SmallString<64> Str;
4355 llvm::raw_svector_ostream OS(Str);
4356 OS << *Function;
4357 if (Function->getPrimaryTemplate())
4358 OS << "<>";
4359 OS << "(";
4360 for (unsigned I = 0, N = Function->getNumParams(); I != N; ++I) {
4361 if (I)
4362 OS << ", ";
4363 OS << Function->getParamDecl(I)->getType().getAsString(Policy);
4364 }
4365
4366 if (Function->isVariadic()) {
4367 if (Function->getNumParams())
4368 OS << ", ";
4369 OS << "...";
4370 }
4371 OS << ")";
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004372 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00004373 }
4374
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004375 if (const ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004376 SmallString<64> Str;
4377 llvm::raw_svector_ostream OS(Str);
4378 OS << *ClassTemplate;
4379 OS << "<";
4380 TemplateParameterList *Params = ClassTemplate->getTemplateParameters();
4381 for (unsigned I = 0, N = Params->size(); I != N; ++I) {
4382 if (I)
4383 OS << ", ";
4384
4385 NamedDecl *Param = Params->getParam(I);
4386 if (Param->getIdentifier()) {
4387 OS << Param->getIdentifier()->getName();
4388 continue;
4389 }
4390
4391 // There is no parameter name, which makes this tricky. Try to come up
4392 // with something useful that isn't too long.
4393 if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(Param))
4394 OS << (TTP->wasDeclaredWithTypename()? "typename" : "class");
4395 else if (NonTypeTemplateParmDecl *NTTP
4396 = dyn_cast<NonTypeTemplateParmDecl>(Param))
4397 OS << NTTP->getType().getAsString(Policy);
4398 else
4399 OS << "template<...> class";
4400 }
4401
4402 OS << ">";
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004403 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00004404 }
4405
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004406 if (const ClassTemplateSpecializationDecl *ClassSpec
Guy Benyei11169dd2012-12-18 14:30:41 +00004407 = dyn_cast<ClassTemplateSpecializationDecl>(D)) {
4408 // If the type was explicitly written, use that.
4409 if (TypeSourceInfo *TSInfo = ClassSpec->getTypeAsWritten())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004410 return cxstring::createDup(TSInfo->getType().getAsString(Policy));
Guy Benyei11169dd2012-12-18 14:30:41 +00004411
Benjamin Kramer9170e912013-02-22 15:46:01 +00004412 SmallString<128> Str;
Guy Benyei11169dd2012-12-18 14:30:41 +00004413 llvm::raw_svector_ostream OS(Str);
4414 OS << *ClassSpec;
Benjamin Kramer9170e912013-02-22 15:46:01 +00004415 TemplateSpecializationType::PrintTemplateArgumentList(OS,
Guy Benyei11169dd2012-12-18 14:30:41 +00004416 ClassSpec->getTemplateArgs().data(),
4417 ClassSpec->getTemplateArgs().size(),
4418 Policy);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004419 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00004420 }
4421
4422 return clang_getCursorSpelling(C);
4423}
4424
4425CXString clang_getCursorKindSpelling(enum CXCursorKind Kind) {
4426 switch (Kind) {
4427 case CXCursor_FunctionDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004428 return cxstring::createRef("FunctionDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004429 case CXCursor_TypedefDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004430 return cxstring::createRef("TypedefDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004431 case CXCursor_EnumDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004432 return cxstring::createRef("EnumDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004433 case CXCursor_EnumConstantDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004434 return cxstring::createRef("EnumConstantDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004435 case CXCursor_StructDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004436 return cxstring::createRef("StructDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004437 case CXCursor_UnionDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004438 return cxstring::createRef("UnionDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004439 case CXCursor_ClassDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004440 return cxstring::createRef("ClassDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004441 case CXCursor_FieldDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004442 return cxstring::createRef("FieldDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004443 case CXCursor_VarDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004444 return cxstring::createRef("VarDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004445 case CXCursor_ParmDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004446 return cxstring::createRef("ParmDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004447 case CXCursor_ObjCInterfaceDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004448 return cxstring::createRef("ObjCInterfaceDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004449 case CXCursor_ObjCCategoryDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004450 return cxstring::createRef("ObjCCategoryDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004451 case CXCursor_ObjCProtocolDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004452 return cxstring::createRef("ObjCProtocolDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004453 case CXCursor_ObjCPropertyDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004454 return cxstring::createRef("ObjCPropertyDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004455 case CXCursor_ObjCIvarDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004456 return cxstring::createRef("ObjCIvarDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004457 case CXCursor_ObjCInstanceMethodDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004458 return cxstring::createRef("ObjCInstanceMethodDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004459 case CXCursor_ObjCClassMethodDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004460 return cxstring::createRef("ObjCClassMethodDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004461 case CXCursor_ObjCImplementationDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004462 return cxstring::createRef("ObjCImplementationDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004463 case CXCursor_ObjCCategoryImplDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004464 return cxstring::createRef("ObjCCategoryImplDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004465 case CXCursor_CXXMethod:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004466 return cxstring::createRef("CXXMethod");
Guy Benyei11169dd2012-12-18 14:30:41 +00004467 case CXCursor_UnexposedDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004468 return cxstring::createRef("UnexposedDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004469 case CXCursor_ObjCSuperClassRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004470 return cxstring::createRef("ObjCSuperClassRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004471 case CXCursor_ObjCProtocolRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004472 return cxstring::createRef("ObjCProtocolRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004473 case CXCursor_ObjCClassRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004474 return cxstring::createRef("ObjCClassRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004475 case CXCursor_TypeRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004476 return cxstring::createRef("TypeRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004477 case CXCursor_TemplateRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004478 return cxstring::createRef("TemplateRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004479 case CXCursor_NamespaceRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004480 return cxstring::createRef("NamespaceRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004481 case CXCursor_MemberRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004482 return cxstring::createRef("MemberRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004483 case CXCursor_LabelRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004484 return cxstring::createRef("LabelRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004485 case CXCursor_OverloadedDeclRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004486 return cxstring::createRef("OverloadedDeclRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004487 case CXCursor_VariableRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004488 return cxstring::createRef("VariableRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004489 case CXCursor_IntegerLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004490 return cxstring::createRef("IntegerLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00004491 case CXCursor_FloatingLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004492 return cxstring::createRef("FloatingLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00004493 case CXCursor_ImaginaryLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004494 return cxstring::createRef("ImaginaryLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00004495 case CXCursor_StringLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004496 return cxstring::createRef("StringLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00004497 case CXCursor_CharacterLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004498 return cxstring::createRef("CharacterLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00004499 case CXCursor_ParenExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004500 return cxstring::createRef("ParenExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004501 case CXCursor_UnaryOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004502 return cxstring::createRef("UnaryOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00004503 case CXCursor_ArraySubscriptExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004504 return cxstring::createRef("ArraySubscriptExpr");
Alexey Bataev1a3320e2015-08-25 14:24:04 +00004505 case CXCursor_OMPArraySectionExpr:
4506 return cxstring::createRef("OMPArraySectionExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004507 case CXCursor_BinaryOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004508 return cxstring::createRef("BinaryOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00004509 case CXCursor_CompoundAssignOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004510 return cxstring::createRef("CompoundAssignOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00004511 case CXCursor_ConditionalOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004512 return cxstring::createRef("ConditionalOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00004513 case CXCursor_CStyleCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004514 return cxstring::createRef("CStyleCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004515 case CXCursor_CompoundLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004516 return cxstring::createRef("CompoundLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004517 case CXCursor_InitListExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004518 return cxstring::createRef("InitListExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004519 case CXCursor_AddrLabelExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004520 return cxstring::createRef("AddrLabelExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004521 case CXCursor_StmtExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004522 return cxstring::createRef("StmtExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004523 case CXCursor_GenericSelectionExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004524 return cxstring::createRef("GenericSelectionExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004525 case CXCursor_GNUNullExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004526 return cxstring::createRef("GNUNullExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004527 case CXCursor_CXXStaticCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004528 return cxstring::createRef("CXXStaticCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004529 case CXCursor_CXXDynamicCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004530 return cxstring::createRef("CXXDynamicCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004531 case CXCursor_CXXReinterpretCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004532 return cxstring::createRef("CXXReinterpretCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004533 case CXCursor_CXXConstCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004534 return cxstring::createRef("CXXConstCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004535 case CXCursor_CXXFunctionalCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004536 return cxstring::createRef("CXXFunctionalCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004537 case CXCursor_CXXTypeidExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004538 return cxstring::createRef("CXXTypeidExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004539 case CXCursor_CXXBoolLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004540 return cxstring::createRef("CXXBoolLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004541 case CXCursor_CXXNullPtrLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004542 return cxstring::createRef("CXXNullPtrLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004543 case CXCursor_CXXThisExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004544 return cxstring::createRef("CXXThisExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004545 case CXCursor_CXXThrowExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004546 return cxstring::createRef("CXXThrowExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004547 case CXCursor_CXXNewExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004548 return cxstring::createRef("CXXNewExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004549 case CXCursor_CXXDeleteExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004550 return cxstring::createRef("CXXDeleteExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004551 case CXCursor_UnaryExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004552 return cxstring::createRef("UnaryExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004553 case CXCursor_ObjCStringLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004554 return cxstring::createRef("ObjCStringLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00004555 case CXCursor_ObjCBoolLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004556 return cxstring::createRef("ObjCBoolLiteralExpr");
Argyrios Kyrtzidisc2233be2013-04-23 17:57:17 +00004557 case CXCursor_ObjCSelfExpr:
4558 return cxstring::createRef("ObjCSelfExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004559 case CXCursor_ObjCEncodeExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004560 return cxstring::createRef("ObjCEncodeExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004561 case CXCursor_ObjCSelectorExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004562 return cxstring::createRef("ObjCSelectorExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004563 case CXCursor_ObjCProtocolExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004564 return cxstring::createRef("ObjCProtocolExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004565 case CXCursor_ObjCBridgedCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004566 return cxstring::createRef("ObjCBridgedCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004567 case CXCursor_BlockExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004568 return cxstring::createRef("BlockExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004569 case CXCursor_PackExpansionExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004570 return cxstring::createRef("PackExpansionExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004571 case CXCursor_SizeOfPackExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004572 return cxstring::createRef("SizeOfPackExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004573 case CXCursor_LambdaExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004574 return cxstring::createRef("LambdaExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004575 case CXCursor_UnexposedExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004576 return cxstring::createRef("UnexposedExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004577 case CXCursor_DeclRefExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004578 return cxstring::createRef("DeclRefExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004579 case CXCursor_MemberRefExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004580 return cxstring::createRef("MemberRefExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004581 case CXCursor_CallExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004582 return cxstring::createRef("CallExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004583 case CXCursor_ObjCMessageExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004584 return cxstring::createRef("ObjCMessageExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004585 case CXCursor_UnexposedStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004586 return cxstring::createRef("UnexposedStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004587 case CXCursor_DeclStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004588 return cxstring::createRef("DeclStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004589 case CXCursor_LabelStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004590 return cxstring::createRef("LabelStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004591 case CXCursor_CompoundStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004592 return cxstring::createRef("CompoundStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004593 case CXCursor_CaseStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004594 return cxstring::createRef("CaseStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004595 case CXCursor_DefaultStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004596 return cxstring::createRef("DefaultStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004597 case CXCursor_IfStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004598 return cxstring::createRef("IfStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004599 case CXCursor_SwitchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004600 return cxstring::createRef("SwitchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004601 case CXCursor_WhileStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004602 return cxstring::createRef("WhileStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004603 case CXCursor_DoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004604 return cxstring::createRef("DoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004605 case CXCursor_ForStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004606 return cxstring::createRef("ForStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004607 case CXCursor_GotoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004608 return cxstring::createRef("GotoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004609 case CXCursor_IndirectGotoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004610 return cxstring::createRef("IndirectGotoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004611 case CXCursor_ContinueStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004612 return cxstring::createRef("ContinueStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004613 case CXCursor_BreakStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004614 return cxstring::createRef("BreakStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004615 case CXCursor_ReturnStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004616 return cxstring::createRef("ReturnStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004617 case CXCursor_GCCAsmStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004618 return cxstring::createRef("GCCAsmStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004619 case CXCursor_MSAsmStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004620 return cxstring::createRef("MSAsmStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004621 case CXCursor_ObjCAtTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004622 return cxstring::createRef("ObjCAtTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004623 case CXCursor_ObjCAtCatchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004624 return cxstring::createRef("ObjCAtCatchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004625 case CXCursor_ObjCAtFinallyStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004626 return cxstring::createRef("ObjCAtFinallyStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004627 case CXCursor_ObjCAtThrowStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004628 return cxstring::createRef("ObjCAtThrowStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004629 case CXCursor_ObjCAtSynchronizedStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004630 return cxstring::createRef("ObjCAtSynchronizedStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004631 case CXCursor_ObjCAutoreleasePoolStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004632 return cxstring::createRef("ObjCAutoreleasePoolStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004633 case CXCursor_ObjCForCollectionStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004634 return cxstring::createRef("ObjCForCollectionStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004635 case CXCursor_CXXCatchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004636 return cxstring::createRef("CXXCatchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004637 case CXCursor_CXXTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004638 return cxstring::createRef("CXXTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004639 case CXCursor_CXXForRangeStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004640 return cxstring::createRef("CXXForRangeStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004641 case CXCursor_SEHTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004642 return cxstring::createRef("SEHTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004643 case CXCursor_SEHExceptStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004644 return cxstring::createRef("SEHExceptStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004645 case CXCursor_SEHFinallyStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004646 return cxstring::createRef("SEHFinallyStmt");
Nico Weber9b982072014-07-07 00:12:30 +00004647 case CXCursor_SEHLeaveStmt:
4648 return cxstring::createRef("SEHLeaveStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004649 case CXCursor_NullStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004650 return cxstring::createRef("NullStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004651 case CXCursor_InvalidFile:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004652 return cxstring::createRef("InvalidFile");
Guy Benyei11169dd2012-12-18 14:30:41 +00004653 case CXCursor_InvalidCode:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004654 return cxstring::createRef("InvalidCode");
Guy Benyei11169dd2012-12-18 14:30:41 +00004655 case CXCursor_NoDeclFound:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004656 return cxstring::createRef("NoDeclFound");
Guy Benyei11169dd2012-12-18 14:30:41 +00004657 case CXCursor_NotImplemented:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004658 return cxstring::createRef("NotImplemented");
Guy Benyei11169dd2012-12-18 14:30:41 +00004659 case CXCursor_TranslationUnit:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004660 return cxstring::createRef("TranslationUnit");
Guy Benyei11169dd2012-12-18 14:30:41 +00004661 case CXCursor_UnexposedAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004662 return cxstring::createRef("UnexposedAttr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004663 case CXCursor_IBActionAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004664 return cxstring::createRef("attribute(ibaction)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004665 case CXCursor_IBOutletAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004666 return cxstring::createRef("attribute(iboutlet)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004667 case CXCursor_IBOutletCollectionAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004668 return cxstring::createRef("attribute(iboutletcollection)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004669 case CXCursor_CXXFinalAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004670 return cxstring::createRef("attribute(final)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004671 case CXCursor_CXXOverrideAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004672 return cxstring::createRef("attribute(override)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004673 case CXCursor_AnnotateAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004674 return cxstring::createRef("attribute(annotate)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004675 case CXCursor_AsmLabelAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004676 return cxstring::createRef("asm label");
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00004677 case CXCursor_PackedAttr:
4678 return cxstring::createRef("attribute(packed)");
Joey Gouly81228382014-05-01 15:41:58 +00004679 case CXCursor_PureAttr:
4680 return cxstring::createRef("attribute(pure)");
4681 case CXCursor_ConstAttr:
4682 return cxstring::createRef("attribute(const)");
4683 case CXCursor_NoDuplicateAttr:
4684 return cxstring::createRef("attribute(noduplicate)");
Eli Bendersky2581e662014-05-28 19:29:58 +00004685 case CXCursor_CUDAConstantAttr:
4686 return cxstring::createRef("attribute(constant)");
4687 case CXCursor_CUDADeviceAttr:
4688 return cxstring::createRef("attribute(device)");
4689 case CXCursor_CUDAGlobalAttr:
4690 return cxstring::createRef("attribute(global)");
4691 case CXCursor_CUDAHostAttr:
4692 return cxstring::createRef("attribute(host)");
Eli Bendersky9b071472014-08-08 14:59:00 +00004693 case CXCursor_CUDASharedAttr:
4694 return cxstring::createRef("attribute(shared)");
Saleem Abdulrasool79c69712015-09-05 18:53:43 +00004695 case CXCursor_VisibilityAttr:
4696 return cxstring::createRef("attribute(visibility)");
Saleem Abdulrasool8aa0b802015-12-10 18:45:18 +00004697 case CXCursor_DLLExport:
4698 return cxstring::createRef("attribute(dllexport)");
4699 case CXCursor_DLLImport:
4700 return cxstring::createRef("attribute(dllimport)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004701 case CXCursor_PreprocessingDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004702 return cxstring::createRef("preprocessing directive");
Guy Benyei11169dd2012-12-18 14:30:41 +00004703 case CXCursor_MacroDefinition:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004704 return cxstring::createRef("macro definition");
Guy Benyei11169dd2012-12-18 14:30:41 +00004705 case CXCursor_MacroExpansion:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004706 return cxstring::createRef("macro expansion");
Guy Benyei11169dd2012-12-18 14:30:41 +00004707 case CXCursor_InclusionDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004708 return cxstring::createRef("inclusion directive");
Guy Benyei11169dd2012-12-18 14:30:41 +00004709 case CXCursor_Namespace:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004710 return cxstring::createRef("Namespace");
Guy Benyei11169dd2012-12-18 14:30:41 +00004711 case CXCursor_LinkageSpec:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004712 return cxstring::createRef("LinkageSpec");
Guy Benyei11169dd2012-12-18 14:30:41 +00004713 case CXCursor_CXXBaseSpecifier:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004714 return cxstring::createRef("C++ base class specifier");
Guy Benyei11169dd2012-12-18 14:30:41 +00004715 case CXCursor_Constructor:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004716 return cxstring::createRef("CXXConstructor");
Guy Benyei11169dd2012-12-18 14:30:41 +00004717 case CXCursor_Destructor:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004718 return cxstring::createRef("CXXDestructor");
Guy Benyei11169dd2012-12-18 14:30:41 +00004719 case CXCursor_ConversionFunction:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004720 return cxstring::createRef("CXXConversion");
Guy Benyei11169dd2012-12-18 14:30:41 +00004721 case CXCursor_TemplateTypeParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004722 return cxstring::createRef("TemplateTypeParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00004723 case CXCursor_NonTypeTemplateParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004724 return cxstring::createRef("NonTypeTemplateParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00004725 case CXCursor_TemplateTemplateParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004726 return cxstring::createRef("TemplateTemplateParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00004727 case CXCursor_FunctionTemplate:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004728 return cxstring::createRef("FunctionTemplate");
Guy Benyei11169dd2012-12-18 14:30:41 +00004729 case CXCursor_ClassTemplate:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004730 return cxstring::createRef("ClassTemplate");
Guy Benyei11169dd2012-12-18 14:30:41 +00004731 case CXCursor_ClassTemplatePartialSpecialization:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004732 return cxstring::createRef("ClassTemplatePartialSpecialization");
Guy Benyei11169dd2012-12-18 14:30:41 +00004733 case CXCursor_NamespaceAlias:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004734 return cxstring::createRef("NamespaceAlias");
Guy Benyei11169dd2012-12-18 14:30:41 +00004735 case CXCursor_UsingDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004736 return cxstring::createRef("UsingDirective");
Guy Benyei11169dd2012-12-18 14:30:41 +00004737 case CXCursor_UsingDeclaration:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004738 return cxstring::createRef("UsingDeclaration");
Guy Benyei11169dd2012-12-18 14:30:41 +00004739 case CXCursor_TypeAliasDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004740 return cxstring::createRef("TypeAliasDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004741 case CXCursor_ObjCSynthesizeDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004742 return cxstring::createRef("ObjCSynthesizeDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004743 case CXCursor_ObjCDynamicDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004744 return cxstring::createRef("ObjCDynamicDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004745 case CXCursor_CXXAccessSpecifier:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004746 return cxstring::createRef("CXXAccessSpecifier");
Guy Benyei11169dd2012-12-18 14:30:41 +00004747 case CXCursor_ModuleImportDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004748 return cxstring::createRef("ModuleImport");
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00004749 case CXCursor_OMPParallelDirective:
Alexey Bataev1b59ab52014-02-27 08:29:12 +00004750 return cxstring::createRef("OMPParallelDirective");
4751 case CXCursor_OMPSimdDirective:
4752 return cxstring::createRef("OMPSimdDirective");
Alexey Bataevf29276e2014-06-18 04:14:57 +00004753 case CXCursor_OMPForDirective:
4754 return cxstring::createRef("OMPForDirective");
Alexander Musmanf82886e2014-09-18 05:12:34 +00004755 case CXCursor_OMPForSimdDirective:
4756 return cxstring::createRef("OMPForSimdDirective");
Alexey Bataevd3f8dd22014-06-25 11:44:49 +00004757 case CXCursor_OMPSectionsDirective:
4758 return cxstring::createRef("OMPSectionsDirective");
Alexey Bataev1e0498a2014-06-26 08:21:58 +00004759 case CXCursor_OMPSectionDirective:
4760 return cxstring::createRef("OMPSectionDirective");
Alexey Bataevd1e40fb2014-06-26 12:05:45 +00004761 case CXCursor_OMPSingleDirective:
4762 return cxstring::createRef("OMPSingleDirective");
Alexander Musman80c22892014-07-17 08:54:58 +00004763 case CXCursor_OMPMasterDirective:
4764 return cxstring::createRef("OMPMasterDirective");
Alexander Musmand9ed09f2014-07-21 09:42:05 +00004765 case CXCursor_OMPCriticalDirective:
4766 return cxstring::createRef("OMPCriticalDirective");
Alexey Bataev4acb8592014-07-07 13:01:15 +00004767 case CXCursor_OMPParallelForDirective:
4768 return cxstring::createRef("OMPParallelForDirective");
Alexander Musmane4e893b2014-09-23 09:33:00 +00004769 case CXCursor_OMPParallelForSimdDirective:
4770 return cxstring::createRef("OMPParallelForSimdDirective");
Alexey Bataev84d0b3e2014-07-08 08:12:03 +00004771 case CXCursor_OMPParallelSectionsDirective:
4772 return cxstring::createRef("OMPParallelSectionsDirective");
Alexey Bataev9c2e8ee2014-07-11 11:25:16 +00004773 case CXCursor_OMPTaskDirective:
4774 return cxstring::createRef("OMPTaskDirective");
Alexey Bataev68446b72014-07-18 07:47:19 +00004775 case CXCursor_OMPTaskyieldDirective:
4776 return cxstring::createRef("OMPTaskyieldDirective");
Alexey Bataev4d1dfea2014-07-18 09:11:51 +00004777 case CXCursor_OMPBarrierDirective:
4778 return cxstring::createRef("OMPBarrierDirective");
Alexey Bataev2df347a2014-07-18 10:17:07 +00004779 case CXCursor_OMPTaskwaitDirective:
4780 return cxstring::createRef("OMPTaskwaitDirective");
Alexey Bataevc30dd2d2015-06-18 12:14:09 +00004781 case CXCursor_OMPTaskgroupDirective:
4782 return cxstring::createRef("OMPTaskgroupDirective");
Alexey Bataev6125da92014-07-21 11:26:11 +00004783 case CXCursor_OMPFlushDirective:
4784 return cxstring::createRef("OMPFlushDirective");
Alexey Bataev9fb6e642014-07-22 06:45:04 +00004785 case CXCursor_OMPOrderedDirective:
4786 return cxstring::createRef("OMPOrderedDirective");
Alexey Bataev0162e452014-07-22 10:10:35 +00004787 case CXCursor_OMPAtomicDirective:
4788 return cxstring::createRef("OMPAtomicDirective");
Alexey Bataev0bd520b2014-09-19 08:19:49 +00004789 case CXCursor_OMPTargetDirective:
4790 return cxstring::createRef("OMPTargetDirective");
Michael Wong65f367f2015-07-21 13:44:28 +00004791 case CXCursor_OMPTargetDataDirective:
4792 return cxstring::createRef("OMPTargetDataDirective");
Samuel Antaodf67fc42016-01-19 19:15:56 +00004793 case CXCursor_OMPTargetEnterDataDirective:
4794 return cxstring::createRef("OMPTargetEnterDataDirective");
Samuel Antao72590762016-01-19 20:04:50 +00004795 case CXCursor_OMPTargetExitDataDirective:
4796 return cxstring::createRef("OMPTargetExitDataDirective");
Arpith Chacko Jacobe955b3d2016-01-26 18:48:41 +00004797 case CXCursor_OMPTargetParallelDirective:
4798 return cxstring::createRef("OMPTargetParallelDirective");
Arpith Chacko Jacob05bebb52016-02-03 15:46:42 +00004799 case CXCursor_OMPTargetParallelForDirective:
4800 return cxstring::createRef("OMPTargetParallelForDirective");
Samuel Antao686c70c2016-05-26 17:30:50 +00004801 case CXCursor_OMPTargetUpdateDirective:
4802 return cxstring::createRef("OMPTargetUpdateDirective");
Alexey Bataev13314bf2014-10-09 04:18:56 +00004803 case CXCursor_OMPTeamsDirective:
4804 return cxstring::createRef("OMPTeamsDirective");
Alexey Bataev6d4ed052015-07-01 06:57:41 +00004805 case CXCursor_OMPCancellationPointDirective:
4806 return cxstring::createRef("OMPCancellationPointDirective");
Alexey Bataev80909872015-07-02 11:25:17 +00004807 case CXCursor_OMPCancelDirective:
4808 return cxstring::createRef("OMPCancelDirective");
Alexey Bataev49f6e782015-12-01 04:18:41 +00004809 case CXCursor_OMPTaskLoopDirective:
4810 return cxstring::createRef("OMPTaskLoopDirective");
Alexey Bataev0a6ed842015-12-03 09:40:15 +00004811 case CXCursor_OMPTaskLoopSimdDirective:
4812 return cxstring::createRef("OMPTaskLoopSimdDirective");
Carlo Bertolli6200a3d2015-12-14 14:51:25 +00004813 case CXCursor_OMPDistributeDirective:
4814 return cxstring::createRef("OMPDistributeDirective");
Francisco Lopes da Silva975a9f62015-01-21 16:24:11 +00004815 case CXCursor_OverloadCandidate:
4816 return cxstring::createRef("OverloadCandidate");
Sergey Kalinichev8f3b1872015-11-15 13:48:32 +00004817 case CXCursor_TypeAliasTemplateDecl:
4818 return cxstring::createRef("TypeAliasTemplateDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004819 }
4820
4821 llvm_unreachable("Unhandled CXCursorKind");
4822}
4823
4824struct GetCursorData {
4825 SourceLocation TokenBeginLoc;
4826 bool PointsAtMacroArgExpansion;
4827 bool VisitedObjCPropertyImplDecl;
4828 SourceLocation VisitedDeclaratorDeclStartLoc;
4829 CXCursor &BestCursor;
4830
4831 GetCursorData(SourceManager &SM,
4832 SourceLocation tokenBegin, CXCursor &outputCursor)
4833 : TokenBeginLoc(tokenBegin), BestCursor(outputCursor) {
4834 PointsAtMacroArgExpansion = SM.isMacroArgExpansion(tokenBegin);
4835 VisitedObjCPropertyImplDecl = false;
4836 }
4837};
4838
4839static enum CXChildVisitResult GetCursorVisitor(CXCursor cursor,
4840 CXCursor parent,
4841 CXClientData client_data) {
4842 GetCursorData *Data = static_cast<GetCursorData *>(client_data);
4843 CXCursor *BestCursor = &Data->BestCursor;
4844
4845 // If we point inside a macro argument we should provide info of what the
4846 // token is so use the actual cursor, don't replace it with a macro expansion
4847 // cursor.
4848 if (cursor.kind == CXCursor_MacroExpansion && Data->PointsAtMacroArgExpansion)
4849 return CXChildVisit_Recurse;
4850
4851 if (clang_isDeclaration(cursor.kind)) {
4852 // Avoid having the implicit methods override the property decls.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004853 if (const ObjCMethodDecl *MD
Guy Benyei11169dd2012-12-18 14:30:41 +00004854 = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
4855 if (MD->isImplicit())
4856 return CXChildVisit_Break;
4857
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004858 } else if (const ObjCInterfaceDecl *ID
Guy Benyei11169dd2012-12-18 14:30:41 +00004859 = dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(cursor))) {
4860 // Check that when we have multiple @class references in the same line,
4861 // that later ones do not override the previous ones.
4862 // If we have:
4863 // @class Foo, Bar;
4864 // source ranges for both start at '@', so 'Bar' will end up overriding
4865 // 'Foo' even though the cursor location was at 'Foo'.
4866 if (BestCursor->kind == CXCursor_ObjCInterfaceDecl ||
4867 BestCursor->kind == CXCursor_ObjCClassRef)
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004868 if (const ObjCInterfaceDecl *PrevID
Guy Benyei11169dd2012-12-18 14:30:41 +00004869 = dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(*BestCursor))){
4870 if (PrevID != ID &&
4871 !PrevID->isThisDeclarationADefinition() &&
4872 !ID->isThisDeclarationADefinition())
4873 return CXChildVisit_Break;
4874 }
4875
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004876 } else if (const DeclaratorDecl *DD
Guy Benyei11169dd2012-12-18 14:30:41 +00004877 = dyn_cast_or_null<DeclaratorDecl>(getCursorDecl(cursor))) {
4878 SourceLocation StartLoc = DD->getSourceRange().getBegin();
4879 // Check that when we have multiple declarators in the same line,
4880 // that later ones do not override the previous ones.
4881 // If we have:
4882 // int Foo, Bar;
4883 // source ranges for both start at 'int', so 'Bar' will end up overriding
4884 // 'Foo' even though the cursor location was at 'Foo'.
4885 if (Data->VisitedDeclaratorDeclStartLoc == StartLoc)
4886 return CXChildVisit_Break;
4887 Data->VisitedDeclaratorDeclStartLoc = StartLoc;
4888
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004889 } else if (const ObjCPropertyImplDecl *PropImp
Guy Benyei11169dd2012-12-18 14:30:41 +00004890 = dyn_cast_or_null<ObjCPropertyImplDecl>(getCursorDecl(cursor))) {
4891 (void)PropImp;
4892 // Check that when we have multiple @synthesize in the same line,
4893 // that later ones do not override the previous ones.
4894 // If we have:
4895 // @synthesize Foo, Bar;
4896 // source ranges for both start at '@', so 'Bar' will end up overriding
4897 // 'Foo' even though the cursor location was at 'Foo'.
4898 if (Data->VisitedObjCPropertyImplDecl)
4899 return CXChildVisit_Break;
4900 Data->VisitedObjCPropertyImplDecl = true;
4901 }
4902 }
4903
4904 if (clang_isExpression(cursor.kind) &&
4905 clang_isDeclaration(BestCursor->kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004906 if (const Decl *D = getCursorDecl(*BestCursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004907 // Avoid having the cursor of an expression replace the declaration cursor
4908 // when the expression source range overlaps the declaration range.
4909 // This can happen for C++ constructor expressions whose range generally
4910 // include the variable declaration, e.g.:
4911 // MyCXXClass foo; // Make sure pointing at 'foo' returns a VarDecl cursor.
4912 if (D->getLocation().isValid() && Data->TokenBeginLoc.isValid() &&
4913 D->getLocation() == Data->TokenBeginLoc)
4914 return CXChildVisit_Break;
4915 }
4916 }
4917
4918 // If our current best cursor is the construction of a temporary object,
4919 // don't replace that cursor with a type reference, because we want
4920 // clang_getCursor() to point at the constructor.
4921 if (clang_isExpression(BestCursor->kind) &&
4922 isa<CXXTemporaryObjectExpr>(getCursorExpr(*BestCursor)) &&
4923 cursor.kind == CXCursor_TypeRef) {
4924 // Keep the cursor pointing at CXXTemporaryObjectExpr but also mark it
4925 // as having the actual point on the type reference.
4926 *BestCursor = getTypeRefedCallExprCursor(*BestCursor);
4927 return CXChildVisit_Recurse;
4928 }
Douglas Gregore9d95f12015-07-07 03:57:35 +00004929
4930 // If we already have an Objective-C superclass reference, don't
4931 // update it further.
4932 if (BestCursor->kind == CXCursor_ObjCSuperClassRef)
4933 return CXChildVisit_Break;
4934
Guy Benyei11169dd2012-12-18 14:30:41 +00004935 *BestCursor = cursor;
4936 return CXChildVisit_Recurse;
4937}
4938
4939CXCursor clang_getCursor(CXTranslationUnit TU, CXSourceLocation Loc) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00004940 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004941 LOG_BAD_TU(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004942 return clang_getNullCursor();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004943 }
Guy Benyei11169dd2012-12-18 14:30:41 +00004944
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004945 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004946 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
4947
4948 SourceLocation SLoc = cxloc::translateSourceLocation(Loc);
4949 CXCursor Result = cxcursor::getCursor(TU, SLoc);
4950
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004951 LOG_FUNC_SECTION {
Guy Benyei11169dd2012-12-18 14:30:41 +00004952 CXFile SearchFile;
4953 unsigned SearchLine, SearchColumn;
4954 CXFile ResultFile;
4955 unsigned ResultLine, ResultColumn;
4956 CXString SearchFileName, ResultFileName, KindSpelling, USR;
4957 const char *IsDef = clang_isCursorDefinition(Result)? " (Definition)" : "";
4958 CXSourceLocation ResultLoc = clang_getCursorLocation(Result);
Craig Topper69186e72014-06-08 08:38:04 +00004959
4960 clang_getFileLocation(Loc, &SearchFile, &SearchLine, &SearchColumn,
4961 nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004962 clang_getFileLocation(ResultLoc, &ResultFile, &ResultLine,
Craig Topper69186e72014-06-08 08:38:04 +00004963 &ResultColumn, nullptr);
Guy Benyei11169dd2012-12-18 14:30:41 +00004964 SearchFileName = clang_getFileName(SearchFile);
4965 ResultFileName = clang_getFileName(ResultFile);
4966 KindSpelling = clang_getCursorKindSpelling(Result.kind);
4967 USR = clang_getCursorUSR(Result);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004968 *Log << llvm::format("(%s:%d:%d) = %s",
4969 clang_getCString(SearchFileName), SearchLine, SearchColumn,
4970 clang_getCString(KindSpelling))
4971 << llvm::format("(%s:%d:%d):%s%s",
4972 clang_getCString(ResultFileName), ResultLine, ResultColumn,
4973 clang_getCString(USR), IsDef);
Guy Benyei11169dd2012-12-18 14:30:41 +00004974 clang_disposeString(SearchFileName);
4975 clang_disposeString(ResultFileName);
4976 clang_disposeString(KindSpelling);
4977 clang_disposeString(USR);
4978
4979 CXCursor Definition = clang_getCursorDefinition(Result);
4980 if (!clang_equalCursors(Definition, clang_getNullCursor())) {
4981 CXSourceLocation DefinitionLoc = clang_getCursorLocation(Definition);
4982 CXString DefinitionKindSpelling
4983 = clang_getCursorKindSpelling(Definition.kind);
4984 CXFile DefinitionFile;
4985 unsigned DefinitionLine, DefinitionColumn;
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004986 clang_getFileLocation(DefinitionLoc, &DefinitionFile,
Craig Topper69186e72014-06-08 08:38:04 +00004987 &DefinitionLine, &DefinitionColumn, nullptr);
Guy Benyei11169dd2012-12-18 14:30:41 +00004988 CXString DefinitionFileName = clang_getFileName(DefinitionFile);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004989 *Log << llvm::format(" -> %s(%s:%d:%d)",
4990 clang_getCString(DefinitionKindSpelling),
4991 clang_getCString(DefinitionFileName),
4992 DefinitionLine, DefinitionColumn);
Guy Benyei11169dd2012-12-18 14:30:41 +00004993 clang_disposeString(DefinitionFileName);
4994 clang_disposeString(DefinitionKindSpelling);
4995 }
4996 }
4997
4998 return Result;
4999}
5000
5001CXCursor clang_getNullCursor(void) {
5002 return MakeCXCursorInvalid(CXCursor_InvalidFile);
5003}
5004
5005unsigned clang_equalCursors(CXCursor X, CXCursor Y) {
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00005006 // Clear out the "FirstInDeclGroup" part in a declaration cursor, since we
5007 // can't set consistently. For example, when visiting a DeclStmt we will set
5008 // it but we don't set it on the result of clang_getCursorDefinition for
5009 // a reference of the same declaration.
5010 // FIXME: Setting "FirstInDeclGroup" in CXCursors is a hack that only works
5011 // when visiting a DeclStmt currently, the AST should be enhanced to be able
5012 // to provide that kind of info.
5013 if (clang_isDeclaration(X.kind))
Craig Topper69186e72014-06-08 08:38:04 +00005014 X.data[1] = nullptr;
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00005015 if (clang_isDeclaration(Y.kind))
Craig Topper69186e72014-06-08 08:38:04 +00005016 Y.data[1] = nullptr;
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00005017
Guy Benyei11169dd2012-12-18 14:30:41 +00005018 return X == Y;
5019}
5020
5021unsigned clang_hashCursor(CXCursor C) {
5022 unsigned Index = 0;
5023 if (clang_isExpression(C.kind) || clang_isStatement(C.kind))
5024 Index = 1;
5025
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005026 return llvm::DenseMapInfo<std::pair<unsigned, const void*> >::getHashValue(
Guy Benyei11169dd2012-12-18 14:30:41 +00005027 std::make_pair(C.kind, C.data[Index]));
5028}
5029
5030unsigned clang_isInvalid(enum CXCursorKind K) {
5031 return K >= CXCursor_FirstInvalid && K <= CXCursor_LastInvalid;
5032}
5033
5034unsigned clang_isDeclaration(enum CXCursorKind K) {
5035 return (K >= CXCursor_FirstDecl && K <= CXCursor_LastDecl) ||
5036 (K >= CXCursor_FirstExtraDecl && K <= CXCursor_LastExtraDecl);
5037}
5038
5039unsigned clang_isReference(enum CXCursorKind K) {
5040 return K >= CXCursor_FirstRef && K <= CXCursor_LastRef;
5041}
5042
5043unsigned clang_isExpression(enum CXCursorKind K) {
5044 return K >= CXCursor_FirstExpr && K <= CXCursor_LastExpr;
5045}
5046
5047unsigned clang_isStatement(enum CXCursorKind K) {
5048 return K >= CXCursor_FirstStmt && K <= CXCursor_LastStmt;
5049}
5050
5051unsigned clang_isAttribute(enum CXCursorKind K) {
5052 return K >= CXCursor_FirstAttr && K <= CXCursor_LastAttr;
5053}
5054
5055unsigned clang_isTranslationUnit(enum CXCursorKind K) {
5056 return K == CXCursor_TranslationUnit;
5057}
5058
5059unsigned clang_isPreprocessing(enum CXCursorKind K) {
5060 return K >= CXCursor_FirstPreprocessing && K <= CXCursor_LastPreprocessing;
5061}
5062
5063unsigned clang_isUnexposed(enum CXCursorKind K) {
5064 switch (K) {
5065 case CXCursor_UnexposedDecl:
5066 case CXCursor_UnexposedExpr:
5067 case CXCursor_UnexposedStmt:
5068 case CXCursor_UnexposedAttr:
5069 return true;
5070 default:
5071 return false;
5072 }
5073}
5074
5075CXCursorKind clang_getCursorKind(CXCursor C) {
5076 return C.kind;
5077}
5078
5079CXSourceLocation clang_getCursorLocation(CXCursor C) {
5080 if (clang_isReference(C.kind)) {
5081 switch (C.kind) {
5082 case CXCursor_ObjCSuperClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005083 std::pair<const ObjCInterfaceDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00005084 = getCursorObjCSuperClassRef(C);
5085 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
5086 }
5087
5088 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005089 std::pair<const ObjCProtocolDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00005090 = getCursorObjCProtocolRef(C);
5091 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
5092 }
5093
5094 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005095 std::pair<const ObjCInterfaceDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00005096 = getCursorObjCClassRef(C);
5097 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
5098 }
5099
5100 case CXCursor_TypeRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005101 std::pair<const TypeDecl *, SourceLocation> P = getCursorTypeRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005102 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
5103 }
5104
5105 case CXCursor_TemplateRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005106 std::pair<const TemplateDecl *, SourceLocation> P =
5107 getCursorTemplateRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005108 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
5109 }
5110
5111 case CXCursor_NamespaceRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005112 std::pair<const NamedDecl *, SourceLocation> P = getCursorNamespaceRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005113 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
5114 }
5115
5116 case CXCursor_MemberRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005117 std::pair<const FieldDecl *, SourceLocation> P = getCursorMemberRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005118 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
5119 }
5120
5121 case CXCursor_VariableRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005122 std::pair<const VarDecl *, SourceLocation> P = getCursorVariableRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005123 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
5124 }
5125
5126 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005127 const CXXBaseSpecifier *BaseSpec = getCursorCXXBaseSpecifier(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005128 if (!BaseSpec)
5129 return clang_getNullLocation();
5130
5131 if (TypeSourceInfo *TSInfo = BaseSpec->getTypeSourceInfo())
5132 return cxloc::translateSourceLocation(getCursorContext(C),
5133 TSInfo->getTypeLoc().getBeginLoc());
5134
5135 return cxloc::translateSourceLocation(getCursorContext(C),
5136 BaseSpec->getLocStart());
5137 }
5138
5139 case CXCursor_LabelRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005140 std::pair<const LabelStmt *, SourceLocation> P = getCursorLabelRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005141 return cxloc::translateSourceLocation(getCursorContext(C), P.second);
5142 }
5143
5144 case CXCursor_OverloadedDeclRef:
5145 return cxloc::translateSourceLocation(getCursorContext(C),
5146 getCursorOverloadedDeclRef(C).second);
5147
5148 default:
5149 // FIXME: Need a way to enumerate all non-reference cases.
5150 llvm_unreachable("Missed a reference kind");
5151 }
5152 }
5153
5154 if (clang_isExpression(C.kind))
5155 return cxloc::translateSourceLocation(getCursorContext(C),
5156 getLocationFromExpr(getCursorExpr(C)));
5157
5158 if (clang_isStatement(C.kind))
5159 return cxloc::translateSourceLocation(getCursorContext(C),
5160 getCursorStmt(C)->getLocStart());
5161
5162 if (C.kind == CXCursor_PreprocessingDirective) {
5163 SourceLocation L = cxcursor::getCursorPreprocessingDirective(C).getBegin();
5164 return cxloc::translateSourceLocation(getCursorContext(C), L);
5165 }
5166
5167 if (C.kind == CXCursor_MacroExpansion) {
5168 SourceLocation L
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00005169 = cxcursor::getCursorMacroExpansion(C).getSourceRange().getBegin();
Guy Benyei11169dd2012-12-18 14:30:41 +00005170 return cxloc::translateSourceLocation(getCursorContext(C), L);
5171 }
5172
5173 if (C.kind == CXCursor_MacroDefinition) {
5174 SourceLocation L = cxcursor::getCursorMacroDefinition(C)->getLocation();
5175 return cxloc::translateSourceLocation(getCursorContext(C), L);
5176 }
5177
5178 if (C.kind == CXCursor_InclusionDirective) {
5179 SourceLocation L
5180 = cxcursor::getCursorInclusionDirective(C)->getSourceRange().getBegin();
5181 return cxloc::translateSourceLocation(getCursorContext(C), L);
5182 }
5183
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00005184 if (clang_isAttribute(C.kind)) {
5185 SourceLocation L
5186 = cxcursor::getCursorAttr(C)->getLocation();
5187 return cxloc::translateSourceLocation(getCursorContext(C), L);
5188 }
5189
Guy Benyei11169dd2012-12-18 14:30:41 +00005190 if (!clang_isDeclaration(C.kind))
5191 return clang_getNullLocation();
5192
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005193 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005194 if (!D)
5195 return clang_getNullLocation();
5196
5197 SourceLocation Loc = D->getLocation();
5198 // FIXME: Multiple variables declared in a single declaration
5199 // currently lack the information needed to correctly determine their
5200 // ranges when accounting for the type-specifier. We use context
5201 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
5202 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005203 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005204 if (!cxcursor::isFirstInDeclGroup(C))
5205 Loc = VD->getLocation();
5206 }
5207
5208 // For ObjC methods, give the start location of the method name.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005209 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00005210 Loc = MD->getSelectorStartLoc();
5211
5212 return cxloc::translateSourceLocation(getCursorContext(C), Loc);
5213}
5214
5215} // end extern "C"
5216
5217CXCursor cxcursor::getCursor(CXTranslationUnit TU, SourceLocation SLoc) {
5218 assert(TU);
5219
5220 // Guard against an invalid SourceLocation, or we may assert in one
5221 // of the following calls.
5222 if (SLoc.isInvalid())
5223 return clang_getNullCursor();
5224
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005225 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005226
5227 // Translate the given source location to make it point at the beginning of
5228 // the token under the cursor.
5229 SLoc = Lexer::GetBeginningOfToken(SLoc, CXXUnit->getSourceManager(),
5230 CXXUnit->getASTContext().getLangOpts());
5231
5232 CXCursor Result = MakeCXCursorInvalid(CXCursor_NoDeclFound);
5233 if (SLoc.isValid()) {
5234 GetCursorData ResultData(CXXUnit->getSourceManager(), SLoc, Result);
5235 CursorVisitor CursorVis(TU, GetCursorVisitor, &ResultData,
5236 /*VisitPreprocessorLast=*/true,
5237 /*VisitIncludedEntities=*/false,
5238 SourceLocation(SLoc));
5239 CursorVis.visitFileRegion();
5240 }
5241
5242 return Result;
5243}
5244
5245static SourceRange getRawCursorExtent(CXCursor C) {
5246 if (clang_isReference(C.kind)) {
5247 switch (C.kind) {
5248 case CXCursor_ObjCSuperClassRef:
5249 return getCursorObjCSuperClassRef(C).second;
5250
5251 case CXCursor_ObjCProtocolRef:
5252 return getCursorObjCProtocolRef(C).second;
5253
5254 case CXCursor_ObjCClassRef:
5255 return getCursorObjCClassRef(C).second;
5256
5257 case CXCursor_TypeRef:
5258 return getCursorTypeRef(C).second;
5259
5260 case CXCursor_TemplateRef:
5261 return getCursorTemplateRef(C).second;
5262
5263 case CXCursor_NamespaceRef:
5264 return getCursorNamespaceRef(C).second;
5265
5266 case CXCursor_MemberRef:
5267 return getCursorMemberRef(C).second;
5268
5269 case CXCursor_CXXBaseSpecifier:
5270 return getCursorCXXBaseSpecifier(C)->getSourceRange();
5271
5272 case CXCursor_LabelRef:
5273 return getCursorLabelRef(C).second;
5274
5275 case CXCursor_OverloadedDeclRef:
5276 return getCursorOverloadedDeclRef(C).second;
5277
5278 case CXCursor_VariableRef:
5279 return getCursorVariableRef(C).second;
5280
5281 default:
5282 // FIXME: Need a way to enumerate all non-reference cases.
5283 llvm_unreachable("Missed a reference kind");
5284 }
5285 }
5286
5287 if (clang_isExpression(C.kind))
5288 return getCursorExpr(C)->getSourceRange();
5289
5290 if (clang_isStatement(C.kind))
5291 return getCursorStmt(C)->getSourceRange();
5292
5293 if (clang_isAttribute(C.kind))
5294 return getCursorAttr(C)->getRange();
5295
5296 if (C.kind == CXCursor_PreprocessingDirective)
5297 return cxcursor::getCursorPreprocessingDirective(C);
5298
5299 if (C.kind == CXCursor_MacroExpansion) {
5300 ASTUnit *TU = getCursorASTUnit(C);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00005301 SourceRange Range = cxcursor::getCursorMacroExpansion(C).getSourceRange();
Guy Benyei11169dd2012-12-18 14:30:41 +00005302 return TU->mapRangeFromPreamble(Range);
5303 }
5304
5305 if (C.kind == CXCursor_MacroDefinition) {
5306 ASTUnit *TU = getCursorASTUnit(C);
5307 SourceRange Range = cxcursor::getCursorMacroDefinition(C)->getSourceRange();
5308 return TU->mapRangeFromPreamble(Range);
5309 }
5310
5311 if (C.kind == CXCursor_InclusionDirective) {
5312 ASTUnit *TU = getCursorASTUnit(C);
5313 SourceRange Range = cxcursor::getCursorInclusionDirective(C)->getSourceRange();
5314 return TU->mapRangeFromPreamble(Range);
5315 }
5316
5317 if (C.kind == CXCursor_TranslationUnit) {
5318 ASTUnit *TU = getCursorASTUnit(C);
5319 FileID MainID = TU->getSourceManager().getMainFileID();
5320 SourceLocation Start = TU->getSourceManager().getLocForStartOfFile(MainID);
5321 SourceLocation End = TU->getSourceManager().getLocForEndOfFile(MainID);
5322 return SourceRange(Start, End);
5323 }
5324
5325 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005326 const Decl *D = cxcursor::getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005327 if (!D)
5328 return SourceRange();
5329
5330 SourceRange R = D->getSourceRange();
5331 // FIXME: Multiple variables declared in a single declaration
5332 // currently lack the information needed to correctly determine their
5333 // ranges when accounting for the type-specifier. We use context
5334 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
5335 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005336 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005337 if (!cxcursor::isFirstInDeclGroup(C))
5338 R.setBegin(VD->getLocation());
5339 }
5340 return R;
5341 }
5342 return SourceRange();
5343}
5344
5345/// \brief Retrieves the "raw" cursor extent, which is then extended to include
5346/// the decl-specifier-seq for declarations.
5347static SourceRange getFullCursorExtent(CXCursor C, SourceManager &SrcMgr) {
5348 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005349 const Decl *D = cxcursor::getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005350 if (!D)
5351 return SourceRange();
5352
5353 SourceRange R = D->getSourceRange();
5354
5355 // Adjust the start of the location for declarations preceded by
5356 // declaration specifiers.
5357 SourceLocation StartLoc;
5358 if (const DeclaratorDecl *DD = dyn_cast<DeclaratorDecl>(D)) {
5359 if (TypeSourceInfo *TI = DD->getTypeSourceInfo())
5360 StartLoc = TI->getTypeLoc().getLocStart();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005361 } else if (const TypedefDecl *Typedef = dyn_cast<TypedefDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005362 if (TypeSourceInfo *TI = Typedef->getTypeSourceInfo())
5363 StartLoc = TI->getTypeLoc().getLocStart();
5364 }
5365
5366 if (StartLoc.isValid() && R.getBegin().isValid() &&
5367 SrcMgr.isBeforeInTranslationUnit(StartLoc, R.getBegin()))
5368 R.setBegin(StartLoc);
5369
5370 // FIXME: Multiple variables declared in a single declaration
5371 // currently lack the information needed to correctly determine their
5372 // ranges when accounting for the type-specifier. We use context
5373 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
5374 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005375 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005376 if (!cxcursor::isFirstInDeclGroup(C))
5377 R.setBegin(VD->getLocation());
5378 }
5379
5380 return R;
5381 }
5382
5383 return getRawCursorExtent(C);
5384}
5385
5386extern "C" {
5387
5388CXSourceRange clang_getCursorExtent(CXCursor C) {
5389 SourceRange R = getRawCursorExtent(C);
5390 if (R.isInvalid())
5391 return clang_getNullRange();
5392
5393 return cxloc::translateSourceRange(getCursorContext(C), R);
5394}
5395
5396CXCursor clang_getCursorReferenced(CXCursor C) {
5397 if (clang_isInvalid(C.kind))
5398 return clang_getNullCursor();
5399
5400 CXTranslationUnit tu = getCursorTU(C);
5401 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005402 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005403 if (!D)
5404 return clang_getNullCursor();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005405 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00005406 return MakeCursorOverloadedDeclRef(Using, D->getLocation(), tu);
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005407 if (const ObjCPropertyImplDecl *PropImpl =
5408 dyn_cast<ObjCPropertyImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00005409 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
5410 return MakeCXCursor(Property, tu);
5411
5412 return C;
5413 }
5414
5415 if (clang_isExpression(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005416 const Expr *E = getCursorExpr(C);
5417 const Decl *D = getDeclFromExpr(E);
Guy Benyei11169dd2012-12-18 14:30:41 +00005418 if (D) {
5419 CXCursor declCursor = MakeCXCursor(D, tu);
5420 declCursor = getSelectorIdentifierCursor(getSelectorIdentifierIndex(C),
5421 declCursor);
5422 return declCursor;
5423 }
5424
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005425 if (const OverloadExpr *Ovl = dyn_cast_or_null<OverloadExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00005426 return MakeCursorOverloadedDeclRef(Ovl, tu);
5427
5428 return clang_getNullCursor();
5429 }
5430
5431 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005432 const Stmt *S = getCursorStmt(C);
5433 if (const GotoStmt *Goto = dyn_cast_or_null<GotoStmt>(S))
Guy Benyei11169dd2012-12-18 14:30:41 +00005434 if (LabelDecl *label = Goto->getLabel())
5435 if (LabelStmt *labelS = label->getStmt())
5436 return MakeCXCursor(labelS, getCursorDecl(C), tu);
5437
5438 return clang_getNullCursor();
5439 }
Richard Smith66a81862015-05-04 02:25:31 +00005440
Guy Benyei11169dd2012-12-18 14:30:41 +00005441 if (C.kind == CXCursor_MacroExpansion) {
Richard Smith66a81862015-05-04 02:25:31 +00005442 if (const MacroDefinitionRecord *Def =
5443 getCursorMacroExpansion(C).getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005444 return MakeMacroDefinitionCursor(Def, tu);
5445 }
5446
5447 if (!clang_isReference(C.kind))
5448 return clang_getNullCursor();
5449
5450 switch (C.kind) {
5451 case CXCursor_ObjCSuperClassRef:
5452 return MakeCXCursor(getCursorObjCSuperClassRef(C).first, tu);
5453
5454 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005455 const ObjCProtocolDecl *Prot = getCursorObjCProtocolRef(C).first;
5456 if (const ObjCProtocolDecl *Def = Prot->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005457 return MakeCXCursor(Def, tu);
5458
5459 return MakeCXCursor(Prot, tu);
5460 }
5461
5462 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005463 const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
5464 if (const ObjCInterfaceDecl *Def = Class->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005465 return MakeCXCursor(Def, tu);
5466
5467 return MakeCXCursor(Class, tu);
5468 }
5469
5470 case CXCursor_TypeRef:
5471 return MakeCXCursor(getCursorTypeRef(C).first, tu );
5472
5473 case CXCursor_TemplateRef:
5474 return MakeCXCursor(getCursorTemplateRef(C).first, tu );
5475
5476 case CXCursor_NamespaceRef:
5477 return MakeCXCursor(getCursorNamespaceRef(C).first, tu );
5478
5479 case CXCursor_MemberRef:
5480 return MakeCXCursor(getCursorMemberRef(C).first, tu );
5481
5482 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005483 const CXXBaseSpecifier *B = cxcursor::getCursorCXXBaseSpecifier(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005484 return clang_getTypeDeclaration(cxtype::MakeCXType(B->getType(),
5485 tu ));
5486 }
5487
5488 case CXCursor_LabelRef:
5489 // FIXME: We end up faking the "parent" declaration here because we
5490 // don't want to make CXCursor larger.
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005491 return MakeCXCursor(getCursorLabelRef(C).first,
5492 cxtu::getASTUnit(tu)->getASTContext()
5493 .getTranslationUnitDecl(),
Guy Benyei11169dd2012-12-18 14:30:41 +00005494 tu);
5495
5496 case CXCursor_OverloadedDeclRef:
5497 return C;
5498
5499 case CXCursor_VariableRef:
5500 return MakeCXCursor(getCursorVariableRef(C).first, tu);
5501
5502 default:
5503 // We would prefer to enumerate all non-reference cursor kinds here.
5504 llvm_unreachable("Unhandled reference cursor kind");
5505 }
5506}
5507
5508CXCursor clang_getCursorDefinition(CXCursor C) {
5509 if (clang_isInvalid(C.kind))
5510 return clang_getNullCursor();
5511
5512 CXTranslationUnit TU = getCursorTU(C);
5513
5514 bool WasReference = false;
5515 if (clang_isReference(C.kind) || clang_isExpression(C.kind)) {
5516 C = clang_getCursorReferenced(C);
5517 WasReference = true;
5518 }
5519
5520 if (C.kind == CXCursor_MacroExpansion)
5521 return clang_getCursorReferenced(C);
5522
5523 if (!clang_isDeclaration(C.kind))
5524 return clang_getNullCursor();
5525
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005526 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005527 if (!D)
5528 return clang_getNullCursor();
5529
5530 switch (D->getKind()) {
5531 // Declaration kinds that don't really separate the notions of
5532 // declaration and definition.
5533 case Decl::Namespace:
5534 case Decl::Typedef:
5535 case Decl::TypeAlias:
5536 case Decl::TypeAliasTemplate:
5537 case Decl::TemplateTypeParm:
5538 case Decl::EnumConstant:
5539 case Decl::Field:
John McCall5e77d762013-04-16 07:28:30 +00005540 case Decl::MSProperty:
Guy Benyei11169dd2012-12-18 14:30:41 +00005541 case Decl::IndirectField:
5542 case Decl::ObjCIvar:
5543 case Decl::ObjCAtDefsField:
5544 case Decl::ImplicitParam:
5545 case Decl::ParmVar:
5546 case Decl::NonTypeTemplateParm:
5547 case Decl::TemplateTemplateParm:
5548 case Decl::ObjCCategoryImpl:
5549 case Decl::ObjCImplementation:
5550 case Decl::AccessSpec:
5551 case Decl::LinkageSpec:
5552 case Decl::ObjCPropertyImpl:
5553 case Decl::FileScopeAsm:
5554 case Decl::StaticAssert:
5555 case Decl::Block:
Tareq A. Siraj6dfa25a2013-04-16 19:37:38 +00005556 case Decl::Captured:
Alexey Bataev4244be22016-02-11 05:35:55 +00005557 case Decl::OMPCapturedExpr:
Guy Benyei11169dd2012-12-18 14:30:41 +00005558 case Decl::Label: // FIXME: Is this right??
5559 case Decl::ClassScopeFunctionSpecialization:
5560 case Decl::Import:
Alexey Bataeva769e072013-03-22 06:34:35 +00005561 case Decl::OMPThreadPrivate:
Alexey Bataev94a4f0c2016-03-03 05:21:39 +00005562 case Decl::OMPDeclareReduction:
Douglas Gregor85f3f952015-07-07 03:57:15 +00005563 case Decl::ObjCTypeParam:
David Majnemerd9b1a4f2015-11-04 03:40:30 +00005564 case Decl::BuiltinTemplate:
Nico Weber66220292016-03-02 17:28:48 +00005565 case Decl::PragmaComment:
Nico Webercbbaeb12016-03-02 19:28:54 +00005566 case Decl::PragmaDetectMismatch:
Guy Benyei11169dd2012-12-18 14:30:41 +00005567 return C;
5568
5569 // Declaration kinds that don't make any sense here, but are
5570 // nonetheless harmless.
David Blaikief005d3c2013-02-22 17:44:58 +00005571 case Decl::Empty:
Guy Benyei11169dd2012-12-18 14:30:41 +00005572 case Decl::TranslationUnit:
Richard Smithf19e1272015-03-07 00:04:49 +00005573 case Decl::ExternCContext:
Guy Benyei11169dd2012-12-18 14:30:41 +00005574 break;
5575
5576 // Declaration kinds for which the definition is not resolvable.
5577 case Decl::UnresolvedUsingTypename:
5578 case Decl::UnresolvedUsingValue:
5579 break;
5580
5581 case Decl::UsingDirective:
5582 return MakeCXCursor(cast<UsingDirectiveDecl>(D)->getNominatedNamespace(),
5583 TU);
5584
5585 case Decl::NamespaceAlias:
5586 return MakeCXCursor(cast<NamespaceAliasDecl>(D)->getNamespace(), TU);
5587
5588 case Decl::Enum:
5589 case Decl::Record:
5590 case Decl::CXXRecord:
5591 case Decl::ClassTemplateSpecialization:
5592 case Decl::ClassTemplatePartialSpecialization:
5593 if (TagDecl *Def = cast<TagDecl>(D)->getDefinition())
5594 return MakeCXCursor(Def, TU);
5595 return clang_getNullCursor();
5596
5597 case Decl::Function:
5598 case Decl::CXXMethod:
5599 case Decl::CXXConstructor:
5600 case Decl::CXXDestructor:
5601 case Decl::CXXConversion: {
Craig Topper69186e72014-06-08 08:38:04 +00005602 const FunctionDecl *Def = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005603 if (cast<FunctionDecl>(D)->getBody(Def))
Dmitri Gribenko9c256e32013-01-14 00:46:27 +00005604 return MakeCXCursor(Def, TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005605 return clang_getNullCursor();
5606 }
5607
Larisse Voufo39a1e502013-08-06 01:03:05 +00005608 case Decl::Var:
5609 case Decl::VarTemplateSpecialization:
5610 case Decl::VarTemplatePartialSpecialization: {
Guy Benyei11169dd2012-12-18 14:30:41 +00005611 // Ask the variable if it has a definition.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005612 if (const VarDecl *Def = cast<VarDecl>(D)->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005613 return MakeCXCursor(Def, TU);
5614 return clang_getNullCursor();
5615 }
5616
5617 case Decl::FunctionTemplate: {
Craig Topper69186e72014-06-08 08:38:04 +00005618 const FunctionDecl *Def = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005619 if (cast<FunctionTemplateDecl>(D)->getTemplatedDecl()->getBody(Def))
5620 return MakeCXCursor(Def->getDescribedFunctionTemplate(), TU);
5621 return clang_getNullCursor();
5622 }
5623
5624 case Decl::ClassTemplate: {
5625 if (RecordDecl *Def = cast<ClassTemplateDecl>(D)->getTemplatedDecl()
5626 ->getDefinition())
5627 return MakeCXCursor(cast<CXXRecordDecl>(Def)->getDescribedClassTemplate(),
5628 TU);
5629 return clang_getNullCursor();
5630 }
5631
Larisse Voufo39a1e502013-08-06 01:03:05 +00005632 case Decl::VarTemplate: {
5633 if (VarDecl *Def =
5634 cast<VarTemplateDecl>(D)->getTemplatedDecl()->getDefinition())
5635 return MakeCXCursor(cast<VarDecl>(Def)->getDescribedVarTemplate(), TU);
5636 return clang_getNullCursor();
5637 }
5638
Guy Benyei11169dd2012-12-18 14:30:41 +00005639 case Decl::Using:
5640 return MakeCursorOverloadedDeclRef(cast<UsingDecl>(D),
5641 D->getLocation(), TU);
5642
5643 case Decl::UsingShadow:
5644 return clang_getCursorDefinition(
5645 MakeCXCursor(cast<UsingShadowDecl>(D)->getTargetDecl(),
5646 TU));
5647
5648 case Decl::ObjCMethod: {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005649 const ObjCMethodDecl *Method = cast<ObjCMethodDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00005650 if (Method->isThisDeclarationADefinition())
5651 return C;
5652
5653 // Dig out the method definition in the associated
5654 // @implementation, if we have it.
5655 // FIXME: The ASTs should make finding the definition easier.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005656 if (const ObjCInterfaceDecl *Class
Guy Benyei11169dd2012-12-18 14:30:41 +00005657 = dyn_cast<ObjCInterfaceDecl>(Method->getDeclContext()))
5658 if (ObjCImplementationDecl *ClassImpl = Class->getImplementation())
5659 if (ObjCMethodDecl *Def = ClassImpl->getMethod(Method->getSelector(),
5660 Method->isInstanceMethod()))
5661 if (Def->isThisDeclarationADefinition())
5662 return MakeCXCursor(Def, TU);
5663
5664 return clang_getNullCursor();
5665 }
5666
5667 case Decl::ObjCCategory:
5668 if (ObjCCategoryImplDecl *Impl
5669 = cast<ObjCCategoryDecl>(D)->getImplementation())
5670 return MakeCXCursor(Impl, TU);
5671 return clang_getNullCursor();
5672
5673 case Decl::ObjCProtocol:
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005674 if (const ObjCProtocolDecl *Def = cast<ObjCProtocolDecl>(D)->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005675 return MakeCXCursor(Def, TU);
5676 return clang_getNullCursor();
5677
5678 case Decl::ObjCInterface: {
5679 // There are two notions of a "definition" for an Objective-C
5680 // class: the interface and its implementation. When we resolved a
5681 // reference to an Objective-C class, produce the @interface as
5682 // the definition; when we were provided with the interface,
5683 // produce the @implementation as the definition.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005684 const ObjCInterfaceDecl *IFace = cast<ObjCInterfaceDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00005685 if (WasReference) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005686 if (const ObjCInterfaceDecl *Def = IFace->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005687 return MakeCXCursor(Def, TU);
5688 } else if (ObjCImplementationDecl *Impl = IFace->getImplementation())
5689 return MakeCXCursor(Impl, TU);
5690 return clang_getNullCursor();
5691 }
5692
5693 case Decl::ObjCProperty:
5694 // FIXME: We don't really know where to find the
5695 // ObjCPropertyImplDecls that implement this property.
5696 return clang_getNullCursor();
5697
5698 case Decl::ObjCCompatibleAlias:
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005699 if (const ObjCInterfaceDecl *Class
Guy Benyei11169dd2012-12-18 14:30:41 +00005700 = cast<ObjCCompatibleAliasDecl>(D)->getClassInterface())
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005701 if (const ObjCInterfaceDecl *Def = Class->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005702 return MakeCXCursor(Def, TU);
5703
5704 return clang_getNullCursor();
5705
5706 case Decl::Friend:
5707 if (NamedDecl *Friend = cast<FriendDecl>(D)->getFriendDecl())
5708 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
5709 return clang_getNullCursor();
5710
5711 case Decl::FriendTemplate:
5712 if (NamedDecl *Friend = cast<FriendTemplateDecl>(D)->getFriendDecl())
5713 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
5714 return clang_getNullCursor();
5715 }
5716
5717 return clang_getNullCursor();
5718}
5719
5720unsigned clang_isCursorDefinition(CXCursor C) {
5721 if (!clang_isDeclaration(C.kind))
5722 return 0;
5723
5724 return clang_getCursorDefinition(C) == C;
5725}
5726
5727CXCursor clang_getCanonicalCursor(CXCursor C) {
5728 if (!clang_isDeclaration(C.kind))
5729 return C;
5730
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005731 if (const Decl *D = getCursorDecl(C)) {
5732 if (const ObjCCategoryImplDecl *CatImplD = dyn_cast<ObjCCategoryImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00005733 if (ObjCCategoryDecl *CatD = CatImplD->getCategoryDecl())
5734 return MakeCXCursor(CatD, getCursorTU(C));
5735
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005736 if (const ObjCImplDecl *ImplD = dyn_cast<ObjCImplDecl>(D))
5737 if (const ObjCInterfaceDecl *IFD = ImplD->getClassInterface())
Guy Benyei11169dd2012-12-18 14:30:41 +00005738 return MakeCXCursor(IFD, getCursorTU(C));
5739
5740 return MakeCXCursor(D->getCanonicalDecl(), getCursorTU(C));
5741 }
5742
5743 return C;
5744}
5745
5746int clang_Cursor_getObjCSelectorIndex(CXCursor cursor) {
5747 return cxcursor::getSelectorIdentifierIndexAndLoc(cursor).first;
5748}
5749
5750unsigned clang_getNumOverloadedDecls(CXCursor C) {
5751 if (C.kind != CXCursor_OverloadedDeclRef)
5752 return 0;
5753
5754 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005755 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Guy Benyei11169dd2012-12-18 14:30:41 +00005756 return E->getNumDecls();
5757
5758 if (OverloadedTemplateStorage *S
5759 = Storage.dyn_cast<OverloadedTemplateStorage*>())
5760 return S->size();
5761
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005762 const Decl *D = Storage.get<const Decl *>();
5763 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00005764 return Using->shadow_size();
5765
5766 return 0;
5767}
5768
5769CXCursor clang_getOverloadedDecl(CXCursor cursor, unsigned index) {
5770 if (cursor.kind != CXCursor_OverloadedDeclRef)
5771 return clang_getNullCursor();
5772
5773 if (index >= clang_getNumOverloadedDecls(cursor))
5774 return clang_getNullCursor();
5775
5776 CXTranslationUnit TU = getCursorTU(cursor);
5777 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(cursor).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005778 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Guy Benyei11169dd2012-12-18 14:30:41 +00005779 return MakeCXCursor(E->decls_begin()[index], TU);
5780
5781 if (OverloadedTemplateStorage *S
5782 = Storage.dyn_cast<OverloadedTemplateStorage*>())
5783 return MakeCXCursor(S->begin()[index], TU);
5784
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005785 const Decl *D = Storage.get<const Decl *>();
5786 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005787 // FIXME: This is, unfortunately, linear time.
5788 UsingDecl::shadow_iterator Pos = Using->shadow_begin();
5789 std::advance(Pos, index);
5790 return MakeCXCursor(cast<UsingShadowDecl>(*Pos)->getTargetDecl(), TU);
5791 }
5792
5793 return clang_getNullCursor();
5794}
5795
5796void clang_getDefinitionSpellingAndExtent(CXCursor C,
5797 const char **startBuf,
5798 const char **endBuf,
5799 unsigned *startLine,
5800 unsigned *startColumn,
5801 unsigned *endLine,
5802 unsigned *endColumn) {
5803 assert(getCursorDecl(C) && "CXCursor has null decl");
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005804 const FunctionDecl *FD = dyn_cast<FunctionDecl>(getCursorDecl(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00005805 CompoundStmt *Body = dyn_cast<CompoundStmt>(FD->getBody());
5806
5807 SourceManager &SM = FD->getASTContext().getSourceManager();
5808 *startBuf = SM.getCharacterData(Body->getLBracLoc());
5809 *endBuf = SM.getCharacterData(Body->getRBracLoc());
5810 *startLine = SM.getSpellingLineNumber(Body->getLBracLoc());
5811 *startColumn = SM.getSpellingColumnNumber(Body->getLBracLoc());
5812 *endLine = SM.getSpellingLineNumber(Body->getRBracLoc());
5813 *endColumn = SM.getSpellingColumnNumber(Body->getRBracLoc());
5814}
5815
5816
5817CXSourceRange clang_getCursorReferenceNameRange(CXCursor C, unsigned NameFlags,
5818 unsigned PieceIndex) {
5819 RefNamePieces Pieces;
5820
5821 switch (C.kind) {
5822 case CXCursor_MemberRefExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005823 if (const MemberExpr *E = dyn_cast<MemberExpr>(getCursorExpr(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00005824 Pieces = buildPieces(NameFlags, true, E->getMemberNameInfo(),
5825 E->getQualifierLoc().getSourceRange());
5826 break;
5827
5828 case CXCursor_DeclRefExpr:
James Y Knight04ec5bf2015-12-24 02:59:37 +00005829 if (const DeclRefExpr *E = dyn_cast<DeclRefExpr>(getCursorExpr(C))) {
5830 SourceRange TemplateArgLoc(E->getLAngleLoc(), E->getRAngleLoc());
5831 Pieces =
5832 buildPieces(NameFlags, false, E->getNameInfo(),
5833 E->getQualifierLoc().getSourceRange(), &TemplateArgLoc);
5834 }
Guy Benyei11169dd2012-12-18 14:30:41 +00005835 break;
5836
5837 case CXCursor_CallExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005838 if (const CXXOperatorCallExpr *OCE =
Guy Benyei11169dd2012-12-18 14:30:41 +00005839 dyn_cast<CXXOperatorCallExpr>(getCursorExpr(C))) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005840 const Expr *Callee = OCE->getCallee();
5841 if (const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Callee))
Guy Benyei11169dd2012-12-18 14:30:41 +00005842 Callee = ICE->getSubExpr();
5843
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005844 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(Callee))
Guy Benyei11169dd2012-12-18 14:30:41 +00005845 Pieces = buildPieces(NameFlags, false, DRE->getNameInfo(),
5846 DRE->getQualifierLoc().getSourceRange());
5847 }
5848 break;
5849
5850 default:
5851 break;
5852 }
5853
5854 if (Pieces.empty()) {
5855 if (PieceIndex == 0)
5856 return clang_getCursorExtent(C);
5857 } else if (PieceIndex < Pieces.size()) {
5858 SourceRange R = Pieces[PieceIndex];
5859 if (R.isValid())
5860 return cxloc::translateSourceRange(getCursorContext(C), R);
5861 }
5862
5863 return clang_getNullRange();
5864}
5865
5866void clang_enableStackTraces(void) {
5867 llvm::sys::PrintStackTraceOnErrorSignal();
5868}
5869
5870void clang_executeOnThread(void (*fn)(void*), void *user_data,
5871 unsigned stack_size) {
5872 llvm::llvm_execute_on_thread(fn, user_data, stack_size);
5873}
5874
5875} // end: extern "C"
5876
5877//===----------------------------------------------------------------------===//
5878// Token-based Operations.
5879//===----------------------------------------------------------------------===//
5880
5881/* CXToken layout:
5882 * int_data[0]: a CXTokenKind
5883 * int_data[1]: starting token location
5884 * int_data[2]: token length
5885 * int_data[3]: reserved
5886 * ptr_data: for identifiers and keywords, an IdentifierInfo*.
5887 * otherwise unused.
5888 */
5889extern "C" {
5890
5891CXTokenKind clang_getTokenKind(CXToken CXTok) {
5892 return static_cast<CXTokenKind>(CXTok.int_data[0]);
5893}
5894
5895CXString clang_getTokenSpelling(CXTranslationUnit TU, CXToken CXTok) {
5896 switch (clang_getTokenKind(CXTok)) {
5897 case CXToken_Identifier:
5898 case CXToken_Keyword:
5899 // We know we have an IdentifierInfo*, so use that.
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005900 return cxstring::createRef(static_cast<IdentifierInfo *>(CXTok.ptr_data)
Guy Benyei11169dd2012-12-18 14:30:41 +00005901 ->getNameStart());
5902
5903 case CXToken_Literal: {
5904 // We have stashed the starting pointer in the ptr_data field. Use it.
5905 const char *Text = static_cast<const char *>(CXTok.ptr_data);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00005906 return cxstring::createDup(StringRef(Text, CXTok.int_data[2]));
Guy Benyei11169dd2012-12-18 14:30:41 +00005907 }
5908
5909 case CXToken_Punctuation:
5910 case CXToken_Comment:
5911 break;
5912 }
5913
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005914 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005915 LOG_BAD_TU(TU);
5916 return cxstring::createEmpty();
5917 }
5918
Guy Benyei11169dd2012-12-18 14:30:41 +00005919 // We have to find the starting buffer pointer the hard way, by
5920 // deconstructing the source location.
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005921 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005922 if (!CXXUnit)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00005923 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00005924
5925 SourceLocation Loc = SourceLocation::getFromRawEncoding(CXTok.int_data[1]);
5926 std::pair<FileID, unsigned> LocInfo
5927 = CXXUnit->getSourceManager().getDecomposedSpellingLoc(Loc);
5928 bool Invalid = false;
5929 StringRef Buffer
5930 = CXXUnit->getSourceManager().getBufferData(LocInfo.first, &Invalid);
5931 if (Invalid)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00005932 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00005933
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00005934 return cxstring::createDup(Buffer.substr(LocInfo.second, CXTok.int_data[2]));
Guy Benyei11169dd2012-12-18 14:30:41 +00005935}
5936
5937CXSourceLocation clang_getTokenLocation(CXTranslationUnit TU, CXToken CXTok) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005938 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005939 LOG_BAD_TU(TU);
5940 return clang_getNullLocation();
5941 }
5942
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005943 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005944 if (!CXXUnit)
5945 return clang_getNullLocation();
5946
5947 return cxloc::translateSourceLocation(CXXUnit->getASTContext(),
5948 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
5949}
5950
5951CXSourceRange clang_getTokenExtent(CXTranslationUnit TU, CXToken CXTok) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005952 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005953 LOG_BAD_TU(TU);
5954 return clang_getNullRange();
5955 }
5956
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005957 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005958 if (!CXXUnit)
5959 return clang_getNullRange();
5960
5961 return cxloc::translateSourceRange(CXXUnit->getASTContext(),
5962 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
5963}
5964
5965static void getTokens(ASTUnit *CXXUnit, SourceRange Range,
5966 SmallVectorImpl<CXToken> &CXTokens) {
5967 SourceManager &SourceMgr = CXXUnit->getSourceManager();
5968 std::pair<FileID, unsigned> BeginLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005969 = SourceMgr.getDecomposedSpellingLoc(Range.getBegin());
Guy Benyei11169dd2012-12-18 14:30:41 +00005970 std::pair<FileID, unsigned> EndLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005971 = SourceMgr.getDecomposedSpellingLoc(Range.getEnd());
Guy Benyei11169dd2012-12-18 14:30:41 +00005972
5973 // Cannot tokenize across files.
5974 if (BeginLocInfo.first != EndLocInfo.first)
5975 return;
5976
5977 // Create a lexer
5978 bool Invalid = false;
5979 StringRef Buffer
5980 = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
5981 if (Invalid)
5982 return;
5983
5984 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
5985 CXXUnit->getASTContext().getLangOpts(),
5986 Buffer.begin(), Buffer.data() + BeginLocInfo.second, Buffer.end());
5987 Lex.SetCommentRetentionState(true);
5988
5989 // Lex tokens until we hit the end of the range.
5990 const char *EffectiveBufferEnd = Buffer.data() + EndLocInfo.second;
5991 Token Tok;
5992 bool previousWasAt = false;
5993 do {
5994 // Lex the next token
5995 Lex.LexFromRawLexer(Tok);
5996 if (Tok.is(tok::eof))
5997 break;
5998
5999 // Initialize the CXToken.
6000 CXToken CXTok;
6001
6002 // - Common fields
6003 CXTok.int_data[1] = Tok.getLocation().getRawEncoding();
6004 CXTok.int_data[2] = Tok.getLength();
6005 CXTok.int_data[3] = 0;
6006
6007 // - Kind-specific fields
6008 if (Tok.isLiteral()) {
6009 CXTok.int_data[0] = CXToken_Literal;
Dmitri Gribenkof9304482013-01-23 15:56:07 +00006010 CXTok.ptr_data = const_cast<char *>(Tok.getLiteralData());
Guy Benyei11169dd2012-12-18 14:30:41 +00006011 } else if (Tok.is(tok::raw_identifier)) {
6012 // Lookup the identifier to determine whether we have a keyword.
6013 IdentifierInfo *II
6014 = CXXUnit->getPreprocessor().LookUpIdentifierInfo(Tok);
6015
6016 if ((II->getObjCKeywordID() != tok::objc_not_keyword) && previousWasAt) {
6017 CXTok.int_data[0] = CXToken_Keyword;
6018 }
6019 else {
6020 CXTok.int_data[0] = Tok.is(tok::identifier)
6021 ? CXToken_Identifier
6022 : CXToken_Keyword;
6023 }
6024 CXTok.ptr_data = II;
6025 } else if (Tok.is(tok::comment)) {
6026 CXTok.int_data[0] = CXToken_Comment;
Craig Topper69186e72014-06-08 08:38:04 +00006027 CXTok.ptr_data = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006028 } else {
6029 CXTok.int_data[0] = CXToken_Punctuation;
Craig Topper69186e72014-06-08 08:38:04 +00006030 CXTok.ptr_data = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006031 }
6032 CXTokens.push_back(CXTok);
6033 previousWasAt = Tok.is(tok::at);
6034 } while (Lex.getBufferLocation() <= EffectiveBufferEnd);
6035}
6036
6037void clang_tokenize(CXTranslationUnit TU, CXSourceRange Range,
6038 CXToken **Tokens, unsigned *NumTokens) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006039 LOG_FUNC_SECTION {
6040 *Log << TU << ' ' << Range;
6041 }
6042
Guy Benyei11169dd2012-12-18 14:30:41 +00006043 if (Tokens)
Craig Topper69186e72014-06-08 08:38:04 +00006044 *Tokens = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006045 if (NumTokens)
6046 *NumTokens = 0;
6047
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006048 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006049 LOG_BAD_TU(TU);
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00006050 return;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006051 }
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00006052
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006053 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00006054 if (!CXXUnit || !Tokens || !NumTokens)
6055 return;
6056
6057 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
6058
6059 SourceRange R = cxloc::translateCXSourceRange(Range);
6060 if (R.isInvalid())
6061 return;
6062
6063 SmallVector<CXToken, 32> CXTokens;
6064 getTokens(CXXUnit, R, CXTokens);
6065
6066 if (CXTokens.empty())
6067 return;
6068
6069 *Tokens = (CXToken *)malloc(sizeof(CXToken) * CXTokens.size());
6070 memmove(*Tokens, CXTokens.data(), sizeof(CXToken) * CXTokens.size());
6071 *NumTokens = CXTokens.size();
6072}
6073
6074void clang_disposeTokens(CXTranslationUnit TU,
6075 CXToken *Tokens, unsigned NumTokens) {
6076 free(Tokens);
6077}
6078
6079} // end: extern "C"
6080
6081//===----------------------------------------------------------------------===//
6082// Token annotation APIs.
6083//===----------------------------------------------------------------------===//
6084
Guy Benyei11169dd2012-12-18 14:30:41 +00006085static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
6086 CXCursor parent,
6087 CXClientData client_data);
6088static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
6089 CXClientData client_data);
6090
6091namespace {
6092class AnnotateTokensWorker {
Guy Benyei11169dd2012-12-18 14:30:41 +00006093 CXToken *Tokens;
6094 CXCursor *Cursors;
6095 unsigned NumTokens;
6096 unsigned TokIdx;
6097 unsigned PreprocessingTokIdx;
6098 CursorVisitor AnnotateVis;
6099 SourceManager &SrcMgr;
6100 bool HasContextSensitiveKeywords;
6101
6102 struct PostChildrenInfo {
6103 CXCursor Cursor;
6104 SourceRange CursorRange;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00006105 unsigned BeforeReachingCursorIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00006106 unsigned BeforeChildrenTokenIdx;
6107 };
Dmitri Gribenkof8579502013-01-12 19:30:44 +00006108 SmallVector<PostChildrenInfo, 8> PostChildrenInfos;
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00006109
6110 CXToken &getTok(unsigned Idx) {
6111 assert(Idx < NumTokens);
6112 return Tokens[Idx];
6113 }
6114 const CXToken &getTok(unsigned Idx) const {
6115 assert(Idx < NumTokens);
6116 return Tokens[Idx];
6117 }
Guy Benyei11169dd2012-12-18 14:30:41 +00006118 bool MoreTokens() const { return TokIdx < NumTokens; }
6119 unsigned NextToken() const { return TokIdx; }
6120 void AdvanceToken() { ++TokIdx; }
6121 SourceLocation GetTokenLoc(unsigned tokI) {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00006122 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[1]);
Guy Benyei11169dd2012-12-18 14:30:41 +00006123 }
6124 bool isFunctionMacroToken(unsigned tokI) const {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00006125 return getTok(tokI).int_data[3] != 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00006126 }
6127 SourceLocation getFunctionMacroTokenLoc(unsigned tokI) const {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00006128 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[3]);
Guy Benyei11169dd2012-12-18 14:30:41 +00006129 }
6130
6131 void annotateAndAdvanceTokens(CXCursor, RangeComparisonResult, SourceRange);
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00006132 bool annotateAndAdvanceFunctionMacroTokens(CXCursor, RangeComparisonResult,
Guy Benyei11169dd2012-12-18 14:30:41 +00006133 SourceRange);
6134
6135public:
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006136 AnnotateTokensWorker(CXToken *tokens, CXCursor *cursors, unsigned numTokens,
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006137 CXTranslationUnit TU, SourceRange RegionOfInterest)
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006138 : Tokens(tokens), Cursors(cursors),
Guy Benyei11169dd2012-12-18 14:30:41 +00006139 NumTokens(numTokens), TokIdx(0), PreprocessingTokIdx(0),
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006140 AnnotateVis(TU,
Guy Benyei11169dd2012-12-18 14:30:41 +00006141 AnnotateTokensVisitor, this,
6142 /*VisitPreprocessorLast=*/true,
6143 /*VisitIncludedEntities=*/false,
6144 RegionOfInterest,
6145 /*VisitDeclsOnly=*/false,
6146 AnnotateTokensPostChildrenVisitor),
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006147 SrcMgr(cxtu::getASTUnit(TU)->getSourceManager()),
Guy Benyei11169dd2012-12-18 14:30:41 +00006148 HasContextSensitiveKeywords(false) { }
6149
6150 void VisitChildren(CXCursor C) { AnnotateVis.VisitChildren(C); }
6151 enum CXChildVisitResult Visit(CXCursor cursor, CXCursor parent);
6152 bool postVisitChildren(CXCursor cursor);
6153 void AnnotateTokens();
6154
6155 /// \brief Determine whether the annotator saw any cursors that have
6156 /// context-sensitive keywords.
6157 bool hasContextSensitiveKeywords() const {
6158 return HasContextSensitiveKeywords;
6159 }
6160
6161 ~AnnotateTokensWorker() {
6162 assert(PostChildrenInfos.empty());
6163 }
6164};
Alexander Kornienkoab9db512015-06-22 23:07:51 +00006165}
Guy Benyei11169dd2012-12-18 14:30:41 +00006166
6167void AnnotateTokensWorker::AnnotateTokens() {
6168 // Walk the AST within the region of interest, annotating tokens
6169 // along the way.
6170 AnnotateVis.visitFileRegion();
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006171}
Guy Benyei11169dd2012-12-18 14:30:41 +00006172
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006173static inline void updateCursorAnnotation(CXCursor &Cursor,
6174 const CXCursor &updateC) {
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00006175 if (clang_isInvalid(updateC.kind) || !clang_isInvalid(Cursor.kind))
Guy Benyei11169dd2012-12-18 14:30:41 +00006176 return;
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006177 Cursor = updateC;
Guy Benyei11169dd2012-12-18 14:30:41 +00006178}
6179
6180/// \brief It annotates and advances tokens with a cursor until the comparison
6181//// between the cursor location and the source range is the same as
6182/// \arg compResult.
6183///
6184/// Pass RangeBefore to annotate tokens with a cursor until a range is reached.
6185/// Pass RangeOverlap to annotate tokens inside a range.
6186void AnnotateTokensWorker::annotateAndAdvanceTokens(CXCursor updateC,
6187 RangeComparisonResult compResult,
6188 SourceRange range) {
6189 while (MoreTokens()) {
6190 const unsigned I = NextToken();
6191 if (isFunctionMacroToken(I))
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00006192 if (!annotateAndAdvanceFunctionMacroTokens(updateC, compResult, range))
6193 return;
Guy Benyei11169dd2012-12-18 14:30:41 +00006194
6195 SourceLocation TokLoc = GetTokenLoc(I);
6196 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006197 updateCursorAnnotation(Cursors[I], updateC);
Guy Benyei11169dd2012-12-18 14:30:41 +00006198 AdvanceToken();
6199 continue;
6200 }
6201 break;
6202 }
6203}
6204
6205/// \brief Special annotation handling for macro argument tokens.
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00006206/// \returns true if it advanced beyond all macro tokens, false otherwise.
6207bool AnnotateTokensWorker::annotateAndAdvanceFunctionMacroTokens(
Guy Benyei11169dd2012-12-18 14:30:41 +00006208 CXCursor updateC,
6209 RangeComparisonResult compResult,
6210 SourceRange range) {
6211 assert(MoreTokens());
6212 assert(isFunctionMacroToken(NextToken()) &&
6213 "Should be called only for macro arg tokens");
6214
6215 // This works differently than annotateAndAdvanceTokens; because expanded
6216 // macro arguments can have arbitrary translation-unit source order, we do not
6217 // advance the token index one by one until a token fails the range test.
6218 // We only advance once past all of the macro arg tokens if all of them
6219 // pass the range test. If one of them fails we keep the token index pointing
6220 // at the start of the macro arg tokens so that the failing token will be
6221 // annotated by a subsequent annotation try.
6222
6223 bool atLeastOneCompFail = false;
6224
6225 unsigned I = NextToken();
6226 for (; I < NumTokens && isFunctionMacroToken(I); ++I) {
6227 SourceLocation TokLoc = getFunctionMacroTokenLoc(I);
6228 if (TokLoc.isFileID())
6229 continue; // not macro arg token, it's parens or comma.
6230 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
6231 if (clang_isInvalid(clang_getCursorKind(Cursors[I])))
6232 Cursors[I] = updateC;
6233 } else
6234 atLeastOneCompFail = true;
6235 }
6236
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00006237 if (atLeastOneCompFail)
6238 return false;
6239
6240 TokIdx = I; // All of the tokens were handled, advance beyond all of them.
6241 return true;
Guy Benyei11169dd2012-12-18 14:30:41 +00006242}
6243
6244enum CXChildVisitResult
6245AnnotateTokensWorker::Visit(CXCursor cursor, CXCursor parent) {
Guy Benyei11169dd2012-12-18 14:30:41 +00006246 SourceRange cursorRange = getRawCursorExtent(cursor);
6247 if (cursorRange.isInvalid())
6248 return CXChildVisit_Recurse;
6249
6250 if (!HasContextSensitiveKeywords) {
6251 // Objective-C properties can have context-sensitive keywords.
6252 if (cursor.kind == CXCursor_ObjCPropertyDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006253 if (const ObjCPropertyDecl *Property
Guy Benyei11169dd2012-12-18 14:30:41 +00006254 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(cursor)))
6255 HasContextSensitiveKeywords = Property->getPropertyAttributesAsWritten() != 0;
6256 }
6257 // Objective-C methods can have context-sensitive keywords.
6258 else if (cursor.kind == CXCursor_ObjCInstanceMethodDecl ||
6259 cursor.kind == CXCursor_ObjCClassMethodDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006260 if (const ObjCMethodDecl *Method
Guy Benyei11169dd2012-12-18 14:30:41 +00006261 = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
6262 if (Method->getObjCDeclQualifier())
6263 HasContextSensitiveKeywords = true;
6264 else {
Aaron Ballman43b68be2014-03-07 17:50:17 +00006265 for (const auto *P : Method->params()) {
6266 if (P->getObjCDeclQualifier()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00006267 HasContextSensitiveKeywords = true;
6268 break;
6269 }
6270 }
6271 }
6272 }
6273 }
6274 // C++ methods can have context-sensitive keywords.
6275 else if (cursor.kind == CXCursor_CXXMethod) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006276 if (const CXXMethodDecl *Method
Guy Benyei11169dd2012-12-18 14:30:41 +00006277 = dyn_cast_or_null<CXXMethodDecl>(getCursorDecl(cursor))) {
6278 if (Method->hasAttr<FinalAttr>() || Method->hasAttr<OverrideAttr>())
6279 HasContextSensitiveKeywords = true;
6280 }
6281 }
6282 // C++ classes can have context-sensitive keywords.
6283 else if (cursor.kind == CXCursor_StructDecl ||
6284 cursor.kind == CXCursor_ClassDecl ||
6285 cursor.kind == CXCursor_ClassTemplate ||
6286 cursor.kind == CXCursor_ClassTemplatePartialSpecialization) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006287 if (const Decl *D = getCursorDecl(cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +00006288 if (D->hasAttr<FinalAttr>())
6289 HasContextSensitiveKeywords = true;
6290 }
6291 }
Argyrios Kyrtzidis990b3862013-06-04 18:24:30 +00006292
6293 // Don't override a property annotation with its getter/setter method.
6294 if (cursor.kind == CXCursor_ObjCInstanceMethodDecl &&
6295 parent.kind == CXCursor_ObjCPropertyDecl)
6296 return CXChildVisit_Continue;
Guy Benyei11169dd2012-12-18 14:30:41 +00006297
6298 if (clang_isPreprocessing(cursor.kind)) {
6299 // Items in the preprocessing record are kept separate from items in
6300 // declarations, so we keep a separate token index.
6301 unsigned SavedTokIdx = TokIdx;
6302 TokIdx = PreprocessingTokIdx;
6303
6304 // Skip tokens up until we catch up to the beginning of the preprocessing
6305 // entry.
6306 while (MoreTokens()) {
6307 const unsigned I = NextToken();
6308 SourceLocation TokLoc = GetTokenLoc(I);
6309 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
6310 case RangeBefore:
6311 AdvanceToken();
6312 continue;
6313 case RangeAfter:
6314 case RangeOverlap:
6315 break;
6316 }
6317 break;
6318 }
6319
6320 // Look at all of the tokens within this range.
6321 while (MoreTokens()) {
6322 const unsigned I = NextToken();
6323 SourceLocation TokLoc = GetTokenLoc(I);
6324 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
6325 case RangeBefore:
6326 llvm_unreachable("Infeasible");
6327 case RangeAfter:
6328 break;
6329 case RangeOverlap:
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00006330 // For macro expansions, just note where the beginning of the macro
6331 // expansion occurs.
6332 if (cursor.kind == CXCursor_MacroExpansion) {
6333 if (TokLoc == cursorRange.getBegin())
6334 Cursors[I] = cursor;
6335 AdvanceToken();
6336 break;
6337 }
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006338 // We may have already annotated macro names inside macro definitions.
6339 if (Cursors[I].kind != CXCursor_MacroExpansion)
6340 Cursors[I] = cursor;
Guy Benyei11169dd2012-12-18 14:30:41 +00006341 AdvanceToken();
Guy Benyei11169dd2012-12-18 14:30:41 +00006342 continue;
6343 }
6344 break;
6345 }
6346
6347 // Save the preprocessing token index; restore the non-preprocessing
6348 // token index.
6349 PreprocessingTokIdx = TokIdx;
6350 TokIdx = SavedTokIdx;
6351 return CXChildVisit_Recurse;
6352 }
6353
6354 if (cursorRange.isInvalid())
6355 return CXChildVisit_Continue;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00006356
6357 unsigned BeforeReachingCursorIdx = NextToken();
Guy Benyei11169dd2012-12-18 14:30:41 +00006358 const enum CXCursorKind cursorK = clang_getCursorKind(cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00006359 const enum CXCursorKind K = clang_getCursorKind(parent);
6360 const CXCursor updateC =
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00006361 (clang_isInvalid(K) || K == CXCursor_TranslationUnit ||
6362 // Attributes are annotated out-of-order, skip tokens until we reach it.
6363 clang_isAttribute(cursor.kind))
Guy Benyei11169dd2012-12-18 14:30:41 +00006364 ? clang_getNullCursor() : parent;
6365
6366 annotateAndAdvanceTokens(updateC, RangeBefore, cursorRange);
6367
6368 // Avoid having the cursor of an expression "overwrite" the annotation of the
6369 // variable declaration that it belongs to.
6370 // This can happen for C++ constructor expressions whose range generally
6371 // include the variable declaration, e.g.:
6372 // MyCXXClass foo; // Make sure we don't annotate 'foo' as a CallExpr cursor.
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00006373 if (clang_isExpression(cursorK) && MoreTokens()) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00006374 const Expr *E = getCursorExpr(cursor);
Dmitri Gribenkoa1691182013-01-26 18:12:08 +00006375 if (const Decl *D = getCursorParentDecl(cursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00006376 const unsigned I = NextToken();
6377 if (E->getLocStart().isValid() && D->getLocation().isValid() &&
6378 E->getLocStart() == D->getLocation() &&
6379 E->getLocStart() == GetTokenLoc(I)) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006380 updateCursorAnnotation(Cursors[I], updateC);
Guy Benyei11169dd2012-12-18 14:30:41 +00006381 AdvanceToken();
6382 }
6383 }
6384 }
6385
6386 // Before recursing into the children keep some state that we are going
6387 // to use in the AnnotateTokensWorker::postVisitChildren callback to do some
6388 // extra work after the child nodes are visited.
6389 // Note that we don't call VisitChildren here to avoid traversing statements
6390 // code-recursively which can blow the stack.
6391
6392 PostChildrenInfo Info;
6393 Info.Cursor = cursor;
6394 Info.CursorRange = cursorRange;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00006395 Info.BeforeReachingCursorIdx = BeforeReachingCursorIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00006396 Info.BeforeChildrenTokenIdx = NextToken();
6397 PostChildrenInfos.push_back(Info);
6398
6399 return CXChildVisit_Recurse;
6400}
6401
6402bool AnnotateTokensWorker::postVisitChildren(CXCursor cursor) {
6403 if (PostChildrenInfos.empty())
6404 return false;
6405 const PostChildrenInfo &Info = PostChildrenInfos.back();
6406 if (!clang_equalCursors(Info.Cursor, cursor))
6407 return false;
6408
6409 const unsigned BeforeChildren = Info.BeforeChildrenTokenIdx;
6410 const unsigned AfterChildren = NextToken();
6411 SourceRange cursorRange = Info.CursorRange;
6412
6413 // Scan the tokens that are at the end of the cursor, but are not captured
6414 // but the child cursors.
6415 annotateAndAdvanceTokens(cursor, RangeOverlap, cursorRange);
6416
6417 // Scan the tokens that are at the beginning of the cursor, but are not
6418 // capture by the child cursors.
6419 for (unsigned I = BeforeChildren; I != AfterChildren; ++I) {
6420 if (!clang_isInvalid(clang_getCursorKind(Cursors[I])))
6421 break;
6422
6423 Cursors[I] = cursor;
6424 }
6425
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00006426 // Attributes are annotated out-of-order, rewind TokIdx to when we first
6427 // encountered the attribute cursor.
6428 if (clang_isAttribute(cursor.kind))
6429 TokIdx = Info.BeforeReachingCursorIdx;
6430
Guy Benyei11169dd2012-12-18 14:30:41 +00006431 PostChildrenInfos.pop_back();
6432 return false;
6433}
6434
6435static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
6436 CXCursor parent,
6437 CXClientData client_data) {
6438 return static_cast<AnnotateTokensWorker*>(client_data)->Visit(cursor, parent);
6439}
6440
6441static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
6442 CXClientData client_data) {
6443 return static_cast<AnnotateTokensWorker*>(client_data)->
6444 postVisitChildren(cursor);
6445}
6446
6447namespace {
6448
6449/// \brief Uses the macro expansions in the preprocessing record to find
6450/// and mark tokens that are macro arguments. This info is used by the
6451/// AnnotateTokensWorker.
6452class MarkMacroArgTokensVisitor {
6453 SourceManager &SM;
6454 CXToken *Tokens;
6455 unsigned NumTokens;
6456 unsigned CurIdx;
6457
6458public:
6459 MarkMacroArgTokensVisitor(SourceManager &SM,
6460 CXToken *tokens, unsigned numTokens)
6461 : SM(SM), Tokens(tokens), NumTokens(numTokens), CurIdx(0) { }
6462
6463 CXChildVisitResult visit(CXCursor cursor, CXCursor parent) {
6464 if (cursor.kind != CXCursor_MacroExpansion)
6465 return CXChildVisit_Continue;
6466
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006467 SourceRange macroRange = getCursorMacroExpansion(cursor).getSourceRange();
Guy Benyei11169dd2012-12-18 14:30:41 +00006468 if (macroRange.getBegin() == macroRange.getEnd())
6469 return CXChildVisit_Continue; // it's not a function macro.
6470
6471 for (; CurIdx < NumTokens; ++CurIdx) {
6472 if (!SM.isBeforeInTranslationUnit(getTokenLoc(CurIdx),
6473 macroRange.getBegin()))
6474 break;
6475 }
6476
6477 if (CurIdx == NumTokens)
6478 return CXChildVisit_Break;
6479
6480 for (; CurIdx < NumTokens; ++CurIdx) {
6481 SourceLocation tokLoc = getTokenLoc(CurIdx);
6482 if (!SM.isBeforeInTranslationUnit(tokLoc, macroRange.getEnd()))
6483 break;
6484
6485 setFunctionMacroTokenLoc(CurIdx, SM.getMacroArgExpandedLocation(tokLoc));
6486 }
6487
6488 if (CurIdx == NumTokens)
6489 return CXChildVisit_Break;
6490
6491 return CXChildVisit_Continue;
6492 }
6493
6494private:
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00006495 CXToken &getTok(unsigned Idx) {
6496 assert(Idx < NumTokens);
6497 return Tokens[Idx];
6498 }
6499 const CXToken &getTok(unsigned Idx) const {
6500 assert(Idx < NumTokens);
6501 return Tokens[Idx];
6502 }
6503
Guy Benyei11169dd2012-12-18 14:30:41 +00006504 SourceLocation getTokenLoc(unsigned tokI) {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00006505 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[1]);
Guy Benyei11169dd2012-12-18 14:30:41 +00006506 }
6507
6508 void setFunctionMacroTokenLoc(unsigned tokI, SourceLocation loc) {
6509 // The third field is reserved and currently not used. Use it here
6510 // to mark macro arg expanded tokens with their expanded locations.
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00006511 getTok(tokI).int_data[3] = loc.getRawEncoding();
Guy Benyei11169dd2012-12-18 14:30:41 +00006512 }
6513};
6514
6515} // end anonymous namespace
6516
6517static CXChildVisitResult
6518MarkMacroArgTokensVisitorDelegate(CXCursor cursor, CXCursor parent,
6519 CXClientData client_data) {
6520 return static_cast<MarkMacroArgTokensVisitor*>(client_data)->visit(cursor,
6521 parent);
6522}
6523
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006524/// \brief Used by \c annotatePreprocessorTokens.
6525/// \returns true if lexing was finished, false otherwise.
6526static bool lexNext(Lexer &Lex, Token &Tok,
6527 unsigned &NextIdx, unsigned NumTokens) {
6528 if (NextIdx >= NumTokens)
6529 return true;
6530
6531 ++NextIdx;
6532 Lex.LexFromRawLexer(Tok);
Alexander Kornienko1a9f1842015-12-28 15:24:08 +00006533 return Tok.is(tok::eof);
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006534}
6535
Guy Benyei11169dd2012-12-18 14:30:41 +00006536static void annotatePreprocessorTokens(CXTranslationUnit TU,
6537 SourceRange RegionOfInterest,
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006538 CXCursor *Cursors,
6539 CXToken *Tokens,
6540 unsigned NumTokens) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006541 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00006542
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006543 Preprocessor &PP = CXXUnit->getPreprocessor();
Guy Benyei11169dd2012-12-18 14:30:41 +00006544 SourceManager &SourceMgr = CXXUnit->getSourceManager();
6545 std::pair<FileID, unsigned> BeginLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00006546 = SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getBegin());
Guy Benyei11169dd2012-12-18 14:30:41 +00006547 std::pair<FileID, unsigned> EndLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00006548 = SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getEnd());
Guy Benyei11169dd2012-12-18 14:30:41 +00006549
6550 if (BeginLocInfo.first != EndLocInfo.first)
6551 return;
6552
6553 StringRef Buffer;
6554 bool Invalid = false;
6555 Buffer = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
6556 if (Buffer.empty() || Invalid)
6557 return;
6558
6559 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
6560 CXXUnit->getASTContext().getLangOpts(),
6561 Buffer.begin(), Buffer.data() + BeginLocInfo.second,
6562 Buffer.end());
6563 Lex.SetCommentRetentionState(true);
6564
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006565 unsigned NextIdx = 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00006566 // Lex tokens in raw mode until we hit the end of the range, to avoid
6567 // entering #includes or expanding macros.
6568 while (true) {
6569 Token Tok;
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006570 if (lexNext(Lex, Tok, NextIdx, NumTokens))
6571 break;
6572 unsigned TokIdx = NextIdx-1;
6573 assert(Tok.getLocation() ==
6574 SourceLocation::getFromRawEncoding(Tokens[TokIdx].int_data[1]));
Guy Benyei11169dd2012-12-18 14:30:41 +00006575
6576 reprocess:
6577 if (Tok.is(tok::hash) && Tok.isAtStartOfLine()) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006578 // We have found a preprocessing directive. Annotate the tokens
6579 // appropriately.
Guy Benyei11169dd2012-12-18 14:30:41 +00006580 //
6581 // FIXME: Some simple tests here could identify macro definitions and
6582 // #undefs, to provide specific cursor kinds for those.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006583
6584 SourceLocation BeginLoc = Tok.getLocation();
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006585 if (lexNext(Lex, Tok, NextIdx, NumTokens))
6586 break;
6587
Craig Topper69186e72014-06-08 08:38:04 +00006588 MacroInfo *MI = nullptr;
Alp Toker2d57cea2014-05-17 04:53:25 +00006589 if (Tok.is(tok::raw_identifier) && Tok.getRawIdentifier() == "define") {
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006590 if (lexNext(Lex, Tok, NextIdx, NumTokens))
6591 break;
6592
6593 if (Tok.is(tok::raw_identifier)) {
Alp Toker2d57cea2014-05-17 04:53:25 +00006594 IdentifierInfo &II =
6595 PP.getIdentifierTable().get(Tok.getRawIdentifier());
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006596 SourceLocation MappedTokLoc =
6597 CXXUnit->mapLocationToPreamble(Tok.getLocation());
6598 MI = getMacroInfo(II, MappedTokLoc, TU);
6599 }
6600 }
6601
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006602 bool finished = false;
Guy Benyei11169dd2012-12-18 14:30:41 +00006603 do {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006604 if (lexNext(Lex, Tok, NextIdx, NumTokens)) {
6605 finished = true;
6606 break;
6607 }
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006608 // If we are in a macro definition, check if the token was ever a
6609 // macro name and annotate it if that's the case.
6610 if (MI) {
6611 SourceLocation SaveLoc = Tok.getLocation();
6612 Tok.setLocation(CXXUnit->mapLocationToPreamble(SaveLoc));
Richard Smith66a81862015-05-04 02:25:31 +00006613 MacroDefinitionRecord *MacroDef =
6614 checkForMacroInMacroDefinition(MI, Tok, TU);
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006615 Tok.setLocation(SaveLoc);
6616 if (MacroDef)
Richard Smith66a81862015-05-04 02:25:31 +00006617 Cursors[NextIdx - 1] =
6618 MakeMacroExpansionCursor(MacroDef, Tok.getLocation(), TU);
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006619 }
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006620 } while (!Tok.isAtStartOfLine());
6621
6622 unsigned LastIdx = finished ? NextIdx-1 : NextIdx-2;
6623 assert(TokIdx <= LastIdx);
6624 SourceLocation EndLoc =
6625 SourceLocation::getFromRawEncoding(Tokens[LastIdx].int_data[1]);
6626 CXCursor Cursor =
6627 MakePreprocessingDirectiveCursor(SourceRange(BeginLoc, EndLoc), TU);
6628
6629 for (; TokIdx <= LastIdx; ++TokIdx)
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006630 updateCursorAnnotation(Cursors[TokIdx], Cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00006631
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006632 if (finished)
6633 break;
6634 goto reprocess;
Guy Benyei11169dd2012-12-18 14:30:41 +00006635 }
Guy Benyei11169dd2012-12-18 14:30:41 +00006636 }
6637}
6638
6639// This gets run a separate thread to avoid stack blowout.
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00006640static void clang_annotateTokensImpl(CXTranslationUnit TU, ASTUnit *CXXUnit,
6641 CXToken *Tokens, unsigned NumTokens,
6642 CXCursor *Cursors) {
Dmitri Gribenko183436e2013-01-26 21:49:50 +00006643 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00006644 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
6645 setThreadBackgroundPriority();
6646
6647 // Determine the region of interest, which contains all of the tokens.
6648 SourceRange RegionOfInterest;
6649 RegionOfInterest.setBegin(
6650 cxloc::translateSourceLocation(clang_getTokenLocation(TU, Tokens[0])));
6651 RegionOfInterest.setEnd(
6652 cxloc::translateSourceLocation(clang_getTokenLocation(TU,
6653 Tokens[NumTokens-1])));
6654
Guy Benyei11169dd2012-12-18 14:30:41 +00006655 // Relex the tokens within the source range to look for preprocessing
6656 // directives.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006657 annotatePreprocessorTokens(TU, RegionOfInterest, Cursors, Tokens, NumTokens);
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00006658
6659 // If begin location points inside a macro argument, set it to the expansion
6660 // location so we can have the full context when annotating semantically.
6661 {
6662 SourceManager &SM = CXXUnit->getSourceManager();
6663 SourceLocation Loc =
6664 SM.getMacroArgExpandedLocation(RegionOfInterest.getBegin());
6665 if (Loc.isMacroID())
6666 RegionOfInterest.setBegin(SM.getExpansionLoc(Loc));
6667 }
6668
Guy Benyei11169dd2012-12-18 14:30:41 +00006669 if (CXXUnit->getPreprocessor().getPreprocessingRecord()) {
6670 // Search and mark tokens that are macro argument expansions.
6671 MarkMacroArgTokensVisitor Visitor(CXXUnit->getSourceManager(),
6672 Tokens, NumTokens);
6673 CursorVisitor MacroArgMarker(TU,
6674 MarkMacroArgTokensVisitorDelegate, &Visitor,
6675 /*VisitPreprocessorLast=*/true,
6676 /*VisitIncludedEntities=*/false,
6677 RegionOfInterest);
6678 MacroArgMarker.visitPreprocessedEntitiesInRegion();
6679 }
6680
6681 // Annotate all of the source locations in the region of interest that map to
6682 // a specific cursor.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006683 AnnotateTokensWorker W(Tokens, Cursors, NumTokens, TU, RegionOfInterest);
Guy Benyei11169dd2012-12-18 14:30:41 +00006684
6685 // FIXME: We use a ridiculous stack size here because the data-recursion
6686 // algorithm uses a large stack frame than the non-data recursive version,
6687 // and AnnotationTokensWorker currently transforms the data-recursion
6688 // algorithm back into a traditional recursion by explicitly calling
6689 // VisitChildren(). We will need to remove this explicit recursive call.
6690 W.AnnotateTokens();
6691
6692 // If we ran into any entities that involve context-sensitive keywords,
6693 // take another pass through the tokens to mark them as such.
6694 if (W.hasContextSensitiveKeywords()) {
6695 for (unsigned I = 0; I != NumTokens; ++I) {
6696 if (clang_getTokenKind(Tokens[I]) != CXToken_Identifier)
6697 continue;
6698
6699 if (Cursors[I].kind == CXCursor_ObjCPropertyDecl) {
6700 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006701 if (const ObjCPropertyDecl *Property
Guy Benyei11169dd2012-12-18 14:30:41 +00006702 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(Cursors[I]))) {
6703 if (Property->getPropertyAttributesAsWritten() != 0 &&
6704 llvm::StringSwitch<bool>(II->getName())
6705 .Case("readonly", true)
6706 .Case("assign", true)
6707 .Case("unsafe_unretained", true)
6708 .Case("readwrite", true)
6709 .Case("retain", true)
6710 .Case("copy", true)
6711 .Case("nonatomic", true)
6712 .Case("atomic", true)
6713 .Case("getter", true)
6714 .Case("setter", true)
6715 .Case("strong", true)
6716 .Case("weak", true)
6717 .Default(false))
6718 Tokens[I].int_data[0] = CXToken_Keyword;
6719 }
6720 continue;
6721 }
6722
6723 if (Cursors[I].kind == CXCursor_ObjCInstanceMethodDecl ||
6724 Cursors[I].kind == CXCursor_ObjCClassMethodDecl) {
6725 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
6726 if (llvm::StringSwitch<bool>(II->getName())
6727 .Case("in", true)
6728 .Case("out", true)
6729 .Case("inout", true)
6730 .Case("oneway", true)
6731 .Case("bycopy", true)
6732 .Case("byref", true)
6733 .Default(false))
6734 Tokens[I].int_data[0] = CXToken_Keyword;
6735 continue;
6736 }
6737
6738 if (Cursors[I].kind == CXCursor_CXXFinalAttr ||
6739 Cursors[I].kind == CXCursor_CXXOverrideAttr) {
6740 Tokens[I].int_data[0] = CXToken_Keyword;
6741 continue;
6742 }
6743 }
6744 }
6745}
6746
6747extern "C" {
6748
6749void clang_annotateTokens(CXTranslationUnit TU,
6750 CXToken *Tokens, unsigned NumTokens,
6751 CXCursor *Cursors) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006752 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006753 LOG_BAD_TU(TU);
6754 return;
6755 }
6756 if (NumTokens == 0 || !Tokens || !Cursors) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006757 LOG_FUNC_SECTION { *Log << "<null input>"; }
Guy Benyei11169dd2012-12-18 14:30:41 +00006758 return;
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006759 }
6760
6761 LOG_FUNC_SECTION {
6762 *Log << TU << ' ';
6763 CXSourceLocation bloc = clang_getTokenLocation(TU, Tokens[0]);
6764 CXSourceLocation eloc = clang_getTokenLocation(TU, Tokens[NumTokens-1]);
6765 *Log << clang_getRange(bloc, eloc);
6766 }
Guy Benyei11169dd2012-12-18 14:30:41 +00006767
6768 // Any token we don't specifically annotate will have a NULL cursor.
6769 CXCursor C = clang_getNullCursor();
6770 for (unsigned I = 0; I != NumTokens; ++I)
6771 Cursors[I] = C;
6772
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006773 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00006774 if (!CXXUnit)
6775 return;
6776
6777 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00006778
6779 auto AnnotateTokensImpl = [=]() {
6780 clang_annotateTokensImpl(TU, CXXUnit, Tokens, NumTokens, Cursors);
6781 };
Guy Benyei11169dd2012-12-18 14:30:41 +00006782 llvm::CrashRecoveryContext CRC;
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00006783 if (!RunSafely(CRC, AnnotateTokensImpl, GetSafetyThreadStackSize() * 2)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00006784 fprintf(stderr, "libclang: crash detected while annotating tokens\n");
6785 }
6786}
6787
6788} // end: extern "C"
6789
6790//===----------------------------------------------------------------------===//
6791// Operations for querying linkage of a cursor.
6792//===----------------------------------------------------------------------===//
6793
6794extern "C" {
6795CXLinkageKind clang_getCursorLinkage(CXCursor cursor) {
6796 if (!clang_isDeclaration(cursor.kind))
6797 return CXLinkage_Invalid;
6798
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006799 const Decl *D = cxcursor::getCursorDecl(cursor);
6800 if (const NamedDecl *ND = dyn_cast_or_null<NamedDecl>(D))
Rafael Espindola3ae00052013-05-13 00:12:11 +00006801 switch (ND->getLinkageInternal()) {
Rafael Espindola50df3a02013-05-25 17:16:20 +00006802 case NoLinkage:
6803 case VisibleNoLinkage: return CXLinkage_NoLinkage;
Guy Benyei11169dd2012-12-18 14:30:41 +00006804 case InternalLinkage: return CXLinkage_Internal;
6805 case UniqueExternalLinkage: return CXLinkage_UniqueExternal;
6806 case ExternalLinkage: return CXLinkage_External;
6807 };
6808
6809 return CXLinkage_Invalid;
6810}
6811} // end: extern "C"
6812
6813//===----------------------------------------------------------------------===//
Ehsan Akhgari93697fa2015-11-23 19:56:46 +00006814// Operations for querying visibility of a cursor.
6815//===----------------------------------------------------------------------===//
6816
6817extern "C" {
6818CXVisibilityKind clang_getCursorVisibility(CXCursor cursor) {
6819 if (!clang_isDeclaration(cursor.kind))
6820 return CXVisibility_Invalid;
6821
6822 const Decl *D = cxcursor::getCursorDecl(cursor);
6823 if (const NamedDecl *ND = dyn_cast_or_null<NamedDecl>(D))
6824 switch (ND->getVisibility()) {
6825 case HiddenVisibility: return CXVisibility_Hidden;
6826 case ProtectedVisibility: return CXVisibility_Protected;
6827 case DefaultVisibility: return CXVisibility_Default;
6828 };
6829
6830 return CXVisibility_Invalid;
6831}
6832} // end: extern "C"
6833
6834//===----------------------------------------------------------------------===//
Guy Benyei11169dd2012-12-18 14:30:41 +00006835// Operations for querying language of a cursor.
6836//===----------------------------------------------------------------------===//
6837
6838static CXLanguageKind getDeclLanguage(const Decl *D) {
6839 if (!D)
6840 return CXLanguage_C;
6841
6842 switch (D->getKind()) {
6843 default:
6844 break;
6845 case Decl::ImplicitParam:
6846 case Decl::ObjCAtDefsField:
6847 case Decl::ObjCCategory:
6848 case Decl::ObjCCategoryImpl:
6849 case Decl::ObjCCompatibleAlias:
6850 case Decl::ObjCImplementation:
6851 case Decl::ObjCInterface:
6852 case Decl::ObjCIvar:
6853 case Decl::ObjCMethod:
6854 case Decl::ObjCProperty:
6855 case Decl::ObjCPropertyImpl:
6856 case Decl::ObjCProtocol:
Douglas Gregor85f3f952015-07-07 03:57:15 +00006857 case Decl::ObjCTypeParam:
Guy Benyei11169dd2012-12-18 14:30:41 +00006858 return CXLanguage_ObjC;
6859 case Decl::CXXConstructor:
6860 case Decl::CXXConversion:
6861 case Decl::CXXDestructor:
6862 case Decl::CXXMethod:
6863 case Decl::CXXRecord:
6864 case Decl::ClassTemplate:
6865 case Decl::ClassTemplatePartialSpecialization:
6866 case Decl::ClassTemplateSpecialization:
6867 case Decl::Friend:
6868 case Decl::FriendTemplate:
6869 case Decl::FunctionTemplate:
6870 case Decl::LinkageSpec:
6871 case Decl::Namespace:
6872 case Decl::NamespaceAlias:
6873 case Decl::NonTypeTemplateParm:
6874 case Decl::StaticAssert:
6875 case Decl::TemplateTemplateParm:
6876 case Decl::TemplateTypeParm:
6877 case Decl::UnresolvedUsingTypename:
6878 case Decl::UnresolvedUsingValue:
6879 case Decl::Using:
6880 case Decl::UsingDirective:
6881 case Decl::UsingShadow:
6882 return CXLanguage_CPlusPlus;
6883 }
6884
6885 return CXLanguage_C;
6886}
6887
6888extern "C" {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006889
6890static CXAvailabilityKind getCursorAvailabilityForDecl(const Decl *D) {
6891 if (isa<FunctionDecl>(D) && cast<FunctionDecl>(D)->isDeleted())
Manuel Klimek8e3a7ed2015-09-25 17:53:16 +00006892 return CXAvailability_NotAvailable;
Guy Benyei11169dd2012-12-18 14:30:41 +00006893
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006894 switch (D->getAvailability()) {
6895 case AR_Available:
6896 case AR_NotYetIntroduced:
6897 if (const EnumConstantDecl *EnumConst = dyn_cast<EnumConstantDecl>(D))
Benjamin Kramer656363d2013-10-15 18:53:18 +00006898 return getCursorAvailabilityForDecl(
6899 cast<Decl>(EnumConst->getDeclContext()));
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006900 return CXAvailability_Available;
6901
6902 case AR_Deprecated:
6903 return CXAvailability_Deprecated;
6904
6905 case AR_Unavailable:
6906 return CXAvailability_NotAvailable;
6907 }
Benjamin Kramer656363d2013-10-15 18:53:18 +00006908
6909 llvm_unreachable("Unknown availability kind!");
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006910}
6911
Guy Benyei11169dd2012-12-18 14:30:41 +00006912enum CXAvailabilityKind clang_getCursorAvailability(CXCursor cursor) {
6913 if (clang_isDeclaration(cursor.kind))
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006914 if (const Decl *D = cxcursor::getCursorDecl(cursor))
6915 return getCursorAvailabilityForDecl(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00006916
6917 return CXAvailability_Available;
6918}
6919
6920static CXVersion convertVersion(VersionTuple In) {
6921 CXVersion Out = { -1, -1, -1 };
6922 if (In.empty())
6923 return Out;
6924
6925 Out.Major = In.getMajor();
6926
NAKAMURA Takumic2b5d1f2013-02-21 02:32:34 +00006927 Optional<unsigned> Minor = In.getMinor();
6928 if (Minor.hasValue())
Guy Benyei11169dd2012-12-18 14:30:41 +00006929 Out.Minor = *Minor;
6930 else
6931 return Out;
6932
NAKAMURA Takumic2b5d1f2013-02-21 02:32:34 +00006933 Optional<unsigned> Subminor = In.getSubminor();
6934 if (Subminor.hasValue())
Guy Benyei11169dd2012-12-18 14:30:41 +00006935 Out.Subminor = *Subminor;
6936
6937 return Out;
6938}
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006939
6940static int getCursorPlatformAvailabilityForDecl(const Decl *D,
6941 int *always_deprecated,
6942 CXString *deprecated_message,
6943 int *always_unavailable,
6944 CXString *unavailable_message,
6945 CXPlatformAvailability *availability,
6946 int availability_size) {
6947 bool HadAvailAttr = false;
6948 int N = 0;
Aaron Ballmanb97112e2014-03-08 22:19:01 +00006949 for (auto A : D->attrs()) {
6950 if (DeprecatedAttr *Deprecated = dyn_cast<DeprecatedAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006951 HadAvailAttr = true;
6952 if (always_deprecated)
6953 *always_deprecated = 1;
Nico Weberaacf0312014-04-24 05:16:45 +00006954 if (deprecated_message) {
Argyrios Kyrtzidisedfe07f2014-04-24 06:05:40 +00006955 clang_disposeString(*deprecated_message);
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006956 *deprecated_message = cxstring::createDup(Deprecated->getMessage());
Nico Weberaacf0312014-04-24 05:16:45 +00006957 }
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006958 continue;
6959 }
6960
Aaron Ballmanb97112e2014-03-08 22:19:01 +00006961 if (UnavailableAttr *Unavailable = dyn_cast<UnavailableAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006962 HadAvailAttr = true;
6963 if (always_unavailable)
6964 *always_unavailable = 1;
6965 if (unavailable_message) {
Argyrios Kyrtzidisedfe07f2014-04-24 06:05:40 +00006966 clang_disposeString(*unavailable_message);
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006967 *unavailable_message = cxstring::createDup(Unavailable->getMessage());
6968 }
6969 continue;
6970 }
6971
Aaron Ballmanb97112e2014-03-08 22:19:01 +00006972 if (AvailabilityAttr *Avail = dyn_cast<AvailabilityAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006973 HadAvailAttr = true;
6974 if (N < availability_size) {
6975 availability[N].Platform
6976 = cxstring::createDup(Avail->getPlatform()->getName());
6977 availability[N].Introduced = convertVersion(Avail->getIntroduced());
6978 availability[N].Deprecated = convertVersion(Avail->getDeprecated());
6979 availability[N].Obsoleted = convertVersion(Avail->getObsoleted());
6980 availability[N].Unavailable = Avail->getUnavailable();
6981 availability[N].Message = cxstring::createDup(Avail->getMessage());
6982 }
6983 ++N;
6984 }
6985 }
6986
6987 if (!HadAvailAttr)
6988 if (const EnumConstantDecl *EnumConst = dyn_cast<EnumConstantDecl>(D))
6989 return getCursorPlatformAvailabilityForDecl(
6990 cast<Decl>(EnumConst->getDeclContext()),
6991 always_deprecated,
6992 deprecated_message,
6993 always_unavailable,
6994 unavailable_message,
6995 availability,
6996 availability_size);
Guy Benyei11169dd2012-12-18 14:30:41 +00006997
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006998 return N;
6999}
7000
Guy Benyei11169dd2012-12-18 14:30:41 +00007001int clang_getCursorPlatformAvailability(CXCursor cursor,
7002 int *always_deprecated,
7003 CXString *deprecated_message,
7004 int *always_unavailable,
7005 CXString *unavailable_message,
7006 CXPlatformAvailability *availability,
7007 int availability_size) {
7008 if (always_deprecated)
7009 *always_deprecated = 0;
7010 if (deprecated_message)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00007011 *deprecated_message = cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00007012 if (always_unavailable)
7013 *always_unavailable = 0;
7014 if (unavailable_message)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00007015 *unavailable_message = cxstring::createEmpty();
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00007016
Guy Benyei11169dd2012-12-18 14:30:41 +00007017 if (!clang_isDeclaration(cursor.kind))
7018 return 0;
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00007019
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00007020 const Decl *D = cxcursor::getCursorDecl(cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00007021 if (!D)
7022 return 0;
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00007023
7024 return getCursorPlatformAvailabilityForDecl(D, always_deprecated,
7025 deprecated_message,
7026 always_unavailable,
7027 unavailable_message,
7028 availability,
7029 availability_size);
Guy Benyei11169dd2012-12-18 14:30:41 +00007030}
7031
7032void clang_disposeCXPlatformAvailability(CXPlatformAvailability *availability) {
7033 clang_disposeString(availability->Platform);
7034 clang_disposeString(availability->Message);
7035}
7036
7037CXLanguageKind clang_getCursorLanguage(CXCursor cursor) {
7038 if (clang_isDeclaration(cursor.kind))
7039 return getDeclLanguage(cxcursor::getCursorDecl(cursor));
7040
7041 return CXLanguage_Invalid;
7042}
7043
7044 /// \brief If the given cursor is the "templated" declaration
7045 /// descibing a class or function template, return the class or
7046 /// function template.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00007047static const Decl *maybeGetTemplateCursor(const Decl *D) {
Guy Benyei11169dd2012-12-18 14:30:41 +00007048 if (!D)
Craig Topper69186e72014-06-08 08:38:04 +00007049 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00007050
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00007051 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00007052 if (FunctionTemplateDecl *FunTmpl = FD->getDescribedFunctionTemplate())
7053 return FunTmpl;
7054
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00007055 if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00007056 if (ClassTemplateDecl *ClassTmpl = RD->getDescribedClassTemplate())
7057 return ClassTmpl;
7058
7059 return D;
7060}
7061
Argyrios Kyrtzidis4e0854f2014-10-15 17:05:31 +00007062
7063enum CX_StorageClass clang_Cursor_getStorageClass(CXCursor C) {
7064 StorageClass sc = SC_None;
7065 const Decl *D = getCursorDecl(C);
7066 if (D) {
7067 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
7068 sc = FD->getStorageClass();
7069 } else if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
7070 sc = VD->getStorageClass();
7071 } else {
7072 return CX_SC_Invalid;
7073 }
7074 } else {
7075 return CX_SC_Invalid;
7076 }
7077 switch (sc) {
7078 case SC_None:
7079 return CX_SC_None;
7080 case SC_Extern:
7081 return CX_SC_Extern;
7082 case SC_Static:
7083 return CX_SC_Static;
7084 case SC_PrivateExtern:
7085 return CX_SC_PrivateExtern;
Argyrios Kyrtzidis4e0854f2014-10-15 17:05:31 +00007086 case SC_Auto:
7087 return CX_SC_Auto;
7088 case SC_Register:
7089 return CX_SC_Register;
Argyrios Kyrtzidis4e0854f2014-10-15 17:05:31 +00007090 }
Kaelyn Takataab61e702014-10-15 18:03:26 +00007091 llvm_unreachable("Unhandled storage class!");
Argyrios Kyrtzidis4e0854f2014-10-15 17:05:31 +00007092}
7093
Guy Benyei11169dd2012-12-18 14:30:41 +00007094CXCursor clang_getCursorSemanticParent(CXCursor cursor) {
7095 if (clang_isDeclaration(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00007096 if (const Decl *D = getCursorDecl(cursor)) {
7097 const DeclContext *DC = D->getDeclContext();
Guy Benyei11169dd2012-12-18 14:30:41 +00007098 if (!DC)
7099 return clang_getNullCursor();
7100
7101 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
7102 getCursorTU(cursor));
7103 }
7104 }
7105
7106 if (clang_isStatement(cursor.kind) || clang_isExpression(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00007107 if (const Decl *D = getCursorDecl(cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +00007108 return MakeCXCursor(D, getCursorTU(cursor));
7109 }
7110
7111 return clang_getNullCursor();
7112}
7113
7114CXCursor clang_getCursorLexicalParent(CXCursor cursor) {
7115 if (clang_isDeclaration(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00007116 if (const Decl *D = getCursorDecl(cursor)) {
7117 const DeclContext *DC = D->getLexicalDeclContext();
Guy Benyei11169dd2012-12-18 14:30:41 +00007118 if (!DC)
7119 return clang_getNullCursor();
7120
7121 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
7122 getCursorTU(cursor));
7123 }
7124 }
7125
7126 // FIXME: Note that we can't easily compute the lexical context of a
7127 // statement or expression, so we return nothing.
7128 return clang_getNullCursor();
7129}
7130
7131CXFile clang_getIncludedFile(CXCursor cursor) {
7132 if (cursor.kind != CXCursor_InclusionDirective)
Craig Topper69186e72014-06-08 08:38:04 +00007133 return nullptr;
7134
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00007135 const InclusionDirective *ID = getCursorInclusionDirective(cursor);
Dmitri Gribenkof9304482013-01-23 15:56:07 +00007136 return const_cast<FileEntry *>(ID->getFile());
Guy Benyei11169dd2012-12-18 14:30:41 +00007137}
7138
Argyrios Kyrtzidis9adfd8a2013-04-18 22:15:49 +00007139unsigned clang_Cursor_getObjCPropertyAttributes(CXCursor C, unsigned reserved) {
7140 if (C.kind != CXCursor_ObjCPropertyDecl)
7141 return CXObjCPropertyAttr_noattr;
7142
7143 unsigned Result = CXObjCPropertyAttr_noattr;
7144 const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(getCursorDecl(C));
7145 ObjCPropertyDecl::PropertyAttributeKind Attr =
7146 PD->getPropertyAttributesAsWritten();
7147
7148#define SET_CXOBJCPROP_ATTR(A) \
7149 if (Attr & ObjCPropertyDecl::OBJC_PR_##A) \
7150 Result |= CXObjCPropertyAttr_##A
7151 SET_CXOBJCPROP_ATTR(readonly);
7152 SET_CXOBJCPROP_ATTR(getter);
7153 SET_CXOBJCPROP_ATTR(assign);
7154 SET_CXOBJCPROP_ATTR(readwrite);
7155 SET_CXOBJCPROP_ATTR(retain);
7156 SET_CXOBJCPROP_ATTR(copy);
7157 SET_CXOBJCPROP_ATTR(nonatomic);
7158 SET_CXOBJCPROP_ATTR(setter);
7159 SET_CXOBJCPROP_ATTR(atomic);
7160 SET_CXOBJCPROP_ATTR(weak);
7161 SET_CXOBJCPROP_ATTR(strong);
7162 SET_CXOBJCPROP_ATTR(unsafe_unretained);
7163#undef SET_CXOBJCPROP_ATTR
7164
7165 return Result;
7166}
7167
Argyrios Kyrtzidis9d9bc012013-04-18 23:29:12 +00007168unsigned clang_Cursor_getObjCDeclQualifiers(CXCursor C) {
7169 if (!clang_isDeclaration(C.kind))
7170 return CXObjCDeclQualifier_None;
7171
7172 Decl::ObjCDeclQualifier QT = Decl::OBJC_TQ_None;
7173 const Decl *D = getCursorDecl(C);
7174 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
7175 QT = MD->getObjCDeclQualifier();
7176 else if (const ParmVarDecl *PD = dyn_cast<ParmVarDecl>(D))
7177 QT = PD->getObjCDeclQualifier();
7178 if (QT == Decl::OBJC_TQ_None)
7179 return CXObjCDeclQualifier_None;
7180
7181 unsigned Result = CXObjCDeclQualifier_None;
7182 if (QT & Decl::OBJC_TQ_In) Result |= CXObjCDeclQualifier_In;
7183 if (QT & Decl::OBJC_TQ_Inout) Result |= CXObjCDeclQualifier_Inout;
7184 if (QT & Decl::OBJC_TQ_Out) Result |= CXObjCDeclQualifier_Out;
7185 if (QT & Decl::OBJC_TQ_Bycopy) Result |= CXObjCDeclQualifier_Bycopy;
7186 if (QT & Decl::OBJC_TQ_Byref) Result |= CXObjCDeclQualifier_Byref;
7187 if (QT & Decl::OBJC_TQ_Oneway) Result |= CXObjCDeclQualifier_Oneway;
7188
7189 return Result;
7190}
7191
Argyrios Kyrtzidis7b50fc52013-07-05 20:44:37 +00007192unsigned clang_Cursor_isObjCOptional(CXCursor C) {
7193 if (!clang_isDeclaration(C.kind))
7194 return 0;
7195
7196 const Decl *D = getCursorDecl(C);
7197 if (const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(D))
7198 return PD->getPropertyImplementation() == ObjCPropertyDecl::Optional;
7199 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
7200 return MD->getImplementationControl() == ObjCMethodDecl::Optional;
7201
7202 return 0;
7203}
7204
Argyrios Kyrtzidis23814e42013-04-18 23:53:05 +00007205unsigned clang_Cursor_isVariadic(CXCursor C) {
7206 if (!clang_isDeclaration(C.kind))
7207 return 0;
7208
7209 const Decl *D = getCursorDecl(C);
7210 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
7211 return FD->isVariadic();
7212 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
7213 return MD->isVariadic();
7214
7215 return 0;
7216}
7217
Guy Benyei11169dd2012-12-18 14:30:41 +00007218CXSourceRange clang_Cursor_getCommentRange(CXCursor C) {
7219 if (!clang_isDeclaration(C.kind))
7220 return clang_getNullRange();
7221
7222 const Decl *D = getCursorDecl(C);
7223 ASTContext &Context = getCursorContext(C);
7224 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
7225 if (!RC)
7226 return clang_getNullRange();
7227
7228 return cxloc::translateSourceRange(Context, RC->getSourceRange());
7229}
7230
7231CXString clang_Cursor_getRawCommentText(CXCursor C) {
7232 if (!clang_isDeclaration(C.kind))
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00007233 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00007234
7235 const Decl *D = getCursorDecl(C);
7236 ASTContext &Context = getCursorContext(C);
7237 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
7238 StringRef RawText = RC ? RC->getRawText(Context.getSourceManager()) :
7239 StringRef();
7240
7241 // Don't duplicate the string because RawText points directly into source
7242 // code.
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00007243 return cxstring::createRef(RawText);
Guy Benyei11169dd2012-12-18 14:30:41 +00007244}
7245
7246CXString clang_Cursor_getBriefCommentText(CXCursor C) {
7247 if (!clang_isDeclaration(C.kind))
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00007248 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00007249
7250 const Decl *D = getCursorDecl(C);
7251 const ASTContext &Context = getCursorContext(C);
7252 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
7253
7254 if (RC) {
7255 StringRef BriefText = RC->getBriefText(Context);
7256
7257 // Don't duplicate the string because RawComment ensures that this memory
7258 // will not go away.
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00007259 return cxstring::createRef(BriefText);
Guy Benyei11169dd2012-12-18 14:30:41 +00007260 }
7261
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00007262 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00007263}
7264
Guy Benyei11169dd2012-12-18 14:30:41 +00007265CXModule clang_Cursor_getModule(CXCursor C) {
7266 if (C.kind == CXCursor_ModuleImportDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00007267 if (const ImportDecl *ImportD =
7268 dyn_cast_or_null<ImportDecl>(getCursorDecl(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00007269 return ImportD->getImportedModule();
7270 }
7271
Craig Topper69186e72014-06-08 08:38:04 +00007272 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00007273}
7274
Argyrios Kyrtzidisf6d49c32014-05-14 23:14:37 +00007275CXModule clang_getModuleForFile(CXTranslationUnit TU, CXFile File) {
7276 if (isNotUsableTU(TU)) {
7277 LOG_BAD_TU(TU);
7278 return nullptr;
7279 }
7280 if (!File)
7281 return nullptr;
7282 FileEntry *FE = static_cast<FileEntry *>(File);
7283
7284 ASTUnit &Unit = *cxtu::getASTUnit(TU);
7285 HeaderSearch &HS = Unit.getPreprocessor().getHeaderSearchInfo();
7286 ModuleMap::KnownHeader Header = HS.findModuleForHeader(FE);
7287
Richard Smithfeb54b62014-10-23 02:01:19 +00007288 return Header.getModule();
Argyrios Kyrtzidisf6d49c32014-05-14 23:14:37 +00007289}
7290
Argyrios Kyrtzidis12fdb9e2013-04-26 22:47:49 +00007291CXFile clang_Module_getASTFile(CXModule CXMod) {
7292 if (!CXMod)
Craig Topper69186e72014-06-08 08:38:04 +00007293 return nullptr;
Argyrios Kyrtzidis12fdb9e2013-04-26 22:47:49 +00007294 Module *Mod = static_cast<Module*>(CXMod);
7295 return const_cast<FileEntry *>(Mod->getASTFile());
7296}
7297
Guy Benyei11169dd2012-12-18 14:30:41 +00007298CXModule clang_Module_getParent(CXModule CXMod) {
7299 if (!CXMod)
Craig Topper69186e72014-06-08 08:38:04 +00007300 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00007301 Module *Mod = static_cast<Module*>(CXMod);
7302 return Mod->Parent;
7303}
7304
7305CXString clang_Module_getName(CXModule CXMod) {
7306 if (!CXMod)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00007307 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00007308 Module *Mod = static_cast<Module*>(CXMod);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00007309 return cxstring::createDup(Mod->Name);
Guy Benyei11169dd2012-12-18 14:30:41 +00007310}
7311
7312CXString clang_Module_getFullName(CXModule CXMod) {
7313 if (!CXMod)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00007314 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00007315 Module *Mod = static_cast<Module*>(CXMod);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00007316 return cxstring::createDup(Mod->getFullModuleName());
Guy Benyei11169dd2012-12-18 14:30:41 +00007317}
7318
Argyrios Kyrtzidis884337f2014-05-15 04:44:25 +00007319int clang_Module_isSystem(CXModule CXMod) {
7320 if (!CXMod)
7321 return 0;
7322 Module *Mod = static_cast<Module*>(CXMod);
7323 return Mod->IsSystem;
7324}
7325
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00007326unsigned clang_Module_getNumTopLevelHeaders(CXTranslationUnit TU,
7327 CXModule CXMod) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00007328 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00007329 LOG_BAD_TU(TU);
7330 return 0;
7331 }
7332 if (!CXMod)
Guy Benyei11169dd2012-12-18 14:30:41 +00007333 return 0;
7334 Module *Mod = static_cast<Module*>(CXMod);
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00007335 FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
7336 ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
7337 return TopHeaders.size();
Guy Benyei11169dd2012-12-18 14:30:41 +00007338}
7339
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00007340CXFile clang_Module_getTopLevelHeader(CXTranslationUnit TU,
7341 CXModule CXMod, unsigned Index) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00007342 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00007343 LOG_BAD_TU(TU);
Craig Topper69186e72014-06-08 08:38:04 +00007344 return nullptr;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00007345 }
7346 if (!CXMod)
Craig Topper69186e72014-06-08 08:38:04 +00007347 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00007348 Module *Mod = static_cast<Module*>(CXMod);
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00007349 FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
Guy Benyei11169dd2012-12-18 14:30:41 +00007350
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00007351 ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
7352 if (Index < TopHeaders.size())
7353 return const_cast<FileEntry *>(TopHeaders[Index]);
Guy Benyei11169dd2012-12-18 14:30:41 +00007354
Craig Topper69186e72014-06-08 08:38:04 +00007355 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00007356}
7357
7358} // end: extern "C"
7359
7360//===----------------------------------------------------------------------===//
7361// C++ AST instrospection.
7362//===----------------------------------------------------------------------===//
7363
7364extern "C" {
Jonathan Coe29565352016-04-27 12:48:25 +00007365
7366unsigned clang_CXXConstructor_isDefaultConstructor(CXCursor C) {
7367 if (!clang_isDeclaration(C.kind))
7368 return 0;
7369
7370 const Decl *D = cxcursor::getCursorDecl(C);
7371 const CXXConstructorDecl *Constructor =
7372 D ? dyn_cast_or_null<CXXConstructorDecl>(D->getAsFunction()) : nullptr;
7373 return (Constructor && Constructor->isDefaultConstructor()) ? 1 : 0;
7374}
7375
7376unsigned clang_CXXConstructor_isCopyConstructor(CXCursor C) {
7377 if (!clang_isDeclaration(C.kind))
7378 return 0;
7379
7380 const Decl *D = cxcursor::getCursorDecl(C);
7381 const CXXConstructorDecl *Constructor =
7382 D ? dyn_cast_or_null<CXXConstructorDecl>(D->getAsFunction()) : nullptr;
7383 return (Constructor && Constructor->isCopyConstructor()) ? 1 : 0;
7384}
7385
7386unsigned clang_CXXConstructor_isMoveConstructor(CXCursor C) {
7387 if (!clang_isDeclaration(C.kind))
7388 return 0;
7389
7390 const Decl *D = cxcursor::getCursorDecl(C);
7391 const CXXConstructorDecl *Constructor =
7392 D ? dyn_cast_or_null<CXXConstructorDecl>(D->getAsFunction()) : nullptr;
7393 return (Constructor && Constructor->isMoveConstructor()) ? 1 : 0;
7394}
7395
7396unsigned clang_CXXConstructor_isConvertingConstructor(CXCursor C) {
7397 if (!clang_isDeclaration(C.kind))
7398 return 0;
7399
7400 const Decl *D = cxcursor::getCursorDecl(C);
7401 const CXXConstructorDecl *Constructor =
7402 D ? dyn_cast_or_null<CXXConstructorDecl>(D->getAsFunction()) : nullptr;
7403 // Passing 'false' excludes constructors marked 'explicit'.
7404 return (Constructor && Constructor->isConvertingConstructor(false)) ? 1 : 0;
7405}
7406
Saleem Abdulrasool6ea75db2015-10-27 15:50:22 +00007407unsigned clang_CXXField_isMutable(CXCursor C) {
7408 if (!clang_isDeclaration(C.kind))
7409 return 0;
7410
7411 if (const auto D = cxcursor::getCursorDecl(C))
7412 if (const auto FD = dyn_cast_or_null<FieldDecl>(D))
7413 return FD->isMutable() ? 1 : 0;
7414 return 0;
7415}
7416
Dmitri Gribenko62770be2013-05-17 18:38:35 +00007417unsigned clang_CXXMethod_isPureVirtual(CXCursor C) {
7418 if (!clang_isDeclaration(C.kind))
7419 return 0;
7420
Dmitri Gribenko62770be2013-05-17 18:38:35 +00007421 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00007422 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00007423 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Dmitri Gribenko62770be2013-05-17 18:38:35 +00007424 return (Method && Method->isVirtual() && Method->isPure()) ? 1 : 0;
7425}
7426
Dmitri Gribenkoe570ede2014-04-07 14:59:13 +00007427unsigned clang_CXXMethod_isConst(CXCursor C) {
7428 if (!clang_isDeclaration(C.kind))
7429 return 0;
7430
7431 const Decl *D = cxcursor::getCursorDecl(C);
7432 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00007433 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Dmitri Gribenkoe570ede2014-04-07 14:59:13 +00007434 return (Method && (Method->getTypeQualifiers() & Qualifiers::Const)) ? 1 : 0;
7435}
7436
Jonathan Coe29565352016-04-27 12:48:25 +00007437unsigned clang_CXXMethod_isDefaulted(CXCursor C) {
7438 if (!clang_isDeclaration(C.kind))
7439 return 0;
7440
7441 const Decl *D = cxcursor::getCursorDecl(C);
7442 const CXXMethodDecl *Method =
7443 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
7444 return (Method && Method->isDefaulted()) ? 1 : 0;
7445}
7446
Guy Benyei11169dd2012-12-18 14:30:41 +00007447unsigned clang_CXXMethod_isStatic(CXCursor C) {
7448 if (!clang_isDeclaration(C.kind))
7449 return 0;
7450
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00007451 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00007452 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00007453 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00007454 return (Method && Method->isStatic()) ? 1 : 0;
7455}
7456
7457unsigned clang_CXXMethod_isVirtual(CXCursor C) {
7458 if (!clang_isDeclaration(C.kind))
7459 return 0;
7460
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00007461 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00007462 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00007463 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00007464 return (Method && Method->isVirtual()) ? 1 : 0;
7465}
7466} // end: extern "C"
7467
7468//===----------------------------------------------------------------------===//
7469// Attribute introspection.
7470//===----------------------------------------------------------------------===//
7471
7472extern "C" {
7473CXType clang_getIBOutletCollectionType(CXCursor C) {
7474 if (C.kind != CXCursor_IBOutletCollectionAttr)
7475 return cxtype::MakeCXType(QualType(), cxcursor::getCursorTU(C));
7476
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00007477 const IBOutletCollectionAttr *A =
Guy Benyei11169dd2012-12-18 14:30:41 +00007478 cast<IBOutletCollectionAttr>(cxcursor::getCursorAttr(C));
7479
7480 return cxtype::MakeCXType(A->getInterface(), cxcursor::getCursorTU(C));
7481}
7482} // end: extern "C"
7483
7484//===----------------------------------------------------------------------===//
7485// Inspecting memory usage.
7486//===----------------------------------------------------------------------===//
7487
7488typedef std::vector<CXTUResourceUsageEntry> MemUsageEntries;
7489
7490static inline void createCXTUResourceUsageEntry(MemUsageEntries &entries,
7491 enum CXTUResourceUsageKind k,
7492 unsigned long amount) {
7493 CXTUResourceUsageEntry entry = { k, amount };
7494 entries.push_back(entry);
7495}
7496
7497extern "C" {
7498
7499const char *clang_getTUResourceUsageName(CXTUResourceUsageKind kind) {
7500 const char *str = "";
7501 switch (kind) {
7502 case CXTUResourceUsage_AST:
7503 str = "ASTContext: expressions, declarations, and types";
7504 break;
7505 case CXTUResourceUsage_Identifiers:
7506 str = "ASTContext: identifiers";
7507 break;
7508 case CXTUResourceUsage_Selectors:
7509 str = "ASTContext: selectors";
7510 break;
7511 case CXTUResourceUsage_GlobalCompletionResults:
7512 str = "Code completion: cached global results";
7513 break;
7514 case CXTUResourceUsage_SourceManagerContentCache:
7515 str = "SourceManager: content cache allocator";
7516 break;
7517 case CXTUResourceUsage_AST_SideTables:
7518 str = "ASTContext: side tables";
7519 break;
7520 case CXTUResourceUsage_SourceManager_Membuffer_Malloc:
7521 str = "SourceManager: malloc'ed memory buffers";
7522 break;
7523 case CXTUResourceUsage_SourceManager_Membuffer_MMap:
7524 str = "SourceManager: mmap'ed memory buffers";
7525 break;
7526 case CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc:
7527 str = "ExternalASTSource: malloc'ed memory buffers";
7528 break;
7529 case CXTUResourceUsage_ExternalASTSource_Membuffer_MMap:
7530 str = "ExternalASTSource: mmap'ed memory buffers";
7531 break;
7532 case CXTUResourceUsage_Preprocessor:
7533 str = "Preprocessor: malloc'ed memory";
7534 break;
7535 case CXTUResourceUsage_PreprocessingRecord:
7536 str = "Preprocessor: PreprocessingRecord";
7537 break;
7538 case CXTUResourceUsage_SourceManager_DataStructures:
7539 str = "SourceManager: data structures and tables";
7540 break;
7541 case CXTUResourceUsage_Preprocessor_HeaderSearch:
7542 str = "Preprocessor: header search tables";
7543 break;
7544 }
7545 return str;
7546}
7547
7548CXTUResourceUsage clang_getCXTUResourceUsage(CXTranslationUnit TU) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00007549 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00007550 LOG_BAD_TU(TU);
Craig Topper69186e72014-06-08 08:38:04 +00007551 CXTUResourceUsage usage = { (void*) nullptr, 0, nullptr };
Guy Benyei11169dd2012-12-18 14:30:41 +00007552 return usage;
7553 }
7554
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007555 ASTUnit *astUnit = cxtu::getASTUnit(TU);
Ahmed Charlesb8984322014-03-07 20:03:18 +00007556 std::unique_ptr<MemUsageEntries> entries(new MemUsageEntries());
Guy Benyei11169dd2012-12-18 14:30:41 +00007557 ASTContext &astContext = astUnit->getASTContext();
7558
7559 // How much memory is used by AST nodes and types?
7560 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST,
7561 (unsigned long) astContext.getASTAllocatedMemory());
7562
7563 // How much memory is used by identifiers?
7564 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Identifiers,
7565 (unsigned long) astContext.Idents.getAllocator().getTotalMemory());
7566
7567 // How much memory is used for selectors?
7568 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Selectors,
7569 (unsigned long) astContext.Selectors.getTotalMemory());
7570
7571 // How much memory is used by ASTContext's side tables?
7572 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST_SideTables,
7573 (unsigned long) astContext.getSideTableAllocatedMemory());
7574
7575 // How much memory is used for caching global code completion results?
7576 unsigned long completionBytes = 0;
7577 if (GlobalCodeCompletionAllocator *completionAllocator =
Alp Tokerf994cef2014-07-05 03:08:06 +00007578 astUnit->getCachedCompletionAllocator().get()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00007579 completionBytes = completionAllocator->getTotalMemory();
7580 }
7581 createCXTUResourceUsageEntry(*entries,
7582 CXTUResourceUsage_GlobalCompletionResults,
7583 completionBytes);
7584
7585 // How much memory is being used by SourceManager's content cache?
7586 createCXTUResourceUsageEntry(*entries,
7587 CXTUResourceUsage_SourceManagerContentCache,
7588 (unsigned long) astContext.getSourceManager().getContentCacheSize());
7589
7590 // How much memory is being used by the MemoryBuffer's in SourceManager?
7591 const SourceManager::MemoryBufferSizes &srcBufs =
7592 astUnit->getSourceManager().getMemoryBufferSizes();
7593
7594 createCXTUResourceUsageEntry(*entries,
7595 CXTUResourceUsage_SourceManager_Membuffer_Malloc,
7596 (unsigned long) srcBufs.malloc_bytes);
7597 createCXTUResourceUsageEntry(*entries,
7598 CXTUResourceUsage_SourceManager_Membuffer_MMap,
7599 (unsigned long) srcBufs.mmap_bytes);
7600 createCXTUResourceUsageEntry(*entries,
7601 CXTUResourceUsage_SourceManager_DataStructures,
7602 (unsigned long) astContext.getSourceManager()
7603 .getDataStructureSizes());
7604
7605 // How much memory is being used by the ExternalASTSource?
7606 if (ExternalASTSource *esrc = astContext.getExternalSource()) {
7607 const ExternalASTSource::MemoryBufferSizes &sizes =
7608 esrc->getMemoryBufferSizes();
7609
7610 createCXTUResourceUsageEntry(*entries,
7611 CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc,
7612 (unsigned long) sizes.malloc_bytes);
7613 createCXTUResourceUsageEntry(*entries,
7614 CXTUResourceUsage_ExternalASTSource_Membuffer_MMap,
7615 (unsigned long) sizes.mmap_bytes);
7616 }
7617
7618 // How much memory is being used by the Preprocessor?
7619 Preprocessor &pp = astUnit->getPreprocessor();
7620 createCXTUResourceUsageEntry(*entries,
7621 CXTUResourceUsage_Preprocessor,
7622 pp.getTotalMemory());
7623
7624 if (PreprocessingRecord *pRec = pp.getPreprocessingRecord()) {
7625 createCXTUResourceUsageEntry(*entries,
7626 CXTUResourceUsage_PreprocessingRecord,
7627 pRec->getTotalMemory());
7628 }
7629
7630 createCXTUResourceUsageEntry(*entries,
7631 CXTUResourceUsage_Preprocessor_HeaderSearch,
7632 pp.getHeaderSearchInfo().getTotalMemory());
Craig Topper69186e72014-06-08 08:38:04 +00007633
Guy Benyei11169dd2012-12-18 14:30:41 +00007634 CXTUResourceUsage usage = { (void*) entries.get(),
7635 (unsigned) entries->size(),
Alexander Kornienko6ee521c2015-01-23 15:36:10 +00007636 !entries->empty() ? &(*entries)[0] : nullptr };
Ahmed Charles9a16beb2014-03-07 19:33:25 +00007637 entries.release();
Guy Benyei11169dd2012-12-18 14:30:41 +00007638 return usage;
7639}
7640
7641void clang_disposeCXTUResourceUsage(CXTUResourceUsage usage) {
7642 if (usage.data)
7643 delete (MemUsageEntries*) usage.data;
7644}
7645
Argyrios Kyrtzidis0e282ef2013-12-06 18:55:45 +00007646CXSourceRangeList *clang_getSkippedRanges(CXTranslationUnit TU, CXFile file) {
7647 CXSourceRangeList *skipped = new CXSourceRangeList;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00007648 skipped->count = 0;
Craig Topper69186e72014-06-08 08:38:04 +00007649 skipped->ranges = nullptr;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00007650
Dmitri Gribenko852d6222014-02-11 15:02:48 +00007651 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00007652 LOG_BAD_TU(TU);
7653 return skipped;
7654 }
7655
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00007656 if (!file)
7657 return skipped;
7658
7659 ASTUnit *astUnit = cxtu::getASTUnit(TU);
7660 PreprocessingRecord *ppRec = astUnit->getPreprocessor().getPreprocessingRecord();
7661 if (!ppRec)
7662 return skipped;
7663
7664 ASTContext &Ctx = astUnit->getASTContext();
7665 SourceManager &sm = Ctx.getSourceManager();
7666 FileEntry *fileEntry = static_cast<FileEntry *>(file);
7667 FileID wantedFileID = sm.translateFile(fileEntry);
7668
7669 const std::vector<SourceRange> &SkippedRanges = ppRec->getSkippedRanges();
7670 std::vector<SourceRange> wantedRanges;
7671 for (std::vector<SourceRange>::const_iterator i = SkippedRanges.begin(), ei = SkippedRanges.end();
7672 i != ei; ++i) {
7673 if (sm.getFileID(i->getBegin()) == wantedFileID || sm.getFileID(i->getEnd()) == wantedFileID)
7674 wantedRanges.push_back(*i);
7675 }
7676
7677 skipped->count = wantedRanges.size();
7678 skipped->ranges = new CXSourceRange[skipped->count];
7679 for (unsigned i = 0, ei = skipped->count; i != ei; ++i)
7680 skipped->ranges[i] = cxloc::translateSourceRange(Ctx, wantedRanges[i]);
7681
7682 return skipped;
7683}
7684
Argyrios Kyrtzidis0e282ef2013-12-06 18:55:45 +00007685void clang_disposeSourceRangeList(CXSourceRangeList *ranges) {
7686 if (ranges) {
7687 delete[] ranges->ranges;
7688 delete ranges;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00007689 }
7690}
7691
Guy Benyei11169dd2012-12-18 14:30:41 +00007692} // end extern "C"
7693
7694void clang::PrintLibclangResourceUsage(CXTranslationUnit TU) {
7695 CXTUResourceUsage Usage = clang_getCXTUResourceUsage(TU);
7696 for (unsigned I = 0; I != Usage.numEntries; ++I)
7697 fprintf(stderr, " %s: %lu\n",
7698 clang_getTUResourceUsageName(Usage.entries[I].kind),
7699 Usage.entries[I].amount);
7700
7701 clang_disposeCXTUResourceUsage(Usage);
7702}
7703
7704//===----------------------------------------------------------------------===//
7705// Misc. utility functions.
7706//===----------------------------------------------------------------------===//
7707
7708/// Default to using an 8 MB stack size on "safety" threads.
7709static unsigned SafetyStackThreadSize = 8 << 20;
7710
7711namespace clang {
7712
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00007713bool RunSafely(llvm::CrashRecoveryContext &CRC, llvm::function_ref<void()> Fn,
Guy Benyei11169dd2012-12-18 14:30:41 +00007714 unsigned Size) {
7715 if (!Size)
7716 Size = GetSafetyThreadStackSize();
7717 if (Size)
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00007718 return CRC.RunSafelyOnThread(Fn, Size);
7719 return CRC.RunSafely(Fn);
Guy Benyei11169dd2012-12-18 14:30:41 +00007720}
7721
7722unsigned GetSafetyThreadStackSize() {
7723 return SafetyStackThreadSize;
7724}
7725
7726void SetSafetyThreadStackSize(unsigned Value) {
7727 SafetyStackThreadSize = Value;
7728}
7729
Alexander Kornienkoab9db512015-06-22 23:07:51 +00007730}
Guy Benyei11169dd2012-12-18 14:30:41 +00007731
7732void clang::setThreadBackgroundPriority() {
7733 if (getenv("LIBCLANG_BGPRIO_DISABLE"))
7734 return;
7735
Alp Toker1a86ad22014-07-06 06:24:00 +00007736#ifdef USE_DARWIN_THREADS
Guy Benyei11169dd2012-12-18 14:30:41 +00007737 setpriority(PRIO_DARWIN_THREAD, 0, PRIO_DARWIN_BG);
7738#endif
7739}
7740
7741void cxindex::printDiagsToStderr(ASTUnit *Unit) {
7742 if (!Unit)
7743 return;
7744
7745 for (ASTUnit::stored_diag_iterator D = Unit->stored_diag_begin(),
7746 DEnd = Unit->stored_diag_end();
7747 D != DEnd; ++D) {
Ben Langmuir749323f2014-04-22 17:40:12 +00007748 CXStoredDiagnostic Diag(*D, Unit->getLangOpts());
Guy Benyei11169dd2012-12-18 14:30:41 +00007749 CXString Msg = clang_formatDiagnostic(&Diag,
7750 clang_defaultDiagnosticDisplayOptions());
7751 fprintf(stderr, "%s\n", clang_getCString(Msg));
7752 clang_disposeString(Msg);
7753 }
7754#ifdef LLVM_ON_WIN32
7755 // On Windows, force a flush, since there may be multiple copies of
7756 // stderr and stdout in the file system, all with different buffers
7757 // but writing to the same device.
7758 fflush(stderr);
7759#endif
7760}
7761
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007762MacroInfo *cxindex::getMacroInfo(const IdentifierInfo &II,
7763 SourceLocation MacroDefLoc,
7764 CXTranslationUnit TU){
7765 if (MacroDefLoc.isInvalid() || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00007766 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007767 if (!II.hadMacroDefinition())
Craig Topper69186e72014-06-08 08:38:04 +00007768 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007769
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007770 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00007771 Preprocessor &PP = Unit->getPreprocessor();
Richard Smith20e883e2015-04-29 23:20:19 +00007772 MacroDirective *MD = PP.getLocalMacroDirectiveHistory(&II);
Argyrios Kyrtzidisb6210df2013-03-26 17:17:01 +00007773 if (MD) {
7774 for (MacroDirective::DefInfo
7775 Def = MD->getDefinition(); Def; Def = Def.getPreviousDefinition()) {
7776 if (MacroDefLoc == Def.getMacroInfo()->getDefinitionLoc())
7777 return Def.getMacroInfo();
7778 }
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007779 }
7780
Craig Topper69186e72014-06-08 08:38:04 +00007781 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007782}
7783
Richard Smith66a81862015-05-04 02:25:31 +00007784const MacroInfo *cxindex::getMacroInfo(const MacroDefinitionRecord *MacroDef,
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00007785 CXTranslationUnit TU) {
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007786 if (!MacroDef || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00007787 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007788 const IdentifierInfo *II = MacroDef->getName();
7789 if (!II)
Craig Topper69186e72014-06-08 08:38:04 +00007790 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007791
7792 return getMacroInfo(*II, MacroDef->getLocation(), TU);
7793}
7794
Richard Smith66a81862015-05-04 02:25:31 +00007795MacroDefinitionRecord *
7796cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI, const Token &Tok,
7797 CXTranslationUnit TU) {
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007798 if (!MI || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00007799 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007800 if (Tok.isNot(tok::raw_identifier))
Craig Topper69186e72014-06-08 08:38:04 +00007801 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007802
7803 if (MI->getNumTokens() == 0)
Craig Topper69186e72014-06-08 08:38:04 +00007804 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007805 SourceRange DefRange(MI->getReplacementToken(0).getLocation(),
7806 MI->getDefinitionEndLoc());
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007807 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007808
7809 // Check that the token is inside the definition and not its argument list.
7810 SourceManager &SM = Unit->getSourceManager();
7811 if (SM.isBeforeInTranslationUnit(Tok.getLocation(), DefRange.getBegin()))
Craig Topper69186e72014-06-08 08:38:04 +00007812 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007813 if (SM.isBeforeInTranslationUnit(DefRange.getEnd(), Tok.getLocation()))
Craig Topper69186e72014-06-08 08:38:04 +00007814 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007815
7816 Preprocessor &PP = Unit->getPreprocessor();
7817 PreprocessingRecord *PPRec = PP.getPreprocessingRecord();
7818 if (!PPRec)
Craig Topper69186e72014-06-08 08:38:04 +00007819 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007820
Alp Toker2d57cea2014-05-17 04:53:25 +00007821 IdentifierInfo &II = PP.getIdentifierTable().get(Tok.getRawIdentifier());
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007822 if (!II.hadMacroDefinition())
Craig Topper69186e72014-06-08 08:38:04 +00007823 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007824
7825 // Check that the identifier is not one of the macro arguments.
7826 if (std::find(MI->arg_begin(), MI->arg_end(), &II) != MI->arg_end())
Craig Topper69186e72014-06-08 08:38:04 +00007827 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007828
Richard Smith20e883e2015-04-29 23:20:19 +00007829 MacroDirective *InnerMD = PP.getLocalMacroDirectiveHistory(&II);
Argyrios Kyrtzidis09c9e812013-02-20 00:54:57 +00007830 if (!InnerMD)
Craig Topper69186e72014-06-08 08:38:04 +00007831 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007832
Argyrios Kyrtzidisb6210df2013-03-26 17:17:01 +00007833 return PPRec->findMacroDefinition(InnerMD->getMacroInfo());
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007834}
7835
Richard Smith66a81862015-05-04 02:25:31 +00007836MacroDefinitionRecord *
7837cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI, SourceLocation Loc,
7838 CXTranslationUnit TU) {
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007839 if (Loc.isInvalid() || !MI || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00007840 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007841
7842 if (MI->getNumTokens() == 0)
Craig Topper69186e72014-06-08 08:38:04 +00007843 return nullptr;
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007844 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007845 Preprocessor &PP = Unit->getPreprocessor();
7846 if (!PP.getPreprocessingRecord())
Craig Topper69186e72014-06-08 08:38:04 +00007847 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007848 Loc = Unit->getSourceManager().getSpellingLoc(Loc);
7849 Token Tok;
7850 if (PP.getRawToken(Loc, Tok))
Craig Topper69186e72014-06-08 08:38:04 +00007851 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007852
7853 return checkForMacroInMacroDefinition(MI, Tok, TU);
7854}
7855
Guy Benyei11169dd2012-12-18 14:30:41 +00007856extern "C" {
7857
7858CXString clang_getClangVersion() {
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00007859 return cxstring::createDup(getClangFullVersion());
Guy Benyei11169dd2012-12-18 14:30:41 +00007860}
7861
7862} // end: extern "C"
7863
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007864Logger &cxindex::Logger::operator<<(CXTranslationUnit TU) {
7865 if (TU) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007866 if (ASTUnit *Unit = cxtu::getASTUnit(TU)) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007867 LogOS << '<' << Unit->getMainFileName() << '>';
Argyrios Kyrtzidis37f2ab42013-03-05 20:21:14 +00007868 if (Unit->isMainFileAST())
7869 LogOS << " (" << Unit->getASTFileName() << ')';
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007870 return *this;
7871 }
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00007872 } else {
7873 LogOS << "<NULL TU>";
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007874 }
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007875 return *this;
7876}
7877
Argyrios Kyrtzidisba4b5f82013-03-08 02:32:26 +00007878Logger &cxindex::Logger::operator<<(const FileEntry *FE) {
7879 *this << FE->getName();
7880 return *this;
7881}
7882
7883Logger &cxindex::Logger::operator<<(CXCursor cursor) {
7884 CXString cursorName = clang_getCursorDisplayName(cursor);
7885 *this << cursorName << "@" << clang_getCursorLocation(cursor);
7886 clang_disposeString(cursorName);
7887 return *this;
7888}
7889
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007890Logger &cxindex::Logger::operator<<(CXSourceLocation Loc) {
7891 CXFile File;
7892 unsigned Line, Column;
Craig Topper69186e72014-06-08 08:38:04 +00007893 clang_getFileLocation(Loc, &File, &Line, &Column, nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007894 CXString FileName = clang_getFileName(File);
7895 *this << llvm::format("(%s:%d:%d)", clang_getCString(FileName), Line, Column);
7896 clang_disposeString(FileName);
7897 return *this;
7898}
7899
7900Logger &cxindex::Logger::operator<<(CXSourceRange range) {
7901 CXSourceLocation BLoc = clang_getRangeStart(range);
7902 CXSourceLocation ELoc = clang_getRangeEnd(range);
7903
7904 CXFile BFile;
7905 unsigned BLine, BColumn;
Craig Topper69186e72014-06-08 08:38:04 +00007906 clang_getFileLocation(BLoc, &BFile, &BLine, &BColumn, nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007907
7908 CXFile EFile;
7909 unsigned ELine, EColumn;
Craig Topper69186e72014-06-08 08:38:04 +00007910 clang_getFileLocation(ELoc, &EFile, &ELine, &EColumn, nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007911
7912 CXString BFileName = clang_getFileName(BFile);
7913 if (BFile == EFile) {
7914 *this << llvm::format("[%s %d:%d-%d:%d]", clang_getCString(BFileName),
7915 BLine, BColumn, ELine, EColumn);
7916 } else {
7917 CXString EFileName = clang_getFileName(EFile);
7918 *this << llvm::format("[%s:%d:%d - ", clang_getCString(BFileName),
7919 BLine, BColumn)
7920 << llvm::format("%s:%d:%d]", clang_getCString(EFileName),
7921 ELine, EColumn);
7922 clang_disposeString(EFileName);
7923 }
7924 clang_disposeString(BFileName);
7925 return *this;
7926}
7927
7928Logger &cxindex::Logger::operator<<(CXString Str) {
7929 *this << clang_getCString(Str);
7930 return *this;
7931}
7932
7933Logger &cxindex::Logger::operator<<(const llvm::format_object_base &Fmt) {
7934 LogOS << Fmt;
7935 return *this;
7936}
7937
Chandler Carruth37ad2582014-06-27 15:14:39 +00007938static llvm::ManagedStatic<llvm::sys::Mutex> LoggingMutex;
7939
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007940cxindex::Logger::~Logger() {
Chandler Carruth37ad2582014-06-27 15:14:39 +00007941 llvm::sys::ScopedLock L(*LoggingMutex);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007942
7943 static llvm::TimeRecord sBeginTR = llvm::TimeRecord::getCurrentTime();
7944
Dmitri Gribenkof8579502013-01-12 19:30:44 +00007945 raw_ostream &OS = llvm::errs();
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007946 OS << "[libclang:" << Name << ':';
7947
Alp Toker1a86ad22014-07-06 06:24:00 +00007948#ifdef USE_DARWIN_THREADS
7949 // TODO: Portability.
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007950 mach_port_t tid = pthread_mach_thread_np(pthread_self());
7951 OS << tid << ':';
7952#endif
7953
7954 llvm::TimeRecord TR = llvm::TimeRecord::getCurrentTime();
7955 OS << llvm::format("%7.4f] ", TR.getWallTime() - sBeginTR.getWallTime());
Yaron Keren09fb7c62015-03-10 07:33:23 +00007956 OS << Msg << '\n';
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007957
7958 if (Trace) {
Zachary Turner1fe2a8d2015-03-05 19:15:09 +00007959 llvm::sys::PrintStackTrace(OS);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007960 OS << "--------------------------------------------------\n";
7961 }
7962}
Benjamin Kramerc1ffdab2016-03-03 08:58:18 +00007963
7964#ifdef CLANG_TOOL_EXTRA_BUILD
7965// This anchor is used to force the linker to link the clang-tidy plugin.
7966extern volatile int ClangTidyPluginAnchorSource;
7967static int LLVM_ATTRIBUTE_UNUSED ClangTidyPluginAnchorDestination =
7968 ClangTidyPluginAnchorSource;
7969#endif