blob: b3f33ad8ffda2dec3ec22dbe21566fa084e89264 [file] [log] [blame]
Guy Benyei11169dd2012-12-18 14:30:41 +00001//===- CIndex.cpp - Clang-C Source Indexing Library -----------------------===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file implements the main API hooks in the Clang-C Source Indexing
11// library.
12//
13//===----------------------------------------------------------------------===//
14
15#include "CIndexer.h"
16#include "CIndexDiagnostic.h"
Chandler Carruth4b417452013-01-19 08:09:44 +000017#include "CLog.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000018#include "CXCursor.h"
19#include "CXSourceLocation.h"
20#include "CXString.h"
21#include "CXTranslationUnit.h"
22#include "CXType.h"
23#include "CursorVisitor.h"
David Blaikie0a4e61f2013-09-13 18:32:52 +000024#include "clang/AST/Attr.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000025#include "clang/AST/StmtVisitor.h"
26#include "clang/Basic/Diagnostic.h"
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +000027#include "clang/Basic/DiagnosticCategories.h"
28#include "clang/Basic/DiagnosticIDs.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000029#include "clang/Basic/Version.h"
30#include "clang/Frontend/ASTUnit.h"
31#include "clang/Frontend/CompilerInstance.h"
32#include "clang/Frontend/FrontendDiagnostic.h"
Argyrios Kyrtzidisca741ce2016-02-14 22:30:14 +000033#include "clang/Index/CodegenNameGenerator.h"
Dmitri Gribenko9e605112013-11-13 22:16:51 +000034#include "clang/Index/CommentToXML.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000035#include "clang/Lex/HeaderSearch.h"
36#include "clang/Lex/Lexer.h"
37#include "clang/Lex/PreprocessingRecord.h"
38#include "clang/Lex/Preprocessor.h"
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +000039#include "clang/Serialization/SerializationDiagnostic.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000040#include "llvm/ADT/Optional.h"
41#include "llvm/ADT/STLExtras.h"
42#include "llvm/ADT/StringSwitch.h"
Alp Toker1d257e12014-06-04 03:28:55 +000043#include "llvm/Config/llvm-config.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000044#include "llvm/Support/Compiler.h"
45#include "llvm/Support/CrashRecoveryContext.h"
Chandler Carruth4b417452013-01-19 08:09:44 +000046#include "llvm/Support/Format.h"
Chandler Carruth37ad2582014-06-27 15:14:39 +000047#include "llvm/Support/ManagedStatic.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000048#include "llvm/Support/MemoryBuffer.h"
49#include "llvm/Support/Mutex.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000050#include "llvm/Support/Program.h"
51#include "llvm/Support/SaveAndRestore.h"
52#include "llvm/Support/Signals.h"
Adrian Prantlbc068582015-07-08 01:00:30 +000053#include "llvm/Support/TargetSelect.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000054#include "llvm/Support/Threading.h"
55#include "llvm/Support/Timer.h"
56#include "llvm/Support/raw_ostream.h"
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +000057
Alp Toker1a86ad22014-07-06 06:24:00 +000058#if LLVM_ENABLE_THREADS != 0 && defined(__APPLE__)
59#define USE_DARWIN_THREADS
60#endif
61
62#ifdef USE_DARWIN_THREADS
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +000063#include <pthread.h>
64#endif
Guy Benyei11169dd2012-12-18 14:30:41 +000065
66using namespace clang;
67using namespace clang::cxcursor;
Guy Benyei11169dd2012-12-18 14:30:41 +000068using namespace clang::cxtu;
69using namespace clang::cxindex;
70
Dmitri Gribenkod36209e2013-01-26 21:32:42 +000071CXTranslationUnit cxtu::MakeCXTranslationUnit(CIndexer *CIdx, ASTUnit *AU) {
72 if (!AU)
Craig Topper69186e72014-06-08 08:38:04 +000073 return nullptr;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +000074 assert(CIdx);
Guy Benyei11169dd2012-12-18 14:30:41 +000075 CXTranslationUnit D = new CXTranslationUnitImpl();
76 D->CIdx = CIdx;
Dmitri Gribenkod36209e2013-01-26 21:32:42 +000077 D->TheASTUnit = AU;
Dmitri Gribenko74895212013-02-03 13:52:47 +000078 D->StringPool = new cxstring::CXStringPool();
Craig Topper69186e72014-06-08 08:38:04 +000079 D->Diagnostics = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +000080 D->OverridenCursorsPool = createOverridenCXCursorsPool();
Craig Topper69186e72014-06-08 08:38:04 +000081 D->CommentToXML = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +000082 return D;
83}
84
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +000085bool cxtu::isASTReadError(ASTUnit *AU) {
86 for (ASTUnit::stored_diag_iterator D = AU->stored_diag_begin(),
87 DEnd = AU->stored_diag_end();
88 D != DEnd; ++D) {
89 if (D->getLevel() >= DiagnosticsEngine::Error &&
90 DiagnosticIDs::getCategoryNumberForDiag(D->getID()) ==
91 diag::DiagCat_AST_Deserialization_Issue)
92 return true;
93 }
94 return false;
95}
96
Guy Benyei11169dd2012-12-18 14:30:41 +000097cxtu::CXTUOwner::~CXTUOwner() {
98 if (TU)
99 clang_disposeTranslationUnit(TU);
100}
101
102/// \brief Compare two source ranges to determine their relative position in
103/// the translation unit.
104static RangeComparisonResult RangeCompare(SourceManager &SM,
105 SourceRange R1,
106 SourceRange R2) {
107 assert(R1.isValid() && "First range is invalid?");
108 assert(R2.isValid() && "Second range is invalid?");
109 if (R1.getEnd() != R2.getBegin() &&
110 SM.isBeforeInTranslationUnit(R1.getEnd(), R2.getBegin()))
111 return RangeBefore;
112 if (R2.getEnd() != R1.getBegin() &&
113 SM.isBeforeInTranslationUnit(R2.getEnd(), R1.getBegin()))
114 return RangeAfter;
115 return RangeOverlap;
116}
117
118/// \brief Determine if a source location falls within, before, or after a
119/// a given source range.
120static RangeComparisonResult LocationCompare(SourceManager &SM,
121 SourceLocation L, SourceRange R) {
122 assert(R.isValid() && "First range is invalid?");
123 assert(L.isValid() && "Second range is invalid?");
124 if (L == R.getBegin() || L == R.getEnd())
125 return RangeOverlap;
126 if (SM.isBeforeInTranslationUnit(L, R.getBegin()))
127 return RangeBefore;
128 if (SM.isBeforeInTranslationUnit(R.getEnd(), L))
129 return RangeAfter;
130 return RangeOverlap;
131}
132
133/// \brief Translate a Clang source range into a CIndex source range.
134///
135/// Clang internally represents ranges where the end location points to the
136/// start of the token at the end. However, for external clients it is more
137/// useful to have a CXSourceRange be a proper half-open interval. This routine
138/// does the appropriate translation.
139CXSourceRange cxloc::translateSourceRange(const SourceManager &SM,
140 const LangOptions &LangOpts,
141 const CharSourceRange &R) {
142 // We want the last character in this location, so we will adjust the
143 // location accordingly.
144 SourceLocation EndLoc = R.getEnd();
145 if (EndLoc.isValid() && EndLoc.isMacroID() && !SM.isMacroArgExpansion(EndLoc))
146 EndLoc = SM.getExpansionRange(EndLoc).second;
Yaron Keren8b563662015-10-03 10:46:20 +0000147 if (R.isTokenRange() && EndLoc.isValid()) {
Guy Benyei11169dd2012-12-18 14:30:41 +0000148 unsigned Length = Lexer::MeasureTokenLength(SM.getSpellingLoc(EndLoc),
149 SM, LangOpts);
150 EndLoc = EndLoc.getLocWithOffset(Length);
151 }
152
Bill Wendlingeade3622013-01-23 08:25:41 +0000153 CXSourceRange Result = {
Dmitri Gribenkof9304482013-01-23 15:56:07 +0000154 { &SM, &LangOpts },
Bill Wendlingeade3622013-01-23 08:25:41 +0000155 R.getBegin().getRawEncoding(),
156 EndLoc.getRawEncoding()
157 };
Guy Benyei11169dd2012-12-18 14:30:41 +0000158 return Result;
159}
160
161//===----------------------------------------------------------------------===//
162// Cursor visitor.
163//===----------------------------------------------------------------------===//
164
165static SourceRange getRawCursorExtent(CXCursor C);
166static SourceRange getFullCursorExtent(CXCursor C, SourceManager &SrcMgr);
167
168
169RangeComparisonResult CursorVisitor::CompareRegionOfInterest(SourceRange R) {
170 return RangeCompare(AU->getSourceManager(), R, RegionOfInterest);
171}
172
173/// \brief Visit the given cursor and, if requested by the visitor,
174/// its children.
175///
176/// \param Cursor the cursor to visit.
177///
178/// \param CheckedRegionOfInterest if true, then the caller already checked
179/// that this cursor is within the region of interest.
180///
181/// \returns true if the visitation should be aborted, false if it
182/// should continue.
183bool CursorVisitor::Visit(CXCursor Cursor, bool CheckedRegionOfInterest) {
184 if (clang_isInvalid(Cursor.kind))
185 return false;
186
187 if (clang_isDeclaration(Cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +0000188 const Decl *D = getCursorDecl(Cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +0000189 if (!D) {
190 assert(0 && "Invalid declaration cursor");
191 return true; // abort.
192 }
193
194 // Ignore implicit declarations, unless it's an objc method because
195 // currently we should report implicit methods for properties when indexing.
196 if (D->isImplicit() && !isa<ObjCMethodDecl>(D))
197 return false;
198 }
199
200 // If we have a range of interest, and this cursor doesn't intersect with it,
201 // we're done.
202 if (RegionOfInterest.isValid() && !CheckedRegionOfInterest) {
203 SourceRange Range = getRawCursorExtent(Cursor);
204 if (Range.isInvalid() || CompareRegionOfInterest(Range))
205 return false;
206 }
207
208 switch (Visitor(Cursor, Parent, ClientData)) {
209 case CXChildVisit_Break:
210 return true;
211
212 case CXChildVisit_Continue:
213 return false;
214
215 case CXChildVisit_Recurse: {
216 bool ret = VisitChildren(Cursor);
217 if (PostChildrenVisitor)
218 if (PostChildrenVisitor(Cursor, ClientData))
219 return true;
220 return ret;
221 }
222 }
223
224 llvm_unreachable("Invalid CXChildVisitResult!");
225}
226
227static bool visitPreprocessedEntitiesInRange(SourceRange R,
228 PreprocessingRecord &PPRec,
229 CursorVisitor &Visitor) {
230 SourceManager &SM = Visitor.getASTUnit()->getSourceManager();
231 FileID FID;
232
233 if (!Visitor.shouldVisitIncludedEntities()) {
234 // If the begin/end of the range lie in the same FileID, do the optimization
235 // where we skip preprocessed entities that do not come from the same FileID.
236 FID = SM.getFileID(SM.getFileLoc(R.getBegin()));
237 if (FID != SM.getFileID(SM.getFileLoc(R.getEnd())))
238 FID = FileID();
239 }
240
Benjamin Kramerb4ef6682015-02-06 17:25:10 +0000241 const auto &Entities = PPRec.getPreprocessedEntitiesInRange(R);
242 return Visitor.visitPreprocessedEntities(Entities.begin(), Entities.end(),
Guy Benyei11169dd2012-12-18 14:30:41 +0000243 PPRec, FID);
244}
245
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000246bool CursorVisitor::visitFileRegion() {
Guy Benyei11169dd2012-12-18 14:30:41 +0000247 if (RegionOfInterest.isInvalid())
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000248 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000249
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +0000250 ASTUnit *Unit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +0000251 SourceManager &SM = Unit->getSourceManager();
252
253 std::pair<FileID, unsigned>
254 Begin = SM.getDecomposedLoc(SM.getFileLoc(RegionOfInterest.getBegin())),
255 End = SM.getDecomposedLoc(SM.getFileLoc(RegionOfInterest.getEnd()));
256
257 if (End.first != Begin.first) {
258 // If the end does not reside in the same file, try to recover by
259 // picking the end of the file of begin location.
260 End.first = Begin.first;
261 End.second = SM.getFileIDSize(Begin.first);
262 }
263
264 assert(Begin.first == End.first);
265 if (Begin.second > End.second)
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000266 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000267
268 FileID File = Begin.first;
269 unsigned Offset = Begin.second;
270 unsigned Length = End.second - Begin.second;
271
272 if (!VisitDeclsOnly && !VisitPreprocessorLast)
273 if (visitPreprocessedEntitiesInRegion())
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000274 return true; // visitation break.
Guy Benyei11169dd2012-12-18 14:30:41 +0000275
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000276 if (visitDeclsFromFileRegion(File, Offset, Length))
277 return true; // visitation break.
Guy Benyei11169dd2012-12-18 14:30:41 +0000278
279 if (!VisitDeclsOnly && VisitPreprocessorLast)
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000280 return visitPreprocessedEntitiesInRegion();
281
282 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000283}
284
285static bool isInLexicalContext(Decl *D, DeclContext *DC) {
286 if (!DC)
287 return false;
288
289 for (DeclContext *DeclDC = D->getLexicalDeclContext();
290 DeclDC; DeclDC = DeclDC->getLexicalParent()) {
291 if (DeclDC == DC)
292 return true;
293 }
294 return false;
295}
296
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000297bool CursorVisitor::visitDeclsFromFileRegion(FileID File,
Guy Benyei11169dd2012-12-18 14:30:41 +0000298 unsigned Offset, unsigned Length) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +0000299 ASTUnit *Unit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +0000300 SourceManager &SM = Unit->getSourceManager();
301 SourceRange Range = RegionOfInterest;
302
303 SmallVector<Decl *, 16> Decls;
304 Unit->findFileRegionDecls(File, Offset, Length, Decls);
305
306 // If we didn't find any file level decls for the file, try looking at the
307 // file that it was included from.
308 while (Decls.empty() || Decls.front()->isTopLevelDeclInObjCContainer()) {
309 bool Invalid = false;
310 const SrcMgr::SLocEntry &SLEntry = SM.getSLocEntry(File, &Invalid);
311 if (Invalid)
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000312 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000313
314 SourceLocation Outer;
315 if (SLEntry.isFile())
316 Outer = SLEntry.getFile().getIncludeLoc();
317 else
318 Outer = SLEntry.getExpansion().getExpansionLocStart();
319 if (Outer.isInvalid())
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000320 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000321
Benjamin Kramer867ea1d2014-03-02 13:01:17 +0000322 std::tie(File, Offset) = SM.getDecomposedExpansionLoc(Outer);
Guy Benyei11169dd2012-12-18 14:30:41 +0000323 Length = 0;
324 Unit->findFileRegionDecls(File, Offset, Length, Decls);
325 }
326
327 assert(!Decls.empty());
328
329 bool VisitedAtLeastOnce = false;
Craig Topper69186e72014-06-08 08:38:04 +0000330 DeclContext *CurDC = nullptr;
Craig Topper2341c0d2013-07-04 03:08:24 +0000331 SmallVectorImpl<Decl *>::iterator DIt = Decls.begin();
332 for (SmallVectorImpl<Decl *>::iterator DE = Decls.end(); DIt != DE; ++DIt) {
Guy Benyei11169dd2012-12-18 14:30:41 +0000333 Decl *D = *DIt;
334 if (D->getSourceRange().isInvalid())
335 continue;
336
337 if (isInLexicalContext(D, CurDC))
338 continue;
339
340 CurDC = dyn_cast<DeclContext>(D);
341
342 if (TagDecl *TD = dyn_cast<TagDecl>(D))
343 if (!TD->isFreeStanding())
344 continue;
345
346 RangeComparisonResult CompRes = RangeCompare(SM, D->getSourceRange(),Range);
347 if (CompRes == RangeBefore)
348 continue;
349 if (CompRes == RangeAfter)
350 break;
351
352 assert(CompRes == RangeOverlap);
353 VisitedAtLeastOnce = true;
354
355 if (isa<ObjCContainerDecl>(D)) {
356 FileDI_current = &DIt;
357 FileDE_current = DE;
358 } else {
Craig Topper69186e72014-06-08 08:38:04 +0000359 FileDI_current = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +0000360 }
361
362 if (Visit(MakeCXCursor(D, TU, Range), /*CheckedRegionOfInterest=*/true))
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000363 return true; // visitation break.
Guy Benyei11169dd2012-12-18 14:30:41 +0000364 }
365
366 if (VisitedAtLeastOnce)
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000367 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000368
369 // No Decls overlapped with the range. Move up the lexical context until there
370 // is a context that contains the range or we reach the translation unit
371 // level.
372 DeclContext *DC = DIt == Decls.begin() ? (*DIt)->getLexicalDeclContext()
373 : (*(DIt-1))->getLexicalDeclContext();
374
375 while (DC && !DC->isTranslationUnit()) {
376 Decl *D = cast<Decl>(DC);
377 SourceRange CurDeclRange = D->getSourceRange();
378 if (CurDeclRange.isInvalid())
379 break;
380
381 if (RangeCompare(SM, CurDeclRange, Range) == RangeOverlap) {
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000382 if (Visit(MakeCXCursor(D, TU, Range), /*CheckedRegionOfInterest=*/true))
383 return true; // visitation break.
Guy Benyei11169dd2012-12-18 14:30:41 +0000384 }
385
386 DC = D->getLexicalDeclContext();
387 }
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000388
389 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000390}
391
392bool CursorVisitor::visitPreprocessedEntitiesInRegion() {
393 if (!AU->getPreprocessor().getPreprocessingRecord())
394 return false;
395
396 PreprocessingRecord &PPRec
397 = *AU->getPreprocessor().getPreprocessingRecord();
398 SourceManager &SM = AU->getSourceManager();
399
400 if (RegionOfInterest.isValid()) {
401 SourceRange MappedRange = AU->mapRangeToPreamble(RegionOfInterest);
402 SourceLocation B = MappedRange.getBegin();
403 SourceLocation E = MappedRange.getEnd();
404
405 if (AU->isInPreambleFileID(B)) {
406 if (SM.isLoadedSourceLocation(E))
407 return visitPreprocessedEntitiesInRange(SourceRange(B, E),
408 PPRec, *this);
409
410 // Beginning of range lies in the preamble but it also extends beyond
411 // it into the main file. Split the range into 2 parts, one covering
412 // the preamble and another covering the main file. This allows subsequent
413 // calls to visitPreprocessedEntitiesInRange to accept a source range that
414 // lies in the same FileID, allowing it to skip preprocessed entities that
415 // do not come from the same FileID.
416 bool breaked =
417 visitPreprocessedEntitiesInRange(
418 SourceRange(B, AU->getEndOfPreambleFileID()),
419 PPRec, *this);
420 if (breaked) return true;
421 return visitPreprocessedEntitiesInRange(
422 SourceRange(AU->getStartOfMainFileID(), E),
423 PPRec, *this);
424 }
425
426 return visitPreprocessedEntitiesInRange(SourceRange(B, E), PPRec, *this);
427 }
428
429 bool OnlyLocalDecls
430 = !AU->isMainFileAST() && AU->getOnlyLocalDecls();
431
432 if (OnlyLocalDecls)
433 return visitPreprocessedEntities(PPRec.local_begin(), PPRec.local_end(),
434 PPRec);
435
436 return visitPreprocessedEntities(PPRec.begin(), PPRec.end(), PPRec);
437}
438
439template<typename InputIterator>
440bool CursorVisitor::visitPreprocessedEntities(InputIterator First,
441 InputIterator Last,
442 PreprocessingRecord &PPRec,
443 FileID FID) {
444 for (; First != Last; ++First) {
445 if (!FID.isInvalid() && !PPRec.isEntityInFileID(First, FID))
446 continue;
447
448 PreprocessedEntity *PPE = *First;
Argyrios Kyrtzidis1030f262013-05-07 20:37:17 +0000449 if (!PPE)
450 continue;
451
Guy Benyei11169dd2012-12-18 14:30:41 +0000452 if (MacroExpansion *ME = dyn_cast<MacroExpansion>(PPE)) {
453 if (Visit(MakeMacroExpansionCursor(ME, TU)))
454 return true;
Richard Smith66a81862015-05-04 02:25:31 +0000455
Guy Benyei11169dd2012-12-18 14:30:41 +0000456 continue;
457 }
Richard Smith66a81862015-05-04 02:25:31 +0000458
459 if (MacroDefinitionRecord *MD = dyn_cast<MacroDefinitionRecord>(PPE)) {
Guy Benyei11169dd2012-12-18 14:30:41 +0000460 if (Visit(MakeMacroDefinitionCursor(MD, TU)))
461 return true;
Richard Smith66a81862015-05-04 02:25:31 +0000462
Guy Benyei11169dd2012-12-18 14:30:41 +0000463 continue;
464 }
465
466 if (InclusionDirective *ID = dyn_cast<InclusionDirective>(PPE)) {
467 if (Visit(MakeInclusionDirectiveCursor(ID, TU)))
468 return true;
469
470 continue;
471 }
472 }
473
474 return false;
475}
476
477/// \brief Visit the children of the given cursor.
478///
479/// \returns true if the visitation should be aborted, false if it
480/// should continue.
481bool CursorVisitor::VisitChildren(CXCursor Cursor) {
482 if (clang_isReference(Cursor.kind) &&
483 Cursor.kind != CXCursor_CXXBaseSpecifier) {
484 // By definition, references have no children.
485 return false;
486 }
487
488 // Set the Parent field to Cursor, then back to its old value once we're
489 // done.
490 SetParentRAII SetParent(Parent, StmtParent, Cursor);
491
492 if (clang_isDeclaration(Cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +0000493 Decl *D = const_cast<Decl *>(getCursorDecl(Cursor));
Guy Benyei11169dd2012-12-18 14:30:41 +0000494 if (!D)
495 return false;
496
497 return VisitAttributes(D) || Visit(D);
498 }
499
500 if (clang_isStatement(Cursor.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +0000501 if (const Stmt *S = getCursorStmt(Cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +0000502 return Visit(S);
503
504 return false;
505 }
506
507 if (clang_isExpression(Cursor.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +0000508 if (const Expr *E = getCursorExpr(Cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +0000509 return Visit(E);
510
511 return false;
512 }
513
514 if (clang_isTranslationUnit(Cursor.kind)) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +0000515 CXTranslationUnit TU = getCursorTU(Cursor);
516 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +0000517
518 int VisitOrder[2] = { VisitPreprocessorLast, !VisitPreprocessorLast };
519 for (unsigned I = 0; I != 2; ++I) {
520 if (VisitOrder[I]) {
521 if (!CXXUnit->isMainFileAST() && CXXUnit->getOnlyLocalDecls() &&
522 RegionOfInterest.isInvalid()) {
523 for (ASTUnit::top_level_iterator TL = CXXUnit->top_level_begin(),
524 TLEnd = CXXUnit->top_level_end();
525 TL != TLEnd; ++TL) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +0000526 if (Visit(MakeCXCursor(*TL, TU, RegionOfInterest), true))
Guy Benyei11169dd2012-12-18 14:30:41 +0000527 return true;
528 }
529 } else if (VisitDeclContext(
530 CXXUnit->getASTContext().getTranslationUnitDecl()))
531 return true;
532 continue;
533 }
534
535 // Walk the preprocessing record.
536 if (CXXUnit->getPreprocessor().getPreprocessingRecord())
537 visitPreprocessedEntitiesInRegion();
538 }
539
540 return false;
541 }
542
543 if (Cursor.kind == CXCursor_CXXBaseSpecifier) {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +0000544 if (const CXXBaseSpecifier *Base = getCursorCXXBaseSpecifier(Cursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +0000545 if (TypeSourceInfo *BaseTSInfo = Base->getTypeSourceInfo()) {
546 return Visit(BaseTSInfo->getTypeLoc());
547 }
548 }
549 }
550
551 if (Cursor.kind == CXCursor_IBOutletCollectionAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +0000552 const IBOutletCollectionAttr *A =
Guy Benyei11169dd2012-12-18 14:30:41 +0000553 cast<IBOutletCollectionAttr>(cxcursor::getCursorAttr(Cursor));
Richard Smithb1f9a282013-10-31 01:56:18 +0000554 if (const ObjCObjectType *ObjT = A->getInterface()->getAs<ObjCObjectType>())
Richard Smithb87c4652013-10-31 21:23:20 +0000555 return Visit(cxcursor::MakeCursorObjCClassRef(
556 ObjT->getInterface(),
557 A->getInterfaceLoc()->getTypeLoc().getLocStart(), TU));
Guy Benyei11169dd2012-12-18 14:30:41 +0000558 }
559
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +0000560 // If pointing inside a macro definition, check if the token is an identifier
561 // that was ever defined as a macro. In such a case, create a "pseudo" macro
562 // expansion cursor for that token.
563 SourceLocation BeginLoc = RegionOfInterest.getBegin();
564 if (Cursor.kind == CXCursor_MacroDefinition &&
565 BeginLoc == RegionOfInterest.getEnd()) {
566 SourceLocation Loc = AU->mapLocationToPreamble(BeginLoc);
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +0000567 const MacroInfo *MI =
568 getMacroInfo(cxcursor::getCursorMacroDefinition(Cursor), TU);
Richard Smith66a81862015-05-04 02:25:31 +0000569 if (MacroDefinitionRecord *MacroDef =
570 checkForMacroInMacroDefinition(MI, Loc, TU))
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +0000571 return Visit(cxcursor::MakeMacroExpansionCursor(MacroDef, BeginLoc, TU));
572 }
573
Guy Benyei11169dd2012-12-18 14:30:41 +0000574 // Nothing to visit at the moment.
575 return false;
576}
577
578bool CursorVisitor::VisitBlockDecl(BlockDecl *B) {
579 if (TypeSourceInfo *TSInfo = B->getSignatureAsWritten())
580 if (Visit(TSInfo->getTypeLoc()))
581 return true;
582
583 if (Stmt *Body = B->getBody())
584 return Visit(MakeCXCursor(Body, StmtParent, TU, RegionOfInterest));
585
586 return false;
587}
588
Ted Kremenek03325582013-02-21 01:29:01 +0000589Optional<bool> CursorVisitor::shouldVisitCursor(CXCursor Cursor) {
Guy Benyei11169dd2012-12-18 14:30:41 +0000590 if (RegionOfInterest.isValid()) {
591 SourceRange Range = getFullCursorExtent(Cursor, AU->getSourceManager());
592 if (Range.isInvalid())
David Blaikie7a30dc52013-02-21 01:47:18 +0000593 return None;
Guy Benyei11169dd2012-12-18 14:30:41 +0000594
595 switch (CompareRegionOfInterest(Range)) {
596 case RangeBefore:
597 // This declaration comes before the region of interest; skip it.
David Blaikie7a30dc52013-02-21 01:47:18 +0000598 return None;
Guy Benyei11169dd2012-12-18 14:30:41 +0000599
600 case RangeAfter:
601 // This declaration comes after the region of interest; we're done.
602 return false;
603
604 case RangeOverlap:
605 // This declaration overlaps the region of interest; visit it.
606 break;
607 }
608 }
609 return true;
610}
611
612bool CursorVisitor::VisitDeclContext(DeclContext *DC) {
613 DeclContext::decl_iterator I = DC->decls_begin(), E = DC->decls_end();
614
615 // FIXME: Eventually remove. This part of a hack to support proper
616 // iteration over all Decls contained lexically within an ObjC container.
617 SaveAndRestore<DeclContext::decl_iterator*> DI_saved(DI_current, &I);
618 SaveAndRestore<DeclContext::decl_iterator> DE_saved(DE_current, E);
619
620 for ( ; I != E; ++I) {
621 Decl *D = *I;
622 if (D->getLexicalDeclContext() != DC)
623 continue;
624 CXCursor Cursor = MakeCXCursor(D, TU, RegionOfInterest);
625
626 // Ignore synthesized ivars here, otherwise if we have something like:
627 // @synthesize prop = _prop;
628 // and '_prop' is not declared, we will encounter a '_prop' ivar before
629 // encountering the 'prop' synthesize declaration and we will think that
630 // we passed the region-of-interest.
631 if (ObjCIvarDecl *ivarD = dyn_cast<ObjCIvarDecl>(D)) {
632 if (ivarD->getSynthesize())
633 continue;
634 }
635
636 // FIXME: ObjCClassRef/ObjCProtocolRef for forward class/protocol
637 // declarations is a mismatch with the compiler semantics.
638 if (Cursor.kind == CXCursor_ObjCInterfaceDecl) {
639 ObjCInterfaceDecl *ID = cast<ObjCInterfaceDecl>(D);
640 if (!ID->isThisDeclarationADefinition())
641 Cursor = MakeCursorObjCClassRef(ID, ID->getLocation(), TU);
642
643 } else if (Cursor.kind == CXCursor_ObjCProtocolDecl) {
644 ObjCProtocolDecl *PD = cast<ObjCProtocolDecl>(D);
645 if (!PD->isThisDeclarationADefinition())
646 Cursor = MakeCursorObjCProtocolRef(PD, PD->getLocation(), TU);
647 }
648
Ted Kremenek03325582013-02-21 01:29:01 +0000649 const Optional<bool> &V = shouldVisitCursor(Cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +0000650 if (!V.hasValue())
651 continue;
652 if (!V.getValue())
653 return false;
654 if (Visit(Cursor, true))
655 return true;
656 }
657 return false;
658}
659
660bool CursorVisitor::VisitTranslationUnitDecl(TranslationUnitDecl *D) {
661 llvm_unreachable("Translation units are visited directly by Visit()");
662}
663
Sergey Kalinichev8f3b1872015-11-15 13:48:32 +0000664bool CursorVisitor::VisitTypeAliasTemplateDecl(TypeAliasTemplateDecl *D) {
665 if (VisitTemplateParameters(D->getTemplateParameters()))
666 return true;
667
668 return Visit(MakeCXCursor(D->getTemplatedDecl(), TU, RegionOfInterest));
669}
670
Guy Benyei11169dd2012-12-18 14:30:41 +0000671bool CursorVisitor::VisitTypeAliasDecl(TypeAliasDecl *D) {
672 if (TypeSourceInfo *TSInfo = D->getTypeSourceInfo())
673 return Visit(TSInfo->getTypeLoc());
674
675 return false;
676}
677
678bool CursorVisitor::VisitTypedefDecl(TypedefDecl *D) {
679 if (TypeSourceInfo *TSInfo = D->getTypeSourceInfo())
680 return Visit(TSInfo->getTypeLoc());
681
682 return false;
683}
684
685bool CursorVisitor::VisitTagDecl(TagDecl *D) {
686 return VisitDeclContext(D);
687}
688
689bool CursorVisitor::VisitClassTemplateSpecializationDecl(
690 ClassTemplateSpecializationDecl *D) {
691 bool ShouldVisitBody = false;
692 switch (D->getSpecializationKind()) {
693 case TSK_Undeclared:
694 case TSK_ImplicitInstantiation:
695 // Nothing to visit
696 return false;
697
698 case TSK_ExplicitInstantiationDeclaration:
699 case TSK_ExplicitInstantiationDefinition:
700 break;
701
702 case TSK_ExplicitSpecialization:
703 ShouldVisitBody = true;
704 break;
705 }
706
707 // Visit the template arguments used in the specialization.
708 if (TypeSourceInfo *SpecType = D->getTypeAsWritten()) {
709 TypeLoc TL = SpecType->getTypeLoc();
David Blaikie6adc78e2013-02-18 22:06:02 +0000710 if (TemplateSpecializationTypeLoc TSTLoc =
711 TL.getAs<TemplateSpecializationTypeLoc>()) {
712 for (unsigned I = 0, N = TSTLoc.getNumArgs(); I != N; ++I)
713 if (VisitTemplateArgumentLoc(TSTLoc.getArgLoc(I)))
Guy Benyei11169dd2012-12-18 14:30:41 +0000714 return true;
715 }
716 }
Alexander Kornienko1a9f1842015-12-28 15:24:08 +0000717
718 return ShouldVisitBody && VisitCXXRecordDecl(D);
Guy Benyei11169dd2012-12-18 14:30:41 +0000719}
720
721bool CursorVisitor::VisitClassTemplatePartialSpecializationDecl(
722 ClassTemplatePartialSpecializationDecl *D) {
723 // FIXME: Visit the "outer" template parameter lists on the TagDecl
724 // before visiting these template parameters.
725 if (VisitTemplateParameters(D->getTemplateParameters()))
726 return true;
727
728 // Visit the partial specialization arguments.
Enea Zaffanella6dbe1872013-08-10 07:24:53 +0000729 const ASTTemplateArgumentListInfo *Info = D->getTemplateArgsAsWritten();
730 const TemplateArgumentLoc *TemplateArgs = Info->getTemplateArgs();
731 for (unsigned I = 0, N = Info->NumTemplateArgs; I != N; ++I)
Guy Benyei11169dd2012-12-18 14:30:41 +0000732 if (VisitTemplateArgumentLoc(TemplateArgs[I]))
733 return true;
734
735 return VisitCXXRecordDecl(D);
736}
737
738bool CursorVisitor::VisitTemplateTypeParmDecl(TemplateTypeParmDecl *D) {
739 // Visit the default argument.
740 if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited())
741 if (TypeSourceInfo *DefArg = D->getDefaultArgumentInfo())
742 if (Visit(DefArg->getTypeLoc()))
743 return true;
744
745 return false;
746}
747
748bool CursorVisitor::VisitEnumConstantDecl(EnumConstantDecl *D) {
749 if (Expr *Init = D->getInitExpr())
750 return Visit(MakeCXCursor(Init, StmtParent, TU, RegionOfInterest));
751 return false;
752}
753
754bool CursorVisitor::VisitDeclaratorDecl(DeclaratorDecl *DD) {
Argyrios Kyrtzidis2ec76742013-04-05 21:04:10 +0000755 unsigned NumParamList = DD->getNumTemplateParameterLists();
756 for (unsigned i = 0; i < NumParamList; i++) {
757 TemplateParameterList* Params = DD->getTemplateParameterList(i);
758 if (VisitTemplateParameters(Params))
759 return true;
760 }
761
Guy Benyei11169dd2012-12-18 14:30:41 +0000762 if (TypeSourceInfo *TSInfo = DD->getTypeSourceInfo())
763 if (Visit(TSInfo->getTypeLoc()))
764 return true;
765
766 // Visit the nested-name-specifier, if present.
767 if (NestedNameSpecifierLoc QualifierLoc = DD->getQualifierLoc())
768 if (VisitNestedNameSpecifierLoc(QualifierLoc))
769 return true;
770
771 return false;
772}
773
Benjamin Kramer4cadf292014-03-07 21:51:58 +0000774/// \brief Compare two base or member initializers based on their source order.
775static int CompareCXXCtorInitializers(CXXCtorInitializer *const *X,
776 CXXCtorInitializer *const *Y) {
777 return (*X)->getSourceOrder() - (*Y)->getSourceOrder();
778}
779
Guy Benyei11169dd2012-12-18 14:30:41 +0000780bool CursorVisitor::VisitFunctionDecl(FunctionDecl *ND) {
Argyrios Kyrtzidis2ec76742013-04-05 21:04:10 +0000781 unsigned NumParamList = ND->getNumTemplateParameterLists();
782 for (unsigned i = 0; i < NumParamList; i++) {
783 TemplateParameterList* Params = ND->getTemplateParameterList(i);
784 if (VisitTemplateParameters(Params))
785 return true;
786 }
787
Guy Benyei11169dd2012-12-18 14:30:41 +0000788 if (TypeSourceInfo *TSInfo = ND->getTypeSourceInfo()) {
789 // Visit the function declaration's syntactic components in the order
790 // written. This requires a bit of work.
791 TypeLoc TL = TSInfo->getTypeLoc().IgnoreParens();
David Blaikie6adc78e2013-02-18 22:06:02 +0000792 FunctionTypeLoc FTL = TL.getAs<FunctionTypeLoc>();
Guy Benyei11169dd2012-12-18 14:30:41 +0000793
794 // If we have a function declared directly (without the use of a typedef),
795 // visit just the return type. Otherwise, just visit the function's type
796 // now.
Alp Toker42a16a62014-01-25 23:51:36 +0000797 if ((FTL && !isa<CXXConversionDecl>(ND) && Visit(FTL.getReturnLoc())) ||
Guy Benyei11169dd2012-12-18 14:30:41 +0000798 (!FTL && Visit(TL)))
799 return true;
800
801 // Visit the nested-name-specifier, if present.
802 if (NestedNameSpecifierLoc QualifierLoc = ND->getQualifierLoc())
803 if (VisitNestedNameSpecifierLoc(QualifierLoc))
804 return true;
805
806 // Visit the declaration name.
Argyrios Kyrtzidis4a4d2b42014-02-09 08:13:47 +0000807 if (!isa<CXXDestructorDecl>(ND))
808 if (VisitDeclarationNameInfo(ND->getNameInfo()))
809 return true;
Guy Benyei11169dd2012-12-18 14:30:41 +0000810
811 // FIXME: Visit explicitly-specified template arguments!
812
813 // Visit the function parameters, if we have a function type.
David Blaikie6adc78e2013-02-18 22:06:02 +0000814 if (FTL && VisitFunctionTypeLoc(FTL, true))
Guy Benyei11169dd2012-12-18 14:30:41 +0000815 return true;
816
Bill Wendling44426052012-12-20 19:22:21 +0000817 // FIXME: Attributes?
Guy Benyei11169dd2012-12-18 14:30:41 +0000818 }
819
820 if (ND->doesThisDeclarationHaveABody() && !ND->isLateTemplateParsed()) {
821 if (CXXConstructorDecl *Constructor = dyn_cast<CXXConstructorDecl>(ND)) {
822 // Find the initializers that were written in the source.
823 SmallVector<CXXCtorInitializer *, 4> WrittenInits;
Aaron Ballman0ad78302014-03-13 17:34:31 +0000824 for (auto *I : Constructor->inits()) {
825 if (!I->isWritten())
Guy Benyei11169dd2012-12-18 14:30:41 +0000826 continue;
827
Aaron Ballman0ad78302014-03-13 17:34:31 +0000828 WrittenInits.push_back(I);
Guy Benyei11169dd2012-12-18 14:30:41 +0000829 }
830
831 // Sort the initializers in source order
Benjamin Kramer4cadf292014-03-07 21:51:58 +0000832 llvm::array_pod_sort(WrittenInits.begin(), WrittenInits.end(),
833 &CompareCXXCtorInitializers);
834
Guy Benyei11169dd2012-12-18 14:30:41 +0000835 // Visit the initializers in source order
836 for (unsigned I = 0, N = WrittenInits.size(); I != N; ++I) {
837 CXXCtorInitializer *Init = WrittenInits[I];
838 if (Init->isAnyMemberInitializer()) {
839 if (Visit(MakeCursorMemberRef(Init->getAnyMember(),
840 Init->getMemberLocation(), TU)))
841 return true;
842 } else if (TypeSourceInfo *TInfo = Init->getTypeSourceInfo()) {
843 if (Visit(TInfo->getTypeLoc()))
844 return true;
845 }
846
847 // Visit the initializer value.
848 if (Expr *Initializer = Init->getInit())
849 if (Visit(MakeCXCursor(Initializer, ND, TU, RegionOfInterest)))
850 return true;
851 }
852 }
853
854 if (Visit(MakeCXCursor(ND->getBody(), StmtParent, TU, RegionOfInterest)))
855 return true;
856 }
857
858 return false;
859}
860
861bool CursorVisitor::VisitFieldDecl(FieldDecl *D) {
862 if (VisitDeclaratorDecl(D))
863 return true;
864
865 if (Expr *BitWidth = D->getBitWidth())
866 return Visit(MakeCXCursor(BitWidth, StmtParent, TU, RegionOfInterest));
867
868 return false;
869}
870
871bool CursorVisitor::VisitVarDecl(VarDecl *D) {
872 if (VisitDeclaratorDecl(D))
873 return true;
874
875 if (Expr *Init = D->getInit())
876 return Visit(MakeCXCursor(Init, StmtParent, TU, RegionOfInterest));
877
878 return false;
879}
880
881bool CursorVisitor::VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl *D) {
882 if (VisitDeclaratorDecl(D))
883 return true;
884
885 if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited())
886 if (Expr *DefArg = D->getDefaultArgument())
887 return Visit(MakeCXCursor(DefArg, StmtParent, TU, RegionOfInterest));
888
889 return false;
890}
891
892bool CursorVisitor::VisitFunctionTemplateDecl(FunctionTemplateDecl *D) {
893 // FIXME: Visit the "outer" template parameter lists on the FunctionDecl
894 // before visiting these template parameters.
895 if (VisitTemplateParameters(D->getTemplateParameters()))
896 return true;
897
898 return VisitFunctionDecl(D->getTemplatedDecl());
899}
900
901bool CursorVisitor::VisitClassTemplateDecl(ClassTemplateDecl *D) {
902 // FIXME: Visit the "outer" template parameter lists on the TagDecl
903 // before visiting these template parameters.
904 if (VisitTemplateParameters(D->getTemplateParameters()))
905 return true;
906
907 return VisitCXXRecordDecl(D->getTemplatedDecl());
908}
909
910bool CursorVisitor::VisitTemplateTemplateParmDecl(TemplateTemplateParmDecl *D) {
911 if (VisitTemplateParameters(D->getTemplateParameters()))
912 return true;
913
914 if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited() &&
915 VisitTemplateArgumentLoc(D->getDefaultArgument()))
916 return true;
917
918 return false;
919}
920
Douglas Gregor9bda6cf2015-07-07 03:58:14 +0000921bool CursorVisitor::VisitObjCTypeParamDecl(ObjCTypeParamDecl *D) {
922 // Visit the bound, if it's explicit.
923 if (D->hasExplicitBound()) {
924 if (auto TInfo = D->getTypeSourceInfo()) {
925 if (Visit(TInfo->getTypeLoc()))
926 return true;
927 }
928 }
929
930 return false;
931}
932
Guy Benyei11169dd2012-12-18 14:30:41 +0000933bool CursorVisitor::VisitObjCMethodDecl(ObjCMethodDecl *ND) {
Alp Toker314cc812014-01-25 16:55:45 +0000934 if (TypeSourceInfo *TSInfo = ND->getReturnTypeSourceInfo())
Guy Benyei11169dd2012-12-18 14:30:41 +0000935 if (Visit(TSInfo->getTypeLoc()))
936 return true;
937
Aaron Ballman43b68be2014-03-07 17:50:17 +0000938 for (const auto *P : ND->params()) {
939 if (Visit(MakeCXCursor(P, TU, RegionOfInterest)))
Guy Benyei11169dd2012-12-18 14:30:41 +0000940 return true;
941 }
942
Alexander Kornienko1a9f1842015-12-28 15:24:08 +0000943 return ND->isThisDeclarationADefinition() &&
944 Visit(MakeCXCursor(ND->getBody(), StmtParent, TU, RegionOfInterest));
Guy Benyei11169dd2012-12-18 14:30:41 +0000945}
946
947template <typename DeclIt>
948static void addRangedDeclsInContainer(DeclIt *DI_current, DeclIt DE_current,
949 SourceManager &SM, SourceLocation EndLoc,
950 SmallVectorImpl<Decl *> &Decls) {
951 DeclIt next = *DI_current;
952 while (++next != DE_current) {
953 Decl *D_next = *next;
954 if (!D_next)
955 break;
956 SourceLocation L = D_next->getLocStart();
957 if (!L.isValid())
958 break;
959 if (SM.isBeforeInTranslationUnit(L, EndLoc)) {
960 *DI_current = next;
961 Decls.push_back(D_next);
962 continue;
963 }
964 break;
965 }
966}
967
Guy Benyei11169dd2012-12-18 14:30:41 +0000968bool CursorVisitor::VisitObjCContainerDecl(ObjCContainerDecl *D) {
969 // FIXME: Eventually convert back to just 'VisitDeclContext()'. Essentially
970 // an @implementation can lexically contain Decls that are not properly
971 // nested in the AST. When we identify such cases, we need to retrofit
972 // this nesting here.
973 if (!DI_current && !FileDI_current)
974 return VisitDeclContext(D);
975
976 // Scan the Decls that immediately come after the container
977 // in the current DeclContext. If any fall within the
978 // container's lexical region, stash them into a vector
979 // for later processing.
980 SmallVector<Decl *, 24> DeclsInContainer;
981 SourceLocation EndLoc = D->getSourceRange().getEnd();
982 SourceManager &SM = AU->getSourceManager();
983 if (EndLoc.isValid()) {
984 if (DI_current) {
985 addRangedDeclsInContainer(DI_current, DE_current, SM, EndLoc,
986 DeclsInContainer);
987 } else {
988 addRangedDeclsInContainer(FileDI_current, FileDE_current, SM, EndLoc,
989 DeclsInContainer);
990 }
991 }
992
993 // The common case.
994 if (DeclsInContainer.empty())
995 return VisitDeclContext(D);
996
997 // Get all the Decls in the DeclContext, and sort them with the
998 // additional ones we've collected. Then visit them.
Aaron Ballman629afae2014-03-07 19:56:05 +0000999 for (auto *SubDecl : D->decls()) {
1000 if (!SubDecl || SubDecl->getLexicalDeclContext() != D ||
1001 SubDecl->getLocStart().isInvalid())
Guy Benyei11169dd2012-12-18 14:30:41 +00001002 continue;
Aaron Ballman629afae2014-03-07 19:56:05 +00001003 DeclsInContainer.push_back(SubDecl);
Guy Benyei11169dd2012-12-18 14:30:41 +00001004 }
1005
1006 // Now sort the Decls so that they appear in lexical order.
1007 std::sort(DeclsInContainer.begin(), DeclsInContainer.end(),
Benjamin Kramerbbdd7642014-03-01 14:48:57 +00001008 [&SM](Decl *A, Decl *B) {
1009 SourceLocation L_A = A->getLocStart();
1010 SourceLocation L_B = B->getLocStart();
1011 assert(L_A.isValid() && L_B.isValid());
1012 return SM.isBeforeInTranslationUnit(L_A, L_B);
1013 });
Guy Benyei11169dd2012-12-18 14:30:41 +00001014
1015 // Now visit the decls.
1016 for (SmallVectorImpl<Decl*>::iterator I = DeclsInContainer.begin(),
1017 E = DeclsInContainer.end(); I != E; ++I) {
1018 CXCursor Cursor = MakeCXCursor(*I, TU, RegionOfInterest);
Ted Kremenek03325582013-02-21 01:29:01 +00001019 const Optional<bool> &V = shouldVisitCursor(Cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00001020 if (!V.hasValue())
1021 continue;
1022 if (!V.getValue())
1023 return false;
1024 if (Visit(Cursor, true))
1025 return true;
1026 }
1027 return false;
1028}
1029
1030bool CursorVisitor::VisitObjCCategoryDecl(ObjCCategoryDecl *ND) {
1031 if (Visit(MakeCursorObjCClassRef(ND->getClassInterface(), ND->getLocation(),
1032 TU)))
1033 return true;
1034
Douglas Gregore9d95f12015-07-07 03:57:35 +00001035 if (VisitObjCTypeParamList(ND->getTypeParamList()))
1036 return true;
1037
Guy Benyei11169dd2012-12-18 14:30:41 +00001038 ObjCCategoryDecl::protocol_loc_iterator PL = ND->protocol_loc_begin();
1039 for (ObjCCategoryDecl::protocol_iterator I = ND->protocol_begin(),
1040 E = ND->protocol_end(); I != E; ++I, ++PL)
1041 if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
1042 return true;
1043
1044 return VisitObjCContainerDecl(ND);
1045}
1046
1047bool CursorVisitor::VisitObjCProtocolDecl(ObjCProtocolDecl *PID) {
1048 if (!PID->isThisDeclarationADefinition())
1049 return Visit(MakeCursorObjCProtocolRef(PID, PID->getLocation(), TU));
1050
1051 ObjCProtocolDecl::protocol_loc_iterator PL = PID->protocol_loc_begin();
1052 for (ObjCProtocolDecl::protocol_iterator I = PID->protocol_begin(),
1053 E = PID->protocol_end(); I != E; ++I, ++PL)
1054 if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
1055 return true;
1056
1057 return VisitObjCContainerDecl(PID);
1058}
1059
1060bool CursorVisitor::VisitObjCPropertyDecl(ObjCPropertyDecl *PD) {
1061 if (PD->getTypeSourceInfo() && Visit(PD->getTypeSourceInfo()->getTypeLoc()))
1062 return true;
1063
1064 // FIXME: This implements a workaround with @property declarations also being
1065 // installed in the DeclContext for the @interface. Eventually this code
1066 // should be removed.
1067 ObjCCategoryDecl *CDecl = dyn_cast<ObjCCategoryDecl>(PD->getDeclContext());
1068 if (!CDecl || !CDecl->IsClassExtension())
1069 return false;
1070
1071 ObjCInterfaceDecl *ID = CDecl->getClassInterface();
1072 if (!ID)
1073 return false;
1074
1075 IdentifierInfo *PropertyId = PD->getIdentifier();
1076 ObjCPropertyDecl *prevDecl =
Manman Ren5b786402016-01-28 18:49:28 +00001077 ObjCPropertyDecl::findPropertyDecl(cast<DeclContext>(ID), PropertyId,
1078 PD->getQueryKind());
Guy Benyei11169dd2012-12-18 14:30:41 +00001079
1080 if (!prevDecl)
1081 return false;
1082
1083 // Visit synthesized methods since they will be skipped when visiting
1084 // the @interface.
1085 if (ObjCMethodDecl *MD = prevDecl->getGetterMethodDecl())
1086 if (MD->isPropertyAccessor() && MD->getLexicalDeclContext() == CDecl)
1087 if (Visit(MakeCXCursor(MD, TU, RegionOfInterest)))
1088 return true;
1089
1090 if (ObjCMethodDecl *MD = prevDecl->getSetterMethodDecl())
1091 if (MD->isPropertyAccessor() && MD->getLexicalDeclContext() == CDecl)
1092 if (Visit(MakeCXCursor(MD, TU, RegionOfInterest)))
1093 return true;
1094
1095 return false;
1096}
1097
Douglas Gregore9d95f12015-07-07 03:57:35 +00001098bool CursorVisitor::VisitObjCTypeParamList(ObjCTypeParamList *typeParamList) {
1099 if (!typeParamList)
1100 return false;
1101
1102 for (auto *typeParam : *typeParamList) {
1103 // Visit the type parameter.
1104 if (Visit(MakeCXCursor(typeParam, TU, RegionOfInterest)))
1105 return true;
Douglas Gregore9d95f12015-07-07 03:57:35 +00001106 }
1107
1108 return false;
1109}
1110
Guy Benyei11169dd2012-12-18 14:30:41 +00001111bool CursorVisitor::VisitObjCInterfaceDecl(ObjCInterfaceDecl *D) {
1112 if (!D->isThisDeclarationADefinition()) {
1113 // Forward declaration is treated like a reference.
1114 return Visit(MakeCursorObjCClassRef(D, D->getLocation(), TU));
1115 }
1116
Douglas Gregore9d95f12015-07-07 03:57:35 +00001117 // Objective-C type parameters.
1118 if (VisitObjCTypeParamList(D->getTypeParamListAsWritten()))
1119 return true;
1120
Guy Benyei11169dd2012-12-18 14:30:41 +00001121 // Issue callbacks for super class.
1122 if (D->getSuperClass() &&
1123 Visit(MakeCursorObjCSuperClassRef(D->getSuperClass(),
1124 D->getSuperClassLoc(),
1125 TU)))
1126 return true;
1127
Douglas Gregore9d95f12015-07-07 03:57:35 +00001128 if (TypeSourceInfo *SuperClassTInfo = D->getSuperClassTInfo())
1129 if (Visit(SuperClassTInfo->getTypeLoc()))
1130 return true;
1131
Guy Benyei11169dd2012-12-18 14:30:41 +00001132 ObjCInterfaceDecl::protocol_loc_iterator PL = D->protocol_loc_begin();
1133 for (ObjCInterfaceDecl::protocol_iterator I = D->protocol_begin(),
1134 E = D->protocol_end(); I != E; ++I, ++PL)
1135 if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
1136 return true;
1137
1138 return VisitObjCContainerDecl(D);
1139}
1140
1141bool CursorVisitor::VisitObjCImplDecl(ObjCImplDecl *D) {
1142 return VisitObjCContainerDecl(D);
1143}
1144
1145bool CursorVisitor::VisitObjCCategoryImplDecl(ObjCCategoryImplDecl *D) {
1146 // 'ID' could be null when dealing with invalid code.
1147 if (ObjCInterfaceDecl *ID = D->getClassInterface())
1148 if (Visit(MakeCursorObjCClassRef(ID, D->getLocation(), TU)))
1149 return true;
1150
1151 return VisitObjCImplDecl(D);
1152}
1153
1154bool CursorVisitor::VisitObjCImplementationDecl(ObjCImplementationDecl *D) {
1155#if 0
1156 // Issue callbacks for super class.
1157 // FIXME: No source location information!
1158 if (D->getSuperClass() &&
1159 Visit(MakeCursorObjCSuperClassRef(D->getSuperClass(),
1160 D->getSuperClassLoc(),
1161 TU)))
1162 return true;
1163#endif
1164
1165 return VisitObjCImplDecl(D);
1166}
1167
1168bool CursorVisitor::VisitObjCPropertyImplDecl(ObjCPropertyImplDecl *PD) {
1169 if (ObjCIvarDecl *Ivar = PD->getPropertyIvarDecl())
1170 if (PD->isIvarNameSpecified())
1171 return Visit(MakeCursorMemberRef(Ivar, PD->getPropertyIvarDeclLoc(), TU));
1172
1173 return false;
1174}
1175
1176bool CursorVisitor::VisitNamespaceDecl(NamespaceDecl *D) {
1177 return VisitDeclContext(D);
1178}
1179
1180bool CursorVisitor::VisitNamespaceAliasDecl(NamespaceAliasDecl *D) {
1181 // Visit nested-name-specifier.
1182 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1183 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1184 return true;
1185
1186 return Visit(MakeCursorNamespaceRef(D->getAliasedNamespace(),
1187 D->getTargetNameLoc(), TU));
1188}
1189
1190bool CursorVisitor::VisitUsingDecl(UsingDecl *D) {
1191 // Visit nested-name-specifier.
1192 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc()) {
1193 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1194 return true;
1195 }
1196
1197 if (Visit(MakeCursorOverloadedDeclRef(D, D->getLocation(), TU)))
1198 return true;
1199
1200 return VisitDeclarationNameInfo(D->getNameInfo());
1201}
1202
1203bool CursorVisitor::VisitUsingDirectiveDecl(UsingDirectiveDecl *D) {
1204 // Visit nested-name-specifier.
1205 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1206 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1207 return true;
1208
1209 return Visit(MakeCursorNamespaceRef(D->getNominatedNamespaceAsWritten(),
1210 D->getIdentLocation(), TU));
1211}
1212
1213bool CursorVisitor::VisitUnresolvedUsingValueDecl(UnresolvedUsingValueDecl *D) {
1214 // Visit nested-name-specifier.
1215 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc()) {
1216 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1217 return true;
1218 }
1219
1220 return VisitDeclarationNameInfo(D->getNameInfo());
1221}
1222
1223bool CursorVisitor::VisitUnresolvedUsingTypenameDecl(
1224 UnresolvedUsingTypenameDecl *D) {
1225 // Visit nested-name-specifier.
1226 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1227 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1228 return true;
1229
1230 return false;
1231}
1232
1233bool CursorVisitor::VisitDeclarationNameInfo(DeclarationNameInfo Name) {
1234 switch (Name.getName().getNameKind()) {
1235 case clang::DeclarationName::Identifier:
1236 case clang::DeclarationName::CXXLiteralOperatorName:
1237 case clang::DeclarationName::CXXOperatorName:
1238 case clang::DeclarationName::CXXUsingDirective:
1239 return false;
1240
1241 case clang::DeclarationName::CXXConstructorName:
1242 case clang::DeclarationName::CXXDestructorName:
1243 case clang::DeclarationName::CXXConversionFunctionName:
1244 if (TypeSourceInfo *TSInfo = Name.getNamedTypeInfo())
1245 return Visit(TSInfo->getTypeLoc());
1246 return false;
1247
1248 case clang::DeclarationName::ObjCZeroArgSelector:
1249 case clang::DeclarationName::ObjCOneArgSelector:
1250 case clang::DeclarationName::ObjCMultiArgSelector:
1251 // FIXME: Per-identifier location info?
1252 return false;
1253 }
1254
1255 llvm_unreachable("Invalid DeclarationName::Kind!");
1256}
1257
1258bool CursorVisitor::VisitNestedNameSpecifier(NestedNameSpecifier *NNS,
1259 SourceRange Range) {
1260 // FIXME: This whole routine is a hack to work around the lack of proper
1261 // source information in nested-name-specifiers (PR5791). Since we do have
1262 // a beginning source location, we can visit the first component of the
1263 // nested-name-specifier, if it's a single-token component.
1264 if (!NNS)
1265 return false;
1266
1267 // Get the first component in the nested-name-specifier.
1268 while (NestedNameSpecifier *Prefix = NNS->getPrefix())
1269 NNS = Prefix;
1270
1271 switch (NNS->getKind()) {
1272 case NestedNameSpecifier::Namespace:
1273 return Visit(MakeCursorNamespaceRef(NNS->getAsNamespace(), Range.getBegin(),
1274 TU));
1275
1276 case NestedNameSpecifier::NamespaceAlias:
1277 return Visit(MakeCursorNamespaceRef(NNS->getAsNamespaceAlias(),
1278 Range.getBegin(), TU));
1279
1280 case NestedNameSpecifier::TypeSpec: {
1281 // If the type has a form where we know that the beginning of the source
1282 // range matches up with a reference cursor. Visit the appropriate reference
1283 // cursor.
1284 const Type *T = NNS->getAsType();
1285 if (const TypedefType *Typedef = dyn_cast<TypedefType>(T))
1286 return Visit(MakeCursorTypeRef(Typedef->getDecl(), Range.getBegin(), TU));
1287 if (const TagType *Tag = dyn_cast<TagType>(T))
1288 return Visit(MakeCursorTypeRef(Tag->getDecl(), Range.getBegin(), TU));
1289 if (const TemplateSpecializationType *TST
1290 = dyn_cast<TemplateSpecializationType>(T))
1291 return VisitTemplateName(TST->getTemplateName(), Range.getBegin());
1292 break;
1293 }
1294
1295 case NestedNameSpecifier::TypeSpecWithTemplate:
1296 case NestedNameSpecifier::Global:
1297 case NestedNameSpecifier::Identifier:
Nikola Smiljanic67860242014-09-26 00:28:20 +00001298 case NestedNameSpecifier::Super:
Guy Benyei11169dd2012-12-18 14:30:41 +00001299 break;
1300 }
1301
1302 return false;
1303}
1304
1305bool
1306CursorVisitor::VisitNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier) {
1307 SmallVector<NestedNameSpecifierLoc, 4> Qualifiers;
1308 for (; Qualifier; Qualifier = Qualifier.getPrefix())
1309 Qualifiers.push_back(Qualifier);
1310
1311 while (!Qualifiers.empty()) {
1312 NestedNameSpecifierLoc Q = Qualifiers.pop_back_val();
1313 NestedNameSpecifier *NNS = Q.getNestedNameSpecifier();
1314 switch (NNS->getKind()) {
1315 case NestedNameSpecifier::Namespace:
1316 if (Visit(MakeCursorNamespaceRef(NNS->getAsNamespace(),
1317 Q.getLocalBeginLoc(),
1318 TU)))
1319 return true;
1320
1321 break;
1322
1323 case NestedNameSpecifier::NamespaceAlias:
1324 if (Visit(MakeCursorNamespaceRef(NNS->getAsNamespaceAlias(),
1325 Q.getLocalBeginLoc(),
1326 TU)))
1327 return true;
1328
1329 break;
1330
1331 case NestedNameSpecifier::TypeSpec:
1332 case NestedNameSpecifier::TypeSpecWithTemplate:
1333 if (Visit(Q.getTypeLoc()))
1334 return true;
1335
1336 break;
1337
1338 case NestedNameSpecifier::Global:
1339 case NestedNameSpecifier::Identifier:
Nikola Smiljanic67860242014-09-26 00:28:20 +00001340 case NestedNameSpecifier::Super:
Guy Benyei11169dd2012-12-18 14:30:41 +00001341 break;
1342 }
1343 }
1344
1345 return false;
1346}
1347
1348bool CursorVisitor::VisitTemplateParameters(
1349 const TemplateParameterList *Params) {
1350 if (!Params)
1351 return false;
1352
1353 for (TemplateParameterList::const_iterator P = Params->begin(),
1354 PEnd = Params->end();
1355 P != PEnd; ++P) {
1356 if (Visit(MakeCXCursor(*P, TU, RegionOfInterest)))
1357 return true;
1358 }
1359
1360 return false;
1361}
1362
1363bool CursorVisitor::VisitTemplateName(TemplateName Name, SourceLocation Loc) {
1364 switch (Name.getKind()) {
1365 case TemplateName::Template:
1366 return Visit(MakeCursorTemplateRef(Name.getAsTemplateDecl(), Loc, TU));
1367
1368 case TemplateName::OverloadedTemplate:
1369 // Visit the overloaded template set.
1370 if (Visit(MakeCursorOverloadedDeclRef(Name, Loc, TU)))
1371 return true;
1372
1373 return false;
1374
1375 case TemplateName::DependentTemplate:
1376 // FIXME: Visit nested-name-specifier.
1377 return false;
1378
1379 case TemplateName::QualifiedTemplate:
1380 // FIXME: Visit nested-name-specifier.
1381 return Visit(MakeCursorTemplateRef(
1382 Name.getAsQualifiedTemplateName()->getDecl(),
1383 Loc, TU));
1384
1385 case TemplateName::SubstTemplateTemplateParm:
1386 return Visit(MakeCursorTemplateRef(
1387 Name.getAsSubstTemplateTemplateParm()->getParameter(),
1388 Loc, TU));
1389
1390 case TemplateName::SubstTemplateTemplateParmPack:
1391 return Visit(MakeCursorTemplateRef(
1392 Name.getAsSubstTemplateTemplateParmPack()->getParameterPack(),
1393 Loc, TU));
1394 }
1395
1396 llvm_unreachable("Invalid TemplateName::Kind!");
1397}
1398
1399bool CursorVisitor::VisitTemplateArgumentLoc(const TemplateArgumentLoc &TAL) {
1400 switch (TAL.getArgument().getKind()) {
1401 case TemplateArgument::Null:
1402 case TemplateArgument::Integral:
1403 case TemplateArgument::Pack:
1404 return false;
1405
1406 case TemplateArgument::Type:
1407 if (TypeSourceInfo *TSInfo = TAL.getTypeSourceInfo())
1408 return Visit(TSInfo->getTypeLoc());
1409 return false;
1410
1411 case TemplateArgument::Declaration:
1412 if (Expr *E = TAL.getSourceDeclExpression())
1413 return Visit(MakeCXCursor(E, StmtParent, TU, RegionOfInterest));
1414 return false;
1415
1416 case TemplateArgument::NullPtr:
1417 if (Expr *E = TAL.getSourceNullPtrExpression())
1418 return Visit(MakeCXCursor(E, StmtParent, TU, RegionOfInterest));
1419 return false;
1420
1421 case TemplateArgument::Expression:
1422 if (Expr *E = TAL.getSourceExpression())
1423 return Visit(MakeCXCursor(E, StmtParent, TU, RegionOfInterest));
1424 return false;
1425
1426 case TemplateArgument::Template:
1427 case TemplateArgument::TemplateExpansion:
1428 if (VisitNestedNameSpecifierLoc(TAL.getTemplateQualifierLoc()))
1429 return true;
1430
1431 return VisitTemplateName(TAL.getArgument().getAsTemplateOrTemplatePattern(),
1432 TAL.getTemplateNameLoc());
1433 }
1434
1435 llvm_unreachable("Invalid TemplateArgument::Kind!");
1436}
1437
1438bool CursorVisitor::VisitLinkageSpecDecl(LinkageSpecDecl *D) {
1439 return VisitDeclContext(D);
1440}
1441
1442bool CursorVisitor::VisitQualifiedTypeLoc(QualifiedTypeLoc TL) {
1443 return Visit(TL.getUnqualifiedLoc());
1444}
1445
1446bool CursorVisitor::VisitBuiltinTypeLoc(BuiltinTypeLoc TL) {
1447 ASTContext &Context = AU->getASTContext();
1448
1449 // Some builtin types (such as Objective-C's "id", "sel", and
1450 // "Class") have associated declarations. Create cursors for those.
1451 QualType VisitType;
1452 switch (TL.getTypePtr()->getKind()) {
1453
1454 case BuiltinType::Void:
1455 case BuiltinType::NullPtr:
1456 case BuiltinType::Dependent:
Guy Benyeid8a08ea2012-12-18 14:38:23 +00001457 case BuiltinType::OCLImage1d:
1458 case BuiltinType::OCLImage1dArray:
1459 case BuiltinType::OCLImage1dBuffer:
1460 case BuiltinType::OCLImage2d:
1461 case BuiltinType::OCLImage2dArray:
Alexey Bader9c8453f2015-09-15 11:18:52 +00001462 case BuiltinType::OCLImage2dDepth:
1463 case BuiltinType::OCLImage2dArrayDepth:
1464 case BuiltinType::OCLImage2dMSAA:
1465 case BuiltinType::OCLImage2dArrayMSAA:
1466 case BuiltinType::OCLImage2dMSAADepth:
1467 case BuiltinType::OCLImage2dArrayMSAADepth:
Guy Benyeid8a08ea2012-12-18 14:38:23 +00001468 case BuiltinType::OCLImage3d:
NAKAMURA Takumi288c42e2013-02-07 12:47:42 +00001469 case BuiltinType::OCLSampler:
Guy Benyei1b4fb3e2013-01-20 12:31:11 +00001470 case BuiltinType::OCLEvent:
Alexey Bader9c8453f2015-09-15 11:18:52 +00001471 case BuiltinType::OCLClkEvent:
1472 case BuiltinType::OCLQueue:
1473 case BuiltinType::OCLNDRange:
1474 case BuiltinType::OCLReserveID:
Guy Benyei11169dd2012-12-18 14:30:41 +00001475#define BUILTIN_TYPE(Id, SingletonId)
1476#define SIGNED_TYPE(Id, SingletonId) case BuiltinType::Id:
1477#define UNSIGNED_TYPE(Id, SingletonId) case BuiltinType::Id:
1478#define FLOATING_TYPE(Id, SingletonId) case BuiltinType::Id:
1479#define PLACEHOLDER_TYPE(Id, SingletonId) case BuiltinType::Id:
1480#include "clang/AST/BuiltinTypes.def"
1481 break;
1482
1483 case BuiltinType::ObjCId:
1484 VisitType = Context.getObjCIdType();
1485 break;
1486
1487 case BuiltinType::ObjCClass:
1488 VisitType = Context.getObjCClassType();
1489 break;
1490
1491 case BuiltinType::ObjCSel:
1492 VisitType = Context.getObjCSelType();
1493 break;
1494 }
1495
1496 if (!VisitType.isNull()) {
1497 if (const TypedefType *Typedef = VisitType->getAs<TypedefType>())
1498 return Visit(MakeCursorTypeRef(Typedef->getDecl(), TL.getBuiltinLoc(),
1499 TU));
1500 }
1501
1502 return false;
1503}
1504
1505bool CursorVisitor::VisitTypedefTypeLoc(TypedefTypeLoc TL) {
1506 return Visit(MakeCursorTypeRef(TL.getTypedefNameDecl(), TL.getNameLoc(), TU));
1507}
1508
1509bool CursorVisitor::VisitUnresolvedUsingTypeLoc(UnresolvedUsingTypeLoc TL) {
1510 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1511}
1512
1513bool CursorVisitor::VisitTagTypeLoc(TagTypeLoc TL) {
1514 if (TL.isDefinition())
1515 return Visit(MakeCXCursor(TL.getDecl(), TU, RegionOfInterest));
1516
1517 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1518}
1519
1520bool CursorVisitor::VisitTemplateTypeParmTypeLoc(TemplateTypeParmTypeLoc TL) {
1521 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1522}
1523
1524bool CursorVisitor::VisitObjCInterfaceTypeLoc(ObjCInterfaceTypeLoc TL) {
Hans Wennborg59dbe862015-09-29 20:56:43 +00001525 return Visit(MakeCursorObjCClassRef(TL.getIFaceDecl(), TL.getNameLoc(), TU));
Guy Benyei11169dd2012-12-18 14:30:41 +00001526}
1527
1528bool CursorVisitor::VisitObjCObjectTypeLoc(ObjCObjectTypeLoc TL) {
1529 if (TL.hasBaseTypeAsWritten() && Visit(TL.getBaseLoc()))
1530 return true;
1531
Douglas Gregore9d95f12015-07-07 03:57:35 +00001532 for (unsigned I = 0, N = TL.getNumTypeArgs(); I != N; ++I) {
1533 if (Visit(TL.getTypeArgTInfo(I)->getTypeLoc()))
1534 return true;
1535 }
1536
Guy Benyei11169dd2012-12-18 14:30:41 +00001537 for (unsigned I = 0, N = TL.getNumProtocols(); I != N; ++I) {
1538 if (Visit(MakeCursorObjCProtocolRef(TL.getProtocol(I), TL.getProtocolLoc(I),
1539 TU)))
1540 return true;
1541 }
1542
1543 return false;
1544}
1545
1546bool CursorVisitor::VisitObjCObjectPointerTypeLoc(ObjCObjectPointerTypeLoc TL) {
1547 return Visit(TL.getPointeeLoc());
1548}
1549
1550bool CursorVisitor::VisitParenTypeLoc(ParenTypeLoc TL) {
1551 return Visit(TL.getInnerLoc());
1552}
1553
1554bool CursorVisitor::VisitPointerTypeLoc(PointerTypeLoc TL) {
1555 return Visit(TL.getPointeeLoc());
1556}
1557
1558bool CursorVisitor::VisitBlockPointerTypeLoc(BlockPointerTypeLoc TL) {
1559 return Visit(TL.getPointeeLoc());
1560}
1561
1562bool CursorVisitor::VisitMemberPointerTypeLoc(MemberPointerTypeLoc TL) {
1563 return Visit(TL.getPointeeLoc());
1564}
1565
1566bool CursorVisitor::VisitLValueReferenceTypeLoc(LValueReferenceTypeLoc TL) {
1567 return Visit(TL.getPointeeLoc());
1568}
1569
1570bool CursorVisitor::VisitRValueReferenceTypeLoc(RValueReferenceTypeLoc TL) {
1571 return Visit(TL.getPointeeLoc());
1572}
1573
1574bool CursorVisitor::VisitAttributedTypeLoc(AttributedTypeLoc TL) {
1575 return Visit(TL.getModifiedLoc());
1576}
1577
1578bool CursorVisitor::VisitFunctionTypeLoc(FunctionTypeLoc TL,
1579 bool SkipResultType) {
Alp Toker42a16a62014-01-25 23:51:36 +00001580 if (!SkipResultType && Visit(TL.getReturnLoc()))
Guy Benyei11169dd2012-12-18 14:30:41 +00001581 return true;
1582
Alp Tokerb3fd5cf2014-01-21 00:32:38 +00001583 for (unsigned I = 0, N = TL.getNumParams(); I != N; ++I)
1584 if (Decl *D = TL.getParam(I))
Guy Benyei11169dd2012-12-18 14:30:41 +00001585 if (Visit(MakeCXCursor(D, TU, RegionOfInterest)))
1586 return true;
1587
1588 return false;
1589}
1590
1591bool CursorVisitor::VisitArrayTypeLoc(ArrayTypeLoc TL) {
1592 if (Visit(TL.getElementLoc()))
1593 return true;
1594
1595 if (Expr *Size = TL.getSizeExpr())
1596 return Visit(MakeCXCursor(Size, StmtParent, TU, RegionOfInterest));
1597
1598 return false;
1599}
1600
Reid Kleckner8a365022013-06-24 17:51:48 +00001601bool CursorVisitor::VisitDecayedTypeLoc(DecayedTypeLoc TL) {
1602 return Visit(TL.getOriginalLoc());
1603}
1604
Reid Kleckner0503a872013-12-05 01:23:43 +00001605bool CursorVisitor::VisitAdjustedTypeLoc(AdjustedTypeLoc TL) {
1606 return Visit(TL.getOriginalLoc());
1607}
1608
Guy Benyei11169dd2012-12-18 14:30:41 +00001609bool CursorVisitor::VisitTemplateSpecializationTypeLoc(
1610 TemplateSpecializationTypeLoc TL) {
1611 // Visit the template name.
1612 if (VisitTemplateName(TL.getTypePtr()->getTemplateName(),
1613 TL.getTemplateNameLoc()))
1614 return true;
1615
1616 // Visit the template arguments.
1617 for (unsigned I = 0, N = TL.getNumArgs(); I != N; ++I)
1618 if (VisitTemplateArgumentLoc(TL.getArgLoc(I)))
1619 return true;
1620
1621 return false;
1622}
1623
1624bool CursorVisitor::VisitTypeOfExprTypeLoc(TypeOfExprTypeLoc TL) {
1625 return Visit(MakeCXCursor(TL.getUnderlyingExpr(), StmtParent, TU));
1626}
1627
1628bool CursorVisitor::VisitTypeOfTypeLoc(TypeOfTypeLoc TL) {
1629 if (TypeSourceInfo *TSInfo = TL.getUnderlyingTInfo())
1630 return Visit(TSInfo->getTypeLoc());
1631
1632 return false;
1633}
1634
1635bool CursorVisitor::VisitUnaryTransformTypeLoc(UnaryTransformTypeLoc TL) {
1636 if (TypeSourceInfo *TSInfo = TL.getUnderlyingTInfo())
1637 return Visit(TSInfo->getTypeLoc());
1638
1639 return false;
1640}
1641
1642bool CursorVisitor::VisitDependentNameTypeLoc(DependentNameTypeLoc TL) {
Hans Wennborg59dbe862015-09-29 20:56:43 +00001643 return VisitNestedNameSpecifierLoc(TL.getQualifierLoc());
Guy Benyei11169dd2012-12-18 14:30:41 +00001644}
1645
1646bool CursorVisitor::VisitDependentTemplateSpecializationTypeLoc(
1647 DependentTemplateSpecializationTypeLoc TL) {
1648 // Visit the nested-name-specifier, if there is one.
1649 if (TL.getQualifierLoc() &&
1650 VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
1651 return true;
1652
1653 // Visit the template arguments.
1654 for (unsigned I = 0, N = TL.getNumArgs(); I != N; ++I)
1655 if (VisitTemplateArgumentLoc(TL.getArgLoc(I)))
1656 return true;
1657
1658 return false;
1659}
1660
1661bool CursorVisitor::VisitElaboratedTypeLoc(ElaboratedTypeLoc TL) {
1662 if (VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
1663 return true;
1664
1665 return Visit(TL.getNamedTypeLoc());
1666}
1667
1668bool CursorVisitor::VisitPackExpansionTypeLoc(PackExpansionTypeLoc TL) {
1669 return Visit(TL.getPatternLoc());
1670}
1671
1672bool CursorVisitor::VisitDecltypeTypeLoc(DecltypeTypeLoc TL) {
1673 if (Expr *E = TL.getUnderlyingExpr())
1674 return Visit(MakeCXCursor(E, StmtParent, TU));
1675
1676 return false;
1677}
1678
1679bool CursorVisitor::VisitInjectedClassNameTypeLoc(InjectedClassNameTypeLoc TL) {
1680 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1681}
1682
1683bool CursorVisitor::VisitAtomicTypeLoc(AtomicTypeLoc TL) {
1684 return Visit(TL.getValueLoc());
1685}
1686
Xiuli Pan9c14e282016-01-09 12:53:17 +00001687bool CursorVisitor::VisitPipeTypeLoc(PipeTypeLoc TL) {
1688 return Visit(TL.getValueLoc());
1689}
1690
Guy Benyei11169dd2012-12-18 14:30:41 +00001691#define DEFAULT_TYPELOC_IMPL(CLASS, PARENT) \
1692bool CursorVisitor::Visit##CLASS##TypeLoc(CLASS##TypeLoc TL) { \
1693 return Visit##PARENT##Loc(TL); \
1694}
1695
1696DEFAULT_TYPELOC_IMPL(Complex, Type)
1697DEFAULT_TYPELOC_IMPL(ConstantArray, ArrayType)
1698DEFAULT_TYPELOC_IMPL(IncompleteArray, ArrayType)
1699DEFAULT_TYPELOC_IMPL(VariableArray, ArrayType)
1700DEFAULT_TYPELOC_IMPL(DependentSizedArray, ArrayType)
1701DEFAULT_TYPELOC_IMPL(DependentSizedExtVector, Type)
1702DEFAULT_TYPELOC_IMPL(Vector, Type)
1703DEFAULT_TYPELOC_IMPL(ExtVector, VectorType)
1704DEFAULT_TYPELOC_IMPL(FunctionProto, FunctionType)
1705DEFAULT_TYPELOC_IMPL(FunctionNoProto, FunctionType)
1706DEFAULT_TYPELOC_IMPL(Record, TagType)
1707DEFAULT_TYPELOC_IMPL(Enum, TagType)
1708DEFAULT_TYPELOC_IMPL(SubstTemplateTypeParm, Type)
1709DEFAULT_TYPELOC_IMPL(SubstTemplateTypeParmPack, Type)
1710DEFAULT_TYPELOC_IMPL(Auto, Type)
1711
1712bool CursorVisitor::VisitCXXRecordDecl(CXXRecordDecl *D) {
1713 // Visit the nested-name-specifier, if present.
1714 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1715 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1716 return true;
1717
1718 if (D->isCompleteDefinition()) {
Aaron Ballman574705e2014-03-13 15:41:46 +00001719 for (const auto &I : D->bases()) {
1720 if (Visit(cxcursor::MakeCursorCXXBaseSpecifier(&I, TU)))
Guy Benyei11169dd2012-12-18 14:30:41 +00001721 return true;
1722 }
1723 }
1724
1725 return VisitTagDecl(D);
1726}
1727
1728bool CursorVisitor::VisitAttributes(Decl *D) {
Aaron Ballmanb97112e2014-03-08 22:19:01 +00001729 for (const auto *I : D->attrs())
1730 if (Visit(MakeCXCursor(I, D, TU)))
Guy Benyei11169dd2012-12-18 14:30:41 +00001731 return true;
1732
1733 return false;
1734}
1735
1736//===----------------------------------------------------------------------===//
1737// Data-recursive visitor methods.
1738//===----------------------------------------------------------------------===//
1739
1740namespace {
1741#define DEF_JOB(NAME, DATA, KIND)\
1742class NAME : public VisitorJob {\
1743public:\
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001744 NAME(const DATA *d, CXCursor parent) : \
1745 VisitorJob(parent, VisitorJob::KIND, d) {} \
Guy Benyei11169dd2012-12-18 14:30:41 +00001746 static bool classof(const VisitorJob *VJ) { return VJ->getKind() == KIND; }\
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001747 const DATA *get() const { return static_cast<const DATA*>(data[0]); }\
Guy Benyei11169dd2012-12-18 14:30:41 +00001748};
1749
1750DEF_JOB(StmtVisit, Stmt, StmtVisitKind)
1751DEF_JOB(MemberExprParts, MemberExpr, MemberExprPartsKind)
1752DEF_JOB(DeclRefExprParts, DeclRefExpr, DeclRefExprPartsKind)
1753DEF_JOB(OverloadExprParts, OverloadExpr, OverloadExprPartsKind)
Guy Benyei11169dd2012-12-18 14:30:41 +00001754DEF_JOB(SizeOfPackExprParts, SizeOfPackExpr, SizeOfPackExprPartsKind)
1755DEF_JOB(LambdaExprParts, LambdaExpr, LambdaExprPartsKind)
1756DEF_JOB(PostChildrenVisit, void, PostChildrenVisitKind)
1757#undef DEF_JOB
1758
James Y Knight04ec5bf2015-12-24 02:59:37 +00001759class ExplicitTemplateArgsVisit : public VisitorJob {
1760public:
1761 ExplicitTemplateArgsVisit(const TemplateArgumentLoc *Begin,
1762 const TemplateArgumentLoc *End, CXCursor parent)
1763 : VisitorJob(parent, VisitorJob::ExplicitTemplateArgsVisitKind, Begin,
1764 End) {}
1765 static bool classof(const VisitorJob *VJ) {
1766 return VJ->getKind() == ExplicitTemplateArgsVisitKind;
1767 }
1768 const TemplateArgumentLoc *begin() const {
1769 return static_cast<const TemplateArgumentLoc *>(data[0]);
1770 }
1771 const TemplateArgumentLoc *end() {
1772 return static_cast<const TemplateArgumentLoc *>(data[1]);
1773 }
1774};
Guy Benyei11169dd2012-12-18 14:30:41 +00001775class DeclVisit : public VisitorJob {
1776public:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001777 DeclVisit(const Decl *D, CXCursor parent, bool isFirst) :
Guy Benyei11169dd2012-12-18 14:30:41 +00001778 VisitorJob(parent, VisitorJob::DeclVisitKind,
Craig Topper69186e72014-06-08 08:38:04 +00001779 D, isFirst ? (void*) 1 : (void*) nullptr) {}
Guy Benyei11169dd2012-12-18 14:30:41 +00001780 static bool classof(const VisitorJob *VJ) {
1781 return VJ->getKind() == DeclVisitKind;
1782 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001783 const Decl *get() const { return static_cast<const Decl *>(data[0]); }
Dmitri Gribenkoe5423a72015-03-23 19:23:50 +00001784 bool isFirst() const { return data[1] != nullptr; }
Guy Benyei11169dd2012-12-18 14:30:41 +00001785};
1786class TypeLocVisit : public VisitorJob {
1787public:
1788 TypeLocVisit(TypeLoc tl, CXCursor parent) :
1789 VisitorJob(parent, VisitorJob::TypeLocVisitKind,
1790 tl.getType().getAsOpaquePtr(), tl.getOpaqueData()) {}
1791
1792 static bool classof(const VisitorJob *VJ) {
1793 return VJ->getKind() == TypeLocVisitKind;
1794 }
1795
1796 TypeLoc get() const {
1797 QualType T = QualType::getFromOpaquePtr(data[0]);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001798 return TypeLoc(T, const_cast<void *>(data[1]));
Guy Benyei11169dd2012-12-18 14:30:41 +00001799 }
1800};
1801
1802class LabelRefVisit : public VisitorJob {
1803public:
1804 LabelRefVisit(LabelDecl *LD, SourceLocation labelLoc, CXCursor parent)
1805 : VisitorJob(parent, VisitorJob::LabelRefVisitKind, LD,
1806 labelLoc.getPtrEncoding()) {}
1807
1808 static bool classof(const VisitorJob *VJ) {
1809 return VJ->getKind() == VisitorJob::LabelRefVisitKind;
1810 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001811 const LabelDecl *get() const {
1812 return static_cast<const LabelDecl *>(data[0]);
1813 }
Guy Benyei11169dd2012-12-18 14:30:41 +00001814 SourceLocation getLoc() const {
1815 return SourceLocation::getFromPtrEncoding(data[1]); }
1816};
1817
1818class NestedNameSpecifierLocVisit : public VisitorJob {
1819public:
1820 NestedNameSpecifierLocVisit(NestedNameSpecifierLoc Qualifier, CXCursor parent)
1821 : VisitorJob(parent, VisitorJob::NestedNameSpecifierLocVisitKind,
1822 Qualifier.getNestedNameSpecifier(),
1823 Qualifier.getOpaqueData()) { }
1824
1825 static bool classof(const VisitorJob *VJ) {
1826 return VJ->getKind() == VisitorJob::NestedNameSpecifierLocVisitKind;
1827 }
1828
1829 NestedNameSpecifierLoc get() const {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001830 return NestedNameSpecifierLoc(
1831 const_cast<NestedNameSpecifier *>(
1832 static_cast<const NestedNameSpecifier *>(data[0])),
1833 const_cast<void *>(data[1]));
Guy Benyei11169dd2012-12-18 14:30:41 +00001834 }
1835};
1836
1837class DeclarationNameInfoVisit : public VisitorJob {
1838public:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001839 DeclarationNameInfoVisit(const Stmt *S, CXCursor parent)
Dmitri Gribenkodd7dacf2013-02-03 13:19:54 +00001840 : VisitorJob(parent, VisitorJob::DeclarationNameInfoVisitKind, S) {}
Guy Benyei11169dd2012-12-18 14:30:41 +00001841 static bool classof(const VisitorJob *VJ) {
1842 return VJ->getKind() == VisitorJob::DeclarationNameInfoVisitKind;
1843 }
1844 DeclarationNameInfo get() const {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001845 const Stmt *S = static_cast<const Stmt *>(data[0]);
Guy Benyei11169dd2012-12-18 14:30:41 +00001846 switch (S->getStmtClass()) {
1847 default:
1848 llvm_unreachable("Unhandled Stmt");
1849 case clang::Stmt::MSDependentExistsStmtClass:
1850 return cast<MSDependentExistsStmt>(S)->getNameInfo();
1851 case Stmt::CXXDependentScopeMemberExprClass:
1852 return cast<CXXDependentScopeMemberExpr>(S)->getMemberNameInfo();
1853 case Stmt::DependentScopeDeclRefExprClass:
1854 return cast<DependentScopeDeclRefExpr>(S)->getNameInfo();
Alexander Musmand9ed09f2014-07-21 09:42:05 +00001855 case Stmt::OMPCriticalDirectiveClass:
1856 return cast<OMPCriticalDirective>(S)->getDirectiveName();
Guy Benyei11169dd2012-12-18 14:30:41 +00001857 }
1858 }
1859};
1860class MemberRefVisit : public VisitorJob {
1861public:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001862 MemberRefVisit(const FieldDecl *D, SourceLocation L, CXCursor parent)
Guy Benyei11169dd2012-12-18 14:30:41 +00001863 : VisitorJob(parent, VisitorJob::MemberRefVisitKind, D,
1864 L.getPtrEncoding()) {}
1865 static bool classof(const VisitorJob *VJ) {
1866 return VJ->getKind() == VisitorJob::MemberRefVisitKind;
1867 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001868 const FieldDecl *get() const {
1869 return static_cast<const FieldDecl *>(data[0]);
Guy Benyei11169dd2012-12-18 14:30:41 +00001870 }
1871 SourceLocation getLoc() const {
1872 return SourceLocation::getFromRawEncoding((unsigned)(uintptr_t) data[1]);
1873 }
1874};
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001875class EnqueueVisitor : public ConstStmtVisitor<EnqueueVisitor, void> {
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001876 friend class OMPClauseEnqueue;
Guy Benyei11169dd2012-12-18 14:30:41 +00001877 VisitorWorkList &WL;
1878 CXCursor Parent;
1879public:
1880 EnqueueVisitor(VisitorWorkList &wl, CXCursor parent)
1881 : WL(wl), Parent(parent) {}
1882
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001883 void VisitAddrLabelExpr(const AddrLabelExpr *E);
1884 void VisitBlockExpr(const BlockExpr *B);
1885 void VisitCompoundLiteralExpr(const CompoundLiteralExpr *E);
1886 void VisitCompoundStmt(const CompoundStmt *S);
1887 void VisitCXXDefaultArgExpr(const CXXDefaultArgExpr *E) { /* Do nothing. */ }
1888 void VisitMSDependentExistsStmt(const MSDependentExistsStmt *S);
1889 void VisitCXXDependentScopeMemberExpr(const CXXDependentScopeMemberExpr *E);
1890 void VisitCXXNewExpr(const CXXNewExpr *E);
1891 void VisitCXXScalarValueInitExpr(const CXXScalarValueInitExpr *E);
1892 void VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *E);
1893 void VisitCXXPseudoDestructorExpr(const CXXPseudoDestructorExpr *E);
1894 void VisitCXXTemporaryObjectExpr(const CXXTemporaryObjectExpr *E);
1895 void VisitCXXTypeidExpr(const CXXTypeidExpr *E);
1896 void VisitCXXUnresolvedConstructExpr(const CXXUnresolvedConstructExpr *E);
1897 void VisitCXXUuidofExpr(const CXXUuidofExpr *E);
1898 void VisitCXXCatchStmt(const CXXCatchStmt *S);
Argyrios Kyrtzidis99891242014-11-13 09:03:21 +00001899 void VisitCXXForRangeStmt(const CXXForRangeStmt *S);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001900 void VisitDeclRefExpr(const DeclRefExpr *D);
1901 void VisitDeclStmt(const DeclStmt *S);
1902 void VisitDependentScopeDeclRefExpr(const DependentScopeDeclRefExpr *E);
1903 void VisitDesignatedInitExpr(const DesignatedInitExpr *E);
1904 void VisitExplicitCastExpr(const ExplicitCastExpr *E);
1905 void VisitForStmt(const ForStmt *FS);
1906 void VisitGotoStmt(const GotoStmt *GS);
1907 void VisitIfStmt(const IfStmt *If);
1908 void VisitInitListExpr(const InitListExpr *IE);
1909 void VisitMemberExpr(const MemberExpr *M);
1910 void VisitOffsetOfExpr(const OffsetOfExpr *E);
1911 void VisitObjCEncodeExpr(const ObjCEncodeExpr *E);
1912 void VisitObjCMessageExpr(const ObjCMessageExpr *M);
1913 void VisitOverloadExpr(const OverloadExpr *E);
1914 void VisitUnaryExprOrTypeTraitExpr(const UnaryExprOrTypeTraitExpr *E);
1915 void VisitStmt(const Stmt *S);
1916 void VisitSwitchStmt(const SwitchStmt *S);
1917 void VisitWhileStmt(const WhileStmt *W);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001918 void VisitTypeTraitExpr(const TypeTraitExpr *E);
1919 void VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *E);
1920 void VisitExpressionTraitExpr(const ExpressionTraitExpr *E);
1921 void VisitUnresolvedMemberExpr(const UnresolvedMemberExpr *U);
1922 void VisitVAArgExpr(const VAArgExpr *E);
1923 void VisitSizeOfPackExpr(const SizeOfPackExpr *E);
1924 void VisitPseudoObjectExpr(const PseudoObjectExpr *E);
1925 void VisitOpaqueValueExpr(const OpaqueValueExpr *E);
1926 void VisitLambdaExpr(const LambdaExpr *E);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001927 void VisitOMPExecutableDirective(const OMPExecutableDirective *D);
Alexander Musman3aaab662014-08-19 11:27:13 +00001928 void VisitOMPLoopDirective(const OMPLoopDirective *D);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001929 void VisitOMPParallelDirective(const OMPParallelDirective *D);
Alexey Bataev1b59ab52014-02-27 08:29:12 +00001930 void VisitOMPSimdDirective(const OMPSimdDirective *D);
Alexey Bataevf29276e2014-06-18 04:14:57 +00001931 void VisitOMPForDirective(const OMPForDirective *D);
Alexander Musmanf82886e2014-09-18 05:12:34 +00001932 void VisitOMPForSimdDirective(const OMPForSimdDirective *D);
Alexey Bataevd3f8dd22014-06-25 11:44:49 +00001933 void VisitOMPSectionsDirective(const OMPSectionsDirective *D);
Alexey Bataev1e0498a2014-06-26 08:21:58 +00001934 void VisitOMPSectionDirective(const OMPSectionDirective *D);
Alexey Bataevd1e40fb2014-06-26 12:05:45 +00001935 void VisitOMPSingleDirective(const OMPSingleDirective *D);
Alexander Musman80c22892014-07-17 08:54:58 +00001936 void VisitOMPMasterDirective(const OMPMasterDirective *D);
Alexander Musmand9ed09f2014-07-21 09:42:05 +00001937 void VisitOMPCriticalDirective(const OMPCriticalDirective *D);
Alexey Bataev4acb8592014-07-07 13:01:15 +00001938 void VisitOMPParallelForDirective(const OMPParallelForDirective *D);
Alexander Musmane4e893b2014-09-23 09:33:00 +00001939 void VisitOMPParallelForSimdDirective(const OMPParallelForSimdDirective *D);
Alexey Bataev84d0b3e2014-07-08 08:12:03 +00001940 void VisitOMPParallelSectionsDirective(const OMPParallelSectionsDirective *D);
Alexey Bataev9c2e8ee2014-07-11 11:25:16 +00001941 void VisitOMPTaskDirective(const OMPTaskDirective *D);
Alexey Bataev68446b72014-07-18 07:47:19 +00001942 void VisitOMPTaskyieldDirective(const OMPTaskyieldDirective *D);
Alexey Bataev4d1dfea2014-07-18 09:11:51 +00001943 void VisitOMPBarrierDirective(const OMPBarrierDirective *D);
Alexey Bataev2df347a2014-07-18 10:17:07 +00001944 void VisitOMPTaskwaitDirective(const OMPTaskwaitDirective *D);
Alexey Bataevc30dd2d2015-06-18 12:14:09 +00001945 void VisitOMPTaskgroupDirective(const OMPTaskgroupDirective *D);
Alexey Bataev6d4ed052015-07-01 06:57:41 +00001946 void
1947 VisitOMPCancellationPointDirective(const OMPCancellationPointDirective *D);
Alexey Bataev80909872015-07-02 11:25:17 +00001948 void VisitOMPCancelDirective(const OMPCancelDirective *D);
Alexey Bataev6125da92014-07-21 11:26:11 +00001949 void VisitOMPFlushDirective(const OMPFlushDirective *D);
Alexey Bataev9fb6e642014-07-22 06:45:04 +00001950 void VisitOMPOrderedDirective(const OMPOrderedDirective *D);
Alexey Bataev0162e452014-07-22 10:10:35 +00001951 void VisitOMPAtomicDirective(const OMPAtomicDirective *D);
Alexey Bataev0bd520b2014-09-19 08:19:49 +00001952 void VisitOMPTargetDirective(const OMPTargetDirective *D);
Michael Wong65f367f2015-07-21 13:44:28 +00001953 void VisitOMPTargetDataDirective(const OMPTargetDataDirective *D);
Samuel Antaodf67fc42016-01-19 19:15:56 +00001954 void VisitOMPTargetEnterDataDirective(const OMPTargetEnterDataDirective *D);
Samuel Antao72590762016-01-19 20:04:50 +00001955 void VisitOMPTargetExitDataDirective(const OMPTargetExitDataDirective *D);
Arpith Chacko Jacobe955b3d2016-01-26 18:48:41 +00001956 void VisitOMPTargetParallelDirective(const OMPTargetParallelDirective *D);
Arpith Chacko Jacob05bebb52016-02-03 15:46:42 +00001957 void
1958 VisitOMPTargetParallelForDirective(const OMPTargetParallelForDirective *D);
Alexey Bataev13314bf2014-10-09 04:18:56 +00001959 void VisitOMPTeamsDirective(const OMPTeamsDirective *D);
Alexey Bataev49f6e782015-12-01 04:18:41 +00001960 void VisitOMPTaskLoopDirective(const OMPTaskLoopDirective *D);
Alexey Bataev0a6ed842015-12-03 09:40:15 +00001961 void VisitOMPTaskLoopSimdDirective(const OMPTaskLoopSimdDirective *D);
Carlo Bertolli6200a3d2015-12-14 14:51:25 +00001962 void VisitOMPDistributeDirective(const OMPDistributeDirective *D);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001963
Guy Benyei11169dd2012-12-18 14:30:41 +00001964private:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001965 void AddDeclarationNameInfo(const Stmt *S);
Guy Benyei11169dd2012-12-18 14:30:41 +00001966 void AddNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier);
James Y Knight04ec5bf2015-12-24 02:59:37 +00001967 void AddExplicitTemplateArgs(const TemplateArgumentLoc *A,
1968 unsigned NumTemplateArgs);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001969 void AddMemberRef(const FieldDecl *D, SourceLocation L);
1970 void AddStmt(const Stmt *S);
1971 void AddDecl(const Decl *D, bool isFirst = true);
Guy Benyei11169dd2012-12-18 14:30:41 +00001972 void AddTypeLoc(TypeSourceInfo *TI);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001973 void EnqueueChildren(const Stmt *S);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001974 void EnqueueChildren(const OMPClause *S);
Guy Benyei11169dd2012-12-18 14:30:41 +00001975};
Alexander Kornienkoab9db512015-06-22 23:07:51 +00001976} // end anonyous namespace
Guy Benyei11169dd2012-12-18 14:30:41 +00001977
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001978void EnqueueVisitor::AddDeclarationNameInfo(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001979 // 'S' should always be non-null, since it comes from the
1980 // statement we are visiting.
1981 WL.push_back(DeclarationNameInfoVisit(S, Parent));
1982}
1983
1984void
1985EnqueueVisitor::AddNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier) {
1986 if (Qualifier)
1987 WL.push_back(NestedNameSpecifierLocVisit(Qualifier, Parent));
1988}
1989
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001990void EnqueueVisitor::AddStmt(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001991 if (S)
1992 WL.push_back(StmtVisit(S, Parent));
1993}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001994void EnqueueVisitor::AddDecl(const Decl *D, bool isFirst) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001995 if (D)
1996 WL.push_back(DeclVisit(D, Parent, isFirst));
1997}
James Y Knight04ec5bf2015-12-24 02:59:37 +00001998void EnqueueVisitor::AddExplicitTemplateArgs(const TemplateArgumentLoc *A,
1999 unsigned NumTemplateArgs) {
2000 WL.push_back(ExplicitTemplateArgsVisit(A, A + NumTemplateArgs, Parent));
Guy Benyei11169dd2012-12-18 14:30:41 +00002001}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002002void EnqueueVisitor::AddMemberRef(const FieldDecl *D, SourceLocation L) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002003 if (D)
2004 WL.push_back(MemberRefVisit(D, L, Parent));
2005}
2006void EnqueueVisitor::AddTypeLoc(TypeSourceInfo *TI) {
2007 if (TI)
2008 WL.push_back(TypeLocVisit(TI->getTypeLoc(), Parent));
2009 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002010void EnqueueVisitor::EnqueueChildren(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002011 unsigned size = WL.size();
Benjamin Kramer642f1732015-07-02 21:03:14 +00002012 for (const Stmt *SubStmt : S->children()) {
2013 AddStmt(SubStmt);
Guy Benyei11169dd2012-12-18 14:30:41 +00002014 }
2015 if (size == WL.size())
2016 return;
2017 // Now reverse the entries we just added. This will match the DFS
2018 // ordering performed by the worklist.
2019 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
2020 std::reverse(I, E);
2021}
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002022namespace {
2023class OMPClauseEnqueue : public ConstOMPClauseVisitor<OMPClauseEnqueue> {
2024 EnqueueVisitor *Visitor;
Alexey Bataev756c1962013-09-24 03:17:45 +00002025 /// \brief Process clauses with list of variables.
2026 template <typename T>
2027 void VisitOMPClauseList(T *Node);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002028public:
2029 OMPClauseEnqueue(EnqueueVisitor *Visitor) : Visitor(Visitor) { }
2030#define OPENMP_CLAUSE(Name, Class) \
2031 void Visit##Class(const Class *C);
2032#include "clang/Basic/OpenMPKinds.def"
Alexey Bataev3392d762016-02-16 11:18:12 +00002033 void VisitOMPClauseWithPreInit(const OMPClauseWithPreInit *C);
Alexey Bataev005248a2016-02-25 05:25:57 +00002034 void VisitOMPClauseWithPostUpdate(const OMPClauseWithPostUpdate *C);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002035};
2036
Alexey Bataev3392d762016-02-16 11:18:12 +00002037void OMPClauseEnqueue::VisitOMPClauseWithPreInit(
2038 const OMPClauseWithPreInit *C) {
2039 Visitor->AddStmt(C->getPreInitStmt());
2040}
2041
Alexey Bataev005248a2016-02-25 05:25:57 +00002042void OMPClauseEnqueue::VisitOMPClauseWithPostUpdate(
2043 const OMPClauseWithPostUpdate *C) {
2044 Visitor->AddStmt(C->getPostUpdateExpr());
2045}
2046
Alexey Bataevaadd52e2014-02-13 05:29:23 +00002047void OMPClauseEnqueue::VisitOMPIfClause(const OMPIfClause *C) {
2048 Visitor->AddStmt(C->getCondition());
2049}
2050
Alexey Bataev3778b602014-07-17 07:32:53 +00002051void OMPClauseEnqueue::VisitOMPFinalClause(const OMPFinalClause *C) {
2052 Visitor->AddStmt(C->getCondition());
2053}
2054
Alexey Bataev568a8332014-03-06 06:15:19 +00002055void OMPClauseEnqueue::VisitOMPNumThreadsClause(const OMPNumThreadsClause *C) {
2056 Visitor->AddStmt(C->getNumThreads());
2057}
2058
Alexey Bataev62c87d22014-03-21 04:51:18 +00002059void OMPClauseEnqueue::VisitOMPSafelenClause(const OMPSafelenClause *C) {
2060 Visitor->AddStmt(C->getSafelen());
2061}
2062
Alexey Bataev66b15b52015-08-21 11:14:16 +00002063void OMPClauseEnqueue::VisitOMPSimdlenClause(const OMPSimdlenClause *C) {
2064 Visitor->AddStmt(C->getSimdlen());
2065}
2066
Alexander Musman8bd31e62014-05-27 15:12:19 +00002067void OMPClauseEnqueue::VisitOMPCollapseClause(const OMPCollapseClause *C) {
2068 Visitor->AddStmt(C->getNumForLoops());
2069}
2070
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002071void OMPClauseEnqueue::VisitOMPDefaultClause(const OMPDefaultClause *C) { }
Alexey Bataev756c1962013-09-24 03:17:45 +00002072
Alexey Bataevbcbadb62014-05-06 06:04:14 +00002073void OMPClauseEnqueue::VisitOMPProcBindClause(const OMPProcBindClause *C) { }
2074
Alexey Bataev56dafe82014-06-20 07:16:17 +00002075void OMPClauseEnqueue::VisitOMPScheduleClause(const OMPScheduleClause *C) {
Alexey Bataev3392d762016-02-16 11:18:12 +00002076 VisitOMPClauseWithPreInit(C);
Alexey Bataev56dafe82014-06-20 07:16:17 +00002077 Visitor->AddStmt(C->getChunkSize());
2078}
2079
Alexey Bataev10e775f2015-07-30 11:36:16 +00002080void OMPClauseEnqueue::VisitOMPOrderedClause(const OMPOrderedClause *C) {
2081 Visitor->AddStmt(C->getNumForLoops());
2082}
Alexey Bataev142e1fc2014-06-20 09:44:06 +00002083
Alexey Bataev236070f2014-06-20 11:19:47 +00002084void OMPClauseEnqueue::VisitOMPNowaitClause(const OMPNowaitClause *) {}
2085
Alexey Bataev7aea99a2014-07-17 12:19:31 +00002086void OMPClauseEnqueue::VisitOMPUntiedClause(const OMPUntiedClause *) {}
2087
Alexey Bataev74ba3a52014-07-17 12:47:03 +00002088void OMPClauseEnqueue::VisitOMPMergeableClause(const OMPMergeableClause *) {}
2089
Alexey Bataevf98b00c2014-07-23 02:27:21 +00002090void OMPClauseEnqueue::VisitOMPReadClause(const OMPReadClause *) {}
2091
Alexey Bataevdea47612014-07-23 07:46:59 +00002092void OMPClauseEnqueue::VisitOMPWriteClause(const OMPWriteClause *) {}
2093
Alexey Bataev67a4f222014-07-23 10:25:33 +00002094void OMPClauseEnqueue::VisitOMPUpdateClause(const OMPUpdateClause *) {}
2095
Alexey Bataev459dec02014-07-24 06:46:57 +00002096void OMPClauseEnqueue::VisitOMPCaptureClause(const OMPCaptureClause *) {}
2097
Alexey Bataev82bad8b2014-07-24 08:55:34 +00002098void OMPClauseEnqueue::VisitOMPSeqCstClause(const OMPSeqCstClause *) {}
2099
Alexey Bataev346265e2015-09-25 10:37:12 +00002100void OMPClauseEnqueue::VisitOMPThreadsClause(const OMPThreadsClause *) {}
2101
Alexey Bataevd14d1e62015-09-28 06:39:35 +00002102void OMPClauseEnqueue::VisitOMPSIMDClause(const OMPSIMDClause *) {}
2103
Alexey Bataevb825de12015-12-07 10:51:44 +00002104void OMPClauseEnqueue::VisitOMPNogroupClause(const OMPNogroupClause *) {}
2105
Michael Wonge710d542015-08-07 16:16:36 +00002106void OMPClauseEnqueue::VisitOMPDeviceClause(const OMPDeviceClause *C) {
2107 Visitor->AddStmt(C->getDevice());
2108}
2109
Kelvin Li099bb8c2015-11-24 20:50:12 +00002110void OMPClauseEnqueue::VisitOMPNumTeamsClause(const OMPNumTeamsClause *C) {
2111 Visitor->AddStmt(C->getNumTeams());
2112}
2113
Kelvin Lia15fb1a2015-11-27 18:47:36 +00002114void OMPClauseEnqueue::VisitOMPThreadLimitClause(const OMPThreadLimitClause *C) {
2115 Visitor->AddStmt(C->getThreadLimit());
2116}
2117
Alexey Bataeva0569352015-12-01 10:17:31 +00002118void OMPClauseEnqueue::VisitOMPPriorityClause(const OMPPriorityClause *C) {
2119 Visitor->AddStmt(C->getPriority());
2120}
2121
Alexey Bataev1fd4aed2015-12-07 12:52:51 +00002122void OMPClauseEnqueue::VisitOMPGrainsizeClause(const OMPGrainsizeClause *C) {
2123 Visitor->AddStmt(C->getGrainsize());
2124}
2125
Alexey Bataev382967a2015-12-08 12:06:20 +00002126void OMPClauseEnqueue::VisitOMPNumTasksClause(const OMPNumTasksClause *C) {
2127 Visitor->AddStmt(C->getNumTasks());
2128}
2129
Alexey Bataev28c75412015-12-15 08:19:24 +00002130void OMPClauseEnqueue::VisitOMPHintClause(const OMPHintClause *C) {
2131 Visitor->AddStmt(C->getHint());
2132}
2133
Alexey Bataev756c1962013-09-24 03:17:45 +00002134template<typename T>
2135void OMPClauseEnqueue::VisitOMPClauseList(T *Node) {
Alexey Bataev03b340a2014-10-21 03:16:40 +00002136 for (const auto *I : Node->varlists()) {
Aaron Ballman2205d2a2014-03-14 15:55:35 +00002137 Visitor->AddStmt(I);
Alexey Bataev03b340a2014-10-21 03:16:40 +00002138 }
Alexey Bataev756c1962013-09-24 03:17:45 +00002139}
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002140
2141void OMPClauseEnqueue::VisitOMPPrivateClause(const OMPPrivateClause *C) {
Alexey Bataev756c1962013-09-24 03:17:45 +00002142 VisitOMPClauseList(C);
Alexey Bataev03b340a2014-10-21 03:16:40 +00002143 for (const auto *E : C->private_copies()) {
2144 Visitor->AddStmt(E);
2145 }
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002146}
Alexey Bataevd5af8e42013-10-01 05:32:34 +00002147void OMPClauseEnqueue::VisitOMPFirstprivateClause(
2148 const OMPFirstprivateClause *C) {
2149 VisitOMPClauseList(C);
Alexey Bataev417089f2016-02-17 13:19:37 +00002150 VisitOMPClauseWithPreInit(C);
2151 for (const auto *E : C->private_copies()) {
2152 Visitor->AddStmt(E);
2153 }
2154 for (const auto *E : C->inits()) {
2155 Visitor->AddStmt(E);
2156 }
Alexey Bataevd5af8e42013-10-01 05:32:34 +00002157}
Alexander Musman1bb328c2014-06-04 13:06:39 +00002158void OMPClauseEnqueue::VisitOMPLastprivateClause(
2159 const OMPLastprivateClause *C) {
2160 VisitOMPClauseList(C);
Alexey Bataev005248a2016-02-25 05:25:57 +00002161 VisitOMPClauseWithPreInit(C);
2162 VisitOMPClauseWithPostUpdate(C);
Alexey Bataev38e89532015-04-16 04:54:05 +00002163 for (auto *E : C->private_copies()) {
2164 Visitor->AddStmt(E);
2165 }
2166 for (auto *E : C->source_exprs()) {
2167 Visitor->AddStmt(E);
2168 }
2169 for (auto *E : C->destination_exprs()) {
2170 Visitor->AddStmt(E);
2171 }
2172 for (auto *E : C->assignment_ops()) {
2173 Visitor->AddStmt(E);
2174 }
Alexander Musman1bb328c2014-06-04 13:06:39 +00002175}
Alexey Bataev758e55e2013-09-06 18:03:48 +00002176void OMPClauseEnqueue::VisitOMPSharedClause(const OMPSharedClause *C) {
Alexey Bataev756c1962013-09-24 03:17:45 +00002177 VisitOMPClauseList(C);
Alexey Bataev758e55e2013-09-06 18:03:48 +00002178}
Alexey Bataevc5e02582014-06-16 07:08:35 +00002179void OMPClauseEnqueue::VisitOMPReductionClause(const OMPReductionClause *C) {
2180 VisitOMPClauseList(C);
Alexey Bataevf24e7b12015-10-08 09:10:53 +00002181 for (auto *E : C->privates()) {
2182 Visitor->AddStmt(E);
2183 }
Alexey Bataev794ba0d2015-04-10 10:43:45 +00002184 for (auto *E : C->lhs_exprs()) {
2185 Visitor->AddStmt(E);
2186 }
2187 for (auto *E : C->rhs_exprs()) {
2188 Visitor->AddStmt(E);
2189 }
2190 for (auto *E : C->reduction_ops()) {
2191 Visitor->AddStmt(E);
2192 }
Alexey Bataevc5e02582014-06-16 07:08:35 +00002193}
Alexander Musman8dba6642014-04-22 13:09:42 +00002194void OMPClauseEnqueue::VisitOMPLinearClause(const OMPLinearClause *C) {
2195 VisitOMPClauseList(C);
Alexey Bataevbd9fec12015-08-18 06:47:21 +00002196 for (const auto *E : C->privates()) {
2197 Visitor->AddStmt(E);
2198 }
Alexander Musman3276a272015-03-21 10:12:56 +00002199 for (const auto *E : C->inits()) {
2200 Visitor->AddStmt(E);
2201 }
2202 for (const auto *E : C->updates()) {
2203 Visitor->AddStmt(E);
2204 }
2205 for (const auto *E : C->finals()) {
2206 Visitor->AddStmt(E);
2207 }
Alexander Musman8dba6642014-04-22 13:09:42 +00002208 Visitor->AddStmt(C->getStep());
Alexander Musman3276a272015-03-21 10:12:56 +00002209 Visitor->AddStmt(C->getCalcStep());
Alexander Musman8dba6642014-04-22 13:09:42 +00002210}
Alexander Musmanf0d76e72014-05-29 14:36:25 +00002211void OMPClauseEnqueue::VisitOMPAlignedClause(const OMPAlignedClause *C) {
2212 VisitOMPClauseList(C);
2213 Visitor->AddStmt(C->getAlignment());
2214}
Alexey Bataevd48bcd82014-03-31 03:36:38 +00002215void OMPClauseEnqueue::VisitOMPCopyinClause(const OMPCopyinClause *C) {
2216 VisitOMPClauseList(C);
Alexey Bataevf56f98c2015-04-16 05:39:01 +00002217 for (auto *E : C->source_exprs()) {
2218 Visitor->AddStmt(E);
2219 }
2220 for (auto *E : C->destination_exprs()) {
2221 Visitor->AddStmt(E);
2222 }
2223 for (auto *E : C->assignment_ops()) {
2224 Visitor->AddStmt(E);
2225 }
Alexey Bataevd48bcd82014-03-31 03:36:38 +00002226}
Alexey Bataevbae9a792014-06-27 10:37:06 +00002227void
2228OMPClauseEnqueue::VisitOMPCopyprivateClause(const OMPCopyprivateClause *C) {
2229 VisitOMPClauseList(C);
Alexey Bataeva63048e2015-03-23 06:18:07 +00002230 for (auto *E : C->source_exprs()) {
2231 Visitor->AddStmt(E);
2232 }
2233 for (auto *E : C->destination_exprs()) {
2234 Visitor->AddStmt(E);
2235 }
2236 for (auto *E : C->assignment_ops()) {
2237 Visitor->AddStmt(E);
2238 }
Alexey Bataevbae9a792014-06-27 10:37:06 +00002239}
Alexey Bataev6125da92014-07-21 11:26:11 +00002240void OMPClauseEnqueue::VisitOMPFlushClause(const OMPFlushClause *C) {
2241 VisitOMPClauseList(C);
2242}
Alexey Bataev1c2cfbc2015-06-23 14:25:19 +00002243void OMPClauseEnqueue::VisitOMPDependClause(const OMPDependClause *C) {
2244 VisitOMPClauseList(C);
2245}
Kelvin Li0bff7af2015-11-23 05:32:03 +00002246void OMPClauseEnqueue::VisitOMPMapClause(const OMPMapClause *C) {
2247 VisitOMPClauseList(C);
2248}
Carlo Bertollib4adf552016-01-15 18:50:31 +00002249void OMPClauseEnqueue::VisitOMPDistScheduleClause(
2250 const OMPDistScheduleClause *C) {
Alexey Bataev3392d762016-02-16 11:18:12 +00002251 VisitOMPClauseWithPreInit(C);
Carlo Bertollib4adf552016-01-15 18:50:31 +00002252 Visitor->AddStmt(C->getChunkSize());
Carlo Bertollib4adf552016-01-15 18:50:31 +00002253}
Alexey Bataev3392d762016-02-16 11:18:12 +00002254void OMPClauseEnqueue::VisitOMPDefaultmapClause(
2255 const OMPDefaultmapClause * /*C*/) {}
Alexander Kornienkoab9db512015-06-22 23:07:51 +00002256}
Alexey Bataev756c1962013-09-24 03:17:45 +00002257
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002258void EnqueueVisitor::EnqueueChildren(const OMPClause *S) {
2259 unsigned size = WL.size();
2260 OMPClauseEnqueue Visitor(this);
2261 Visitor.Visit(S);
2262 if (size == WL.size())
2263 return;
2264 // Now reverse the entries we just added. This will match the DFS
2265 // ordering performed by the worklist.
2266 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
2267 std::reverse(I, E);
2268}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002269void EnqueueVisitor::VisitAddrLabelExpr(const AddrLabelExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002270 WL.push_back(LabelRefVisit(E->getLabel(), E->getLabelLoc(), Parent));
2271}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002272void EnqueueVisitor::VisitBlockExpr(const BlockExpr *B) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002273 AddDecl(B->getBlockDecl());
2274}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002275void EnqueueVisitor::VisitCompoundLiteralExpr(const CompoundLiteralExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002276 EnqueueChildren(E);
2277 AddTypeLoc(E->getTypeSourceInfo());
2278}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002279void EnqueueVisitor::VisitCompoundStmt(const CompoundStmt *S) {
Pete Cooper57d3f142015-07-30 17:22:52 +00002280 for (auto &I : llvm::reverse(S->body()))
2281 AddStmt(I);
Guy Benyei11169dd2012-12-18 14:30:41 +00002282}
2283void EnqueueVisitor::
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002284VisitMSDependentExistsStmt(const MSDependentExistsStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002285 AddStmt(S->getSubStmt());
2286 AddDeclarationNameInfo(S);
2287 if (NestedNameSpecifierLoc QualifierLoc = S->getQualifierLoc())
2288 AddNestedNameSpecifierLoc(QualifierLoc);
2289}
2290
2291void EnqueueVisitor::
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002292VisitCXXDependentScopeMemberExpr(const CXXDependentScopeMemberExpr *E) {
James Y Knight04ec5bf2015-12-24 02:59:37 +00002293 if (E->hasExplicitTemplateArgs())
2294 AddExplicitTemplateArgs(E->getTemplateArgs(), E->getNumTemplateArgs());
Guy Benyei11169dd2012-12-18 14:30:41 +00002295 AddDeclarationNameInfo(E);
2296 if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
2297 AddNestedNameSpecifierLoc(QualifierLoc);
2298 if (!E->isImplicitAccess())
2299 AddStmt(E->getBase());
2300}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002301void EnqueueVisitor::VisitCXXNewExpr(const CXXNewExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002302 // Enqueue the initializer , if any.
2303 AddStmt(E->getInitializer());
2304 // Enqueue the array size, if any.
2305 AddStmt(E->getArraySize());
2306 // Enqueue the allocated type.
2307 AddTypeLoc(E->getAllocatedTypeSourceInfo());
2308 // Enqueue the placement arguments.
2309 for (unsigned I = E->getNumPlacementArgs(); I > 0; --I)
2310 AddStmt(E->getPlacementArg(I-1));
2311}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002312void EnqueueVisitor::VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *CE) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002313 for (unsigned I = CE->getNumArgs(); I > 1 /* Yes, this is 1 */; --I)
2314 AddStmt(CE->getArg(I-1));
2315 AddStmt(CE->getCallee());
2316 AddStmt(CE->getArg(0));
2317}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002318void EnqueueVisitor::VisitCXXPseudoDestructorExpr(
2319 const CXXPseudoDestructorExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002320 // Visit the name of the type being destroyed.
2321 AddTypeLoc(E->getDestroyedTypeInfo());
2322 // Visit the scope type that looks disturbingly like the nested-name-specifier
2323 // but isn't.
2324 AddTypeLoc(E->getScopeTypeInfo());
2325 // Visit the nested-name-specifier.
2326 if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
2327 AddNestedNameSpecifierLoc(QualifierLoc);
2328 // Visit base expression.
2329 AddStmt(E->getBase());
2330}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002331void EnqueueVisitor::VisitCXXScalarValueInitExpr(
2332 const CXXScalarValueInitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002333 AddTypeLoc(E->getTypeSourceInfo());
2334}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002335void EnqueueVisitor::VisitCXXTemporaryObjectExpr(
2336 const CXXTemporaryObjectExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002337 EnqueueChildren(E);
2338 AddTypeLoc(E->getTypeSourceInfo());
2339}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002340void EnqueueVisitor::VisitCXXTypeidExpr(const CXXTypeidExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002341 EnqueueChildren(E);
2342 if (E->isTypeOperand())
2343 AddTypeLoc(E->getTypeOperandSourceInfo());
2344}
2345
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002346void EnqueueVisitor::VisitCXXUnresolvedConstructExpr(
2347 const CXXUnresolvedConstructExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002348 EnqueueChildren(E);
2349 AddTypeLoc(E->getTypeSourceInfo());
2350}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002351void EnqueueVisitor::VisitCXXUuidofExpr(const CXXUuidofExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002352 EnqueueChildren(E);
2353 if (E->isTypeOperand())
2354 AddTypeLoc(E->getTypeOperandSourceInfo());
2355}
2356
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002357void EnqueueVisitor::VisitCXXCatchStmt(const CXXCatchStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002358 EnqueueChildren(S);
2359 AddDecl(S->getExceptionDecl());
2360}
2361
Argyrios Kyrtzidis99891242014-11-13 09:03:21 +00002362void EnqueueVisitor::VisitCXXForRangeStmt(const CXXForRangeStmt *S) {
Argyrios Kyrtzidiscde70692014-11-13 09:50:19 +00002363 AddStmt(S->getBody());
Argyrios Kyrtzidis99891242014-11-13 09:03:21 +00002364 AddStmt(S->getRangeInit());
Argyrios Kyrtzidiscde70692014-11-13 09:50:19 +00002365 AddDecl(S->getLoopVariable());
Argyrios Kyrtzidis99891242014-11-13 09:03:21 +00002366}
2367
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002368void EnqueueVisitor::VisitDeclRefExpr(const DeclRefExpr *DR) {
James Y Knight04ec5bf2015-12-24 02:59:37 +00002369 if (DR->hasExplicitTemplateArgs())
2370 AddExplicitTemplateArgs(DR->getTemplateArgs(), DR->getNumTemplateArgs());
Guy Benyei11169dd2012-12-18 14:30:41 +00002371 WL.push_back(DeclRefExprParts(DR, Parent));
2372}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002373void EnqueueVisitor::VisitDependentScopeDeclRefExpr(
2374 const DependentScopeDeclRefExpr *E) {
James Y Knight04ec5bf2015-12-24 02:59:37 +00002375 if (E->hasExplicitTemplateArgs())
2376 AddExplicitTemplateArgs(E->getTemplateArgs(), E->getNumTemplateArgs());
Guy Benyei11169dd2012-12-18 14:30:41 +00002377 AddDeclarationNameInfo(E);
2378 AddNestedNameSpecifierLoc(E->getQualifierLoc());
2379}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002380void EnqueueVisitor::VisitDeclStmt(const DeclStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002381 unsigned size = WL.size();
2382 bool isFirst = true;
Aaron Ballman535bbcc2014-03-14 17:01:24 +00002383 for (const auto *D : S->decls()) {
2384 AddDecl(D, isFirst);
Guy Benyei11169dd2012-12-18 14:30:41 +00002385 isFirst = false;
2386 }
2387 if (size == WL.size())
2388 return;
2389 // Now reverse the entries we just added. This will match the DFS
2390 // ordering performed by the worklist.
2391 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
2392 std::reverse(I, E);
2393}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002394void EnqueueVisitor::VisitDesignatedInitExpr(const DesignatedInitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002395 AddStmt(E->getInit());
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002396 for (DesignatedInitExpr::const_reverse_designators_iterator
Guy Benyei11169dd2012-12-18 14:30:41 +00002397 D = E->designators_rbegin(), DEnd = E->designators_rend();
2398 D != DEnd; ++D) {
2399 if (D->isFieldDesignator()) {
2400 if (FieldDecl *Field = D->getField())
2401 AddMemberRef(Field, D->getFieldLoc());
2402 continue;
2403 }
2404 if (D->isArrayDesignator()) {
2405 AddStmt(E->getArrayIndex(*D));
2406 continue;
2407 }
2408 assert(D->isArrayRangeDesignator() && "Unknown designator kind");
2409 AddStmt(E->getArrayRangeEnd(*D));
2410 AddStmt(E->getArrayRangeStart(*D));
2411 }
2412}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002413void EnqueueVisitor::VisitExplicitCastExpr(const ExplicitCastExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002414 EnqueueChildren(E);
2415 AddTypeLoc(E->getTypeInfoAsWritten());
2416}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002417void EnqueueVisitor::VisitForStmt(const ForStmt *FS) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002418 AddStmt(FS->getBody());
2419 AddStmt(FS->getInc());
2420 AddStmt(FS->getCond());
2421 AddDecl(FS->getConditionVariable());
2422 AddStmt(FS->getInit());
2423}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002424void EnqueueVisitor::VisitGotoStmt(const GotoStmt *GS) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002425 WL.push_back(LabelRefVisit(GS->getLabel(), GS->getLabelLoc(), Parent));
2426}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002427void EnqueueVisitor::VisitIfStmt(const IfStmt *If) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002428 AddStmt(If->getElse());
2429 AddStmt(If->getThen());
2430 AddStmt(If->getCond());
2431 AddDecl(If->getConditionVariable());
2432}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002433void EnqueueVisitor::VisitInitListExpr(const InitListExpr *IE) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002434 // We care about the syntactic form of the initializer list, only.
2435 if (InitListExpr *Syntactic = IE->getSyntacticForm())
2436 IE = Syntactic;
2437 EnqueueChildren(IE);
2438}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002439void EnqueueVisitor::VisitMemberExpr(const MemberExpr *M) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002440 WL.push_back(MemberExprParts(M, Parent));
2441
2442 // If the base of the member access expression is an implicit 'this', don't
2443 // visit it.
2444 // FIXME: If we ever want to show these implicit accesses, this will be
2445 // unfortunate. However, clang_getCursor() relies on this behavior.
Argyrios Kyrtzidis58d0e7a2015-03-13 04:40:07 +00002446 if (M->isImplicitAccess())
2447 return;
2448
2449 // Ignore base anonymous struct/union fields, otherwise they will shadow the
2450 // real field that that we are interested in.
2451 if (auto *SubME = dyn_cast<MemberExpr>(M->getBase())) {
2452 if (auto *FD = dyn_cast_or_null<FieldDecl>(SubME->getMemberDecl())) {
2453 if (FD->isAnonymousStructOrUnion()) {
2454 AddStmt(SubME->getBase());
2455 return;
2456 }
2457 }
2458 }
2459
2460 AddStmt(M->getBase());
Guy Benyei11169dd2012-12-18 14:30:41 +00002461}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002462void EnqueueVisitor::VisitObjCEncodeExpr(const ObjCEncodeExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002463 AddTypeLoc(E->getEncodedTypeSourceInfo());
2464}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002465void EnqueueVisitor::VisitObjCMessageExpr(const ObjCMessageExpr *M) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002466 EnqueueChildren(M);
2467 AddTypeLoc(M->getClassReceiverTypeInfo());
2468}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002469void EnqueueVisitor::VisitOffsetOfExpr(const OffsetOfExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002470 // Visit the components of the offsetof expression.
2471 for (unsigned N = E->getNumComponents(), I = N; I > 0; --I) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002472 const OffsetOfNode &Node = E->getComponent(I-1);
2473 switch (Node.getKind()) {
2474 case OffsetOfNode::Array:
2475 AddStmt(E->getIndexExpr(Node.getArrayExprIndex()));
2476 break;
2477 case OffsetOfNode::Field:
2478 AddMemberRef(Node.getField(), Node.getSourceRange().getEnd());
2479 break;
2480 case OffsetOfNode::Identifier:
2481 case OffsetOfNode::Base:
2482 continue;
2483 }
2484 }
2485 // Visit the type into which we're computing the offset.
2486 AddTypeLoc(E->getTypeSourceInfo());
2487}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002488void EnqueueVisitor::VisitOverloadExpr(const OverloadExpr *E) {
James Y Knight04ec5bf2015-12-24 02:59:37 +00002489 if (E->hasExplicitTemplateArgs())
2490 AddExplicitTemplateArgs(E->getTemplateArgs(), E->getNumTemplateArgs());
Guy Benyei11169dd2012-12-18 14:30:41 +00002491 WL.push_back(OverloadExprParts(E, Parent));
2492}
2493void EnqueueVisitor::VisitUnaryExprOrTypeTraitExpr(
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002494 const UnaryExprOrTypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002495 EnqueueChildren(E);
2496 if (E->isArgumentType())
2497 AddTypeLoc(E->getArgumentTypeInfo());
2498}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002499void EnqueueVisitor::VisitStmt(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002500 EnqueueChildren(S);
2501}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002502void EnqueueVisitor::VisitSwitchStmt(const SwitchStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002503 AddStmt(S->getBody());
2504 AddStmt(S->getCond());
2505 AddDecl(S->getConditionVariable());
2506}
2507
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002508void EnqueueVisitor::VisitWhileStmt(const WhileStmt *W) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002509 AddStmt(W->getBody());
2510 AddStmt(W->getCond());
2511 AddDecl(W->getConditionVariable());
2512}
2513
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002514void EnqueueVisitor::VisitTypeTraitExpr(const TypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002515 for (unsigned I = E->getNumArgs(); I > 0; --I)
2516 AddTypeLoc(E->getArg(I-1));
2517}
2518
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002519void EnqueueVisitor::VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002520 AddTypeLoc(E->getQueriedTypeSourceInfo());
2521}
2522
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002523void EnqueueVisitor::VisitExpressionTraitExpr(const ExpressionTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002524 EnqueueChildren(E);
2525}
2526
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002527void EnqueueVisitor::VisitUnresolvedMemberExpr(const UnresolvedMemberExpr *U) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002528 VisitOverloadExpr(U);
2529 if (!U->isImplicitAccess())
2530 AddStmt(U->getBase());
2531}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002532void EnqueueVisitor::VisitVAArgExpr(const VAArgExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002533 AddStmt(E->getSubExpr());
2534 AddTypeLoc(E->getWrittenTypeInfo());
2535}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002536void EnqueueVisitor::VisitSizeOfPackExpr(const SizeOfPackExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002537 WL.push_back(SizeOfPackExprParts(E, Parent));
2538}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002539void EnqueueVisitor::VisitOpaqueValueExpr(const OpaqueValueExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002540 // If the opaque value has a source expression, just transparently
2541 // visit that. This is useful for (e.g.) pseudo-object expressions.
2542 if (Expr *SourceExpr = E->getSourceExpr())
2543 return Visit(SourceExpr);
2544}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002545void EnqueueVisitor::VisitLambdaExpr(const LambdaExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002546 AddStmt(E->getBody());
2547 WL.push_back(LambdaExprParts(E, Parent));
2548}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002549void EnqueueVisitor::VisitPseudoObjectExpr(const PseudoObjectExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002550 // Treat the expression like its syntactic form.
2551 Visit(E->getSyntacticForm());
2552}
2553
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002554void EnqueueVisitor::VisitOMPExecutableDirective(
2555 const OMPExecutableDirective *D) {
2556 EnqueueChildren(D);
2557 for (ArrayRef<OMPClause *>::iterator I = D->clauses().begin(),
2558 E = D->clauses().end();
2559 I != E; ++I)
2560 EnqueueChildren(*I);
2561}
2562
Alexander Musman3aaab662014-08-19 11:27:13 +00002563void EnqueueVisitor::VisitOMPLoopDirective(const OMPLoopDirective *D) {
2564 VisitOMPExecutableDirective(D);
2565}
2566
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002567void EnqueueVisitor::VisitOMPParallelDirective(const OMPParallelDirective *D) {
2568 VisitOMPExecutableDirective(D);
2569}
2570
Alexey Bataev1b59ab52014-02-27 08:29:12 +00002571void EnqueueVisitor::VisitOMPSimdDirective(const OMPSimdDirective *D) {
Alexander Musman3aaab662014-08-19 11:27:13 +00002572 VisitOMPLoopDirective(D);
Alexey Bataev1b59ab52014-02-27 08:29:12 +00002573}
2574
Alexey Bataevf29276e2014-06-18 04:14:57 +00002575void EnqueueVisitor::VisitOMPForDirective(const OMPForDirective *D) {
Alexander Musman3aaab662014-08-19 11:27:13 +00002576 VisitOMPLoopDirective(D);
Alexey Bataevf29276e2014-06-18 04:14:57 +00002577}
2578
Alexander Musmanf82886e2014-09-18 05:12:34 +00002579void EnqueueVisitor::VisitOMPForSimdDirective(const OMPForSimdDirective *D) {
2580 VisitOMPLoopDirective(D);
2581}
2582
Alexey Bataevd3f8dd22014-06-25 11:44:49 +00002583void EnqueueVisitor::VisitOMPSectionsDirective(const OMPSectionsDirective *D) {
2584 VisitOMPExecutableDirective(D);
2585}
2586
Alexey Bataev1e0498a2014-06-26 08:21:58 +00002587void EnqueueVisitor::VisitOMPSectionDirective(const OMPSectionDirective *D) {
2588 VisitOMPExecutableDirective(D);
2589}
2590
Alexey Bataevd1e40fb2014-06-26 12:05:45 +00002591void EnqueueVisitor::VisitOMPSingleDirective(const OMPSingleDirective *D) {
2592 VisitOMPExecutableDirective(D);
2593}
2594
Alexander Musman80c22892014-07-17 08:54:58 +00002595void EnqueueVisitor::VisitOMPMasterDirective(const OMPMasterDirective *D) {
2596 VisitOMPExecutableDirective(D);
2597}
2598
Alexander Musmand9ed09f2014-07-21 09:42:05 +00002599void EnqueueVisitor::VisitOMPCriticalDirective(const OMPCriticalDirective *D) {
2600 VisitOMPExecutableDirective(D);
2601 AddDeclarationNameInfo(D);
2602}
2603
Alexey Bataev4acb8592014-07-07 13:01:15 +00002604void
2605EnqueueVisitor::VisitOMPParallelForDirective(const OMPParallelForDirective *D) {
Alexander Musman3aaab662014-08-19 11:27:13 +00002606 VisitOMPLoopDirective(D);
Alexey Bataev4acb8592014-07-07 13:01:15 +00002607}
2608
Alexander Musmane4e893b2014-09-23 09:33:00 +00002609void EnqueueVisitor::VisitOMPParallelForSimdDirective(
2610 const OMPParallelForSimdDirective *D) {
2611 VisitOMPLoopDirective(D);
2612}
2613
Alexey Bataev84d0b3e2014-07-08 08:12:03 +00002614void EnqueueVisitor::VisitOMPParallelSectionsDirective(
2615 const OMPParallelSectionsDirective *D) {
2616 VisitOMPExecutableDirective(D);
2617}
2618
Alexey Bataev9c2e8ee2014-07-11 11:25:16 +00002619void EnqueueVisitor::VisitOMPTaskDirective(const OMPTaskDirective *D) {
2620 VisitOMPExecutableDirective(D);
2621}
2622
Alexey Bataev68446b72014-07-18 07:47:19 +00002623void
2624EnqueueVisitor::VisitOMPTaskyieldDirective(const OMPTaskyieldDirective *D) {
2625 VisitOMPExecutableDirective(D);
2626}
2627
Alexey Bataev4d1dfea2014-07-18 09:11:51 +00002628void EnqueueVisitor::VisitOMPBarrierDirective(const OMPBarrierDirective *D) {
2629 VisitOMPExecutableDirective(D);
2630}
2631
Alexey Bataev2df347a2014-07-18 10:17:07 +00002632void EnqueueVisitor::VisitOMPTaskwaitDirective(const OMPTaskwaitDirective *D) {
2633 VisitOMPExecutableDirective(D);
2634}
2635
Alexey Bataevc30dd2d2015-06-18 12:14:09 +00002636void EnqueueVisitor::VisitOMPTaskgroupDirective(
2637 const OMPTaskgroupDirective *D) {
2638 VisitOMPExecutableDirective(D);
2639}
2640
Alexey Bataev6125da92014-07-21 11:26:11 +00002641void EnqueueVisitor::VisitOMPFlushDirective(const OMPFlushDirective *D) {
2642 VisitOMPExecutableDirective(D);
2643}
2644
Alexey Bataev9fb6e642014-07-22 06:45:04 +00002645void EnqueueVisitor::VisitOMPOrderedDirective(const OMPOrderedDirective *D) {
2646 VisitOMPExecutableDirective(D);
2647}
2648
Alexey Bataev0162e452014-07-22 10:10:35 +00002649void EnqueueVisitor::VisitOMPAtomicDirective(const OMPAtomicDirective *D) {
2650 VisitOMPExecutableDirective(D);
2651}
2652
Alexey Bataev0bd520b2014-09-19 08:19:49 +00002653void EnqueueVisitor::VisitOMPTargetDirective(const OMPTargetDirective *D) {
2654 VisitOMPExecutableDirective(D);
2655}
2656
Michael Wong65f367f2015-07-21 13:44:28 +00002657void EnqueueVisitor::VisitOMPTargetDataDirective(const
2658 OMPTargetDataDirective *D) {
2659 VisitOMPExecutableDirective(D);
2660}
2661
Samuel Antaodf67fc42016-01-19 19:15:56 +00002662void EnqueueVisitor::VisitOMPTargetEnterDataDirective(
2663 const OMPTargetEnterDataDirective *D) {
2664 VisitOMPExecutableDirective(D);
2665}
2666
Samuel Antao72590762016-01-19 20:04:50 +00002667void EnqueueVisitor::VisitOMPTargetExitDataDirective(
2668 const OMPTargetExitDataDirective *D) {
2669 VisitOMPExecutableDirective(D);
2670}
2671
Arpith Chacko Jacobe955b3d2016-01-26 18:48:41 +00002672void EnqueueVisitor::VisitOMPTargetParallelDirective(
2673 const OMPTargetParallelDirective *D) {
2674 VisitOMPExecutableDirective(D);
2675}
2676
Arpith Chacko Jacob05bebb52016-02-03 15:46:42 +00002677void EnqueueVisitor::VisitOMPTargetParallelForDirective(
2678 const OMPTargetParallelForDirective *D) {
2679 VisitOMPLoopDirective(D);
2680}
2681
Alexey Bataev13314bf2014-10-09 04:18:56 +00002682void EnqueueVisitor::VisitOMPTeamsDirective(const OMPTeamsDirective *D) {
2683 VisitOMPExecutableDirective(D);
2684}
2685
Alexey Bataev6d4ed052015-07-01 06:57:41 +00002686void EnqueueVisitor::VisitOMPCancellationPointDirective(
2687 const OMPCancellationPointDirective *D) {
2688 VisitOMPExecutableDirective(D);
2689}
2690
Alexey Bataev80909872015-07-02 11:25:17 +00002691void EnqueueVisitor::VisitOMPCancelDirective(const OMPCancelDirective *D) {
2692 VisitOMPExecutableDirective(D);
2693}
2694
Alexey Bataev49f6e782015-12-01 04:18:41 +00002695void EnqueueVisitor::VisitOMPTaskLoopDirective(const OMPTaskLoopDirective *D) {
2696 VisitOMPLoopDirective(D);
2697}
2698
Alexey Bataev0a6ed842015-12-03 09:40:15 +00002699void EnqueueVisitor::VisitOMPTaskLoopSimdDirective(
2700 const OMPTaskLoopSimdDirective *D) {
2701 VisitOMPLoopDirective(D);
2702}
2703
Carlo Bertolli6200a3d2015-12-14 14:51:25 +00002704void EnqueueVisitor::VisitOMPDistributeDirective(
2705 const OMPDistributeDirective *D) {
2706 VisitOMPLoopDirective(D);
2707}
2708
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002709void CursorVisitor::EnqueueWorkList(VisitorWorkList &WL, const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002710 EnqueueVisitor(WL, MakeCXCursor(S, StmtParent, TU,RegionOfInterest)).Visit(S);
2711}
2712
2713bool CursorVisitor::IsInRegionOfInterest(CXCursor C) {
2714 if (RegionOfInterest.isValid()) {
2715 SourceRange Range = getRawCursorExtent(C);
2716 if (Range.isInvalid() || CompareRegionOfInterest(Range))
2717 return false;
2718 }
2719 return true;
2720}
2721
2722bool CursorVisitor::RunVisitorWorkList(VisitorWorkList &WL) {
2723 while (!WL.empty()) {
2724 // Dequeue the worklist item.
Robert Wilhelm25284cc2013-08-23 16:11:15 +00002725 VisitorJob LI = WL.pop_back_val();
Guy Benyei11169dd2012-12-18 14:30:41 +00002726
2727 // Set the Parent field, then back to its old value once we're done.
2728 SetParentRAII SetParent(Parent, StmtParent, LI.getParent());
2729
2730 switch (LI.getKind()) {
2731 case VisitorJob::DeclVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002732 const Decl *D = cast<DeclVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002733 if (!D)
2734 continue;
2735
2736 // For now, perform default visitation for Decls.
2737 if (Visit(MakeCXCursor(D, TU, RegionOfInterest,
2738 cast<DeclVisit>(&LI)->isFirst())))
2739 return true;
2740
2741 continue;
2742 }
2743 case VisitorJob::ExplicitTemplateArgsVisitKind: {
James Y Knight04ec5bf2015-12-24 02:59:37 +00002744 for (const TemplateArgumentLoc &Arg :
2745 *cast<ExplicitTemplateArgsVisit>(&LI)) {
2746 if (VisitTemplateArgumentLoc(Arg))
Guy Benyei11169dd2012-12-18 14:30:41 +00002747 return true;
2748 }
2749 continue;
2750 }
2751 case VisitorJob::TypeLocVisitKind: {
2752 // Perform default visitation for TypeLocs.
2753 if (Visit(cast<TypeLocVisit>(&LI)->get()))
2754 return true;
2755 continue;
2756 }
2757 case VisitorJob::LabelRefVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002758 const LabelDecl *LS = cast<LabelRefVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002759 if (LabelStmt *stmt = LS->getStmt()) {
2760 if (Visit(MakeCursorLabelRef(stmt, cast<LabelRefVisit>(&LI)->getLoc(),
2761 TU))) {
2762 return true;
2763 }
2764 }
2765 continue;
2766 }
2767
2768 case VisitorJob::NestedNameSpecifierLocVisitKind: {
2769 NestedNameSpecifierLocVisit *V = cast<NestedNameSpecifierLocVisit>(&LI);
2770 if (VisitNestedNameSpecifierLoc(V->get()))
2771 return true;
2772 continue;
2773 }
2774
2775 case VisitorJob::DeclarationNameInfoVisitKind: {
2776 if (VisitDeclarationNameInfo(cast<DeclarationNameInfoVisit>(&LI)
2777 ->get()))
2778 return true;
2779 continue;
2780 }
2781 case VisitorJob::MemberRefVisitKind: {
2782 MemberRefVisit *V = cast<MemberRefVisit>(&LI);
2783 if (Visit(MakeCursorMemberRef(V->get(), V->getLoc(), TU)))
2784 return true;
2785 continue;
2786 }
2787 case VisitorJob::StmtVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002788 const Stmt *S = cast<StmtVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002789 if (!S)
2790 continue;
2791
2792 // Update the current cursor.
2793 CXCursor Cursor = MakeCXCursor(S, StmtParent, TU, RegionOfInterest);
2794 if (!IsInRegionOfInterest(Cursor))
2795 continue;
2796 switch (Visitor(Cursor, Parent, ClientData)) {
2797 case CXChildVisit_Break: return true;
2798 case CXChildVisit_Continue: break;
2799 case CXChildVisit_Recurse:
2800 if (PostChildrenVisitor)
Craig Topper69186e72014-06-08 08:38:04 +00002801 WL.push_back(PostChildrenVisit(nullptr, Cursor));
Guy Benyei11169dd2012-12-18 14:30:41 +00002802 EnqueueWorkList(WL, S);
2803 break;
2804 }
2805 continue;
2806 }
2807 case VisitorJob::MemberExprPartsKind: {
2808 // Handle the other pieces in the MemberExpr besides the base.
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002809 const MemberExpr *M = cast<MemberExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002810
2811 // Visit the nested-name-specifier
2812 if (NestedNameSpecifierLoc QualifierLoc = M->getQualifierLoc())
2813 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2814 return true;
2815
2816 // Visit the declaration name.
2817 if (VisitDeclarationNameInfo(M->getMemberNameInfo()))
2818 return true;
2819
2820 // Visit the explicitly-specified template arguments, if any.
2821 if (M->hasExplicitTemplateArgs()) {
2822 for (const TemplateArgumentLoc *Arg = M->getTemplateArgs(),
2823 *ArgEnd = Arg + M->getNumTemplateArgs();
2824 Arg != ArgEnd; ++Arg) {
2825 if (VisitTemplateArgumentLoc(*Arg))
2826 return true;
2827 }
2828 }
2829 continue;
2830 }
2831 case VisitorJob::DeclRefExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002832 const DeclRefExpr *DR = cast<DeclRefExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002833 // Visit nested-name-specifier, if present.
2834 if (NestedNameSpecifierLoc QualifierLoc = DR->getQualifierLoc())
2835 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2836 return true;
2837 // Visit declaration name.
2838 if (VisitDeclarationNameInfo(DR->getNameInfo()))
2839 return true;
2840 continue;
2841 }
2842 case VisitorJob::OverloadExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002843 const OverloadExpr *O = cast<OverloadExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002844 // Visit the nested-name-specifier.
2845 if (NestedNameSpecifierLoc QualifierLoc = O->getQualifierLoc())
2846 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2847 return true;
2848 // Visit the declaration name.
2849 if (VisitDeclarationNameInfo(O->getNameInfo()))
2850 return true;
2851 // Visit the overloaded declaration reference.
2852 if (Visit(MakeCursorOverloadedDeclRef(O, TU)))
2853 return true;
2854 continue;
2855 }
2856 case VisitorJob::SizeOfPackExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002857 const SizeOfPackExpr *E = cast<SizeOfPackExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002858 NamedDecl *Pack = E->getPack();
2859 if (isa<TemplateTypeParmDecl>(Pack)) {
2860 if (Visit(MakeCursorTypeRef(cast<TemplateTypeParmDecl>(Pack),
2861 E->getPackLoc(), TU)))
2862 return true;
2863
2864 continue;
2865 }
2866
2867 if (isa<TemplateTemplateParmDecl>(Pack)) {
2868 if (Visit(MakeCursorTemplateRef(cast<TemplateTemplateParmDecl>(Pack),
2869 E->getPackLoc(), TU)))
2870 return true;
2871
2872 continue;
2873 }
2874
2875 // Non-type template parameter packs and function parameter packs are
2876 // treated like DeclRefExpr cursors.
2877 continue;
2878 }
2879
2880 case VisitorJob::LambdaExprPartsKind: {
2881 // Visit captures.
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002882 const LambdaExpr *E = cast<LambdaExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002883 for (LambdaExpr::capture_iterator C = E->explicit_capture_begin(),
2884 CEnd = E->explicit_capture_end();
2885 C != CEnd; ++C) {
Richard Smithba71c082013-05-16 06:20:58 +00002886 // FIXME: Lambda init-captures.
2887 if (!C->capturesVariable())
Guy Benyei11169dd2012-12-18 14:30:41 +00002888 continue;
Richard Smithba71c082013-05-16 06:20:58 +00002889
Guy Benyei11169dd2012-12-18 14:30:41 +00002890 if (Visit(MakeCursorVariableRef(C->getCapturedVar(),
2891 C->getLocation(),
2892 TU)))
2893 return true;
2894 }
2895
2896 // Visit parameters and return type, if present.
2897 if (E->hasExplicitParameters() || E->hasExplicitResultType()) {
2898 TypeLoc TL = E->getCallOperator()->getTypeSourceInfo()->getTypeLoc();
2899 if (E->hasExplicitParameters() && E->hasExplicitResultType()) {
2900 // Visit the whole type.
2901 if (Visit(TL))
2902 return true;
David Blaikie6adc78e2013-02-18 22:06:02 +00002903 } else if (FunctionProtoTypeLoc Proto =
2904 TL.getAs<FunctionProtoTypeLoc>()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002905 if (E->hasExplicitParameters()) {
2906 // Visit parameters.
Alp Tokerb3fd5cf2014-01-21 00:32:38 +00002907 for (unsigned I = 0, N = Proto.getNumParams(); I != N; ++I)
2908 if (Visit(MakeCXCursor(Proto.getParam(I), TU)))
Guy Benyei11169dd2012-12-18 14:30:41 +00002909 return true;
2910 } else {
2911 // Visit result type.
Alp Toker42a16a62014-01-25 23:51:36 +00002912 if (Visit(Proto.getReturnLoc()))
Guy Benyei11169dd2012-12-18 14:30:41 +00002913 return true;
2914 }
2915 }
2916 }
2917 break;
2918 }
2919
2920 case VisitorJob::PostChildrenVisitKind:
2921 if (PostChildrenVisitor(Parent, ClientData))
2922 return true;
2923 break;
2924 }
2925 }
2926 return false;
2927}
2928
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002929bool CursorVisitor::Visit(const Stmt *S) {
Craig Topper69186e72014-06-08 08:38:04 +00002930 VisitorWorkList *WL = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00002931 if (!WorkListFreeList.empty()) {
2932 WL = WorkListFreeList.back();
2933 WL->clear();
2934 WorkListFreeList.pop_back();
2935 }
2936 else {
2937 WL = new VisitorWorkList();
2938 WorkListCache.push_back(WL);
2939 }
2940 EnqueueWorkList(*WL, S);
2941 bool result = RunVisitorWorkList(*WL);
2942 WorkListFreeList.push_back(WL);
2943 return result;
2944}
2945
2946namespace {
Dmitri Gribenkof8579502013-01-12 19:30:44 +00002947typedef SmallVector<SourceRange, 4> RefNamePieces;
James Y Knight04ec5bf2015-12-24 02:59:37 +00002948RefNamePieces buildPieces(unsigned NameFlags, bool IsMemberRefExpr,
2949 const DeclarationNameInfo &NI, SourceRange QLoc,
2950 const SourceRange *TemplateArgsLoc = nullptr) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002951 const bool WantQualifier = NameFlags & CXNameRange_WantQualifier;
2952 const bool WantTemplateArgs = NameFlags & CXNameRange_WantTemplateArgs;
2953 const bool WantSinglePiece = NameFlags & CXNameRange_WantSinglePiece;
2954
2955 const DeclarationName::NameKind Kind = NI.getName().getNameKind();
2956
2957 RefNamePieces Pieces;
2958
2959 if (WantQualifier && QLoc.isValid())
2960 Pieces.push_back(QLoc);
2961
2962 if (Kind != DeclarationName::CXXOperatorName || IsMemberRefExpr)
2963 Pieces.push_back(NI.getLoc());
James Y Knight04ec5bf2015-12-24 02:59:37 +00002964
2965 if (WantTemplateArgs && TemplateArgsLoc && TemplateArgsLoc->isValid())
2966 Pieces.push_back(*TemplateArgsLoc);
2967
Guy Benyei11169dd2012-12-18 14:30:41 +00002968 if (Kind == DeclarationName::CXXOperatorName) {
2969 Pieces.push_back(SourceLocation::getFromRawEncoding(
2970 NI.getInfo().CXXOperatorName.BeginOpNameLoc));
2971 Pieces.push_back(SourceLocation::getFromRawEncoding(
2972 NI.getInfo().CXXOperatorName.EndOpNameLoc));
2973 }
2974
2975 if (WantSinglePiece) {
2976 SourceRange R(Pieces.front().getBegin(), Pieces.back().getEnd());
2977 Pieces.clear();
2978 Pieces.push_back(R);
2979 }
2980
2981 return Pieces;
2982}
Alexander Kornienkoab9db512015-06-22 23:07:51 +00002983}
Guy Benyei11169dd2012-12-18 14:30:41 +00002984
2985//===----------------------------------------------------------------------===//
2986// Misc. API hooks.
2987//===----------------------------------------------------------------------===//
2988
Chad Rosier05c71aa2013-03-27 18:28:23 +00002989static void fatal_error_handler(void *user_data, const std::string& reason,
2990 bool gen_crash_diag) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002991 // Write the result out to stderr avoiding errs() because raw_ostreams can
2992 // call report_fatal_error.
2993 fprintf(stderr, "LIBCLANG FATAL ERROR: %s\n", reason.c_str());
2994 ::abort();
2995}
2996
Chandler Carruth66660742014-06-27 16:37:27 +00002997namespace {
2998struct RegisterFatalErrorHandler {
2999 RegisterFatalErrorHandler() {
3000 llvm::install_fatal_error_handler(fatal_error_handler, nullptr);
3001 }
3002};
3003}
3004
3005static llvm::ManagedStatic<RegisterFatalErrorHandler> RegisterFatalErrorHandlerOnce;
3006
Guy Benyei11169dd2012-12-18 14:30:41 +00003007extern "C" {
3008CXIndex clang_createIndex(int excludeDeclarationsFromPCH,
3009 int displayDiagnostics) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003010 // We use crash recovery to make some of our APIs more reliable, implicitly
3011 // enable it.
Argyrios Kyrtzidis3701f542013-11-27 08:58:09 +00003012 if (!getenv("LIBCLANG_DISABLE_CRASH_RECOVERY"))
3013 llvm::CrashRecoveryContext::Enable();
Guy Benyei11169dd2012-12-18 14:30:41 +00003014
Chandler Carruth66660742014-06-27 16:37:27 +00003015 // Look through the managed static to trigger construction of the managed
3016 // static which registers our fatal error handler. This ensures it is only
3017 // registered once.
3018 (void)*RegisterFatalErrorHandlerOnce;
Guy Benyei11169dd2012-12-18 14:30:41 +00003019
Adrian Prantlbc068582015-07-08 01:00:30 +00003020 // Initialize targets for clang module support.
3021 llvm::InitializeAllTargets();
3022 llvm::InitializeAllTargetMCs();
3023 llvm::InitializeAllAsmPrinters();
3024 llvm::InitializeAllAsmParsers();
3025
Adrian Prantlfb2398d2015-07-17 01:19:54 +00003026 CIndexer *CIdxr = new CIndexer();
3027
Guy Benyei11169dd2012-12-18 14:30:41 +00003028 if (excludeDeclarationsFromPCH)
3029 CIdxr->setOnlyLocalDecls();
3030 if (displayDiagnostics)
3031 CIdxr->setDisplayDiagnostics();
3032
3033 if (getenv("LIBCLANG_BGPRIO_INDEX"))
3034 CIdxr->setCXGlobalOptFlags(CIdxr->getCXGlobalOptFlags() |
3035 CXGlobalOpt_ThreadBackgroundPriorityForIndexing);
3036 if (getenv("LIBCLANG_BGPRIO_EDIT"))
3037 CIdxr->setCXGlobalOptFlags(CIdxr->getCXGlobalOptFlags() |
3038 CXGlobalOpt_ThreadBackgroundPriorityForEditing);
3039
3040 return CIdxr;
3041}
3042
3043void clang_disposeIndex(CXIndex CIdx) {
3044 if (CIdx)
3045 delete static_cast<CIndexer *>(CIdx);
3046}
3047
3048void clang_CXIndex_setGlobalOptions(CXIndex CIdx, unsigned options) {
3049 if (CIdx)
3050 static_cast<CIndexer *>(CIdx)->setCXGlobalOptFlags(options);
3051}
3052
3053unsigned clang_CXIndex_getGlobalOptions(CXIndex CIdx) {
3054 if (CIdx)
3055 return static_cast<CIndexer *>(CIdx)->getCXGlobalOptFlags();
3056 return 0;
3057}
3058
3059void clang_toggleCrashRecovery(unsigned isEnabled) {
3060 if (isEnabled)
3061 llvm::CrashRecoveryContext::Enable();
3062 else
3063 llvm::CrashRecoveryContext::Disable();
3064}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003065
Guy Benyei11169dd2012-12-18 14:30:41 +00003066CXTranslationUnit clang_createTranslationUnit(CXIndex CIdx,
3067 const char *ast_filename) {
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00003068 CXTranslationUnit TU;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003069 enum CXErrorCode Result =
3070 clang_createTranslationUnit2(CIdx, ast_filename, &TU);
Reid Klecknerfd48fc62014-02-12 23:56:20 +00003071 (void)Result;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003072 assert((TU && Result == CXError_Success) ||
3073 (!TU && Result != CXError_Success));
3074 return TU;
3075}
3076
3077enum CXErrorCode clang_createTranslationUnit2(CXIndex CIdx,
3078 const char *ast_filename,
3079 CXTranslationUnit *out_TU) {
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00003080 if (out_TU)
Craig Topper69186e72014-06-08 08:38:04 +00003081 *out_TU = nullptr;
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00003082
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003083 if (!CIdx || !ast_filename || !out_TU)
3084 return CXError_InvalidArguments;
Guy Benyei11169dd2012-12-18 14:30:41 +00003085
Argyrios Kyrtzidis27021012013-05-24 22:24:07 +00003086 LOG_FUNC_SECTION {
3087 *Log << ast_filename;
3088 }
3089
Guy Benyei11169dd2012-12-18 14:30:41 +00003090 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
3091 FileSystemOptions FileSystemOpts;
3092
Justin Bognerd512c1e2014-10-15 00:33:06 +00003093 IntrusiveRefCntPtr<DiagnosticsEngine> Diags =
3094 CompilerInstance::createDiagnostics(new DiagnosticOptions());
David Blaikie6f7382d2014-08-10 19:08:04 +00003095 std::unique_ptr<ASTUnit> AU = ASTUnit::LoadFromASTFile(
Adrian Prantlfb2398d2015-07-17 01:19:54 +00003096 ast_filename, CXXIdx->getPCHContainerOperations()->getRawReader(), Diags,
Adrian Prantl6b21ab22015-08-27 19:46:20 +00003097 FileSystemOpts, /*UseDebugInfo=*/false,
3098 CXXIdx->getOnlyLocalDecls(), None,
David Blaikie6f7382d2014-08-10 19:08:04 +00003099 /*CaptureDiagnostics=*/true,
3100 /*AllowPCHWithCompilerErrors=*/true,
3101 /*UserFilesAreVolatile=*/true);
3102 *out_TU = MakeCXTranslationUnit(CXXIdx, AU.release());
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003103 return *out_TU ? CXError_Success : CXError_Failure;
Guy Benyei11169dd2012-12-18 14:30:41 +00003104}
3105
3106unsigned clang_defaultEditingTranslationUnitOptions() {
3107 return CXTranslationUnit_PrecompiledPreamble |
3108 CXTranslationUnit_CacheCompletionResults;
3109}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003110
Guy Benyei11169dd2012-12-18 14:30:41 +00003111CXTranslationUnit
3112clang_createTranslationUnitFromSourceFile(CXIndex CIdx,
3113 const char *source_filename,
3114 int num_command_line_args,
3115 const char * const *command_line_args,
3116 unsigned num_unsaved_files,
3117 struct CXUnsavedFile *unsaved_files) {
3118 unsigned Options = CXTranslationUnit_DetailedPreprocessingRecord;
3119 return clang_parseTranslationUnit(CIdx, source_filename,
3120 command_line_args, num_command_line_args,
3121 unsaved_files, num_unsaved_files,
3122 Options);
3123}
3124
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003125static CXErrorCode
3126clang_parseTranslationUnit_Impl(CXIndex CIdx, const char *source_filename,
3127 const char *const *command_line_args,
3128 int num_command_line_args,
3129 ArrayRef<CXUnsavedFile> unsaved_files,
3130 unsigned options, CXTranslationUnit *out_TU) {
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00003131 // Set up the initial return values.
3132 if (out_TU)
Craig Topper69186e72014-06-08 08:38:04 +00003133 *out_TU = nullptr;
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00003134
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003135 // Check arguments.
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003136 if (!CIdx || !out_TU)
3137 return CXError_InvalidArguments;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003138
Guy Benyei11169dd2012-12-18 14:30:41 +00003139 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
3140
3141 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
3142 setThreadBackgroundPriority();
3143
3144 bool PrecompilePreamble = options & CXTranslationUnit_PrecompiledPreamble;
Benjamin Kramer5c248d82015-12-15 09:30:31 +00003145 bool CreatePreambleOnFirstParse =
3146 options & CXTranslationUnit_CreatePreambleOnFirstParse;
Guy Benyei11169dd2012-12-18 14:30:41 +00003147 // FIXME: Add a flag for modules.
3148 TranslationUnitKind TUKind
3149 = (options & CXTranslationUnit_Incomplete)? TU_Prefix : TU_Complete;
Alp Toker8c8a8752013-12-03 06:53:35 +00003150 bool CacheCodeCompletionResults
Guy Benyei11169dd2012-12-18 14:30:41 +00003151 = options & CXTranslationUnit_CacheCompletionResults;
3152 bool IncludeBriefCommentsInCodeCompletion
3153 = options & CXTranslationUnit_IncludeBriefCommentsInCodeCompletion;
3154 bool SkipFunctionBodies = options & CXTranslationUnit_SkipFunctionBodies;
3155 bool ForSerialization = options & CXTranslationUnit_ForSerialization;
3156
3157 // Configure the diagnostics.
3158 IntrusiveRefCntPtr<DiagnosticsEngine>
Sean Silvaf1b49e22013-01-20 01:58:28 +00003159 Diags(CompilerInstance::createDiagnostics(new DiagnosticOptions));
Guy Benyei11169dd2012-12-18 14:30:41 +00003160
Manuel Klimek016c0242016-03-01 10:56:19 +00003161 if (options & CXTranslationUnit_KeepGoing)
3162 Diags->setFatalsAsError(true);
3163
Guy Benyei11169dd2012-12-18 14:30:41 +00003164 // Recover resources if we crash before exiting this function.
3165 llvm::CrashRecoveryContextCleanupRegistrar<DiagnosticsEngine,
3166 llvm::CrashRecoveryContextReleaseRefCleanup<DiagnosticsEngine> >
Alp Tokerf994cef2014-07-05 03:08:06 +00003167 DiagCleanup(Diags.get());
Guy Benyei11169dd2012-12-18 14:30:41 +00003168
Ahmed Charlesb8984322014-03-07 20:03:18 +00003169 std::unique_ptr<std::vector<ASTUnit::RemappedFile>> RemappedFiles(
3170 new std::vector<ASTUnit::RemappedFile>());
Guy Benyei11169dd2012-12-18 14:30:41 +00003171
3172 // Recover resources if we crash before exiting this function.
3173 llvm::CrashRecoveryContextCleanupRegistrar<
3174 std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
3175
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003176 for (auto &UF : unsaved_files) {
Rafael Espindolad87f8d72014-08-27 20:03:29 +00003177 std::unique_ptr<llvm::MemoryBuffer> MB =
Alp Toker9d85b182014-07-07 01:23:14 +00003178 llvm::MemoryBuffer::getMemBufferCopy(getContents(UF), UF.Filename);
Rafael Espindolad87f8d72014-08-27 20:03:29 +00003179 RemappedFiles->push_back(std::make_pair(UF.Filename, MB.release()));
Guy Benyei11169dd2012-12-18 14:30:41 +00003180 }
3181
Ahmed Charlesb8984322014-03-07 20:03:18 +00003182 std::unique_ptr<std::vector<const char *>> Args(
3183 new std::vector<const char *>());
Guy Benyei11169dd2012-12-18 14:30:41 +00003184
3185 // Recover resources if we crash before exiting this method.
3186 llvm::CrashRecoveryContextCleanupRegistrar<std::vector<const char*> >
3187 ArgsCleanup(Args.get());
3188
3189 // Since the Clang C library is primarily used by batch tools dealing with
3190 // (often very broken) source code, where spell-checking can have a
3191 // significant negative impact on performance (particularly when
3192 // precompiled headers are involved), we disable it by default.
3193 // Only do this if we haven't found a spell-checking-related argument.
3194 bool FoundSpellCheckingArgument = false;
3195 for (int I = 0; I != num_command_line_args; ++I) {
3196 if (strcmp(command_line_args[I], "-fno-spell-checking") == 0 ||
3197 strcmp(command_line_args[I], "-fspell-checking") == 0) {
3198 FoundSpellCheckingArgument = true;
3199 break;
3200 }
3201 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003202 Args->insert(Args->end(), command_line_args,
3203 command_line_args + num_command_line_args);
3204
Benjamin Kramerc02670e2015-11-18 16:14:27 +00003205 if (!FoundSpellCheckingArgument)
3206 Args->insert(Args->begin() + 1, "-fno-spell-checking");
3207
Guy Benyei11169dd2012-12-18 14:30:41 +00003208 // The 'source_filename' argument is optional. If the caller does not
3209 // specify it then it is assumed that the source file is specified
3210 // in the actual argument list.
3211 // Put the source file after command_line_args otherwise if '-x' flag is
3212 // present it will be unused.
3213 if (source_filename)
3214 Args->push_back(source_filename);
3215
3216 // Do we need the detailed preprocessing record?
3217 if (options & CXTranslationUnit_DetailedPreprocessingRecord) {
3218 Args->push_back("-Xclang");
3219 Args->push_back("-detailed-preprocessing-record");
3220 }
3221
3222 unsigned NumErrors = Diags->getClient()->getNumErrors();
Ahmed Charlesb8984322014-03-07 20:03:18 +00003223 std::unique_ptr<ASTUnit> ErrUnit;
Benjamin Kramer5c248d82015-12-15 09:30:31 +00003224 // Unless the user specified that they want the preamble on the first parse
3225 // set it up to be created on the first reparse. This makes the first parse
3226 // faster, trading for a slower (first) reparse.
3227 unsigned PrecompilePreambleAfterNParses =
3228 !PrecompilePreamble ? 0 : 2 - CreatePreambleOnFirstParse;
Ahmed Charlesb8984322014-03-07 20:03:18 +00003229 std::unique_ptr<ASTUnit> Unit(ASTUnit::LoadFromCommandLine(
Adrian Prantlbb165fb2015-06-20 18:53:08 +00003230 Args->data(), Args->data() + Args->size(),
3231 CXXIdx->getPCHContainerOperations(), Diags,
Ahmed Charlesb8984322014-03-07 20:03:18 +00003232 CXXIdx->getClangResourcesPath(), CXXIdx->getOnlyLocalDecls(),
3233 /*CaptureDiagnostics=*/true, *RemappedFiles.get(),
Benjamin Kramer5c248d82015-12-15 09:30:31 +00003234 /*RemappedFilesKeepOriginalName=*/true, PrecompilePreambleAfterNParses,
3235 TUKind, CacheCodeCompletionResults, IncludeBriefCommentsInCodeCompletion,
Ahmed Charlesb8984322014-03-07 20:03:18 +00003236 /*AllowPCHWithCompilerErrors=*/true, SkipFunctionBodies,
Argyrios Kyrtzidisa3e2ff12015-11-20 03:36:21 +00003237 /*UserFilesAreVolatile=*/true, ForSerialization,
3238 CXXIdx->getPCHContainerOperations()->getRawReader().getFormat(),
3239 &ErrUnit));
Guy Benyei11169dd2012-12-18 14:30:41 +00003240
Artem Belevich0ff05cd2015-07-13 23:27:56 +00003241 // Early failures in LoadFromCommandLine may return with ErrUnit unset.
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003242 if (!Unit && !ErrUnit)
3243 return CXError_ASTReadError;
Artem Belevich0ff05cd2015-07-13 23:27:56 +00003244
Guy Benyei11169dd2012-12-18 14:30:41 +00003245 if (NumErrors != Diags->getClient()->getNumErrors()) {
3246 // Make sure to check that 'Unit' is non-NULL.
3247 if (CXXIdx->getDisplayDiagnostics())
3248 printDiagsToStderr(Unit ? Unit.get() : ErrUnit.get());
3249 }
3250
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003251 if (isASTReadError(Unit ? Unit.get() : ErrUnit.get()))
3252 return CXError_ASTReadError;
3253
3254 *out_TU = MakeCXTranslationUnit(CXXIdx, Unit.release());
3255 return *out_TU ? CXError_Success : CXError_Failure;
Guy Benyei11169dd2012-12-18 14:30:41 +00003256}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003257
3258CXTranslationUnit
3259clang_parseTranslationUnit(CXIndex CIdx,
3260 const char *source_filename,
3261 const char *const *command_line_args,
3262 int num_command_line_args,
3263 struct CXUnsavedFile *unsaved_files,
3264 unsigned num_unsaved_files,
3265 unsigned options) {
3266 CXTranslationUnit TU;
3267 enum CXErrorCode Result = clang_parseTranslationUnit2(
3268 CIdx, source_filename, command_line_args, num_command_line_args,
3269 unsaved_files, num_unsaved_files, options, &TU);
Reid Kleckner6eaf05a2014-02-13 01:19:59 +00003270 (void)Result;
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00003271 assert((TU && Result == CXError_Success) ||
3272 (!TU && Result != CXError_Success));
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003273 return TU;
3274}
3275
3276enum CXErrorCode clang_parseTranslationUnit2(
Benjamin Kramerc02670e2015-11-18 16:14:27 +00003277 CXIndex CIdx, const char *source_filename,
3278 const char *const *command_line_args, int num_command_line_args,
3279 struct CXUnsavedFile *unsaved_files, unsigned num_unsaved_files,
3280 unsigned options, CXTranslationUnit *out_TU) {
3281 SmallVector<const char *, 4> Args;
3282 Args.push_back("clang");
3283 Args.append(command_line_args, command_line_args + num_command_line_args);
3284 return clang_parseTranslationUnit2FullArgv(
3285 CIdx, source_filename, Args.data(), Args.size(), unsaved_files,
3286 num_unsaved_files, options, out_TU);
3287}
3288
3289enum CXErrorCode clang_parseTranslationUnit2FullArgv(
3290 CXIndex CIdx, const char *source_filename,
3291 const char *const *command_line_args, int num_command_line_args,
3292 struct CXUnsavedFile *unsaved_files, unsigned num_unsaved_files,
3293 unsigned options, CXTranslationUnit *out_TU) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00003294 LOG_FUNC_SECTION {
3295 *Log << source_filename << ": ";
3296 for (int i = 0; i != num_command_line_args; ++i)
3297 *Log << command_line_args[i] << " ";
3298 }
3299
Alp Toker9d85b182014-07-07 01:23:14 +00003300 if (num_unsaved_files && !unsaved_files)
3301 return CXError_InvalidArguments;
3302
Alp Toker5c532982014-07-07 22:42:03 +00003303 CXErrorCode result = CXError_Failure;
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003304 auto ParseTranslationUnitImpl = [=, &result] {
3305 result = clang_parseTranslationUnit_Impl(
3306 CIdx, source_filename, command_line_args, num_command_line_args,
3307 llvm::makeArrayRef(unsaved_files, num_unsaved_files), options, out_TU);
3308 };
Guy Benyei11169dd2012-12-18 14:30:41 +00003309 llvm::CrashRecoveryContext CRC;
3310
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003311 if (!RunSafely(CRC, ParseTranslationUnitImpl)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003312 fprintf(stderr, "libclang: crash detected during parsing: {\n");
3313 fprintf(stderr, " 'source_filename' : '%s'\n", source_filename);
3314 fprintf(stderr, " 'command_line_args' : [");
3315 for (int i = 0; i != num_command_line_args; ++i) {
3316 if (i)
3317 fprintf(stderr, ", ");
3318 fprintf(stderr, "'%s'", command_line_args[i]);
3319 }
3320 fprintf(stderr, "],\n");
3321 fprintf(stderr, " 'unsaved_files' : [");
3322 for (unsigned i = 0; i != num_unsaved_files; ++i) {
3323 if (i)
3324 fprintf(stderr, ", ");
3325 fprintf(stderr, "('%s', '...', %ld)", unsaved_files[i].Filename,
3326 unsaved_files[i].Length);
3327 }
3328 fprintf(stderr, "],\n");
3329 fprintf(stderr, " 'options' : %d,\n", options);
3330 fprintf(stderr, "}\n");
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003331
3332 return CXError_Crashed;
Guy Benyei11169dd2012-12-18 14:30:41 +00003333 } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003334 if (CXTranslationUnit *TU = out_TU)
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003335 PrintLibclangResourceUsage(*TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003336 }
Alp Toker5c532982014-07-07 22:42:03 +00003337
3338 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003339}
3340
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003341CXString clang_Type_getObjCEncoding(CXType CT) {
3342 CXTranslationUnit tu = static_cast<CXTranslationUnit>(CT.data[1]);
3343 ASTContext &Ctx = getASTUnit(tu)->getASTContext();
3344 std::string encoding;
3345 Ctx.getObjCEncodingForType(QualType::getFromOpaquePtr(CT.data[0]),
3346 encoding);
3347
3348 return cxstring::createDup(encoding);
3349}
3350
3351static const IdentifierInfo *getMacroIdentifier(CXCursor C) {
3352 if (C.kind == CXCursor_MacroDefinition) {
3353 if (const MacroDefinitionRecord *MDR = getCursorMacroDefinition(C))
3354 return MDR->getName();
3355 } else if (C.kind == CXCursor_MacroExpansion) {
3356 MacroExpansionCursor ME = getCursorMacroExpansion(C);
3357 return ME.getName();
3358 }
3359 return nullptr;
3360}
3361
3362unsigned clang_Cursor_isMacroFunctionLike(CXCursor C) {
3363 const IdentifierInfo *II = getMacroIdentifier(C);
3364 if (!II) {
3365 return false;
3366 }
3367 ASTUnit *ASTU = getCursorASTUnit(C);
3368 Preprocessor &PP = ASTU->getPreprocessor();
3369 if (const MacroInfo *MI = PP.getMacroInfo(II))
3370 return MI->isFunctionLike();
3371 return false;
3372}
3373
3374unsigned clang_Cursor_isMacroBuiltin(CXCursor C) {
3375 const IdentifierInfo *II = getMacroIdentifier(C);
3376 if (!II) {
3377 return false;
3378 }
3379 ASTUnit *ASTU = getCursorASTUnit(C);
3380 Preprocessor &PP = ASTU->getPreprocessor();
3381 if (const MacroInfo *MI = PP.getMacroInfo(II))
3382 return MI->isBuiltinMacro();
3383 return false;
3384}
3385
3386unsigned clang_Cursor_isFunctionInlined(CXCursor C) {
3387 const Decl *D = getCursorDecl(C);
3388 const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(D);
3389 if (!FD) {
3390 return false;
3391 }
3392 return FD->isInlined();
3393}
3394
3395static StringLiteral* getCFSTR_value(CallExpr *callExpr) {
3396 if (callExpr->getNumArgs() != 1) {
3397 return nullptr;
3398 }
3399
3400 StringLiteral *S = nullptr;
3401 auto *arg = callExpr->getArg(0);
3402 if (arg->getStmtClass() == Stmt::ImplicitCastExprClass) {
3403 ImplicitCastExpr *I = static_cast<ImplicitCastExpr *>(arg);
3404 auto *subExpr = I->getSubExprAsWritten();
3405
3406 if(subExpr->getStmtClass() != Stmt::StringLiteralClass){
3407 return nullptr;
3408 }
3409
3410 S = static_cast<StringLiteral *>(I->getSubExprAsWritten());
3411 } else if (arg->getStmtClass() == Stmt::StringLiteralClass) {
3412 S = static_cast<StringLiteral *>(callExpr->getArg(0));
3413 } else {
3414 return nullptr;
3415 }
3416 return S;
3417}
3418
3419typedef struct {
3420 CXEvalResultKind EvalType;
3421 union {
3422 int intVal;
3423 double floatVal;
3424 char *stringVal;
3425 } EvalData;
3426} ExprEvalResult;
3427
3428void clang_EvalResult_dispose(CXEvalResult E) {
3429 ExprEvalResult *ER = (ExprEvalResult *)E;
3430 if (ER) {
3431 CXEvalResultKind evalType = ER->EvalType;
3432
3433 if (evalType != CXEval_UnExposed && evalType != CXEval_Float &&
3434 evalType != CXEval_Int && ER->EvalData.stringVal) {
3435 free((void *) ER->EvalData.stringVal);
3436 }
3437 free((void *)ER);
3438 }
3439}
3440
3441CXEvalResultKind clang_EvalResult_getKind(CXEvalResult E) {
3442 if (!E) {
3443 return CXEval_UnExposed;
3444 }
3445 return ((ExprEvalResult *)E)->EvalType;
3446}
3447
3448int clang_EvalResult_getAsInt(CXEvalResult E) {
3449 if (!E) {
3450 return 0;
3451 }
3452 return ((ExprEvalResult *)E)->EvalData.intVal;
3453}
3454
3455double clang_EvalResult_getAsDouble(CXEvalResult E) {
3456 if (!E) {
3457 return 0;
3458 }
3459 return ((ExprEvalResult *)E)->EvalData.floatVal;
3460}
3461
3462const char* clang_EvalResult_getAsStr(CXEvalResult E) {
3463 if (!E) {
3464 return nullptr;
3465 }
3466 return ((ExprEvalResult *)E)->EvalData.stringVal;
3467}
3468
3469static const ExprEvalResult* evaluateExpr(Expr *expr, CXCursor C) {
3470 Expr::EvalResult ER;
3471 ASTContext &ctx = getCursorContext(C);
3472 if (!expr) {
3473 return nullptr;
3474 }
3475 expr = expr->IgnoreParens();
3476 bool res = expr->EvaluateAsRValue(ER, ctx);
3477 QualType rettype;
3478 CallExpr *callExpr;
3479 ExprEvalResult *result = (ExprEvalResult *) malloc(sizeof(ExprEvalResult));
3480 if (!result) {
3481 return nullptr;
3482 }
3483 result->EvalType = CXEval_UnExposed;
3484
3485 if (res) {
3486
3487 if (ER.Val.isInt()) {
3488 result->EvalType = CXEval_Int;
3489 result->EvalData.intVal = ER.Val.getInt().getExtValue();
3490 return result;
3491 } else if (ER.Val.isFloat()) {
3492
3493 llvm::SmallVector<char, 100> Buffer;
3494 ER.Val.getFloat().toString(Buffer);
3495 std::string floatStr(Buffer.data(), Buffer.size());
3496 result->EvalType = CXEval_Float;
3497 bool ignored;
3498 llvm::APFloat apFloat = ER.Val.getFloat();
3499 apFloat.convert(llvm::APFloat::IEEEdouble,
3500 llvm::APFloat::rmNearestTiesToEven, &ignored);
3501 result->EvalData.floatVal = apFloat.convertToDouble();
3502 return result;
3503
3504 } else if (expr->getStmtClass() == Stmt::ImplicitCastExprClass) {
3505
3506 const ImplicitCastExpr *I = dyn_cast<ImplicitCastExpr>(expr);
3507 auto *subExpr = I->getSubExprAsWritten();
3508 if (subExpr->getStmtClass() == Stmt::StringLiteralClass ||
3509 subExpr->getStmtClass() == Stmt::ObjCStringLiteralClass) {
3510
3511 const StringLiteral *StrE = nullptr;
3512 const ObjCStringLiteral *ObjCExpr;
3513 ObjCExpr = dyn_cast<ObjCStringLiteral>(subExpr);
3514
3515 if (ObjCExpr) {
3516 StrE = ObjCExpr->getString();
3517 result->EvalType = CXEval_ObjCStrLiteral;
3518 } else {
3519 StrE = cast<StringLiteral>(I->getSubExprAsWritten());
3520 result->EvalType = CXEval_StrLiteral;
3521 }
3522
3523 std::string strRef(StrE->getString().str());
3524 result->EvalData.stringVal = (char *)malloc(strRef.size()+1);
3525 strncpy((char*)result->EvalData.stringVal, strRef.c_str(),
3526 strRef.size());
3527 result->EvalData.stringVal[strRef.size()] = '\0';
3528 return result;
3529 }
3530
3531 } else if (expr->getStmtClass() == Stmt::ObjCStringLiteralClass ||
3532 expr->getStmtClass() == Stmt::StringLiteralClass) {
3533
3534 const StringLiteral *StrE = nullptr;
3535 const ObjCStringLiteral *ObjCExpr;
3536 ObjCExpr = dyn_cast<ObjCStringLiteral>(expr);
3537
3538 if (ObjCExpr) {
3539 StrE = ObjCExpr->getString();
3540 result->EvalType = CXEval_ObjCStrLiteral;
3541 } else {
3542 StrE = cast<StringLiteral>(expr);
3543 result->EvalType = CXEval_StrLiteral;
3544 }
3545
3546 std::string strRef(StrE->getString().str());
3547 result->EvalData.stringVal = (char *)malloc(strRef.size()+1);
3548 strncpy((char*)result->EvalData.stringVal, strRef.c_str(),
3549 strRef.size());
3550 result->EvalData.stringVal[strRef.size()] = '\0';
3551 return result;
3552
3553 } else if (expr->getStmtClass() == Stmt::CStyleCastExprClass) {
3554
3555 CStyleCastExpr *CC = static_cast<CStyleCastExpr *>(expr);
3556
3557 rettype = CC->getType();
3558 if (rettype.getAsString() == "CFStringRef" &&
3559 CC->getSubExpr()->getStmtClass() == Stmt::CallExprClass) {
3560
3561 callExpr = static_cast<CallExpr *>(CC->getSubExpr());
3562 StringLiteral* S = getCFSTR_value(callExpr);
3563 if (S) {
3564 std::string strLiteral(S->getString().str());
3565 result->EvalType = CXEval_CFStr;
3566
3567 result->EvalData.stringVal = (char *)malloc(strLiteral.size()+1);
3568 strncpy((char*)result->EvalData.stringVal, strLiteral.c_str(),
3569 strLiteral.size());
3570 result->EvalData.stringVal[strLiteral.size()] = '\0';
3571 return result;
3572 }
3573 }
3574
3575 } else if (expr->getStmtClass() == Stmt::CallExprClass) {
3576
3577 callExpr = static_cast<CallExpr *>(expr);
3578 rettype = callExpr->getCallReturnType(ctx);
3579
3580 if (rettype->isVectorType() || callExpr->getNumArgs() > 1) {
3581 return nullptr;
3582 }
3583 if (rettype->isIntegralType(ctx) || rettype->isRealFloatingType()) {
3584 if(callExpr->getNumArgs() == 1 &&
3585 !callExpr->getArg(0)->getType()->isIntegralType(ctx)){
3586
3587 return nullptr;
3588 }
3589 } else if(rettype.getAsString() == "CFStringRef") {
3590
3591 StringLiteral* S = getCFSTR_value(callExpr);
3592 if (S) {
3593 std::string strLiteral(S->getString().str());
3594 result->EvalType = CXEval_CFStr;
3595 result->EvalData.stringVal = (char *)malloc(strLiteral.size()+1);
3596 strncpy((char*)result->EvalData.stringVal, strLiteral.c_str(),
3597 strLiteral.size());
3598 result->EvalData.stringVal[strLiteral.size()] = '\0';
3599 return result;
3600 }
3601 }
3602
3603 } else if (expr->getStmtClass() == Stmt::DeclRefExprClass) {
3604
3605 DeclRefExpr *D = static_cast<DeclRefExpr *>(expr);
3606 ValueDecl *V = D->getDecl();
3607 if (V->getKind() == Decl::Function) {
3608 std::string strName(V->getNameAsString());
3609 result->EvalType = CXEval_Other;
3610 result->EvalData.stringVal = (char *)malloc(strName.size()+1);
3611 strncpy((char*)result->EvalData.stringVal, strName.c_str(),
3612 strName.size());
3613 result->EvalData.stringVal[strName.size()] = '\0';
3614 return result;
3615 }
3616 }
3617
3618 }
3619
3620 clang_EvalResult_dispose((CXEvalResult *)result);
3621 return nullptr;
3622}
3623
3624CXEvalResult clang_Cursor_Evaluate(CXCursor C) {
3625 const Decl *D = getCursorDecl(C);
3626 if (D) {
3627 const Expr *expr = nullptr;
3628 if (auto *Var = dyn_cast<VarDecl>(D)) {
3629 expr = Var->getInit();
3630 } else if (auto *Field = dyn_cast<FieldDecl>(D)) {
3631 expr = Field->getInClassInitializer();
3632 }
3633 if (expr)
Aaron Ballman01dc1572016-01-20 15:25:30 +00003634 return const_cast<CXEvalResult>(reinterpret_cast<const void *>(
3635 evaluateExpr(const_cast<Expr *>(expr), C)));
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003636 return nullptr;
3637 }
3638
3639 const CompoundStmt *compoundStmt = dyn_cast_or_null<CompoundStmt>(getCursorStmt(C));
3640 if (compoundStmt) {
3641 Expr *expr = nullptr;
3642 for (auto *bodyIterator : compoundStmt->body()) {
3643 if ((expr = dyn_cast<Expr>(bodyIterator))) {
3644 break;
3645 }
3646 }
3647 if (expr)
Aaron Ballman01dc1572016-01-20 15:25:30 +00003648 return const_cast<CXEvalResult>(
3649 reinterpret_cast<const void *>(evaluateExpr(expr, C)));
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003650 }
3651 return nullptr;
3652}
3653
3654unsigned clang_Cursor_hasAttrs(CXCursor C) {
3655 const Decl *D = getCursorDecl(C);
3656 if (!D) {
3657 return 0;
3658 }
3659
3660 if (D->hasAttrs()) {
3661 return 1;
3662 }
3663
3664 return 0;
3665}
Guy Benyei11169dd2012-12-18 14:30:41 +00003666unsigned clang_defaultSaveOptions(CXTranslationUnit TU) {
3667 return CXSaveTranslationUnit_None;
3668}
3669
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003670static CXSaveError clang_saveTranslationUnit_Impl(CXTranslationUnit TU,
3671 const char *FileName,
3672 unsigned options) {
3673 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00003674 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
3675 setThreadBackgroundPriority();
3676
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003677 bool hadError = cxtu::getASTUnit(TU)->Save(FileName);
3678 return hadError ? CXSaveError_Unknown : CXSaveError_None;
Guy Benyei11169dd2012-12-18 14:30:41 +00003679}
3680
3681int clang_saveTranslationUnit(CXTranslationUnit TU, const char *FileName,
3682 unsigned options) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00003683 LOG_FUNC_SECTION {
3684 *Log << TU << ' ' << FileName;
3685 }
3686
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003687 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003688 LOG_BAD_TU(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003689 return CXSaveError_InvalidTU;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003690 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003691
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003692 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003693 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
3694 if (!CXXUnit->hasSema())
3695 return CXSaveError_InvalidTU;
3696
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003697 CXSaveError result;
3698 auto SaveTranslationUnitImpl = [=, &result]() {
3699 result = clang_saveTranslationUnit_Impl(TU, FileName, options);
3700 };
Guy Benyei11169dd2012-12-18 14:30:41 +00003701
3702 if (!CXXUnit->getDiagnostics().hasUnrecoverableErrorOccurred() ||
3703 getenv("LIBCLANG_NOTHREADS")) {
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003704 SaveTranslationUnitImpl();
Guy Benyei11169dd2012-12-18 14:30:41 +00003705
3706 if (getenv("LIBCLANG_RESOURCE_USAGE"))
3707 PrintLibclangResourceUsage(TU);
3708
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003709 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003710 }
3711
3712 // We have an AST that has invalid nodes due to compiler errors.
3713 // Use a crash recovery thread for protection.
3714
3715 llvm::CrashRecoveryContext CRC;
3716
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003717 if (!RunSafely(CRC, SaveTranslationUnitImpl)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003718 fprintf(stderr, "libclang: crash detected during AST saving: {\n");
3719 fprintf(stderr, " 'filename' : '%s'\n", FileName);
3720 fprintf(stderr, " 'options' : %d,\n", options);
3721 fprintf(stderr, "}\n");
3722
3723 return CXSaveError_Unknown;
3724
3725 } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
3726 PrintLibclangResourceUsage(TU);
3727 }
3728
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003729 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003730}
3731
3732void clang_disposeTranslationUnit(CXTranslationUnit CTUnit) {
3733 if (CTUnit) {
3734 // If the translation unit has been marked as unsafe to free, just discard
3735 // it.
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003736 ASTUnit *Unit = cxtu::getASTUnit(CTUnit);
3737 if (Unit && Unit->isUnsafeToFree())
Guy Benyei11169dd2012-12-18 14:30:41 +00003738 return;
3739
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003740 delete cxtu::getASTUnit(CTUnit);
Dmitri Gribenkob95b3f12013-01-26 22:44:19 +00003741 delete CTUnit->StringPool;
Guy Benyei11169dd2012-12-18 14:30:41 +00003742 delete static_cast<CXDiagnosticSetImpl *>(CTUnit->Diagnostics);
3743 disposeOverridenCXCursorsPool(CTUnit->OverridenCursorsPool);
Dmitri Gribenko9e605112013-11-13 22:16:51 +00003744 delete CTUnit->CommentToXML;
Guy Benyei11169dd2012-12-18 14:30:41 +00003745 delete CTUnit;
3746 }
3747}
3748
3749unsigned clang_defaultReparseOptions(CXTranslationUnit TU) {
3750 return CXReparse_None;
3751}
3752
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003753static CXErrorCode
3754clang_reparseTranslationUnit_Impl(CXTranslationUnit TU,
3755 ArrayRef<CXUnsavedFile> unsaved_files,
3756 unsigned options) {
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003757 // Check arguments.
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003758 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003759 LOG_BAD_TU(TU);
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003760 return CXError_InvalidArguments;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003761 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003762
3763 // Reset the associated diagnostics.
3764 delete static_cast<CXDiagnosticSetImpl*>(TU->Diagnostics);
Craig Topper69186e72014-06-08 08:38:04 +00003765 TU->Diagnostics = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00003766
Dmitri Gribenko183436e2013-01-26 21:49:50 +00003767 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00003768 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
3769 setThreadBackgroundPriority();
3770
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003771 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003772 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
Ahmed Charlesb8984322014-03-07 20:03:18 +00003773
3774 std::unique_ptr<std::vector<ASTUnit::RemappedFile>> RemappedFiles(
3775 new std::vector<ASTUnit::RemappedFile>());
3776
Guy Benyei11169dd2012-12-18 14:30:41 +00003777 // Recover resources if we crash before exiting this function.
3778 llvm::CrashRecoveryContextCleanupRegistrar<
3779 std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
Alp Toker9d85b182014-07-07 01:23:14 +00003780
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003781 for (auto &UF : unsaved_files) {
Rafael Espindolad87f8d72014-08-27 20:03:29 +00003782 std::unique_ptr<llvm::MemoryBuffer> MB =
Alp Toker9d85b182014-07-07 01:23:14 +00003783 llvm::MemoryBuffer::getMemBufferCopy(getContents(UF), UF.Filename);
Rafael Espindolad87f8d72014-08-27 20:03:29 +00003784 RemappedFiles->push_back(std::make_pair(UF.Filename, MB.release()));
Guy Benyei11169dd2012-12-18 14:30:41 +00003785 }
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003786
Adrian Prantlbb165fb2015-06-20 18:53:08 +00003787 if (!CXXUnit->Reparse(CXXIdx->getPCHContainerOperations(),
3788 *RemappedFiles.get()))
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003789 return CXError_Success;
3790 if (isASTReadError(CXXUnit))
3791 return CXError_ASTReadError;
3792 return CXError_Failure;
Guy Benyei11169dd2012-12-18 14:30:41 +00003793}
3794
3795int clang_reparseTranslationUnit(CXTranslationUnit TU,
3796 unsigned num_unsaved_files,
3797 struct CXUnsavedFile *unsaved_files,
3798 unsigned options) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00003799 LOG_FUNC_SECTION {
3800 *Log << TU;
3801 }
3802
Alp Toker9d85b182014-07-07 01:23:14 +00003803 if (num_unsaved_files && !unsaved_files)
3804 return CXError_InvalidArguments;
3805
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003806 CXErrorCode result;
3807 auto ReparseTranslationUnitImpl = [=, &result]() {
3808 result = clang_reparseTranslationUnit_Impl(
3809 TU, llvm::makeArrayRef(unsaved_files, num_unsaved_files), options);
3810 };
Guy Benyei11169dd2012-12-18 14:30:41 +00003811
3812 if (getenv("LIBCLANG_NOTHREADS")) {
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003813 ReparseTranslationUnitImpl();
Alp Toker5c532982014-07-07 22:42:03 +00003814 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003815 }
3816
3817 llvm::CrashRecoveryContext CRC;
3818
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003819 if (!RunSafely(CRC, ReparseTranslationUnitImpl)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003820 fprintf(stderr, "libclang: crash detected during reparsing\n");
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003821 cxtu::getASTUnit(TU)->setUnsafeToFree(true);
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003822 return CXError_Crashed;
Guy Benyei11169dd2012-12-18 14:30:41 +00003823 } else if (getenv("LIBCLANG_RESOURCE_USAGE"))
3824 PrintLibclangResourceUsage(TU);
3825
Alp Toker5c532982014-07-07 22:42:03 +00003826 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003827}
3828
3829
3830CXString clang_getTranslationUnitSpelling(CXTranslationUnit CTUnit) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003831 if (isNotUsableTU(CTUnit)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003832 LOG_BAD_TU(CTUnit);
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003833 return cxstring::createEmpty();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003834 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003835
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003836 ASTUnit *CXXUnit = cxtu::getASTUnit(CTUnit);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003837 return cxstring::createDup(CXXUnit->getOriginalSourceFileName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003838}
3839
3840CXCursor clang_getTranslationUnitCursor(CXTranslationUnit TU) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003841 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003842 LOG_BAD_TU(TU);
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00003843 return clang_getNullCursor();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003844 }
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00003845
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003846 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003847 return MakeCXCursor(CXXUnit->getASTContext().getTranslationUnitDecl(), TU);
3848}
3849
3850} // end: extern "C"
3851
3852//===----------------------------------------------------------------------===//
3853// CXFile Operations.
3854//===----------------------------------------------------------------------===//
3855
3856extern "C" {
3857CXString clang_getFileName(CXFile SFile) {
3858 if (!SFile)
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00003859 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00003860
3861 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003862 return cxstring::createRef(FEnt->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003863}
3864
3865time_t clang_getFileTime(CXFile SFile) {
3866 if (!SFile)
3867 return 0;
3868
3869 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
3870 return FEnt->getModificationTime();
3871}
3872
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003873CXFile clang_getFile(CXTranslationUnit TU, const char *file_name) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003874 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003875 LOG_BAD_TU(TU);
Craig Topper69186e72014-06-08 08:38:04 +00003876 return nullptr;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003877 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003878
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003879 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003880
3881 FileManager &FMgr = CXXUnit->getFileManager();
3882 return const_cast<FileEntry *>(FMgr.getFile(file_name));
3883}
3884
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003885unsigned clang_isFileMultipleIncludeGuarded(CXTranslationUnit TU,
3886 CXFile file) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003887 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003888 LOG_BAD_TU(TU);
3889 return 0;
3890 }
3891
3892 if (!file)
Guy Benyei11169dd2012-12-18 14:30:41 +00003893 return 0;
3894
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003895 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003896 FileEntry *FEnt = static_cast<FileEntry *>(file);
3897 return CXXUnit->getPreprocessor().getHeaderSearchInfo()
3898 .isFileMultipleIncludeGuarded(FEnt);
3899}
3900
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003901int clang_getFileUniqueID(CXFile file, CXFileUniqueID *outID) {
3902 if (!file || !outID)
3903 return 1;
3904
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003905 FileEntry *FEnt = static_cast<FileEntry *>(file);
Rafael Espindolaf8f91b82013-08-01 21:42:11 +00003906 const llvm::sys::fs::UniqueID &ID = FEnt->getUniqueID();
3907 outID->data[0] = ID.getDevice();
3908 outID->data[1] = ID.getFile();
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003909 outID->data[2] = FEnt->getModificationTime();
3910 return 0;
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003911}
3912
Argyrios Kyrtzidisac3997e2014-08-16 00:26:19 +00003913int clang_File_isEqual(CXFile file1, CXFile file2) {
3914 if (file1 == file2)
3915 return true;
3916
3917 if (!file1 || !file2)
3918 return false;
3919
3920 FileEntry *FEnt1 = static_cast<FileEntry *>(file1);
3921 FileEntry *FEnt2 = static_cast<FileEntry *>(file2);
3922 return FEnt1->getUniqueID() == FEnt2->getUniqueID();
3923}
3924
Guy Benyei11169dd2012-12-18 14:30:41 +00003925} // end: extern "C"
3926
3927//===----------------------------------------------------------------------===//
3928// CXCursor Operations.
3929//===----------------------------------------------------------------------===//
3930
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003931static const Decl *getDeclFromExpr(const Stmt *E) {
3932 if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003933 return getDeclFromExpr(CE->getSubExpr());
3934
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003935 if (const DeclRefExpr *RefExpr = dyn_cast<DeclRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003936 return RefExpr->getDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003937 if (const MemberExpr *ME = dyn_cast<MemberExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003938 return ME->getMemberDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003939 if (const ObjCIvarRefExpr *RE = dyn_cast<ObjCIvarRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003940 return RE->getDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003941 if (const ObjCPropertyRefExpr *PRE = dyn_cast<ObjCPropertyRefExpr>(E)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003942 if (PRE->isExplicitProperty())
3943 return PRE->getExplicitProperty();
3944 // It could be messaging both getter and setter as in:
3945 // ++myobj.myprop;
3946 // in which case prefer to associate the setter since it is less obvious
3947 // from inspecting the source that the setter is going to get called.
3948 if (PRE->isMessagingSetter())
3949 return PRE->getImplicitPropertySetter();
3950 return PRE->getImplicitPropertyGetter();
3951 }
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003952 if (const PseudoObjectExpr *POE = dyn_cast<PseudoObjectExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003953 return getDeclFromExpr(POE->getSyntacticForm());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003954 if (const OpaqueValueExpr *OVE = dyn_cast<OpaqueValueExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003955 if (Expr *Src = OVE->getSourceExpr())
3956 return getDeclFromExpr(Src);
3957
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003958 if (const CallExpr *CE = dyn_cast<CallExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003959 return getDeclFromExpr(CE->getCallee());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003960 if (const CXXConstructExpr *CE = dyn_cast<CXXConstructExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003961 if (!CE->isElidable())
3962 return CE->getConstructor();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003963 if (const ObjCMessageExpr *OME = dyn_cast<ObjCMessageExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003964 return OME->getMethodDecl();
3965
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003966 if (const ObjCProtocolExpr *PE = dyn_cast<ObjCProtocolExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003967 return PE->getProtocol();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003968 if (const SubstNonTypeTemplateParmPackExpr *NTTP
Guy Benyei11169dd2012-12-18 14:30:41 +00003969 = dyn_cast<SubstNonTypeTemplateParmPackExpr>(E))
3970 return NTTP->getParameterPack();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003971 if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003972 if (isa<NonTypeTemplateParmDecl>(SizeOfPack->getPack()) ||
3973 isa<ParmVarDecl>(SizeOfPack->getPack()))
3974 return SizeOfPack->getPack();
Craig Topper69186e72014-06-08 08:38:04 +00003975
3976 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00003977}
3978
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003979static SourceLocation getLocationFromExpr(const Expr *E) {
3980 if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003981 return getLocationFromExpr(CE->getSubExpr());
3982
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003983 if (const ObjCMessageExpr *Msg = dyn_cast<ObjCMessageExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003984 return /*FIXME:*/Msg->getLeftLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003985 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003986 return DRE->getLocation();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003987 if (const MemberExpr *Member = dyn_cast<MemberExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003988 return Member->getMemberLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003989 if (const ObjCIvarRefExpr *Ivar = dyn_cast<ObjCIvarRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003990 return Ivar->getLocation();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003991 if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003992 return SizeOfPack->getPackLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003993 if (const ObjCPropertyRefExpr *PropRef = dyn_cast<ObjCPropertyRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003994 return PropRef->getLocation();
3995
3996 return E->getLocStart();
3997}
3998
3999extern "C" {
4000
4001unsigned clang_visitChildren(CXCursor parent,
4002 CXCursorVisitor visitor,
4003 CXClientData client_data) {
4004 CursorVisitor CursorVis(getCursorTU(parent), visitor, client_data,
4005 /*VisitPreprocessorLast=*/false);
4006 return CursorVis.VisitChildren(parent);
4007}
4008
4009#ifndef __has_feature
4010#define __has_feature(x) 0
4011#endif
4012#if __has_feature(blocks)
4013typedef enum CXChildVisitResult
4014 (^CXCursorVisitorBlock)(CXCursor cursor, CXCursor parent);
4015
4016static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
4017 CXClientData client_data) {
4018 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
4019 return block(cursor, parent);
4020}
4021#else
4022// If we are compiled with a compiler that doesn't have native blocks support,
4023// define and call the block manually, so the
4024typedef struct _CXChildVisitResult
4025{
4026 void *isa;
4027 int flags;
4028 int reserved;
4029 enum CXChildVisitResult(*invoke)(struct _CXChildVisitResult*, CXCursor,
4030 CXCursor);
4031} *CXCursorVisitorBlock;
4032
4033static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
4034 CXClientData client_data) {
4035 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
4036 return block->invoke(block, cursor, parent);
4037}
4038#endif
4039
4040
4041unsigned clang_visitChildrenWithBlock(CXCursor parent,
4042 CXCursorVisitorBlock block) {
4043 return clang_visitChildren(parent, visitWithBlock, block);
4044}
4045
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004046static CXString getDeclSpelling(const Decl *D) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004047 if (!D)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00004048 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00004049
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004050 const NamedDecl *ND = dyn_cast<NamedDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00004051 if (!ND) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004052 if (const ObjCPropertyImplDecl *PropImpl =
4053 dyn_cast<ObjCPropertyImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004054 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004055 return cxstring::createDup(Property->getIdentifier()->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00004056
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004057 if (const ImportDecl *ImportD = dyn_cast<ImportDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004058 if (Module *Mod = ImportD->getImportedModule())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004059 return cxstring::createDup(Mod->getFullModuleName());
Guy Benyei11169dd2012-12-18 14:30:41 +00004060
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00004061 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00004062 }
4063
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004064 if (const ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(ND))
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004065 return cxstring::createDup(OMD->getSelector().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00004066
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004067 if (const ObjCCategoryImplDecl *CIMP = dyn_cast<ObjCCategoryImplDecl>(ND))
Guy Benyei11169dd2012-12-18 14:30:41 +00004068 // No, this isn't the same as the code below. getIdentifier() is non-virtual
4069 // and returns different names. NamedDecl returns the class name and
4070 // ObjCCategoryImplDecl returns the category name.
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004071 return cxstring::createRef(CIMP->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00004072
4073 if (isa<UsingDirectiveDecl>(D))
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00004074 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00004075
4076 SmallString<1024> S;
4077 llvm::raw_svector_ostream os(S);
4078 ND->printName(os);
4079
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004080 return cxstring::createDup(os.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00004081}
4082
4083CXString clang_getCursorSpelling(CXCursor C) {
4084 if (clang_isTranslationUnit(C.kind))
Dmitri Gribenko2c173b42013-01-11 19:28:44 +00004085 return clang_getTranslationUnitSpelling(getCursorTU(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00004086
4087 if (clang_isReference(C.kind)) {
4088 switch (C.kind) {
4089 case CXCursor_ObjCSuperClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004090 const ObjCInterfaceDecl *Super = getCursorObjCSuperClassRef(C).first;
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004091 return cxstring::createRef(Super->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00004092 }
4093 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004094 const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004095 return cxstring::createRef(Class->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00004096 }
4097 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004098 const ObjCProtocolDecl *OID = getCursorObjCProtocolRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00004099 assert(OID && "getCursorSpelling(): Missing protocol decl");
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004100 return cxstring::createRef(OID->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00004101 }
4102 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004103 const CXXBaseSpecifier *B = getCursorCXXBaseSpecifier(C);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004104 return cxstring::createDup(B->getType().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00004105 }
4106 case CXCursor_TypeRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004107 const TypeDecl *Type = getCursorTypeRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00004108 assert(Type && "Missing type decl");
4109
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004110 return cxstring::createDup(getCursorContext(C).getTypeDeclType(Type).
Guy Benyei11169dd2012-12-18 14:30:41 +00004111 getAsString());
4112 }
4113 case CXCursor_TemplateRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004114 const TemplateDecl *Template = getCursorTemplateRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00004115 assert(Template && "Missing template decl");
4116
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004117 return cxstring::createDup(Template->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00004118 }
4119
4120 case CXCursor_NamespaceRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004121 const NamedDecl *NS = getCursorNamespaceRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00004122 assert(NS && "Missing namespace decl");
4123
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004124 return cxstring::createDup(NS->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00004125 }
4126
4127 case CXCursor_MemberRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004128 const FieldDecl *Field = getCursorMemberRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00004129 assert(Field && "Missing member decl");
4130
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004131 return cxstring::createDup(Field->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00004132 }
4133
4134 case CXCursor_LabelRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004135 const LabelStmt *Label = getCursorLabelRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00004136 assert(Label && "Missing label");
4137
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004138 return cxstring::createRef(Label->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00004139 }
4140
4141 case CXCursor_OverloadedDeclRef: {
4142 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004143 if (const Decl *D = Storage.dyn_cast<const Decl *>()) {
4144 if (const NamedDecl *ND = dyn_cast<NamedDecl>(D))
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004145 return cxstring::createDup(ND->getNameAsString());
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00004146 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00004147 }
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004148 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004149 return cxstring::createDup(E->getName().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00004150 OverloadedTemplateStorage *Ovl
4151 = Storage.get<OverloadedTemplateStorage*>();
4152 if (Ovl->size() == 0)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00004153 return cxstring::createEmpty();
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004154 return cxstring::createDup((*Ovl->begin())->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00004155 }
4156
4157 case CXCursor_VariableRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004158 const VarDecl *Var = getCursorVariableRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00004159 assert(Var && "Missing variable decl");
4160
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004161 return cxstring::createDup(Var->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00004162 }
4163
4164 default:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004165 return cxstring::createRef("<not implemented>");
Guy Benyei11169dd2012-12-18 14:30:41 +00004166 }
4167 }
4168
4169 if (clang_isExpression(C.kind)) {
Argyrios Kyrtzidis3227d862014-03-03 19:40:52 +00004170 const Expr *E = getCursorExpr(C);
4171
4172 if (C.kind == CXCursor_ObjCStringLiteral ||
4173 C.kind == CXCursor_StringLiteral) {
4174 const StringLiteral *SLit;
4175 if (const ObjCStringLiteral *OSL = dyn_cast<ObjCStringLiteral>(E)) {
4176 SLit = OSL->getString();
4177 } else {
4178 SLit = cast<StringLiteral>(E);
4179 }
4180 SmallString<256> Buf;
4181 llvm::raw_svector_ostream OS(Buf);
4182 SLit->outputString(OS);
4183 return cxstring::createDup(OS.str());
4184 }
4185
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004186 const Decl *D = getDeclFromExpr(getCursorExpr(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00004187 if (D)
4188 return getDeclSpelling(D);
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00004189 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00004190 }
4191
4192 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004193 const Stmt *S = getCursorStmt(C);
4194 if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S))
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004195 return cxstring::createRef(Label->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00004196
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00004197 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00004198 }
4199
4200 if (C.kind == CXCursor_MacroExpansion)
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004201 return cxstring::createRef(getCursorMacroExpansion(C).getName()
Guy Benyei11169dd2012-12-18 14:30:41 +00004202 ->getNameStart());
4203
4204 if (C.kind == CXCursor_MacroDefinition)
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004205 return cxstring::createRef(getCursorMacroDefinition(C)->getName()
Guy Benyei11169dd2012-12-18 14:30:41 +00004206 ->getNameStart());
4207
4208 if (C.kind == CXCursor_InclusionDirective)
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004209 return cxstring::createDup(getCursorInclusionDirective(C)->getFileName());
Guy Benyei11169dd2012-12-18 14:30:41 +00004210
4211 if (clang_isDeclaration(C.kind))
4212 return getDeclSpelling(getCursorDecl(C));
4213
4214 if (C.kind == CXCursor_AnnotateAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00004215 const AnnotateAttr *AA = cast<AnnotateAttr>(cxcursor::getCursorAttr(C));
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004216 return cxstring::createDup(AA->getAnnotation());
Guy Benyei11169dd2012-12-18 14:30:41 +00004217 }
4218
4219 if (C.kind == CXCursor_AsmLabelAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00004220 const AsmLabelAttr *AA = cast<AsmLabelAttr>(cxcursor::getCursorAttr(C));
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004221 return cxstring::createDup(AA->getLabel());
Guy Benyei11169dd2012-12-18 14:30:41 +00004222 }
4223
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00004224 if (C.kind == CXCursor_PackedAttr) {
4225 return cxstring::createRef("packed");
4226 }
4227
Saleem Abdulrasool79c69712015-09-05 18:53:43 +00004228 if (C.kind == CXCursor_VisibilityAttr) {
4229 const VisibilityAttr *AA = cast<VisibilityAttr>(cxcursor::getCursorAttr(C));
4230 switch (AA->getVisibility()) {
4231 case VisibilityAttr::VisibilityType::Default:
4232 return cxstring::createRef("default");
4233 case VisibilityAttr::VisibilityType::Hidden:
4234 return cxstring::createRef("hidden");
4235 case VisibilityAttr::VisibilityType::Protected:
4236 return cxstring::createRef("protected");
4237 }
4238 llvm_unreachable("unknown visibility type");
4239 }
4240
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00004241 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00004242}
4243
4244CXSourceRange clang_Cursor_getSpellingNameRange(CXCursor C,
4245 unsigned pieceIndex,
4246 unsigned options) {
4247 if (clang_Cursor_isNull(C))
4248 return clang_getNullRange();
4249
4250 ASTContext &Ctx = getCursorContext(C);
4251
4252 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004253 const Stmt *S = getCursorStmt(C);
4254 if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004255 if (pieceIndex > 0)
4256 return clang_getNullRange();
4257 return cxloc::translateSourceRange(Ctx, Label->getIdentLoc());
4258 }
4259
4260 return clang_getNullRange();
4261 }
4262
4263 if (C.kind == CXCursor_ObjCMessageExpr) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004264 if (const ObjCMessageExpr *
Guy Benyei11169dd2012-12-18 14:30:41 +00004265 ME = dyn_cast_or_null<ObjCMessageExpr>(getCursorExpr(C))) {
4266 if (pieceIndex >= ME->getNumSelectorLocs())
4267 return clang_getNullRange();
4268 return cxloc::translateSourceRange(Ctx, ME->getSelectorLoc(pieceIndex));
4269 }
4270 }
4271
4272 if (C.kind == CXCursor_ObjCInstanceMethodDecl ||
4273 C.kind == CXCursor_ObjCClassMethodDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004274 if (const ObjCMethodDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00004275 MD = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(C))) {
4276 if (pieceIndex >= MD->getNumSelectorLocs())
4277 return clang_getNullRange();
4278 return cxloc::translateSourceRange(Ctx, MD->getSelectorLoc(pieceIndex));
4279 }
4280 }
4281
4282 if (C.kind == CXCursor_ObjCCategoryDecl ||
4283 C.kind == CXCursor_ObjCCategoryImplDecl) {
4284 if (pieceIndex > 0)
4285 return clang_getNullRange();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004286 if (const ObjCCategoryDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00004287 CD = dyn_cast_or_null<ObjCCategoryDecl>(getCursorDecl(C)))
4288 return cxloc::translateSourceRange(Ctx, CD->getCategoryNameLoc());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004289 if (const ObjCCategoryImplDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00004290 CID = dyn_cast_or_null<ObjCCategoryImplDecl>(getCursorDecl(C)))
4291 return cxloc::translateSourceRange(Ctx, CID->getCategoryNameLoc());
4292 }
4293
4294 if (C.kind == CXCursor_ModuleImportDecl) {
4295 if (pieceIndex > 0)
4296 return clang_getNullRange();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004297 if (const ImportDecl *ImportD =
4298 dyn_cast_or_null<ImportDecl>(getCursorDecl(C))) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004299 ArrayRef<SourceLocation> Locs = ImportD->getIdentifierLocs();
4300 if (!Locs.empty())
4301 return cxloc::translateSourceRange(Ctx,
4302 SourceRange(Locs.front(), Locs.back()));
4303 }
4304 return clang_getNullRange();
4305 }
4306
Argyrios Kyrtzidisa2a1e532014-08-26 20:23:26 +00004307 if (C.kind == CXCursor_CXXMethod || C.kind == CXCursor_Destructor ||
4308 C.kind == CXCursor_ConversionFunction) {
4309 if (pieceIndex > 0)
4310 return clang_getNullRange();
4311 if (const FunctionDecl *FD =
4312 dyn_cast_or_null<FunctionDecl>(getCursorDecl(C))) {
4313 DeclarationNameInfo FunctionName = FD->getNameInfo();
4314 return cxloc::translateSourceRange(Ctx, FunctionName.getSourceRange());
4315 }
4316 return clang_getNullRange();
4317 }
4318
Guy Benyei11169dd2012-12-18 14:30:41 +00004319 // FIXME: A CXCursor_InclusionDirective should give the location of the
4320 // filename, but we don't keep track of this.
4321
4322 // FIXME: A CXCursor_AnnotateAttr should give the location of the annotation
4323 // but we don't keep track of this.
4324
4325 // FIXME: A CXCursor_AsmLabelAttr should give the location of the label
4326 // but we don't keep track of this.
4327
4328 // Default handling, give the location of the cursor.
4329
4330 if (pieceIndex > 0)
4331 return clang_getNullRange();
4332
4333 CXSourceLocation CXLoc = clang_getCursorLocation(C);
4334 SourceLocation Loc = cxloc::translateSourceLocation(CXLoc);
4335 return cxloc::translateSourceRange(Ctx, Loc);
4336}
4337
Eli Bendersky44a206f2014-07-31 18:04:56 +00004338CXString clang_Cursor_getMangling(CXCursor C) {
4339 if (clang_isInvalid(C.kind) || !clang_isDeclaration(C.kind))
4340 return cxstring::createEmpty();
4341
Eli Bendersky44a206f2014-07-31 18:04:56 +00004342 // Mangling only works for functions and variables.
Eli Bendersky79759592014-08-01 15:01:10 +00004343 const Decl *D = getCursorDecl(C);
Eli Bendersky44a206f2014-07-31 18:04:56 +00004344 if (!D || !(isa<FunctionDecl>(D) || isa<VarDecl>(D)))
4345 return cxstring::createEmpty();
4346
Argyrios Kyrtzidisca741ce2016-02-14 22:30:14 +00004347 ASTContext &Ctx = D->getASTContext();
4348 index::CodegenNameGenerator CGNameGen(Ctx);
4349 return cxstring::createDup(CGNameGen.getName(D));
Eli Bendersky44a206f2014-07-31 18:04:56 +00004350}
4351
Saleem Abdulrasool60034432015-11-12 03:57:22 +00004352CXStringSet *clang_Cursor_getCXXManglings(CXCursor C) {
4353 if (clang_isInvalid(C.kind) || !clang_isDeclaration(C.kind))
4354 return nullptr;
4355
4356 const Decl *D = getCursorDecl(C);
4357 if (!(isa<CXXRecordDecl>(D) || isa<CXXMethodDecl>(D)))
4358 return nullptr;
4359
Argyrios Kyrtzidisca741ce2016-02-14 22:30:14 +00004360 ASTContext &Ctx = D->getASTContext();
4361 index::CodegenNameGenerator CGNameGen(Ctx);
4362 std::vector<std::string> Manglings = CGNameGen.getAllManglings(D);
Saleem Abdulrasool60034432015-11-12 03:57:22 +00004363 return cxstring::createSet(Manglings);
4364}
4365
Guy Benyei11169dd2012-12-18 14:30:41 +00004366CXString clang_getCursorDisplayName(CXCursor C) {
4367 if (!clang_isDeclaration(C.kind))
4368 return clang_getCursorSpelling(C);
4369
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004370 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004371 if (!D)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00004372 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00004373
4374 PrintingPolicy Policy = getCursorContext(C).getPrintingPolicy();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004375 if (const FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004376 D = FunTmpl->getTemplatedDecl();
4377
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004378 if (const FunctionDecl *Function = dyn_cast<FunctionDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004379 SmallString<64> Str;
4380 llvm::raw_svector_ostream OS(Str);
4381 OS << *Function;
4382 if (Function->getPrimaryTemplate())
4383 OS << "<>";
4384 OS << "(";
4385 for (unsigned I = 0, N = Function->getNumParams(); I != N; ++I) {
4386 if (I)
4387 OS << ", ";
4388 OS << Function->getParamDecl(I)->getType().getAsString(Policy);
4389 }
4390
4391 if (Function->isVariadic()) {
4392 if (Function->getNumParams())
4393 OS << ", ";
4394 OS << "...";
4395 }
4396 OS << ")";
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004397 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00004398 }
4399
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004400 if (const ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004401 SmallString<64> Str;
4402 llvm::raw_svector_ostream OS(Str);
4403 OS << *ClassTemplate;
4404 OS << "<";
4405 TemplateParameterList *Params = ClassTemplate->getTemplateParameters();
4406 for (unsigned I = 0, N = Params->size(); I != N; ++I) {
4407 if (I)
4408 OS << ", ";
4409
4410 NamedDecl *Param = Params->getParam(I);
4411 if (Param->getIdentifier()) {
4412 OS << Param->getIdentifier()->getName();
4413 continue;
4414 }
4415
4416 // There is no parameter name, which makes this tricky. Try to come up
4417 // with something useful that isn't too long.
4418 if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(Param))
4419 OS << (TTP->wasDeclaredWithTypename()? "typename" : "class");
4420 else if (NonTypeTemplateParmDecl *NTTP
4421 = dyn_cast<NonTypeTemplateParmDecl>(Param))
4422 OS << NTTP->getType().getAsString(Policy);
4423 else
4424 OS << "template<...> class";
4425 }
4426
4427 OS << ">";
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004428 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00004429 }
4430
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004431 if (const ClassTemplateSpecializationDecl *ClassSpec
Guy Benyei11169dd2012-12-18 14:30:41 +00004432 = dyn_cast<ClassTemplateSpecializationDecl>(D)) {
4433 // If the type was explicitly written, use that.
4434 if (TypeSourceInfo *TSInfo = ClassSpec->getTypeAsWritten())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004435 return cxstring::createDup(TSInfo->getType().getAsString(Policy));
Guy Benyei11169dd2012-12-18 14:30:41 +00004436
Benjamin Kramer9170e912013-02-22 15:46:01 +00004437 SmallString<128> Str;
Guy Benyei11169dd2012-12-18 14:30:41 +00004438 llvm::raw_svector_ostream OS(Str);
4439 OS << *ClassSpec;
Benjamin Kramer9170e912013-02-22 15:46:01 +00004440 TemplateSpecializationType::PrintTemplateArgumentList(OS,
Guy Benyei11169dd2012-12-18 14:30:41 +00004441 ClassSpec->getTemplateArgs().data(),
4442 ClassSpec->getTemplateArgs().size(),
4443 Policy);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004444 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00004445 }
4446
4447 return clang_getCursorSpelling(C);
4448}
4449
4450CXString clang_getCursorKindSpelling(enum CXCursorKind Kind) {
4451 switch (Kind) {
4452 case CXCursor_FunctionDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004453 return cxstring::createRef("FunctionDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004454 case CXCursor_TypedefDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004455 return cxstring::createRef("TypedefDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004456 case CXCursor_EnumDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004457 return cxstring::createRef("EnumDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004458 case CXCursor_EnumConstantDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004459 return cxstring::createRef("EnumConstantDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004460 case CXCursor_StructDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004461 return cxstring::createRef("StructDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004462 case CXCursor_UnionDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004463 return cxstring::createRef("UnionDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004464 case CXCursor_ClassDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004465 return cxstring::createRef("ClassDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004466 case CXCursor_FieldDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004467 return cxstring::createRef("FieldDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004468 case CXCursor_VarDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004469 return cxstring::createRef("VarDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004470 case CXCursor_ParmDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004471 return cxstring::createRef("ParmDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004472 case CXCursor_ObjCInterfaceDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004473 return cxstring::createRef("ObjCInterfaceDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004474 case CXCursor_ObjCCategoryDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004475 return cxstring::createRef("ObjCCategoryDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004476 case CXCursor_ObjCProtocolDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004477 return cxstring::createRef("ObjCProtocolDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004478 case CXCursor_ObjCPropertyDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004479 return cxstring::createRef("ObjCPropertyDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004480 case CXCursor_ObjCIvarDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004481 return cxstring::createRef("ObjCIvarDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004482 case CXCursor_ObjCInstanceMethodDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004483 return cxstring::createRef("ObjCInstanceMethodDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004484 case CXCursor_ObjCClassMethodDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004485 return cxstring::createRef("ObjCClassMethodDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004486 case CXCursor_ObjCImplementationDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004487 return cxstring::createRef("ObjCImplementationDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004488 case CXCursor_ObjCCategoryImplDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004489 return cxstring::createRef("ObjCCategoryImplDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004490 case CXCursor_CXXMethod:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004491 return cxstring::createRef("CXXMethod");
Guy Benyei11169dd2012-12-18 14:30:41 +00004492 case CXCursor_UnexposedDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004493 return cxstring::createRef("UnexposedDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004494 case CXCursor_ObjCSuperClassRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004495 return cxstring::createRef("ObjCSuperClassRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004496 case CXCursor_ObjCProtocolRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004497 return cxstring::createRef("ObjCProtocolRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004498 case CXCursor_ObjCClassRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004499 return cxstring::createRef("ObjCClassRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004500 case CXCursor_TypeRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004501 return cxstring::createRef("TypeRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004502 case CXCursor_TemplateRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004503 return cxstring::createRef("TemplateRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004504 case CXCursor_NamespaceRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004505 return cxstring::createRef("NamespaceRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004506 case CXCursor_MemberRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004507 return cxstring::createRef("MemberRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004508 case CXCursor_LabelRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004509 return cxstring::createRef("LabelRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004510 case CXCursor_OverloadedDeclRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004511 return cxstring::createRef("OverloadedDeclRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004512 case CXCursor_VariableRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004513 return cxstring::createRef("VariableRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004514 case CXCursor_IntegerLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004515 return cxstring::createRef("IntegerLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00004516 case CXCursor_FloatingLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004517 return cxstring::createRef("FloatingLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00004518 case CXCursor_ImaginaryLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004519 return cxstring::createRef("ImaginaryLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00004520 case CXCursor_StringLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004521 return cxstring::createRef("StringLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00004522 case CXCursor_CharacterLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004523 return cxstring::createRef("CharacterLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00004524 case CXCursor_ParenExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004525 return cxstring::createRef("ParenExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004526 case CXCursor_UnaryOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004527 return cxstring::createRef("UnaryOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00004528 case CXCursor_ArraySubscriptExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004529 return cxstring::createRef("ArraySubscriptExpr");
Alexey Bataev1a3320e2015-08-25 14:24:04 +00004530 case CXCursor_OMPArraySectionExpr:
4531 return cxstring::createRef("OMPArraySectionExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004532 case CXCursor_BinaryOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004533 return cxstring::createRef("BinaryOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00004534 case CXCursor_CompoundAssignOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004535 return cxstring::createRef("CompoundAssignOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00004536 case CXCursor_ConditionalOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004537 return cxstring::createRef("ConditionalOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00004538 case CXCursor_CStyleCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004539 return cxstring::createRef("CStyleCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004540 case CXCursor_CompoundLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004541 return cxstring::createRef("CompoundLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004542 case CXCursor_InitListExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004543 return cxstring::createRef("InitListExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004544 case CXCursor_AddrLabelExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004545 return cxstring::createRef("AddrLabelExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004546 case CXCursor_StmtExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004547 return cxstring::createRef("StmtExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004548 case CXCursor_GenericSelectionExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004549 return cxstring::createRef("GenericSelectionExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004550 case CXCursor_GNUNullExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004551 return cxstring::createRef("GNUNullExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004552 case CXCursor_CXXStaticCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004553 return cxstring::createRef("CXXStaticCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004554 case CXCursor_CXXDynamicCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004555 return cxstring::createRef("CXXDynamicCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004556 case CXCursor_CXXReinterpretCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004557 return cxstring::createRef("CXXReinterpretCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004558 case CXCursor_CXXConstCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004559 return cxstring::createRef("CXXConstCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004560 case CXCursor_CXXFunctionalCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004561 return cxstring::createRef("CXXFunctionalCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004562 case CXCursor_CXXTypeidExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004563 return cxstring::createRef("CXXTypeidExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004564 case CXCursor_CXXBoolLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004565 return cxstring::createRef("CXXBoolLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004566 case CXCursor_CXXNullPtrLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004567 return cxstring::createRef("CXXNullPtrLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004568 case CXCursor_CXXThisExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004569 return cxstring::createRef("CXXThisExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004570 case CXCursor_CXXThrowExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004571 return cxstring::createRef("CXXThrowExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004572 case CXCursor_CXXNewExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004573 return cxstring::createRef("CXXNewExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004574 case CXCursor_CXXDeleteExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004575 return cxstring::createRef("CXXDeleteExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004576 case CXCursor_UnaryExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004577 return cxstring::createRef("UnaryExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004578 case CXCursor_ObjCStringLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004579 return cxstring::createRef("ObjCStringLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00004580 case CXCursor_ObjCBoolLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004581 return cxstring::createRef("ObjCBoolLiteralExpr");
Argyrios Kyrtzidisc2233be2013-04-23 17:57:17 +00004582 case CXCursor_ObjCSelfExpr:
4583 return cxstring::createRef("ObjCSelfExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004584 case CXCursor_ObjCEncodeExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004585 return cxstring::createRef("ObjCEncodeExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004586 case CXCursor_ObjCSelectorExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004587 return cxstring::createRef("ObjCSelectorExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004588 case CXCursor_ObjCProtocolExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004589 return cxstring::createRef("ObjCProtocolExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004590 case CXCursor_ObjCBridgedCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004591 return cxstring::createRef("ObjCBridgedCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004592 case CXCursor_BlockExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004593 return cxstring::createRef("BlockExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004594 case CXCursor_PackExpansionExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004595 return cxstring::createRef("PackExpansionExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004596 case CXCursor_SizeOfPackExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004597 return cxstring::createRef("SizeOfPackExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004598 case CXCursor_LambdaExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004599 return cxstring::createRef("LambdaExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004600 case CXCursor_UnexposedExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004601 return cxstring::createRef("UnexposedExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004602 case CXCursor_DeclRefExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004603 return cxstring::createRef("DeclRefExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004604 case CXCursor_MemberRefExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004605 return cxstring::createRef("MemberRefExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004606 case CXCursor_CallExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004607 return cxstring::createRef("CallExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004608 case CXCursor_ObjCMessageExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004609 return cxstring::createRef("ObjCMessageExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004610 case CXCursor_UnexposedStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004611 return cxstring::createRef("UnexposedStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004612 case CXCursor_DeclStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004613 return cxstring::createRef("DeclStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004614 case CXCursor_LabelStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004615 return cxstring::createRef("LabelStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004616 case CXCursor_CompoundStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004617 return cxstring::createRef("CompoundStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004618 case CXCursor_CaseStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004619 return cxstring::createRef("CaseStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004620 case CXCursor_DefaultStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004621 return cxstring::createRef("DefaultStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004622 case CXCursor_IfStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004623 return cxstring::createRef("IfStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004624 case CXCursor_SwitchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004625 return cxstring::createRef("SwitchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004626 case CXCursor_WhileStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004627 return cxstring::createRef("WhileStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004628 case CXCursor_DoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004629 return cxstring::createRef("DoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004630 case CXCursor_ForStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004631 return cxstring::createRef("ForStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004632 case CXCursor_GotoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004633 return cxstring::createRef("GotoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004634 case CXCursor_IndirectGotoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004635 return cxstring::createRef("IndirectGotoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004636 case CXCursor_ContinueStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004637 return cxstring::createRef("ContinueStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004638 case CXCursor_BreakStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004639 return cxstring::createRef("BreakStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004640 case CXCursor_ReturnStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004641 return cxstring::createRef("ReturnStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004642 case CXCursor_GCCAsmStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004643 return cxstring::createRef("GCCAsmStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004644 case CXCursor_MSAsmStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004645 return cxstring::createRef("MSAsmStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004646 case CXCursor_ObjCAtTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004647 return cxstring::createRef("ObjCAtTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004648 case CXCursor_ObjCAtCatchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004649 return cxstring::createRef("ObjCAtCatchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004650 case CXCursor_ObjCAtFinallyStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004651 return cxstring::createRef("ObjCAtFinallyStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004652 case CXCursor_ObjCAtThrowStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004653 return cxstring::createRef("ObjCAtThrowStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004654 case CXCursor_ObjCAtSynchronizedStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004655 return cxstring::createRef("ObjCAtSynchronizedStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004656 case CXCursor_ObjCAutoreleasePoolStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004657 return cxstring::createRef("ObjCAutoreleasePoolStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004658 case CXCursor_ObjCForCollectionStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004659 return cxstring::createRef("ObjCForCollectionStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004660 case CXCursor_CXXCatchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004661 return cxstring::createRef("CXXCatchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004662 case CXCursor_CXXTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004663 return cxstring::createRef("CXXTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004664 case CXCursor_CXXForRangeStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004665 return cxstring::createRef("CXXForRangeStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004666 case CXCursor_SEHTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004667 return cxstring::createRef("SEHTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004668 case CXCursor_SEHExceptStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004669 return cxstring::createRef("SEHExceptStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004670 case CXCursor_SEHFinallyStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004671 return cxstring::createRef("SEHFinallyStmt");
Nico Weber9b982072014-07-07 00:12:30 +00004672 case CXCursor_SEHLeaveStmt:
4673 return cxstring::createRef("SEHLeaveStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004674 case CXCursor_NullStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004675 return cxstring::createRef("NullStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004676 case CXCursor_InvalidFile:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004677 return cxstring::createRef("InvalidFile");
Guy Benyei11169dd2012-12-18 14:30:41 +00004678 case CXCursor_InvalidCode:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004679 return cxstring::createRef("InvalidCode");
Guy Benyei11169dd2012-12-18 14:30:41 +00004680 case CXCursor_NoDeclFound:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004681 return cxstring::createRef("NoDeclFound");
Guy Benyei11169dd2012-12-18 14:30:41 +00004682 case CXCursor_NotImplemented:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004683 return cxstring::createRef("NotImplemented");
Guy Benyei11169dd2012-12-18 14:30:41 +00004684 case CXCursor_TranslationUnit:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004685 return cxstring::createRef("TranslationUnit");
Guy Benyei11169dd2012-12-18 14:30:41 +00004686 case CXCursor_UnexposedAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004687 return cxstring::createRef("UnexposedAttr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004688 case CXCursor_IBActionAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004689 return cxstring::createRef("attribute(ibaction)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004690 case CXCursor_IBOutletAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004691 return cxstring::createRef("attribute(iboutlet)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004692 case CXCursor_IBOutletCollectionAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004693 return cxstring::createRef("attribute(iboutletcollection)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004694 case CXCursor_CXXFinalAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004695 return cxstring::createRef("attribute(final)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004696 case CXCursor_CXXOverrideAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004697 return cxstring::createRef("attribute(override)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004698 case CXCursor_AnnotateAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004699 return cxstring::createRef("attribute(annotate)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004700 case CXCursor_AsmLabelAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004701 return cxstring::createRef("asm label");
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00004702 case CXCursor_PackedAttr:
4703 return cxstring::createRef("attribute(packed)");
Joey Gouly81228382014-05-01 15:41:58 +00004704 case CXCursor_PureAttr:
4705 return cxstring::createRef("attribute(pure)");
4706 case CXCursor_ConstAttr:
4707 return cxstring::createRef("attribute(const)");
4708 case CXCursor_NoDuplicateAttr:
4709 return cxstring::createRef("attribute(noduplicate)");
Eli Bendersky2581e662014-05-28 19:29:58 +00004710 case CXCursor_CUDAConstantAttr:
4711 return cxstring::createRef("attribute(constant)");
4712 case CXCursor_CUDADeviceAttr:
4713 return cxstring::createRef("attribute(device)");
4714 case CXCursor_CUDAGlobalAttr:
4715 return cxstring::createRef("attribute(global)");
4716 case CXCursor_CUDAHostAttr:
4717 return cxstring::createRef("attribute(host)");
Eli Bendersky9b071472014-08-08 14:59:00 +00004718 case CXCursor_CUDASharedAttr:
4719 return cxstring::createRef("attribute(shared)");
Saleem Abdulrasool79c69712015-09-05 18:53:43 +00004720 case CXCursor_VisibilityAttr:
4721 return cxstring::createRef("attribute(visibility)");
Saleem Abdulrasool8aa0b802015-12-10 18:45:18 +00004722 case CXCursor_DLLExport:
4723 return cxstring::createRef("attribute(dllexport)");
4724 case CXCursor_DLLImport:
4725 return cxstring::createRef("attribute(dllimport)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004726 case CXCursor_PreprocessingDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004727 return cxstring::createRef("preprocessing directive");
Guy Benyei11169dd2012-12-18 14:30:41 +00004728 case CXCursor_MacroDefinition:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004729 return cxstring::createRef("macro definition");
Guy Benyei11169dd2012-12-18 14:30:41 +00004730 case CXCursor_MacroExpansion:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004731 return cxstring::createRef("macro expansion");
Guy Benyei11169dd2012-12-18 14:30:41 +00004732 case CXCursor_InclusionDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004733 return cxstring::createRef("inclusion directive");
Guy Benyei11169dd2012-12-18 14:30:41 +00004734 case CXCursor_Namespace:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004735 return cxstring::createRef("Namespace");
Guy Benyei11169dd2012-12-18 14:30:41 +00004736 case CXCursor_LinkageSpec:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004737 return cxstring::createRef("LinkageSpec");
Guy Benyei11169dd2012-12-18 14:30:41 +00004738 case CXCursor_CXXBaseSpecifier:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004739 return cxstring::createRef("C++ base class specifier");
Guy Benyei11169dd2012-12-18 14:30:41 +00004740 case CXCursor_Constructor:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004741 return cxstring::createRef("CXXConstructor");
Guy Benyei11169dd2012-12-18 14:30:41 +00004742 case CXCursor_Destructor:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004743 return cxstring::createRef("CXXDestructor");
Guy Benyei11169dd2012-12-18 14:30:41 +00004744 case CXCursor_ConversionFunction:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004745 return cxstring::createRef("CXXConversion");
Guy Benyei11169dd2012-12-18 14:30:41 +00004746 case CXCursor_TemplateTypeParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004747 return cxstring::createRef("TemplateTypeParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00004748 case CXCursor_NonTypeTemplateParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004749 return cxstring::createRef("NonTypeTemplateParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00004750 case CXCursor_TemplateTemplateParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004751 return cxstring::createRef("TemplateTemplateParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00004752 case CXCursor_FunctionTemplate:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004753 return cxstring::createRef("FunctionTemplate");
Guy Benyei11169dd2012-12-18 14:30:41 +00004754 case CXCursor_ClassTemplate:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004755 return cxstring::createRef("ClassTemplate");
Guy Benyei11169dd2012-12-18 14:30:41 +00004756 case CXCursor_ClassTemplatePartialSpecialization:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004757 return cxstring::createRef("ClassTemplatePartialSpecialization");
Guy Benyei11169dd2012-12-18 14:30:41 +00004758 case CXCursor_NamespaceAlias:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004759 return cxstring::createRef("NamespaceAlias");
Guy Benyei11169dd2012-12-18 14:30:41 +00004760 case CXCursor_UsingDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004761 return cxstring::createRef("UsingDirective");
Guy Benyei11169dd2012-12-18 14:30:41 +00004762 case CXCursor_UsingDeclaration:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004763 return cxstring::createRef("UsingDeclaration");
Guy Benyei11169dd2012-12-18 14:30:41 +00004764 case CXCursor_TypeAliasDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004765 return cxstring::createRef("TypeAliasDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004766 case CXCursor_ObjCSynthesizeDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004767 return cxstring::createRef("ObjCSynthesizeDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004768 case CXCursor_ObjCDynamicDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004769 return cxstring::createRef("ObjCDynamicDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004770 case CXCursor_CXXAccessSpecifier:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004771 return cxstring::createRef("CXXAccessSpecifier");
Guy Benyei11169dd2012-12-18 14:30:41 +00004772 case CXCursor_ModuleImportDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004773 return cxstring::createRef("ModuleImport");
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00004774 case CXCursor_OMPParallelDirective:
Alexey Bataev1b59ab52014-02-27 08:29:12 +00004775 return cxstring::createRef("OMPParallelDirective");
4776 case CXCursor_OMPSimdDirective:
4777 return cxstring::createRef("OMPSimdDirective");
Alexey Bataevf29276e2014-06-18 04:14:57 +00004778 case CXCursor_OMPForDirective:
4779 return cxstring::createRef("OMPForDirective");
Alexander Musmanf82886e2014-09-18 05:12:34 +00004780 case CXCursor_OMPForSimdDirective:
4781 return cxstring::createRef("OMPForSimdDirective");
Alexey Bataevd3f8dd22014-06-25 11:44:49 +00004782 case CXCursor_OMPSectionsDirective:
4783 return cxstring::createRef("OMPSectionsDirective");
Alexey Bataev1e0498a2014-06-26 08:21:58 +00004784 case CXCursor_OMPSectionDirective:
4785 return cxstring::createRef("OMPSectionDirective");
Alexey Bataevd1e40fb2014-06-26 12:05:45 +00004786 case CXCursor_OMPSingleDirective:
4787 return cxstring::createRef("OMPSingleDirective");
Alexander Musman80c22892014-07-17 08:54:58 +00004788 case CXCursor_OMPMasterDirective:
4789 return cxstring::createRef("OMPMasterDirective");
Alexander Musmand9ed09f2014-07-21 09:42:05 +00004790 case CXCursor_OMPCriticalDirective:
4791 return cxstring::createRef("OMPCriticalDirective");
Alexey Bataev4acb8592014-07-07 13:01:15 +00004792 case CXCursor_OMPParallelForDirective:
4793 return cxstring::createRef("OMPParallelForDirective");
Alexander Musmane4e893b2014-09-23 09:33:00 +00004794 case CXCursor_OMPParallelForSimdDirective:
4795 return cxstring::createRef("OMPParallelForSimdDirective");
Alexey Bataev84d0b3e2014-07-08 08:12:03 +00004796 case CXCursor_OMPParallelSectionsDirective:
4797 return cxstring::createRef("OMPParallelSectionsDirective");
Alexey Bataev9c2e8ee2014-07-11 11:25:16 +00004798 case CXCursor_OMPTaskDirective:
4799 return cxstring::createRef("OMPTaskDirective");
Alexey Bataev68446b72014-07-18 07:47:19 +00004800 case CXCursor_OMPTaskyieldDirective:
4801 return cxstring::createRef("OMPTaskyieldDirective");
Alexey Bataev4d1dfea2014-07-18 09:11:51 +00004802 case CXCursor_OMPBarrierDirective:
4803 return cxstring::createRef("OMPBarrierDirective");
Alexey Bataev2df347a2014-07-18 10:17:07 +00004804 case CXCursor_OMPTaskwaitDirective:
4805 return cxstring::createRef("OMPTaskwaitDirective");
Alexey Bataevc30dd2d2015-06-18 12:14:09 +00004806 case CXCursor_OMPTaskgroupDirective:
4807 return cxstring::createRef("OMPTaskgroupDirective");
Alexey Bataev6125da92014-07-21 11:26:11 +00004808 case CXCursor_OMPFlushDirective:
4809 return cxstring::createRef("OMPFlushDirective");
Alexey Bataev9fb6e642014-07-22 06:45:04 +00004810 case CXCursor_OMPOrderedDirective:
4811 return cxstring::createRef("OMPOrderedDirective");
Alexey Bataev0162e452014-07-22 10:10:35 +00004812 case CXCursor_OMPAtomicDirective:
4813 return cxstring::createRef("OMPAtomicDirective");
Alexey Bataev0bd520b2014-09-19 08:19:49 +00004814 case CXCursor_OMPTargetDirective:
4815 return cxstring::createRef("OMPTargetDirective");
Michael Wong65f367f2015-07-21 13:44:28 +00004816 case CXCursor_OMPTargetDataDirective:
4817 return cxstring::createRef("OMPTargetDataDirective");
Samuel Antaodf67fc42016-01-19 19:15:56 +00004818 case CXCursor_OMPTargetEnterDataDirective:
4819 return cxstring::createRef("OMPTargetEnterDataDirective");
Samuel Antao72590762016-01-19 20:04:50 +00004820 case CXCursor_OMPTargetExitDataDirective:
4821 return cxstring::createRef("OMPTargetExitDataDirective");
Arpith Chacko Jacobe955b3d2016-01-26 18:48:41 +00004822 case CXCursor_OMPTargetParallelDirective:
4823 return cxstring::createRef("OMPTargetParallelDirective");
Arpith Chacko Jacob05bebb52016-02-03 15:46:42 +00004824 case CXCursor_OMPTargetParallelForDirective:
4825 return cxstring::createRef("OMPTargetParallelForDirective");
Alexey Bataev13314bf2014-10-09 04:18:56 +00004826 case CXCursor_OMPTeamsDirective:
4827 return cxstring::createRef("OMPTeamsDirective");
Alexey Bataev6d4ed052015-07-01 06:57:41 +00004828 case CXCursor_OMPCancellationPointDirective:
4829 return cxstring::createRef("OMPCancellationPointDirective");
Alexey Bataev80909872015-07-02 11:25:17 +00004830 case CXCursor_OMPCancelDirective:
4831 return cxstring::createRef("OMPCancelDirective");
Alexey Bataev49f6e782015-12-01 04:18:41 +00004832 case CXCursor_OMPTaskLoopDirective:
4833 return cxstring::createRef("OMPTaskLoopDirective");
Alexey Bataev0a6ed842015-12-03 09:40:15 +00004834 case CXCursor_OMPTaskLoopSimdDirective:
4835 return cxstring::createRef("OMPTaskLoopSimdDirective");
Carlo Bertolli6200a3d2015-12-14 14:51:25 +00004836 case CXCursor_OMPDistributeDirective:
4837 return cxstring::createRef("OMPDistributeDirective");
Francisco Lopes da Silva975a9f62015-01-21 16:24:11 +00004838 case CXCursor_OverloadCandidate:
4839 return cxstring::createRef("OverloadCandidate");
Sergey Kalinichev8f3b1872015-11-15 13:48:32 +00004840 case CXCursor_TypeAliasTemplateDecl:
4841 return cxstring::createRef("TypeAliasTemplateDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004842 }
4843
4844 llvm_unreachable("Unhandled CXCursorKind");
4845}
4846
4847struct GetCursorData {
4848 SourceLocation TokenBeginLoc;
4849 bool PointsAtMacroArgExpansion;
4850 bool VisitedObjCPropertyImplDecl;
4851 SourceLocation VisitedDeclaratorDeclStartLoc;
4852 CXCursor &BestCursor;
4853
4854 GetCursorData(SourceManager &SM,
4855 SourceLocation tokenBegin, CXCursor &outputCursor)
4856 : TokenBeginLoc(tokenBegin), BestCursor(outputCursor) {
4857 PointsAtMacroArgExpansion = SM.isMacroArgExpansion(tokenBegin);
4858 VisitedObjCPropertyImplDecl = false;
4859 }
4860};
4861
4862static enum CXChildVisitResult GetCursorVisitor(CXCursor cursor,
4863 CXCursor parent,
4864 CXClientData client_data) {
4865 GetCursorData *Data = static_cast<GetCursorData *>(client_data);
4866 CXCursor *BestCursor = &Data->BestCursor;
4867
4868 // If we point inside a macro argument we should provide info of what the
4869 // token is so use the actual cursor, don't replace it with a macro expansion
4870 // cursor.
4871 if (cursor.kind == CXCursor_MacroExpansion && Data->PointsAtMacroArgExpansion)
4872 return CXChildVisit_Recurse;
4873
4874 if (clang_isDeclaration(cursor.kind)) {
4875 // Avoid having the implicit methods override the property decls.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004876 if (const ObjCMethodDecl *MD
Guy Benyei11169dd2012-12-18 14:30:41 +00004877 = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
4878 if (MD->isImplicit())
4879 return CXChildVisit_Break;
4880
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004881 } else if (const ObjCInterfaceDecl *ID
Guy Benyei11169dd2012-12-18 14:30:41 +00004882 = dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(cursor))) {
4883 // Check that when we have multiple @class references in the same line,
4884 // that later ones do not override the previous ones.
4885 // If we have:
4886 // @class Foo, Bar;
4887 // source ranges for both start at '@', so 'Bar' will end up overriding
4888 // 'Foo' even though the cursor location was at 'Foo'.
4889 if (BestCursor->kind == CXCursor_ObjCInterfaceDecl ||
4890 BestCursor->kind == CXCursor_ObjCClassRef)
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004891 if (const ObjCInterfaceDecl *PrevID
Guy Benyei11169dd2012-12-18 14:30:41 +00004892 = dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(*BestCursor))){
4893 if (PrevID != ID &&
4894 !PrevID->isThisDeclarationADefinition() &&
4895 !ID->isThisDeclarationADefinition())
4896 return CXChildVisit_Break;
4897 }
4898
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004899 } else if (const DeclaratorDecl *DD
Guy Benyei11169dd2012-12-18 14:30:41 +00004900 = dyn_cast_or_null<DeclaratorDecl>(getCursorDecl(cursor))) {
4901 SourceLocation StartLoc = DD->getSourceRange().getBegin();
4902 // Check that when we have multiple declarators in the same line,
4903 // that later ones do not override the previous ones.
4904 // If we have:
4905 // int Foo, Bar;
4906 // source ranges for both start at 'int', so 'Bar' will end up overriding
4907 // 'Foo' even though the cursor location was at 'Foo'.
4908 if (Data->VisitedDeclaratorDeclStartLoc == StartLoc)
4909 return CXChildVisit_Break;
4910 Data->VisitedDeclaratorDeclStartLoc = StartLoc;
4911
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004912 } else if (const ObjCPropertyImplDecl *PropImp
Guy Benyei11169dd2012-12-18 14:30:41 +00004913 = dyn_cast_or_null<ObjCPropertyImplDecl>(getCursorDecl(cursor))) {
4914 (void)PropImp;
4915 // Check that when we have multiple @synthesize in the same line,
4916 // that later ones do not override the previous ones.
4917 // If we have:
4918 // @synthesize Foo, Bar;
4919 // source ranges for both start at '@', so 'Bar' will end up overriding
4920 // 'Foo' even though the cursor location was at 'Foo'.
4921 if (Data->VisitedObjCPropertyImplDecl)
4922 return CXChildVisit_Break;
4923 Data->VisitedObjCPropertyImplDecl = true;
4924 }
4925 }
4926
4927 if (clang_isExpression(cursor.kind) &&
4928 clang_isDeclaration(BestCursor->kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004929 if (const Decl *D = getCursorDecl(*BestCursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004930 // Avoid having the cursor of an expression replace the declaration cursor
4931 // when the expression source range overlaps the declaration range.
4932 // This can happen for C++ constructor expressions whose range generally
4933 // include the variable declaration, e.g.:
4934 // MyCXXClass foo; // Make sure pointing at 'foo' returns a VarDecl cursor.
4935 if (D->getLocation().isValid() && Data->TokenBeginLoc.isValid() &&
4936 D->getLocation() == Data->TokenBeginLoc)
4937 return CXChildVisit_Break;
4938 }
4939 }
4940
4941 // If our current best cursor is the construction of a temporary object,
4942 // don't replace that cursor with a type reference, because we want
4943 // clang_getCursor() to point at the constructor.
4944 if (clang_isExpression(BestCursor->kind) &&
4945 isa<CXXTemporaryObjectExpr>(getCursorExpr(*BestCursor)) &&
4946 cursor.kind == CXCursor_TypeRef) {
4947 // Keep the cursor pointing at CXXTemporaryObjectExpr but also mark it
4948 // as having the actual point on the type reference.
4949 *BestCursor = getTypeRefedCallExprCursor(*BestCursor);
4950 return CXChildVisit_Recurse;
4951 }
Douglas Gregore9d95f12015-07-07 03:57:35 +00004952
4953 // If we already have an Objective-C superclass reference, don't
4954 // update it further.
4955 if (BestCursor->kind == CXCursor_ObjCSuperClassRef)
4956 return CXChildVisit_Break;
4957
Guy Benyei11169dd2012-12-18 14:30:41 +00004958 *BestCursor = cursor;
4959 return CXChildVisit_Recurse;
4960}
4961
4962CXCursor clang_getCursor(CXTranslationUnit TU, CXSourceLocation Loc) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00004963 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004964 LOG_BAD_TU(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004965 return clang_getNullCursor();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004966 }
Guy Benyei11169dd2012-12-18 14:30:41 +00004967
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004968 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004969 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
4970
4971 SourceLocation SLoc = cxloc::translateSourceLocation(Loc);
4972 CXCursor Result = cxcursor::getCursor(TU, SLoc);
4973
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004974 LOG_FUNC_SECTION {
Guy Benyei11169dd2012-12-18 14:30:41 +00004975 CXFile SearchFile;
4976 unsigned SearchLine, SearchColumn;
4977 CXFile ResultFile;
4978 unsigned ResultLine, ResultColumn;
4979 CXString SearchFileName, ResultFileName, KindSpelling, USR;
4980 const char *IsDef = clang_isCursorDefinition(Result)? " (Definition)" : "";
4981 CXSourceLocation ResultLoc = clang_getCursorLocation(Result);
Craig Topper69186e72014-06-08 08:38:04 +00004982
4983 clang_getFileLocation(Loc, &SearchFile, &SearchLine, &SearchColumn,
4984 nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004985 clang_getFileLocation(ResultLoc, &ResultFile, &ResultLine,
Craig Topper69186e72014-06-08 08:38:04 +00004986 &ResultColumn, nullptr);
Guy Benyei11169dd2012-12-18 14:30:41 +00004987 SearchFileName = clang_getFileName(SearchFile);
4988 ResultFileName = clang_getFileName(ResultFile);
4989 KindSpelling = clang_getCursorKindSpelling(Result.kind);
4990 USR = clang_getCursorUSR(Result);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004991 *Log << llvm::format("(%s:%d:%d) = %s",
4992 clang_getCString(SearchFileName), SearchLine, SearchColumn,
4993 clang_getCString(KindSpelling))
4994 << llvm::format("(%s:%d:%d):%s%s",
4995 clang_getCString(ResultFileName), ResultLine, ResultColumn,
4996 clang_getCString(USR), IsDef);
Guy Benyei11169dd2012-12-18 14:30:41 +00004997 clang_disposeString(SearchFileName);
4998 clang_disposeString(ResultFileName);
4999 clang_disposeString(KindSpelling);
5000 clang_disposeString(USR);
5001
5002 CXCursor Definition = clang_getCursorDefinition(Result);
5003 if (!clang_equalCursors(Definition, clang_getNullCursor())) {
5004 CXSourceLocation DefinitionLoc = clang_getCursorLocation(Definition);
5005 CXString DefinitionKindSpelling
5006 = clang_getCursorKindSpelling(Definition.kind);
5007 CXFile DefinitionFile;
5008 unsigned DefinitionLine, DefinitionColumn;
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00005009 clang_getFileLocation(DefinitionLoc, &DefinitionFile,
Craig Topper69186e72014-06-08 08:38:04 +00005010 &DefinitionLine, &DefinitionColumn, nullptr);
Guy Benyei11169dd2012-12-18 14:30:41 +00005011 CXString DefinitionFileName = clang_getFileName(DefinitionFile);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00005012 *Log << llvm::format(" -> %s(%s:%d:%d)",
5013 clang_getCString(DefinitionKindSpelling),
5014 clang_getCString(DefinitionFileName),
5015 DefinitionLine, DefinitionColumn);
Guy Benyei11169dd2012-12-18 14:30:41 +00005016 clang_disposeString(DefinitionFileName);
5017 clang_disposeString(DefinitionKindSpelling);
5018 }
5019 }
5020
5021 return Result;
5022}
5023
5024CXCursor clang_getNullCursor(void) {
5025 return MakeCXCursorInvalid(CXCursor_InvalidFile);
5026}
5027
5028unsigned clang_equalCursors(CXCursor X, CXCursor Y) {
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00005029 // Clear out the "FirstInDeclGroup" part in a declaration cursor, since we
5030 // can't set consistently. For example, when visiting a DeclStmt we will set
5031 // it but we don't set it on the result of clang_getCursorDefinition for
5032 // a reference of the same declaration.
5033 // FIXME: Setting "FirstInDeclGroup" in CXCursors is a hack that only works
5034 // when visiting a DeclStmt currently, the AST should be enhanced to be able
5035 // to provide that kind of info.
5036 if (clang_isDeclaration(X.kind))
Craig Topper69186e72014-06-08 08:38:04 +00005037 X.data[1] = nullptr;
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00005038 if (clang_isDeclaration(Y.kind))
Craig Topper69186e72014-06-08 08:38:04 +00005039 Y.data[1] = nullptr;
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00005040
Guy Benyei11169dd2012-12-18 14:30:41 +00005041 return X == Y;
5042}
5043
5044unsigned clang_hashCursor(CXCursor C) {
5045 unsigned Index = 0;
5046 if (clang_isExpression(C.kind) || clang_isStatement(C.kind))
5047 Index = 1;
5048
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005049 return llvm::DenseMapInfo<std::pair<unsigned, const void*> >::getHashValue(
Guy Benyei11169dd2012-12-18 14:30:41 +00005050 std::make_pair(C.kind, C.data[Index]));
5051}
5052
5053unsigned clang_isInvalid(enum CXCursorKind K) {
5054 return K >= CXCursor_FirstInvalid && K <= CXCursor_LastInvalid;
5055}
5056
5057unsigned clang_isDeclaration(enum CXCursorKind K) {
5058 return (K >= CXCursor_FirstDecl && K <= CXCursor_LastDecl) ||
5059 (K >= CXCursor_FirstExtraDecl && K <= CXCursor_LastExtraDecl);
5060}
5061
5062unsigned clang_isReference(enum CXCursorKind K) {
5063 return K >= CXCursor_FirstRef && K <= CXCursor_LastRef;
5064}
5065
5066unsigned clang_isExpression(enum CXCursorKind K) {
5067 return K >= CXCursor_FirstExpr && K <= CXCursor_LastExpr;
5068}
5069
5070unsigned clang_isStatement(enum CXCursorKind K) {
5071 return K >= CXCursor_FirstStmt && K <= CXCursor_LastStmt;
5072}
5073
5074unsigned clang_isAttribute(enum CXCursorKind K) {
5075 return K >= CXCursor_FirstAttr && K <= CXCursor_LastAttr;
5076}
5077
5078unsigned clang_isTranslationUnit(enum CXCursorKind K) {
5079 return K == CXCursor_TranslationUnit;
5080}
5081
5082unsigned clang_isPreprocessing(enum CXCursorKind K) {
5083 return K >= CXCursor_FirstPreprocessing && K <= CXCursor_LastPreprocessing;
5084}
5085
5086unsigned clang_isUnexposed(enum CXCursorKind K) {
5087 switch (K) {
5088 case CXCursor_UnexposedDecl:
5089 case CXCursor_UnexposedExpr:
5090 case CXCursor_UnexposedStmt:
5091 case CXCursor_UnexposedAttr:
5092 return true;
5093 default:
5094 return false;
5095 }
5096}
5097
5098CXCursorKind clang_getCursorKind(CXCursor C) {
5099 return C.kind;
5100}
5101
5102CXSourceLocation clang_getCursorLocation(CXCursor C) {
5103 if (clang_isReference(C.kind)) {
5104 switch (C.kind) {
5105 case CXCursor_ObjCSuperClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005106 std::pair<const ObjCInterfaceDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00005107 = getCursorObjCSuperClassRef(C);
5108 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
5109 }
5110
5111 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005112 std::pair<const ObjCProtocolDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00005113 = getCursorObjCProtocolRef(C);
5114 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
5115 }
5116
5117 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005118 std::pair<const ObjCInterfaceDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00005119 = getCursorObjCClassRef(C);
5120 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
5121 }
5122
5123 case CXCursor_TypeRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005124 std::pair<const TypeDecl *, SourceLocation> P = getCursorTypeRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005125 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
5126 }
5127
5128 case CXCursor_TemplateRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005129 std::pair<const TemplateDecl *, SourceLocation> P =
5130 getCursorTemplateRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005131 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
5132 }
5133
5134 case CXCursor_NamespaceRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005135 std::pair<const NamedDecl *, SourceLocation> P = getCursorNamespaceRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005136 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
5137 }
5138
5139 case CXCursor_MemberRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005140 std::pair<const FieldDecl *, SourceLocation> P = getCursorMemberRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005141 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
5142 }
5143
5144 case CXCursor_VariableRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005145 std::pair<const VarDecl *, SourceLocation> P = getCursorVariableRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005146 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
5147 }
5148
5149 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005150 const CXXBaseSpecifier *BaseSpec = getCursorCXXBaseSpecifier(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005151 if (!BaseSpec)
5152 return clang_getNullLocation();
5153
5154 if (TypeSourceInfo *TSInfo = BaseSpec->getTypeSourceInfo())
5155 return cxloc::translateSourceLocation(getCursorContext(C),
5156 TSInfo->getTypeLoc().getBeginLoc());
5157
5158 return cxloc::translateSourceLocation(getCursorContext(C),
5159 BaseSpec->getLocStart());
5160 }
5161
5162 case CXCursor_LabelRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005163 std::pair<const LabelStmt *, SourceLocation> P = getCursorLabelRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005164 return cxloc::translateSourceLocation(getCursorContext(C), P.second);
5165 }
5166
5167 case CXCursor_OverloadedDeclRef:
5168 return cxloc::translateSourceLocation(getCursorContext(C),
5169 getCursorOverloadedDeclRef(C).second);
5170
5171 default:
5172 // FIXME: Need a way to enumerate all non-reference cases.
5173 llvm_unreachable("Missed a reference kind");
5174 }
5175 }
5176
5177 if (clang_isExpression(C.kind))
5178 return cxloc::translateSourceLocation(getCursorContext(C),
5179 getLocationFromExpr(getCursorExpr(C)));
5180
5181 if (clang_isStatement(C.kind))
5182 return cxloc::translateSourceLocation(getCursorContext(C),
5183 getCursorStmt(C)->getLocStart());
5184
5185 if (C.kind == CXCursor_PreprocessingDirective) {
5186 SourceLocation L = cxcursor::getCursorPreprocessingDirective(C).getBegin();
5187 return cxloc::translateSourceLocation(getCursorContext(C), L);
5188 }
5189
5190 if (C.kind == CXCursor_MacroExpansion) {
5191 SourceLocation L
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00005192 = cxcursor::getCursorMacroExpansion(C).getSourceRange().getBegin();
Guy Benyei11169dd2012-12-18 14:30:41 +00005193 return cxloc::translateSourceLocation(getCursorContext(C), L);
5194 }
5195
5196 if (C.kind == CXCursor_MacroDefinition) {
5197 SourceLocation L = cxcursor::getCursorMacroDefinition(C)->getLocation();
5198 return cxloc::translateSourceLocation(getCursorContext(C), L);
5199 }
5200
5201 if (C.kind == CXCursor_InclusionDirective) {
5202 SourceLocation L
5203 = cxcursor::getCursorInclusionDirective(C)->getSourceRange().getBegin();
5204 return cxloc::translateSourceLocation(getCursorContext(C), L);
5205 }
5206
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00005207 if (clang_isAttribute(C.kind)) {
5208 SourceLocation L
5209 = cxcursor::getCursorAttr(C)->getLocation();
5210 return cxloc::translateSourceLocation(getCursorContext(C), L);
5211 }
5212
Guy Benyei11169dd2012-12-18 14:30:41 +00005213 if (!clang_isDeclaration(C.kind))
5214 return clang_getNullLocation();
5215
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005216 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005217 if (!D)
5218 return clang_getNullLocation();
5219
5220 SourceLocation Loc = D->getLocation();
5221 // FIXME: Multiple variables declared in a single declaration
5222 // currently lack the information needed to correctly determine their
5223 // ranges when accounting for the type-specifier. We use context
5224 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
5225 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005226 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005227 if (!cxcursor::isFirstInDeclGroup(C))
5228 Loc = VD->getLocation();
5229 }
5230
5231 // For ObjC methods, give the start location of the method name.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005232 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00005233 Loc = MD->getSelectorStartLoc();
5234
5235 return cxloc::translateSourceLocation(getCursorContext(C), Loc);
5236}
5237
5238} // end extern "C"
5239
5240CXCursor cxcursor::getCursor(CXTranslationUnit TU, SourceLocation SLoc) {
5241 assert(TU);
5242
5243 // Guard against an invalid SourceLocation, or we may assert in one
5244 // of the following calls.
5245 if (SLoc.isInvalid())
5246 return clang_getNullCursor();
5247
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005248 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005249
5250 // Translate the given source location to make it point at the beginning of
5251 // the token under the cursor.
5252 SLoc = Lexer::GetBeginningOfToken(SLoc, CXXUnit->getSourceManager(),
5253 CXXUnit->getASTContext().getLangOpts());
5254
5255 CXCursor Result = MakeCXCursorInvalid(CXCursor_NoDeclFound);
5256 if (SLoc.isValid()) {
5257 GetCursorData ResultData(CXXUnit->getSourceManager(), SLoc, Result);
5258 CursorVisitor CursorVis(TU, GetCursorVisitor, &ResultData,
5259 /*VisitPreprocessorLast=*/true,
5260 /*VisitIncludedEntities=*/false,
5261 SourceLocation(SLoc));
5262 CursorVis.visitFileRegion();
5263 }
5264
5265 return Result;
5266}
5267
5268static SourceRange getRawCursorExtent(CXCursor C) {
5269 if (clang_isReference(C.kind)) {
5270 switch (C.kind) {
5271 case CXCursor_ObjCSuperClassRef:
5272 return getCursorObjCSuperClassRef(C).second;
5273
5274 case CXCursor_ObjCProtocolRef:
5275 return getCursorObjCProtocolRef(C).second;
5276
5277 case CXCursor_ObjCClassRef:
5278 return getCursorObjCClassRef(C).second;
5279
5280 case CXCursor_TypeRef:
5281 return getCursorTypeRef(C).second;
5282
5283 case CXCursor_TemplateRef:
5284 return getCursorTemplateRef(C).second;
5285
5286 case CXCursor_NamespaceRef:
5287 return getCursorNamespaceRef(C).second;
5288
5289 case CXCursor_MemberRef:
5290 return getCursorMemberRef(C).second;
5291
5292 case CXCursor_CXXBaseSpecifier:
5293 return getCursorCXXBaseSpecifier(C)->getSourceRange();
5294
5295 case CXCursor_LabelRef:
5296 return getCursorLabelRef(C).second;
5297
5298 case CXCursor_OverloadedDeclRef:
5299 return getCursorOverloadedDeclRef(C).second;
5300
5301 case CXCursor_VariableRef:
5302 return getCursorVariableRef(C).second;
5303
5304 default:
5305 // FIXME: Need a way to enumerate all non-reference cases.
5306 llvm_unreachable("Missed a reference kind");
5307 }
5308 }
5309
5310 if (clang_isExpression(C.kind))
5311 return getCursorExpr(C)->getSourceRange();
5312
5313 if (clang_isStatement(C.kind))
5314 return getCursorStmt(C)->getSourceRange();
5315
5316 if (clang_isAttribute(C.kind))
5317 return getCursorAttr(C)->getRange();
5318
5319 if (C.kind == CXCursor_PreprocessingDirective)
5320 return cxcursor::getCursorPreprocessingDirective(C);
5321
5322 if (C.kind == CXCursor_MacroExpansion) {
5323 ASTUnit *TU = getCursorASTUnit(C);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00005324 SourceRange Range = cxcursor::getCursorMacroExpansion(C).getSourceRange();
Guy Benyei11169dd2012-12-18 14:30:41 +00005325 return TU->mapRangeFromPreamble(Range);
5326 }
5327
5328 if (C.kind == CXCursor_MacroDefinition) {
5329 ASTUnit *TU = getCursorASTUnit(C);
5330 SourceRange Range = cxcursor::getCursorMacroDefinition(C)->getSourceRange();
5331 return TU->mapRangeFromPreamble(Range);
5332 }
5333
5334 if (C.kind == CXCursor_InclusionDirective) {
5335 ASTUnit *TU = getCursorASTUnit(C);
5336 SourceRange Range = cxcursor::getCursorInclusionDirective(C)->getSourceRange();
5337 return TU->mapRangeFromPreamble(Range);
5338 }
5339
5340 if (C.kind == CXCursor_TranslationUnit) {
5341 ASTUnit *TU = getCursorASTUnit(C);
5342 FileID MainID = TU->getSourceManager().getMainFileID();
5343 SourceLocation Start = TU->getSourceManager().getLocForStartOfFile(MainID);
5344 SourceLocation End = TU->getSourceManager().getLocForEndOfFile(MainID);
5345 return SourceRange(Start, End);
5346 }
5347
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 // FIXME: Multiple variables declared in a single declaration
5355 // currently lack the information needed to correctly determine their
5356 // ranges when accounting for the type-specifier. We use context
5357 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
5358 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005359 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005360 if (!cxcursor::isFirstInDeclGroup(C))
5361 R.setBegin(VD->getLocation());
5362 }
5363 return R;
5364 }
5365 return SourceRange();
5366}
5367
5368/// \brief Retrieves the "raw" cursor extent, which is then extended to include
5369/// the decl-specifier-seq for declarations.
5370static SourceRange getFullCursorExtent(CXCursor C, SourceManager &SrcMgr) {
5371 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005372 const Decl *D = cxcursor::getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005373 if (!D)
5374 return SourceRange();
5375
5376 SourceRange R = D->getSourceRange();
5377
5378 // Adjust the start of the location for declarations preceded by
5379 // declaration specifiers.
5380 SourceLocation StartLoc;
5381 if (const DeclaratorDecl *DD = dyn_cast<DeclaratorDecl>(D)) {
5382 if (TypeSourceInfo *TI = DD->getTypeSourceInfo())
5383 StartLoc = TI->getTypeLoc().getLocStart();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005384 } else if (const TypedefDecl *Typedef = dyn_cast<TypedefDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005385 if (TypeSourceInfo *TI = Typedef->getTypeSourceInfo())
5386 StartLoc = TI->getTypeLoc().getLocStart();
5387 }
5388
5389 if (StartLoc.isValid() && R.getBegin().isValid() &&
5390 SrcMgr.isBeforeInTranslationUnit(StartLoc, R.getBegin()))
5391 R.setBegin(StartLoc);
5392
5393 // FIXME: Multiple variables declared in a single declaration
5394 // currently lack the information needed to correctly determine their
5395 // ranges when accounting for the type-specifier. We use context
5396 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
5397 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005398 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005399 if (!cxcursor::isFirstInDeclGroup(C))
5400 R.setBegin(VD->getLocation());
5401 }
5402
5403 return R;
5404 }
5405
5406 return getRawCursorExtent(C);
5407}
5408
5409extern "C" {
5410
5411CXSourceRange clang_getCursorExtent(CXCursor C) {
5412 SourceRange R = getRawCursorExtent(C);
5413 if (R.isInvalid())
5414 return clang_getNullRange();
5415
5416 return cxloc::translateSourceRange(getCursorContext(C), R);
5417}
5418
5419CXCursor clang_getCursorReferenced(CXCursor C) {
5420 if (clang_isInvalid(C.kind))
5421 return clang_getNullCursor();
5422
5423 CXTranslationUnit tu = getCursorTU(C);
5424 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005425 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005426 if (!D)
5427 return clang_getNullCursor();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005428 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00005429 return MakeCursorOverloadedDeclRef(Using, D->getLocation(), tu);
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005430 if (const ObjCPropertyImplDecl *PropImpl =
5431 dyn_cast<ObjCPropertyImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00005432 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
5433 return MakeCXCursor(Property, tu);
5434
5435 return C;
5436 }
5437
5438 if (clang_isExpression(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005439 const Expr *E = getCursorExpr(C);
5440 const Decl *D = getDeclFromExpr(E);
Guy Benyei11169dd2012-12-18 14:30:41 +00005441 if (D) {
5442 CXCursor declCursor = MakeCXCursor(D, tu);
5443 declCursor = getSelectorIdentifierCursor(getSelectorIdentifierIndex(C),
5444 declCursor);
5445 return declCursor;
5446 }
5447
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005448 if (const OverloadExpr *Ovl = dyn_cast_or_null<OverloadExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00005449 return MakeCursorOverloadedDeclRef(Ovl, tu);
5450
5451 return clang_getNullCursor();
5452 }
5453
5454 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005455 const Stmt *S = getCursorStmt(C);
5456 if (const GotoStmt *Goto = dyn_cast_or_null<GotoStmt>(S))
Guy Benyei11169dd2012-12-18 14:30:41 +00005457 if (LabelDecl *label = Goto->getLabel())
5458 if (LabelStmt *labelS = label->getStmt())
5459 return MakeCXCursor(labelS, getCursorDecl(C), tu);
5460
5461 return clang_getNullCursor();
5462 }
Richard Smith66a81862015-05-04 02:25:31 +00005463
Guy Benyei11169dd2012-12-18 14:30:41 +00005464 if (C.kind == CXCursor_MacroExpansion) {
Richard Smith66a81862015-05-04 02:25:31 +00005465 if (const MacroDefinitionRecord *Def =
5466 getCursorMacroExpansion(C).getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005467 return MakeMacroDefinitionCursor(Def, tu);
5468 }
5469
5470 if (!clang_isReference(C.kind))
5471 return clang_getNullCursor();
5472
5473 switch (C.kind) {
5474 case CXCursor_ObjCSuperClassRef:
5475 return MakeCXCursor(getCursorObjCSuperClassRef(C).first, tu);
5476
5477 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005478 const ObjCProtocolDecl *Prot = getCursorObjCProtocolRef(C).first;
5479 if (const ObjCProtocolDecl *Def = Prot->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005480 return MakeCXCursor(Def, tu);
5481
5482 return MakeCXCursor(Prot, tu);
5483 }
5484
5485 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005486 const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
5487 if (const ObjCInterfaceDecl *Def = Class->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005488 return MakeCXCursor(Def, tu);
5489
5490 return MakeCXCursor(Class, tu);
5491 }
5492
5493 case CXCursor_TypeRef:
5494 return MakeCXCursor(getCursorTypeRef(C).first, tu );
5495
5496 case CXCursor_TemplateRef:
5497 return MakeCXCursor(getCursorTemplateRef(C).first, tu );
5498
5499 case CXCursor_NamespaceRef:
5500 return MakeCXCursor(getCursorNamespaceRef(C).first, tu );
5501
5502 case CXCursor_MemberRef:
5503 return MakeCXCursor(getCursorMemberRef(C).first, tu );
5504
5505 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005506 const CXXBaseSpecifier *B = cxcursor::getCursorCXXBaseSpecifier(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005507 return clang_getTypeDeclaration(cxtype::MakeCXType(B->getType(),
5508 tu ));
5509 }
5510
5511 case CXCursor_LabelRef:
5512 // FIXME: We end up faking the "parent" declaration here because we
5513 // don't want to make CXCursor larger.
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005514 return MakeCXCursor(getCursorLabelRef(C).first,
5515 cxtu::getASTUnit(tu)->getASTContext()
5516 .getTranslationUnitDecl(),
Guy Benyei11169dd2012-12-18 14:30:41 +00005517 tu);
5518
5519 case CXCursor_OverloadedDeclRef:
5520 return C;
5521
5522 case CXCursor_VariableRef:
5523 return MakeCXCursor(getCursorVariableRef(C).first, tu);
5524
5525 default:
5526 // We would prefer to enumerate all non-reference cursor kinds here.
5527 llvm_unreachable("Unhandled reference cursor kind");
5528 }
5529}
5530
5531CXCursor clang_getCursorDefinition(CXCursor C) {
5532 if (clang_isInvalid(C.kind))
5533 return clang_getNullCursor();
5534
5535 CXTranslationUnit TU = getCursorTU(C);
5536
5537 bool WasReference = false;
5538 if (clang_isReference(C.kind) || clang_isExpression(C.kind)) {
5539 C = clang_getCursorReferenced(C);
5540 WasReference = true;
5541 }
5542
5543 if (C.kind == CXCursor_MacroExpansion)
5544 return clang_getCursorReferenced(C);
5545
5546 if (!clang_isDeclaration(C.kind))
5547 return clang_getNullCursor();
5548
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005549 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005550 if (!D)
5551 return clang_getNullCursor();
5552
5553 switch (D->getKind()) {
5554 // Declaration kinds that don't really separate the notions of
5555 // declaration and definition.
5556 case Decl::Namespace:
5557 case Decl::Typedef:
5558 case Decl::TypeAlias:
5559 case Decl::TypeAliasTemplate:
5560 case Decl::TemplateTypeParm:
5561 case Decl::EnumConstant:
5562 case Decl::Field:
John McCall5e77d762013-04-16 07:28:30 +00005563 case Decl::MSProperty:
Guy Benyei11169dd2012-12-18 14:30:41 +00005564 case Decl::IndirectField:
5565 case Decl::ObjCIvar:
5566 case Decl::ObjCAtDefsField:
5567 case Decl::ImplicitParam:
5568 case Decl::ParmVar:
5569 case Decl::NonTypeTemplateParm:
5570 case Decl::TemplateTemplateParm:
5571 case Decl::ObjCCategoryImpl:
5572 case Decl::ObjCImplementation:
5573 case Decl::AccessSpec:
5574 case Decl::LinkageSpec:
5575 case Decl::ObjCPropertyImpl:
5576 case Decl::FileScopeAsm:
5577 case Decl::StaticAssert:
5578 case Decl::Block:
Tareq A. Siraj6dfa25a2013-04-16 19:37:38 +00005579 case Decl::Captured:
Alexey Bataev4244be22016-02-11 05:35:55 +00005580 case Decl::OMPCapturedExpr:
Guy Benyei11169dd2012-12-18 14:30:41 +00005581 case Decl::Label: // FIXME: Is this right??
5582 case Decl::ClassScopeFunctionSpecialization:
5583 case Decl::Import:
Alexey Bataeva769e072013-03-22 06:34:35 +00005584 case Decl::OMPThreadPrivate:
Douglas Gregor85f3f952015-07-07 03:57:15 +00005585 case Decl::ObjCTypeParam:
David Majnemerd9b1a4f2015-11-04 03:40:30 +00005586 case Decl::BuiltinTemplate:
Guy Benyei11169dd2012-12-18 14:30:41 +00005587 return C;
5588
5589 // Declaration kinds that don't make any sense here, but are
5590 // nonetheless harmless.
David Blaikief005d3c2013-02-22 17:44:58 +00005591 case Decl::Empty:
Guy Benyei11169dd2012-12-18 14:30:41 +00005592 case Decl::TranslationUnit:
Richard Smithf19e1272015-03-07 00:04:49 +00005593 case Decl::ExternCContext:
Guy Benyei11169dd2012-12-18 14:30:41 +00005594 break;
5595
5596 // Declaration kinds for which the definition is not resolvable.
5597 case Decl::UnresolvedUsingTypename:
5598 case Decl::UnresolvedUsingValue:
5599 break;
5600
5601 case Decl::UsingDirective:
5602 return MakeCXCursor(cast<UsingDirectiveDecl>(D)->getNominatedNamespace(),
5603 TU);
5604
5605 case Decl::NamespaceAlias:
5606 return MakeCXCursor(cast<NamespaceAliasDecl>(D)->getNamespace(), TU);
5607
5608 case Decl::Enum:
5609 case Decl::Record:
5610 case Decl::CXXRecord:
5611 case Decl::ClassTemplateSpecialization:
5612 case Decl::ClassTemplatePartialSpecialization:
5613 if (TagDecl *Def = cast<TagDecl>(D)->getDefinition())
5614 return MakeCXCursor(Def, TU);
5615 return clang_getNullCursor();
5616
5617 case Decl::Function:
5618 case Decl::CXXMethod:
5619 case Decl::CXXConstructor:
5620 case Decl::CXXDestructor:
5621 case Decl::CXXConversion: {
Craig Topper69186e72014-06-08 08:38:04 +00005622 const FunctionDecl *Def = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005623 if (cast<FunctionDecl>(D)->getBody(Def))
Dmitri Gribenko9c256e32013-01-14 00:46:27 +00005624 return MakeCXCursor(Def, TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005625 return clang_getNullCursor();
5626 }
5627
Larisse Voufo39a1e502013-08-06 01:03:05 +00005628 case Decl::Var:
5629 case Decl::VarTemplateSpecialization:
5630 case Decl::VarTemplatePartialSpecialization: {
Guy Benyei11169dd2012-12-18 14:30:41 +00005631 // Ask the variable if it has a definition.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005632 if (const VarDecl *Def = cast<VarDecl>(D)->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005633 return MakeCXCursor(Def, TU);
5634 return clang_getNullCursor();
5635 }
5636
5637 case Decl::FunctionTemplate: {
Craig Topper69186e72014-06-08 08:38:04 +00005638 const FunctionDecl *Def = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005639 if (cast<FunctionTemplateDecl>(D)->getTemplatedDecl()->getBody(Def))
5640 return MakeCXCursor(Def->getDescribedFunctionTemplate(), TU);
5641 return clang_getNullCursor();
5642 }
5643
5644 case Decl::ClassTemplate: {
5645 if (RecordDecl *Def = cast<ClassTemplateDecl>(D)->getTemplatedDecl()
5646 ->getDefinition())
5647 return MakeCXCursor(cast<CXXRecordDecl>(Def)->getDescribedClassTemplate(),
5648 TU);
5649 return clang_getNullCursor();
5650 }
5651
Larisse Voufo39a1e502013-08-06 01:03:05 +00005652 case Decl::VarTemplate: {
5653 if (VarDecl *Def =
5654 cast<VarTemplateDecl>(D)->getTemplatedDecl()->getDefinition())
5655 return MakeCXCursor(cast<VarDecl>(Def)->getDescribedVarTemplate(), TU);
5656 return clang_getNullCursor();
5657 }
5658
Guy Benyei11169dd2012-12-18 14:30:41 +00005659 case Decl::Using:
5660 return MakeCursorOverloadedDeclRef(cast<UsingDecl>(D),
5661 D->getLocation(), TU);
5662
5663 case Decl::UsingShadow:
5664 return clang_getCursorDefinition(
5665 MakeCXCursor(cast<UsingShadowDecl>(D)->getTargetDecl(),
5666 TU));
5667
5668 case Decl::ObjCMethod: {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005669 const ObjCMethodDecl *Method = cast<ObjCMethodDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00005670 if (Method->isThisDeclarationADefinition())
5671 return C;
5672
5673 // Dig out the method definition in the associated
5674 // @implementation, if we have it.
5675 // FIXME: The ASTs should make finding the definition easier.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005676 if (const ObjCInterfaceDecl *Class
Guy Benyei11169dd2012-12-18 14:30:41 +00005677 = dyn_cast<ObjCInterfaceDecl>(Method->getDeclContext()))
5678 if (ObjCImplementationDecl *ClassImpl = Class->getImplementation())
5679 if (ObjCMethodDecl *Def = ClassImpl->getMethod(Method->getSelector(),
5680 Method->isInstanceMethod()))
5681 if (Def->isThisDeclarationADefinition())
5682 return MakeCXCursor(Def, TU);
5683
5684 return clang_getNullCursor();
5685 }
5686
5687 case Decl::ObjCCategory:
5688 if (ObjCCategoryImplDecl *Impl
5689 = cast<ObjCCategoryDecl>(D)->getImplementation())
5690 return MakeCXCursor(Impl, TU);
5691 return clang_getNullCursor();
5692
5693 case Decl::ObjCProtocol:
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005694 if (const ObjCProtocolDecl *Def = cast<ObjCProtocolDecl>(D)->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005695 return MakeCXCursor(Def, TU);
5696 return clang_getNullCursor();
5697
5698 case Decl::ObjCInterface: {
5699 // There are two notions of a "definition" for an Objective-C
5700 // class: the interface and its implementation. When we resolved a
5701 // reference to an Objective-C class, produce the @interface as
5702 // the definition; when we were provided with the interface,
5703 // produce the @implementation as the definition.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005704 const ObjCInterfaceDecl *IFace = cast<ObjCInterfaceDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00005705 if (WasReference) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005706 if (const ObjCInterfaceDecl *Def = IFace->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005707 return MakeCXCursor(Def, TU);
5708 } else if (ObjCImplementationDecl *Impl = IFace->getImplementation())
5709 return MakeCXCursor(Impl, TU);
5710 return clang_getNullCursor();
5711 }
5712
5713 case Decl::ObjCProperty:
5714 // FIXME: We don't really know where to find the
5715 // ObjCPropertyImplDecls that implement this property.
5716 return clang_getNullCursor();
5717
5718 case Decl::ObjCCompatibleAlias:
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005719 if (const ObjCInterfaceDecl *Class
Guy Benyei11169dd2012-12-18 14:30:41 +00005720 = cast<ObjCCompatibleAliasDecl>(D)->getClassInterface())
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005721 if (const ObjCInterfaceDecl *Def = Class->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005722 return MakeCXCursor(Def, TU);
5723
5724 return clang_getNullCursor();
5725
5726 case Decl::Friend:
5727 if (NamedDecl *Friend = cast<FriendDecl>(D)->getFriendDecl())
5728 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
5729 return clang_getNullCursor();
5730
5731 case Decl::FriendTemplate:
5732 if (NamedDecl *Friend = cast<FriendTemplateDecl>(D)->getFriendDecl())
5733 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
5734 return clang_getNullCursor();
5735 }
5736
5737 return clang_getNullCursor();
5738}
5739
5740unsigned clang_isCursorDefinition(CXCursor C) {
5741 if (!clang_isDeclaration(C.kind))
5742 return 0;
5743
5744 return clang_getCursorDefinition(C) == C;
5745}
5746
5747CXCursor clang_getCanonicalCursor(CXCursor C) {
5748 if (!clang_isDeclaration(C.kind))
5749 return C;
5750
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005751 if (const Decl *D = getCursorDecl(C)) {
5752 if (const ObjCCategoryImplDecl *CatImplD = dyn_cast<ObjCCategoryImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00005753 if (ObjCCategoryDecl *CatD = CatImplD->getCategoryDecl())
5754 return MakeCXCursor(CatD, getCursorTU(C));
5755
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005756 if (const ObjCImplDecl *ImplD = dyn_cast<ObjCImplDecl>(D))
5757 if (const ObjCInterfaceDecl *IFD = ImplD->getClassInterface())
Guy Benyei11169dd2012-12-18 14:30:41 +00005758 return MakeCXCursor(IFD, getCursorTU(C));
5759
5760 return MakeCXCursor(D->getCanonicalDecl(), getCursorTU(C));
5761 }
5762
5763 return C;
5764}
5765
5766int clang_Cursor_getObjCSelectorIndex(CXCursor cursor) {
5767 return cxcursor::getSelectorIdentifierIndexAndLoc(cursor).first;
5768}
5769
5770unsigned clang_getNumOverloadedDecls(CXCursor C) {
5771 if (C.kind != CXCursor_OverloadedDeclRef)
5772 return 0;
5773
5774 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005775 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Guy Benyei11169dd2012-12-18 14:30:41 +00005776 return E->getNumDecls();
5777
5778 if (OverloadedTemplateStorage *S
5779 = Storage.dyn_cast<OverloadedTemplateStorage*>())
5780 return S->size();
5781
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005782 const Decl *D = Storage.get<const Decl *>();
5783 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00005784 return Using->shadow_size();
5785
5786 return 0;
5787}
5788
5789CXCursor clang_getOverloadedDecl(CXCursor cursor, unsigned index) {
5790 if (cursor.kind != CXCursor_OverloadedDeclRef)
5791 return clang_getNullCursor();
5792
5793 if (index >= clang_getNumOverloadedDecls(cursor))
5794 return clang_getNullCursor();
5795
5796 CXTranslationUnit TU = getCursorTU(cursor);
5797 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(cursor).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005798 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Guy Benyei11169dd2012-12-18 14:30:41 +00005799 return MakeCXCursor(E->decls_begin()[index], TU);
5800
5801 if (OverloadedTemplateStorage *S
5802 = Storage.dyn_cast<OverloadedTemplateStorage*>())
5803 return MakeCXCursor(S->begin()[index], TU);
5804
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005805 const Decl *D = Storage.get<const Decl *>();
5806 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005807 // FIXME: This is, unfortunately, linear time.
5808 UsingDecl::shadow_iterator Pos = Using->shadow_begin();
5809 std::advance(Pos, index);
5810 return MakeCXCursor(cast<UsingShadowDecl>(*Pos)->getTargetDecl(), TU);
5811 }
5812
5813 return clang_getNullCursor();
5814}
5815
5816void clang_getDefinitionSpellingAndExtent(CXCursor C,
5817 const char **startBuf,
5818 const char **endBuf,
5819 unsigned *startLine,
5820 unsigned *startColumn,
5821 unsigned *endLine,
5822 unsigned *endColumn) {
5823 assert(getCursorDecl(C) && "CXCursor has null decl");
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005824 const FunctionDecl *FD = dyn_cast<FunctionDecl>(getCursorDecl(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00005825 CompoundStmt *Body = dyn_cast<CompoundStmt>(FD->getBody());
5826
5827 SourceManager &SM = FD->getASTContext().getSourceManager();
5828 *startBuf = SM.getCharacterData(Body->getLBracLoc());
5829 *endBuf = SM.getCharacterData(Body->getRBracLoc());
5830 *startLine = SM.getSpellingLineNumber(Body->getLBracLoc());
5831 *startColumn = SM.getSpellingColumnNumber(Body->getLBracLoc());
5832 *endLine = SM.getSpellingLineNumber(Body->getRBracLoc());
5833 *endColumn = SM.getSpellingColumnNumber(Body->getRBracLoc());
5834}
5835
5836
5837CXSourceRange clang_getCursorReferenceNameRange(CXCursor C, unsigned NameFlags,
5838 unsigned PieceIndex) {
5839 RefNamePieces Pieces;
5840
5841 switch (C.kind) {
5842 case CXCursor_MemberRefExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005843 if (const MemberExpr *E = dyn_cast<MemberExpr>(getCursorExpr(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00005844 Pieces = buildPieces(NameFlags, true, E->getMemberNameInfo(),
5845 E->getQualifierLoc().getSourceRange());
5846 break;
5847
5848 case CXCursor_DeclRefExpr:
James Y Knight04ec5bf2015-12-24 02:59:37 +00005849 if (const DeclRefExpr *E = dyn_cast<DeclRefExpr>(getCursorExpr(C))) {
5850 SourceRange TemplateArgLoc(E->getLAngleLoc(), E->getRAngleLoc());
5851 Pieces =
5852 buildPieces(NameFlags, false, E->getNameInfo(),
5853 E->getQualifierLoc().getSourceRange(), &TemplateArgLoc);
5854 }
Guy Benyei11169dd2012-12-18 14:30:41 +00005855 break;
5856
5857 case CXCursor_CallExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005858 if (const CXXOperatorCallExpr *OCE =
Guy Benyei11169dd2012-12-18 14:30:41 +00005859 dyn_cast<CXXOperatorCallExpr>(getCursorExpr(C))) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005860 const Expr *Callee = OCE->getCallee();
5861 if (const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Callee))
Guy Benyei11169dd2012-12-18 14:30:41 +00005862 Callee = ICE->getSubExpr();
5863
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005864 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(Callee))
Guy Benyei11169dd2012-12-18 14:30:41 +00005865 Pieces = buildPieces(NameFlags, false, DRE->getNameInfo(),
5866 DRE->getQualifierLoc().getSourceRange());
5867 }
5868 break;
5869
5870 default:
5871 break;
5872 }
5873
5874 if (Pieces.empty()) {
5875 if (PieceIndex == 0)
5876 return clang_getCursorExtent(C);
5877 } else if (PieceIndex < Pieces.size()) {
5878 SourceRange R = Pieces[PieceIndex];
5879 if (R.isValid())
5880 return cxloc::translateSourceRange(getCursorContext(C), R);
5881 }
5882
5883 return clang_getNullRange();
5884}
5885
5886void clang_enableStackTraces(void) {
5887 llvm::sys::PrintStackTraceOnErrorSignal();
5888}
5889
5890void clang_executeOnThread(void (*fn)(void*), void *user_data,
5891 unsigned stack_size) {
5892 llvm::llvm_execute_on_thread(fn, user_data, stack_size);
5893}
5894
5895} // end: extern "C"
5896
5897//===----------------------------------------------------------------------===//
5898// Token-based Operations.
5899//===----------------------------------------------------------------------===//
5900
5901/* CXToken layout:
5902 * int_data[0]: a CXTokenKind
5903 * int_data[1]: starting token location
5904 * int_data[2]: token length
5905 * int_data[3]: reserved
5906 * ptr_data: for identifiers and keywords, an IdentifierInfo*.
5907 * otherwise unused.
5908 */
5909extern "C" {
5910
5911CXTokenKind clang_getTokenKind(CXToken CXTok) {
5912 return static_cast<CXTokenKind>(CXTok.int_data[0]);
5913}
5914
5915CXString clang_getTokenSpelling(CXTranslationUnit TU, CXToken CXTok) {
5916 switch (clang_getTokenKind(CXTok)) {
5917 case CXToken_Identifier:
5918 case CXToken_Keyword:
5919 // We know we have an IdentifierInfo*, so use that.
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005920 return cxstring::createRef(static_cast<IdentifierInfo *>(CXTok.ptr_data)
Guy Benyei11169dd2012-12-18 14:30:41 +00005921 ->getNameStart());
5922
5923 case CXToken_Literal: {
5924 // We have stashed the starting pointer in the ptr_data field. Use it.
5925 const char *Text = static_cast<const char *>(CXTok.ptr_data);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00005926 return cxstring::createDup(StringRef(Text, CXTok.int_data[2]));
Guy Benyei11169dd2012-12-18 14:30:41 +00005927 }
5928
5929 case CXToken_Punctuation:
5930 case CXToken_Comment:
5931 break;
5932 }
5933
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005934 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005935 LOG_BAD_TU(TU);
5936 return cxstring::createEmpty();
5937 }
5938
Guy Benyei11169dd2012-12-18 14:30:41 +00005939 // We have to find the starting buffer pointer the hard way, by
5940 // deconstructing the source location.
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005941 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005942 if (!CXXUnit)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00005943 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00005944
5945 SourceLocation Loc = SourceLocation::getFromRawEncoding(CXTok.int_data[1]);
5946 std::pair<FileID, unsigned> LocInfo
5947 = CXXUnit->getSourceManager().getDecomposedSpellingLoc(Loc);
5948 bool Invalid = false;
5949 StringRef Buffer
5950 = CXXUnit->getSourceManager().getBufferData(LocInfo.first, &Invalid);
5951 if (Invalid)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00005952 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00005953
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00005954 return cxstring::createDup(Buffer.substr(LocInfo.second, CXTok.int_data[2]));
Guy Benyei11169dd2012-12-18 14:30:41 +00005955}
5956
5957CXSourceLocation clang_getTokenLocation(CXTranslationUnit TU, CXToken CXTok) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005958 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005959 LOG_BAD_TU(TU);
5960 return clang_getNullLocation();
5961 }
5962
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005963 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005964 if (!CXXUnit)
5965 return clang_getNullLocation();
5966
5967 return cxloc::translateSourceLocation(CXXUnit->getASTContext(),
5968 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
5969}
5970
5971CXSourceRange clang_getTokenExtent(CXTranslationUnit TU, CXToken CXTok) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005972 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005973 LOG_BAD_TU(TU);
5974 return clang_getNullRange();
5975 }
5976
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005977 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005978 if (!CXXUnit)
5979 return clang_getNullRange();
5980
5981 return cxloc::translateSourceRange(CXXUnit->getASTContext(),
5982 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
5983}
5984
5985static void getTokens(ASTUnit *CXXUnit, SourceRange Range,
5986 SmallVectorImpl<CXToken> &CXTokens) {
5987 SourceManager &SourceMgr = CXXUnit->getSourceManager();
5988 std::pair<FileID, unsigned> BeginLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005989 = SourceMgr.getDecomposedSpellingLoc(Range.getBegin());
Guy Benyei11169dd2012-12-18 14:30:41 +00005990 std::pair<FileID, unsigned> EndLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005991 = SourceMgr.getDecomposedSpellingLoc(Range.getEnd());
Guy Benyei11169dd2012-12-18 14:30:41 +00005992
5993 // Cannot tokenize across files.
5994 if (BeginLocInfo.first != EndLocInfo.first)
5995 return;
5996
5997 // Create a lexer
5998 bool Invalid = false;
5999 StringRef Buffer
6000 = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
6001 if (Invalid)
6002 return;
6003
6004 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
6005 CXXUnit->getASTContext().getLangOpts(),
6006 Buffer.begin(), Buffer.data() + BeginLocInfo.second, Buffer.end());
6007 Lex.SetCommentRetentionState(true);
6008
6009 // Lex tokens until we hit the end of the range.
6010 const char *EffectiveBufferEnd = Buffer.data() + EndLocInfo.second;
6011 Token Tok;
6012 bool previousWasAt = false;
6013 do {
6014 // Lex the next token
6015 Lex.LexFromRawLexer(Tok);
6016 if (Tok.is(tok::eof))
6017 break;
6018
6019 // Initialize the CXToken.
6020 CXToken CXTok;
6021
6022 // - Common fields
6023 CXTok.int_data[1] = Tok.getLocation().getRawEncoding();
6024 CXTok.int_data[2] = Tok.getLength();
6025 CXTok.int_data[3] = 0;
6026
6027 // - Kind-specific fields
6028 if (Tok.isLiteral()) {
6029 CXTok.int_data[0] = CXToken_Literal;
Dmitri Gribenkof9304482013-01-23 15:56:07 +00006030 CXTok.ptr_data = const_cast<char *>(Tok.getLiteralData());
Guy Benyei11169dd2012-12-18 14:30:41 +00006031 } else if (Tok.is(tok::raw_identifier)) {
6032 // Lookup the identifier to determine whether we have a keyword.
6033 IdentifierInfo *II
6034 = CXXUnit->getPreprocessor().LookUpIdentifierInfo(Tok);
6035
6036 if ((II->getObjCKeywordID() != tok::objc_not_keyword) && previousWasAt) {
6037 CXTok.int_data[0] = CXToken_Keyword;
6038 }
6039 else {
6040 CXTok.int_data[0] = Tok.is(tok::identifier)
6041 ? CXToken_Identifier
6042 : CXToken_Keyword;
6043 }
6044 CXTok.ptr_data = II;
6045 } else if (Tok.is(tok::comment)) {
6046 CXTok.int_data[0] = CXToken_Comment;
Craig Topper69186e72014-06-08 08:38:04 +00006047 CXTok.ptr_data = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006048 } else {
6049 CXTok.int_data[0] = CXToken_Punctuation;
Craig Topper69186e72014-06-08 08:38:04 +00006050 CXTok.ptr_data = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006051 }
6052 CXTokens.push_back(CXTok);
6053 previousWasAt = Tok.is(tok::at);
6054 } while (Lex.getBufferLocation() <= EffectiveBufferEnd);
6055}
6056
6057void clang_tokenize(CXTranslationUnit TU, CXSourceRange Range,
6058 CXToken **Tokens, unsigned *NumTokens) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006059 LOG_FUNC_SECTION {
6060 *Log << TU << ' ' << Range;
6061 }
6062
Guy Benyei11169dd2012-12-18 14:30:41 +00006063 if (Tokens)
Craig Topper69186e72014-06-08 08:38:04 +00006064 *Tokens = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006065 if (NumTokens)
6066 *NumTokens = 0;
6067
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006068 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006069 LOG_BAD_TU(TU);
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00006070 return;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006071 }
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00006072
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006073 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00006074 if (!CXXUnit || !Tokens || !NumTokens)
6075 return;
6076
6077 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
6078
6079 SourceRange R = cxloc::translateCXSourceRange(Range);
6080 if (R.isInvalid())
6081 return;
6082
6083 SmallVector<CXToken, 32> CXTokens;
6084 getTokens(CXXUnit, R, CXTokens);
6085
6086 if (CXTokens.empty())
6087 return;
6088
6089 *Tokens = (CXToken *)malloc(sizeof(CXToken) * CXTokens.size());
6090 memmove(*Tokens, CXTokens.data(), sizeof(CXToken) * CXTokens.size());
6091 *NumTokens = CXTokens.size();
6092}
6093
6094void clang_disposeTokens(CXTranslationUnit TU,
6095 CXToken *Tokens, unsigned NumTokens) {
6096 free(Tokens);
6097}
6098
6099} // end: extern "C"
6100
6101//===----------------------------------------------------------------------===//
6102// Token annotation APIs.
6103//===----------------------------------------------------------------------===//
6104
Guy Benyei11169dd2012-12-18 14:30:41 +00006105static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
6106 CXCursor parent,
6107 CXClientData client_data);
6108static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
6109 CXClientData client_data);
6110
6111namespace {
6112class AnnotateTokensWorker {
Guy Benyei11169dd2012-12-18 14:30:41 +00006113 CXToken *Tokens;
6114 CXCursor *Cursors;
6115 unsigned NumTokens;
6116 unsigned TokIdx;
6117 unsigned PreprocessingTokIdx;
6118 CursorVisitor AnnotateVis;
6119 SourceManager &SrcMgr;
6120 bool HasContextSensitiveKeywords;
6121
6122 struct PostChildrenInfo {
6123 CXCursor Cursor;
6124 SourceRange CursorRange;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00006125 unsigned BeforeReachingCursorIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00006126 unsigned BeforeChildrenTokenIdx;
6127 };
Dmitri Gribenkof8579502013-01-12 19:30:44 +00006128 SmallVector<PostChildrenInfo, 8> PostChildrenInfos;
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00006129
6130 CXToken &getTok(unsigned Idx) {
6131 assert(Idx < NumTokens);
6132 return Tokens[Idx];
6133 }
6134 const CXToken &getTok(unsigned Idx) const {
6135 assert(Idx < NumTokens);
6136 return Tokens[Idx];
6137 }
Guy Benyei11169dd2012-12-18 14:30:41 +00006138 bool MoreTokens() const { return TokIdx < NumTokens; }
6139 unsigned NextToken() const { return TokIdx; }
6140 void AdvanceToken() { ++TokIdx; }
6141 SourceLocation GetTokenLoc(unsigned tokI) {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00006142 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[1]);
Guy Benyei11169dd2012-12-18 14:30:41 +00006143 }
6144 bool isFunctionMacroToken(unsigned tokI) const {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00006145 return getTok(tokI).int_data[3] != 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00006146 }
6147 SourceLocation getFunctionMacroTokenLoc(unsigned tokI) const {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00006148 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[3]);
Guy Benyei11169dd2012-12-18 14:30:41 +00006149 }
6150
6151 void annotateAndAdvanceTokens(CXCursor, RangeComparisonResult, SourceRange);
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00006152 bool annotateAndAdvanceFunctionMacroTokens(CXCursor, RangeComparisonResult,
Guy Benyei11169dd2012-12-18 14:30:41 +00006153 SourceRange);
6154
6155public:
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006156 AnnotateTokensWorker(CXToken *tokens, CXCursor *cursors, unsigned numTokens,
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006157 CXTranslationUnit TU, SourceRange RegionOfInterest)
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006158 : Tokens(tokens), Cursors(cursors),
Guy Benyei11169dd2012-12-18 14:30:41 +00006159 NumTokens(numTokens), TokIdx(0), PreprocessingTokIdx(0),
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006160 AnnotateVis(TU,
Guy Benyei11169dd2012-12-18 14:30:41 +00006161 AnnotateTokensVisitor, this,
6162 /*VisitPreprocessorLast=*/true,
6163 /*VisitIncludedEntities=*/false,
6164 RegionOfInterest,
6165 /*VisitDeclsOnly=*/false,
6166 AnnotateTokensPostChildrenVisitor),
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006167 SrcMgr(cxtu::getASTUnit(TU)->getSourceManager()),
Guy Benyei11169dd2012-12-18 14:30:41 +00006168 HasContextSensitiveKeywords(false) { }
6169
6170 void VisitChildren(CXCursor C) { AnnotateVis.VisitChildren(C); }
6171 enum CXChildVisitResult Visit(CXCursor cursor, CXCursor parent);
6172 bool postVisitChildren(CXCursor cursor);
6173 void AnnotateTokens();
6174
6175 /// \brief Determine whether the annotator saw any cursors that have
6176 /// context-sensitive keywords.
6177 bool hasContextSensitiveKeywords() const {
6178 return HasContextSensitiveKeywords;
6179 }
6180
6181 ~AnnotateTokensWorker() {
6182 assert(PostChildrenInfos.empty());
6183 }
6184};
Alexander Kornienkoab9db512015-06-22 23:07:51 +00006185}
Guy Benyei11169dd2012-12-18 14:30:41 +00006186
6187void AnnotateTokensWorker::AnnotateTokens() {
6188 // Walk the AST within the region of interest, annotating tokens
6189 // along the way.
6190 AnnotateVis.visitFileRegion();
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006191}
Guy Benyei11169dd2012-12-18 14:30:41 +00006192
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006193static inline void updateCursorAnnotation(CXCursor &Cursor,
6194 const CXCursor &updateC) {
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00006195 if (clang_isInvalid(updateC.kind) || !clang_isInvalid(Cursor.kind))
Guy Benyei11169dd2012-12-18 14:30:41 +00006196 return;
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006197 Cursor = updateC;
Guy Benyei11169dd2012-12-18 14:30:41 +00006198}
6199
6200/// \brief It annotates and advances tokens with a cursor until the comparison
6201//// between the cursor location and the source range is the same as
6202/// \arg compResult.
6203///
6204/// Pass RangeBefore to annotate tokens with a cursor until a range is reached.
6205/// Pass RangeOverlap to annotate tokens inside a range.
6206void AnnotateTokensWorker::annotateAndAdvanceTokens(CXCursor updateC,
6207 RangeComparisonResult compResult,
6208 SourceRange range) {
6209 while (MoreTokens()) {
6210 const unsigned I = NextToken();
6211 if (isFunctionMacroToken(I))
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00006212 if (!annotateAndAdvanceFunctionMacroTokens(updateC, compResult, range))
6213 return;
Guy Benyei11169dd2012-12-18 14:30:41 +00006214
6215 SourceLocation TokLoc = GetTokenLoc(I);
6216 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006217 updateCursorAnnotation(Cursors[I], updateC);
Guy Benyei11169dd2012-12-18 14:30:41 +00006218 AdvanceToken();
6219 continue;
6220 }
6221 break;
6222 }
6223}
6224
6225/// \brief Special annotation handling for macro argument tokens.
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00006226/// \returns true if it advanced beyond all macro tokens, false otherwise.
6227bool AnnotateTokensWorker::annotateAndAdvanceFunctionMacroTokens(
Guy Benyei11169dd2012-12-18 14:30:41 +00006228 CXCursor updateC,
6229 RangeComparisonResult compResult,
6230 SourceRange range) {
6231 assert(MoreTokens());
6232 assert(isFunctionMacroToken(NextToken()) &&
6233 "Should be called only for macro arg tokens");
6234
6235 // This works differently than annotateAndAdvanceTokens; because expanded
6236 // macro arguments can have arbitrary translation-unit source order, we do not
6237 // advance the token index one by one until a token fails the range test.
6238 // We only advance once past all of the macro arg tokens if all of them
6239 // pass the range test. If one of them fails we keep the token index pointing
6240 // at the start of the macro arg tokens so that the failing token will be
6241 // annotated by a subsequent annotation try.
6242
6243 bool atLeastOneCompFail = false;
6244
6245 unsigned I = NextToken();
6246 for (; I < NumTokens && isFunctionMacroToken(I); ++I) {
6247 SourceLocation TokLoc = getFunctionMacroTokenLoc(I);
6248 if (TokLoc.isFileID())
6249 continue; // not macro arg token, it's parens or comma.
6250 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
6251 if (clang_isInvalid(clang_getCursorKind(Cursors[I])))
6252 Cursors[I] = updateC;
6253 } else
6254 atLeastOneCompFail = true;
6255 }
6256
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00006257 if (atLeastOneCompFail)
6258 return false;
6259
6260 TokIdx = I; // All of the tokens were handled, advance beyond all of them.
6261 return true;
Guy Benyei11169dd2012-12-18 14:30:41 +00006262}
6263
6264enum CXChildVisitResult
6265AnnotateTokensWorker::Visit(CXCursor cursor, CXCursor parent) {
Guy Benyei11169dd2012-12-18 14:30:41 +00006266 SourceRange cursorRange = getRawCursorExtent(cursor);
6267 if (cursorRange.isInvalid())
6268 return CXChildVisit_Recurse;
6269
6270 if (!HasContextSensitiveKeywords) {
6271 // Objective-C properties can have context-sensitive keywords.
6272 if (cursor.kind == CXCursor_ObjCPropertyDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006273 if (const ObjCPropertyDecl *Property
Guy Benyei11169dd2012-12-18 14:30:41 +00006274 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(cursor)))
6275 HasContextSensitiveKeywords = Property->getPropertyAttributesAsWritten() != 0;
6276 }
6277 // Objective-C methods can have context-sensitive keywords.
6278 else if (cursor.kind == CXCursor_ObjCInstanceMethodDecl ||
6279 cursor.kind == CXCursor_ObjCClassMethodDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006280 if (const ObjCMethodDecl *Method
Guy Benyei11169dd2012-12-18 14:30:41 +00006281 = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
6282 if (Method->getObjCDeclQualifier())
6283 HasContextSensitiveKeywords = true;
6284 else {
Aaron Ballman43b68be2014-03-07 17:50:17 +00006285 for (const auto *P : Method->params()) {
6286 if (P->getObjCDeclQualifier()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00006287 HasContextSensitiveKeywords = true;
6288 break;
6289 }
6290 }
6291 }
6292 }
6293 }
6294 // C++ methods can have context-sensitive keywords.
6295 else if (cursor.kind == CXCursor_CXXMethod) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006296 if (const CXXMethodDecl *Method
Guy Benyei11169dd2012-12-18 14:30:41 +00006297 = dyn_cast_or_null<CXXMethodDecl>(getCursorDecl(cursor))) {
6298 if (Method->hasAttr<FinalAttr>() || Method->hasAttr<OverrideAttr>())
6299 HasContextSensitiveKeywords = true;
6300 }
6301 }
6302 // C++ classes can have context-sensitive keywords.
6303 else if (cursor.kind == CXCursor_StructDecl ||
6304 cursor.kind == CXCursor_ClassDecl ||
6305 cursor.kind == CXCursor_ClassTemplate ||
6306 cursor.kind == CXCursor_ClassTemplatePartialSpecialization) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006307 if (const Decl *D = getCursorDecl(cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +00006308 if (D->hasAttr<FinalAttr>())
6309 HasContextSensitiveKeywords = true;
6310 }
6311 }
Argyrios Kyrtzidis990b3862013-06-04 18:24:30 +00006312
6313 // Don't override a property annotation with its getter/setter method.
6314 if (cursor.kind == CXCursor_ObjCInstanceMethodDecl &&
6315 parent.kind == CXCursor_ObjCPropertyDecl)
6316 return CXChildVisit_Continue;
Guy Benyei11169dd2012-12-18 14:30:41 +00006317
6318 if (clang_isPreprocessing(cursor.kind)) {
6319 // Items in the preprocessing record are kept separate from items in
6320 // declarations, so we keep a separate token index.
6321 unsigned SavedTokIdx = TokIdx;
6322 TokIdx = PreprocessingTokIdx;
6323
6324 // Skip tokens up until we catch up to the beginning of the preprocessing
6325 // entry.
6326 while (MoreTokens()) {
6327 const unsigned I = NextToken();
6328 SourceLocation TokLoc = GetTokenLoc(I);
6329 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
6330 case RangeBefore:
6331 AdvanceToken();
6332 continue;
6333 case RangeAfter:
6334 case RangeOverlap:
6335 break;
6336 }
6337 break;
6338 }
6339
6340 // Look at all of the tokens within this range.
6341 while (MoreTokens()) {
6342 const unsigned I = NextToken();
6343 SourceLocation TokLoc = GetTokenLoc(I);
6344 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
6345 case RangeBefore:
6346 llvm_unreachable("Infeasible");
6347 case RangeAfter:
6348 break;
6349 case RangeOverlap:
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00006350 // For macro expansions, just note where the beginning of the macro
6351 // expansion occurs.
6352 if (cursor.kind == CXCursor_MacroExpansion) {
6353 if (TokLoc == cursorRange.getBegin())
6354 Cursors[I] = cursor;
6355 AdvanceToken();
6356 break;
6357 }
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006358 // We may have already annotated macro names inside macro definitions.
6359 if (Cursors[I].kind != CXCursor_MacroExpansion)
6360 Cursors[I] = cursor;
Guy Benyei11169dd2012-12-18 14:30:41 +00006361 AdvanceToken();
Guy Benyei11169dd2012-12-18 14:30:41 +00006362 continue;
6363 }
6364 break;
6365 }
6366
6367 // Save the preprocessing token index; restore the non-preprocessing
6368 // token index.
6369 PreprocessingTokIdx = TokIdx;
6370 TokIdx = SavedTokIdx;
6371 return CXChildVisit_Recurse;
6372 }
6373
6374 if (cursorRange.isInvalid())
6375 return CXChildVisit_Continue;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00006376
6377 unsigned BeforeReachingCursorIdx = NextToken();
Guy Benyei11169dd2012-12-18 14:30:41 +00006378 const enum CXCursorKind cursorK = clang_getCursorKind(cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00006379 const enum CXCursorKind K = clang_getCursorKind(parent);
6380 const CXCursor updateC =
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00006381 (clang_isInvalid(K) || K == CXCursor_TranslationUnit ||
6382 // Attributes are annotated out-of-order, skip tokens until we reach it.
6383 clang_isAttribute(cursor.kind))
Guy Benyei11169dd2012-12-18 14:30:41 +00006384 ? clang_getNullCursor() : parent;
6385
6386 annotateAndAdvanceTokens(updateC, RangeBefore, cursorRange);
6387
6388 // Avoid having the cursor of an expression "overwrite" the annotation of the
6389 // variable declaration that it belongs to.
6390 // This can happen for C++ constructor expressions whose range generally
6391 // include the variable declaration, e.g.:
6392 // MyCXXClass foo; // Make sure we don't annotate 'foo' as a CallExpr cursor.
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00006393 if (clang_isExpression(cursorK) && MoreTokens()) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00006394 const Expr *E = getCursorExpr(cursor);
Dmitri Gribenkoa1691182013-01-26 18:12:08 +00006395 if (const Decl *D = getCursorParentDecl(cursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00006396 const unsigned I = NextToken();
6397 if (E->getLocStart().isValid() && D->getLocation().isValid() &&
6398 E->getLocStart() == D->getLocation() &&
6399 E->getLocStart() == GetTokenLoc(I)) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006400 updateCursorAnnotation(Cursors[I], updateC);
Guy Benyei11169dd2012-12-18 14:30:41 +00006401 AdvanceToken();
6402 }
6403 }
6404 }
6405
6406 // Before recursing into the children keep some state that we are going
6407 // to use in the AnnotateTokensWorker::postVisitChildren callback to do some
6408 // extra work after the child nodes are visited.
6409 // Note that we don't call VisitChildren here to avoid traversing statements
6410 // code-recursively which can blow the stack.
6411
6412 PostChildrenInfo Info;
6413 Info.Cursor = cursor;
6414 Info.CursorRange = cursorRange;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00006415 Info.BeforeReachingCursorIdx = BeforeReachingCursorIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00006416 Info.BeforeChildrenTokenIdx = NextToken();
6417 PostChildrenInfos.push_back(Info);
6418
6419 return CXChildVisit_Recurse;
6420}
6421
6422bool AnnotateTokensWorker::postVisitChildren(CXCursor cursor) {
6423 if (PostChildrenInfos.empty())
6424 return false;
6425 const PostChildrenInfo &Info = PostChildrenInfos.back();
6426 if (!clang_equalCursors(Info.Cursor, cursor))
6427 return false;
6428
6429 const unsigned BeforeChildren = Info.BeforeChildrenTokenIdx;
6430 const unsigned AfterChildren = NextToken();
6431 SourceRange cursorRange = Info.CursorRange;
6432
6433 // Scan the tokens that are at the end of the cursor, but are not captured
6434 // but the child cursors.
6435 annotateAndAdvanceTokens(cursor, RangeOverlap, cursorRange);
6436
6437 // Scan the tokens that are at the beginning of the cursor, but are not
6438 // capture by the child cursors.
6439 for (unsigned I = BeforeChildren; I != AfterChildren; ++I) {
6440 if (!clang_isInvalid(clang_getCursorKind(Cursors[I])))
6441 break;
6442
6443 Cursors[I] = cursor;
6444 }
6445
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00006446 // Attributes are annotated out-of-order, rewind TokIdx to when we first
6447 // encountered the attribute cursor.
6448 if (clang_isAttribute(cursor.kind))
6449 TokIdx = Info.BeforeReachingCursorIdx;
6450
Guy Benyei11169dd2012-12-18 14:30:41 +00006451 PostChildrenInfos.pop_back();
6452 return false;
6453}
6454
6455static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
6456 CXCursor parent,
6457 CXClientData client_data) {
6458 return static_cast<AnnotateTokensWorker*>(client_data)->Visit(cursor, parent);
6459}
6460
6461static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
6462 CXClientData client_data) {
6463 return static_cast<AnnotateTokensWorker*>(client_data)->
6464 postVisitChildren(cursor);
6465}
6466
6467namespace {
6468
6469/// \brief Uses the macro expansions in the preprocessing record to find
6470/// and mark tokens that are macro arguments. This info is used by the
6471/// AnnotateTokensWorker.
6472class MarkMacroArgTokensVisitor {
6473 SourceManager &SM;
6474 CXToken *Tokens;
6475 unsigned NumTokens;
6476 unsigned CurIdx;
6477
6478public:
6479 MarkMacroArgTokensVisitor(SourceManager &SM,
6480 CXToken *tokens, unsigned numTokens)
6481 : SM(SM), Tokens(tokens), NumTokens(numTokens), CurIdx(0) { }
6482
6483 CXChildVisitResult visit(CXCursor cursor, CXCursor parent) {
6484 if (cursor.kind != CXCursor_MacroExpansion)
6485 return CXChildVisit_Continue;
6486
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006487 SourceRange macroRange = getCursorMacroExpansion(cursor).getSourceRange();
Guy Benyei11169dd2012-12-18 14:30:41 +00006488 if (macroRange.getBegin() == macroRange.getEnd())
6489 return CXChildVisit_Continue; // it's not a function macro.
6490
6491 for (; CurIdx < NumTokens; ++CurIdx) {
6492 if (!SM.isBeforeInTranslationUnit(getTokenLoc(CurIdx),
6493 macroRange.getBegin()))
6494 break;
6495 }
6496
6497 if (CurIdx == NumTokens)
6498 return CXChildVisit_Break;
6499
6500 for (; CurIdx < NumTokens; ++CurIdx) {
6501 SourceLocation tokLoc = getTokenLoc(CurIdx);
6502 if (!SM.isBeforeInTranslationUnit(tokLoc, macroRange.getEnd()))
6503 break;
6504
6505 setFunctionMacroTokenLoc(CurIdx, SM.getMacroArgExpandedLocation(tokLoc));
6506 }
6507
6508 if (CurIdx == NumTokens)
6509 return CXChildVisit_Break;
6510
6511 return CXChildVisit_Continue;
6512 }
6513
6514private:
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00006515 CXToken &getTok(unsigned Idx) {
6516 assert(Idx < NumTokens);
6517 return Tokens[Idx];
6518 }
6519 const CXToken &getTok(unsigned Idx) const {
6520 assert(Idx < NumTokens);
6521 return Tokens[Idx];
6522 }
6523
Guy Benyei11169dd2012-12-18 14:30:41 +00006524 SourceLocation getTokenLoc(unsigned tokI) {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00006525 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[1]);
Guy Benyei11169dd2012-12-18 14:30:41 +00006526 }
6527
6528 void setFunctionMacroTokenLoc(unsigned tokI, SourceLocation loc) {
6529 // The third field is reserved and currently not used. Use it here
6530 // to mark macro arg expanded tokens with their expanded locations.
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00006531 getTok(tokI).int_data[3] = loc.getRawEncoding();
Guy Benyei11169dd2012-12-18 14:30:41 +00006532 }
6533};
6534
6535} // end anonymous namespace
6536
6537static CXChildVisitResult
6538MarkMacroArgTokensVisitorDelegate(CXCursor cursor, CXCursor parent,
6539 CXClientData client_data) {
6540 return static_cast<MarkMacroArgTokensVisitor*>(client_data)->visit(cursor,
6541 parent);
6542}
6543
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006544/// \brief Used by \c annotatePreprocessorTokens.
6545/// \returns true if lexing was finished, false otherwise.
6546static bool lexNext(Lexer &Lex, Token &Tok,
6547 unsigned &NextIdx, unsigned NumTokens) {
6548 if (NextIdx >= NumTokens)
6549 return true;
6550
6551 ++NextIdx;
6552 Lex.LexFromRawLexer(Tok);
Alexander Kornienko1a9f1842015-12-28 15:24:08 +00006553 return Tok.is(tok::eof);
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006554}
6555
Guy Benyei11169dd2012-12-18 14:30:41 +00006556static void annotatePreprocessorTokens(CXTranslationUnit TU,
6557 SourceRange RegionOfInterest,
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006558 CXCursor *Cursors,
6559 CXToken *Tokens,
6560 unsigned NumTokens) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006561 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00006562
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006563 Preprocessor &PP = CXXUnit->getPreprocessor();
Guy Benyei11169dd2012-12-18 14:30:41 +00006564 SourceManager &SourceMgr = CXXUnit->getSourceManager();
6565 std::pair<FileID, unsigned> BeginLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00006566 = SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getBegin());
Guy Benyei11169dd2012-12-18 14:30:41 +00006567 std::pair<FileID, unsigned> EndLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00006568 = SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getEnd());
Guy Benyei11169dd2012-12-18 14:30:41 +00006569
6570 if (BeginLocInfo.first != EndLocInfo.first)
6571 return;
6572
6573 StringRef Buffer;
6574 bool Invalid = false;
6575 Buffer = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
6576 if (Buffer.empty() || Invalid)
6577 return;
6578
6579 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
6580 CXXUnit->getASTContext().getLangOpts(),
6581 Buffer.begin(), Buffer.data() + BeginLocInfo.second,
6582 Buffer.end());
6583 Lex.SetCommentRetentionState(true);
6584
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006585 unsigned NextIdx = 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00006586 // Lex tokens in raw mode until we hit the end of the range, to avoid
6587 // entering #includes or expanding macros.
6588 while (true) {
6589 Token Tok;
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006590 if (lexNext(Lex, Tok, NextIdx, NumTokens))
6591 break;
6592 unsigned TokIdx = NextIdx-1;
6593 assert(Tok.getLocation() ==
6594 SourceLocation::getFromRawEncoding(Tokens[TokIdx].int_data[1]));
Guy Benyei11169dd2012-12-18 14:30:41 +00006595
6596 reprocess:
6597 if (Tok.is(tok::hash) && Tok.isAtStartOfLine()) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006598 // We have found a preprocessing directive. Annotate the tokens
6599 // appropriately.
Guy Benyei11169dd2012-12-18 14:30:41 +00006600 //
6601 // FIXME: Some simple tests here could identify macro definitions and
6602 // #undefs, to provide specific cursor kinds for those.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006603
6604 SourceLocation BeginLoc = Tok.getLocation();
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006605 if (lexNext(Lex, Tok, NextIdx, NumTokens))
6606 break;
6607
Craig Topper69186e72014-06-08 08:38:04 +00006608 MacroInfo *MI = nullptr;
Alp Toker2d57cea2014-05-17 04:53:25 +00006609 if (Tok.is(tok::raw_identifier) && Tok.getRawIdentifier() == "define") {
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006610 if (lexNext(Lex, Tok, NextIdx, NumTokens))
6611 break;
6612
6613 if (Tok.is(tok::raw_identifier)) {
Alp Toker2d57cea2014-05-17 04:53:25 +00006614 IdentifierInfo &II =
6615 PP.getIdentifierTable().get(Tok.getRawIdentifier());
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006616 SourceLocation MappedTokLoc =
6617 CXXUnit->mapLocationToPreamble(Tok.getLocation());
6618 MI = getMacroInfo(II, MappedTokLoc, TU);
6619 }
6620 }
6621
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006622 bool finished = false;
Guy Benyei11169dd2012-12-18 14:30:41 +00006623 do {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006624 if (lexNext(Lex, Tok, NextIdx, NumTokens)) {
6625 finished = true;
6626 break;
6627 }
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006628 // If we are in a macro definition, check if the token was ever a
6629 // macro name and annotate it if that's the case.
6630 if (MI) {
6631 SourceLocation SaveLoc = Tok.getLocation();
6632 Tok.setLocation(CXXUnit->mapLocationToPreamble(SaveLoc));
Richard Smith66a81862015-05-04 02:25:31 +00006633 MacroDefinitionRecord *MacroDef =
6634 checkForMacroInMacroDefinition(MI, Tok, TU);
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006635 Tok.setLocation(SaveLoc);
6636 if (MacroDef)
Richard Smith66a81862015-05-04 02:25:31 +00006637 Cursors[NextIdx - 1] =
6638 MakeMacroExpansionCursor(MacroDef, Tok.getLocation(), TU);
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006639 }
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006640 } while (!Tok.isAtStartOfLine());
6641
6642 unsigned LastIdx = finished ? NextIdx-1 : NextIdx-2;
6643 assert(TokIdx <= LastIdx);
6644 SourceLocation EndLoc =
6645 SourceLocation::getFromRawEncoding(Tokens[LastIdx].int_data[1]);
6646 CXCursor Cursor =
6647 MakePreprocessingDirectiveCursor(SourceRange(BeginLoc, EndLoc), TU);
6648
6649 for (; TokIdx <= LastIdx; ++TokIdx)
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006650 updateCursorAnnotation(Cursors[TokIdx], Cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00006651
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006652 if (finished)
6653 break;
6654 goto reprocess;
Guy Benyei11169dd2012-12-18 14:30:41 +00006655 }
Guy Benyei11169dd2012-12-18 14:30:41 +00006656 }
6657}
6658
6659// This gets run a separate thread to avoid stack blowout.
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00006660static void clang_annotateTokensImpl(CXTranslationUnit TU, ASTUnit *CXXUnit,
6661 CXToken *Tokens, unsigned NumTokens,
6662 CXCursor *Cursors) {
Dmitri Gribenko183436e2013-01-26 21:49:50 +00006663 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00006664 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
6665 setThreadBackgroundPriority();
6666
6667 // Determine the region of interest, which contains all of the tokens.
6668 SourceRange RegionOfInterest;
6669 RegionOfInterest.setBegin(
6670 cxloc::translateSourceLocation(clang_getTokenLocation(TU, Tokens[0])));
6671 RegionOfInterest.setEnd(
6672 cxloc::translateSourceLocation(clang_getTokenLocation(TU,
6673 Tokens[NumTokens-1])));
6674
Guy Benyei11169dd2012-12-18 14:30:41 +00006675 // Relex the tokens within the source range to look for preprocessing
6676 // directives.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006677 annotatePreprocessorTokens(TU, RegionOfInterest, Cursors, Tokens, NumTokens);
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00006678
6679 // If begin location points inside a macro argument, set it to the expansion
6680 // location so we can have the full context when annotating semantically.
6681 {
6682 SourceManager &SM = CXXUnit->getSourceManager();
6683 SourceLocation Loc =
6684 SM.getMacroArgExpandedLocation(RegionOfInterest.getBegin());
6685 if (Loc.isMacroID())
6686 RegionOfInterest.setBegin(SM.getExpansionLoc(Loc));
6687 }
6688
Guy Benyei11169dd2012-12-18 14:30:41 +00006689 if (CXXUnit->getPreprocessor().getPreprocessingRecord()) {
6690 // Search and mark tokens that are macro argument expansions.
6691 MarkMacroArgTokensVisitor Visitor(CXXUnit->getSourceManager(),
6692 Tokens, NumTokens);
6693 CursorVisitor MacroArgMarker(TU,
6694 MarkMacroArgTokensVisitorDelegate, &Visitor,
6695 /*VisitPreprocessorLast=*/true,
6696 /*VisitIncludedEntities=*/false,
6697 RegionOfInterest);
6698 MacroArgMarker.visitPreprocessedEntitiesInRegion();
6699 }
6700
6701 // Annotate all of the source locations in the region of interest that map to
6702 // a specific cursor.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006703 AnnotateTokensWorker W(Tokens, Cursors, NumTokens, TU, RegionOfInterest);
Guy Benyei11169dd2012-12-18 14:30:41 +00006704
6705 // FIXME: We use a ridiculous stack size here because the data-recursion
6706 // algorithm uses a large stack frame than the non-data recursive version,
6707 // and AnnotationTokensWorker currently transforms the data-recursion
6708 // algorithm back into a traditional recursion by explicitly calling
6709 // VisitChildren(). We will need to remove this explicit recursive call.
6710 W.AnnotateTokens();
6711
6712 // If we ran into any entities that involve context-sensitive keywords,
6713 // take another pass through the tokens to mark them as such.
6714 if (W.hasContextSensitiveKeywords()) {
6715 for (unsigned I = 0; I != NumTokens; ++I) {
6716 if (clang_getTokenKind(Tokens[I]) != CXToken_Identifier)
6717 continue;
6718
6719 if (Cursors[I].kind == CXCursor_ObjCPropertyDecl) {
6720 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006721 if (const ObjCPropertyDecl *Property
Guy Benyei11169dd2012-12-18 14:30:41 +00006722 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(Cursors[I]))) {
6723 if (Property->getPropertyAttributesAsWritten() != 0 &&
6724 llvm::StringSwitch<bool>(II->getName())
6725 .Case("readonly", true)
6726 .Case("assign", true)
6727 .Case("unsafe_unretained", true)
6728 .Case("readwrite", true)
6729 .Case("retain", true)
6730 .Case("copy", true)
6731 .Case("nonatomic", true)
6732 .Case("atomic", true)
6733 .Case("getter", true)
6734 .Case("setter", true)
6735 .Case("strong", true)
6736 .Case("weak", true)
6737 .Default(false))
6738 Tokens[I].int_data[0] = CXToken_Keyword;
6739 }
6740 continue;
6741 }
6742
6743 if (Cursors[I].kind == CXCursor_ObjCInstanceMethodDecl ||
6744 Cursors[I].kind == CXCursor_ObjCClassMethodDecl) {
6745 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
6746 if (llvm::StringSwitch<bool>(II->getName())
6747 .Case("in", true)
6748 .Case("out", true)
6749 .Case("inout", true)
6750 .Case("oneway", true)
6751 .Case("bycopy", true)
6752 .Case("byref", true)
6753 .Default(false))
6754 Tokens[I].int_data[0] = CXToken_Keyword;
6755 continue;
6756 }
6757
6758 if (Cursors[I].kind == CXCursor_CXXFinalAttr ||
6759 Cursors[I].kind == CXCursor_CXXOverrideAttr) {
6760 Tokens[I].int_data[0] = CXToken_Keyword;
6761 continue;
6762 }
6763 }
6764 }
6765}
6766
6767extern "C" {
6768
6769void clang_annotateTokens(CXTranslationUnit TU,
6770 CXToken *Tokens, unsigned NumTokens,
6771 CXCursor *Cursors) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006772 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006773 LOG_BAD_TU(TU);
6774 return;
6775 }
6776 if (NumTokens == 0 || !Tokens || !Cursors) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006777 LOG_FUNC_SECTION { *Log << "<null input>"; }
Guy Benyei11169dd2012-12-18 14:30:41 +00006778 return;
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006779 }
6780
6781 LOG_FUNC_SECTION {
6782 *Log << TU << ' ';
6783 CXSourceLocation bloc = clang_getTokenLocation(TU, Tokens[0]);
6784 CXSourceLocation eloc = clang_getTokenLocation(TU, Tokens[NumTokens-1]);
6785 *Log << clang_getRange(bloc, eloc);
6786 }
Guy Benyei11169dd2012-12-18 14:30:41 +00006787
6788 // Any token we don't specifically annotate will have a NULL cursor.
6789 CXCursor C = clang_getNullCursor();
6790 for (unsigned I = 0; I != NumTokens; ++I)
6791 Cursors[I] = C;
6792
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006793 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00006794 if (!CXXUnit)
6795 return;
6796
6797 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00006798
6799 auto AnnotateTokensImpl = [=]() {
6800 clang_annotateTokensImpl(TU, CXXUnit, Tokens, NumTokens, Cursors);
6801 };
Guy Benyei11169dd2012-12-18 14:30:41 +00006802 llvm::CrashRecoveryContext CRC;
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00006803 if (!RunSafely(CRC, AnnotateTokensImpl, GetSafetyThreadStackSize() * 2)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00006804 fprintf(stderr, "libclang: crash detected while annotating tokens\n");
6805 }
6806}
6807
6808} // end: extern "C"
6809
6810//===----------------------------------------------------------------------===//
6811// Operations for querying linkage of a cursor.
6812//===----------------------------------------------------------------------===//
6813
6814extern "C" {
6815CXLinkageKind clang_getCursorLinkage(CXCursor cursor) {
6816 if (!clang_isDeclaration(cursor.kind))
6817 return CXLinkage_Invalid;
6818
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006819 const Decl *D = cxcursor::getCursorDecl(cursor);
6820 if (const NamedDecl *ND = dyn_cast_or_null<NamedDecl>(D))
Rafael Espindola3ae00052013-05-13 00:12:11 +00006821 switch (ND->getLinkageInternal()) {
Rafael Espindola50df3a02013-05-25 17:16:20 +00006822 case NoLinkage:
6823 case VisibleNoLinkage: return CXLinkage_NoLinkage;
Guy Benyei11169dd2012-12-18 14:30:41 +00006824 case InternalLinkage: return CXLinkage_Internal;
6825 case UniqueExternalLinkage: return CXLinkage_UniqueExternal;
6826 case ExternalLinkage: return CXLinkage_External;
6827 };
6828
6829 return CXLinkage_Invalid;
6830}
6831} // end: extern "C"
6832
6833//===----------------------------------------------------------------------===//
Ehsan Akhgari93697fa2015-11-23 19:56:46 +00006834// Operations for querying visibility of a cursor.
6835//===----------------------------------------------------------------------===//
6836
6837extern "C" {
6838CXVisibilityKind clang_getCursorVisibility(CXCursor cursor) {
6839 if (!clang_isDeclaration(cursor.kind))
6840 return CXVisibility_Invalid;
6841
6842 const Decl *D = cxcursor::getCursorDecl(cursor);
6843 if (const NamedDecl *ND = dyn_cast_or_null<NamedDecl>(D))
6844 switch (ND->getVisibility()) {
6845 case HiddenVisibility: return CXVisibility_Hidden;
6846 case ProtectedVisibility: return CXVisibility_Protected;
6847 case DefaultVisibility: return CXVisibility_Default;
6848 };
6849
6850 return CXVisibility_Invalid;
6851}
6852} // end: extern "C"
6853
6854//===----------------------------------------------------------------------===//
Guy Benyei11169dd2012-12-18 14:30:41 +00006855// Operations for querying language of a cursor.
6856//===----------------------------------------------------------------------===//
6857
6858static CXLanguageKind getDeclLanguage(const Decl *D) {
6859 if (!D)
6860 return CXLanguage_C;
6861
6862 switch (D->getKind()) {
6863 default:
6864 break;
6865 case Decl::ImplicitParam:
6866 case Decl::ObjCAtDefsField:
6867 case Decl::ObjCCategory:
6868 case Decl::ObjCCategoryImpl:
6869 case Decl::ObjCCompatibleAlias:
6870 case Decl::ObjCImplementation:
6871 case Decl::ObjCInterface:
6872 case Decl::ObjCIvar:
6873 case Decl::ObjCMethod:
6874 case Decl::ObjCProperty:
6875 case Decl::ObjCPropertyImpl:
6876 case Decl::ObjCProtocol:
Douglas Gregor85f3f952015-07-07 03:57:15 +00006877 case Decl::ObjCTypeParam:
Guy Benyei11169dd2012-12-18 14:30:41 +00006878 return CXLanguage_ObjC;
6879 case Decl::CXXConstructor:
6880 case Decl::CXXConversion:
6881 case Decl::CXXDestructor:
6882 case Decl::CXXMethod:
6883 case Decl::CXXRecord:
6884 case Decl::ClassTemplate:
6885 case Decl::ClassTemplatePartialSpecialization:
6886 case Decl::ClassTemplateSpecialization:
6887 case Decl::Friend:
6888 case Decl::FriendTemplate:
6889 case Decl::FunctionTemplate:
6890 case Decl::LinkageSpec:
6891 case Decl::Namespace:
6892 case Decl::NamespaceAlias:
6893 case Decl::NonTypeTemplateParm:
6894 case Decl::StaticAssert:
6895 case Decl::TemplateTemplateParm:
6896 case Decl::TemplateTypeParm:
6897 case Decl::UnresolvedUsingTypename:
6898 case Decl::UnresolvedUsingValue:
6899 case Decl::Using:
6900 case Decl::UsingDirective:
6901 case Decl::UsingShadow:
6902 return CXLanguage_CPlusPlus;
6903 }
6904
6905 return CXLanguage_C;
6906}
6907
6908extern "C" {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006909
6910static CXAvailabilityKind getCursorAvailabilityForDecl(const Decl *D) {
6911 if (isa<FunctionDecl>(D) && cast<FunctionDecl>(D)->isDeleted())
Manuel Klimek8e3a7ed2015-09-25 17:53:16 +00006912 return CXAvailability_NotAvailable;
Guy Benyei11169dd2012-12-18 14:30:41 +00006913
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006914 switch (D->getAvailability()) {
6915 case AR_Available:
6916 case AR_NotYetIntroduced:
6917 if (const EnumConstantDecl *EnumConst = dyn_cast<EnumConstantDecl>(D))
Benjamin Kramer656363d2013-10-15 18:53:18 +00006918 return getCursorAvailabilityForDecl(
6919 cast<Decl>(EnumConst->getDeclContext()));
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006920 return CXAvailability_Available;
6921
6922 case AR_Deprecated:
6923 return CXAvailability_Deprecated;
6924
6925 case AR_Unavailable:
6926 return CXAvailability_NotAvailable;
6927 }
Benjamin Kramer656363d2013-10-15 18:53:18 +00006928
6929 llvm_unreachable("Unknown availability kind!");
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006930}
6931
Guy Benyei11169dd2012-12-18 14:30:41 +00006932enum CXAvailabilityKind clang_getCursorAvailability(CXCursor cursor) {
6933 if (clang_isDeclaration(cursor.kind))
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006934 if (const Decl *D = cxcursor::getCursorDecl(cursor))
6935 return getCursorAvailabilityForDecl(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00006936
6937 return CXAvailability_Available;
6938}
6939
6940static CXVersion convertVersion(VersionTuple In) {
6941 CXVersion Out = { -1, -1, -1 };
6942 if (In.empty())
6943 return Out;
6944
6945 Out.Major = In.getMajor();
6946
NAKAMURA Takumic2b5d1f2013-02-21 02:32:34 +00006947 Optional<unsigned> Minor = In.getMinor();
6948 if (Minor.hasValue())
Guy Benyei11169dd2012-12-18 14:30:41 +00006949 Out.Minor = *Minor;
6950 else
6951 return Out;
6952
NAKAMURA Takumic2b5d1f2013-02-21 02:32:34 +00006953 Optional<unsigned> Subminor = In.getSubminor();
6954 if (Subminor.hasValue())
Guy Benyei11169dd2012-12-18 14:30:41 +00006955 Out.Subminor = *Subminor;
6956
6957 return Out;
6958}
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006959
6960static int getCursorPlatformAvailabilityForDecl(const Decl *D,
6961 int *always_deprecated,
6962 CXString *deprecated_message,
6963 int *always_unavailable,
6964 CXString *unavailable_message,
6965 CXPlatformAvailability *availability,
6966 int availability_size) {
6967 bool HadAvailAttr = false;
6968 int N = 0;
Aaron Ballmanb97112e2014-03-08 22:19:01 +00006969 for (auto A : D->attrs()) {
6970 if (DeprecatedAttr *Deprecated = dyn_cast<DeprecatedAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006971 HadAvailAttr = true;
6972 if (always_deprecated)
6973 *always_deprecated = 1;
Nico Weberaacf0312014-04-24 05:16:45 +00006974 if (deprecated_message) {
Argyrios Kyrtzidisedfe07f2014-04-24 06:05:40 +00006975 clang_disposeString(*deprecated_message);
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006976 *deprecated_message = cxstring::createDup(Deprecated->getMessage());
Nico Weberaacf0312014-04-24 05:16:45 +00006977 }
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006978 continue;
6979 }
6980
Aaron Ballmanb97112e2014-03-08 22:19:01 +00006981 if (UnavailableAttr *Unavailable = dyn_cast<UnavailableAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006982 HadAvailAttr = true;
6983 if (always_unavailable)
6984 *always_unavailable = 1;
6985 if (unavailable_message) {
Argyrios Kyrtzidisedfe07f2014-04-24 06:05:40 +00006986 clang_disposeString(*unavailable_message);
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006987 *unavailable_message = cxstring::createDup(Unavailable->getMessage());
6988 }
6989 continue;
6990 }
6991
Aaron Ballmanb97112e2014-03-08 22:19:01 +00006992 if (AvailabilityAttr *Avail = dyn_cast<AvailabilityAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006993 HadAvailAttr = true;
6994 if (N < availability_size) {
6995 availability[N].Platform
6996 = cxstring::createDup(Avail->getPlatform()->getName());
6997 availability[N].Introduced = convertVersion(Avail->getIntroduced());
6998 availability[N].Deprecated = convertVersion(Avail->getDeprecated());
6999 availability[N].Obsoleted = convertVersion(Avail->getObsoleted());
7000 availability[N].Unavailable = Avail->getUnavailable();
7001 availability[N].Message = cxstring::createDup(Avail->getMessage());
7002 }
7003 ++N;
7004 }
7005 }
7006
7007 if (!HadAvailAttr)
7008 if (const EnumConstantDecl *EnumConst = dyn_cast<EnumConstantDecl>(D))
7009 return getCursorPlatformAvailabilityForDecl(
7010 cast<Decl>(EnumConst->getDeclContext()),
7011 always_deprecated,
7012 deprecated_message,
7013 always_unavailable,
7014 unavailable_message,
7015 availability,
7016 availability_size);
Guy Benyei11169dd2012-12-18 14:30:41 +00007017
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00007018 return N;
7019}
7020
Guy Benyei11169dd2012-12-18 14:30:41 +00007021int clang_getCursorPlatformAvailability(CXCursor cursor,
7022 int *always_deprecated,
7023 CXString *deprecated_message,
7024 int *always_unavailable,
7025 CXString *unavailable_message,
7026 CXPlatformAvailability *availability,
7027 int availability_size) {
7028 if (always_deprecated)
7029 *always_deprecated = 0;
7030 if (deprecated_message)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00007031 *deprecated_message = cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00007032 if (always_unavailable)
7033 *always_unavailable = 0;
7034 if (unavailable_message)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00007035 *unavailable_message = cxstring::createEmpty();
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00007036
Guy Benyei11169dd2012-12-18 14:30:41 +00007037 if (!clang_isDeclaration(cursor.kind))
7038 return 0;
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00007039
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00007040 const Decl *D = cxcursor::getCursorDecl(cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00007041 if (!D)
7042 return 0;
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00007043
7044 return getCursorPlatformAvailabilityForDecl(D, always_deprecated,
7045 deprecated_message,
7046 always_unavailable,
7047 unavailable_message,
7048 availability,
7049 availability_size);
Guy Benyei11169dd2012-12-18 14:30:41 +00007050}
7051
7052void clang_disposeCXPlatformAvailability(CXPlatformAvailability *availability) {
7053 clang_disposeString(availability->Platform);
7054 clang_disposeString(availability->Message);
7055}
7056
7057CXLanguageKind clang_getCursorLanguage(CXCursor cursor) {
7058 if (clang_isDeclaration(cursor.kind))
7059 return getDeclLanguage(cxcursor::getCursorDecl(cursor));
7060
7061 return CXLanguage_Invalid;
7062}
7063
7064 /// \brief If the given cursor is the "templated" declaration
7065 /// descibing a class or function template, return the class or
7066 /// function template.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00007067static const Decl *maybeGetTemplateCursor(const Decl *D) {
Guy Benyei11169dd2012-12-18 14:30:41 +00007068 if (!D)
Craig Topper69186e72014-06-08 08:38:04 +00007069 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00007070
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00007071 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00007072 if (FunctionTemplateDecl *FunTmpl = FD->getDescribedFunctionTemplate())
7073 return FunTmpl;
7074
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00007075 if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00007076 if (ClassTemplateDecl *ClassTmpl = RD->getDescribedClassTemplate())
7077 return ClassTmpl;
7078
7079 return D;
7080}
7081
Argyrios Kyrtzidis4e0854f2014-10-15 17:05:31 +00007082
7083enum CX_StorageClass clang_Cursor_getStorageClass(CXCursor C) {
7084 StorageClass sc = SC_None;
7085 const Decl *D = getCursorDecl(C);
7086 if (D) {
7087 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
7088 sc = FD->getStorageClass();
7089 } else if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
7090 sc = VD->getStorageClass();
7091 } else {
7092 return CX_SC_Invalid;
7093 }
7094 } else {
7095 return CX_SC_Invalid;
7096 }
7097 switch (sc) {
7098 case SC_None:
7099 return CX_SC_None;
7100 case SC_Extern:
7101 return CX_SC_Extern;
7102 case SC_Static:
7103 return CX_SC_Static;
7104 case SC_PrivateExtern:
7105 return CX_SC_PrivateExtern;
Argyrios Kyrtzidis4e0854f2014-10-15 17:05:31 +00007106 case SC_Auto:
7107 return CX_SC_Auto;
7108 case SC_Register:
7109 return CX_SC_Register;
Argyrios Kyrtzidis4e0854f2014-10-15 17:05:31 +00007110 }
Kaelyn Takataab61e702014-10-15 18:03:26 +00007111 llvm_unreachable("Unhandled storage class!");
Argyrios Kyrtzidis4e0854f2014-10-15 17:05:31 +00007112}
7113
Guy Benyei11169dd2012-12-18 14:30:41 +00007114CXCursor clang_getCursorSemanticParent(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->getDeclContext();
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 if (clang_isStatement(cursor.kind) || clang_isExpression(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00007127 if (const Decl *D = getCursorDecl(cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +00007128 return MakeCXCursor(D, getCursorTU(cursor));
7129 }
7130
7131 return clang_getNullCursor();
7132}
7133
7134CXCursor clang_getCursorLexicalParent(CXCursor cursor) {
7135 if (clang_isDeclaration(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00007136 if (const Decl *D = getCursorDecl(cursor)) {
7137 const DeclContext *DC = D->getLexicalDeclContext();
Guy Benyei11169dd2012-12-18 14:30:41 +00007138 if (!DC)
7139 return clang_getNullCursor();
7140
7141 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
7142 getCursorTU(cursor));
7143 }
7144 }
7145
7146 // FIXME: Note that we can't easily compute the lexical context of a
7147 // statement or expression, so we return nothing.
7148 return clang_getNullCursor();
7149}
7150
7151CXFile clang_getIncludedFile(CXCursor cursor) {
7152 if (cursor.kind != CXCursor_InclusionDirective)
Craig Topper69186e72014-06-08 08:38:04 +00007153 return nullptr;
7154
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00007155 const InclusionDirective *ID = getCursorInclusionDirective(cursor);
Dmitri Gribenkof9304482013-01-23 15:56:07 +00007156 return const_cast<FileEntry *>(ID->getFile());
Guy Benyei11169dd2012-12-18 14:30:41 +00007157}
7158
Argyrios Kyrtzidis9adfd8a2013-04-18 22:15:49 +00007159unsigned clang_Cursor_getObjCPropertyAttributes(CXCursor C, unsigned reserved) {
7160 if (C.kind != CXCursor_ObjCPropertyDecl)
7161 return CXObjCPropertyAttr_noattr;
7162
7163 unsigned Result = CXObjCPropertyAttr_noattr;
7164 const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(getCursorDecl(C));
7165 ObjCPropertyDecl::PropertyAttributeKind Attr =
7166 PD->getPropertyAttributesAsWritten();
7167
7168#define SET_CXOBJCPROP_ATTR(A) \
7169 if (Attr & ObjCPropertyDecl::OBJC_PR_##A) \
7170 Result |= CXObjCPropertyAttr_##A
7171 SET_CXOBJCPROP_ATTR(readonly);
7172 SET_CXOBJCPROP_ATTR(getter);
7173 SET_CXOBJCPROP_ATTR(assign);
7174 SET_CXOBJCPROP_ATTR(readwrite);
7175 SET_CXOBJCPROP_ATTR(retain);
7176 SET_CXOBJCPROP_ATTR(copy);
7177 SET_CXOBJCPROP_ATTR(nonatomic);
7178 SET_CXOBJCPROP_ATTR(setter);
7179 SET_CXOBJCPROP_ATTR(atomic);
7180 SET_CXOBJCPROP_ATTR(weak);
7181 SET_CXOBJCPROP_ATTR(strong);
7182 SET_CXOBJCPROP_ATTR(unsafe_unretained);
7183#undef SET_CXOBJCPROP_ATTR
7184
7185 return Result;
7186}
7187
Argyrios Kyrtzidis9d9bc012013-04-18 23:29:12 +00007188unsigned clang_Cursor_getObjCDeclQualifiers(CXCursor C) {
7189 if (!clang_isDeclaration(C.kind))
7190 return CXObjCDeclQualifier_None;
7191
7192 Decl::ObjCDeclQualifier QT = Decl::OBJC_TQ_None;
7193 const Decl *D = getCursorDecl(C);
7194 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
7195 QT = MD->getObjCDeclQualifier();
7196 else if (const ParmVarDecl *PD = dyn_cast<ParmVarDecl>(D))
7197 QT = PD->getObjCDeclQualifier();
7198 if (QT == Decl::OBJC_TQ_None)
7199 return CXObjCDeclQualifier_None;
7200
7201 unsigned Result = CXObjCDeclQualifier_None;
7202 if (QT & Decl::OBJC_TQ_In) Result |= CXObjCDeclQualifier_In;
7203 if (QT & Decl::OBJC_TQ_Inout) Result |= CXObjCDeclQualifier_Inout;
7204 if (QT & Decl::OBJC_TQ_Out) Result |= CXObjCDeclQualifier_Out;
7205 if (QT & Decl::OBJC_TQ_Bycopy) Result |= CXObjCDeclQualifier_Bycopy;
7206 if (QT & Decl::OBJC_TQ_Byref) Result |= CXObjCDeclQualifier_Byref;
7207 if (QT & Decl::OBJC_TQ_Oneway) Result |= CXObjCDeclQualifier_Oneway;
7208
7209 return Result;
7210}
7211
Argyrios Kyrtzidis7b50fc52013-07-05 20:44:37 +00007212unsigned clang_Cursor_isObjCOptional(CXCursor C) {
7213 if (!clang_isDeclaration(C.kind))
7214 return 0;
7215
7216 const Decl *D = getCursorDecl(C);
7217 if (const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(D))
7218 return PD->getPropertyImplementation() == ObjCPropertyDecl::Optional;
7219 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
7220 return MD->getImplementationControl() == ObjCMethodDecl::Optional;
7221
7222 return 0;
7223}
7224
Argyrios Kyrtzidis23814e42013-04-18 23:53:05 +00007225unsigned clang_Cursor_isVariadic(CXCursor C) {
7226 if (!clang_isDeclaration(C.kind))
7227 return 0;
7228
7229 const Decl *D = getCursorDecl(C);
7230 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
7231 return FD->isVariadic();
7232 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
7233 return MD->isVariadic();
7234
7235 return 0;
7236}
7237
Guy Benyei11169dd2012-12-18 14:30:41 +00007238CXSourceRange clang_Cursor_getCommentRange(CXCursor C) {
7239 if (!clang_isDeclaration(C.kind))
7240 return clang_getNullRange();
7241
7242 const Decl *D = getCursorDecl(C);
7243 ASTContext &Context = getCursorContext(C);
7244 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
7245 if (!RC)
7246 return clang_getNullRange();
7247
7248 return cxloc::translateSourceRange(Context, RC->getSourceRange());
7249}
7250
7251CXString clang_Cursor_getRawCommentText(CXCursor C) {
7252 if (!clang_isDeclaration(C.kind))
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00007253 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00007254
7255 const Decl *D = getCursorDecl(C);
7256 ASTContext &Context = getCursorContext(C);
7257 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
7258 StringRef RawText = RC ? RC->getRawText(Context.getSourceManager()) :
7259 StringRef();
7260
7261 // Don't duplicate the string because RawText points directly into source
7262 // code.
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00007263 return cxstring::createRef(RawText);
Guy Benyei11169dd2012-12-18 14:30:41 +00007264}
7265
7266CXString clang_Cursor_getBriefCommentText(CXCursor C) {
7267 if (!clang_isDeclaration(C.kind))
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00007268 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00007269
7270 const Decl *D = getCursorDecl(C);
7271 const ASTContext &Context = getCursorContext(C);
7272 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
7273
7274 if (RC) {
7275 StringRef BriefText = RC->getBriefText(Context);
7276
7277 // Don't duplicate the string because RawComment ensures that this memory
7278 // will not go away.
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00007279 return cxstring::createRef(BriefText);
Guy Benyei11169dd2012-12-18 14:30:41 +00007280 }
7281
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00007282 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00007283}
7284
Guy Benyei11169dd2012-12-18 14:30:41 +00007285CXModule clang_Cursor_getModule(CXCursor C) {
7286 if (C.kind == CXCursor_ModuleImportDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00007287 if (const ImportDecl *ImportD =
7288 dyn_cast_or_null<ImportDecl>(getCursorDecl(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00007289 return ImportD->getImportedModule();
7290 }
7291
Craig Topper69186e72014-06-08 08:38:04 +00007292 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00007293}
7294
Argyrios Kyrtzidisf6d49c32014-05-14 23:14:37 +00007295CXModule clang_getModuleForFile(CXTranslationUnit TU, CXFile File) {
7296 if (isNotUsableTU(TU)) {
7297 LOG_BAD_TU(TU);
7298 return nullptr;
7299 }
7300 if (!File)
7301 return nullptr;
7302 FileEntry *FE = static_cast<FileEntry *>(File);
7303
7304 ASTUnit &Unit = *cxtu::getASTUnit(TU);
7305 HeaderSearch &HS = Unit.getPreprocessor().getHeaderSearchInfo();
7306 ModuleMap::KnownHeader Header = HS.findModuleForHeader(FE);
7307
Richard Smithfeb54b62014-10-23 02:01:19 +00007308 return Header.getModule();
Argyrios Kyrtzidisf6d49c32014-05-14 23:14:37 +00007309}
7310
Argyrios Kyrtzidis12fdb9e2013-04-26 22:47:49 +00007311CXFile clang_Module_getASTFile(CXModule CXMod) {
7312 if (!CXMod)
Craig Topper69186e72014-06-08 08:38:04 +00007313 return nullptr;
Argyrios Kyrtzidis12fdb9e2013-04-26 22:47:49 +00007314 Module *Mod = static_cast<Module*>(CXMod);
7315 return const_cast<FileEntry *>(Mod->getASTFile());
7316}
7317
Guy Benyei11169dd2012-12-18 14:30:41 +00007318CXModule clang_Module_getParent(CXModule CXMod) {
7319 if (!CXMod)
Craig Topper69186e72014-06-08 08:38:04 +00007320 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00007321 Module *Mod = static_cast<Module*>(CXMod);
7322 return Mod->Parent;
7323}
7324
7325CXString clang_Module_getName(CXModule CXMod) {
7326 if (!CXMod)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00007327 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00007328 Module *Mod = static_cast<Module*>(CXMod);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00007329 return cxstring::createDup(Mod->Name);
Guy Benyei11169dd2012-12-18 14:30:41 +00007330}
7331
7332CXString clang_Module_getFullName(CXModule CXMod) {
7333 if (!CXMod)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00007334 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00007335 Module *Mod = static_cast<Module*>(CXMod);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00007336 return cxstring::createDup(Mod->getFullModuleName());
Guy Benyei11169dd2012-12-18 14:30:41 +00007337}
7338
Argyrios Kyrtzidis884337f2014-05-15 04:44:25 +00007339int clang_Module_isSystem(CXModule CXMod) {
7340 if (!CXMod)
7341 return 0;
7342 Module *Mod = static_cast<Module*>(CXMod);
7343 return Mod->IsSystem;
7344}
7345
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00007346unsigned clang_Module_getNumTopLevelHeaders(CXTranslationUnit TU,
7347 CXModule CXMod) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00007348 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00007349 LOG_BAD_TU(TU);
7350 return 0;
7351 }
7352 if (!CXMod)
Guy Benyei11169dd2012-12-18 14:30:41 +00007353 return 0;
7354 Module *Mod = static_cast<Module*>(CXMod);
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00007355 FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
7356 ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
7357 return TopHeaders.size();
Guy Benyei11169dd2012-12-18 14:30:41 +00007358}
7359
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00007360CXFile clang_Module_getTopLevelHeader(CXTranslationUnit TU,
7361 CXModule CXMod, unsigned Index) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00007362 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00007363 LOG_BAD_TU(TU);
Craig Topper69186e72014-06-08 08:38:04 +00007364 return nullptr;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00007365 }
7366 if (!CXMod)
Craig Topper69186e72014-06-08 08:38:04 +00007367 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00007368 Module *Mod = static_cast<Module*>(CXMod);
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00007369 FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
Guy Benyei11169dd2012-12-18 14:30:41 +00007370
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00007371 ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
7372 if (Index < TopHeaders.size())
7373 return const_cast<FileEntry *>(TopHeaders[Index]);
Guy Benyei11169dd2012-12-18 14:30:41 +00007374
Craig Topper69186e72014-06-08 08:38:04 +00007375 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00007376}
7377
7378} // end: extern "C"
7379
7380//===----------------------------------------------------------------------===//
7381// C++ AST instrospection.
7382//===----------------------------------------------------------------------===//
7383
7384extern "C" {
Saleem Abdulrasool6ea75db2015-10-27 15:50:22 +00007385unsigned clang_CXXField_isMutable(CXCursor C) {
7386 if (!clang_isDeclaration(C.kind))
7387 return 0;
7388
7389 if (const auto D = cxcursor::getCursorDecl(C))
7390 if (const auto FD = dyn_cast_or_null<FieldDecl>(D))
7391 return FD->isMutable() ? 1 : 0;
7392 return 0;
7393}
7394
Dmitri Gribenko62770be2013-05-17 18:38:35 +00007395unsigned clang_CXXMethod_isPureVirtual(CXCursor C) {
7396 if (!clang_isDeclaration(C.kind))
7397 return 0;
7398
Dmitri Gribenko62770be2013-05-17 18:38:35 +00007399 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00007400 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00007401 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Dmitri Gribenko62770be2013-05-17 18:38:35 +00007402 return (Method && Method->isVirtual() && Method->isPure()) ? 1 : 0;
7403}
7404
Dmitri Gribenkoe570ede2014-04-07 14:59:13 +00007405unsigned clang_CXXMethod_isConst(CXCursor C) {
7406 if (!clang_isDeclaration(C.kind))
7407 return 0;
7408
7409 const Decl *D = cxcursor::getCursorDecl(C);
7410 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00007411 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Dmitri Gribenkoe570ede2014-04-07 14:59:13 +00007412 return (Method && (Method->getTypeQualifiers() & Qualifiers::Const)) ? 1 : 0;
7413}
7414
Guy Benyei11169dd2012-12-18 14:30:41 +00007415unsigned clang_CXXMethod_isStatic(CXCursor C) {
7416 if (!clang_isDeclaration(C.kind))
7417 return 0;
7418
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00007419 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00007420 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00007421 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00007422 return (Method && Method->isStatic()) ? 1 : 0;
7423}
7424
7425unsigned clang_CXXMethod_isVirtual(CXCursor C) {
7426 if (!clang_isDeclaration(C.kind))
7427 return 0;
7428
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00007429 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00007430 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00007431 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00007432 return (Method && Method->isVirtual()) ? 1 : 0;
7433}
7434} // end: extern "C"
7435
7436//===----------------------------------------------------------------------===//
7437// Attribute introspection.
7438//===----------------------------------------------------------------------===//
7439
7440extern "C" {
7441CXType clang_getIBOutletCollectionType(CXCursor C) {
7442 if (C.kind != CXCursor_IBOutletCollectionAttr)
7443 return cxtype::MakeCXType(QualType(), cxcursor::getCursorTU(C));
7444
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00007445 const IBOutletCollectionAttr *A =
Guy Benyei11169dd2012-12-18 14:30:41 +00007446 cast<IBOutletCollectionAttr>(cxcursor::getCursorAttr(C));
7447
7448 return cxtype::MakeCXType(A->getInterface(), cxcursor::getCursorTU(C));
7449}
7450} // end: extern "C"
7451
7452//===----------------------------------------------------------------------===//
7453// Inspecting memory usage.
7454//===----------------------------------------------------------------------===//
7455
7456typedef std::vector<CXTUResourceUsageEntry> MemUsageEntries;
7457
7458static inline void createCXTUResourceUsageEntry(MemUsageEntries &entries,
7459 enum CXTUResourceUsageKind k,
7460 unsigned long amount) {
7461 CXTUResourceUsageEntry entry = { k, amount };
7462 entries.push_back(entry);
7463}
7464
7465extern "C" {
7466
7467const char *clang_getTUResourceUsageName(CXTUResourceUsageKind kind) {
7468 const char *str = "";
7469 switch (kind) {
7470 case CXTUResourceUsage_AST:
7471 str = "ASTContext: expressions, declarations, and types";
7472 break;
7473 case CXTUResourceUsage_Identifiers:
7474 str = "ASTContext: identifiers";
7475 break;
7476 case CXTUResourceUsage_Selectors:
7477 str = "ASTContext: selectors";
7478 break;
7479 case CXTUResourceUsage_GlobalCompletionResults:
7480 str = "Code completion: cached global results";
7481 break;
7482 case CXTUResourceUsage_SourceManagerContentCache:
7483 str = "SourceManager: content cache allocator";
7484 break;
7485 case CXTUResourceUsage_AST_SideTables:
7486 str = "ASTContext: side tables";
7487 break;
7488 case CXTUResourceUsage_SourceManager_Membuffer_Malloc:
7489 str = "SourceManager: malloc'ed memory buffers";
7490 break;
7491 case CXTUResourceUsage_SourceManager_Membuffer_MMap:
7492 str = "SourceManager: mmap'ed memory buffers";
7493 break;
7494 case CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc:
7495 str = "ExternalASTSource: malloc'ed memory buffers";
7496 break;
7497 case CXTUResourceUsage_ExternalASTSource_Membuffer_MMap:
7498 str = "ExternalASTSource: mmap'ed memory buffers";
7499 break;
7500 case CXTUResourceUsage_Preprocessor:
7501 str = "Preprocessor: malloc'ed memory";
7502 break;
7503 case CXTUResourceUsage_PreprocessingRecord:
7504 str = "Preprocessor: PreprocessingRecord";
7505 break;
7506 case CXTUResourceUsage_SourceManager_DataStructures:
7507 str = "SourceManager: data structures and tables";
7508 break;
7509 case CXTUResourceUsage_Preprocessor_HeaderSearch:
7510 str = "Preprocessor: header search tables";
7511 break;
7512 }
7513 return str;
7514}
7515
7516CXTUResourceUsage clang_getCXTUResourceUsage(CXTranslationUnit TU) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00007517 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00007518 LOG_BAD_TU(TU);
Craig Topper69186e72014-06-08 08:38:04 +00007519 CXTUResourceUsage usage = { (void*) nullptr, 0, nullptr };
Guy Benyei11169dd2012-12-18 14:30:41 +00007520 return usage;
7521 }
7522
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007523 ASTUnit *astUnit = cxtu::getASTUnit(TU);
Ahmed Charlesb8984322014-03-07 20:03:18 +00007524 std::unique_ptr<MemUsageEntries> entries(new MemUsageEntries());
Guy Benyei11169dd2012-12-18 14:30:41 +00007525 ASTContext &astContext = astUnit->getASTContext();
7526
7527 // How much memory is used by AST nodes and types?
7528 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST,
7529 (unsigned long) astContext.getASTAllocatedMemory());
7530
7531 // How much memory is used by identifiers?
7532 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Identifiers,
7533 (unsigned long) astContext.Idents.getAllocator().getTotalMemory());
7534
7535 // How much memory is used for selectors?
7536 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Selectors,
7537 (unsigned long) astContext.Selectors.getTotalMemory());
7538
7539 // How much memory is used by ASTContext's side tables?
7540 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST_SideTables,
7541 (unsigned long) astContext.getSideTableAllocatedMemory());
7542
7543 // How much memory is used for caching global code completion results?
7544 unsigned long completionBytes = 0;
7545 if (GlobalCodeCompletionAllocator *completionAllocator =
Alp Tokerf994cef2014-07-05 03:08:06 +00007546 astUnit->getCachedCompletionAllocator().get()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00007547 completionBytes = completionAllocator->getTotalMemory();
7548 }
7549 createCXTUResourceUsageEntry(*entries,
7550 CXTUResourceUsage_GlobalCompletionResults,
7551 completionBytes);
7552
7553 // How much memory is being used by SourceManager's content cache?
7554 createCXTUResourceUsageEntry(*entries,
7555 CXTUResourceUsage_SourceManagerContentCache,
7556 (unsigned long) astContext.getSourceManager().getContentCacheSize());
7557
7558 // How much memory is being used by the MemoryBuffer's in SourceManager?
7559 const SourceManager::MemoryBufferSizes &srcBufs =
7560 astUnit->getSourceManager().getMemoryBufferSizes();
7561
7562 createCXTUResourceUsageEntry(*entries,
7563 CXTUResourceUsage_SourceManager_Membuffer_Malloc,
7564 (unsigned long) srcBufs.malloc_bytes);
7565 createCXTUResourceUsageEntry(*entries,
7566 CXTUResourceUsage_SourceManager_Membuffer_MMap,
7567 (unsigned long) srcBufs.mmap_bytes);
7568 createCXTUResourceUsageEntry(*entries,
7569 CXTUResourceUsage_SourceManager_DataStructures,
7570 (unsigned long) astContext.getSourceManager()
7571 .getDataStructureSizes());
7572
7573 // How much memory is being used by the ExternalASTSource?
7574 if (ExternalASTSource *esrc = astContext.getExternalSource()) {
7575 const ExternalASTSource::MemoryBufferSizes &sizes =
7576 esrc->getMemoryBufferSizes();
7577
7578 createCXTUResourceUsageEntry(*entries,
7579 CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc,
7580 (unsigned long) sizes.malloc_bytes);
7581 createCXTUResourceUsageEntry(*entries,
7582 CXTUResourceUsage_ExternalASTSource_Membuffer_MMap,
7583 (unsigned long) sizes.mmap_bytes);
7584 }
7585
7586 // How much memory is being used by the Preprocessor?
7587 Preprocessor &pp = astUnit->getPreprocessor();
7588 createCXTUResourceUsageEntry(*entries,
7589 CXTUResourceUsage_Preprocessor,
7590 pp.getTotalMemory());
7591
7592 if (PreprocessingRecord *pRec = pp.getPreprocessingRecord()) {
7593 createCXTUResourceUsageEntry(*entries,
7594 CXTUResourceUsage_PreprocessingRecord,
7595 pRec->getTotalMemory());
7596 }
7597
7598 createCXTUResourceUsageEntry(*entries,
7599 CXTUResourceUsage_Preprocessor_HeaderSearch,
7600 pp.getHeaderSearchInfo().getTotalMemory());
Craig Topper69186e72014-06-08 08:38:04 +00007601
Guy Benyei11169dd2012-12-18 14:30:41 +00007602 CXTUResourceUsage usage = { (void*) entries.get(),
7603 (unsigned) entries->size(),
Alexander Kornienko6ee521c2015-01-23 15:36:10 +00007604 !entries->empty() ? &(*entries)[0] : nullptr };
Ahmed Charles9a16beb2014-03-07 19:33:25 +00007605 entries.release();
Guy Benyei11169dd2012-12-18 14:30:41 +00007606 return usage;
7607}
7608
7609void clang_disposeCXTUResourceUsage(CXTUResourceUsage usage) {
7610 if (usage.data)
7611 delete (MemUsageEntries*) usage.data;
7612}
7613
Argyrios Kyrtzidis0e282ef2013-12-06 18:55:45 +00007614CXSourceRangeList *clang_getSkippedRanges(CXTranslationUnit TU, CXFile file) {
7615 CXSourceRangeList *skipped = new CXSourceRangeList;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00007616 skipped->count = 0;
Craig Topper69186e72014-06-08 08:38:04 +00007617 skipped->ranges = nullptr;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00007618
Dmitri Gribenko852d6222014-02-11 15:02:48 +00007619 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00007620 LOG_BAD_TU(TU);
7621 return skipped;
7622 }
7623
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00007624 if (!file)
7625 return skipped;
7626
7627 ASTUnit *astUnit = cxtu::getASTUnit(TU);
7628 PreprocessingRecord *ppRec = astUnit->getPreprocessor().getPreprocessingRecord();
7629 if (!ppRec)
7630 return skipped;
7631
7632 ASTContext &Ctx = astUnit->getASTContext();
7633 SourceManager &sm = Ctx.getSourceManager();
7634 FileEntry *fileEntry = static_cast<FileEntry *>(file);
7635 FileID wantedFileID = sm.translateFile(fileEntry);
7636
7637 const std::vector<SourceRange> &SkippedRanges = ppRec->getSkippedRanges();
7638 std::vector<SourceRange> wantedRanges;
7639 for (std::vector<SourceRange>::const_iterator i = SkippedRanges.begin(), ei = SkippedRanges.end();
7640 i != ei; ++i) {
7641 if (sm.getFileID(i->getBegin()) == wantedFileID || sm.getFileID(i->getEnd()) == wantedFileID)
7642 wantedRanges.push_back(*i);
7643 }
7644
7645 skipped->count = wantedRanges.size();
7646 skipped->ranges = new CXSourceRange[skipped->count];
7647 for (unsigned i = 0, ei = skipped->count; i != ei; ++i)
7648 skipped->ranges[i] = cxloc::translateSourceRange(Ctx, wantedRanges[i]);
7649
7650 return skipped;
7651}
7652
Argyrios Kyrtzidis0e282ef2013-12-06 18:55:45 +00007653void clang_disposeSourceRangeList(CXSourceRangeList *ranges) {
7654 if (ranges) {
7655 delete[] ranges->ranges;
7656 delete ranges;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00007657 }
7658}
7659
Guy Benyei11169dd2012-12-18 14:30:41 +00007660} // end extern "C"
7661
7662void clang::PrintLibclangResourceUsage(CXTranslationUnit TU) {
7663 CXTUResourceUsage Usage = clang_getCXTUResourceUsage(TU);
7664 for (unsigned I = 0; I != Usage.numEntries; ++I)
7665 fprintf(stderr, " %s: %lu\n",
7666 clang_getTUResourceUsageName(Usage.entries[I].kind),
7667 Usage.entries[I].amount);
7668
7669 clang_disposeCXTUResourceUsage(Usage);
7670}
7671
7672//===----------------------------------------------------------------------===//
7673// Misc. utility functions.
7674//===----------------------------------------------------------------------===//
7675
7676/// Default to using an 8 MB stack size on "safety" threads.
7677static unsigned SafetyStackThreadSize = 8 << 20;
7678
7679namespace clang {
7680
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00007681bool RunSafely(llvm::CrashRecoveryContext &CRC, llvm::function_ref<void()> Fn,
Guy Benyei11169dd2012-12-18 14:30:41 +00007682 unsigned Size) {
7683 if (!Size)
7684 Size = GetSafetyThreadStackSize();
7685 if (Size)
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00007686 return CRC.RunSafelyOnThread(Fn, Size);
7687 return CRC.RunSafely(Fn);
Guy Benyei11169dd2012-12-18 14:30:41 +00007688}
7689
7690unsigned GetSafetyThreadStackSize() {
7691 return SafetyStackThreadSize;
7692}
7693
7694void SetSafetyThreadStackSize(unsigned Value) {
7695 SafetyStackThreadSize = Value;
7696}
7697
Alexander Kornienkoab9db512015-06-22 23:07:51 +00007698}
Guy Benyei11169dd2012-12-18 14:30:41 +00007699
7700void clang::setThreadBackgroundPriority() {
7701 if (getenv("LIBCLANG_BGPRIO_DISABLE"))
7702 return;
7703
Alp Toker1a86ad22014-07-06 06:24:00 +00007704#ifdef USE_DARWIN_THREADS
Guy Benyei11169dd2012-12-18 14:30:41 +00007705 setpriority(PRIO_DARWIN_THREAD, 0, PRIO_DARWIN_BG);
7706#endif
7707}
7708
7709void cxindex::printDiagsToStderr(ASTUnit *Unit) {
7710 if (!Unit)
7711 return;
7712
7713 for (ASTUnit::stored_diag_iterator D = Unit->stored_diag_begin(),
7714 DEnd = Unit->stored_diag_end();
7715 D != DEnd; ++D) {
Ben Langmuir749323f2014-04-22 17:40:12 +00007716 CXStoredDiagnostic Diag(*D, Unit->getLangOpts());
Guy Benyei11169dd2012-12-18 14:30:41 +00007717 CXString Msg = clang_formatDiagnostic(&Diag,
7718 clang_defaultDiagnosticDisplayOptions());
7719 fprintf(stderr, "%s\n", clang_getCString(Msg));
7720 clang_disposeString(Msg);
7721 }
7722#ifdef LLVM_ON_WIN32
7723 // On Windows, force a flush, since there may be multiple copies of
7724 // stderr and stdout in the file system, all with different buffers
7725 // but writing to the same device.
7726 fflush(stderr);
7727#endif
7728}
7729
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007730MacroInfo *cxindex::getMacroInfo(const IdentifierInfo &II,
7731 SourceLocation MacroDefLoc,
7732 CXTranslationUnit TU){
7733 if (MacroDefLoc.isInvalid() || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00007734 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007735 if (!II.hadMacroDefinition())
Craig Topper69186e72014-06-08 08:38:04 +00007736 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007737
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007738 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00007739 Preprocessor &PP = Unit->getPreprocessor();
Richard Smith20e883e2015-04-29 23:20:19 +00007740 MacroDirective *MD = PP.getLocalMacroDirectiveHistory(&II);
Argyrios Kyrtzidisb6210df2013-03-26 17:17:01 +00007741 if (MD) {
7742 for (MacroDirective::DefInfo
7743 Def = MD->getDefinition(); Def; Def = Def.getPreviousDefinition()) {
7744 if (MacroDefLoc == Def.getMacroInfo()->getDefinitionLoc())
7745 return Def.getMacroInfo();
7746 }
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007747 }
7748
Craig Topper69186e72014-06-08 08:38:04 +00007749 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007750}
7751
Richard Smith66a81862015-05-04 02:25:31 +00007752const MacroInfo *cxindex::getMacroInfo(const MacroDefinitionRecord *MacroDef,
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00007753 CXTranslationUnit TU) {
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007754 if (!MacroDef || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00007755 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007756 const IdentifierInfo *II = MacroDef->getName();
7757 if (!II)
Craig Topper69186e72014-06-08 08:38:04 +00007758 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007759
7760 return getMacroInfo(*II, MacroDef->getLocation(), TU);
7761}
7762
Richard Smith66a81862015-05-04 02:25:31 +00007763MacroDefinitionRecord *
7764cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI, const Token &Tok,
7765 CXTranslationUnit TU) {
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007766 if (!MI || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00007767 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007768 if (Tok.isNot(tok::raw_identifier))
Craig Topper69186e72014-06-08 08:38:04 +00007769 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007770
7771 if (MI->getNumTokens() == 0)
Craig Topper69186e72014-06-08 08:38:04 +00007772 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007773 SourceRange DefRange(MI->getReplacementToken(0).getLocation(),
7774 MI->getDefinitionEndLoc());
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007775 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007776
7777 // Check that the token is inside the definition and not its argument list.
7778 SourceManager &SM = Unit->getSourceManager();
7779 if (SM.isBeforeInTranslationUnit(Tok.getLocation(), DefRange.getBegin()))
Craig Topper69186e72014-06-08 08:38:04 +00007780 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007781 if (SM.isBeforeInTranslationUnit(DefRange.getEnd(), Tok.getLocation()))
Craig Topper69186e72014-06-08 08:38:04 +00007782 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007783
7784 Preprocessor &PP = Unit->getPreprocessor();
7785 PreprocessingRecord *PPRec = PP.getPreprocessingRecord();
7786 if (!PPRec)
Craig Topper69186e72014-06-08 08:38:04 +00007787 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007788
Alp Toker2d57cea2014-05-17 04:53:25 +00007789 IdentifierInfo &II = PP.getIdentifierTable().get(Tok.getRawIdentifier());
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007790 if (!II.hadMacroDefinition())
Craig Topper69186e72014-06-08 08:38:04 +00007791 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007792
7793 // Check that the identifier is not one of the macro arguments.
7794 if (std::find(MI->arg_begin(), MI->arg_end(), &II) != MI->arg_end())
Craig Topper69186e72014-06-08 08:38:04 +00007795 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007796
Richard Smith20e883e2015-04-29 23:20:19 +00007797 MacroDirective *InnerMD = PP.getLocalMacroDirectiveHistory(&II);
Argyrios Kyrtzidis09c9e812013-02-20 00:54:57 +00007798 if (!InnerMD)
Craig Topper69186e72014-06-08 08:38:04 +00007799 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007800
Argyrios Kyrtzidisb6210df2013-03-26 17:17:01 +00007801 return PPRec->findMacroDefinition(InnerMD->getMacroInfo());
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007802}
7803
Richard Smith66a81862015-05-04 02:25:31 +00007804MacroDefinitionRecord *
7805cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI, SourceLocation Loc,
7806 CXTranslationUnit TU) {
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007807 if (Loc.isInvalid() || !MI || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00007808 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007809
7810 if (MI->getNumTokens() == 0)
Craig Topper69186e72014-06-08 08:38:04 +00007811 return nullptr;
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007812 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007813 Preprocessor &PP = Unit->getPreprocessor();
7814 if (!PP.getPreprocessingRecord())
Craig Topper69186e72014-06-08 08:38:04 +00007815 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007816 Loc = Unit->getSourceManager().getSpellingLoc(Loc);
7817 Token Tok;
7818 if (PP.getRawToken(Loc, Tok))
Craig Topper69186e72014-06-08 08:38:04 +00007819 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007820
7821 return checkForMacroInMacroDefinition(MI, Tok, TU);
7822}
7823
Guy Benyei11169dd2012-12-18 14:30:41 +00007824extern "C" {
7825
7826CXString clang_getClangVersion() {
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00007827 return cxstring::createDup(getClangFullVersion());
Guy Benyei11169dd2012-12-18 14:30:41 +00007828}
7829
7830} // end: extern "C"
7831
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007832Logger &cxindex::Logger::operator<<(CXTranslationUnit TU) {
7833 if (TU) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007834 if (ASTUnit *Unit = cxtu::getASTUnit(TU)) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007835 LogOS << '<' << Unit->getMainFileName() << '>';
Argyrios Kyrtzidis37f2ab42013-03-05 20:21:14 +00007836 if (Unit->isMainFileAST())
7837 LogOS << " (" << Unit->getASTFileName() << ')';
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007838 return *this;
7839 }
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00007840 } else {
7841 LogOS << "<NULL TU>";
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007842 }
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007843 return *this;
7844}
7845
Argyrios Kyrtzidisba4b5f82013-03-08 02:32:26 +00007846Logger &cxindex::Logger::operator<<(const FileEntry *FE) {
7847 *this << FE->getName();
7848 return *this;
7849}
7850
7851Logger &cxindex::Logger::operator<<(CXCursor cursor) {
7852 CXString cursorName = clang_getCursorDisplayName(cursor);
7853 *this << cursorName << "@" << clang_getCursorLocation(cursor);
7854 clang_disposeString(cursorName);
7855 return *this;
7856}
7857
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007858Logger &cxindex::Logger::operator<<(CXSourceLocation Loc) {
7859 CXFile File;
7860 unsigned Line, Column;
Craig Topper69186e72014-06-08 08:38:04 +00007861 clang_getFileLocation(Loc, &File, &Line, &Column, nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007862 CXString FileName = clang_getFileName(File);
7863 *this << llvm::format("(%s:%d:%d)", clang_getCString(FileName), Line, Column);
7864 clang_disposeString(FileName);
7865 return *this;
7866}
7867
7868Logger &cxindex::Logger::operator<<(CXSourceRange range) {
7869 CXSourceLocation BLoc = clang_getRangeStart(range);
7870 CXSourceLocation ELoc = clang_getRangeEnd(range);
7871
7872 CXFile BFile;
7873 unsigned BLine, BColumn;
Craig Topper69186e72014-06-08 08:38:04 +00007874 clang_getFileLocation(BLoc, &BFile, &BLine, &BColumn, nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007875
7876 CXFile EFile;
7877 unsigned ELine, EColumn;
Craig Topper69186e72014-06-08 08:38:04 +00007878 clang_getFileLocation(ELoc, &EFile, &ELine, &EColumn, nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007879
7880 CXString BFileName = clang_getFileName(BFile);
7881 if (BFile == EFile) {
7882 *this << llvm::format("[%s %d:%d-%d:%d]", clang_getCString(BFileName),
7883 BLine, BColumn, ELine, EColumn);
7884 } else {
7885 CXString EFileName = clang_getFileName(EFile);
7886 *this << llvm::format("[%s:%d:%d - ", clang_getCString(BFileName),
7887 BLine, BColumn)
7888 << llvm::format("%s:%d:%d]", clang_getCString(EFileName),
7889 ELine, EColumn);
7890 clang_disposeString(EFileName);
7891 }
7892 clang_disposeString(BFileName);
7893 return *this;
7894}
7895
7896Logger &cxindex::Logger::operator<<(CXString Str) {
7897 *this << clang_getCString(Str);
7898 return *this;
7899}
7900
7901Logger &cxindex::Logger::operator<<(const llvm::format_object_base &Fmt) {
7902 LogOS << Fmt;
7903 return *this;
7904}
7905
Chandler Carruth37ad2582014-06-27 15:14:39 +00007906static llvm::ManagedStatic<llvm::sys::Mutex> LoggingMutex;
7907
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007908cxindex::Logger::~Logger() {
Chandler Carruth37ad2582014-06-27 15:14:39 +00007909 llvm::sys::ScopedLock L(*LoggingMutex);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007910
7911 static llvm::TimeRecord sBeginTR = llvm::TimeRecord::getCurrentTime();
7912
Dmitri Gribenkof8579502013-01-12 19:30:44 +00007913 raw_ostream &OS = llvm::errs();
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007914 OS << "[libclang:" << Name << ':';
7915
Alp Toker1a86ad22014-07-06 06:24:00 +00007916#ifdef USE_DARWIN_THREADS
7917 // TODO: Portability.
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007918 mach_port_t tid = pthread_mach_thread_np(pthread_self());
7919 OS << tid << ':';
7920#endif
7921
7922 llvm::TimeRecord TR = llvm::TimeRecord::getCurrentTime();
7923 OS << llvm::format("%7.4f] ", TR.getWallTime() - sBeginTR.getWallTime());
Yaron Keren09fb7c62015-03-10 07:33:23 +00007924 OS << Msg << '\n';
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007925
7926 if (Trace) {
Zachary Turner1fe2a8d2015-03-05 19:15:09 +00007927 llvm::sys::PrintStackTrace(OS);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007928 OS << "--------------------------------------------------\n";
7929 }
7930}