blob: 5146534c0e2339bcd1053ac5a5a9cea40db2072b [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"
Eli Bendersky44a206f2014-07-31 18:04:56 +000025#include "clang/AST/Mangle.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000026#include "clang/AST/StmtVisitor.h"
27#include "clang/Basic/Diagnostic.h"
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +000028#include "clang/Basic/DiagnosticCategories.h"
29#include "clang/Basic/DiagnosticIDs.h"
Eli Bendersky79759592014-08-01 15:01:10 +000030#include "clang/Basic/TargetInfo.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000031#include "clang/Basic/Version.h"
32#include "clang/Frontend/ASTUnit.h"
33#include "clang/Frontend/CompilerInstance.h"
34#include "clang/Frontend/FrontendDiagnostic.h"
Dmitri Gribenko9e605112013-11-13 22:16:51 +000035#include "clang/Index/CommentToXML.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000036#include "clang/Lex/HeaderSearch.h"
37#include "clang/Lex/Lexer.h"
38#include "clang/Lex/PreprocessingRecord.h"
39#include "clang/Lex/Preprocessor.h"
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +000040#include "clang/Serialization/SerializationDiagnostic.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000041#include "llvm/ADT/Optional.h"
42#include "llvm/ADT/STLExtras.h"
43#include "llvm/ADT/StringSwitch.h"
Alp Toker1d257e12014-06-04 03:28:55 +000044#include "llvm/Config/llvm-config.h"
Eli Bendersky79759592014-08-01 15:01:10 +000045#include "llvm/IR/DataLayout.h"
46#include "llvm/IR/Mangler.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000047#include "llvm/Support/Compiler.h"
48#include "llvm/Support/CrashRecoveryContext.h"
Chandler Carruth4b417452013-01-19 08:09:44 +000049#include "llvm/Support/Format.h"
Chandler Carruth37ad2582014-06-27 15:14:39 +000050#include "llvm/Support/ManagedStatic.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000051#include "llvm/Support/MemoryBuffer.h"
52#include "llvm/Support/Mutex.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000053#include "llvm/Support/Program.h"
54#include "llvm/Support/SaveAndRestore.h"
55#include "llvm/Support/Signals.h"
Adrian Prantlbc068582015-07-08 01:00:30 +000056#include "llvm/Support/TargetSelect.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000057#include "llvm/Support/Threading.h"
58#include "llvm/Support/Timer.h"
59#include "llvm/Support/raw_ostream.h"
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +000060
Alp Toker1a86ad22014-07-06 06:24:00 +000061#if LLVM_ENABLE_THREADS != 0 && defined(__APPLE__)
62#define USE_DARWIN_THREADS
63#endif
64
65#ifdef USE_DARWIN_THREADS
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +000066#include <pthread.h>
67#endif
Guy Benyei11169dd2012-12-18 14:30:41 +000068
69using namespace clang;
70using namespace clang::cxcursor;
Guy Benyei11169dd2012-12-18 14:30:41 +000071using namespace clang::cxtu;
72using namespace clang::cxindex;
73
Dmitri Gribenkod36209e2013-01-26 21:32:42 +000074CXTranslationUnit cxtu::MakeCXTranslationUnit(CIndexer *CIdx, ASTUnit *AU) {
75 if (!AU)
Craig Topper69186e72014-06-08 08:38:04 +000076 return nullptr;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +000077 assert(CIdx);
Guy Benyei11169dd2012-12-18 14:30:41 +000078 CXTranslationUnit D = new CXTranslationUnitImpl();
79 D->CIdx = CIdx;
Dmitri Gribenkod36209e2013-01-26 21:32:42 +000080 D->TheASTUnit = AU;
Dmitri Gribenko74895212013-02-03 13:52:47 +000081 D->StringPool = new cxstring::CXStringPool();
Craig Topper69186e72014-06-08 08:38:04 +000082 D->Diagnostics = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +000083 D->OverridenCursorsPool = createOverridenCXCursorsPool();
Craig Topper69186e72014-06-08 08:38:04 +000084 D->CommentToXML = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +000085 return D;
86}
87
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +000088bool cxtu::isASTReadError(ASTUnit *AU) {
89 for (ASTUnit::stored_diag_iterator D = AU->stored_diag_begin(),
90 DEnd = AU->stored_diag_end();
91 D != DEnd; ++D) {
92 if (D->getLevel() >= DiagnosticsEngine::Error &&
93 DiagnosticIDs::getCategoryNumberForDiag(D->getID()) ==
94 diag::DiagCat_AST_Deserialization_Issue)
95 return true;
96 }
97 return false;
98}
99
Guy Benyei11169dd2012-12-18 14:30:41 +0000100cxtu::CXTUOwner::~CXTUOwner() {
101 if (TU)
102 clang_disposeTranslationUnit(TU);
103}
104
105/// \brief Compare two source ranges to determine their relative position in
106/// the translation unit.
107static RangeComparisonResult RangeCompare(SourceManager &SM,
108 SourceRange R1,
109 SourceRange R2) {
110 assert(R1.isValid() && "First range is invalid?");
111 assert(R2.isValid() && "Second range is invalid?");
112 if (R1.getEnd() != R2.getBegin() &&
113 SM.isBeforeInTranslationUnit(R1.getEnd(), R2.getBegin()))
114 return RangeBefore;
115 if (R2.getEnd() != R1.getBegin() &&
116 SM.isBeforeInTranslationUnit(R2.getEnd(), R1.getBegin()))
117 return RangeAfter;
118 return RangeOverlap;
119}
120
121/// \brief Determine if a source location falls within, before, or after a
122/// a given source range.
123static RangeComparisonResult LocationCompare(SourceManager &SM,
124 SourceLocation L, SourceRange R) {
125 assert(R.isValid() && "First range is invalid?");
126 assert(L.isValid() && "Second range is invalid?");
127 if (L == R.getBegin() || L == R.getEnd())
128 return RangeOverlap;
129 if (SM.isBeforeInTranslationUnit(L, R.getBegin()))
130 return RangeBefore;
131 if (SM.isBeforeInTranslationUnit(R.getEnd(), L))
132 return RangeAfter;
133 return RangeOverlap;
134}
135
136/// \brief Translate a Clang source range into a CIndex source range.
137///
138/// Clang internally represents ranges where the end location points to the
139/// start of the token at the end. However, for external clients it is more
140/// useful to have a CXSourceRange be a proper half-open interval. This routine
141/// does the appropriate translation.
142CXSourceRange cxloc::translateSourceRange(const SourceManager &SM,
143 const LangOptions &LangOpts,
144 const CharSourceRange &R) {
145 // We want the last character in this location, so we will adjust the
146 // location accordingly.
147 SourceLocation EndLoc = R.getEnd();
148 if (EndLoc.isValid() && EndLoc.isMacroID() && !SM.isMacroArgExpansion(EndLoc))
149 EndLoc = SM.getExpansionRange(EndLoc).second;
Yaron Keren8b563662015-10-03 10:46:20 +0000150 if (R.isTokenRange() && EndLoc.isValid()) {
Guy Benyei11169dd2012-12-18 14:30:41 +0000151 unsigned Length = Lexer::MeasureTokenLength(SM.getSpellingLoc(EndLoc),
152 SM, LangOpts);
153 EndLoc = EndLoc.getLocWithOffset(Length);
154 }
155
Bill Wendlingeade3622013-01-23 08:25:41 +0000156 CXSourceRange Result = {
Dmitri Gribenkof9304482013-01-23 15:56:07 +0000157 { &SM, &LangOpts },
Bill Wendlingeade3622013-01-23 08:25:41 +0000158 R.getBegin().getRawEncoding(),
159 EndLoc.getRawEncoding()
160 };
Guy Benyei11169dd2012-12-18 14:30:41 +0000161 return Result;
162}
163
164//===----------------------------------------------------------------------===//
165// Cursor visitor.
166//===----------------------------------------------------------------------===//
167
168static SourceRange getRawCursorExtent(CXCursor C);
169static SourceRange getFullCursorExtent(CXCursor C, SourceManager &SrcMgr);
170
171
172RangeComparisonResult CursorVisitor::CompareRegionOfInterest(SourceRange R) {
173 return RangeCompare(AU->getSourceManager(), R, RegionOfInterest);
174}
175
176/// \brief Visit the given cursor and, if requested by the visitor,
177/// its children.
178///
179/// \param Cursor the cursor to visit.
180///
181/// \param CheckedRegionOfInterest if true, then the caller already checked
182/// that this cursor is within the region of interest.
183///
184/// \returns true if the visitation should be aborted, false if it
185/// should continue.
186bool CursorVisitor::Visit(CXCursor Cursor, bool CheckedRegionOfInterest) {
187 if (clang_isInvalid(Cursor.kind))
188 return false;
189
190 if (clang_isDeclaration(Cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +0000191 const Decl *D = getCursorDecl(Cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +0000192 if (!D) {
193 assert(0 && "Invalid declaration cursor");
194 return true; // abort.
195 }
196
197 // Ignore implicit declarations, unless it's an objc method because
198 // currently we should report implicit methods for properties when indexing.
199 if (D->isImplicit() && !isa<ObjCMethodDecl>(D))
200 return false;
201 }
202
203 // If we have a range of interest, and this cursor doesn't intersect with it,
204 // we're done.
205 if (RegionOfInterest.isValid() && !CheckedRegionOfInterest) {
206 SourceRange Range = getRawCursorExtent(Cursor);
207 if (Range.isInvalid() || CompareRegionOfInterest(Range))
208 return false;
209 }
210
211 switch (Visitor(Cursor, Parent, ClientData)) {
212 case CXChildVisit_Break:
213 return true;
214
215 case CXChildVisit_Continue:
216 return false;
217
218 case CXChildVisit_Recurse: {
219 bool ret = VisitChildren(Cursor);
220 if (PostChildrenVisitor)
221 if (PostChildrenVisitor(Cursor, ClientData))
222 return true;
223 return ret;
224 }
225 }
226
227 llvm_unreachable("Invalid CXChildVisitResult!");
228}
229
230static bool visitPreprocessedEntitiesInRange(SourceRange R,
231 PreprocessingRecord &PPRec,
232 CursorVisitor &Visitor) {
233 SourceManager &SM = Visitor.getASTUnit()->getSourceManager();
234 FileID FID;
235
236 if (!Visitor.shouldVisitIncludedEntities()) {
237 // If the begin/end of the range lie in the same FileID, do the optimization
238 // where we skip preprocessed entities that do not come from the same FileID.
239 FID = SM.getFileID(SM.getFileLoc(R.getBegin()));
240 if (FID != SM.getFileID(SM.getFileLoc(R.getEnd())))
241 FID = FileID();
242 }
243
Benjamin Kramerb4ef6682015-02-06 17:25:10 +0000244 const auto &Entities = PPRec.getPreprocessedEntitiesInRange(R);
245 return Visitor.visitPreprocessedEntities(Entities.begin(), Entities.end(),
Guy Benyei11169dd2012-12-18 14:30:41 +0000246 PPRec, FID);
247}
248
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000249bool CursorVisitor::visitFileRegion() {
Guy Benyei11169dd2012-12-18 14:30:41 +0000250 if (RegionOfInterest.isInvalid())
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000251 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000252
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +0000253 ASTUnit *Unit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +0000254 SourceManager &SM = Unit->getSourceManager();
255
256 std::pair<FileID, unsigned>
257 Begin = SM.getDecomposedLoc(SM.getFileLoc(RegionOfInterest.getBegin())),
258 End = SM.getDecomposedLoc(SM.getFileLoc(RegionOfInterest.getEnd()));
259
260 if (End.first != Begin.first) {
261 // If the end does not reside in the same file, try to recover by
262 // picking the end of the file of begin location.
263 End.first = Begin.first;
264 End.second = SM.getFileIDSize(Begin.first);
265 }
266
267 assert(Begin.first == End.first);
268 if (Begin.second > End.second)
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000269 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000270
271 FileID File = Begin.first;
272 unsigned Offset = Begin.second;
273 unsigned Length = End.second - Begin.second;
274
275 if (!VisitDeclsOnly && !VisitPreprocessorLast)
276 if (visitPreprocessedEntitiesInRegion())
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000277 return true; // visitation break.
Guy Benyei11169dd2012-12-18 14:30:41 +0000278
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000279 if (visitDeclsFromFileRegion(File, Offset, Length))
280 return true; // visitation break.
Guy Benyei11169dd2012-12-18 14:30:41 +0000281
282 if (!VisitDeclsOnly && VisitPreprocessorLast)
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000283 return visitPreprocessedEntitiesInRegion();
284
285 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000286}
287
288static bool isInLexicalContext(Decl *D, DeclContext *DC) {
289 if (!DC)
290 return false;
291
292 for (DeclContext *DeclDC = D->getLexicalDeclContext();
293 DeclDC; DeclDC = DeclDC->getLexicalParent()) {
294 if (DeclDC == DC)
295 return true;
296 }
297 return false;
298}
299
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000300bool CursorVisitor::visitDeclsFromFileRegion(FileID File,
Guy Benyei11169dd2012-12-18 14:30:41 +0000301 unsigned Offset, unsigned Length) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +0000302 ASTUnit *Unit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +0000303 SourceManager &SM = Unit->getSourceManager();
304 SourceRange Range = RegionOfInterest;
305
306 SmallVector<Decl *, 16> Decls;
307 Unit->findFileRegionDecls(File, Offset, Length, Decls);
308
309 // If we didn't find any file level decls for the file, try looking at the
310 // file that it was included from.
311 while (Decls.empty() || Decls.front()->isTopLevelDeclInObjCContainer()) {
312 bool Invalid = false;
313 const SrcMgr::SLocEntry &SLEntry = SM.getSLocEntry(File, &Invalid);
314 if (Invalid)
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000315 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000316
317 SourceLocation Outer;
318 if (SLEntry.isFile())
319 Outer = SLEntry.getFile().getIncludeLoc();
320 else
321 Outer = SLEntry.getExpansion().getExpansionLocStart();
322 if (Outer.isInvalid())
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000323 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000324
Benjamin Kramer867ea1d2014-03-02 13:01:17 +0000325 std::tie(File, Offset) = SM.getDecomposedExpansionLoc(Outer);
Guy Benyei11169dd2012-12-18 14:30:41 +0000326 Length = 0;
327 Unit->findFileRegionDecls(File, Offset, Length, Decls);
328 }
329
330 assert(!Decls.empty());
331
332 bool VisitedAtLeastOnce = false;
Craig Topper69186e72014-06-08 08:38:04 +0000333 DeclContext *CurDC = nullptr;
Craig Topper2341c0d2013-07-04 03:08:24 +0000334 SmallVectorImpl<Decl *>::iterator DIt = Decls.begin();
335 for (SmallVectorImpl<Decl *>::iterator DE = Decls.end(); DIt != DE; ++DIt) {
Guy Benyei11169dd2012-12-18 14:30:41 +0000336 Decl *D = *DIt;
337 if (D->getSourceRange().isInvalid())
338 continue;
339
340 if (isInLexicalContext(D, CurDC))
341 continue;
342
343 CurDC = dyn_cast<DeclContext>(D);
344
345 if (TagDecl *TD = dyn_cast<TagDecl>(D))
346 if (!TD->isFreeStanding())
347 continue;
348
349 RangeComparisonResult CompRes = RangeCompare(SM, D->getSourceRange(),Range);
350 if (CompRes == RangeBefore)
351 continue;
352 if (CompRes == RangeAfter)
353 break;
354
355 assert(CompRes == RangeOverlap);
356 VisitedAtLeastOnce = true;
357
358 if (isa<ObjCContainerDecl>(D)) {
359 FileDI_current = &DIt;
360 FileDE_current = DE;
361 } else {
Craig Topper69186e72014-06-08 08:38:04 +0000362 FileDI_current = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +0000363 }
364
365 if (Visit(MakeCXCursor(D, TU, Range), /*CheckedRegionOfInterest=*/true))
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000366 return true; // visitation break.
Guy Benyei11169dd2012-12-18 14:30:41 +0000367 }
368
369 if (VisitedAtLeastOnce)
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000370 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000371
372 // No Decls overlapped with the range. Move up the lexical context until there
373 // is a context that contains the range or we reach the translation unit
374 // level.
375 DeclContext *DC = DIt == Decls.begin() ? (*DIt)->getLexicalDeclContext()
376 : (*(DIt-1))->getLexicalDeclContext();
377
378 while (DC && !DC->isTranslationUnit()) {
379 Decl *D = cast<Decl>(DC);
380 SourceRange CurDeclRange = D->getSourceRange();
381 if (CurDeclRange.isInvalid())
382 break;
383
384 if (RangeCompare(SM, CurDeclRange, Range) == RangeOverlap) {
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000385 if (Visit(MakeCXCursor(D, TU, Range), /*CheckedRegionOfInterest=*/true))
386 return true; // visitation break.
Guy Benyei11169dd2012-12-18 14:30:41 +0000387 }
388
389 DC = D->getLexicalDeclContext();
390 }
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000391
392 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000393}
394
395bool CursorVisitor::visitPreprocessedEntitiesInRegion() {
396 if (!AU->getPreprocessor().getPreprocessingRecord())
397 return false;
398
399 PreprocessingRecord &PPRec
400 = *AU->getPreprocessor().getPreprocessingRecord();
401 SourceManager &SM = AU->getSourceManager();
402
403 if (RegionOfInterest.isValid()) {
404 SourceRange MappedRange = AU->mapRangeToPreamble(RegionOfInterest);
405 SourceLocation B = MappedRange.getBegin();
406 SourceLocation E = MappedRange.getEnd();
407
408 if (AU->isInPreambleFileID(B)) {
409 if (SM.isLoadedSourceLocation(E))
410 return visitPreprocessedEntitiesInRange(SourceRange(B, E),
411 PPRec, *this);
412
413 // Beginning of range lies in the preamble but it also extends beyond
414 // it into the main file. Split the range into 2 parts, one covering
415 // the preamble and another covering the main file. This allows subsequent
416 // calls to visitPreprocessedEntitiesInRange to accept a source range that
417 // lies in the same FileID, allowing it to skip preprocessed entities that
418 // do not come from the same FileID.
419 bool breaked =
420 visitPreprocessedEntitiesInRange(
421 SourceRange(B, AU->getEndOfPreambleFileID()),
422 PPRec, *this);
423 if (breaked) return true;
424 return visitPreprocessedEntitiesInRange(
425 SourceRange(AU->getStartOfMainFileID(), E),
426 PPRec, *this);
427 }
428
429 return visitPreprocessedEntitiesInRange(SourceRange(B, E), PPRec, *this);
430 }
431
432 bool OnlyLocalDecls
433 = !AU->isMainFileAST() && AU->getOnlyLocalDecls();
434
435 if (OnlyLocalDecls)
436 return visitPreprocessedEntities(PPRec.local_begin(), PPRec.local_end(),
437 PPRec);
438
439 return visitPreprocessedEntities(PPRec.begin(), PPRec.end(), PPRec);
440}
441
442template<typename InputIterator>
443bool CursorVisitor::visitPreprocessedEntities(InputIterator First,
444 InputIterator Last,
445 PreprocessingRecord &PPRec,
446 FileID FID) {
447 for (; First != Last; ++First) {
448 if (!FID.isInvalid() && !PPRec.isEntityInFileID(First, FID))
449 continue;
450
451 PreprocessedEntity *PPE = *First;
Argyrios Kyrtzidis1030f262013-05-07 20:37:17 +0000452 if (!PPE)
453 continue;
454
Guy Benyei11169dd2012-12-18 14:30:41 +0000455 if (MacroExpansion *ME = dyn_cast<MacroExpansion>(PPE)) {
456 if (Visit(MakeMacroExpansionCursor(ME, TU)))
457 return true;
Richard Smith66a81862015-05-04 02:25:31 +0000458
Guy Benyei11169dd2012-12-18 14:30:41 +0000459 continue;
460 }
Richard Smith66a81862015-05-04 02:25:31 +0000461
462 if (MacroDefinitionRecord *MD = dyn_cast<MacroDefinitionRecord>(PPE)) {
Guy Benyei11169dd2012-12-18 14:30:41 +0000463 if (Visit(MakeMacroDefinitionCursor(MD, TU)))
464 return true;
Richard Smith66a81862015-05-04 02:25:31 +0000465
Guy Benyei11169dd2012-12-18 14:30:41 +0000466 continue;
467 }
468
469 if (InclusionDirective *ID = dyn_cast<InclusionDirective>(PPE)) {
470 if (Visit(MakeInclusionDirectiveCursor(ID, TU)))
471 return true;
472
473 continue;
474 }
475 }
476
477 return false;
478}
479
480/// \brief Visit the children of the given cursor.
481///
482/// \returns true if the visitation should be aborted, false if it
483/// should continue.
484bool CursorVisitor::VisitChildren(CXCursor Cursor) {
485 if (clang_isReference(Cursor.kind) &&
486 Cursor.kind != CXCursor_CXXBaseSpecifier) {
487 // By definition, references have no children.
488 return false;
489 }
490
491 // Set the Parent field to Cursor, then back to its old value once we're
492 // done.
493 SetParentRAII SetParent(Parent, StmtParent, Cursor);
494
495 if (clang_isDeclaration(Cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +0000496 Decl *D = const_cast<Decl *>(getCursorDecl(Cursor));
Guy Benyei11169dd2012-12-18 14:30:41 +0000497 if (!D)
498 return false;
499
500 return VisitAttributes(D) || Visit(D);
501 }
502
503 if (clang_isStatement(Cursor.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +0000504 if (const Stmt *S = getCursorStmt(Cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +0000505 return Visit(S);
506
507 return false;
508 }
509
510 if (clang_isExpression(Cursor.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +0000511 if (const Expr *E = getCursorExpr(Cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +0000512 return Visit(E);
513
514 return false;
515 }
516
517 if (clang_isTranslationUnit(Cursor.kind)) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +0000518 CXTranslationUnit TU = getCursorTU(Cursor);
519 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +0000520
521 int VisitOrder[2] = { VisitPreprocessorLast, !VisitPreprocessorLast };
522 for (unsigned I = 0; I != 2; ++I) {
523 if (VisitOrder[I]) {
524 if (!CXXUnit->isMainFileAST() && CXXUnit->getOnlyLocalDecls() &&
525 RegionOfInterest.isInvalid()) {
526 for (ASTUnit::top_level_iterator TL = CXXUnit->top_level_begin(),
527 TLEnd = CXXUnit->top_level_end();
528 TL != TLEnd; ++TL) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +0000529 if (Visit(MakeCXCursor(*TL, TU, RegionOfInterest), true))
Guy Benyei11169dd2012-12-18 14:30:41 +0000530 return true;
531 }
532 } else if (VisitDeclContext(
533 CXXUnit->getASTContext().getTranslationUnitDecl()))
534 return true;
535 continue;
536 }
537
538 // Walk the preprocessing record.
539 if (CXXUnit->getPreprocessor().getPreprocessingRecord())
540 visitPreprocessedEntitiesInRegion();
541 }
542
543 return false;
544 }
545
546 if (Cursor.kind == CXCursor_CXXBaseSpecifier) {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +0000547 if (const CXXBaseSpecifier *Base = getCursorCXXBaseSpecifier(Cursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +0000548 if (TypeSourceInfo *BaseTSInfo = Base->getTypeSourceInfo()) {
549 return Visit(BaseTSInfo->getTypeLoc());
550 }
551 }
552 }
553
554 if (Cursor.kind == CXCursor_IBOutletCollectionAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +0000555 const IBOutletCollectionAttr *A =
Guy Benyei11169dd2012-12-18 14:30:41 +0000556 cast<IBOutletCollectionAttr>(cxcursor::getCursorAttr(Cursor));
Richard Smithb1f9a282013-10-31 01:56:18 +0000557 if (const ObjCObjectType *ObjT = A->getInterface()->getAs<ObjCObjectType>())
Richard Smithb87c4652013-10-31 21:23:20 +0000558 return Visit(cxcursor::MakeCursorObjCClassRef(
559 ObjT->getInterface(),
560 A->getInterfaceLoc()->getTypeLoc().getLocStart(), TU));
Guy Benyei11169dd2012-12-18 14:30:41 +0000561 }
562
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +0000563 // If pointing inside a macro definition, check if the token is an identifier
564 // that was ever defined as a macro. In such a case, create a "pseudo" macro
565 // expansion cursor for that token.
566 SourceLocation BeginLoc = RegionOfInterest.getBegin();
567 if (Cursor.kind == CXCursor_MacroDefinition &&
568 BeginLoc == RegionOfInterest.getEnd()) {
569 SourceLocation Loc = AU->mapLocationToPreamble(BeginLoc);
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +0000570 const MacroInfo *MI =
571 getMacroInfo(cxcursor::getCursorMacroDefinition(Cursor), TU);
Richard Smith66a81862015-05-04 02:25:31 +0000572 if (MacroDefinitionRecord *MacroDef =
573 checkForMacroInMacroDefinition(MI, Loc, TU))
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +0000574 return Visit(cxcursor::MakeMacroExpansionCursor(MacroDef, BeginLoc, TU));
575 }
576
Guy Benyei11169dd2012-12-18 14:30:41 +0000577 // Nothing to visit at the moment.
578 return false;
579}
580
581bool CursorVisitor::VisitBlockDecl(BlockDecl *B) {
582 if (TypeSourceInfo *TSInfo = B->getSignatureAsWritten())
583 if (Visit(TSInfo->getTypeLoc()))
584 return true;
585
586 if (Stmt *Body = B->getBody())
587 return Visit(MakeCXCursor(Body, StmtParent, TU, RegionOfInterest));
588
589 return false;
590}
591
Ted Kremenek03325582013-02-21 01:29:01 +0000592Optional<bool> CursorVisitor::shouldVisitCursor(CXCursor Cursor) {
Guy Benyei11169dd2012-12-18 14:30:41 +0000593 if (RegionOfInterest.isValid()) {
594 SourceRange Range = getFullCursorExtent(Cursor, AU->getSourceManager());
595 if (Range.isInvalid())
David Blaikie7a30dc52013-02-21 01:47:18 +0000596 return None;
Guy Benyei11169dd2012-12-18 14:30:41 +0000597
598 switch (CompareRegionOfInterest(Range)) {
599 case RangeBefore:
600 // This declaration comes before the region of interest; skip it.
David Blaikie7a30dc52013-02-21 01:47:18 +0000601 return None;
Guy Benyei11169dd2012-12-18 14:30:41 +0000602
603 case RangeAfter:
604 // This declaration comes after the region of interest; we're done.
605 return false;
606
607 case RangeOverlap:
608 // This declaration overlaps the region of interest; visit it.
609 break;
610 }
611 }
612 return true;
613}
614
615bool CursorVisitor::VisitDeclContext(DeclContext *DC) {
616 DeclContext::decl_iterator I = DC->decls_begin(), E = DC->decls_end();
617
618 // FIXME: Eventually remove. This part of a hack to support proper
619 // iteration over all Decls contained lexically within an ObjC container.
620 SaveAndRestore<DeclContext::decl_iterator*> DI_saved(DI_current, &I);
621 SaveAndRestore<DeclContext::decl_iterator> DE_saved(DE_current, E);
622
623 for ( ; I != E; ++I) {
624 Decl *D = *I;
625 if (D->getLexicalDeclContext() != DC)
626 continue;
627 CXCursor Cursor = MakeCXCursor(D, TU, RegionOfInterest);
628
629 // Ignore synthesized ivars here, otherwise if we have something like:
630 // @synthesize prop = _prop;
631 // and '_prop' is not declared, we will encounter a '_prop' ivar before
632 // encountering the 'prop' synthesize declaration and we will think that
633 // we passed the region-of-interest.
634 if (ObjCIvarDecl *ivarD = dyn_cast<ObjCIvarDecl>(D)) {
635 if (ivarD->getSynthesize())
636 continue;
637 }
638
639 // FIXME: ObjCClassRef/ObjCProtocolRef for forward class/protocol
640 // declarations is a mismatch with the compiler semantics.
641 if (Cursor.kind == CXCursor_ObjCInterfaceDecl) {
642 ObjCInterfaceDecl *ID = cast<ObjCInterfaceDecl>(D);
643 if (!ID->isThisDeclarationADefinition())
644 Cursor = MakeCursorObjCClassRef(ID, ID->getLocation(), TU);
645
646 } else if (Cursor.kind == CXCursor_ObjCProtocolDecl) {
647 ObjCProtocolDecl *PD = cast<ObjCProtocolDecl>(D);
648 if (!PD->isThisDeclarationADefinition())
649 Cursor = MakeCursorObjCProtocolRef(PD, PD->getLocation(), TU);
650 }
651
Ted Kremenek03325582013-02-21 01:29:01 +0000652 const Optional<bool> &V = shouldVisitCursor(Cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +0000653 if (!V.hasValue())
654 continue;
655 if (!V.getValue())
656 return false;
657 if (Visit(Cursor, true))
658 return true;
659 }
660 return false;
661}
662
663bool CursorVisitor::VisitTranslationUnitDecl(TranslationUnitDecl *D) {
664 llvm_unreachable("Translation units are visited directly by Visit()");
665}
666
Sergey Kalinichev8f3b1872015-11-15 13:48:32 +0000667bool CursorVisitor::VisitTypeAliasTemplateDecl(TypeAliasTemplateDecl *D) {
668 if (VisitTemplateParameters(D->getTemplateParameters()))
669 return true;
670
671 return Visit(MakeCXCursor(D->getTemplatedDecl(), TU, RegionOfInterest));
672}
673
Guy Benyei11169dd2012-12-18 14:30:41 +0000674bool CursorVisitor::VisitTypeAliasDecl(TypeAliasDecl *D) {
675 if (TypeSourceInfo *TSInfo = D->getTypeSourceInfo())
676 return Visit(TSInfo->getTypeLoc());
677
678 return false;
679}
680
681bool CursorVisitor::VisitTypedefDecl(TypedefDecl *D) {
682 if (TypeSourceInfo *TSInfo = D->getTypeSourceInfo())
683 return Visit(TSInfo->getTypeLoc());
684
685 return false;
686}
687
688bool CursorVisitor::VisitTagDecl(TagDecl *D) {
689 return VisitDeclContext(D);
690}
691
692bool CursorVisitor::VisitClassTemplateSpecializationDecl(
693 ClassTemplateSpecializationDecl *D) {
694 bool ShouldVisitBody = false;
695 switch (D->getSpecializationKind()) {
696 case TSK_Undeclared:
697 case TSK_ImplicitInstantiation:
698 // Nothing to visit
699 return false;
700
701 case TSK_ExplicitInstantiationDeclaration:
702 case TSK_ExplicitInstantiationDefinition:
703 break;
704
705 case TSK_ExplicitSpecialization:
706 ShouldVisitBody = true;
707 break;
708 }
709
710 // Visit the template arguments used in the specialization.
711 if (TypeSourceInfo *SpecType = D->getTypeAsWritten()) {
712 TypeLoc TL = SpecType->getTypeLoc();
David Blaikie6adc78e2013-02-18 22:06:02 +0000713 if (TemplateSpecializationTypeLoc TSTLoc =
714 TL.getAs<TemplateSpecializationTypeLoc>()) {
715 for (unsigned I = 0, N = TSTLoc.getNumArgs(); I != N; ++I)
716 if (VisitTemplateArgumentLoc(TSTLoc.getArgLoc(I)))
Guy Benyei11169dd2012-12-18 14:30:41 +0000717 return true;
718 }
719 }
Alexander Kornienko1a9f1842015-12-28 15:24:08 +0000720
721 return ShouldVisitBody && VisitCXXRecordDecl(D);
Guy Benyei11169dd2012-12-18 14:30:41 +0000722}
723
724bool CursorVisitor::VisitClassTemplatePartialSpecializationDecl(
725 ClassTemplatePartialSpecializationDecl *D) {
726 // FIXME: Visit the "outer" template parameter lists on the TagDecl
727 // before visiting these template parameters.
728 if (VisitTemplateParameters(D->getTemplateParameters()))
729 return true;
730
731 // Visit the partial specialization arguments.
Enea Zaffanella6dbe1872013-08-10 07:24:53 +0000732 const ASTTemplateArgumentListInfo *Info = D->getTemplateArgsAsWritten();
733 const TemplateArgumentLoc *TemplateArgs = Info->getTemplateArgs();
734 for (unsigned I = 0, N = Info->NumTemplateArgs; I != N; ++I)
Guy Benyei11169dd2012-12-18 14:30:41 +0000735 if (VisitTemplateArgumentLoc(TemplateArgs[I]))
736 return true;
737
738 return VisitCXXRecordDecl(D);
739}
740
741bool CursorVisitor::VisitTemplateTypeParmDecl(TemplateTypeParmDecl *D) {
742 // Visit the default argument.
743 if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited())
744 if (TypeSourceInfo *DefArg = D->getDefaultArgumentInfo())
745 if (Visit(DefArg->getTypeLoc()))
746 return true;
747
748 return false;
749}
750
751bool CursorVisitor::VisitEnumConstantDecl(EnumConstantDecl *D) {
752 if (Expr *Init = D->getInitExpr())
753 return Visit(MakeCXCursor(Init, StmtParent, TU, RegionOfInterest));
754 return false;
755}
756
757bool CursorVisitor::VisitDeclaratorDecl(DeclaratorDecl *DD) {
Argyrios Kyrtzidis2ec76742013-04-05 21:04:10 +0000758 unsigned NumParamList = DD->getNumTemplateParameterLists();
759 for (unsigned i = 0; i < NumParamList; i++) {
760 TemplateParameterList* Params = DD->getTemplateParameterList(i);
761 if (VisitTemplateParameters(Params))
762 return true;
763 }
764
Guy Benyei11169dd2012-12-18 14:30:41 +0000765 if (TypeSourceInfo *TSInfo = DD->getTypeSourceInfo())
766 if (Visit(TSInfo->getTypeLoc()))
767 return true;
768
769 // Visit the nested-name-specifier, if present.
770 if (NestedNameSpecifierLoc QualifierLoc = DD->getQualifierLoc())
771 if (VisitNestedNameSpecifierLoc(QualifierLoc))
772 return true;
773
774 return false;
775}
776
Benjamin Kramer4cadf292014-03-07 21:51:58 +0000777/// \brief Compare two base or member initializers based on their source order.
778static int CompareCXXCtorInitializers(CXXCtorInitializer *const *X,
779 CXXCtorInitializer *const *Y) {
780 return (*X)->getSourceOrder() - (*Y)->getSourceOrder();
781}
782
Guy Benyei11169dd2012-12-18 14:30:41 +0000783bool CursorVisitor::VisitFunctionDecl(FunctionDecl *ND) {
Argyrios Kyrtzidis2ec76742013-04-05 21:04:10 +0000784 unsigned NumParamList = ND->getNumTemplateParameterLists();
785 for (unsigned i = 0; i < NumParamList; i++) {
786 TemplateParameterList* Params = ND->getTemplateParameterList(i);
787 if (VisitTemplateParameters(Params))
788 return true;
789 }
790
Guy Benyei11169dd2012-12-18 14:30:41 +0000791 if (TypeSourceInfo *TSInfo = ND->getTypeSourceInfo()) {
792 // Visit the function declaration's syntactic components in the order
793 // written. This requires a bit of work.
794 TypeLoc TL = TSInfo->getTypeLoc().IgnoreParens();
David Blaikie6adc78e2013-02-18 22:06:02 +0000795 FunctionTypeLoc FTL = TL.getAs<FunctionTypeLoc>();
Guy Benyei11169dd2012-12-18 14:30:41 +0000796
797 // If we have a function declared directly (without the use of a typedef),
798 // visit just the return type. Otherwise, just visit the function's type
799 // now.
Alp Toker42a16a62014-01-25 23:51:36 +0000800 if ((FTL && !isa<CXXConversionDecl>(ND) && Visit(FTL.getReturnLoc())) ||
Guy Benyei11169dd2012-12-18 14:30:41 +0000801 (!FTL && Visit(TL)))
802 return true;
803
804 // Visit the nested-name-specifier, if present.
805 if (NestedNameSpecifierLoc QualifierLoc = ND->getQualifierLoc())
806 if (VisitNestedNameSpecifierLoc(QualifierLoc))
807 return true;
808
809 // Visit the declaration name.
Argyrios Kyrtzidis4a4d2b42014-02-09 08:13:47 +0000810 if (!isa<CXXDestructorDecl>(ND))
811 if (VisitDeclarationNameInfo(ND->getNameInfo()))
812 return true;
Guy Benyei11169dd2012-12-18 14:30:41 +0000813
814 // FIXME: Visit explicitly-specified template arguments!
815
816 // Visit the function parameters, if we have a function type.
David Blaikie6adc78e2013-02-18 22:06:02 +0000817 if (FTL && VisitFunctionTypeLoc(FTL, true))
Guy Benyei11169dd2012-12-18 14:30:41 +0000818 return true;
819
Bill Wendling44426052012-12-20 19:22:21 +0000820 // FIXME: Attributes?
Guy Benyei11169dd2012-12-18 14:30:41 +0000821 }
822
823 if (ND->doesThisDeclarationHaveABody() && !ND->isLateTemplateParsed()) {
824 if (CXXConstructorDecl *Constructor = dyn_cast<CXXConstructorDecl>(ND)) {
825 // Find the initializers that were written in the source.
826 SmallVector<CXXCtorInitializer *, 4> WrittenInits;
Aaron Ballman0ad78302014-03-13 17:34:31 +0000827 for (auto *I : Constructor->inits()) {
828 if (!I->isWritten())
Guy Benyei11169dd2012-12-18 14:30:41 +0000829 continue;
830
Aaron Ballman0ad78302014-03-13 17:34:31 +0000831 WrittenInits.push_back(I);
Guy Benyei11169dd2012-12-18 14:30:41 +0000832 }
833
834 // Sort the initializers in source order
Benjamin Kramer4cadf292014-03-07 21:51:58 +0000835 llvm::array_pod_sort(WrittenInits.begin(), WrittenInits.end(),
836 &CompareCXXCtorInitializers);
837
Guy Benyei11169dd2012-12-18 14:30:41 +0000838 // Visit the initializers in source order
839 for (unsigned I = 0, N = WrittenInits.size(); I != N; ++I) {
840 CXXCtorInitializer *Init = WrittenInits[I];
841 if (Init->isAnyMemberInitializer()) {
842 if (Visit(MakeCursorMemberRef(Init->getAnyMember(),
843 Init->getMemberLocation(), TU)))
844 return true;
845 } else if (TypeSourceInfo *TInfo = Init->getTypeSourceInfo()) {
846 if (Visit(TInfo->getTypeLoc()))
847 return true;
848 }
849
850 // Visit the initializer value.
851 if (Expr *Initializer = Init->getInit())
852 if (Visit(MakeCXCursor(Initializer, ND, TU, RegionOfInterest)))
853 return true;
854 }
855 }
856
857 if (Visit(MakeCXCursor(ND->getBody(), StmtParent, TU, RegionOfInterest)))
858 return true;
859 }
860
861 return false;
862}
863
864bool CursorVisitor::VisitFieldDecl(FieldDecl *D) {
865 if (VisitDeclaratorDecl(D))
866 return true;
867
868 if (Expr *BitWidth = D->getBitWidth())
869 return Visit(MakeCXCursor(BitWidth, StmtParent, TU, RegionOfInterest));
870
871 return false;
872}
873
874bool CursorVisitor::VisitVarDecl(VarDecl *D) {
875 if (VisitDeclaratorDecl(D))
876 return true;
877
878 if (Expr *Init = D->getInit())
879 return Visit(MakeCXCursor(Init, StmtParent, TU, RegionOfInterest));
880
881 return false;
882}
883
884bool CursorVisitor::VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl *D) {
885 if (VisitDeclaratorDecl(D))
886 return true;
887
888 if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited())
889 if (Expr *DefArg = D->getDefaultArgument())
890 return Visit(MakeCXCursor(DefArg, StmtParent, TU, RegionOfInterest));
891
892 return false;
893}
894
895bool CursorVisitor::VisitFunctionTemplateDecl(FunctionTemplateDecl *D) {
896 // FIXME: Visit the "outer" template parameter lists on the FunctionDecl
897 // before visiting these template parameters.
898 if (VisitTemplateParameters(D->getTemplateParameters()))
899 return true;
900
901 return VisitFunctionDecl(D->getTemplatedDecl());
902}
903
904bool CursorVisitor::VisitClassTemplateDecl(ClassTemplateDecl *D) {
905 // FIXME: Visit the "outer" template parameter lists on the TagDecl
906 // before visiting these template parameters.
907 if (VisitTemplateParameters(D->getTemplateParameters()))
908 return true;
909
910 return VisitCXXRecordDecl(D->getTemplatedDecl());
911}
912
913bool CursorVisitor::VisitTemplateTemplateParmDecl(TemplateTemplateParmDecl *D) {
914 if (VisitTemplateParameters(D->getTemplateParameters()))
915 return true;
916
917 if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited() &&
918 VisitTemplateArgumentLoc(D->getDefaultArgument()))
919 return true;
920
921 return false;
922}
923
Douglas Gregor9bda6cf2015-07-07 03:58:14 +0000924bool CursorVisitor::VisitObjCTypeParamDecl(ObjCTypeParamDecl *D) {
925 // Visit the bound, if it's explicit.
926 if (D->hasExplicitBound()) {
927 if (auto TInfo = D->getTypeSourceInfo()) {
928 if (Visit(TInfo->getTypeLoc()))
929 return true;
930 }
931 }
932
933 return false;
934}
935
Guy Benyei11169dd2012-12-18 14:30:41 +0000936bool CursorVisitor::VisitObjCMethodDecl(ObjCMethodDecl *ND) {
Alp Toker314cc812014-01-25 16:55:45 +0000937 if (TypeSourceInfo *TSInfo = ND->getReturnTypeSourceInfo())
Guy Benyei11169dd2012-12-18 14:30:41 +0000938 if (Visit(TSInfo->getTypeLoc()))
939 return true;
940
Aaron Ballman43b68be2014-03-07 17:50:17 +0000941 for (const auto *P : ND->params()) {
942 if (Visit(MakeCXCursor(P, TU, RegionOfInterest)))
Guy Benyei11169dd2012-12-18 14:30:41 +0000943 return true;
944 }
945
Alexander Kornienko1a9f1842015-12-28 15:24:08 +0000946 return ND->isThisDeclarationADefinition() &&
947 Visit(MakeCXCursor(ND->getBody(), StmtParent, TU, RegionOfInterest));
Guy Benyei11169dd2012-12-18 14:30:41 +0000948}
949
950template <typename DeclIt>
951static void addRangedDeclsInContainer(DeclIt *DI_current, DeclIt DE_current,
952 SourceManager &SM, SourceLocation EndLoc,
953 SmallVectorImpl<Decl *> &Decls) {
954 DeclIt next = *DI_current;
955 while (++next != DE_current) {
956 Decl *D_next = *next;
957 if (!D_next)
958 break;
959 SourceLocation L = D_next->getLocStart();
960 if (!L.isValid())
961 break;
962 if (SM.isBeforeInTranslationUnit(L, EndLoc)) {
963 *DI_current = next;
964 Decls.push_back(D_next);
965 continue;
966 }
967 break;
968 }
969}
970
Guy Benyei11169dd2012-12-18 14:30:41 +0000971bool CursorVisitor::VisitObjCContainerDecl(ObjCContainerDecl *D) {
972 // FIXME: Eventually convert back to just 'VisitDeclContext()'. Essentially
973 // an @implementation can lexically contain Decls that are not properly
974 // nested in the AST. When we identify such cases, we need to retrofit
975 // this nesting here.
976 if (!DI_current && !FileDI_current)
977 return VisitDeclContext(D);
978
979 // Scan the Decls that immediately come after the container
980 // in the current DeclContext. If any fall within the
981 // container's lexical region, stash them into a vector
982 // for later processing.
983 SmallVector<Decl *, 24> DeclsInContainer;
984 SourceLocation EndLoc = D->getSourceRange().getEnd();
985 SourceManager &SM = AU->getSourceManager();
986 if (EndLoc.isValid()) {
987 if (DI_current) {
988 addRangedDeclsInContainer(DI_current, DE_current, SM, EndLoc,
989 DeclsInContainer);
990 } else {
991 addRangedDeclsInContainer(FileDI_current, FileDE_current, SM, EndLoc,
992 DeclsInContainer);
993 }
994 }
995
996 // The common case.
997 if (DeclsInContainer.empty())
998 return VisitDeclContext(D);
999
1000 // Get all the Decls in the DeclContext, and sort them with the
1001 // additional ones we've collected. Then visit them.
Aaron Ballman629afae2014-03-07 19:56:05 +00001002 for (auto *SubDecl : D->decls()) {
1003 if (!SubDecl || SubDecl->getLexicalDeclContext() != D ||
1004 SubDecl->getLocStart().isInvalid())
Guy Benyei11169dd2012-12-18 14:30:41 +00001005 continue;
Aaron Ballman629afae2014-03-07 19:56:05 +00001006 DeclsInContainer.push_back(SubDecl);
Guy Benyei11169dd2012-12-18 14:30:41 +00001007 }
1008
1009 // Now sort the Decls so that they appear in lexical order.
1010 std::sort(DeclsInContainer.begin(), DeclsInContainer.end(),
Benjamin Kramerbbdd7642014-03-01 14:48:57 +00001011 [&SM](Decl *A, Decl *B) {
1012 SourceLocation L_A = A->getLocStart();
1013 SourceLocation L_B = B->getLocStart();
1014 assert(L_A.isValid() && L_B.isValid());
1015 return SM.isBeforeInTranslationUnit(L_A, L_B);
1016 });
Guy Benyei11169dd2012-12-18 14:30:41 +00001017
1018 // Now visit the decls.
1019 for (SmallVectorImpl<Decl*>::iterator I = DeclsInContainer.begin(),
1020 E = DeclsInContainer.end(); I != E; ++I) {
1021 CXCursor Cursor = MakeCXCursor(*I, TU, RegionOfInterest);
Ted Kremenek03325582013-02-21 01:29:01 +00001022 const Optional<bool> &V = shouldVisitCursor(Cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00001023 if (!V.hasValue())
1024 continue;
1025 if (!V.getValue())
1026 return false;
1027 if (Visit(Cursor, true))
1028 return true;
1029 }
1030 return false;
1031}
1032
1033bool CursorVisitor::VisitObjCCategoryDecl(ObjCCategoryDecl *ND) {
1034 if (Visit(MakeCursorObjCClassRef(ND->getClassInterface(), ND->getLocation(),
1035 TU)))
1036 return true;
1037
Douglas Gregore9d95f12015-07-07 03:57:35 +00001038 if (VisitObjCTypeParamList(ND->getTypeParamList()))
1039 return true;
1040
Guy Benyei11169dd2012-12-18 14:30:41 +00001041 ObjCCategoryDecl::protocol_loc_iterator PL = ND->protocol_loc_begin();
1042 for (ObjCCategoryDecl::protocol_iterator I = ND->protocol_begin(),
1043 E = ND->protocol_end(); I != E; ++I, ++PL)
1044 if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
1045 return true;
1046
1047 return VisitObjCContainerDecl(ND);
1048}
1049
1050bool CursorVisitor::VisitObjCProtocolDecl(ObjCProtocolDecl *PID) {
1051 if (!PID->isThisDeclarationADefinition())
1052 return Visit(MakeCursorObjCProtocolRef(PID, PID->getLocation(), TU));
1053
1054 ObjCProtocolDecl::protocol_loc_iterator PL = PID->protocol_loc_begin();
1055 for (ObjCProtocolDecl::protocol_iterator I = PID->protocol_begin(),
1056 E = PID->protocol_end(); I != E; ++I, ++PL)
1057 if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
1058 return true;
1059
1060 return VisitObjCContainerDecl(PID);
1061}
1062
1063bool CursorVisitor::VisitObjCPropertyDecl(ObjCPropertyDecl *PD) {
1064 if (PD->getTypeSourceInfo() && Visit(PD->getTypeSourceInfo()->getTypeLoc()))
1065 return true;
1066
1067 // FIXME: This implements a workaround with @property declarations also being
1068 // installed in the DeclContext for the @interface. Eventually this code
1069 // should be removed.
1070 ObjCCategoryDecl *CDecl = dyn_cast<ObjCCategoryDecl>(PD->getDeclContext());
1071 if (!CDecl || !CDecl->IsClassExtension())
1072 return false;
1073
1074 ObjCInterfaceDecl *ID = CDecl->getClassInterface();
1075 if (!ID)
1076 return false;
1077
1078 IdentifierInfo *PropertyId = PD->getIdentifier();
1079 ObjCPropertyDecl *prevDecl =
Manman Ren5b786402016-01-28 18:49:28 +00001080 ObjCPropertyDecl::findPropertyDecl(cast<DeclContext>(ID), PropertyId,
1081 PD->getQueryKind());
Guy Benyei11169dd2012-12-18 14:30:41 +00001082
1083 if (!prevDecl)
1084 return false;
1085
1086 // Visit synthesized methods since they will be skipped when visiting
1087 // the @interface.
1088 if (ObjCMethodDecl *MD = prevDecl->getGetterMethodDecl())
1089 if (MD->isPropertyAccessor() && MD->getLexicalDeclContext() == CDecl)
1090 if (Visit(MakeCXCursor(MD, TU, RegionOfInterest)))
1091 return true;
1092
1093 if (ObjCMethodDecl *MD = prevDecl->getSetterMethodDecl())
1094 if (MD->isPropertyAccessor() && MD->getLexicalDeclContext() == CDecl)
1095 if (Visit(MakeCXCursor(MD, TU, RegionOfInterest)))
1096 return true;
1097
1098 return false;
1099}
1100
Douglas Gregore9d95f12015-07-07 03:57:35 +00001101bool CursorVisitor::VisitObjCTypeParamList(ObjCTypeParamList *typeParamList) {
1102 if (!typeParamList)
1103 return false;
1104
1105 for (auto *typeParam : *typeParamList) {
1106 // Visit the type parameter.
1107 if (Visit(MakeCXCursor(typeParam, TU, RegionOfInterest)))
1108 return true;
Douglas Gregore9d95f12015-07-07 03:57:35 +00001109 }
1110
1111 return false;
1112}
1113
Guy Benyei11169dd2012-12-18 14:30:41 +00001114bool CursorVisitor::VisitObjCInterfaceDecl(ObjCInterfaceDecl *D) {
1115 if (!D->isThisDeclarationADefinition()) {
1116 // Forward declaration is treated like a reference.
1117 return Visit(MakeCursorObjCClassRef(D, D->getLocation(), TU));
1118 }
1119
Douglas Gregore9d95f12015-07-07 03:57:35 +00001120 // Objective-C type parameters.
1121 if (VisitObjCTypeParamList(D->getTypeParamListAsWritten()))
1122 return true;
1123
Guy Benyei11169dd2012-12-18 14:30:41 +00001124 // Issue callbacks for super class.
1125 if (D->getSuperClass() &&
1126 Visit(MakeCursorObjCSuperClassRef(D->getSuperClass(),
1127 D->getSuperClassLoc(),
1128 TU)))
1129 return true;
1130
Douglas Gregore9d95f12015-07-07 03:57:35 +00001131 if (TypeSourceInfo *SuperClassTInfo = D->getSuperClassTInfo())
1132 if (Visit(SuperClassTInfo->getTypeLoc()))
1133 return true;
1134
Guy Benyei11169dd2012-12-18 14:30:41 +00001135 ObjCInterfaceDecl::protocol_loc_iterator PL = D->protocol_loc_begin();
1136 for (ObjCInterfaceDecl::protocol_iterator I = D->protocol_begin(),
1137 E = D->protocol_end(); I != E; ++I, ++PL)
1138 if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
1139 return true;
1140
1141 return VisitObjCContainerDecl(D);
1142}
1143
1144bool CursorVisitor::VisitObjCImplDecl(ObjCImplDecl *D) {
1145 return VisitObjCContainerDecl(D);
1146}
1147
1148bool CursorVisitor::VisitObjCCategoryImplDecl(ObjCCategoryImplDecl *D) {
1149 // 'ID' could be null when dealing with invalid code.
1150 if (ObjCInterfaceDecl *ID = D->getClassInterface())
1151 if (Visit(MakeCursorObjCClassRef(ID, D->getLocation(), TU)))
1152 return true;
1153
1154 return VisitObjCImplDecl(D);
1155}
1156
1157bool CursorVisitor::VisitObjCImplementationDecl(ObjCImplementationDecl *D) {
1158#if 0
1159 // Issue callbacks for super class.
1160 // FIXME: No source location information!
1161 if (D->getSuperClass() &&
1162 Visit(MakeCursorObjCSuperClassRef(D->getSuperClass(),
1163 D->getSuperClassLoc(),
1164 TU)))
1165 return true;
1166#endif
1167
1168 return VisitObjCImplDecl(D);
1169}
1170
1171bool CursorVisitor::VisitObjCPropertyImplDecl(ObjCPropertyImplDecl *PD) {
1172 if (ObjCIvarDecl *Ivar = PD->getPropertyIvarDecl())
1173 if (PD->isIvarNameSpecified())
1174 return Visit(MakeCursorMemberRef(Ivar, PD->getPropertyIvarDeclLoc(), TU));
1175
1176 return false;
1177}
1178
1179bool CursorVisitor::VisitNamespaceDecl(NamespaceDecl *D) {
1180 return VisitDeclContext(D);
1181}
1182
1183bool CursorVisitor::VisitNamespaceAliasDecl(NamespaceAliasDecl *D) {
1184 // Visit nested-name-specifier.
1185 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1186 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1187 return true;
1188
1189 return Visit(MakeCursorNamespaceRef(D->getAliasedNamespace(),
1190 D->getTargetNameLoc(), TU));
1191}
1192
1193bool CursorVisitor::VisitUsingDecl(UsingDecl *D) {
1194 // Visit nested-name-specifier.
1195 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc()) {
1196 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1197 return true;
1198 }
1199
1200 if (Visit(MakeCursorOverloadedDeclRef(D, D->getLocation(), TU)))
1201 return true;
1202
1203 return VisitDeclarationNameInfo(D->getNameInfo());
1204}
1205
1206bool CursorVisitor::VisitUsingDirectiveDecl(UsingDirectiveDecl *D) {
1207 // Visit nested-name-specifier.
1208 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1209 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1210 return true;
1211
1212 return Visit(MakeCursorNamespaceRef(D->getNominatedNamespaceAsWritten(),
1213 D->getIdentLocation(), TU));
1214}
1215
1216bool CursorVisitor::VisitUnresolvedUsingValueDecl(UnresolvedUsingValueDecl *D) {
1217 // Visit nested-name-specifier.
1218 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc()) {
1219 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1220 return true;
1221 }
1222
1223 return VisitDeclarationNameInfo(D->getNameInfo());
1224}
1225
1226bool CursorVisitor::VisitUnresolvedUsingTypenameDecl(
1227 UnresolvedUsingTypenameDecl *D) {
1228 // Visit nested-name-specifier.
1229 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1230 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1231 return true;
1232
1233 return false;
1234}
1235
1236bool CursorVisitor::VisitDeclarationNameInfo(DeclarationNameInfo Name) {
1237 switch (Name.getName().getNameKind()) {
1238 case clang::DeclarationName::Identifier:
1239 case clang::DeclarationName::CXXLiteralOperatorName:
1240 case clang::DeclarationName::CXXOperatorName:
1241 case clang::DeclarationName::CXXUsingDirective:
1242 return false;
1243
1244 case clang::DeclarationName::CXXConstructorName:
1245 case clang::DeclarationName::CXXDestructorName:
1246 case clang::DeclarationName::CXXConversionFunctionName:
1247 if (TypeSourceInfo *TSInfo = Name.getNamedTypeInfo())
1248 return Visit(TSInfo->getTypeLoc());
1249 return false;
1250
1251 case clang::DeclarationName::ObjCZeroArgSelector:
1252 case clang::DeclarationName::ObjCOneArgSelector:
1253 case clang::DeclarationName::ObjCMultiArgSelector:
1254 // FIXME: Per-identifier location info?
1255 return false;
1256 }
1257
1258 llvm_unreachable("Invalid DeclarationName::Kind!");
1259}
1260
1261bool CursorVisitor::VisitNestedNameSpecifier(NestedNameSpecifier *NNS,
1262 SourceRange Range) {
1263 // FIXME: This whole routine is a hack to work around the lack of proper
1264 // source information in nested-name-specifiers (PR5791). Since we do have
1265 // a beginning source location, we can visit the first component of the
1266 // nested-name-specifier, if it's a single-token component.
1267 if (!NNS)
1268 return false;
1269
1270 // Get the first component in the nested-name-specifier.
1271 while (NestedNameSpecifier *Prefix = NNS->getPrefix())
1272 NNS = Prefix;
1273
1274 switch (NNS->getKind()) {
1275 case NestedNameSpecifier::Namespace:
1276 return Visit(MakeCursorNamespaceRef(NNS->getAsNamespace(), Range.getBegin(),
1277 TU));
1278
1279 case NestedNameSpecifier::NamespaceAlias:
1280 return Visit(MakeCursorNamespaceRef(NNS->getAsNamespaceAlias(),
1281 Range.getBegin(), TU));
1282
1283 case NestedNameSpecifier::TypeSpec: {
1284 // If the type has a form where we know that the beginning of the source
1285 // range matches up with a reference cursor. Visit the appropriate reference
1286 // cursor.
1287 const Type *T = NNS->getAsType();
1288 if (const TypedefType *Typedef = dyn_cast<TypedefType>(T))
1289 return Visit(MakeCursorTypeRef(Typedef->getDecl(), Range.getBegin(), TU));
1290 if (const TagType *Tag = dyn_cast<TagType>(T))
1291 return Visit(MakeCursorTypeRef(Tag->getDecl(), Range.getBegin(), TU));
1292 if (const TemplateSpecializationType *TST
1293 = dyn_cast<TemplateSpecializationType>(T))
1294 return VisitTemplateName(TST->getTemplateName(), Range.getBegin());
1295 break;
1296 }
1297
1298 case NestedNameSpecifier::TypeSpecWithTemplate:
1299 case NestedNameSpecifier::Global:
1300 case NestedNameSpecifier::Identifier:
Nikola Smiljanic67860242014-09-26 00:28:20 +00001301 case NestedNameSpecifier::Super:
Guy Benyei11169dd2012-12-18 14:30:41 +00001302 break;
1303 }
1304
1305 return false;
1306}
1307
1308bool
1309CursorVisitor::VisitNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier) {
1310 SmallVector<NestedNameSpecifierLoc, 4> Qualifiers;
1311 for (; Qualifier; Qualifier = Qualifier.getPrefix())
1312 Qualifiers.push_back(Qualifier);
1313
1314 while (!Qualifiers.empty()) {
1315 NestedNameSpecifierLoc Q = Qualifiers.pop_back_val();
1316 NestedNameSpecifier *NNS = Q.getNestedNameSpecifier();
1317 switch (NNS->getKind()) {
1318 case NestedNameSpecifier::Namespace:
1319 if (Visit(MakeCursorNamespaceRef(NNS->getAsNamespace(),
1320 Q.getLocalBeginLoc(),
1321 TU)))
1322 return true;
1323
1324 break;
1325
1326 case NestedNameSpecifier::NamespaceAlias:
1327 if (Visit(MakeCursorNamespaceRef(NNS->getAsNamespaceAlias(),
1328 Q.getLocalBeginLoc(),
1329 TU)))
1330 return true;
1331
1332 break;
1333
1334 case NestedNameSpecifier::TypeSpec:
1335 case NestedNameSpecifier::TypeSpecWithTemplate:
1336 if (Visit(Q.getTypeLoc()))
1337 return true;
1338
1339 break;
1340
1341 case NestedNameSpecifier::Global:
1342 case NestedNameSpecifier::Identifier:
Nikola Smiljanic67860242014-09-26 00:28:20 +00001343 case NestedNameSpecifier::Super:
Guy Benyei11169dd2012-12-18 14:30:41 +00001344 break;
1345 }
1346 }
1347
1348 return false;
1349}
1350
1351bool CursorVisitor::VisitTemplateParameters(
1352 const TemplateParameterList *Params) {
1353 if (!Params)
1354 return false;
1355
1356 for (TemplateParameterList::const_iterator P = Params->begin(),
1357 PEnd = Params->end();
1358 P != PEnd; ++P) {
1359 if (Visit(MakeCXCursor(*P, TU, RegionOfInterest)))
1360 return true;
1361 }
1362
1363 return false;
1364}
1365
1366bool CursorVisitor::VisitTemplateName(TemplateName Name, SourceLocation Loc) {
1367 switch (Name.getKind()) {
1368 case TemplateName::Template:
1369 return Visit(MakeCursorTemplateRef(Name.getAsTemplateDecl(), Loc, TU));
1370
1371 case TemplateName::OverloadedTemplate:
1372 // Visit the overloaded template set.
1373 if (Visit(MakeCursorOverloadedDeclRef(Name, Loc, TU)))
1374 return true;
1375
1376 return false;
1377
1378 case TemplateName::DependentTemplate:
1379 // FIXME: Visit nested-name-specifier.
1380 return false;
1381
1382 case TemplateName::QualifiedTemplate:
1383 // FIXME: Visit nested-name-specifier.
1384 return Visit(MakeCursorTemplateRef(
1385 Name.getAsQualifiedTemplateName()->getDecl(),
1386 Loc, TU));
1387
1388 case TemplateName::SubstTemplateTemplateParm:
1389 return Visit(MakeCursorTemplateRef(
1390 Name.getAsSubstTemplateTemplateParm()->getParameter(),
1391 Loc, TU));
1392
1393 case TemplateName::SubstTemplateTemplateParmPack:
1394 return Visit(MakeCursorTemplateRef(
1395 Name.getAsSubstTemplateTemplateParmPack()->getParameterPack(),
1396 Loc, TU));
1397 }
1398
1399 llvm_unreachable("Invalid TemplateName::Kind!");
1400}
1401
1402bool CursorVisitor::VisitTemplateArgumentLoc(const TemplateArgumentLoc &TAL) {
1403 switch (TAL.getArgument().getKind()) {
1404 case TemplateArgument::Null:
1405 case TemplateArgument::Integral:
1406 case TemplateArgument::Pack:
1407 return false;
1408
1409 case TemplateArgument::Type:
1410 if (TypeSourceInfo *TSInfo = TAL.getTypeSourceInfo())
1411 return Visit(TSInfo->getTypeLoc());
1412 return false;
1413
1414 case TemplateArgument::Declaration:
1415 if (Expr *E = TAL.getSourceDeclExpression())
1416 return Visit(MakeCXCursor(E, StmtParent, TU, RegionOfInterest));
1417 return false;
1418
1419 case TemplateArgument::NullPtr:
1420 if (Expr *E = TAL.getSourceNullPtrExpression())
1421 return Visit(MakeCXCursor(E, StmtParent, TU, RegionOfInterest));
1422 return false;
1423
1424 case TemplateArgument::Expression:
1425 if (Expr *E = TAL.getSourceExpression())
1426 return Visit(MakeCXCursor(E, StmtParent, TU, RegionOfInterest));
1427 return false;
1428
1429 case TemplateArgument::Template:
1430 case TemplateArgument::TemplateExpansion:
1431 if (VisitNestedNameSpecifierLoc(TAL.getTemplateQualifierLoc()))
1432 return true;
1433
1434 return VisitTemplateName(TAL.getArgument().getAsTemplateOrTemplatePattern(),
1435 TAL.getTemplateNameLoc());
1436 }
1437
1438 llvm_unreachable("Invalid TemplateArgument::Kind!");
1439}
1440
1441bool CursorVisitor::VisitLinkageSpecDecl(LinkageSpecDecl *D) {
1442 return VisitDeclContext(D);
1443}
1444
1445bool CursorVisitor::VisitQualifiedTypeLoc(QualifiedTypeLoc TL) {
1446 return Visit(TL.getUnqualifiedLoc());
1447}
1448
1449bool CursorVisitor::VisitBuiltinTypeLoc(BuiltinTypeLoc TL) {
1450 ASTContext &Context = AU->getASTContext();
1451
1452 // Some builtin types (such as Objective-C's "id", "sel", and
1453 // "Class") have associated declarations. Create cursors for those.
1454 QualType VisitType;
1455 switch (TL.getTypePtr()->getKind()) {
1456
1457 case BuiltinType::Void:
1458 case BuiltinType::NullPtr:
1459 case BuiltinType::Dependent:
Guy Benyeid8a08ea2012-12-18 14:38:23 +00001460 case BuiltinType::OCLImage1d:
1461 case BuiltinType::OCLImage1dArray:
1462 case BuiltinType::OCLImage1dBuffer:
1463 case BuiltinType::OCLImage2d:
1464 case BuiltinType::OCLImage2dArray:
Alexey Bader9c8453f2015-09-15 11:18:52 +00001465 case BuiltinType::OCLImage2dDepth:
1466 case BuiltinType::OCLImage2dArrayDepth:
1467 case BuiltinType::OCLImage2dMSAA:
1468 case BuiltinType::OCLImage2dArrayMSAA:
1469 case BuiltinType::OCLImage2dMSAADepth:
1470 case BuiltinType::OCLImage2dArrayMSAADepth:
Guy Benyeid8a08ea2012-12-18 14:38:23 +00001471 case BuiltinType::OCLImage3d:
NAKAMURA Takumi288c42e2013-02-07 12:47:42 +00001472 case BuiltinType::OCLSampler:
Guy Benyei1b4fb3e2013-01-20 12:31:11 +00001473 case BuiltinType::OCLEvent:
Alexey Bader9c8453f2015-09-15 11:18:52 +00001474 case BuiltinType::OCLClkEvent:
1475 case BuiltinType::OCLQueue:
1476 case BuiltinType::OCLNDRange:
1477 case BuiltinType::OCLReserveID:
Guy Benyei11169dd2012-12-18 14:30:41 +00001478#define BUILTIN_TYPE(Id, SingletonId)
1479#define SIGNED_TYPE(Id, SingletonId) case BuiltinType::Id:
1480#define UNSIGNED_TYPE(Id, SingletonId) case BuiltinType::Id:
1481#define FLOATING_TYPE(Id, SingletonId) case BuiltinType::Id:
1482#define PLACEHOLDER_TYPE(Id, SingletonId) case BuiltinType::Id:
1483#include "clang/AST/BuiltinTypes.def"
1484 break;
1485
1486 case BuiltinType::ObjCId:
1487 VisitType = Context.getObjCIdType();
1488 break;
1489
1490 case BuiltinType::ObjCClass:
1491 VisitType = Context.getObjCClassType();
1492 break;
1493
1494 case BuiltinType::ObjCSel:
1495 VisitType = Context.getObjCSelType();
1496 break;
1497 }
1498
1499 if (!VisitType.isNull()) {
1500 if (const TypedefType *Typedef = VisitType->getAs<TypedefType>())
1501 return Visit(MakeCursorTypeRef(Typedef->getDecl(), TL.getBuiltinLoc(),
1502 TU));
1503 }
1504
1505 return false;
1506}
1507
1508bool CursorVisitor::VisitTypedefTypeLoc(TypedefTypeLoc TL) {
1509 return Visit(MakeCursorTypeRef(TL.getTypedefNameDecl(), TL.getNameLoc(), TU));
1510}
1511
1512bool CursorVisitor::VisitUnresolvedUsingTypeLoc(UnresolvedUsingTypeLoc TL) {
1513 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1514}
1515
1516bool CursorVisitor::VisitTagTypeLoc(TagTypeLoc TL) {
1517 if (TL.isDefinition())
1518 return Visit(MakeCXCursor(TL.getDecl(), TU, RegionOfInterest));
1519
1520 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1521}
1522
1523bool CursorVisitor::VisitTemplateTypeParmTypeLoc(TemplateTypeParmTypeLoc TL) {
1524 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1525}
1526
1527bool CursorVisitor::VisitObjCInterfaceTypeLoc(ObjCInterfaceTypeLoc TL) {
Hans Wennborg59dbe862015-09-29 20:56:43 +00001528 return Visit(MakeCursorObjCClassRef(TL.getIFaceDecl(), TL.getNameLoc(), TU));
Guy Benyei11169dd2012-12-18 14:30:41 +00001529}
1530
1531bool CursorVisitor::VisitObjCObjectTypeLoc(ObjCObjectTypeLoc TL) {
1532 if (TL.hasBaseTypeAsWritten() && Visit(TL.getBaseLoc()))
1533 return true;
1534
Douglas Gregore9d95f12015-07-07 03:57:35 +00001535 for (unsigned I = 0, N = TL.getNumTypeArgs(); I != N; ++I) {
1536 if (Visit(TL.getTypeArgTInfo(I)->getTypeLoc()))
1537 return true;
1538 }
1539
Guy Benyei11169dd2012-12-18 14:30:41 +00001540 for (unsigned I = 0, N = TL.getNumProtocols(); I != N; ++I) {
1541 if (Visit(MakeCursorObjCProtocolRef(TL.getProtocol(I), TL.getProtocolLoc(I),
1542 TU)))
1543 return true;
1544 }
1545
1546 return false;
1547}
1548
1549bool CursorVisitor::VisitObjCObjectPointerTypeLoc(ObjCObjectPointerTypeLoc TL) {
1550 return Visit(TL.getPointeeLoc());
1551}
1552
1553bool CursorVisitor::VisitParenTypeLoc(ParenTypeLoc TL) {
1554 return Visit(TL.getInnerLoc());
1555}
1556
1557bool CursorVisitor::VisitPointerTypeLoc(PointerTypeLoc TL) {
1558 return Visit(TL.getPointeeLoc());
1559}
1560
1561bool CursorVisitor::VisitBlockPointerTypeLoc(BlockPointerTypeLoc TL) {
1562 return Visit(TL.getPointeeLoc());
1563}
1564
1565bool CursorVisitor::VisitMemberPointerTypeLoc(MemberPointerTypeLoc TL) {
1566 return Visit(TL.getPointeeLoc());
1567}
1568
1569bool CursorVisitor::VisitLValueReferenceTypeLoc(LValueReferenceTypeLoc TL) {
1570 return Visit(TL.getPointeeLoc());
1571}
1572
1573bool CursorVisitor::VisitRValueReferenceTypeLoc(RValueReferenceTypeLoc TL) {
1574 return Visit(TL.getPointeeLoc());
1575}
1576
1577bool CursorVisitor::VisitAttributedTypeLoc(AttributedTypeLoc TL) {
1578 return Visit(TL.getModifiedLoc());
1579}
1580
1581bool CursorVisitor::VisitFunctionTypeLoc(FunctionTypeLoc TL,
1582 bool SkipResultType) {
Alp Toker42a16a62014-01-25 23:51:36 +00001583 if (!SkipResultType && Visit(TL.getReturnLoc()))
Guy Benyei11169dd2012-12-18 14:30:41 +00001584 return true;
1585
Alp Tokerb3fd5cf2014-01-21 00:32:38 +00001586 for (unsigned I = 0, N = TL.getNumParams(); I != N; ++I)
1587 if (Decl *D = TL.getParam(I))
Guy Benyei11169dd2012-12-18 14:30:41 +00001588 if (Visit(MakeCXCursor(D, TU, RegionOfInterest)))
1589 return true;
1590
1591 return false;
1592}
1593
1594bool CursorVisitor::VisitArrayTypeLoc(ArrayTypeLoc TL) {
1595 if (Visit(TL.getElementLoc()))
1596 return true;
1597
1598 if (Expr *Size = TL.getSizeExpr())
1599 return Visit(MakeCXCursor(Size, StmtParent, TU, RegionOfInterest));
1600
1601 return false;
1602}
1603
Reid Kleckner8a365022013-06-24 17:51:48 +00001604bool CursorVisitor::VisitDecayedTypeLoc(DecayedTypeLoc TL) {
1605 return Visit(TL.getOriginalLoc());
1606}
1607
Reid Kleckner0503a872013-12-05 01:23:43 +00001608bool CursorVisitor::VisitAdjustedTypeLoc(AdjustedTypeLoc TL) {
1609 return Visit(TL.getOriginalLoc());
1610}
1611
Guy Benyei11169dd2012-12-18 14:30:41 +00001612bool CursorVisitor::VisitTemplateSpecializationTypeLoc(
1613 TemplateSpecializationTypeLoc TL) {
1614 // Visit the template name.
1615 if (VisitTemplateName(TL.getTypePtr()->getTemplateName(),
1616 TL.getTemplateNameLoc()))
1617 return true;
1618
1619 // Visit the template arguments.
1620 for (unsigned I = 0, N = TL.getNumArgs(); I != N; ++I)
1621 if (VisitTemplateArgumentLoc(TL.getArgLoc(I)))
1622 return true;
1623
1624 return false;
1625}
1626
1627bool CursorVisitor::VisitTypeOfExprTypeLoc(TypeOfExprTypeLoc TL) {
1628 return Visit(MakeCXCursor(TL.getUnderlyingExpr(), StmtParent, TU));
1629}
1630
1631bool CursorVisitor::VisitTypeOfTypeLoc(TypeOfTypeLoc TL) {
1632 if (TypeSourceInfo *TSInfo = TL.getUnderlyingTInfo())
1633 return Visit(TSInfo->getTypeLoc());
1634
1635 return false;
1636}
1637
1638bool CursorVisitor::VisitUnaryTransformTypeLoc(UnaryTransformTypeLoc TL) {
1639 if (TypeSourceInfo *TSInfo = TL.getUnderlyingTInfo())
1640 return Visit(TSInfo->getTypeLoc());
1641
1642 return false;
1643}
1644
1645bool CursorVisitor::VisitDependentNameTypeLoc(DependentNameTypeLoc TL) {
Hans Wennborg59dbe862015-09-29 20:56:43 +00001646 return VisitNestedNameSpecifierLoc(TL.getQualifierLoc());
Guy Benyei11169dd2012-12-18 14:30:41 +00001647}
1648
1649bool CursorVisitor::VisitDependentTemplateSpecializationTypeLoc(
1650 DependentTemplateSpecializationTypeLoc TL) {
1651 // Visit the nested-name-specifier, if there is one.
1652 if (TL.getQualifierLoc() &&
1653 VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
1654 return true;
1655
1656 // Visit the template arguments.
1657 for (unsigned I = 0, N = TL.getNumArgs(); I != N; ++I)
1658 if (VisitTemplateArgumentLoc(TL.getArgLoc(I)))
1659 return true;
1660
1661 return false;
1662}
1663
1664bool CursorVisitor::VisitElaboratedTypeLoc(ElaboratedTypeLoc TL) {
1665 if (VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
1666 return true;
1667
1668 return Visit(TL.getNamedTypeLoc());
1669}
1670
1671bool CursorVisitor::VisitPackExpansionTypeLoc(PackExpansionTypeLoc TL) {
1672 return Visit(TL.getPatternLoc());
1673}
1674
1675bool CursorVisitor::VisitDecltypeTypeLoc(DecltypeTypeLoc TL) {
1676 if (Expr *E = TL.getUnderlyingExpr())
1677 return Visit(MakeCXCursor(E, StmtParent, TU));
1678
1679 return false;
1680}
1681
1682bool CursorVisitor::VisitInjectedClassNameTypeLoc(InjectedClassNameTypeLoc TL) {
1683 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1684}
1685
1686bool CursorVisitor::VisitAtomicTypeLoc(AtomicTypeLoc TL) {
1687 return Visit(TL.getValueLoc());
1688}
1689
Xiuli Pan9c14e282016-01-09 12:53:17 +00001690bool CursorVisitor::VisitPipeTypeLoc(PipeTypeLoc TL) {
1691 return Visit(TL.getValueLoc());
1692}
1693
Guy Benyei11169dd2012-12-18 14:30:41 +00001694#define DEFAULT_TYPELOC_IMPL(CLASS, PARENT) \
1695bool CursorVisitor::Visit##CLASS##TypeLoc(CLASS##TypeLoc TL) { \
1696 return Visit##PARENT##Loc(TL); \
1697}
1698
1699DEFAULT_TYPELOC_IMPL(Complex, Type)
1700DEFAULT_TYPELOC_IMPL(ConstantArray, ArrayType)
1701DEFAULT_TYPELOC_IMPL(IncompleteArray, ArrayType)
1702DEFAULT_TYPELOC_IMPL(VariableArray, ArrayType)
1703DEFAULT_TYPELOC_IMPL(DependentSizedArray, ArrayType)
1704DEFAULT_TYPELOC_IMPL(DependentSizedExtVector, Type)
1705DEFAULT_TYPELOC_IMPL(Vector, Type)
1706DEFAULT_TYPELOC_IMPL(ExtVector, VectorType)
1707DEFAULT_TYPELOC_IMPL(FunctionProto, FunctionType)
1708DEFAULT_TYPELOC_IMPL(FunctionNoProto, FunctionType)
1709DEFAULT_TYPELOC_IMPL(Record, TagType)
1710DEFAULT_TYPELOC_IMPL(Enum, TagType)
1711DEFAULT_TYPELOC_IMPL(SubstTemplateTypeParm, Type)
1712DEFAULT_TYPELOC_IMPL(SubstTemplateTypeParmPack, Type)
1713DEFAULT_TYPELOC_IMPL(Auto, Type)
1714
1715bool CursorVisitor::VisitCXXRecordDecl(CXXRecordDecl *D) {
1716 // Visit the nested-name-specifier, if present.
1717 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1718 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1719 return true;
1720
1721 if (D->isCompleteDefinition()) {
Aaron Ballman574705e2014-03-13 15:41:46 +00001722 for (const auto &I : D->bases()) {
1723 if (Visit(cxcursor::MakeCursorCXXBaseSpecifier(&I, TU)))
Guy Benyei11169dd2012-12-18 14:30:41 +00001724 return true;
1725 }
1726 }
1727
1728 return VisitTagDecl(D);
1729}
1730
1731bool CursorVisitor::VisitAttributes(Decl *D) {
Aaron Ballmanb97112e2014-03-08 22:19:01 +00001732 for (const auto *I : D->attrs())
1733 if (Visit(MakeCXCursor(I, D, TU)))
Guy Benyei11169dd2012-12-18 14:30:41 +00001734 return true;
1735
1736 return false;
1737}
1738
1739//===----------------------------------------------------------------------===//
1740// Data-recursive visitor methods.
1741//===----------------------------------------------------------------------===//
1742
1743namespace {
1744#define DEF_JOB(NAME, DATA, KIND)\
1745class NAME : public VisitorJob {\
1746public:\
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001747 NAME(const DATA *d, CXCursor parent) : \
1748 VisitorJob(parent, VisitorJob::KIND, d) {} \
Guy Benyei11169dd2012-12-18 14:30:41 +00001749 static bool classof(const VisitorJob *VJ) { return VJ->getKind() == KIND; }\
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001750 const DATA *get() const { return static_cast<const DATA*>(data[0]); }\
Guy Benyei11169dd2012-12-18 14:30:41 +00001751};
1752
1753DEF_JOB(StmtVisit, Stmt, StmtVisitKind)
1754DEF_JOB(MemberExprParts, MemberExpr, MemberExprPartsKind)
1755DEF_JOB(DeclRefExprParts, DeclRefExpr, DeclRefExprPartsKind)
1756DEF_JOB(OverloadExprParts, OverloadExpr, OverloadExprPartsKind)
Guy Benyei11169dd2012-12-18 14:30:41 +00001757DEF_JOB(SizeOfPackExprParts, SizeOfPackExpr, SizeOfPackExprPartsKind)
1758DEF_JOB(LambdaExprParts, LambdaExpr, LambdaExprPartsKind)
1759DEF_JOB(PostChildrenVisit, void, PostChildrenVisitKind)
1760#undef DEF_JOB
1761
James Y Knight04ec5bf2015-12-24 02:59:37 +00001762class ExplicitTemplateArgsVisit : public VisitorJob {
1763public:
1764 ExplicitTemplateArgsVisit(const TemplateArgumentLoc *Begin,
1765 const TemplateArgumentLoc *End, CXCursor parent)
1766 : VisitorJob(parent, VisitorJob::ExplicitTemplateArgsVisitKind, Begin,
1767 End) {}
1768 static bool classof(const VisitorJob *VJ) {
1769 return VJ->getKind() == ExplicitTemplateArgsVisitKind;
1770 }
1771 const TemplateArgumentLoc *begin() const {
1772 return static_cast<const TemplateArgumentLoc *>(data[0]);
1773 }
1774 const TemplateArgumentLoc *end() {
1775 return static_cast<const TemplateArgumentLoc *>(data[1]);
1776 }
1777};
Guy Benyei11169dd2012-12-18 14:30:41 +00001778class DeclVisit : public VisitorJob {
1779public:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001780 DeclVisit(const Decl *D, CXCursor parent, bool isFirst) :
Guy Benyei11169dd2012-12-18 14:30:41 +00001781 VisitorJob(parent, VisitorJob::DeclVisitKind,
Craig Topper69186e72014-06-08 08:38:04 +00001782 D, isFirst ? (void*) 1 : (void*) nullptr) {}
Guy Benyei11169dd2012-12-18 14:30:41 +00001783 static bool classof(const VisitorJob *VJ) {
1784 return VJ->getKind() == DeclVisitKind;
1785 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001786 const Decl *get() const { return static_cast<const Decl *>(data[0]); }
Dmitri Gribenkoe5423a72015-03-23 19:23:50 +00001787 bool isFirst() const { return data[1] != nullptr; }
Guy Benyei11169dd2012-12-18 14:30:41 +00001788};
1789class TypeLocVisit : public VisitorJob {
1790public:
1791 TypeLocVisit(TypeLoc tl, CXCursor parent) :
1792 VisitorJob(parent, VisitorJob::TypeLocVisitKind,
1793 tl.getType().getAsOpaquePtr(), tl.getOpaqueData()) {}
1794
1795 static bool classof(const VisitorJob *VJ) {
1796 return VJ->getKind() == TypeLocVisitKind;
1797 }
1798
1799 TypeLoc get() const {
1800 QualType T = QualType::getFromOpaquePtr(data[0]);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001801 return TypeLoc(T, const_cast<void *>(data[1]));
Guy Benyei11169dd2012-12-18 14:30:41 +00001802 }
1803};
1804
1805class LabelRefVisit : public VisitorJob {
1806public:
1807 LabelRefVisit(LabelDecl *LD, SourceLocation labelLoc, CXCursor parent)
1808 : VisitorJob(parent, VisitorJob::LabelRefVisitKind, LD,
1809 labelLoc.getPtrEncoding()) {}
1810
1811 static bool classof(const VisitorJob *VJ) {
1812 return VJ->getKind() == VisitorJob::LabelRefVisitKind;
1813 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001814 const LabelDecl *get() const {
1815 return static_cast<const LabelDecl *>(data[0]);
1816 }
Guy Benyei11169dd2012-12-18 14:30:41 +00001817 SourceLocation getLoc() const {
1818 return SourceLocation::getFromPtrEncoding(data[1]); }
1819};
1820
1821class NestedNameSpecifierLocVisit : public VisitorJob {
1822public:
1823 NestedNameSpecifierLocVisit(NestedNameSpecifierLoc Qualifier, CXCursor parent)
1824 : VisitorJob(parent, VisitorJob::NestedNameSpecifierLocVisitKind,
1825 Qualifier.getNestedNameSpecifier(),
1826 Qualifier.getOpaqueData()) { }
1827
1828 static bool classof(const VisitorJob *VJ) {
1829 return VJ->getKind() == VisitorJob::NestedNameSpecifierLocVisitKind;
1830 }
1831
1832 NestedNameSpecifierLoc get() const {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001833 return NestedNameSpecifierLoc(
1834 const_cast<NestedNameSpecifier *>(
1835 static_cast<const NestedNameSpecifier *>(data[0])),
1836 const_cast<void *>(data[1]));
Guy Benyei11169dd2012-12-18 14:30:41 +00001837 }
1838};
1839
1840class DeclarationNameInfoVisit : public VisitorJob {
1841public:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001842 DeclarationNameInfoVisit(const Stmt *S, CXCursor parent)
Dmitri Gribenkodd7dacf2013-02-03 13:19:54 +00001843 : VisitorJob(parent, VisitorJob::DeclarationNameInfoVisitKind, S) {}
Guy Benyei11169dd2012-12-18 14:30:41 +00001844 static bool classof(const VisitorJob *VJ) {
1845 return VJ->getKind() == VisitorJob::DeclarationNameInfoVisitKind;
1846 }
1847 DeclarationNameInfo get() const {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001848 const Stmt *S = static_cast<const Stmt *>(data[0]);
Guy Benyei11169dd2012-12-18 14:30:41 +00001849 switch (S->getStmtClass()) {
1850 default:
1851 llvm_unreachable("Unhandled Stmt");
1852 case clang::Stmt::MSDependentExistsStmtClass:
1853 return cast<MSDependentExistsStmt>(S)->getNameInfo();
1854 case Stmt::CXXDependentScopeMemberExprClass:
1855 return cast<CXXDependentScopeMemberExpr>(S)->getMemberNameInfo();
1856 case Stmt::DependentScopeDeclRefExprClass:
1857 return cast<DependentScopeDeclRefExpr>(S)->getNameInfo();
Alexander Musmand9ed09f2014-07-21 09:42:05 +00001858 case Stmt::OMPCriticalDirectiveClass:
1859 return cast<OMPCriticalDirective>(S)->getDirectiveName();
Guy Benyei11169dd2012-12-18 14:30:41 +00001860 }
1861 }
1862};
1863class MemberRefVisit : public VisitorJob {
1864public:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001865 MemberRefVisit(const FieldDecl *D, SourceLocation L, CXCursor parent)
Guy Benyei11169dd2012-12-18 14:30:41 +00001866 : VisitorJob(parent, VisitorJob::MemberRefVisitKind, D,
1867 L.getPtrEncoding()) {}
1868 static bool classof(const VisitorJob *VJ) {
1869 return VJ->getKind() == VisitorJob::MemberRefVisitKind;
1870 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001871 const FieldDecl *get() const {
1872 return static_cast<const FieldDecl *>(data[0]);
Guy Benyei11169dd2012-12-18 14:30:41 +00001873 }
1874 SourceLocation getLoc() const {
1875 return SourceLocation::getFromRawEncoding((unsigned)(uintptr_t) data[1]);
1876 }
1877};
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001878class EnqueueVisitor : public ConstStmtVisitor<EnqueueVisitor, void> {
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001879 friend class OMPClauseEnqueue;
Guy Benyei11169dd2012-12-18 14:30:41 +00001880 VisitorWorkList &WL;
1881 CXCursor Parent;
1882public:
1883 EnqueueVisitor(VisitorWorkList &wl, CXCursor parent)
1884 : WL(wl), Parent(parent) {}
1885
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001886 void VisitAddrLabelExpr(const AddrLabelExpr *E);
1887 void VisitBlockExpr(const BlockExpr *B);
1888 void VisitCompoundLiteralExpr(const CompoundLiteralExpr *E);
1889 void VisitCompoundStmt(const CompoundStmt *S);
1890 void VisitCXXDefaultArgExpr(const CXXDefaultArgExpr *E) { /* Do nothing. */ }
1891 void VisitMSDependentExistsStmt(const MSDependentExistsStmt *S);
1892 void VisitCXXDependentScopeMemberExpr(const CXXDependentScopeMemberExpr *E);
1893 void VisitCXXNewExpr(const CXXNewExpr *E);
1894 void VisitCXXScalarValueInitExpr(const CXXScalarValueInitExpr *E);
1895 void VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *E);
1896 void VisitCXXPseudoDestructorExpr(const CXXPseudoDestructorExpr *E);
1897 void VisitCXXTemporaryObjectExpr(const CXXTemporaryObjectExpr *E);
1898 void VisitCXXTypeidExpr(const CXXTypeidExpr *E);
1899 void VisitCXXUnresolvedConstructExpr(const CXXUnresolvedConstructExpr *E);
1900 void VisitCXXUuidofExpr(const CXXUuidofExpr *E);
1901 void VisitCXXCatchStmt(const CXXCatchStmt *S);
Argyrios Kyrtzidis99891242014-11-13 09:03:21 +00001902 void VisitCXXForRangeStmt(const CXXForRangeStmt *S);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001903 void VisitDeclRefExpr(const DeclRefExpr *D);
1904 void VisitDeclStmt(const DeclStmt *S);
1905 void VisitDependentScopeDeclRefExpr(const DependentScopeDeclRefExpr *E);
1906 void VisitDesignatedInitExpr(const DesignatedInitExpr *E);
1907 void VisitExplicitCastExpr(const ExplicitCastExpr *E);
1908 void VisitForStmt(const ForStmt *FS);
1909 void VisitGotoStmt(const GotoStmt *GS);
1910 void VisitIfStmt(const IfStmt *If);
1911 void VisitInitListExpr(const InitListExpr *IE);
1912 void VisitMemberExpr(const MemberExpr *M);
1913 void VisitOffsetOfExpr(const OffsetOfExpr *E);
1914 void VisitObjCEncodeExpr(const ObjCEncodeExpr *E);
1915 void VisitObjCMessageExpr(const ObjCMessageExpr *M);
1916 void VisitOverloadExpr(const OverloadExpr *E);
1917 void VisitUnaryExprOrTypeTraitExpr(const UnaryExprOrTypeTraitExpr *E);
1918 void VisitStmt(const Stmt *S);
1919 void VisitSwitchStmt(const SwitchStmt *S);
1920 void VisitWhileStmt(const WhileStmt *W);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001921 void VisitTypeTraitExpr(const TypeTraitExpr *E);
1922 void VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *E);
1923 void VisitExpressionTraitExpr(const ExpressionTraitExpr *E);
1924 void VisitUnresolvedMemberExpr(const UnresolvedMemberExpr *U);
1925 void VisitVAArgExpr(const VAArgExpr *E);
1926 void VisitSizeOfPackExpr(const SizeOfPackExpr *E);
1927 void VisitPseudoObjectExpr(const PseudoObjectExpr *E);
1928 void VisitOpaqueValueExpr(const OpaqueValueExpr *E);
1929 void VisitLambdaExpr(const LambdaExpr *E);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001930 void VisitOMPExecutableDirective(const OMPExecutableDirective *D);
Alexander Musman3aaab662014-08-19 11:27:13 +00001931 void VisitOMPLoopDirective(const OMPLoopDirective *D);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001932 void VisitOMPParallelDirective(const OMPParallelDirective *D);
Alexey Bataev1b59ab52014-02-27 08:29:12 +00001933 void VisitOMPSimdDirective(const OMPSimdDirective *D);
Alexey Bataevf29276e2014-06-18 04:14:57 +00001934 void VisitOMPForDirective(const OMPForDirective *D);
Alexander Musmanf82886e2014-09-18 05:12:34 +00001935 void VisitOMPForSimdDirective(const OMPForSimdDirective *D);
Alexey Bataevd3f8dd22014-06-25 11:44:49 +00001936 void VisitOMPSectionsDirective(const OMPSectionsDirective *D);
Alexey Bataev1e0498a2014-06-26 08:21:58 +00001937 void VisitOMPSectionDirective(const OMPSectionDirective *D);
Alexey Bataevd1e40fb2014-06-26 12:05:45 +00001938 void VisitOMPSingleDirective(const OMPSingleDirective *D);
Alexander Musman80c22892014-07-17 08:54:58 +00001939 void VisitOMPMasterDirective(const OMPMasterDirective *D);
Alexander Musmand9ed09f2014-07-21 09:42:05 +00001940 void VisitOMPCriticalDirective(const OMPCriticalDirective *D);
Alexey Bataev4acb8592014-07-07 13:01:15 +00001941 void VisitOMPParallelForDirective(const OMPParallelForDirective *D);
Alexander Musmane4e893b2014-09-23 09:33:00 +00001942 void VisitOMPParallelForSimdDirective(const OMPParallelForSimdDirective *D);
Alexey Bataev84d0b3e2014-07-08 08:12:03 +00001943 void VisitOMPParallelSectionsDirective(const OMPParallelSectionsDirective *D);
Alexey Bataev9c2e8ee2014-07-11 11:25:16 +00001944 void VisitOMPTaskDirective(const OMPTaskDirective *D);
Alexey Bataev68446b72014-07-18 07:47:19 +00001945 void VisitOMPTaskyieldDirective(const OMPTaskyieldDirective *D);
Alexey Bataev4d1dfea2014-07-18 09:11:51 +00001946 void VisitOMPBarrierDirective(const OMPBarrierDirective *D);
Alexey Bataev2df347a2014-07-18 10:17:07 +00001947 void VisitOMPTaskwaitDirective(const OMPTaskwaitDirective *D);
Alexey Bataevc30dd2d2015-06-18 12:14:09 +00001948 void VisitOMPTaskgroupDirective(const OMPTaskgroupDirective *D);
Alexey Bataev6d4ed052015-07-01 06:57:41 +00001949 void
1950 VisitOMPCancellationPointDirective(const OMPCancellationPointDirective *D);
Alexey Bataev80909872015-07-02 11:25:17 +00001951 void VisitOMPCancelDirective(const OMPCancelDirective *D);
Alexey Bataev6125da92014-07-21 11:26:11 +00001952 void VisitOMPFlushDirective(const OMPFlushDirective *D);
Alexey Bataev9fb6e642014-07-22 06:45:04 +00001953 void VisitOMPOrderedDirective(const OMPOrderedDirective *D);
Alexey Bataev0162e452014-07-22 10:10:35 +00001954 void VisitOMPAtomicDirective(const OMPAtomicDirective *D);
Alexey Bataev0bd520b2014-09-19 08:19:49 +00001955 void VisitOMPTargetDirective(const OMPTargetDirective *D);
Michael Wong65f367f2015-07-21 13:44:28 +00001956 void VisitOMPTargetDataDirective(const OMPTargetDataDirective *D);
Samuel Antaodf67fc42016-01-19 19:15:56 +00001957 void VisitOMPTargetEnterDataDirective(const OMPTargetEnterDataDirective *D);
Samuel Antao72590762016-01-19 20:04:50 +00001958 void VisitOMPTargetExitDataDirective(const OMPTargetExitDataDirective *D);
Arpith Chacko Jacobe955b3d2016-01-26 18:48:41 +00001959 void VisitOMPTargetParallelDirective(const OMPTargetParallelDirective *D);
Arpith Chacko Jacob05bebb52016-02-03 15:46:42 +00001960 void
1961 VisitOMPTargetParallelForDirective(const OMPTargetParallelForDirective *D);
Alexey Bataev13314bf2014-10-09 04:18:56 +00001962 void VisitOMPTeamsDirective(const OMPTeamsDirective *D);
Alexey Bataev49f6e782015-12-01 04:18:41 +00001963 void VisitOMPTaskLoopDirective(const OMPTaskLoopDirective *D);
Alexey Bataev0a6ed842015-12-03 09:40:15 +00001964 void VisitOMPTaskLoopSimdDirective(const OMPTaskLoopSimdDirective *D);
Carlo Bertolli6200a3d2015-12-14 14:51:25 +00001965 void VisitOMPDistributeDirective(const OMPDistributeDirective *D);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001966
Guy Benyei11169dd2012-12-18 14:30:41 +00001967private:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001968 void AddDeclarationNameInfo(const Stmt *S);
Guy Benyei11169dd2012-12-18 14:30:41 +00001969 void AddNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier);
James Y Knight04ec5bf2015-12-24 02:59:37 +00001970 void AddExplicitTemplateArgs(const TemplateArgumentLoc *A,
1971 unsigned NumTemplateArgs);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001972 void AddMemberRef(const FieldDecl *D, SourceLocation L);
1973 void AddStmt(const Stmt *S);
1974 void AddDecl(const Decl *D, bool isFirst = true);
Guy Benyei11169dd2012-12-18 14:30:41 +00001975 void AddTypeLoc(TypeSourceInfo *TI);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001976 void EnqueueChildren(const Stmt *S);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001977 void EnqueueChildren(const OMPClause *S);
Guy Benyei11169dd2012-12-18 14:30:41 +00001978};
Alexander Kornienkoab9db512015-06-22 23:07:51 +00001979} // end anonyous namespace
Guy Benyei11169dd2012-12-18 14:30:41 +00001980
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001981void EnqueueVisitor::AddDeclarationNameInfo(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001982 // 'S' should always be non-null, since it comes from the
1983 // statement we are visiting.
1984 WL.push_back(DeclarationNameInfoVisit(S, Parent));
1985}
1986
1987void
1988EnqueueVisitor::AddNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier) {
1989 if (Qualifier)
1990 WL.push_back(NestedNameSpecifierLocVisit(Qualifier, Parent));
1991}
1992
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001993void EnqueueVisitor::AddStmt(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001994 if (S)
1995 WL.push_back(StmtVisit(S, Parent));
1996}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001997void EnqueueVisitor::AddDecl(const Decl *D, bool isFirst) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001998 if (D)
1999 WL.push_back(DeclVisit(D, Parent, isFirst));
2000}
James Y Knight04ec5bf2015-12-24 02:59:37 +00002001void EnqueueVisitor::AddExplicitTemplateArgs(const TemplateArgumentLoc *A,
2002 unsigned NumTemplateArgs) {
2003 WL.push_back(ExplicitTemplateArgsVisit(A, A + NumTemplateArgs, Parent));
Guy Benyei11169dd2012-12-18 14:30:41 +00002004}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002005void EnqueueVisitor::AddMemberRef(const FieldDecl *D, SourceLocation L) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002006 if (D)
2007 WL.push_back(MemberRefVisit(D, L, Parent));
2008}
2009void EnqueueVisitor::AddTypeLoc(TypeSourceInfo *TI) {
2010 if (TI)
2011 WL.push_back(TypeLocVisit(TI->getTypeLoc(), Parent));
2012 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002013void EnqueueVisitor::EnqueueChildren(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002014 unsigned size = WL.size();
Benjamin Kramer642f1732015-07-02 21:03:14 +00002015 for (const Stmt *SubStmt : S->children()) {
2016 AddStmt(SubStmt);
Guy Benyei11169dd2012-12-18 14:30:41 +00002017 }
2018 if (size == WL.size())
2019 return;
2020 // Now reverse the entries we just added. This will match the DFS
2021 // ordering performed by the worklist.
2022 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
2023 std::reverse(I, E);
2024}
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002025namespace {
2026class OMPClauseEnqueue : public ConstOMPClauseVisitor<OMPClauseEnqueue> {
2027 EnqueueVisitor *Visitor;
Alexey Bataev756c1962013-09-24 03:17:45 +00002028 /// \brief Process clauses with list of variables.
2029 template <typename T>
2030 void VisitOMPClauseList(T *Node);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002031public:
2032 OMPClauseEnqueue(EnqueueVisitor *Visitor) : Visitor(Visitor) { }
2033#define OPENMP_CLAUSE(Name, Class) \
2034 void Visit##Class(const Class *C);
2035#include "clang/Basic/OpenMPKinds.def"
2036};
2037
Alexey Bataevaadd52e2014-02-13 05:29:23 +00002038void OMPClauseEnqueue::VisitOMPIfClause(const OMPIfClause *C) {
2039 Visitor->AddStmt(C->getCondition());
2040}
2041
Alexey Bataev3778b602014-07-17 07:32:53 +00002042void OMPClauseEnqueue::VisitOMPFinalClause(const OMPFinalClause *C) {
2043 Visitor->AddStmt(C->getCondition());
2044}
2045
Alexey Bataev568a8332014-03-06 06:15:19 +00002046void OMPClauseEnqueue::VisitOMPNumThreadsClause(const OMPNumThreadsClause *C) {
2047 Visitor->AddStmt(C->getNumThreads());
2048}
2049
Alexey Bataev62c87d22014-03-21 04:51:18 +00002050void OMPClauseEnqueue::VisitOMPSafelenClause(const OMPSafelenClause *C) {
2051 Visitor->AddStmt(C->getSafelen());
2052}
2053
Alexey Bataev66b15b52015-08-21 11:14:16 +00002054void OMPClauseEnqueue::VisitOMPSimdlenClause(const OMPSimdlenClause *C) {
2055 Visitor->AddStmt(C->getSimdlen());
2056}
2057
Alexander Musman8bd31e62014-05-27 15:12:19 +00002058void OMPClauseEnqueue::VisitOMPCollapseClause(const OMPCollapseClause *C) {
2059 Visitor->AddStmt(C->getNumForLoops());
2060}
2061
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002062void OMPClauseEnqueue::VisitOMPDefaultClause(const OMPDefaultClause *C) { }
Alexey Bataev756c1962013-09-24 03:17:45 +00002063
Alexey Bataevbcbadb62014-05-06 06:04:14 +00002064void OMPClauseEnqueue::VisitOMPProcBindClause(const OMPProcBindClause *C) { }
2065
Alexey Bataev56dafe82014-06-20 07:16:17 +00002066void OMPClauseEnqueue::VisitOMPScheduleClause(const OMPScheduleClause *C) {
2067 Visitor->AddStmt(C->getChunkSize());
Alexey Bataev040d5402015-05-12 08:35:28 +00002068 Visitor->AddStmt(C->getHelperChunkSize());
Alexey Bataev56dafe82014-06-20 07:16:17 +00002069}
2070
Alexey Bataev10e775f2015-07-30 11:36:16 +00002071void OMPClauseEnqueue::VisitOMPOrderedClause(const OMPOrderedClause *C) {
2072 Visitor->AddStmt(C->getNumForLoops());
2073}
Alexey Bataev142e1fc2014-06-20 09:44:06 +00002074
Alexey Bataev236070f2014-06-20 11:19:47 +00002075void OMPClauseEnqueue::VisitOMPNowaitClause(const OMPNowaitClause *) {}
2076
Alexey Bataev7aea99a2014-07-17 12:19:31 +00002077void OMPClauseEnqueue::VisitOMPUntiedClause(const OMPUntiedClause *) {}
2078
Alexey Bataev74ba3a52014-07-17 12:47:03 +00002079void OMPClauseEnqueue::VisitOMPMergeableClause(const OMPMergeableClause *) {}
2080
Alexey Bataevf98b00c2014-07-23 02:27:21 +00002081void OMPClauseEnqueue::VisitOMPReadClause(const OMPReadClause *) {}
2082
Alexey Bataevdea47612014-07-23 07:46:59 +00002083void OMPClauseEnqueue::VisitOMPWriteClause(const OMPWriteClause *) {}
2084
Alexey Bataev67a4f222014-07-23 10:25:33 +00002085void OMPClauseEnqueue::VisitOMPUpdateClause(const OMPUpdateClause *) {}
2086
Alexey Bataev459dec02014-07-24 06:46:57 +00002087void OMPClauseEnqueue::VisitOMPCaptureClause(const OMPCaptureClause *) {}
2088
Alexey Bataev82bad8b2014-07-24 08:55:34 +00002089void OMPClauseEnqueue::VisitOMPSeqCstClause(const OMPSeqCstClause *) {}
2090
Alexey Bataev346265e2015-09-25 10:37:12 +00002091void OMPClauseEnqueue::VisitOMPThreadsClause(const OMPThreadsClause *) {}
2092
Alexey Bataevd14d1e62015-09-28 06:39:35 +00002093void OMPClauseEnqueue::VisitOMPSIMDClause(const OMPSIMDClause *) {}
2094
Alexey Bataevb825de12015-12-07 10:51:44 +00002095void OMPClauseEnqueue::VisitOMPNogroupClause(const OMPNogroupClause *) {}
2096
Michael Wonge710d542015-08-07 16:16:36 +00002097void OMPClauseEnqueue::VisitOMPDeviceClause(const OMPDeviceClause *C) {
2098 Visitor->AddStmt(C->getDevice());
2099}
2100
Kelvin Li099bb8c2015-11-24 20:50:12 +00002101void OMPClauseEnqueue::VisitOMPNumTeamsClause(const OMPNumTeamsClause *C) {
2102 Visitor->AddStmt(C->getNumTeams());
2103}
2104
Kelvin Lia15fb1a2015-11-27 18:47:36 +00002105void OMPClauseEnqueue::VisitOMPThreadLimitClause(const OMPThreadLimitClause *C) {
2106 Visitor->AddStmt(C->getThreadLimit());
2107}
2108
Alexey Bataeva0569352015-12-01 10:17:31 +00002109void OMPClauseEnqueue::VisitOMPPriorityClause(const OMPPriorityClause *C) {
2110 Visitor->AddStmt(C->getPriority());
2111}
2112
Alexey Bataev1fd4aed2015-12-07 12:52:51 +00002113void OMPClauseEnqueue::VisitOMPGrainsizeClause(const OMPGrainsizeClause *C) {
2114 Visitor->AddStmt(C->getGrainsize());
2115}
2116
Alexey Bataev382967a2015-12-08 12:06:20 +00002117void OMPClauseEnqueue::VisitOMPNumTasksClause(const OMPNumTasksClause *C) {
2118 Visitor->AddStmt(C->getNumTasks());
2119}
2120
Alexey Bataev28c75412015-12-15 08:19:24 +00002121void OMPClauseEnqueue::VisitOMPHintClause(const OMPHintClause *C) {
2122 Visitor->AddStmt(C->getHint());
2123}
2124
Alexey Bataev756c1962013-09-24 03:17:45 +00002125template<typename T>
2126void OMPClauseEnqueue::VisitOMPClauseList(T *Node) {
Alexey Bataev03b340a2014-10-21 03:16:40 +00002127 for (const auto *I : Node->varlists()) {
Aaron Ballman2205d2a2014-03-14 15:55:35 +00002128 Visitor->AddStmt(I);
Alexey Bataev03b340a2014-10-21 03:16:40 +00002129 }
Alexey Bataev756c1962013-09-24 03:17:45 +00002130}
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002131
2132void OMPClauseEnqueue::VisitOMPPrivateClause(const OMPPrivateClause *C) {
Alexey Bataev756c1962013-09-24 03:17:45 +00002133 VisitOMPClauseList(C);
Alexey Bataev03b340a2014-10-21 03:16:40 +00002134 for (const auto *E : C->private_copies()) {
2135 Visitor->AddStmt(E);
2136 }
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002137}
Alexey Bataevd5af8e42013-10-01 05:32:34 +00002138void OMPClauseEnqueue::VisitOMPFirstprivateClause(
2139 const OMPFirstprivateClause *C) {
2140 VisitOMPClauseList(C);
2141}
Alexander Musman1bb328c2014-06-04 13:06:39 +00002142void OMPClauseEnqueue::VisitOMPLastprivateClause(
2143 const OMPLastprivateClause *C) {
2144 VisitOMPClauseList(C);
Alexey Bataev38e89532015-04-16 04:54:05 +00002145 for (auto *E : C->private_copies()) {
2146 Visitor->AddStmt(E);
2147 }
2148 for (auto *E : C->source_exprs()) {
2149 Visitor->AddStmt(E);
2150 }
2151 for (auto *E : C->destination_exprs()) {
2152 Visitor->AddStmt(E);
2153 }
2154 for (auto *E : C->assignment_ops()) {
2155 Visitor->AddStmt(E);
2156 }
Alexander Musman1bb328c2014-06-04 13:06:39 +00002157}
Alexey Bataev758e55e2013-09-06 18:03:48 +00002158void OMPClauseEnqueue::VisitOMPSharedClause(const OMPSharedClause *C) {
Alexey Bataev756c1962013-09-24 03:17:45 +00002159 VisitOMPClauseList(C);
Alexey Bataev758e55e2013-09-06 18:03:48 +00002160}
Alexey Bataevc5e02582014-06-16 07:08:35 +00002161void OMPClauseEnqueue::VisitOMPReductionClause(const OMPReductionClause *C) {
2162 VisitOMPClauseList(C);
Alexey Bataevf24e7b12015-10-08 09:10:53 +00002163 for (auto *E : C->privates()) {
2164 Visitor->AddStmt(E);
2165 }
Alexey Bataev794ba0d2015-04-10 10:43:45 +00002166 for (auto *E : C->lhs_exprs()) {
2167 Visitor->AddStmt(E);
2168 }
2169 for (auto *E : C->rhs_exprs()) {
2170 Visitor->AddStmt(E);
2171 }
2172 for (auto *E : C->reduction_ops()) {
2173 Visitor->AddStmt(E);
2174 }
Alexey Bataevc5e02582014-06-16 07:08:35 +00002175}
Alexander Musman8dba6642014-04-22 13:09:42 +00002176void OMPClauseEnqueue::VisitOMPLinearClause(const OMPLinearClause *C) {
2177 VisitOMPClauseList(C);
Alexey Bataevbd9fec12015-08-18 06:47:21 +00002178 for (const auto *E : C->privates()) {
2179 Visitor->AddStmt(E);
2180 }
Alexander Musman3276a272015-03-21 10:12:56 +00002181 for (const auto *E : C->inits()) {
2182 Visitor->AddStmt(E);
2183 }
2184 for (const auto *E : C->updates()) {
2185 Visitor->AddStmt(E);
2186 }
2187 for (const auto *E : C->finals()) {
2188 Visitor->AddStmt(E);
2189 }
Alexander Musman8dba6642014-04-22 13:09:42 +00002190 Visitor->AddStmt(C->getStep());
Alexander Musman3276a272015-03-21 10:12:56 +00002191 Visitor->AddStmt(C->getCalcStep());
Alexander Musman8dba6642014-04-22 13:09:42 +00002192}
Alexander Musmanf0d76e72014-05-29 14:36:25 +00002193void OMPClauseEnqueue::VisitOMPAlignedClause(const OMPAlignedClause *C) {
2194 VisitOMPClauseList(C);
2195 Visitor->AddStmt(C->getAlignment());
2196}
Alexey Bataevd48bcd82014-03-31 03:36:38 +00002197void OMPClauseEnqueue::VisitOMPCopyinClause(const OMPCopyinClause *C) {
2198 VisitOMPClauseList(C);
Alexey Bataevf56f98c2015-04-16 05:39:01 +00002199 for (auto *E : C->source_exprs()) {
2200 Visitor->AddStmt(E);
2201 }
2202 for (auto *E : C->destination_exprs()) {
2203 Visitor->AddStmt(E);
2204 }
2205 for (auto *E : C->assignment_ops()) {
2206 Visitor->AddStmt(E);
2207 }
Alexey Bataevd48bcd82014-03-31 03:36:38 +00002208}
Alexey Bataevbae9a792014-06-27 10:37:06 +00002209void
2210OMPClauseEnqueue::VisitOMPCopyprivateClause(const OMPCopyprivateClause *C) {
2211 VisitOMPClauseList(C);
Alexey Bataeva63048e2015-03-23 06:18:07 +00002212 for (auto *E : C->source_exprs()) {
2213 Visitor->AddStmt(E);
2214 }
2215 for (auto *E : C->destination_exprs()) {
2216 Visitor->AddStmt(E);
2217 }
2218 for (auto *E : C->assignment_ops()) {
2219 Visitor->AddStmt(E);
2220 }
Alexey Bataevbae9a792014-06-27 10:37:06 +00002221}
Alexey Bataev6125da92014-07-21 11:26:11 +00002222void OMPClauseEnqueue::VisitOMPFlushClause(const OMPFlushClause *C) {
2223 VisitOMPClauseList(C);
2224}
Alexey Bataev1c2cfbc2015-06-23 14:25:19 +00002225void OMPClauseEnqueue::VisitOMPDependClause(const OMPDependClause *C) {
2226 VisitOMPClauseList(C);
2227}
Kelvin Li0bff7af2015-11-23 05:32:03 +00002228void OMPClauseEnqueue::VisitOMPMapClause(const OMPMapClause *C) {
2229 VisitOMPClauseList(C);
2230}
Carlo Bertollib4adf552016-01-15 18:50:31 +00002231void OMPClauseEnqueue::VisitOMPDistScheduleClause(
2232 const OMPDistScheduleClause *C) {
2233 Visitor->AddStmt(C->getChunkSize());
2234 Visitor->AddStmt(C->getHelperChunkSize());
2235}
Arpith Chacko Jacob3cf89042016-01-26 16:37:23 +00002236void OMPClauseEnqueue::VisitOMPDefaultmapClause(const OMPDefaultmapClause *C) {
2237}
Alexander Kornienkoab9db512015-06-22 23:07:51 +00002238}
Alexey Bataev756c1962013-09-24 03:17:45 +00002239
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002240void EnqueueVisitor::EnqueueChildren(const OMPClause *S) {
2241 unsigned size = WL.size();
2242 OMPClauseEnqueue Visitor(this);
2243 Visitor.Visit(S);
2244 if (size == WL.size())
2245 return;
2246 // Now reverse the entries we just added. This will match the DFS
2247 // ordering performed by the worklist.
2248 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
2249 std::reverse(I, E);
2250}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002251void EnqueueVisitor::VisitAddrLabelExpr(const AddrLabelExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002252 WL.push_back(LabelRefVisit(E->getLabel(), E->getLabelLoc(), Parent));
2253}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002254void EnqueueVisitor::VisitBlockExpr(const BlockExpr *B) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002255 AddDecl(B->getBlockDecl());
2256}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002257void EnqueueVisitor::VisitCompoundLiteralExpr(const CompoundLiteralExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002258 EnqueueChildren(E);
2259 AddTypeLoc(E->getTypeSourceInfo());
2260}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002261void EnqueueVisitor::VisitCompoundStmt(const CompoundStmt *S) {
Pete Cooper57d3f142015-07-30 17:22:52 +00002262 for (auto &I : llvm::reverse(S->body()))
2263 AddStmt(I);
Guy Benyei11169dd2012-12-18 14:30:41 +00002264}
2265void EnqueueVisitor::
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002266VisitMSDependentExistsStmt(const MSDependentExistsStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002267 AddStmt(S->getSubStmt());
2268 AddDeclarationNameInfo(S);
2269 if (NestedNameSpecifierLoc QualifierLoc = S->getQualifierLoc())
2270 AddNestedNameSpecifierLoc(QualifierLoc);
2271}
2272
2273void EnqueueVisitor::
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002274VisitCXXDependentScopeMemberExpr(const CXXDependentScopeMemberExpr *E) {
James Y Knight04ec5bf2015-12-24 02:59:37 +00002275 if (E->hasExplicitTemplateArgs())
2276 AddExplicitTemplateArgs(E->getTemplateArgs(), E->getNumTemplateArgs());
Guy Benyei11169dd2012-12-18 14:30:41 +00002277 AddDeclarationNameInfo(E);
2278 if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
2279 AddNestedNameSpecifierLoc(QualifierLoc);
2280 if (!E->isImplicitAccess())
2281 AddStmt(E->getBase());
2282}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002283void EnqueueVisitor::VisitCXXNewExpr(const CXXNewExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002284 // Enqueue the initializer , if any.
2285 AddStmt(E->getInitializer());
2286 // Enqueue the array size, if any.
2287 AddStmt(E->getArraySize());
2288 // Enqueue the allocated type.
2289 AddTypeLoc(E->getAllocatedTypeSourceInfo());
2290 // Enqueue the placement arguments.
2291 for (unsigned I = E->getNumPlacementArgs(); I > 0; --I)
2292 AddStmt(E->getPlacementArg(I-1));
2293}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002294void EnqueueVisitor::VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *CE) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002295 for (unsigned I = CE->getNumArgs(); I > 1 /* Yes, this is 1 */; --I)
2296 AddStmt(CE->getArg(I-1));
2297 AddStmt(CE->getCallee());
2298 AddStmt(CE->getArg(0));
2299}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002300void EnqueueVisitor::VisitCXXPseudoDestructorExpr(
2301 const CXXPseudoDestructorExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002302 // Visit the name of the type being destroyed.
2303 AddTypeLoc(E->getDestroyedTypeInfo());
2304 // Visit the scope type that looks disturbingly like the nested-name-specifier
2305 // but isn't.
2306 AddTypeLoc(E->getScopeTypeInfo());
2307 // Visit the nested-name-specifier.
2308 if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
2309 AddNestedNameSpecifierLoc(QualifierLoc);
2310 // Visit base expression.
2311 AddStmt(E->getBase());
2312}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002313void EnqueueVisitor::VisitCXXScalarValueInitExpr(
2314 const CXXScalarValueInitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002315 AddTypeLoc(E->getTypeSourceInfo());
2316}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002317void EnqueueVisitor::VisitCXXTemporaryObjectExpr(
2318 const CXXTemporaryObjectExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002319 EnqueueChildren(E);
2320 AddTypeLoc(E->getTypeSourceInfo());
2321}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002322void EnqueueVisitor::VisitCXXTypeidExpr(const CXXTypeidExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002323 EnqueueChildren(E);
2324 if (E->isTypeOperand())
2325 AddTypeLoc(E->getTypeOperandSourceInfo());
2326}
2327
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002328void EnqueueVisitor::VisitCXXUnresolvedConstructExpr(
2329 const CXXUnresolvedConstructExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002330 EnqueueChildren(E);
2331 AddTypeLoc(E->getTypeSourceInfo());
2332}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002333void EnqueueVisitor::VisitCXXUuidofExpr(const CXXUuidofExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002334 EnqueueChildren(E);
2335 if (E->isTypeOperand())
2336 AddTypeLoc(E->getTypeOperandSourceInfo());
2337}
2338
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002339void EnqueueVisitor::VisitCXXCatchStmt(const CXXCatchStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002340 EnqueueChildren(S);
2341 AddDecl(S->getExceptionDecl());
2342}
2343
Argyrios Kyrtzidis99891242014-11-13 09:03:21 +00002344void EnqueueVisitor::VisitCXXForRangeStmt(const CXXForRangeStmt *S) {
Argyrios Kyrtzidiscde70692014-11-13 09:50:19 +00002345 AddStmt(S->getBody());
Argyrios Kyrtzidis99891242014-11-13 09:03:21 +00002346 AddStmt(S->getRangeInit());
Argyrios Kyrtzidiscde70692014-11-13 09:50:19 +00002347 AddDecl(S->getLoopVariable());
Argyrios Kyrtzidis99891242014-11-13 09:03:21 +00002348}
2349
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002350void EnqueueVisitor::VisitDeclRefExpr(const DeclRefExpr *DR) {
James Y Knight04ec5bf2015-12-24 02:59:37 +00002351 if (DR->hasExplicitTemplateArgs())
2352 AddExplicitTemplateArgs(DR->getTemplateArgs(), DR->getNumTemplateArgs());
Guy Benyei11169dd2012-12-18 14:30:41 +00002353 WL.push_back(DeclRefExprParts(DR, Parent));
2354}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002355void EnqueueVisitor::VisitDependentScopeDeclRefExpr(
2356 const DependentScopeDeclRefExpr *E) {
James Y Knight04ec5bf2015-12-24 02:59:37 +00002357 if (E->hasExplicitTemplateArgs())
2358 AddExplicitTemplateArgs(E->getTemplateArgs(), E->getNumTemplateArgs());
Guy Benyei11169dd2012-12-18 14:30:41 +00002359 AddDeclarationNameInfo(E);
2360 AddNestedNameSpecifierLoc(E->getQualifierLoc());
2361}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002362void EnqueueVisitor::VisitDeclStmt(const DeclStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002363 unsigned size = WL.size();
2364 bool isFirst = true;
Aaron Ballman535bbcc2014-03-14 17:01:24 +00002365 for (const auto *D : S->decls()) {
2366 AddDecl(D, isFirst);
Guy Benyei11169dd2012-12-18 14:30:41 +00002367 isFirst = false;
2368 }
2369 if (size == WL.size())
2370 return;
2371 // Now reverse the entries we just added. This will match the DFS
2372 // ordering performed by the worklist.
2373 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
2374 std::reverse(I, E);
2375}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002376void EnqueueVisitor::VisitDesignatedInitExpr(const DesignatedInitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002377 AddStmt(E->getInit());
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002378 for (DesignatedInitExpr::const_reverse_designators_iterator
Guy Benyei11169dd2012-12-18 14:30:41 +00002379 D = E->designators_rbegin(), DEnd = E->designators_rend();
2380 D != DEnd; ++D) {
2381 if (D->isFieldDesignator()) {
2382 if (FieldDecl *Field = D->getField())
2383 AddMemberRef(Field, D->getFieldLoc());
2384 continue;
2385 }
2386 if (D->isArrayDesignator()) {
2387 AddStmt(E->getArrayIndex(*D));
2388 continue;
2389 }
2390 assert(D->isArrayRangeDesignator() && "Unknown designator kind");
2391 AddStmt(E->getArrayRangeEnd(*D));
2392 AddStmt(E->getArrayRangeStart(*D));
2393 }
2394}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002395void EnqueueVisitor::VisitExplicitCastExpr(const ExplicitCastExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002396 EnqueueChildren(E);
2397 AddTypeLoc(E->getTypeInfoAsWritten());
2398}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002399void EnqueueVisitor::VisitForStmt(const ForStmt *FS) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002400 AddStmt(FS->getBody());
2401 AddStmt(FS->getInc());
2402 AddStmt(FS->getCond());
2403 AddDecl(FS->getConditionVariable());
2404 AddStmt(FS->getInit());
2405}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002406void EnqueueVisitor::VisitGotoStmt(const GotoStmt *GS) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002407 WL.push_back(LabelRefVisit(GS->getLabel(), GS->getLabelLoc(), Parent));
2408}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002409void EnqueueVisitor::VisitIfStmt(const IfStmt *If) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002410 AddStmt(If->getElse());
2411 AddStmt(If->getThen());
2412 AddStmt(If->getCond());
2413 AddDecl(If->getConditionVariable());
2414}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002415void EnqueueVisitor::VisitInitListExpr(const InitListExpr *IE) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002416 // We care about the syntactic form of the initializer list, only.
2417 if (InitListExpr *Syntactic = IE->getSyntacticForm())
2418 IE = Syntactic;
2419 EnqueueChildren(IE);
2420}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002421void EnqueueVisitor::VisitMemberExpr(const MemberExpr *M) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002422 WL.push_back(MemberExprParts(M, Parent));
2423
2424 // If the base of the member access expression is an implicit 'this', don't
2425 // visit it.
2426 // FIXME: If we ever want to show these implicit accesses, this will be
2427 // unfortunate. However, clang_getCursor() relies on this behavior.
Argyrios Kyrtzidis58d0e7a2015-03-13 04:40:07 +00002428 if (M->isImplicitAccess())
2429 return;
2430
2431 // Ignore base anonymous struct/union fields, otherwise they will shadow the
2432 // real field that that we are interested in.
2433 if (auto *SubME = dyn_cast<MemberExpr>(M->getBase())) {
2434 if (auto *FD = dyn_cast_or_null<FieldDecl>(SubME->getMemberDecl())) {
2435 if (FD->isAnonymousStructOrUnion()) {
2436 AddStmt(SubME->getBase());
2437 return;
2438 }
2439 }
2440 }
2441
2442 AddStmt(M->getBase());
Guy Benyei11169dd2012-12-18 14:30:41 +00002443}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002444void EnqueueVisitor::VisitObjCEncodeExpr(const ObjCEncodeExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002445 AddTypeLoc(E->getEncodedTypeSourceInfo());
2446}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002447void EnqueueVisitor::VisitObjCMessageExpr(const ObjCMessageExpr *M) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002448 EnqueueChildren(M);
2449 AddTypeLoc(M->getClassReceiverTypeInfo());
2450}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002451void EnqueueVisitor::VisitOffsetOfExpr(const OffsetOfExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002452 // Visit the components of the offsetof expression.
2453 for (unsigned N = E->getNumComponents(), I = N; I > 0; --I) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002454 const OffsetOfNode &Node = E->getComponent(I-1);
2455 switch (Node.getKind()) {
2456 case OffsetOfNode::Array:
2457 AddStmt(E->getIndexExpr(Node.getArrayExprIndex()));
2458 break;
2459 case OffsetOfNode::Field:
2460 AddMemberRef(Node.getField(), Node.getSourceRange().getEnd());
2461 break;
2462 case OffsetOfNode::Identifier:
2463 case OffsetOfNode::Base:
2464 continue;
2465 }
2466 }
2467 // Visit the type into which we're computing the offset.
2468 AddTypeLoc(E->getTypeSourceInfo());
2469}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002470void EnqueueVisitor::VisitOverloadExpr(const OverloadExpr *E) {
James Y Knight04ec5bf2015-12-24 02:59:37 +00002471 if (E->hasExplicitTemplateArgs())
2472 AddExplicitTemplateArgs(E->getTemplateArgs(), E->getNumTemplateArgs());
Guy Benyei11169dd2012-12-18 14:30:41 +00002473 WL.push_back(OverloadExprParts(E, Parent));
2474}
2475void EnqueueVisitor::VisitUnaryExprOrTypeTraitExpr(
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002476 const UnaryExprOrTypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002477 EnqueueChildren(E);
2478 if (E->isArgumentType())
2479 AddTypeLoc(E->getArgumentTypeInfo());
2480}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002481void EnqueueVisitor::VisitStmt(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002482 EnqueueChildren(S);
2483}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002484void EnqueueVisitor::VisitSwitchStmt(const SwitchStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002485 AddStmt(S->getBody());
2486 AddStmt(S->getCond());
2487 AddDecl(S->getConditionVariable());
2488}
2489
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002490void EnqueueVisitor::VisitWhileStmt(const WhileStmt *W) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002491 AddStmt(W->getBody());
2492 AddStmt(W->getCond());
2493 AddDecl(W->getConditionVariable());
2494}
2495
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002496void EnqueueVisitor::VisitTypeTraitExpr(const TypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002497 for (unsigned I = E->getNumArgs(); I > 0; --I)
2498 AddTypeLoc(E->getArg(I-1));
2499}
2500
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002501void EnqueueVisitor::VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002502 AddTypeLoc(E->getQueriedTypeSourceInfo());
2503}
2504
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002505void EnqueueVisitor::VisitExpressionTraitExpr(const ExpressionTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002506 EnqueueChildren(E);
2507}
2508
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002509void EnqueueVisitor::VisitUnresolvedMemberExpr(const UnresolvedMemberExpr *U) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002510 VisitOverloadExpr(U);
2511 if (!U->isImplicitAccess())
2512 AddStmt(U->getBase());
2513}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002514void EnqueueVisitor::VisitVAArgExpr(const VAArgExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002515 AddStmt(E->getSubExpr());
2516 AddTypeLoc(E->getWrittenTypeInfo());
2517}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002518void EnqueueVisitor::VisitSizeOfPackExpr(const SizeOfPackExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002519 WL.push_back(SizeOfPackExprParts(E, Parent));
2520}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002521void EnqueueVisitor::VisitOpaqueValueExpr(const OpaqueValueExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002522 // If the opaque value has a source expression, just transparently
2523 // visit that. This is useful for (e.g.) pseudo-object expressions.
2524 if (Expr *SourceExpr = E->getSourceExpr())
2525 return Visit(SourceExpr);
2526}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002527void EnqueueVisitor::VisitLambdaExpr(const LambdaExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002528 AddStmt(E->getBody());
2529 WL.push_back(LambdaExprParts(E, Parent));
2530}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002531void EnqueueVisitor::VisitPseudoObjectExpr(const PseudoObjectExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002532 // Treat the expression like its syntactic form.
2533 Visit(E->getSyntacticForm());
2534}
2535
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002536void EnqueueVisitor::VisitOMPExecutableDirective(
2537 const OMPExecutableDirective *D) {
2538 EnqueueChildren(D);
2539 for (ArrayRef<OMPClause *>::iterator I = D->clauses().begin(),
2540 E = D->clauses().end();
2541 I != E; ++I)
2542 EnqueueChildren(*I);
2543}
2544
Alexander Musman3aaab662014-08-19 11:27:13 +00002545void EnqueueVisitor::VisitOMPLoopDirective(const OMPLoopDirective *D) {
2546 VisitOMPExecutableDirective(D);
2547}
2548
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002549void EnqueueVisitor::VisitOMPParallelDirective(const OMPParallelDirective *D) {
2550 VisitOMPExecutableDirective(D);
2551}
2552
Alexey Bataev1b59ab52014-02-27 08:29:12 +00002553void EnqueueVisitor::VisitOMPSimdDirective(const OMPSimdDirective *D) {
Alexander Musman3aaab662014-08-19 11:27:13 +00002554 VisitOMPLoopDirective(D);
Alexey Bataev1b59ab52014-02-27 08:29:12 +00002555}
2556
Alexey Bataevf29276e2014-06-18 04:14:57 +00002557void EnqueueVisitor::VisitOMPForDirective(const OMPForDirective *D) {
Alexander Musman3aaab662014-08-19 11:27:13 +00002558 VisitOMPLoopDirective(D);
Alexey Bataevf29276e2014-06-18 04:14:57 +00002559}
2560
Alexander Musmanf82886e2014-09-18 05:12:34 +00002561void EnqueueVisitor::VisitOMPForSimdDirective(const OMPForSimdDirective *D) {
2562 VisitOMPLoopDirective(D);
2563}
2564
Alexey Bataevd3f8dd22014-06-25 11:44:49 +00002565void EnqueueVisitor::VisitOMPSectionsDirective(const OMPSectionsDirective *D) {
2566 VisitOMPExecutableDirective(D);
2567}
2568
Alexey Bataev1e0498a2014-06-26 08:21:58 +00002569void EnqueueVisitor::VisitOMPSectionDirective(const OMPSectionDirective *D) {
2570 VisitOMPExecutableDirective(D);
2571}
2572
Alexey Bataevd1e40fb2014-06-26 12:05:45 +00002573void EnqueueVisitor::VisitOMPSingleDirective(const OMPSingleDirective *D) {
2574 VisitOMPExecutableDirective(D);
2575}
2576
Alexander Musman80c22892014-07-17 08:54:58 +00002577void EnqueueVisitor::VisitOMPMasterDirective(const OMPMasterDirective *D) {
2578 VisitOMPExecutableDirective(D);
2579}
2580
Alexander Musmand9ed09f2014-07-21 09:42:05 +00002581void EnqueueVisitor::VisitOMPCriticalDirective(const OMPCriticalDirective *D) {
2582 VisitOMPExecutableDirective(D);
2583 AddDeclarationNameInfo(D);
2584}
2585
Alexey Bataev4acb8592014-07-07 13:01:15 +00002586void
2587EnqueueVisitor::VisitOMPParallelForDirective(const OMPParallelForDirective *D) {
Alexander Musman3aaab662014-08-19 11:27:13 +00002588 VisitOMPLoopDirective(D);
Alexey Bataev4acb8592014-07-07 13:01:15 +00002589}
2590
Alexander Musmane4e893b2014-09-23 09:33:00 +00002591void EnqueueVisitor::VisitOMPParallelForSimdDirective(
2592 const OMPParallelForSimdDirective *D) {
2593 VisitOMPLoopDirective(D);
2594}
2595
Alexey Bataev84d0b3e2014-07-08 08:12:03 +00002596void EnqueueVisitor::VisitOMPParallelSectionsDirective(
2597 const OMPParallelSectionsDirective *D) {
2598 VisitOMPExecutableDirective(D);
2599}
2600
Alexey Bataev9c2e8ee2014-07-11 11:25:16 +00002601void EnqueueVisitor::VisitOMPTaskDirective(const OMPTaskDirective *D) {
2602 VisitOMPExecutableDirective(D);
2603}
2604
Alexey Bataev68446b72014-07-18 07:47:19 +00002605void
2606EnqueueVisitor::VisitOMPTaskyieldDirective(const OMPTaskyieldDirective *D) {
2607 VisitOMPExecutableDirective(D);
2608}
2609
Alexey Bataev4d1dfea2014-07-18 09:11:51 +00002610void EnqueueVisitor::VisitOMPBarrierDirective(const OMPBarrierDirective *D) {
2611 VisitOMPExecutableDirective(D);
2612}
2613
Alexey Bataev2df347a2014-07-18 10:17:07 +00002614void EnqueueVisitor::VisitOMPTaskwaitDirective(const OMPTaskwaitDirective *D) {
2615 VisitOMPExecutableDirective(D);
2616}
2617
Alexey Bataevc30dd2d2015-06-18 12:14:09 +00002618void EnqueueVisitor::VisitOMPTaskgroupDirective(
2619 const OMPTaskgroupDirective *D) {
2620 VisitOMPExecutableDirective(D);
2621}
2622
Alexey Bataev6125da92014-07-21 11:26:11 +00002623void EnqueueVisitor::VisitOMPFlushDirective(const OMPFlushDirective *D) {
2624 VisitOMPExecutableDirective(D);
2625}
2626
Alexey Bataev9fb6e642014-07-22 06:45:04 +00002627void EnqueueVisitor::VisitOMPOrderedDirective(const OMPOrderedDirective *D) {
2628 VisitOMPExecutableDirective(D);
2629}
2630
Alexey Bataev0162e452014-07-22 10:10:35 +00002631void EnqueueVisitor::VisitOMPAtomicDirective(const OMPAtomicDirective *D) {
2632 VisitOMPExecutableDirective(D);
2633}
2634
Alexey Bataev0bd520b2014-09-19 08:19:49 +00002635void EnqueueVisitor::VisitOMPTargetDirective(const OMPTargetDirective *D) {
2636 VisitOMPExecutableDirective(D);
2637}
2638
Michael Wong65f367f2015-07-21 13:44:28 +00002639void EnqueueVisitor::VisitOMPTargetDataDirective(const
2640 OMPTargetDataDirective *D) {
2641 VisitOMPExecutableDirective(D);
2642}
2643
Samuel Antaodf67fc42016-01-19 19:15:56 +00002644void EnqueueVisitor::VisitOMPTargetEnterDataDirective(
2645 const OMPTargetEnterDataDirective *D) {
2646 VisitOMPExecutableDirective(D);
2647}
2648
Samuel Antao72590762016-01-19 20:04:50 +00002649void EnqueueVisitor::VisitOMPTargetExitDataDirective(
2650 const OMPTargetExitDataDirective *D) {
2651 VisitOMPExecutableDirective(D);
2652}
2653
Arpith Chacko Jacobe955b3d2016-01-26 18:48:41 +00002654void EnqueueVisitor::VisitOMPTargetParallelDirective(
2655 const OMPTargetParallelDirective *D) {
2656 VisitOMPExecutableDirective(D);
2657}
2658
Arpith Chacko Jacob05bebb52016-02-03 15:46:42 +00002659void EnqueueVisitor::VisitOMPTargetParallelForDirective(
2660 const OMPTargetParallelForDirective *D) {
2661 VisitOMPLoopDirective(D);
2662}
2663
Alexey Bataev13314bf2014-10-09 04:18:56 +00002664void EnqueueVisitor::VisitOMPTeamsDirective(const OMPTeamsDirective *D) {
2665 VisitOMPExecutableDirective(D);
2666}
2667
Alexey Bataev6d4ed052015-07-01 06:57:41 +00002668void EnqueueVisitor::VisitOMPCancellationPointDirective(
2669 const OMPCancellationPointDirective *D) {
2670 VisitOMPExecutableDirective(D);
2671}
2672
Alexey Bataev80909872015-07-02 11:25:17 +00002673void EnqueueVisitor::VisitOMPCancelDirective(const OMPCancelDirective *D) {
2674 VisitOMPExecutableDirective(D);
2675}
2676
Alexey Bataev49f6e782015-12-01 04:18:41 +00002677void EnqueueVisitor::VisitOMPTaskLoopDirective(const OMPTaskLoopDirective *D) {
2678 VisitOMPLoopDirective(D);
2679}
2680
Alexey Bataev0a6ed842015-12-03 09:40:15 +00002681void EnqueueVisitor::VisitOMPTaskLoopSimdDirective(
2682 const OMPTaskLoopSimdDirective *D) {
2683 VisitOMPLoopDirective(D);
2684}
2685
Carlo Bertolli6200a3d2015-12-14 14:51:25 +00002686void EnqueueVisitor::VisitOMPDistributeDirective(
2687 const OMPDistributeDirective *D) {
2688 VisitOMPLoopDirective(D);
2689}
2690
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002691void CursorVisitor::EnqueueWorkList(VisitorWorkList &WL, const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002692 EnqueueVisitor(WL, MakeCXCursor(S, StmtParent, TU,RegionOfInterest)).Visit(S);
2693}
2694
2695bool CursorVisitor::IsInRegionOfInterest(CXCursor C) {
2696 if (RegionOfInterest.isValid()) {
2697 SourceRange Range = getRawCursorExtent(C);
2698 if (Range.isInvalid() || CompareRegionOfInterest(Range))
2699 return false;
2700 }
2701 return true;
2702}
2703
2704bool CursorVisitor::RunVisitorWorkList(VisitorWorkList &WL) {
2705 while (!WL.empty()) {
2706 // Dequeue the worklist item.
Robert Wilhelm25284cc2013-08-23 16:11:15 +00002707 VisitorJob LI = WL.pop_back_val();
Guy Benyei11169dd2012-12-18 14:30:41 +00002708
2709 // Set the Parent field, then back to its old value once we're done.
2710 SetParentRAII SetParent(Parent, StmtParent, LI.getParent());
2711
2712 switch (LI.getKind()) {
2713 case VisitorJob::DeclVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002714 const Decl *D = cast<DeclVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002715 if (!D)
2716 continue;
2717
2718 // For now, perform default visitation for Decls.
2719 if (Visit(MakeCXCursor(D, TU, RegionOfInterest,
2720 cast<DeclVisit>(&LI)->isFirst())))
2721 return true;
2722
2723 continue;
2724 }
2725 case VisitorJob::ExplicitTemplateArgsVisitKind: {
James Y Knight04ec5bf2015-12-24 02:59:37 +00002726 for (const TemplateArgumentLoc &Arg :
2727 *cast<ExplicitTemplateArgsVisit>(&LI)) {
2728 if (VisitTemplateArgumentLoc(Arg))
Guy Benyei11169dd2012-12-18 14:30:41 +00002729 return true;
2730 }
2731 continue;
2732 }
2733 case VisitorJob::TypeLocVisitKind: {
2734 // Perform default visitation for TypeLocs.
2735 if (Visit(cast<TypeLocVisit>(&LI)->get()))
2736 return true;
2737 continue;
2738 }
2739 case VisitorJob::LabelRefVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002740 const LabelDecl *LS = cast<LabelRefVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002741 if (LabelStmt *stmt = LS->getStmt()) {
2742 if (Visit(MakeCursorLabelRef(stmt, cast<LabelRefVisit>(&LI)->getLoc(),
2743 TU))) {
2744 return true;
2745 }
2746 }
2747 continue;
2748 }
2749
2750 case VisitorJob::NestedNameSpecifierLocVisitKind: {
2751 NestedNameSpecifierLocVisit *V = cast<NestedNameSpecifierLocVisit>(&LI);
2752 if (VisitNestedNameSpecifierLoc(V->get()))
2753 return true;
2754 continue;
2755 }
2756
2757 case VisitorJob::DeclarationNameInfoVisitKind: {
2758 if (VisitDeclarationNameInfo(cast<DeclarationNameInfoVisit>(&LI)
2759 ->get()))
2760 return true;
2761 continue;
2762 }
2763 case VisitorJob::MemberRefVisitKind: {
2764 MemberRefVisit *V = cast<MemberRefVisit>(&LI);
2765 if (Visit(MakeCursorMemberRef(V->get(), V->getLoc(), TU)))
2766 return true;
2767 continue;
2768 }
2769 case VisitorJob::StmtVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002770 const Stmt *S = cast<StmtVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002771 if (!S)
2772 continue;
2773
2774 // Update the current cursor.
2775 CXCursor Cursor = MakeCXCursor(S, StmtParent, TU, RegionOfInterest);
2776 if (!IsInRegionOfInterest(Cursor))
2777 continue;
2778 switch (Visitor(Cursor, Parent, ClientData)) {
2779 case CXChildVisit_Break: return true;
2780 case CXChildVisit_Continue: break;
2781 case CXChildVisit_Recurse:
2782 if (PostChildrenVisitor)
Craig Topper69186e72014-06-08 08:38:04 +00002783 WL.push_back(PostChildrenVisit(nullptr, Cursor));
Guy Benyei11169dd2012-12-18 14:30:41 +00002784 EnqueueWorkList(WL, S);
2785 break;
2786 }
2787 continue;
2788 }
2789 case VisitorJob::MemberExprPartsKind: {
2790 // Handle the other pieces in the MemberExpr besides the base.
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002791 const MemberExpr *M = cast<MemberExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002792
2793 // Visit the nested-name-specifier
2794 if (NestedNameSpecifierLoc QualifierLoc = M->getQualifierLoc())
2795 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2796 return true;
2797
2798 // Visit the declaration name.
2799 if (VisitDeclarationNameInfo(M->getMemberNameInfo()))
2800 return true;
2801
2802 // Visit the explicitly-specified template arguments, if any.
2803 if (M->hasExplicitTemplateArgs()) {
2804 for (const TemplateArgumentLoc *Arg = M->getTemplateArgs(),
2805 *ArgEnd = Arg + M->getNumTemplateArgs();
2806 Arg != ArgEnd; ++Arg) {
2807 if (VisitTemplateArgumentLoc(*Arg))
2808 return true;
2809 }
2810 }
2811 continue;
2812 }
2813 case VisitorJob::DeclRefExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002814 const DeclRefExpr *DR = cast<DeclRefExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002815 // Visit nested-name-specifier, if present.
2816 if (NestedNameSpecifierLoc QualifierLoc = DR->getQualifierLoc())
2817 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2818 return true;
2819 // Visit declaration name.
2820 if (VisitDeclarationNameInfo(DR->getNameInfo()))
2821 return true;
2822 continue;
2823 }
2824 case VisitorJob::OverloadExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002825 const OverloadExpr *O = cast<OverloadExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002826 // Visit the nested-name-specifier.
2827 if (NestedNameSpecifierLoc QualifierLoc = O->getQualifierLoc())
2828 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2829 return true;
2830 // Visit the declaration name.
2831 if (VisitDeclarationNameInfo(O->getNameInfo()))
2832 return true;
2833 // Visit the overloaded declaration reference.
2834 if (Visit(MakeCursorOverloadedDeclRef(O, TU)))
2835 return true;
2836 continue;
2837 }
2838 case VisitorJob::SizeOfPackExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002839 const SizeOfPackExpr *E = cast<SizeOfPackExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002840 NamedDecl *Pack = E->getPack();
2841 if (isa<TemplateTypeParmDecl>(Pack)) {
2842 if (Visit(MakeCursorTypeRef(cast<TemplateTypeParmDecl>(Pack),
2843 E->getPackLoc(), TU)))
2844 return true;
2845
2846 continue;
2847 }
2848
2849 if (isa<TemplateTemplateParmDecl>(Pack)) {
2850 if (Visit(MakeCursorTemplateRef(cast<TemplateTemplateParmDecl>(Pack),
2851 E->getPackLoc(), TU)))
2852 return true;
2853
2854 continue;
2855 }
2856
2857 // Non-type template parameter packs and function parameter packs are
2858 // treated like DeclRefExpr cursors.
2859 continue;
2860 }
2861
2862 case VisitorJob::LambdaExprPartsKind: {
2863 // Visit captures.
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002864 const LambdaExpr *E = cast<LambdaExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002865 for (LambdaExpr::capture_iterator C = E->explicit_capture_begin(),
2866 CEnd = E->explicit_capture_end();
2867 C != CEnd; ++C) {
Richard Smithba71c082013-05-16 06:20:58 +00002868 // FIXME: Lambda init-captures.
2869 if (!C->capturesVariable())
Guy Benyei11169dd2012-12-18 14:30:41 +00002870 continue;
Richard Smithba71c082013-05-16 06:20:58 +00002871
Guy Benyei11169dd2012-12-18 14:30:41 +00002872 if (Visit(MakeCursorVariableRef(C->getCapturedVar(),
2873 C->getLocation(),
2874 TU)))
2875 return true;
2876 }
2877
2878 // Visit parameters and return type, if present.
2879 if (E->hasExplicitParameters() || E->hasExplicitResultType()) {
2880 TypeLoc TL = E->getCallOperator()->getTypeSourceInfo()->getTypeLoc();
2881 if (E->hasExplicitParameters() && E->hasExplicitResultType()) {
2882 // Visit the whole type.
2883 if (Visit(TL))
2884 return true;
David Blaikie6adc78e2013-02-18 22:06:02 +00002885 } else if (FunctionProtoTypeLoc Proto =
2886 TL.getAs<FunctionProtoTypeLoc>()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002887 if (E->hasExplicitParameters()) {
2888 // Visit parameters.
Alp Tokerb3fd5cf2014-01-21 00:32:38 +00002889 for (unsigned I = 0, N = Proto.getNumParams(); I != N; ++I)
2890 if (Visit(MakeCXCursor(Proto.getParam(I), TU)))
Guy Benyei11169dd2012-12-18 14:30:41 +00002891 return true;
2892 } else {
2893 // Visit result type.
Alp Toker42a16a62014-01-25 23:51:36 +00002894 if (Visit(Proto.getReturnLoc()))
Guy Benyei11169dd2012-12-18 14:30:41 +00002895 return true;
2896 }
2897 }
2898 }
2899 break;
2900 }
2901
2902 case VisitorJob::PostChildrenVisitKind:
2903 if (PostChildrenVisitor(Parent, ClientData))
2904 return true;
2905 break;
2906 }
2907 }
2908 return false;
2909}
2910
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002911bool CursorVisitor::Visit(const Stmt *S) {
Craig Topper69186e72014-06-08 08:38:04 +00002912 VisitorWorkList *WL = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00002913 if (!WorkListFreeList.empty()) {
2914 WL = WorkListFreeList.back();
2915 WL->clear();
2916 WorkListFreeList.pop_back();
2917 }
2918 else {
2919 WL = new VisitorWorkList();
2920 WorkListCache.push_back(WL);
2921 }
2922 EnqueueWorkList(*WL, S);
2923 bool result = RunVisitorWorkList(*WL);
2924 WorkListFreeList.push_back(WL);
2925 return result;
2926}
2927
2928namespace {
Dmitri Gribenkof8579502013-01-12 19:30:44 +00002929typedef SmallVector<SourceRange, 4> RefNamePieces;
James Y Knight04ec5bf2015-12-24 02:59:37 +00002930RefNamePieces buildPieces(unsigned NameFlags, bool IsMemberRefExpr,
2931 const DeclarationNameInfo &NI, SourceRange QLoc,
2932 const SourceRange *TemplateArgsLoc = nullptr) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002933 const bool WantQualifier = NameFlags & CXNameRange_WantQualifier;
2934 const bool WantTemplateArgs = NameFlags & CXNameRange_WantTemplateArgs;
2935 const bool WantSinglePiece = NameFlags & CXNameRange_WantSinglePiece;
2936
2937 const DeclarationName::NameKind Kind = NI.getName().getNameKind();
2938
2939 RefNamePieces Pieces;
2940
2941 if (WantQualifier && QLoc.isValid())
2942 Pieces.push_back(QLoc);
2943
2944 if (Kind != DeclarationName::CXXOperatorName || IsMemberRefExpr)
2945 Pieces.push_back(NI.getLoc());
James Y Knight04ec5bf2015-12-24 02:59:37 +00002946
2947 if (WantTemplateArgs && TemplateArgsLoc && TemplateArgsLoc->isValid())
2948 Pieces.push_back(*TemplateArgsLoc);
2949
Guy Benyei11169dd2012-12-18 14:30:41 +00002950 if (Kind == DeclarationName::CXXOperatorName) {
2951 Pieces.push_back(SourceLocation::getFromRawEncoding(
2952 NI.getInfo().CXXOperatorName.BeginOpNameLoc));
2953 Pieces.push_back(SourceLocation::getFromRawEncoding(
2954 NI.getInfo().CXXOperatorName.EndOpNameLoc));
2955 }
2956
2957 if (WantSinglePiece) {
2958 SourceRange R(Pieces.front().getBegin(), Pieces.back().getEnd());
2959 Pieces.clear();
2960 Pieces.push_back(R);
2961 }
2962
2963 return Pieces;
2964}
Alexander Kornienkoab9db512015-06-22 23:07:51 +00002965}
Guy Benyei11169dd2012-12-18 14:30:41 +00002966
2967//===----------------------------------------------------------------------===//
2968// Misc. API hooks.
2969//===----------------------------------------------------------------------===//
2970
Chad Rosier05c71aa2013-03-27 18:28:23 +00002971static void fatal_error_handler(void *user_data, const std::string& reason,
2972 bool gen_crash_diag) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002973 // Write the result out to stderr avoiding errs() because raw_ostreams can
2974 // call report_fatal_error.
2975 fprintf(stderr, "LIBCLANG FATAL ERROR: %s\n", reason.c_str());
2976 ::abort();
2977}
2978
Chandler Carruth66660742014-06-27 16:37:27 +00002979namespace {
2980struct RegisterFatalErrorHandler {
2981 RegisterFatalErrorHandler() {
2982 llvm::install_fatal_error_handler(fatal_error_handler, nullptr);
2983 }
2984};
2985}
2986
2987static llvm::ManagedStatic<RegisterFatalErrorHandler> RegisterFatalErrorHandlerOnce;
2988
Guy Benyei11169dd2012-12-18 14:30:41 +00002989extern "C" {
2990CXIndex clang_createIndex(int excludeDeclarationsFromPCH,
2991 int displayDiagnostics) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002992 // We use crash recovery to make some of our APIs more reliable, implicitly
2993 // enable it.
Argyrios Kyrtzidis3701f542013-11-27 08:58:09 +00002994 if (!getenv("LIBCLANG_DISABLE_CRASH_RECOVERY"))
2995 llvm::CrashRecoveryContext::Enable();
Guy Benyei11169dd2012-12-18 14:30:41 +00002996
Chandler Carruth66660742014-06-27 16:37:27 +00002997 // Look through the managed static to trigger construction of the managed
2998 // static which registers our fatal error handler. This ensures it is only
2999 // registered once.
3000 (void)*RegisterFatalErrorHandlerOnce;
Guy Benyei11169dd2012-12-18 14:30:41 +00003001
Adrian Prantlbc068582015-07-08 01:00:30 +00003002 // Initialize targets for clang module support.
3003 llvm::InitializeAllTargets();
3004 llvm::InitializeAllTargetMCs();
3005 llvm::InitializeAllAsmPrinters();
3006 llvm::InitializeAllAsmParsers();
3007
Adrian Prantlfb2398d2015-07-17 01:19:54 +00003008 CIndexer *CIdxr = new CIndexer();
3009
Guy Benyei11169dd2012-12-18 14:30:41 +00003010 if (excludeDeclarationsFromPCH)
3011 CIdxr->setOnlyLocalDecls();
3012 if (displayDiagnostics)
3013 CIdxr->setDisplayDiagnostics();
3014
3015 if (getenv("LIBCLANG_BGPRIO_INDEX"))
3016 CIdxr->setCXGlobalOptFlags(CIdxr->getCXGlobalOptFlags() |
3017 CXGlobalOpt_ThreadBackgroundPriorityForIndexing);
3018 if (getenv("LIBCLANG_BGPRIO_EDIT"))
3019 CIdxr->setCXGlobalOptFlags(CIdxr->getCXGlobalOptFlags() |
3020 CXGlobalOpt_ThreadBackgroundPriorityForEditing);
3021
3022 return CIdxr;
3023}
3024
3025void clang_disposeIndex(CXIndex CIdx) {
3026 if (CIdx)
3027 delete static_cast<CIndexer *>(CIdx);
3028}
3029
3030void clang_CXIndex_setGlobalOptions(CXIndex CIdx, unsigned options) {
3031 if (CIdx)
3032 static_cast<CIndexer *>(CIdx)->setCXGlobalOptFlags(options);
3033}
3034
3035unsigned clang_CXIndex_getGlobalOptions(CXIndex CIdx) {
3036 if (CIdx)
3037 return static_cast<CIndexer *>(CIdx)->getCXGlobalOptFlags();
3038 return 0;
3039}
3040
3041void clang_toggleCrashRecovery(unsigned isEnabled) {
3042 if (isEnabled)
3043 llvm::CrashRecoveryContext::Enable();
3044 else
3045 llvm::CrashRecoveryContext::Disable();
3046}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003047
Guy Benyei11169dd2012-12-18 14:30:41 +00003048CXTranslationUnit clang_createTranslationUnit(CXIndex CIdx,
3049 const char *ast_filename) {
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00003050 CXTranslationUnit TU;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003051 enum CXErrorCode Result =
3052 clang_createTranslationUnit2(CIdx, ast_filename, &TU);
Reid Klecknerfd48fc62014-02-12 23:56:20 +00003053 (void)Result;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003054 assert((TU && Result == CXError_Success) ||
3055 (!TU && Result != CXError_Success));
3056 return TU;
3057}
3058
3059enum CXErrorCode clang_createTranslationUnit2(CXIndex CIdx,
3060 const char *ast_filename,
3061 CXTranslationUnit *out_TU) {
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00003062 if (out_TU)
Craig Topper69186e72014-06-08 08:38:04 +00003063 *out_TU = nullptr;
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00003064
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003065 if (!CIdx || !ast_filename || !out_TU)
3066 return CXError_InvalidArguments;
Guy Benyei11169dd2012-12-18 14:30:41 +00003067
Argyrios Kyrtzidis27021012013-05-24 22:24:07 +00003068 LOG_FUNC_SECTION {
3069 *Log << ast_filename;
3070 }
3071
Guy Benyei11169dd2012-12-18 14:30:41 +00003072 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
3073 FileSystemOptions FileSystemOpts;
3074
Justin Bognerd512c1e2014-10-15 00:33:06 +00003075 IntrusiveRefCntPtr<DiagnosticsEngine> Diags =
3076 CompilerInstance::createDiagnostics(new DiagnosticOptions());
David Blaikie6f7382d2014-08-10 19:08:04 +00003077 std::unique_ptr<ASTUnit> AU = ASTUnit::LoadFromASTFile(
Adrian Prantlfb2398d2015-07-17 01:19:54 +00003078 ast_filename, CXXIdx->getPCHContainerOperations()->getRawReader(), Diags,
Adrian Prantl6b21ab22015-08-27 19:46:20 +00003079 FileSystemOpts, /*UseDebugInfo=*/false,
3080 CXXIdx->getOnlyLocalDecls(), None,
David Blaikie6f7382d2014-08-10 19:08:04 +00003081 /*CaptureDiagnostics=*/true,
3082 /*AllowPCHWithCompilerErrors=*/true,
3083 /*UserFilesAreVolatile=*/true);
3084 *out_TU = MakeCXTranslationUnit(CXXIdx, AU.release());
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003085 return *out_TU ? CXError_Success : CXError_Failure;
Guy Benyei11169dd2012-12-18 14:30:41 +00003086}
3087
3088unsigned clang_defaultEditingTranslationUnitOptions() {
3089 return CXTranslationUnit_PrecompiledPreamble |
3090 CXTranslationUnit_CacheCompletionResults;
3091}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003092
Guy Benyei11169dd2012-12-18 14:30:41 +00003093CXTranslationUnit
3094clang_createTranslationUnitFromSourceFile(CXIndex CIdx,
3095 const char *source_filename,
3096 int num_command_line_args,
3097 const char * const *command_line_args,
3098 unsigned num_unsaved_files,
3099 struct CXUnsavedFile *unsaved_files) {
3100 unsigned Options = CXTranslationUnit_DetailedPreprocessingRecord;
3101 return clang_parseTranslationUnit(CIdx, source_filename,
3102 command_line_args, num_command_line_args,
3103 unsaved_files, num_unsaved_files,
3104 Options);
3105}
3106
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003107static CXErrorCode
3108clang_parseTranslationUnit_Impl(CXIndex CIdx, const char *source_filename,
3109 const char *const *command_line_args,
3110 int num_command_line_args,
3111 ArrayRef<CXUnsavedFile> unsaved_files,
3112 unsigned options, CXTranslationUnit *out_TU) {
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00003113 // Set up the initial return values.
3114 if (out_TU)
Craig Topper69186e72014-06-08 08:38:04 +00003115 *out_TU = nullptr;
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00003116
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003117 // Check arguments.
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003118 if (!CIdx || !out_TU)
3119 return CXError_InvalidArguments;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003120
Guy Benyei11169dd2012-12-18 14:30:41 +00003121 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
3122
3123 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
3124 setThreadBackgroundPriority();
3125
3126 bool PrecompilePreamble = options & CXTranslationUnit_PrecompiledPreamble;
Benjamin Kramer5c248d82015-12-15 09:30:31 +00003127 bool CreatePreambleOnFirstParse =
3128 options & CXTranslationUnit_CreatePreambleOnFirstParse;
Guy Benyei11169dd2012-12-18 14:30:41 +00003129 // FIXME: Add a flag for modules.
3130 TranslationUnitKind TUKind
3131 = (options & CXTranslationUnit_Incomplete)? TU_Prefix : TU_Complete;
Alp Toker8c8a8752013-12-03 06:53:35 +00003132 bool CacheCodeCompletionResults
Guy Benyei11169dd2012-12-18 14:30:41 +00003133 = options & CXTranslationUnit_CacheCompletionResults;
3134 bool IncludeBriefCommentsInCodeCompletion
3135 = options & CXTranslationUnit_IncludeBriefCommentsInCodeCompletion;
3136 bool SkipFunctionBodies = options & CXTranslationUnit_SkipFunctionBodies;
3137 bool ForSerialization = options & CXTranslationUnit_ForSerialization;
3138
3139 // Configure the diagnostics.
3140 IntrusiveRefCntPtr<DiagnosticsEngine>
Sean Silvaf1b49e22013-01-20 01:58:28 +00003141 Diags(CompilerInstance::createDiagnostics(new DiagnosticOptions));
Guy Benyei11169dd2012-12-18 14:30:41 +00003142
3143 // Recover resources if we crash before exiting this function.
3144 llvm::CrashRecoveryContextCleanupRegistrar<DiagnosticsEngine,
3145 llvm::CrashRecoveryContextReleaseRefCleanup<DiagnosticsEngine> >
Alp Tokerf994cef2014-07-05 03:08:06 +00003146 DiagCleanup(Diags.get());
Guy Benyei11169dd2012-12-18 14:30:41 +00003147
Ahmed Charlesb8984322014-03-07 20:03:18 +00003148 std::unique_ptr<std::vector<ASTUnit::RemappedFile>> RemappedFiles(
3149 new std::vector<ASTUnit::RemappedFile>());
Guy Benyei11169dd2012-12-18 14:30:41 +00003150
3151 // Recover resources if we crash before exiting this function.
3152 llvm::CrashRecoveryContextCleanupRegistrar<
3153 std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
3154
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003155 for (auto &UF : unsaved_files) {
Rafael Espindolad87f8d72014-08-27 20:03:29 +00003156 std::unique_ptr<llvm::MemoryBuffer> MB =
Alp Toker9d85b182014-07-07 01:23:14 +00003157 llvm::MemoryBuffer::getMemBufferCopy(getContents(UF), UF.Filename);
Rafael Espindolad87f8d72014-08-27 20:03:29 +00003158 RemappedFiles->push_back(std::make_pair(UF.Filename, MB.release()));
Guy Benyei11169dd2012-12-18 14:30:41 +00003159 }
3160
Ahmed Charlesb8984322014-03-07 20:03:18 +00003161 std::unique_ptr<std::vector<const char *>> Args(
3162 new std::vector<const char *>());
Guy Benyei11169dd2012-12-18 14:30:41 +00003163
3164 // Recover resources if we crash before exiting this method.
3165 llvm::CrashRecoveryContextCleanupRegistrar<std::vector<const char*> >
3166 ArgsCleanup(Args.get());
3167
3168 // Since the Clang C library is primarily used by batch tools dealing with
3169 // (often very broken) source code, where spell-checking can have a
3170 // significant negative impact on performance (particularly when
3171 // precompiled headers are involved), we disable it by default.
3172 // Only do this if we haven't found a spell-checking-related argument.
3173 bool FoundSpellCheckingArgument = false;
3174 for (int I = 0; I != num_command_line_args; ++I) {
3175 if (strcmp(command_line_args[I], "-fno-spell-checking") == 0 ||
3176 strcmp(command_line_args[I], "-fspell-checking") == 0) {
3177 FoundSpellCheckingArgument = true;
3178 break;
3179 }
3180 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003181 Args->insert(Args->end(), command_line_args,
3182 command_line_args + num_command_line_args);
3183
Benjamin Kramerc02670e2015-11-18 16:14:27 +00003184 if (!FoundSpellCheckingArgument)
3185 Args->insert(Args->begin() + 1, "-fno-spell-checking");
3186
Guy Benyei11169dd2012-12-18 14:30:41 +00003187 // The 'source_filename' argument is optional. If the caller does not
3188 // specify it then it is assumed that the source file is specified
3189 // in the actual argument list.
3190 // Put the source file after command_line_args otherwise if '-x' flag is
3191 // present it will be unused.
3192 if (source_filename)
3193 Args->push_back(source_filename);
3194
3195 // Do we need the detailed preprocessing record?
3196 if (options & CXTranslationUnit_DetailedPreprocessingRecord) {
3197 Args->push_back("-Xclang");
3198 Args->push_back("-detailed-preprocessing-record");
3199 }
3200
3201 unsigned NumErrors = Diags->getClient()->getNumErrors();
Ahmed Charlesb8984322014-03-07 20:03:18 +00003202 std::unique_ptr<ASTUnit> ErrUnit;
Benjamin Kramer5c248d82015-12-15 09:30:31 +00003203 // Unless the user specified that they want the preamble on the first parse
3204 // set it up to be created on the first reparse. This makes the first parse
3205 // faster, trading for a slower (first) reparse.
3206 unsigned PrecompilePreambleAfterNParses =
3207 !PrecompilePreamble ? 0 : 2 - CreatePreambleOnFirstParse;
Ahmed Charlesb8984322014-03-07 20:03:18 +00003208 std::unique_ptr<ASTUnit> Unit(ASTUnit::LoadFromCommandLine(
Adrian Prantlbb165fb2015-06-20 18:53:08 +00003209 Args->data(), Args->data() + Args->size(),
3210 CXXIdx->getPCHContainerOperations(), Diags,
Ahmed Charlesb8984322014-03-07 20:03:18 +00003211 CXXIdx->getClangResourcesPath(), CXXIdx->getOnlyLocalDecls(),
3212 /*CaptureDiagnostics=*/true, *RemappedFiles.get(),
Benjamin Kramer5c248d82015-12-15 09:30:31 +00003213 /*RemappedFilesKeepOriginalName=*/true, PrecompilePreambleAfterNParses,
3214 TUKind, CacheCodeCompletionResults, IncludeBriefCommentsInCodeCompletion,
Ahmed Charlesb8984322014-03-07 20:03:18 +00003215 /*AllowPCHWithCompilerErrors=*/true, SkipFunctionBodies,
Argyrios Kyrtzidisa3e2ff12015-11-20 03:36:21 +00003216 /*UserFilesAreVolatile=*/true, ForSerialization,
3217 CXXIdx->getPCHContainerOperations()->getRawReader().getFormat(),
3218 &ErrUnit));
Guy Benyei11169dd2012-12-18 14:30:41 +00003219
Artem Belevich0ff05cd2015-07-13 23:27:56 +00003220 // Early failures in LoadFromCommandLine may return with ErrUnit unset.
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003221 if (!Unit && !ErrUnit)
3222 return CXError_ASTReadError;
Artem Belevich0ff05cd2015-07-13 23:27:56 +00003223
Guy Benyei11169dd2012-12-18 14:30:41 +00003224 if (NumErrors != Diags->getClient()->getNumErrors()) {
3225 // Make sure to check that 'Unit' is non-NULL.
3226 if (CXXIdx->getDisplayDiagnostics())
3227 printDiagsToStderr(Unit ? Unit.get() : ErrUnit.get());
3228 }
3229
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003230 if (isASTReadError(Unit ? Unit.get() : ErrUnit.get()))
3231 return CXError_ASTReadError;
3232
3233 *out_TU = MakeCXTranslationUnit(CXXIdx, Unit.release());
3234 return *out_TU ? CXError_Success : CXError_Failure;
Guy Benyei11169dd2012-12-18 14:30:41 +00003235}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003236
3237CXTranslationUnit
3238clang_parseTranslationUnit(CXIndex CIdx,
3239 const char *source_filename,
3240 const char *const *command_line_args,
3241 int num_command_line_args,
3242 struct CXUnsavedFile *unsaved_files,
3243 unsigned num_unsaved_files,
3244 unsigned options) {
3245 CXTranslationUnit TU;
3246 enum CXErrorCode Result = clang_parseTranslationUnit2(
3247 CIdx, source_filename, command_line_args, num_command_line_args,
3248 unsaved_files, num_unsaved_files, options, &TU);
Reid Kleckner6eaf05a2014-02-13 01:19:59 +00003249 (void)Result;
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00003250 assert((TU && Result == CXError_Success) ||
3251 (!TU && Result != CXError_Success));
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003252 return TU;
3253}
3254
3255enum CXErrorCode clang_parseTranslationUnit2(
Benjamin Kramerc02670e2015-11-18 16:14:27 +00003256 CXIndex CIdx, const char *source_filename,
3257 const char *const *command_line_args, int num_command_line_args,
3258 struct CXUnsavedFile *unsaved_files, unsigned num_unsaved_files,
3259 unsigned options, CXTranslationUnit *out_TU) {
3260 SmallVector<const char *, 4> Args;
3261 Args.push_back("clang");
3262 Args.append(command_line_args, command_line_args + num_command_line_args);
3263 return clang_parseTranslationUnit2FullArgv(
3264 CIdx, source_filename, Args.data(), Args.size(), unsaved_files,
3265 num_unsaved_files, options, out_TU);
3266}
3267
3268enum CXErrorCode clang_parseTranslationUnit2FullArgv(
3269 CXIndex CIdx, const char *source_filename,
3270 const char *const *command_line_args, int num_command_line_args,
3271 struct CXUnsavedFile *unsaved_files, unsigned num_unsaved_files,
3272 unsigned options, CXTranslationUnit *out_TU) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00003273 LOG_FUNC_SECTION {
3274 *Log << source_filename << ": ";
3275 for (int i = 0; i != num_command_line_args; ++i)
3276 *Log << command_line_args[i] << " ";
3277 }
3278
Alp Toker9d85b182014-07-07 01:23:14 +00003279 if (num_unsaved_files && !unsaved_files)
3280 return CXError_InvalidArguments;
3281
Alp Toker5c532982014-07-07 22:42:03 +00003282 CXErrorCode result = CXError_Failure;
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003283 auto ParseTranslationUnitImpl = [=, &result] {
3284 result = clang_parseTranslationUnit_Impl(
3285 CIdx, source_filename, command_line_args, num_command_line_args,
3286 llvm::makeArrayRef(unsaved_files, num_unsaved_files), options, out_TU);
3287 };
Guy Benyei11169dd2012-12-18 14:30:41 +00003288 llvm::CrashRecoveryContext CRC;
3289
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003290 if (!RunSafely(CRC, ParseTranslationUnitImpl)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003291 fprintf(stderr, "libclang: crash detected during parsing: {\n");
3292 fprintf(stderr, " 'source_filename' : '%s'\n", source_filename);
3293 fprintf(stderr, " 'command_line_args' : [");
3294 for (int i = 0; i != num_command_line_args; ++i) {
3295 if (i)
3296 fprintf(stderr, ", ");
3297 fprintf(stderr, "'%s'", command_line_args[i]);
3298 }
3299 fprintf(stderr, "],\n");
3300 fprintf(stderr, " 'unsaved_files' : [");
3301 for (unsigned i = 0; i != num_unsaved_files; ++i) {
3302 if (i)
3303 fprintf(stderr, ", ");
3304 fprintf(stderr, "('%s', '...', %ld)", unsaved_files[i].Filename,
3305 unsaved_files[i].Length);
3306 }
3307 fprintf(stderr, "],\n");
3308 fprintf(stderr, " 'options' : %d,\n", options);
3309 fprintf(stderr, "}\n");
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003310
3311 return CXError_Crashed;
Guy Benyei11169dd2012-12-18 14:30:41 +00003312 } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003313 if (CXTranslationUnit *TU = out_TU)
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003314 PrintLibclangResourceUsage(*TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003315 }
Alp Toker5c532982014-07-07 22:42:03 +00003316
3317 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003318}
3319
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003320CXString clang_Type_getObjCEncoding(CXType CT) {
3321 CXTranslationUnit tu = static_cast<CXTranslationUnit>(CT.data[1]);
3322 ASTContext &Ctx = getASTUnit(tu)->getASTContext();
3323 std::string encoding;
3324 Ctx.getObjCEncodingForType(QualType::getFromOpaquePtr(CT.data[0]),
3325 encoding);
3326
3327 return cxstring::createDup(encoding);
3328}
3329
3330static const IdentifierInfo *getMacroIdentifier(CXCursor C) {
3331 if (C.kind == CXCursor_MacroDefinition) {
3332 if (const MacroDefinitionRecord *MDR = getCursorMacroDefinition(C))
3333 return MDR->getName();
3334 } else if (C.kind == CXCursor_MacroExpansion) {
3335 MacroExpansionCursor ME = getCursorMacroExpansion(C);
3336 return ME.getName();
3337 }
3338 return nullptr;
3339}
3340
3341unsigned clang_Cursor_isMacroFunctionLike(CXCursor C) {
3342 const IdentifierInfo *II = getMacroIdentifier(C);
3343 if (!II) {
3344 return false;
3345 }
3346 ASTUnit *ASTU = getCursorASTUnit(C);
3347 Preprocessor &PP = ASTU->getPreprocessor();
3348 if (const MacroInfo *MI = PP.getMacroInfo(II))
3349 return MI->isFunctionLike();
3350 return false;
3351}
3352
3353unsigned clang_Cursor_isMacroBuiltin(CXCursor C) {
3354 const IdentifierInfo *II = getMacroIdentifier(C);
3355 if (!II) {
3356 return false;
3357 }
3358 ASTUnit *ASTU = getCursorASTUnit(C);
3359 Preprocessor &PP = ASTU->getPreprocessor();
3360 if (const MacroInfo *MI = PP.getMacroInfo(II))
3361 return MI->isBuiltinMacro();
3362 return false;
3363}
3364
3365unsigned clang_Cursor_isFunctionInlined(CXCursor C) {
3366 const Decl *D = getCursorDecl(C);
3367 const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(D);
3368 if (!FD) {
3369 return false;
3370 }
3371 return FD->isInlined();
3372}
3373
3374static StringLiteral* getCFSTR_value(CallExpr *callExpr) {
3375 if (callExpr->getNumArgs() != 1) {
3376 return nullptr;
3377 }
3378
3379 StringLiteral *S = nullptr;
3380 auto *arg = callExpr->getArg(0);
3381 if (arg->getStmtClass() == Stmt::ImplicitCastExprClass) {
3382 ImplicitCastExpr *I = static_cast<ImplicitCastExpr *>(arg);
3383 auto *subExpr = I->getSubExprAsWritten();
3384
3385 if(subExpr->getStmtClass() != Stmt::StringLiteralClass){
3386 return nullptr;
3387 }
3388
3389 S = static_cast<StringLiteral *>(I->getSubExprAsWritten());
3390 } else if (arg->getStmtClass() == Stmt::StringLiteralClass) {
3391 S = static_cast<StringLiteral *>(callExpr->getArg(0));
3392 } else {
3393 return nullptr;
3394 }
3395 return S;
3396}
3397
3398typedef struct {
3399 CXEvalResultKind EvalType;
3400 union {
3401 int intVal;
3402 double floatVal;
3403 char *stringVal;
3404 } EvalData;
3405} ExprEvalResult;
3406
3407void clang_EvalResult_dispose(CXEvalResult E) {
3408 ExprEvalResult *ER = (ExprEvalResult *)E;
3409 if (ER) {
3410 CXEvalResultKind evalType = ER->EvalType;
3411
3412 if (evalType != CXEval_UnExposed && evalType != CXEval_Float &&
3413 evalType != CXEval_Int && ER->EvalData.stringVal) {
3414 free((void *) ER->EvalData.stringVal);
3415 }
3416 free((void *)ER);
3417 }
3418}
3419
3420CXEvalResultKind clang_EvalResult_getKind(CXEvalResult E) {
3421 if (!E) {
3422 return CXEval_UnExposed;
3423 }
3424 return ((ExprEvalResult *)E)->EvalType;
3425}
3426
3427int clang_EvalResult_getAsInt(CXEvalResult E) {
3428 if (!E) {
3429 return 0;
3430 }
3431 return ((ExprEvalResult *)E)->EvalData.intVal;
3432}
3433
3434double clang_EvalResult_getAsDouble(CXEvalResult E) {
3435 if (!E) {
3436 return 0;
3437 }
3438 return ((ExprEvalResult *)E)->EvalData.floatVal;
3439}
3440
3441const char* clang_EvalResult_getAsStr(CXEvalResult E) {
3442 if (!E) {
3443 return nullptr;
3444 }
3445 return ((ExprEvalResult *)E)->EvalData.stringVal;
3446}
3447
3448static const ExprEvalResult* evaluateExpr(Expr *expr, CXCursor C) {
3449 Expr::EvalResult ER;
3450 ASTContext &ctx = getCursorContext(C);
3451 if (!expr) {
3452 return nullptr;
3453 }
3454 expr = expr->IgnoreParens();
3455 bool res = expr->EvaluateAsRValue(ER, ctx);
3456 QualType rettype;
3457 CallExpr *callExpr;
3458 ExprEvalResult *result = (ExprEvalResult *) malloc(sizeof(ExprEvalResult));
3459 if (!result) {
3460 return nullptr;
3461 }
3462 result->EvalType = CXEval_UnExposed;
3463
3464 if (res) {
3465
3466 if (ER.Val.isInt()) {
3467 result->EvalType = CXEval_Int;
3468 result->EvalData.intVal = ER.Val.getInt().getExtValue();
3469 return result;
3470 } else if (ER.Val.isFloat()) {
3471
3472 llvm::SmallVector<char, 100> Buffer;
3473 ER.Val.getFloat().toString(Buffer);
3474 std::string floatStr(Buffer.data(), Buffer.size());
3475 result->EvalType = CXEval_Float;
3476 bool ignored;
3477 llvm::APFloat apFloat = ER.Val.getFloat();
3478 apFloat.convert(llvm::APFloat::IEEEdouble,
3479 llvm::APFloat::rmNearestTiesToEven, &ignored);
3480 result->EvalData.floatVal = apFloat.convertToDouble();
3481 return result;
3482
3483 } else if (expr->getStmtClass() == Stmt::ImplicitCastExprClass) {
3484
3485 const ImplicitCastExpr *I = dyn_cast<ImplicitCastExpr>(expr);
3486 auto *subExpr = I->getSubExprAsWritten();
3487 if (subExpr->getStmtClass() == Stmt::StringLiteralClass ||
3488 subExpr->getStmtClass() == Stmt::ObjCStringLiteralClass) {
3489
3490 const StringLiteral *StrE = nullptr;
3491 const ObjCStringLiteral *ObjCExpr;
3492 ObjCExpr = dyn_cast<ObjCStringLiteral>(subExpr);
3493
3494 if (ObjCExpr) {
3495 StrE = ObjCExpr->getString();
3496 result->EvalType = CXEval_ObjCStrLiteral;
3497 } else {
3498 StrE = cast<StringLiteral>(I->getSubExprAsWritten());
3499 result->EvalType = CXEval_StrLiteral;
3500 }
3501
3502 std::string strRef(StrE->getString().str());
3503 result->EvalData.stringVal = (char *)malloc(strRef.size()+1);
3504 strncpy((char*)result->EvalData.stringVal, strRef.c_str(),
3505 strRef.size());
3506 result->EvalData.stringVal[strRef.size()] = '\0';
3507 return result;
3508 }
3509
3510 } else if (expr->getStmtClass() == Stmt::ObjCStringLiteralClass ||
3511 expr->getStmtClass() == Stmt::StringLiteralClass) {
3512
3513 const StringLiteral *StrE = nullptr;
3514 const ObjCStringLiteral *ObjCExpr;
3515 ObjCExpr = dyn_cast<ObjCStringLiteral>(expr);
3516
3517 if (ObjCExpr) {
3518 StrE = ObjCExpr->getString();
3519 result->EvalType = CXEval_ObjCStrLiteral;
3520 } else {
3521 StrE = cast<StringLiteral>(expr);
3522 result->EvalType = CXEval_StrLiteral;
3523 }
3524
3525 std::string strRef(StrE->getString().str());
3526 result->EvalData.stringVal = (char *)malloc(strRef.size()+1);
3527 strncpy((char*)result->EvalData.stringVal, strRef.c_str(),
3528 strRef.size());
3529 result->EvalData.stringVal[strRef.size()] = '\0';
3530 return result;
3531
3532 } else if (expr->getStmtClass() == Stmt::CStyleCastExprClass) {
3533
3534 CStyleCastExpr *CC = static_cast<CStyleCastExpr *>(expr);
3535
3536 rettype = CC->getType();
3537 if (rettype.getAsString() == "CFStringRef" &&
3538 CC->getSubExpr()->getStmtClass() == Stmt::CallExprClass) {
3539
3540 callExpr = static_cast<CallExpr *>(CC->getSubExpr());
3541 StringLiteral* S = getCFSTR_value(callExpr);
3542 if (S) {
3543 std::string strLiteral(S->getString().str());
3544 result->EvalType = CXEval_CFStr;
3545
3546 result->EvalData.stringVal = (char *)malloc(strLiteral.size()+1);
3547 strncpy((char*)result->EvalData.stringVal, strLiteral.c_str(),
3548 strLiteral.size());
3549 result->EvalData.stringVal[strLiteral.size()] = '\0';
3550 return result;
3551 }
3552 }
3553
3554 } else if (expr->getStmtClass() == Stmt::CallExprClass) {
3555
3556 callExpr = static_cast<CallExpr *>(expr);
3557 rettype = callExpr->getCallReturnType(ctx);
3558
3559 if (rettype->isVectorType() || callExpr->getNumArgs() > 1) {
3560 return nullptr;
3561 }
3562 if (rettype->isIntegralType(ctx) || rettype->isRealFloatingType()) {
3563 if(callExpr->getNumArgs() == 1 &&
3564 !callExpr->getArg(0)->getType()->isIntegralType(ctx)){
3565
3566 return nullptr;
3567 }
3568 } else if(rettype.getAsString() == "CFStringRef") {
3569
3570 StringLiteral* S = getCFSTR_value(callExpr);
3571 if (S) {
3572 std::string strLiteral(S->getString().str());
3573 result->EvalType = CXEval_CFStr;
3574 result->EvalData.stringVal = (char *)malloc(strLiteral.size()+1);
3575 strncpy((char*)result->EvalData.stringVal, strLiteral.c_str(),
3576 strLiteral.size());
3577 result->EvalData.stringVal[strLiteral.size()] = '\0';
3578 return result;
3579 }
3580 }
3581
3582 } else if (expr->getStmtClass() == Stmt::DeclRefExprClass) {
3583
3584 DeclRefExpr *D = static_cast<DeclRefExpr *>(expr);
3585 ValueDecl *V = D->getDecl();
3586 if (V->getKind() == Decl::Function) {
3587 std::string strName(V->getNameAsString());
3588 result->EvalType = CXEval_Other;
3589 result->EvalData.stringVal = (char *)malloc(strName.size()+1);
3590 strncpy((char*)result->EvalData.stringVal, strName.c_str(),
3591 strName.size());
3592 result->EvalData.stringVal[strName.size()] = '\0';
3593 return result;
3594 }
3595 }
3596
3597 }
3598
3599 clang_EvalResult_dispose((CXEvalResult *)result);
3600 return nullptr;
3601}
3602
3603CXEvalResult clang_Cursor_Evaluate(CXCursor C) {
3604 const Decl *D = getCursorDecl(C);
3605 if (D) {
3606 const Expr *expr = nullptr;
3607 if (auto *Var = dyn_cast<VarDecl>(D)) {
3608 expr = Var->getInit();
3609 } else if (auto *Field = dyn_cast<FieldDecl>(D)) {
3610 expr = Field->getInClassInitializer();
3611 }
3612 if (expr)
Aaron Ballman01dc1572016-01-20 15:25:30 +00003613 return const_cast<CXEvalResult>(reinterpret_cast<const void *>(
3614 evaluateExpr(const_cast<Expr *>(expr), C)));
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003615 return nullptr;
3616 }
3617
3618 const CompoundStmt *compoundStmt = dyn_cast_or_null<CompoundStmt>(getCursorStmt(C));
3619 if (compoundStmt) {
3620 Expr *expr = nullptr;
3621 for (auto *bodyIterator : compoundStmt->body()) {
3622 if ((expr = dyn_cast<Expr>(bodyIterator))) {
3623 break;
3624 }
3625 }
3626 if (expr)
Aaron Ballman01dc1572016-01-20 15:25:30 +00003627 return const_cast<CXEvalResult>(
3628 reinterpret_cast<const void *>(evaluateExpr(expr, C)));
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003629 }
3630 return nullptr;
3631}
3632
3633unsigned clang_Cursor_hasAttrs(CXCursor C) {
3634 const Decl *D = getCursorDecl(C);
3635 if (!D) {
3636 return 0;
3637 }
3638
3639 if (D->hasAttrs()) {
3640 return 1;
3641 }
3642
3643 return 0;
3644}
Guy Benyei11169dd2012-12-18 14:30:41 +00003645unsigned clang_defaultSaveOptions(CXTranslationUnit TU) {
3646 return CXSaveTranslationUnit_None;
3647}
3648
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003649static CXSaveError clang_saveTranslationUnit_Impl(CXTranslationUnit TU,
3650 const char *FileName,
3651 unsigned options) {
3652 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00003653 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
3654 setThreadBackgroundPriority();
3655
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003656 bool hadError = cxtu::getASTUnit(TU)->Save(FileName);
3657 return hadError ? CXSaveError_Unknown : CXSaveError_None;
Guy Benyei11169dd2012-12-18 14:30:41 +00003658}
3659
3660int clang_saveTranslationUnit(CXTranslationUnit TU, const char *FileName,
3661 unsigned options) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00003662 LOG_FUNC_SECTION {
3663 *Log << TU << ' ' << FileName;
3664 }
3665
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003666 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003667 LOG_BAD_TU(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003668 return CXSaveError_InvalidTU;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003669 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003670
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003671 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003672 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
3673 if (!CXXUnit->hasSema())
3674 return CXSaveError_InvalidTU;
3675
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003676 CXSaveError result;
3677 auto SaveTranslationUnitImpl = [=, &result]() {
3678 result = clang_saveTranslationUnit_Impl(TU, FileName, options);
3679 };
Guy Benyei11169dd2012-12-18 14:30:41 +00003680
3681 if (!CXXUnit->getDiagnostics().hasUnrecoverableErrorOccurred() ||
3682 getenv("LIBCLANG_NOTHREADS")) {
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003683 SaveTranslationUnitImpl();
Guy Benyei11169dd2012-12-18 14:30:41 +00003684
3685 if (getenv("LIBCLANG_RESOURCE_USAGE"))
3686 PrintLibclangResourceUsage(TU);
3687
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003688 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003689 }
3690
3691 // We have an AST that has invalid nodes due to compiler errors.
3692 // Use a crash recovery thread for protection.
3693
3694 llvm::CrashRecoveryContext CRC;
3695
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003696 if (!RunSafely(CRC, SaveTranslationUnitImpl)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003697 fprintf(stderr, "libclang: crash detected during AST saving: {\n");
3698 fprintf(stderr, " 'filename' : '%s'\n", FileName);
3699 fprintf(stderr, " 'options' : %d,\n", options);
3700 fprintf(stderr, "}\n");
3701
3702 return CXSaveError_Unknown;
3703
3704 } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
3705 PrintLibclangResourceUsage(TU);
3706 }
3707
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003708 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003709}
3710
3711void clang_disposeTranslationUnit(CXTranslationUnit CTUnit) {
3712 if (CTUnit) {
3713 // If the translation unit has been marked as unsafe to free, just discard
3714 // it.
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003715 ASTUnit *Unit = cxtu::getASTUnit(CTUnit);
3716 if (Unit && Unit->isUnsafeToFree())
Guy Benyei11169dd2012-12-18 14:30:41 +00003717 return;
3718
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003719 delete cxtu::getASTUnit(CTUnit);
Dmitri Gribenkob95b3f12013-01-26 22:44:19 +00003720 delete CTUnit->StringPool;
Guy Benyei11169dd2012-12-18 14:30:41 +00003721 delete static_cast<CXDiagnosticSetImpl *>(CTUnit->Diagnostics);
3722 disposeOverridenCXCursorsPool(CTUnit->OverridenCursorsPool);
Dmitri Gribenko9e605112013-11-13 22:16:51 +00003723 delete CTUnit->CommentToXML;
Guy Benyei11169dd2012-12-18 14:30:41 +00003724 delete CTUnit;
3725 }
3726}
3727
3728unsigned clang_defaultReparseOptions(CXTranslationUnit TU) {
3729 return CXReparse_None;
3730}
3731
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003732static CXErrorCode
3733clang_reparseTranslationUnit_Impl(CXTranslationUnit TU,
3734 ArrayRef<CXUnsavedFile> unsaved_files,
3735 unsigned options) {
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003736 // Check arguments.
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003737 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003738 LOG_BAD_TU(TU);
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003739 return CXError_InvalidArguments;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003740 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003741
3742 // Reset the associated diagnostics.
3743 delete static_cast<CXDiagnosticSetImpl*>(TU->Diagnostics);
Craig Topper69186e72014-06-08 08:38:04 +00003744 TU->Diagnostics = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00003745
Dmitri Gribenko183436e2013-01-26 21:49:50 +00003746 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00003747 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
3748 setThreadBackgroundPriority();
3749
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003750 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003751 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
Ahmed Charlesb8984322014-03-07 20:03:18 +00003752
3753 std::unique_ptr<std::vector<ASTUnit::RemappedFile>> RemappedFiles(
3754 new std::vector<ASTUnit::RemappedFile>());
3755
Guy Benyei11169dd2012-12-18 14:30:41 +00003756 // Recover resources if we crash before exiting this function.
3757 llvm::CrashRecoveryContextCleanupRegistrar<
3758 std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
Alp Toker9d85b182014-07-07 01:23:14 +00003759
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003760 for (auto &UF : unsaved_files) {
Rafael Espindolad87f8d72014-08-27 20:03:29 +00003761 std::unique_ptr<llvm::MemoryBuffer> MB =
Alp Toker9d85b182014-07-07 01:23:14 +00003762 llvm::MemoryBuffer::getMemBufferCopy(getContents(UF), UF.Filename);
Rafael Espindolad87f8d72014-08-27 20:03:29 +00003763 RemappedFiles->push_back(std::make_pair(UF.Filename, MB.release()));
Guy Benyei11169dd2012-12-18 14:30:41 +00003764 }
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003765
Adrian Prantlbb165fb2015-06-20 18:53:08 +00003766 if (!CXXUnit->Reparse(CXXIdx->getPCHContainerOperations(),
3767 *RemappedFiles.get()))
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003768 return CXError_Success;
3769 if (isASTReadError(CXXUnit))
3770 return CXError_ASTReadError;
3771 return CXError_Failure;
Guy Benyei11169dd2012-12-18 14:30:41 +00003772}
3773
3774int clang_reparseTranslationUnit(CXTranslationUnit TU,
3775 unsigned num_unsaved_files,
3776 struct CXUnsavedFile *unsaved_files,
3777 unsigned options) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00003778 LOG_FUNC_SECTION {
3779 *Log << TU;
3780 }
3781
Alp Toker9d85b182014-07-07 01:23:14 +00003782 if (num_unsaved_files && !unsaved_files)
3783 return CXError_InvalidArguments;
3784
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003785 CXErrorCode result;
3786 auto ReparseTranslationUnitImpl = [=, &result]() {
3787 result = clang_reparseTranslationUnit_Impl(
3788 TU, llvm::makeArrayRef(unsaved_files, num_unsaved_files), options);
3789 };
Guy Benyei11169dd2012-12-18 14:30:41 +00003790
3791 if (getenv("LIBCLANG_NOTHREADS")) {
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003792 ReparseTranslationUnitImpl();
Alp Toker5c532982014-07-07 22:42:03 +00003793 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003794 }
3795
3796 llvm::CrashRecoveryContext CRC;
3797
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003798 if (!RunSafely(CRC, ReparseTranslationUnitImpl)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003799 fprintf(stderr, "libclang: crash detected during reparsing\n");
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003800 cxtu::getASTUnit(TU)->setUnsafeToFree(true);
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003801 return CXError_Crashed;
Guy Benyei11169dd2012-12-18 14:30:41 +00003802 } else if (getenv("LIBCLANG_RESOURCE_USAGE"))
3803 PrintLibclangResourceUsage(TU);
3804
Alp Toker5c532982014-07-07 22:42:03 +00003805 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003806}
3807
3808
3809CXString clang_getTranslationUnitSpelling(CXTranslationUnit CTUnit) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003810 if (isNotUsableTU(CTUnit)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003811 LOG_BAD_TU(CTUnit);
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003812 return cxstring::createEmpty();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003813 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003814
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003815 ASTUnit *CXXUnit = cxtu::getASTUnit(CTUnit);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003816 return cxstring::createDup(CXXUnit->getOriginalSourceFileName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003817}
3818
3819CXCursor clang_getTranslationUnitCursor(CXTranslationUnit TU) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003820 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003821 LOG_BAD_TU(TU);
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00003822 return clang_getNullCursor();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003823 }
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00003824
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003825 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003826 return MakeCXCursor(CXXUnit->getASTContext().getTranslationUnitDecl(), TU);
3827}
3828
3829} // end: extern "C"
3830
3831//===----------------------------------------------------------------------===//
3832// CXFile Operations.
3833//===----------------------------------------------------------------------===//
3834
3835extern "C" {
3836CXString clang_getFileName(CXFile SFile) {
3837 if (!SFile)
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00003838 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00003839
3840 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003841 return cxstring::createRef(FEnt->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003842}
3843
3844time_t clang_getFileTime(CXFile SFile) {
3845 if (!SFile)
3846 return 0;
3847
3848 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
3849 return FEnt->getModificationTime();
3850}
3851
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003852CXFile clang_getFile(CXTranslationUnit TU, const char *file_name) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003853 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003854 LOG_BAD_TU(TU);
Craig Topper69186e72014-06-08 08:38:04 +00003855 return nullptr;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003856 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003857
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003858 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003859
3860 FileManager &FMgr = CXXUnit->getFileManager();
3861 return const_cast<FileEntry *>(FMgr.getFile(file_name));
3862}
3863
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003864unsigned clang_isFileMultipleIncludeGuarded(CXTranslationUnit TU,
3865 CXFile file) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003866 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003867 LOG_BAD_TU(TU);
3868 return 0;
3869 }
3870
3871 if (!file)
Guy Benyei11169dd2012-12-18 14:30:41 +00003872 return 0;
3873
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003874 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003875 FileEntry *FEnt = static_cast<FileEntry *>(file);
3876 return CXXUnit->getPreprocessor().getHeaderSearchInfo()
3877 .isFileMultipleIncludeGuarded(FEnt);
3878}
3879
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003880int clang_getFileUniqueID(CXFile file, CXFileUniqueID *outID) {
3881 if (!file || !outID)
3882 return 1;
3883
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003884 FileEntry *FEnt = static_cast<FileEntry *>(file);
Rafael Espindolaf8f91b82013-08-01 21:42:11 +00003885 const llvm::sys::fs::UniqueID &ID = FEnt->getUniqueID();
3886 outID->data[0] = ID.getDevice();
3887 outID->data[1] = ID.getFile();
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003888 outID->data[2] = FEnt->getModificationTime();
3889 return 0;
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003890}
3891
Argyrios Kyrtzidisac3997e2014-08-16 00:26:19 +00003892int clang_File_isEqual(CXFile file1, CXFile file2) {
3893 if (file1 == file2)
3894 return true;
3895
3896 if (!file1 || !file2)
3897 return false;
3898
3899 FileEntry *FEnt1 = static_cast<FileEntry *>(file1);
3900 FileEntry *FEnt2 = static_cast<FileEntry *>(file2);
3901 return FEnt1->getUniqueID() == FEnt2->getUniqueID();
3902}
3903
Guy Benyei11169dd2012-12-18 14:30:41 +00003904} // end: extern "C"
3905
3906//===----------------------------------------------------------------------===//
3907// CXCursor Operations.
3908//===----------------------------------------------------------------------===//
3909
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003910static const Decl *getDeclFromExpr(const Stmt *E) {
3911 if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003912 return getDeclFromExpr(CE->getSubExpr());
3913
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003914 if (const DeclRefExpr *RefExpr = dyn_cast<DeclRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003915 return RefExpr->getDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003916 if (const MemberExpr *ME = dyn_cast<MemberExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003917 return ME->getMemberDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003918 if (const ObjCIvarRefExpr *RE = dyn_cast<ObjCIvarRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003919 return RE->getDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003920 if (const ObjCPropertyRefExpr *PRE = dyn_cast<ObjCPropertyRefExpr>(E)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003921 if (PRE->isExplicitProperty())
3922 return PRE->getExplicitProperty();
3923 // It could be messaging both getter and setter as in:
3924 // ++myobj.myprop;
3925 // in which case prefer to associate the setter since it is less obvious
3926 // from inspecting the source that the setter is going to get called.
3927 if (PRE->isMessagingSetter())
3928 return PRE->getImplicitPropertySetter();
3929 return PRE->getImplicitPropertyGetter();
3930 }
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003931 if (const PseudoObjectExpr *POE = dyn_cast<PseudoObjectExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003932 return getDeclFromExpr(POE->getSyntacticForm());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003933 if (const OpaqueValueExpr *OVE = dyn_cast<OpaqueValueExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003934 if (Expr *Src = OVE->getSourceExpr())
3935 return getDeclFromExpr(Src);
3936
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003937 if (const CallExpr *CE = dyn_cast<CallExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003938 return getDeclFromExpr(CE->getCallee());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003939 if (const CXXConstructExpr *CE = dyn_cast<CXXConstructExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003940 if (!CE->isElidable())
3941 return CE->getConstructor();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003942 if (const ObjCMessageExpr *OME = dyn_cast<ObjCMessageExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003943 return OME->getMethodDecl();
3944
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003945 if (const ObjCProtocolExpr *PE = dyn_cast<ObjCProtocolExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003946 return PE->getProtocol();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003947 if (const SubstNonTypeTemplateParmPackExpr *NTTP
Guy Benyei11169dd2012-12-18 14:30:41 +00003948 = dyn_cast<SubstNonTypeTemplateParmPackExpr>(E))
3949 return NTTP->getParameterPack();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003950 if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003951 if (isa<NonTypeTemplateParmDecl>(SizeOfPack->getPack()) ||
3952 isa<ParmVarDecl>(SizeOfPack->getPack()))
3953 return SizeOfPack->getPack();
Craig Topper69186e72014-06-08 08:38:04 +00003954
3955 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00003956}
3957
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003958static SourceLocation getLocationFromExpr(const Expr *E) {
3959 if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003960 return getLocationFromExpr(CE->getSubExpr());
3961
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003962 if (const ObjCMessageExpr *Msg = dyn_cast<ObjCMessageExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003963 return /*FIXME:*/Msg->getLeftLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003964 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003965 return DRE->getLocation();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003966 if (const MemberExpr *Member = dyn_cast<MemberExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003967 return Member->getMemberLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003968 if (const ObjCIvarRefExpr *Ivar = dyn_cast<ObjCIvarRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003969 return Ivar->getLocation();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003970 if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003971 return SizeOfPack->getPackLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003972 if (const ObjCPropertyRefExpr *PropRef = dyn_cast<ObjCPropertyRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003973 return PropRef->getLocation();
3974
3975 return E->getLocStart();
3976}
3977
Aaron Ballmana85d3f82015-11-12 15:25:06 +00003978static std::string getMangledStructor(std::unique_ptr<MangleContext> &M,
3979 std::unique_ptr<llvm::DataLayout> &DL,
3980 const NamedDecl *ND,
3981 unsigned StructorType) {
3982 std::string FrontendBuf;
3983 llvm::raw_string_ostream FOS(FrontendBuf);
3984
3985 if (const auto *CD = dyn_cast_or_null<CXXConstructorDecl>(ND))
3986 M->mangleCXXCtor(CD, static_cast<CXXCtorType>(StructorType), FOS);
3987 else if (const auto *DD = dyn_cast_or_null<CXXDestructorDecl>(ND))
3988 M->mangleCXXDtor(DD, static_cast<CXXDtorType>(StructorType), FOS);
3989
3990 std::string BackendBuf;
3991 llvm::raw_string_ostream BOS(BackendBuf);
3992
3993 llvm::Mangler::getNameWithPrefix(BOS, llvm::Twine(FOS.str()), *DL);
3994
3995 return BOS.str();
3996}
3997
Guy Benyei11169dd2012-12-18 14:30:41 +00003998extern "C" {
3999
4000unsigned clang_visitChildren(CXCursor parent,
4001 CXCursorVisitor visitor,
4002 CXClientData client_data) {
4003 CursorVisitor CursorVis(getCursorTU(parent), visitor, client_data,
4004 /*VisitPreprocessorLast=*/false);
4005 return CursorVis.VisitChildren(parent);
4006}
4007
4008#ifndef __has_feature
4009#define __has_feature(x) 0
4010#endif
4011#if __has_feature(blocks)
4012typedef enum CXChildVisitResult
4013 (^CXCursorVisitorBlock)(CXCursor cursor, CXCursor parent);
4014
4015static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
4016 CXClientData client_data) {
4017 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
4018 return block(cursor, parent);
4019}
4020#else
4021// If we are compiled with a compiler that doesn't have native blocks support,
4022// define and call the block manually, so the
4023typedef struct _CXChildVisitResult
4024{
4025 void *isa;
4026 int flags;
4027 int reserved;
4028 enum CXChildVisitResult(*invoke)(struct _CXChildVisitResult*, CXCursor,
4029 CXCursor);
4030} *CXCursorVisitorBlock;
4031
4032static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
4033 CXClientData client_data) {
4034 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
4035 return block->invoke(block, cursor, parent);
4036}
4037#endif
4038
4039
4040unsigned clang_visitChildrenWithBlock(CXCursor parent,
4041 CXCursorVisitorBlock block) {
4042 return clang_visitChildren(parent, visitWithBlock, block);
4043}
4044
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004045static CXString getDeclSpelling(const Decl *D) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004046 if (!D)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00004047 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00004048
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004049 const NamedDecl *ND = dyn_cast<NamedDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00004050 if (!ND) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004051 if (const ObjCPropertyImplDecl *PropImpl =
4052 dyn_cast<ObjCPropertyImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004053 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004054 return cxstring::createDup(Property->getIdentifier()->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00004055
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004056 if (const ImportDecl *ImportD = dyn_cast<ImportDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004057 if (Module *Mod = ImportD->getImportedModule())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004058 return cxstring::createDup(Mod->getFullModuleName());
Guy Benyei11169dd2012-12-18 14:30:41 +00004059
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00004060 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00004061 }
4062
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004063 if (const ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(ND))
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004064 return cxstring::createDup(OMD->getSelector().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00004065
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004066 if (const ObjCCategoryImplDecl *CIMP = dyn_cast<ObjCCategoryImplDecl>(ND))
Guy Benyei11169dd2012-12-18 14:30:41 +00004067 // No, this isn't the same as the code below. getIdentifier() is non-virtual
4068 // and returns different names. NamedDecl returns the class name and
4069 // ObjCCategoryImplDecl returns the category name.
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004070 return cxstring::createRef(CIMP->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00004071
4072 if (isa<UsingDirectiveDecl>(D))
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00004073 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00004074
4075 SmallString<1024> S;
4076 llvm::raw_svector_ostream os(S);
4077 ND->printName(os);
4078
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004079 return cxstring::createDup(os.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00004080}
4081
4082CXString clang_getCursorSpelling(CXCursor C) {
4083 if (clang_isTranslationUnit(C.kind))
Dmitri Gribenko2c173b42013-01-11 19:28:44 +00004084 return clang_getTranslationUnitSpelling(getCursorTU(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00004085
4086 if (clang_isReference(C.kind)) {
4087 switch (C.kind) {
4088 case CXCursor_ObjCSuperClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004089 const ObjCInterfaceDecl *Super = getCursorObjCSuperClassRef(C).first;
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004090 return cxstring::createRef(Super->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00004091 }
4092 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004093 const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004094 return cxstring::createRef(Class->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00004095 }
4096 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004097 const ObjCProtocolDecl *OID = getCursorObjCProtocolRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00004098 assert(OID && "getCursorSpelling(): Missing protocol decl");
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004099 return cxstring::createRef(OID->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00004100 }
4101 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004102 const CXXBaseSpecifier *B = getCursorCXXBaseSpecifier(C);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004103 return cxstring::createDup(B->getType().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00004104 }
4105 case CXCursor_TypeRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004106 const TypeDecl *Type = getCursorTypeRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00004107 assert(Type && "Missing type decl");
4108
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004109 return cxstring::createDup(getCursorContext(C).getTypeDeclType(Type).
Guy Benyei11169dd2012-12-18 14:30:41 +00004110 getAsString());
4111 }
4112 case CXCursor_TemplateRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004113 const TemplateDecl *Template = getCursorTemplateRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00004114 assert(Template && "Missing template decl");
4115
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004116 return cxstring::createDup(Template->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00004117 }
4118
4119 case CXCursor_NamespaceRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004120 const NamedDecl *NS = getCursorNamespaceRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00004121 assert(NS && "Missing namespace decl");
4122
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004123 return cxstring::createDup(NS->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00004124 }
4125
4126 case CXCursor_MemberRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004127 const FieldDecl *Field = getCursorMemberRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00004128 assert(Field && "Missing member decl");
4129
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004130 return cxstring::createDup(Field->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00004131 }
4132
4133 case CXCursor_LabelRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004134 const LabelStmt *Label = getCursorLabelRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00004135 assert(Label && "Missing label");
4136
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004137 return cxstring::createRef(Label->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00004138 }
4139
4140 case CXCursor_OverloadedDeclRef: {
4141 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004142 if (const Decl *D = Storage.dyn_cast<const Decl *>()) {
4143 if (const NamedDecl *ND = dyn_cast<NamedDecl>(D))
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004144 return cxstring::createDup(ND->getNameAsString());
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00004145 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00004146 }
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004147 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004148 return cxstring::createDup(E->getName().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00004149 OverloadedTemplateStorage *Ovl
4150 = Storage.get<OverloadedTemplateStorage*>();
4151 if (Ovl->size() == 0)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00004152 return cxstring::createEmpty();
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004153 return cxstring::createDup((*Ovl->begin())->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00004154 }
4155
4156 case CXCursor_VariableRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004157 const VarDecl *Var = getCursorVariableRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00004158 assert(Var && "Missing variable decl");
4159
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004160 return cxstring::createDup(Var->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00004161 }
4162
4163 default:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004164 return cxstring::createRef("<not implemented>");
Guy Benyei11169dd2012-12-18 14:30:41 +00004165 }
4166 }
4167
4168 if (clang_isExpression(C.kind)) {
Argyrios Kyrtzidis3227d862014-03-03 19:40:52 +00004169 const Expr *E = getCursorExpr(C);
4170
4171 if (C.kind == CXCursor_ObjCStringLiteral ||
4172 C.kind == CXCursor_StringLiteral) {
4173 const StringLiteral *SLit;
4174 if (const ObjCStringLiteral *OSL = dyn_cast<ObjCStringLiteral>(E)) {
4175 SLit = OSL->getString();
4176 } else {
4177 SLit = cast<StringLiteral>(E);
4178 }
4179 SmallString<256> Buf;
4180 llvm::raw_svector_ostream OS(Buf);
4181 SLit->outputString(OS);
4182 return cxstring::createDup(OS.str());
4183 }
4184
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004185 const Decl *D = getDeclFromExpr(getCursorExpr(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00004186 if (D)
4187 return getDeclSpelling(D);
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00004188 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00004189 }
4190
4191 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004192 const Stmt *S = getCursorStmt(C);
4193 if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S))
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004194 return cxstring::createRef(Label->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00004195
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00004196 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00004197 }
4198
4199 if (C.kind == CXCursor_MacroExpansion)
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004200 return cxstring::createRef(getCursorMacroExpansion(C).getName()
Guy Benyei11169dd2012-12-18 14:30:41 +00004201 ->getNameStart());
4202
4203 if (C.kind == CXCursor_MacroDefinition)
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004204 return cxstring::createRef(getCursorMacroDefinition(C)->getName()
Guy Benyei11169dd2012-12-18 14:30:41 +00004205 ->getNameStart());
4206
4207 if (C.kind == CXCursor_InclusionDirective)
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004208 return cxstring::createDup(getCursorInclusionDirective(C)->getFileName());
Guy Benyei11169dd2012-12-18 14:30:41 +00004209
4210 if (clang_isDeclaration(C.kind))
4211 return getDeclSpelling(getCursorDecl(C));
4212
4213 if (C.kind == CXCursor_AnnotateAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00004214 const AnnotateAttr *AA = cast<AnnotateAttr>(cxcursor::getCursorAttr(C));
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004215 return cxstring::createDup(AA->getAnnotation());
Guy Benyei11169dd2012-12-18 14:30:41 +00004216 }
4217
4218 if (C.kind == CXCursor_AsmLabelAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00004219 const AsmLabelAttr *AA = cast<AsmLabelAttr>(cxcursor::getCursorAttr(C));
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004220 return cxstring::createDup(AA->getLabel());
Guy Benyei11169dd2012-12-18 14:30:41 +00004221 }
4222
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00004223 if (C.kind == CXCursor_PackedAttr) {
4224 return cxstring::createRef("packed");
4225 }
4226
Saleem Abdulrasool79c69712015-09-05 18:53:43 +00004227 if (C.kind == CXCursor_VisibilityAttr) {
4228 const VisibilityAttr *AA = cast<VisibilityAttr>(cxcursor::getCursorAttr(C));
4229 switch (AA->getVisibility()) {
4230 case VisibilityAttr::VisibilityType::Default:
4231 return cxstring::createRef("default");
4232 case VisibilityAttr::VisibilityType::Hidden:
4233 return cxstring::createRef("hidden");
4234 case VisibilityAttr::VisibilityType::Protected:
4235 return cxstring::createRef("protected");
4236 }
4237 llvm_unreachable("unknown visibility type");
4238 }
4239
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00004240 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00004241}
4242
4243CXSourceRange clang_Cursor_getSpellingNameRange(CXCursor C,
4244 unsigned pieceIndex,
4245 unsigned options) {
4246 if (clang_Cursor_isNull(C))
4247 return clang_getNullRange();
4248
4249 ASTContext &Ctx = getCursorContext(C);
4250
4251 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004252 const Stmt *S = getCursorStmt(C);
4253 if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004254 if (pieceIndex > 0)
4255 return clang_getNullRange();
4256 return cxloc::translateSourceRange(Ctx, Label->getIdentLoc());
4257 }
4258
4259 return clang_getNullRange();
4260 }
4261
4262 if (C.kind == CXCursor_ObjCMessageExpr) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004263 if (const ObjCMessageExpr *
Guy Benyei11169dd2012-12-18 14:30:41 +00004264 ME = dyn_cast_or_null<ObjCMessageExpr>(getCursorExpr(C))) {
4265 if (pieceIndex >= ME->getNumSelectorLocs())
4266 return clang_getNullRange();
4267 return cxloc::translateSourceRange(Ctx, ME->getSelectorLoc(pieceIndex));
4268 }
4269 }
4270
4271 if (C.kind == CXCursor_ObjCInstanceMethodDecl ||
4272 C.kind == CXCursor_ObjCClassMethodDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004273 if (const ObjCMethodDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00004274 MD = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(C))) {
4275 if (pieceIndex >= MD->getNumSelectorLocs())
4276 return clang_getNullRange();
4277 return cxloc::translateSourceRange(Ctx, MD->getSelectorLoc(pieceIndex));
4278 }
4279 }
4280
4281 if (C.kind == CXCursor_ObjCCategoryDecl ||
4282 C.kind == CXCursor_ObjCCategoryImplDecl) {
4283 if (pieceIndex > 0)
4284 return clang_getNullRange();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004285 if (const ObjCCategoryDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00004286 CD = dyn_cast_or_null<ObjCCategoryDecl>(getCursorDecl(C)))
4287 return cxloc::translateSourceRange(Ctx, CD->getCategoryNameLoc());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004288 if (const ObjCCategoryImplDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00004289 CID = dyn_cast_or_null<ObjCCategoryImplDecl>(getCursorDecl(C)))
4290 return cxloc::translateSourceRange(Ctx, CID->getCategoryNameLoc());
4291 }
4292
4293 if (C.kind == CXCursor_ModuleImportDecl) {
4294 if (pieceIndex > 0)
4295 return clang_getNullRange();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004296 if (const ImportDecl *ImportD =
4297 dyn_cast_or_null<ImportDecl>(getCursorDecl(C))) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004298 ArrayRef<SourceLocation> Locs = ImportD->getIdentifierLocs();
4299 if (!Locs.empty())
4300 return cxloc::translateSourceRange(Ctx,
4301 SourceRange(Locs.front(), Locs.back()));
4302 }
4303 return clang_getNullRange();
4304 }
4305
Argyrios Kyrtzidisa2a1e532014-08-26 20:23:26 +00004306 if (C.kind == CXCursor_CXXMethod || C.kind == CXCursor_Destructor ||
4307 C.kind == CXCursor_ConversionFunction) {
4308 if (pieceIndex > 0)
4309 return clang_getNullRange();
4310 if (const FunctionDecl *FD =
4311 dyn_cast_or_null<FunctionDecl>(getCursorDecl(C))) {
4312 DeclarationNameInfo FunctionName = FD->getNameInfo();
4313 return cxloc::translateSourceRange(Ctx, FunctionName.getSourceRange());
4314 }
4315 return clang_getNullRange();
4316 }
4317
Guy Benyei11169dd2012-12-18 14:30:41 +00004318 // FIXME: A CXCursor_InclusionDirective should give the location of the
4319 // filename, but we don't keep track of this.
4320
4321 // FIXME: A CXCursor_AnnotateAttr should give the location of the annotation
4322 // but we don't keep track of this.
4323
4324 // FIXME: A CXCursor_AsmLabelAttr should give the location of the label
4325 // but we don't keep track of this.
4326
4327 // Default handling, give the location of the cursor.
4328
4329 if (pieceIndex > 0)
4330 return clang_getNullRange();
4331
4332 CXSourceLocation CXLoc = clang_getCursorLocation(C);
4333 SourceLocation Loc = cxloc::translateSourceLocation(CXLoc);
4334 return cxloc::translateSourceRange(Ctx, Loc);
4335}
4336
Eli Bendersky44a206f2014-07-31 18:04:56 +00004337CXString clang_Cursor_getMangling(CXCursor C) {
4338 if (clang_isInvalid(C.kind) || !clang_isDeclaration(C.kind))
4339 return cxstring::createEmpty();
4340
Eli Bendersky44a206f2014-07-31 18:04:56 +00004341 // Mangling only works for functions and variables.
Eli Bendersky79759592014-08-01 15:01:10 +00004342 const Decl *D = getCursorDecl(C);
Eli Bendersky44a206f2014-07-31 18:04:56 +00004343 if (!D || !(isa<FunctionDecl>(D) || isa<VarDecl>(D)))
4344 return cxstring::createEmpty();
4345
Eli Bendersky79759592014-08-01 15:01:10 +00004346 // First apply frontend mangling.
Eli Bendersky44a206f2014-07-31 18:04:56 +00004347 const NamedDecl *ND = cast<NamedDecl>(D);
Eli Bendersky79759592014-08-01 15:01:10 +00004348 ASTContext &Ctx = ND->getASTContext();
4349 std::unique_ptr<MangleContext> MC(Ctx.createMangleContext());
Eli Bendersky44a206f2014-07-31 18:04:56 +00004350
Eli Bendersky79759592014-08-01 15:01:10 +00004351 std::string FrontendBuf;
4352 llvm::raw_string_ostream FrontendBufOS(FrontendBuf);
Ehsan Akhgarif8d44de2015-10-08 00:01:20 +00004353 if (MC->shouldMangleDeclName(ND)) {
4354 MC->mangleName(ND, FrontendBufOS);
4355 } else {
4356 ND->printName(FrontendBufOS);
4357 }
Eli Bendersky44a206f2014-07-31 18:04:56 +00004358
Eli Bendersky79759592014-08-01 15:01:10 +00004359 // Now apply backend mangling.
4360 std::unique_ptr<llvm::DataLayout> DL(
Eric Christopher964a5f32015-08-05 23:48:05 +00004361 new llvm::DataLayout(Ctx.getTargetInfo().getDataLayoutString()));
Eli Bendersky79759592014-08-01 15:01:10 +00004362
4363 std::string FinalBuf;
4364 llvm::raw_string_ostream FinalBufOS(FinalBuf);
Rafael Espindolab633d202015-06-23 13:59:36 +00004365 llvm::Mangler::getNameWithPrefix(FinalBufOS, llvm::Twine(FrontendBufOS.str()),
4366 *DL);
Eli Bendersky79759592014-08-01 15:01:10 +00004367
4368 return cxstring::createDup(FinalBufOS.str());
Eli Bendersky44a206f2014-07-31 18:04:56 +00004369}
4370
Saleem Abdulrasool60034432015-11-12 03:57:22 +00004371CXStringSet *clang_Cursor_getCXXManglings(CXCursor C) {
4372 if (clang_isInvalid(C.kind) || !clang_isDeclaration(C.kind))
4373 return nullptr;
4374
4375 const Decl *D = getCursorDecl(C);
4376 if (!(isa<CXXRecordDecl>(D) || isa<CXXMethodDecl>(D)))
4377 return nullptr;
4378
4379 const NamedDecl *ND = cast<NamedDecl>(D);
4380
4381 ASTContext &Ctx = ND->getASTContext();
4382 std::unique_ptr<MangleContext> M(Ctx.createMangleContext());
4383 std::unique_ptr<llvm::DataLayout> DL(
4384 new llvm::DataLayout(Ctx.getTargetInfo().getDataLayoutString()));
4385
4386 std::vector<std::string> Manglings;
4387
4388 auto hasDefaultCXXMethodCC = [](ASTContext &C, const CXXMethodDecl *MD) {
4389 auto DefaultCC = C.getDefaultCallingConvention(/*IsVariadic=*/false,
4390 /*IsCSSMethod=*/true);
4391 auto CC = MD->getType()->getAs<FunctionProtoType>()->getCallConv();
4392 return CC == DefaultCC;
4393 };
4394
4395 if (const auto *CD = dyn_cast_or_null<CXXConstructorDecl>(ND)) {
4396 Manglings.emplace_back(getMangledStructor(M, DL, CD, Ctor_Base));
4397
4398 if (Ctx.getTargetInfo().getCXXABI().isItaniumFamily())
4399 if (!CD->getParent()->isAbstract())
4400 Manglings.emplace_back(getMangledStructor(M, DL, CD, Ctor_Complete));
4401
4402 if (Ctx.getTargetInfo().getCXXABI().isMicrosoft())
4403 if (CD->hasAttr<DLLExportAttr>() && CD->isDefaultConstructor())
4404 if (!(hasDefaultCXXMethodCC(Ctx, CD) && CD->getNumParams() == 0))
4405 Manglings.emplace_back(getMangledStructor(M, DL, CD,
4406 Ctor_DefaultClosure));
4407 } else if (const auto *DD = dyn_cast_or_null<CXXDestructorDecl>(ND)) {
4408 Manglings.emplace_back(getMangledStructor(M, DL, DD, Dtor_Base));
4409 if (Ctx.getTargetInfo().getCXXABI().isItaniumFamily()) {
4410 Manglings.emplace_back(getMangledStructor(M, DL, DD, Dtor_Complete));
Saleem Abdulrasoold5af8ae2015-12-10 06:30:23 +00004411 if (DD->isVirtual())
Saleem Abdulrasool60034432015-11-12 03:57:22 +00004412 Manglings.emplace_back(getMangledStructor(M, DL, DD, Dtor_Deleting));
4413 }
4414 }
4415
4416 return cxstring::createSet(Manglings);
4417}
4418
Guy Benyei11169dd2012-12-18 14:30:41 +00004419CXString clang_getCursorDisplayName(CXCursor C) {
4420 if (!clang_isDeclaration(C.kind))
4421 return clang_getCursorSpelling(C);
4422
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004423 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004424 if (!D)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00004425 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00004426
4427 PrintingPolicy Policy = getCursorContext(C).getPrintingPolicy();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004428 if (const FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004429 D = FunTmpl->getTemplatedDecl();
4430
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004431 if (const FunctionDecl *Function = dyn_cast<FunctionDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004432 SmallString<64> Str;
4433 llvm::raw_svector_ostream OS(Str);
4434 OS << *Function;
4435 if (Function->getPrimaryTemplate())
4436 OS << "<>";
4437 OS << "(";
4438 for (unsigned I = 0, N = Function->getNumParams(); I != N; ++I) {
4439 if (I)
4440 OS << ", ";
4441 OS << Function->getParamDecl(I)->getType().getAsString(Policy);
4442 }
4443
4444 if (Function->isVariadic()) {
4445 if (Function->getNumParams())
4446 OS << ", ";
4447 OS << "...";
4448 }
4449 OS << ")";
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004450 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00004451 }
4452
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004453 if (const ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004454 SmallString<64> Str;
4455 llvm::raw_svector_ostream OS(Str);
4456 OS << *ClassTemplate;
4457 OS << "<";
4458 TemplateParameterList *Params = ClassTemplate->getTemplateParameters();
4459 for (unsigned I = 0, N = Params->size(); I != N; ++I) {
4460 if (I)
4461 OS << ", ";
4462
4463 NamedDecl *Param = Params->getParam(I);
4464 if (Param->getIdentifier()) {
4465 OS << Param->getIdentifier()->getName();
4466 continue;
4467 }
4468
4469 // There is no parameter name, which makes this tricky. Try to come up
4470 // with something useful that isn't too long.
4471 if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(Param))
4472 OS << (TTP->wasDeclaredWithTypename()? "typename" : "class");
4473 else if (NonTypeTemplateParmDecl *NTTP
4474 = dyn_cast<NonTypeTemplateParmDecl>(Param))
4475 OS << NTTP->getType().getAsString(Policy);
4476 else
4477 OS << "template<...> class";
4478 }
4479
4480 OS << ">";
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004481 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00004482 }
4483
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004484 if (const ClassTemplateSpecializationDecl *ClassSpec
Guy Benyei11169dd2012-12-18 14:30:41 +00004485 = dyn_cast<ClassTemplateSpecializationDecl>(D)) {
4486 // If the type was explicitly written, use that.
4487 if (TypeSourceInfo *TSInfo = ClassSpec->getTypeAsWritten())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004488 return cxstring::createDup(TSInfo->getType().getAsString(Policy));
Guy Benyei11169dd2012-12-18 14:30:41 +00004489
Benjamin Kramer9170e912013-02-22 15:46:01 +00004490 SmallString<128> Str;
Guy Benyei11169dd2012-12-18 14:30:41 +00004491 llvm::raw_svector_ostream OS(Str);
4492 OS << *ClassSpec;
Benjamin Kramer9170e912013-02-22 15:46:01 +00004493 TemplateSpecializationType::PrintTemplateArgumentList(OS,
Guy Benyei11169dd2012-12-18 14:30:41 +00004494 ClassSpec->getTemplateArgs().data(),
4495 ClassSpec->getTemplateArgs().size(),
4496 Policy);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004497 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00004498 }
4499
4500 return clang_getCursorSpelling(C);
4501}
4502
4503CXString clang_getCursorKindSpelling(enum CXCursorKind Kind) {
4504 switch (Kind) {
4505 case CXCursor_FunctionDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004506 return cxstring::createRef("FunctionDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004507 case CXCursor_TypedefDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004508 return cxstring::createRef("TypedefDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004509 case CXCursor_EnumDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004510 return cxstring::createRef("EnumDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004511 case CXCursor_EnumConstantDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004512 return cxstring::createRef("EnumConstantDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004513 case CXCursor_StructDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004514 return cxstring::createRef("StructDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004515 case CXCursor_UnionDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004516 return cxstring::createRef("UnionDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004517 case CXCursor_ClassDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004518 return cxstring::createRef("ClassDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004519 case CXCursor_FieldDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004520 return cxstring::createRef("FieldDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004521 case CXCursor_VarDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004522 return cxstring::createRef("VarDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004523 case CXCursor_ParmDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004524 return cxstring::createRef("ParmDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004525 case CXCursor_ObjCInterfaceDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004526 return cxstring::createRef("ObjCInterfaceDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004527 case CXCursor_ObjCCategoryDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004528 return cxstring::createRef("ObjCCategoryDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004529 case CXCursor_ObjCProtocolDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004530 return cxstring::createRef("ObjCProtocolDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004531 case CXCursor_ObjCPropertyDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004532 return cxstring::createRef("ObjCPropertyDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004533 case CXCursor_ObjCIvarDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004534 return cxstring::createRef("ObjCIvarDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004535 case CXCursor_ObjCInstanceMethodDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004536 return cxstring::createRef("ObjCInstanceMethodDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004537 case CXCursor_ObjCClassMethodDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004538 return cxstring::createRef("ObjCClassMethodDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004539 case CXCursor_ObjCImplementationDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004540 return cxstring::createRef("ObjCImplementationDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004541 case CXCursor_ObjCCategoryImplDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004542 return cxstring::createRef("ObjCCategoryImplDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004543 case CXCursor_CXXMethod:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004544 return cxstring::createRef("CXXMethod");
Guy Benyei11169dd2012-12-18 14:30:41 +00004545 case CXCursor_UnexposedDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004546 return cxstring::createRef("UnexposedDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004547 case CXCursor_ObjCSuperClassRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004548 return cxstring::createRef("ObjCSuperClassRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004549 case CXCursor_ObjCProtocolRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004550 return cxstring::createRef("ObjCProtocolRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004551 case CXCursor_ObjCClassRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004552 return cxstring::createRef("ObjCClassRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004553 case CXCursor_TypeRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004554 return cxstring::createRef("TypeRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004555 case CXCursor_TemplateRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004556 return cxstring::createRef("TemplateRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004557 case CXCursor_NamespaceRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004558 return cxstring::createRef("NamespaceRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004559 case CXCursor_MemberRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004560 return cxstring::createRef("MemberRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004561 case CXCursor_LabelRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004562 return cxstring::createRef("LabelRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004563 case CXCursor_OverloadedDeclRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004564 return cxstring::createRef("OverloadedDeclRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004565 case CXCursor_VariableRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004566 return cxstring::createRef("VariableRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004567 case CXCursor_IntegerLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004568 return cxstring::createRef("IntegerLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00004569 case CXCursor_FloatingLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004570 return cxstring::createRef("FloatingLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00004571 case CXCursor_ImaginaryLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004572 return cxstring::createRef("ImaginaryLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00004573 case CXCursor_StringLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004574 return cxstring::createRef("StringLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00004575 case CXCursor_CharacterLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004576 return cxstring::createRef("CharacterLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00004577 case CXCursor_ParenExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004578 return cxstring::createRef("ParenExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004579 case CXCursor_UnaryOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004580 return cxstring::createRef("UnaryOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00004581 case CXCursor_ArraySubscriptExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004582 return cxstring::createRef("ArraySubscriptExpr");
Alexey Bataev1a3320e2015-08-25 14:24:04 +00004583 case CXCursor_OMPArraySectionExpr:
4584 return cxstring::createRef("OMPArraySectionExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004585 case CXCursor_BinaryOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004586 return cxstring::createRef("BinaryOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00004587 case CXCursor_CompoundAssignOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004588 return cxstring::createRef("CompoundAssignOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00004589 case CXCursor_ConditionalOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004590 return cxstring::createRef("ConditionalOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00004591 case CXCursor_CStyleCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004592 return cxstring::createRef("CStyleCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004593 case CXCursor_CompoundLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004594 return cxstring::createRef("CompoundLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004595 case CXCursor_InitListExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004596 return cxstring::createRef("InitListExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004597 case CXCursor_AddrLabelExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004598 return cxstring::createRef("AddrLabelExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004599 case CXCursor_StmtExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004600 return cxstring::createRef("StmtExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004601 case CXCursor_GenericSelectionExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004602 return cxstring::createRef("GenericSelectionExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004603 case CXCursor_GNUNullExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004604 return cxstring::createRef("GNUNullExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004605 case CXCursor_CXXStaticCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004606 return cxstring::createRef("CXXStaticCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004607 case CXCursor_CXXDynamicCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004608 return cxstring::createRef("CXXDynamicCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004609 case CXCursor_CXXReinterpretCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004610 return cxstring::createRef("CXXReinterpretCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004611 case CXCursor_CXXConstCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004612 return cxstring::createRef("CXXConstCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004613 case CXCursor_CXXFunctionalCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004614 return cxstring::createRef("CXXFunctionalCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004615 case CXCursor_CXXTypeidExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004616 return cxstring::createRef("CXXTypeidExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004617 case CXCursor_CXXBoolLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004618 return cxstring::createRef("CXXBoolLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004619 case CXCursor_CXXNullPtrLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004620 return cxstring::createRef("CXXNullPtrLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004621 case CXCursor_CXXThisExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004622 return cxstring::createRef("CXXThisExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004623 case CXCursor_CXXThrowExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004624 return cxstring::createRef("CXXThrowExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004625 case CXCursor_CXXNewExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004626 return cxstring::createRef("CXXNewExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004627 case CXCursor_CXXDeleteExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004628 return cxstring::createRef("CXXDeleteExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004629 case CXCursor_UnaryExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004630 return cxstring::createRef("UnaryExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004631 case CXCursor_ObjCStringLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004632 return cxstring::createRef("ObjCStringLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00004633 case CXCursor_ObjCBoolLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004634 return cxstring::createRef("ObjCBoolLiteralExpr");
Argyrios Kyrtzidisc2233be2013-04-23 17:57:17 +00004635 case CXCursor_ObjCSelfExpr:
4636 return cxstring::createRef("ObjCSelfExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004637 case CXCursor_ObjCEncodeExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004638 return cxstring::createRef("ObjCEncodeExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004639 case CXCursor_ObjCSelectorExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004640 return cxstring::createRef("ObjCSelectorExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004641 case CXCursor_ObjCProtocolExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004642 return cxstring::createRef("ObjCProtocolExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004643 case CXCursor_ObjCBridgedCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004644 return cxstring::createRef("ObjCBridgedCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004645 case CXCursor_BlockExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004646 return cxstring::createRef("BlockExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004647 case CXCursor_PackExpansionExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004648 return cxstring::createRef("PackExpansionExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004649 case CXCursor_SizeOfPackExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004650 return cxstring::createRef("SizeOfPackExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004651 case CXCursor_LambdaExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004652 return cxstring::createRef("LambdaExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004653 case CXCursor_UnexposedExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004654 return cxstring::createRef("UnexposedExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004655 case CXCursor_DeclRefExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004656 return cxstring::createRef("DeclRefExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004657 case CXCursor_MemberRefExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004658 return cxstring::createRef("MemberRefExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004659 case CXCursor_CallExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004660 return cxstring::createRef("CallExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004661 case CXCursor_ObjCMessageExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004662 return cxstring::createRef("ObjCMessageExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004663 case CXCursor_UnexposedStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004664 return cxstring::createRef("UnexposedStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004665 case CXCursor_DeclStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004666 return cxstring::createRef("DeclStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004667 case CXCursor_LabelStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004668 return cxstring::createRef("LabelStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004669 case CXCursor_CompoundStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004670 return cxstring::createRef("CompoundStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004671 case CXCursor_CaseStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004672 return cxstring::createRef("CaseStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004673 case CXCursor_DefaultStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004674 return cxstring::createRef("DefaultStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004675 case CXCursor_IfStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004676 return cxstring::createRef("IfStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004677 case CXCursor_SwitchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004678 return cxstring::createRef("SwitchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004679 case CXCursor_WhileStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004680 return cxstring::createRef("WhileStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004681 case CXCursor_DoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004682 return cxstring::createRef("DoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004683 case CXCursor_ForStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004684 return cxstring::createRef("ForStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004685 case CXCursor_GotoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004686 return cxstring::createRef("GotoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004687 case CXCursor_IndirectGotoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004688 return cxstring::createRef("IndirectGotoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004689 case CXCursor_ContinueStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004690 return cxstring::createRef("ContinueStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004691 case CXCursor_BreakStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004692 return cxstring::createRef("BreakStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004693 case CXCursor_ReturnStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004694 return cxstring::createRef("ReturnStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004695 case CXCursor_GCCAsmStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004696 return cxstring::createRef("GCCAsmStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004697 case CXCursor_MSAsmStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004698 return cxstring::createRef("MSAsmStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004699 case CXCursor_ObjCAtTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004700 return cxstring::createRef("ObjCAtTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004701 case CXCursor_ObjCAtCatchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004702 return cxstring::createRef("ObjCAtCatchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004703 case CXCursor_ObjCAtFinallyStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004704 return cxstring::createRef("ObjCAtFinallyStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004705 case CXCursor_ObjCAtThrowStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004706 return cxstring::createRef("ObjCAtThrowStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004707 case CXCursor_ObjCAtSynchronizedStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004708 return cxstring::createRef("ObjCAtSynchronizedStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004709 case CXCursor_ObjCAutoreleasePoolStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004710 return cxstring::createRef("ObjCAutoreleasePoolStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004711 case CXCursor_ObjCForCollectionStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004712 return cxstring::createRef("ObjCForCollectionStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004713 case CXCursor_CXXCatchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004714 return cxstring::createRef("CXXCatchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004715 case CXCursor_CXXTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004716 return cxstring::createRef("CXXTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004717 case CXCursor_CXXForRangeStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004718 return cxstring::createRef("CXXForRangeStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004719 case CXCursor_SEHTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004720 return cxstring::createRef("SEHTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004721 case CXCursor_SEHExceptStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004722 return cxstring::createRef("SEHExceptStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004723 case CXCursor_SEHFinallyStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004724 return cxstring::createRef("SEHFinallyStmt");
Nico Weber9b982072014-07-07 00:12:30 +00004725 case CXCursor_SEHLeaveStmt:
4726 return cxstring::createRef("SEHLeaveStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004727 case CXCursor_NullStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004728 return cxstring::createRef("NullStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004729 case CXCursor_InvalidFile:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004730 return cxstring::createRef("InvalidFile");
Guy Benyei11169dd2012-12-18 14:30:41 +00004731 case CXCursor_InvalidCode:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004732 return cxstring::createRef("InvalidCode");
Guy Benyei11169dd2012-12-18 14:30:41 +00004733 case CXCursor_NoDeclFound:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004734 return cxstring::createRef("NoDeclFound");
Guy Benyei11169dd2012-12-18 14:30:41 +00004735 case CXCursor_NotImplemented:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004736 return cxstring::createRef("NotImplemented");
Guy Benyei11169dd2012-12-18 14:30:41 +00004737 case CXCursor_TranslationUnit:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004738 return cxstring::createRef("TranslationUnit");
Guy Benyei11169dd2012-12-18 14:30:41 +00004739 case CXCursor_UnexposedAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004740 return cxstring::createRef("UnexposedAttr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004741 case CXCursor_IBActionAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004742 return cxstring::createRef("attribute(ibaction)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004743 case CXCursor_IBOutletAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004744 return cxstring::createRef("attribute(iboutlet)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004745 case CXCursor_IBOutletCollectionAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004746 return cxstring::createRef("attribute(iboutletcollection)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004747 case CXCursor_CXXFinalAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004748 return cxstring::createRef("attribute(final)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004749 case CXCursor_CXXOverrideAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004750 return cxstring::createRef("attribute(override)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004751 case CXCursor_AnnotateAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004752 return cxstring::createRef("attribute(annotate)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004753 case CXCursor_AsmLabelAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004754 return cxstring::createRef("asm label");
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00004755 case CXCursor_PackedAttr:
4756 return cxstring::createRef("attribute(packed)");
Joey Gouly81228382014-05-01 15:41:58 +00004757 case CXCursor_PureAttr:
4758 return cxstring::createRef("attribute(pure)");
4759 case CXCursor_ConstAttr:
4760 return cxstring::createRef("attribute(const)");
4761 case CXCursor_NoDuplicateAttr:
4762 return cxstring::createRef("attribute(noduplicate)");
Eli Bendersky2581e662014-05-28 19:29:58 +00004763 case CXCursor_CUDAConstantAttr:
4764 return cxstring::createRef("attribute(constant)");
4765 case CXCursor_CUDADeviceAttr:
4766 return cxstring::createRef("attribute(device)");
4767 case CXCursor_CUDAGlobalAttr:
4768 return cxstring::createRef("attribute(global)");
4769 case CXCursor_CUDAHostAttr:
4770 return cxstring::createRef("attribute(host)");
Eli Bendersky9b071472014-08-08 14:59:00 +00004771 case CXCursor_CUDASharedAttr:
4772 return cxstring::createRef("attribute(shared)");
Saleem Abdulrasool79c69712015-09-05 18:53:43 +00004773 case CXCursor_VisibilityAttr:
4774 return cxstring::createRef("attribute(visibility)");
Saleem Abdulrasool8aa0b802015-12-10 18:45:18 +00004775 case CXCursor_DLLExport:
4776 return cxstring::createRef("attribute(dllexport)");
4777 case CXCursor_DLLImport:
4778 return cxstring::createRef("attribute(dllimport)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004779 case CXCursor_PreprocessingDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004780 return cxstring::createRef("preprocessing directive");
Guy Benyei11169dd2012-12-18 14:30:41 +00004781 case CXCursor_MacroDefinition:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004782 return cxstring::createRef("macro definition");
Guy Benyei11169dd2012-12-18 14:30:41 +00004783 case CXCursor_MacroExpansion:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004784 return cxstring::createRef("macro expansion");
Guy Benyei11169dd2012-12-18 14:30:41 +00004785 case CXCursor_InclusionDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004786 return cxstring::createRef("inclusion directive");
Guy Benyei11169dd2012-12-18 14:30:41 +00004787 case CXCursor_Namespace:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004788 return cxstring::createRef("Namespace");
Guy Benyei11169dd2012-12-18 14:30:41 +00004789 case CXCursor_LinkageSpec:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004790 return cxstring::createRef("LinkageSpec");
Guy Benyei11169dd2012-12-18 14:30:41 +00004791 case CXCursor_CXXBaseSpecifier:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004792 return cxstring::createRef("C++ base class specifier");
Guy Benyei11169dd2012-12-18 14:30:41 +00004793 case CXCursor_Constructor:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004794 return cxstring::createRef("CXXConstructor");
Guy Benyei11169dd2012-12-18 14:30:41 +00004795 case CXCursor_Destructor:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004796 return cxstring::createRef("CXXDestructor");
Guy Benyei11169dd2012-12-18 14:30:41 +00004797 case CXCursor_ConversionFunction:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004798 return cxstring::createRef("CXXConversion");
Guy Benyei11169dd2012-12-18 14:30:41 +00004799 case CXCursor_TemplateTypeParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004800 return cxstring::createRef("TemplateTypeParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00004801 case CXCursor_NonTypeTemplateParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004802 return cxstring::createRef("NonTypeTemplateParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00004803 case CXCursor_TemplateTemplateParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004804 return cxstring::createRef("TemplateTemplateParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00004805 case CXCursor_FunctionTemplate:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004806 return cxstring::createRef("FunctionTemplate");
Guy Benyei11169dd2012-12-18 14:30:41 +00004807 case CXCursor_ClassTemplate:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004808 return cxstring::createRef("ClassTemplate");
Guy Benyei11169dd2012-12-18 14:30:41 +00004809 case CXCursor_ClassTemplatePartialSpecialization:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004810 return cxstring::createRef("ClassTemplatePartialSpecialization");
Guy Benyei11169dd2012-12-18 14:30:41 +00004811 case CXCursor_NamespaceAlias:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004812 return cxstring::createRef("NamespaceAlias");
Guy Benyei11169dd2012-12-18 14:30:41 +00004813 case CXCursor_UsingDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004814 return cxstring::createRef("UsingDirective");
Guy Benyei11169dd2012-12-18 14:30:41 +00004815 case CXCursor_UsingDeclaration:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004816 return cxstring::createRef("UsingDeclaration");
Guy Benyei11169dd2012-12-18 14:30:41 +00004817 case CXCursor_TypeAliasDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004818 return cxstring::createRef("TypeAliasDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004819 case CXCursor_ObjCSynthesizeDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004820 return cxstring::createRef("ObjCSynthesizeDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004821 case CXCursor_ObjCDynamicDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004822 return cxstring::createRef("ObjCDynamicDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004823 case CXCursor_CXXAccessSpecifier:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004824 return cxstring::createRef("CXXAccessSpecifier");
Guy Benyei11169dd2012-12-18 14:30:41 +00004825 case CXCursor_ModuleImportDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004826 return cxstring::createRef("ModuleImport");
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00004827 case CXCursor_OMPParallelDirective:
Alexey Bataev1b59ab52014-02-27 08:29:12 +00004828 return cxstring::createRef("OMPParallelDirective");
4829 case CXCursor_OMPSimdDirective:
4830 return cxstring::createRef("OMPSimdDirective");
Alexey Bataevf29276e2014-06-18 04:14:57 +00004831 case CXCursor_OMPForDirective:
4832 return cxstring::createRef("OMPForDirective");
Alexander Musmanf82886e2014-09-18 05:12:34 +00004833 case CXCursor_OMPForSimdDirective:
4834 return cxstring::createRef("OMPForSimdDirective");
Alexey Bataevd3f8dd22014-06-25 11:44:49 +00004835 case CXCursor_OMPSectionsDirective:
4836 return cxstring::createRef("OMPSectionsDirective");
Alexey Bataev1e0498a2014-06-26 08:21:58 +00004837 case CXCursor_OMPSectionDirective:
4838 return cxstring::createRef("OMPSectionDirective");
Alexey Bataevd1e40fb2014-06-26 12:05:45 +00004839 case CXCursor_OMPSingleDirective:
4840 return cxstring::createRef("OMPSingleDirective");
Alexander Musman80c22892014-07-17 08:54:58 +00004841 case CXCursor_OMPMasterDirective:
4842 return cxstring::createRef("OMPMasterDirective");
Alexander Musmand9ed09f2014-07-21 09:42:05 +00004843 case CXCursor_OMPCriticalDirective:
4844 return cxstring::createRef("OMPCriticalDirective");
Alexey Bataev4acb8592014-07-07 13:01:15 +00004845 case CXCursor_OMPParallelForDirective:
4846 return cxstring::createRef("OMPParallelForDirective");
Alexander Musmane4e893b2014-09-23 09:33:00 +00004847 case CXCursor_OMPParallelForSimdDirective:
4848 return cxstring::createRef("OMPParallelForSimdDirective");
Alexey Bataev84d0b3e2014-07-08 08:12:03 +00004849 case CXCursor_OMPParallelSectionsDirective:
4850 return cxstring::createRef("OMPParallelSectionsDirective");
Alexey Bataev9c2e8ee2014-07-11 11:25:16 +00004851 case CXCursor_OMPTaskDirective:
4852 return cxstring::createRef("OMPTaskDirective");
Alexey Bataev68446b72014-07-18 07:47:19 +00004853 case CXCursor_OMPTaskyieldDirective:
4854 return cxstring::createRef("OMPTaskyieldDirective");
Alexey Bataev4d1dfea2014-07-18 09:11:51 +00004855 case CXCursor_OMPBarrierDirective:
4856 return cxstring::createRef("OMPBarrierDirective");
Alexey Bataev2df347a2014-07-18 10:17:07 +00004857 case CXCursor_OMPTaskwaitDirective:
4858 return cxstring::createRef("OMPTaskwaitDirective");
Alexey Bataevc30dd2d2015-06-18 12:14:09 +00004859 case CXCursor_OMPTaskgroupDirective:
4860 return cxstring::createRef("OMPTaskgroupDirective");
Alexey Bataev6125da92014-07-21 11:26:11 +00004861 case CXCursor_OMPFlushDirective:
4862 return cxstring::createRef("OMPFlushDirective");
Alexey Bataev9fb6e642014-07-22 06:45:04 +00004863 case CXCursor_OMPOrderedDirective:
4864 return cxstring::createRef("OMPOrderedDirective");
Alexey Bataev0162e452014-07-22 10:10:35 +00004865 case CXCursor_OMPAtomicDirective:
4866 return cxstring::createRef("OMPAtomicDirective");
Alexey Bataev0bd520b2014-09-19 08:19:49 +00004867 case CXCursor_OMPTargetDirective:
4868 return cxstring::createRef("OMPTargetDirective");
Michael Wong65f367f2015-07-21 13:44:28 +00004869 case CXCursor_OMPTargetDataDirective:
4870 return cxstring::createRef("OMPTargetDataDirective");
Samuel Antaodf67fc42016-01-19 19:15:56 +00004871 case CXCursor_OMPTargetEnterDataDirective:
4872 return cxstring::createRef("OMPTargetEnterDataDirective");
Samuel Antao72590762016-01-19 20:04:50 +00004873 case CXCursor_OMPTargetExitDataDirective:
4874 return cxstring::createRef("OMPTargetExitDataDirective");
Arpith Chacko Jacobe955b3d2016-01-26 18:48:41 +00004875 case CXCursor_OMPTargetParallelDirective:
4876 return cxstring::createRef("OMPTargetParallelDirective");
Arpith Chacko Jacob05bebb52016-02-03 15:46:42 +00004877 case CXCursor_OMPTargetParallelForDirective:
4878 return cxstring::createRef("OMPTargetParallelForDirective");
Alexey Bataev13314bf2014-10-09 04:18:56 +00004879 case CXCursor_OMPTeamsDirective:
4880 return cxstring::createRef("OMPTeamsDirective");
Alexey Bataev6d4ed052015-07-01 06:57:41 +00004881 case CXCursor_OMPCancellationPointDirective:
4882 return cxstring::createRef("OMPCancellationPointDirective");
Alexey Bataev80909872015-07-02 11:25:17 +00004883 case CXCursor_OMPCancelDirective:
4884 return cxstring::createRef("OMPCancelDirective");
Alexey Bataev49f6e782015-12-01 04:18:41 +00004885 case CXCursor_OMPTaskLoopDirective:
4886 return cxstring::createRef("OMPTaskLoopDirective");
Alexey Bataev0a6ed842015-12-03 09:40:15 +00004887 case CXCursor_OMPTaskLoopSimdDirective:
4888 return cxstring::createRef("OMPTaskLoopSimdDirective");
Carlo Bertolli6200a3d2015-12-14 14:51:25 +00004889 case CXCursor_OMPDistributeDirective:
4890 return cxstring::createRef("OMPDistributeDirective");
Francisco Lopes da Silva975a9f62015-01-21 16:24:11 +00004891 case CXCursor_OverloadCandidate:
4892 return cxstring::createRef("OverloadCandidate");
Sergey Kalinichev8f3b1872015-11-15 13:48:32 +00004893 case CXCursor_TypeAliasTemplateDecl:
4894 return cxstring::createRef("TypeAliasTemplateDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004895 }
4896
4897 llvm_unreachable("Unhandled CXCursorKind");
4898}
4899
4900struct GetCursorData {
4901 SourceLocation TokenBeginLoc;
4902 bool PointsAtMacroArgExpansion;
4903 bool VisitedObjCPropertyImplDecl;
4904 SourceLocation VisitedDeclaratorDeclStartLoc;
4905 CXCursor &BestCursor;
4906
4907 GetCursorData(SourceManager &SM,
4908 SourceLocation tokenBegin, CXCursor &outputCursor)
4909 : TokenBeginLoc(tokenBegin), BestCursor(outputCursor) {
4910 PointsAtMacroArgExpansion = SM.isMacroArgExpansion(tokenBegin);
4911 VisitedObjCPropertyImplDecl = false;
4912 }
4913};
4914
4915static enum CXChildVisitResult GetCursorVisitor(CXCursor cursor,
4916 CXCursor parent,
4917 CXClientData client_data) {
4918 GetCursorData *Data = static_cast<GetCursorData *>(client_data);
4919 CXCursor *BestCursor = &Data->BestCursor;
4920
4921 // If we point inside a macro argument we should provide info of what the
4922 // token is so use the actual cursor, don't replace it with a macro expansion
4923 // cursor.
4924 if (cursor.kind == CXCursor_MacroExpansion && Data->PointsAtMacroArgExpansion)
4925 return CXChildVisit_Recurse;
4926
4927 if (clang_isDeclaration(cursor.kind)) {
4928 // Avoid having the implicit methods override the property decls.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004929 if (const ObjCMethodDecl *MD
Guy Benyei11169dd2012-12-18 14:30:41 +00004930 = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
4931 if (MD->isImplicit())
4932 return CXChildVisit_Break;
4933
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004934 } else if (const ObjCInterfaceDecl *ID
Guy Benyei11169dd2012-12-18 14:30:41 +00004935 = dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(cursor))) {
4936 // Check that when we have multiple @class references in the same line,
4937 // that later ones do not override the previous ones.
4938 // If we have:
4939 // @class Foo, Bar;
4940 // source ranges for both start at '@', so 'Bar' will end up overriding
4941 // 'Foo' even though the cursor location was at 'Foo'.
4942 if (BestCursor->kind == CXCursor_ObjCInterfaceDecl ||
4943 BestCursor->kind == CXCursor_ObjCClassRef)
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004944 if (const ObjCInterfaceDecl *PrevID
Guy Benyei11169dd2012-12-18 14:30:41 +00004945 = dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(*BestCursor))){
4946 if (PrevID != ID &&
4947 !PrevID->isThisDeclarationADefinition() &&
4948 !ID->isThisDeclarationADefinition())
4949 return CXChildVisit_Break;
4950 }
4951
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004952 } else if (const DeclaratorDecl *DD
Guy Benyei11169dd2012-12-18 14:30:41 +00004953 = dyn_cast_or_null<DeclaratorDecl>(getCursorDecl(cursor))) {
4954 SourceLocation StartLoc = DD->getSourceRange().getBegin();
4955 // Check that when we have multiple declarators in the same line,
4956 // that later ones do not override the previous ones.
4957 // If we have:
4958 // int Foo, Bar;
4959 // source ranges for both start at 'int', so 'Bar' will end up overriding
4960 // 'Foo' even though the cursor location was at 'Foo'.
4961 if (Data->VisitedDeclaratorDeclStartLoc == StartLoc)
4962 return CXChildVisit_Break;
4963 Data->VisitedDeclaratorDeclStartLoc = StartLoc;
4964
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004965 } else if (const ObjCPropertyImplDecl *PropImp
Guy Benyei11169dd2012-12-18 14:30:41 +00004966 = dyn_cast_or_null<ObjCPropertyImplDecl>(getCursorDecl(cursor))) {
4967 (void)PropImp;
4968 // Check that when we have multiple @synthesize in the same line,
4969 // that later ones do not override the previous ones.
4970 // If we have:
4971 // @synthesize Foo, Bar;
4972 // source ranges for both start at '@', so 'Bar' will end up overriding
4973 // 'Foo' even though the cursor location was at 'Foo'.
4974 if (Data->VisitedObjCPropertyImplDecl)
4975 return CXChildVisit_Break;
4976 Data->VisitedObjCPropertyImplDecl = true;
4977 }
4978 }
4979
4980 if (clang_isExpression(cursor.kind) &&
4981 clang_isDeclaration(BestCursor->kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004982 if (const Decl *D = getCursorDecl(*BestCursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004983 // Avoid having the cursor of an expression replace the declaration cursor
4984 // when the expression source range overlaps the declaration range.
4985 // This can happen for C++ constructor expressions whose range generally
4986 // include the variable declaration, e.g.:
4987 // MyCXXClass foo; // Make sure pointing at 'foo' returns a VarDecl cursor.
4988 if (D->getLocation().isValid() && Data->TokenBeginLoc.isValid() &&
4989 D->getLocation() == Data->TokenBeginLoc)
4990 return CXChildVisit_Break;
4991 }
4992 }
4993
4994 // If our current best cursor is the construction of a temporary object,
4995 // don't replace that cursor with a type reference, because we want
4996 // clang_getCursor() to point at the constructor.
4997 if (clang_isExpression(BestCursor->kind) &&
4998 isa<CXXTemporaryObjectExpr>(getCursorExpr(*BestCursor)) &&
4999 cursor.kind == CXCursor_TypeRef) {
5000 // Keep the cursor pointing at CXXTemporaryObjectExpr but also mark it
5001 // as having the actual point on the type reference.
5002 *BestCursor = getTypeRefedCallExprCursor(*BestCursor);
5003 return CXChildVisit_Recurse;
5004 }
Douglas Gregore9d95f12015-07-07 03:57:35 +00005005
5006 // If we already have an Objective-C superclass reference, don't
5007 // update it further.
5008 if (BestCursor->kind == CXCursor_ObjCSuperClassRef)
5009 return CXChildVisit_Break;
5010
Guy Benyei11169dd2012-12-18 14:30:41 +00005011 *BestCursor = cursor;
5012 return CXChildVisit_Recurse;
5013}
5014
5015CXCursor clang_getCursor(CXTranslationUnit TU, CXSourceLocation Loc) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005016 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005017 LOG_BAD_TU(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005018 return clang_getNullCursor();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005019 }
Guy Benyei11169dd2012-12-18 14:30:41 +00005020
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005021 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005022 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
5023
5024 SourceLocation SLoc = cxloc::translateSourceLocation(Loc);
5025 CXCursor Result = cxcursor::getCursor(TU, SLoc);
5026
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00005027 LOG_FUNC_SECTION {
Guy Benyei11169dd2012-12-18 14:30:41 +00005028 CXFile SearchFile;
5029 unsigned SearchLine, SearchColumn;
5030 CXFile ResultFile;
5031 unsigned ResultLine, ResultColumn;
5032 CXString SearchFileName, ResultFileName, KindSpelling, USR;
5033 const char *IsDef = clang_isCursorDefinition(Result)? " (Definition)" : "";
5034 CXSourceLocation ResultLoc = clang_getCursorLocation(Result);
Craig Topper69186e72014-06-08 08:38:04 +00005035
5036 clang_getFileLocation(Loc, &SearchFile, &SearchLine, &SearchColumn,
5037 nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00005038 clang_getFileLocation(ResultLoc, &ResultFile, &ResultLine,
Craig Topper69186e72014-06-08 08:38:04 +00005039 &ResultColumn, nullptr);
Guy Benyei11169dd2012-12-18 14:30:41 +00005040 SearchFileName = clang_getFileName(SearchFile);
5041 ResultFileName = clang_getFileName(ResultFile);
5042 KindSpelling = clang_getCursorKindSpelling(Result.kind);
5043 USR = clang_getCursorUSR(Result);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00005044 *Log << llvm::format("(%s:%d:%d) = %s",
5045 clang_getCString(SearchFileName), SearchLine, SearchColumn,
5046 clang_getCString(KindSpelling))
5047 << llvm::format("(%s:%d:%d):%s%s",
5048 clang_getCString(ResultFileName), ResultLine, ResultColumn,
5049 clang_getCString(USR), IsDef);
Guy Benyei11169dd2012-12-18 14:30:41 +00005050 clang_disposeString(SearchFileName);
5051 clang_disposeString(ResultFileName);
5052 clang_disposeString(KindSpelling);
5053 clang_disposeString(USR);
5054
5055 CXCursor Definition = clang_getCursorDefinition(Result);
5056 if (!clang_equalCursors(Definition, clang_getNullCursor())) {
5057 CXSourceLocation DefinitionLoc = clang_getCursorLocation(Definition);
5058 CXString DefinitionKindSpelling
5059 = clang_getCursorKindSpelling(Definition.kind);
5060 CXFile DefinitionFile;
5061 unsigned DefinitionLine, DefinitionColumn;
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00005062 clang_getFileLocation(DefinitionLoc, &DefinitionFile,
Craig Topper69186e72014-06-08 08:38:04 +00005063 &DefinitionLine, &DefinitionColumn, nullptr);
Guy Benyei11169dd2012-12-18 14:30:41 +00005064 CXString DefinitionFileName = clang_getFileName(DefinitionFile);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00005065 *Log << llvm::format(" -> %s(%s:%d:%d)",
5066 clang_getCString(DefinitionKindSpelling),
5067 clang_getCString(DefinitionFileName),
5068 DefinitionLine, DefinitionColumn);
Guy Benyei11169dd2012-12-18 14:30:41 +00005069 clang_disposeString(DefinitionFileName);
5070 clang_disposeString(DefinitionKindSpelling);
5071 }
5072 }
5073
5074 return Result;
5075}
5076
5077CXCursor clang_getNullCursor(void) {
5078 return MakeCXCursorInvalid(CXCursor_InvalidFile);
5079}
5080
5081unsigned clang_equalCursors(CXCursor X, CXCursor Y) {
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00005082 // Clear out the "FirstInDeclGroup" part in a declaration cursor, since we
5083 // can't set consistently. For example, when visiting a DeclStmt we will set
5084 // it but we don't set it on the result of clang_getCursorDefinition for
5085 // a reference of the same declaration.
5086 // FIXME: Setting "FirstInDeclGroup" in CXCursors is a hack that only works
5087 // when visiting a DeclStmt currently, the AST should be enhanced to be able
5088 // to provide that kind of info.
5089 if (clang_isDeclaration(X.kind))
Craig Topper69186e72014-06-08 08:38:04 +00005090 X.data[1] = nullptr;
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00005091 if (clang_isDeclaration(Y.kind))
Craig Topper69186e72014-06-08 08:38:04 +00005092 Y.data[1] = nullptr;
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00005093
Guy Benyei11169dd2012-12-18 14:30:41 +00005094 return X == Y;
5095}
5096
5097unsigned clang_hashCursor(CXCursor C) {
5098 unsigned Index = 0;
5099 if (clang_isExpression(C.kind) || clang_isStatement(C.kind))
5100 Index = 1;
5101
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005102 return llvm::DenseMapInfo<std::pair<unsigned, const void*> >::getHashValue(
Guy Benyei11169dd2012-12-18 14:30:41 +00005103 std::make_pair(C.kind, C.data[Index]));
5104}
5105
5106unsigned clang_isInvalid(enum CXCursorKind K) {
5107 return K >= CXCursor_FirstInvalid && K <= CXCursor_LastInvalid;
5108}
5109
5110unsigned clang_isDeclaration(enum CXCursorKind K) {
5111 return (K >= CXCursor_FirstDecl && K <= CXCursor_LastDecl) ||
5112 (K >= CXCursor_FirstExtraDecl && K <= CXCursor_LastExtraDecl);
5113}
5114
5115unsigned clang_isReference(enum CXCursorKind K) {
5116 return K >= CXCursor_FirstRef && K <= CXCursor_LastRef;
5117}
5118
5119unsigned clang_isExpression(enum CXCursorKind K) {
5120 return K >= CXCursor_FirstExpr && K <= CXCursor_LastExpr;
5121}
5122
5123unsigned clang_isStatement(enum CXCursorKind K) {
5124 return K >= CXCursor_FirstStmt && K <= CXCursor_LastStmt;
5125}
5126
5127unsigned clang_isAttribute(enum CXCursorKind K) {
5128 return K >= CXCursor_FirstAttr && K <= CXCursor_LastAttr;
5129}
5130
5131unsigned clang_isTranslationUnit(enum CXCursorKind K) {
5132 return K == CXCursor_TranslationUnit;
5133}
5134
5135unsigned clang_isPreprocessing(enum CXCursorKind K) {
5136 return K >= CXCursor_FirstPreprocessing && K <= CXCursor_LastPreprocessing;
5137}
5138
5139unsigned clang_isUnexposed(enum CXCursorKind K) {
5140 switch (K) {
5141 case CXCursor_UnexposedDecl:
5142 case CXCursor_UnexposedExpr:
5143 case CXCursor_UnexposedStmt:
5144 case CXCursor_UnexposedAttr:
5145 return true;
5146 default:
5147 return false;
5148 }
5149}
5150
5151CXCursorKind clang_getCursorKind(CXCursor C) {
5152 return C.kind;
5153}
5154
5155CXSourceLocation clang_getCursorLocation(CXCursor C) {
5156 if (clang_isReference(C.kind)) {
5157 switch (C.kind) {
5158 case CXCursor_ObjCSuperClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005159 std::pair<const ObjCInterfaceDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00005160 = getCursorObjCSuperClassRef(C);
5161 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
5162 }
5163
5164 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005165 std::pair<const ObjCProtocolDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00005166 = getCursorObjCProtocolRef(C);
5167 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
5168 }
5169
5170 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005171 std::pair<const ObjCInterfaceDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00005172 = getCursorObjCClassRef(C);
5173 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
5174 }
5175
5176 case CXCursor_TypeRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005177 std::pair<const TypeDecl *, SourceLocation> P = getCursorTypeRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005178 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
5179 }
5180
5181 case CXCursor_TemplateRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005182 std::pair<const TemplateDecl *, SourceLocation> P =
5183 getCursorTemplateRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005184 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
5185 }
5186
5187 case CXCursor_NamespaceRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005188 std::pair<const NamedDecl *, SourceLocation> P = getCursorNamespaceRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005189 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
5190 }
5191
5192 case CXCursor_MemberRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005193 std::pair<const FieldDecl *, SourceLocation> P = getCursorMemberRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005194 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
5195 }
5196
5197 case CXCursor_VariableRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005198 std::pair<const VarDecl *, SourceLocation> P = getCursorVariableRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005199 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
5200 }
5201
5202 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005203 const CXXBaseSpecifier *BaseSpec = getCursorCXXBaseSpecifier(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005204 if (!BaseSpec)
5205 return clang_getNullLocation();
5206
5207 if (TypeSourceInfo *TSInfo = BaseSpec->getTypeSourceInfo())
5208 return cxloc::translateSourceLocation(getCursorContext(C),
5209 TSInfo->getTypeLoc().getBeginLoc());
5210
5211 return cxloc::translateSourceLocation(getCursorContext(C),
5212 BaseSpec->getLocStart());
5213 }
5214
5215 case CXCursor_LabelRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005216 std::pair<const LabelStmt *, SourceLocation> P = getCursorLabelRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005217 return cxloc::translateSourceLocation(getCursorContext(C), P.second);
5218 }
5219
5220 case CXCursor_OverloadedDeclRef:
5221 return cxloc::translateSourceLocation(getCursorContext(C),
5222 getCursorOverloadedDeclRef(C).second);
5223
5224 default:
5225 // FIXME: Need a way to enumerate all non-reference cases.
5226 llvm_unreachable("Missed a reference kind");
5227 }
5228 }
5229
5230 if (clang_isExpression(C.kind))
5231 return cxloc::translateSourceLocation(getCursorContext(C),
5232 getLocationFromExpr(getCursorExpr(C)));
5233
5234 if (clang_isStatement(C.kind))
5235 return cxloc::translateSourceLocation(getCursorContext(C),
5236 getCursorStmt(C)->getLocStart());
5237
5238 if (C.kind == CXCursor_PreprocessingDirective) {
5239 SourceLocation L = cxcursor::getCursorPreprocessingDirective(C).getBegin();
5240 return cxloc::translateSourceLocation(getCursorContext(C), L);
5241 }
5242
5243 if (C.kind == CXCursor_MacroExpansion) {
5244 SourceLocation L
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00005245 = cxcursor::getCursorMacroExpansion(C).getSourceRange().getBegin();
Guy Benyei11169dd2012-12-18 14:30:41 +00005246 return cxloc::translateSourceLocation(getCursorContext(C), L);
5247 }
5248
5249 if (C.kind == CXCursor_MacroDefinition) {
5250 SourceLocation L = cxcursor::getCursorMacroDefinition(C)->getLocation();
5251 return cxloc::translateSourceLocation(getCursorContext(C), L);
5252 }
5253
5254 if (C.kind == CXCursor_InclusionDirective) {
5255 SourceLocation L
5256 = cxcursor::getCursorInclusionDirective(C)->getSourceRange().getBegin();
5257 return cxloc::translateSourceLocation(getCursorContext(C), L);
5258 }
5259
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00005260 if (clang_isAttribute(C.kind)) {
5261 SourceLocation L
5262 = cxcursor::getCursorAttr(C)->getLocation();
5263 return cxloc::translateSourceLocation(getCursorContext(C), L);
5264 }
5265
Guy Benyei11169dd2012-12-18 14:30:41 +00005266 if (!clang_isDeclaration(C.kind))
5267 return clang_getNullLocation();
5268
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005269 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005270 if (!D)
5271 return clang_getNullLocation();
5272
5273 SourceLocation Loc = D->getLocation();
5274 // FIXME: Multiple variables declared in a single declaration
5275 // currently lack the information needed to correctly determine their
5276 // ranges when accounting for the type-specifier. We use context
5277 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
5278 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005279 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005280 if (!cxcursor::isFirstInDeclGroup(C))
5281 Loc = VD->getLocation();
5282 }
5283
5284 // For ObjC methods, give the start location of the method name.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005285 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00005286 Loc = MD->getSelectorStartLoc();
5287
5288 return cxloc::translateSourceLocation(getCursorContext(C), Loc);
5289}
5290
5291} // end extern "C"
5292
5293CXCursor cxcursor::getCursor(CXTranslationUnit TU, SourceLocation SLoc) {
5294 assert(TU);
5295
5296 // Guard against an invalid SourceLocation, or we may assert in one
5297 // of the following calls.
5298 if (SLoc.isInvalid())
5299 return clang_getNullCursor();
5300
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005301 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005302
5303 // Translate the given source location to make it point at the beginning of
5304 // the token under the cursor.
5305 SLoc = Lexer::GetBeginningOfToken(SLoc, CXXUnit->getSourceManager(),
5306 CXXUnit->getASTContext().getLangOpts());
5307
5308 CXCursor Result = MakeCXCursorInvalid(CXCursor_NoDeclFound);
5309 if (SLoc.isValid()) {
5310 GetCursorData ResultData(CXXUnit->getSourceManager(), SLoc, Result);
5311 CursorVisitor CursorVis(TU, GetCursorVisitor, &ResultData,
5312 /*VisitPreprocessorLast=*/true,
5313 /*VisitIncludedEntities=*/false,
5314 SourceLocation(SLoc));
5315 CursorVis.visitFileRegion();
5316 }
5317
5318 return Result;
5319}
5320
5321static SourceRange getRawCursorExtent(CXCursor C) {
5322 if (clang_isReference(C.kind)) {
5323 switch (C.kind) {
5324 case CXCursor_ObjCSuperClassRef:
5325 return getCursorObjCSuperClassRef(C).second;
5326
5327 case CXCursor_ObjCProtocolRef:
5328 return getCursorObjCProtocolRef(C).second;
5329
5330 case CXCursor_ObjCClassRef:
5331 return getCursorObjCClassRef(C).second;
5332
5333 case CXCursor_TypeRef:
5334 return getCursorTypeRef(C).second;
5335
5336 case CXCursor_TemplateRef:
5337 return getCursorTemplateRef(C).second;
5338
5339 case CXCursor_NamespaceRef:
5340 return getCursorNamespaceRef(C).second;
5341
5342 case CXCursor_MemberRef:
5343 return getCursorMemberRef(C).second;
5344
5345 case CXCursor_CXXBaseSpecifier:
5346 return getCursorCXXBaseSpecifier(C)->getSourceRange();
5347
5348 case CXCursor_LabelRef:
5349 return getCursorLabelRef(C).second;
5350
5351 case CXCursor_OverloadedDeclRef:
5352 return getCursorOverloadedDeclRef(C).second;
5353
5354 case CXCursor_VariableRef:
5355 return getCursorVariableRef(C).second;
5356
5357 default:
5358 // FIXME: Need a way to enumerate all non-reference cases.
5359 llvm_unreachable("Missed a reference kind");
5360 }
5361 }
5362
5363 if (clang_isExpression(C.kind))
5364 return getCursorExpr(C)->getSourceRange();
5365
5366 if (clang_isStatement(C.kind))
5367 return getCursorStmt(C)->getSourceRange();
5368
5369 if (clang_isAttribute(C.kind))
5370 return getCursorAttr(C)->getRange();
5371
5372 if (C.kind == CXCursor_PreprocessingDirective)
5373 return cxcursor::getCursorPreprocessingDirective(C);
5374
5375 if (C.kind == CXCursor_MacroExpansion) {
5376 ASTUnit *TU = getCursorASTUnit(C);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00005377 SourceRange Range = cxcursor::getCursorMacroExpansion(C).getSourceRange();
Guy Benyei11169dd2012-12-18 14:30:41 +00005378 return TU->mapRangeFromPreamble(Range);
5379 }
5380
5381 if (C.kind == CXCursor_MacroDefinition) {
5382 ASTUnit *TU = getCursorASTUnit(C);
5383 SourceRange Range = cxcursor::getCursorMacroDefinition(C)->getSourceRange();
5384 return TU->mapRangeFromPreamble(Range);
5385 }
5386
5387 if (C.kind == CXCursor_InclusionDirective) {
5388 ASTUnit *TU = getCursorASTUnit(C);
5389 SourceRange Range = cxcursor::getCursorInclusionDirective(C)->getSourceRange();
5390 return TU->mapRangeFromPreamble(Range);
5391 }
5392
5393 if (C.kind == CXCursor_TranslationUnit) {
5394 ASTUnit *TU = getCursorASTUnit(C);
5395 FileID MainID = TU->getSourceManager().getMainFileID();
5396 SourceLocation Start = TU->getSourceManager().getLocForStartOfFile(MainID);
5397 SourceLocation End = TU->getSourceManager().getLocForEndOfFile(MainID);
5398 return SourceRange(Start, End);
5399 }
5400
5401 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005402 const Decl *D = cxcursor::getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005403 if (!D)
5404 return SourceRange();
5405
5406 SourceRange R = D->getSourceRange();
5407 // FIXME: Multiple variables declared in a single declaration
5408 // currently lack the information needed to correctly determine their
5409 // ranges when accounting for the type-specifier. We use context
5410 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
5411 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005412 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005413 if (!cxcursor::isFirstInDeclGroup(C))
5414 R.setBegin(VD->getLocation());
5415 }
5416 return R;
5417 }
5418 return SourceRange();
5419}
5420
5421/// \brief Retrieves the "raw" cursor extent, which is then extended to include
5422/// the decl-specifier-seq for declarations.
5423static SourceRange getFullCursorExtent(CXCursor C, SourceManager &SrcMgr) {
5424 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005425 const Decl *D = cxcursor::getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005426 if (!D)
5427 return SourceRange();
5428
5429 SourceRange R = D->getSourceRange();
5430
5431 // Adjust the start of the location for declarations preceded by
5432 // declaration specifiers.
5433 SourceLocation StartLoc;
5434 if (const DeclaratorDecl *DD = dyn_cast<DeclaratorDecl>(D)) {
5435 if (TypeSourceInfo *TI = DD->getTypeSourceInfo())
5436 StartLoc = TI->getTypeLoc().getLocStart();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005437 } else if (const TypedefDecl *Typedef = dyn_cast<TypedefDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005438 if (TypeSourceInfo *TI = Typedef->getTypeSourceInfo())
5439 StartLoc = TI->getTypeLoc().getLocStart();
5440 }
5441
5442 if (StartLoc.isValid() && R.getBegin().isValid() &&
5443 SrcMgr.isBeforeInTranslationUnit(StartLoc, R.getBegin()))
5444 R.setBegin(StartLoc);
5445
5446 // FIXME: Multiple variables declared in a single declaration
5447 // currently lack the information needed to correctly determine their
5448 // ranges when accounting for the type-specifier. We use context
5449 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
5450 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005451 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005452 if (!cxcursor::isFirstInDeclGroup(C))
5453 R.setBegin(VD->getLocation());
5454 }
5455
5456 return R;
5457 }
5458
5459 return getRawCursorExtent(C);
5460}
5461
5462extern "C" {
5463
5464CXSourceRange clang_getCursorExtent(CXCursor C) {
5465 SourceRange R = getRawCursorExtent(C);
5466 if (R.isInvalid())
5467 return clang_getNullRange();
5468
5469 return cxloc::translateSourceRange(getCursorContext(C), R);
5470}
5471
5472CXCursor clang_getCursorReferenced(CXCursor C) {
5473 if (clang_isInvalid(C.kind))
5474 return clang_getNullCursor();
5475
5476 CXTranslationUnit tu = getCursorTU(C);
5477 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005478 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005479 if (!D)
5480 return clang_getNullCursor();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005481 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00005482 return MakeCursorOverloadedDeclRef(Using, D->getLocation(), tu);
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005483 if (const ObjCPropertyImplDecl *PropImpl =
5484 dyn_cast<ObjCPropertyImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00005485 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
5486 return MakeCXCursor(Property, tu);
5487
5488 return C;
5489 }
5490
5491 if (clang_isExpression(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005492 const Expr *E = getCursorExpr(C);
5493 const Decl *D = getDeclFromExpr(E);
Guy Benyei11169dd2012-12-18 14:30:41 +00005494 if (D) {
5495 CXCursor declCursor = MakeCXCursor(D, tu);
5496 declCursor = getSelectorIdentifierCursor(getSelectorIdentifierIndex(C),
5497 declCursor);
5498 return declCursor;
5499 }
5500
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005501 if (const OverloadExpr *Ovl = dyn_cast_or_null<OverloadExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00005502 return MakeCursorOverloadedDeclRef(Ovl, tu);
5503
5504 return clang_getNullCursor();
5505 }
5506
5507 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005508 const Stmt *S = getCursorStmt(C);
5509 if (const GotoStmt *Goto = dyn_cast_or_null<GotoStmt>(S))
Guy Benyei11169dd2012-12-18 14:30:41 +00005510 if (LabelDecl *label = Goto->getLabel())
5511 if (LabelStmt *labelS = label->getStmt())
5512 return MakeCXCursor(labelS, getCursorDecl(C), tu);
5513
5514 return clang_getNullCursor();
5515 }
Richard Smith66a81862015-05-04 02:25:31 +00005516
Guy Benyei11169dd2012-12-18 14:30:41 +00005517 if (C.kind == CXCursor_MacroExpansion) {
Richard Smith66a81862015-05-04 02:25:31 +00005518 if (const MacroDefinitionRecord *Def =
5519 getCursorMacroExpansion(C).getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005520 return MakeMacroDefinitionCursor(Def, tu);
5521 }
5522
5523 if (!clang_isReference(C.kind))
5524 return clang_getNullCursor();
5525
5526 switch (C.kind) {
5527 case CXCursor_ObjCSuperClassRef:
5528 return MakeCXCursor(getCursorObjCSuperClassRef(C).first, tu);
5529
5530 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005531 const ObjCProtocolDecl *Prot = getCursorObjCProtocolRef(C).first;
5532 if (const ObjCProtocolDecl *Def = Prot->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005533 return MakeCXCursor(Def, tu);
5534
5535 return MakeCXCursor(Prot, tu);
5536 }
5537
5538 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005539 const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
5540 if (const ObjCInterfaceDecl *Def = Class->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005541 return MakeCXCursor(Def, tu);
5542
5543 return MakeCXCursor(Class, tu);
5544 }
5545
5546 case CXCursor_TypeRef:
5547 return MakeCXCursor(getCursorTypeRef(C).first, tu );
5548
5549 case CXCursor_TemplateRef:
5550 return MakeCXCursor(getCursorTemplateRef(C).first, tu );
5551
5552 case CXCursor_NamespaceRef:
5553 return MakeCXCursor(getCursorNamespaceRef(C).first, tu );
5554
5555 case CXCursor_MemberRef:
5556 return MakeCXCursor(getCursorMemberRef(C).first, tu );
5557
5558 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005559 const CXXBaseSpecifier *B = cxcursor::getCursorCXXBaseSpecifier(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005560 return clang_getTypeDeclaration(cxtype::MakeCXType(B->getType(),
5561 tu ));
5562 }
5563
5564 case CXCursor_LabelRef:
5565 // FIXME: We end up faking the "parent" declaration here because we
5566 // don't want to make CXCursor larger.
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005567 return MakeCXCursor(getCursorLabelRef(C).first,
5568 cxtu::getASTUnit(tu)->getASTContext()
5569 .getTranslationUnitDecl(),
Guy Benyei11169dd2012-12-18 14:30:41 +00005570 tu);
5571
5572 case CXCursor_OverloadedDeclRef:
5573 return C;
5574
5575 case CXCursor_VariableRef:
5576 return MakeCXCursor(getCursorVariableRef(C).first, tu);
5577
5578 default:
5579 // We would prefer to enumerate all non-reference cursor kinds here.
5580 llvm_unreachable("Unhandled reference cursor kind");
5581 }
5582}
5583
5584CXCursor clang_getCursorDefinition(CXCursor C) {
5585 if (clang_isInvalid(C.kind))
5586 return clang_getNullCursor();
5587
5588 CXTranslationUnit TU = getCursorTU(C);
5589
5590 bool WasReference = false;
5591 if (clang_isReference(C.kind) || clang_isExpression(C.kind)) {
5592 C = clang_getCursorReferenced(C);
5593 WasReference = true;
5594 }
5595
5596 if (C.kind == CXCursor_MacroExpansion)
5597 return clang_getCursorReferenced(C);
5598
5599 if (!clang_isDeclaration(C.kind))
5600 return clang_getNullCursor();
5601
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005602 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005603 if (!D)
5604 return clang_getNullCursor();
5605
5606 switch (D->getKind()) {
5607 // Declaration kinds that don't really separate the notions of
5608 // declaration and definition.
5609 case Decl::Namespace:
5610 case Decl::Typedef:
5611 case Decl::TypeAlias:
5612 case Decl::TypeAliasTemplate:
5613 case Decl::TemplateTypeParm:
5614 case Decl::EnumConstant:
5615 case Decl::Field:
John McCall5e77d762013-04-16 07:28:30 +00005616 case Decl::MSProperty:
Guy Benyei11169dd2012-12-18 14:30:41 +00005617 case Decl::IndirectField:
5618 case Decl::ObjCIvar:
5619 case Decl::ObjCAtDefsField:
5620 case Decl::ImplicitParam:
5621 case Decl::ParmVar:
5622 case Decl::NonTypeTemplateParm:
5623 case Decl::TemplateTemplateParm:
5624 case Decl::ObjCCategoryImpl:
5625 case Decl::ObjCImplementation:
5626 case Decl::AccessSpec:
5627 case Decl::LinkageSpec:
5628 case Decl::ObjCPropertyImpl:
5629 case Decl::FileScopeAsm:
5630 case Decl::StaticAssert:
5631 case Decl::Block:
Tareq A. Siraj6dfa25a2013-04-16 19:37:38 +00005632 case Decl::Captured:
Guy Benyei11169dd2012-12-18 14:30:41 +00005633 case Decl::Label: // FIXME: Is this right??
5634 case Decl::ClassScopeFunctionSpecialization:
5635 case Decl::Import:
Alexey Bataeva769e072013-03-22 06:34:35 +00005636 case Decl::OMPThreadPrivate:
Douglas Gregor85f3f952015-07-07 03:57:15 +00005637 case Decl::ObjCTypeParam:
David Majnemerd9b1a4f2015-11-04 03:40:30 +00005638 case Decl::BuiltinTemplate:
Guy Benyei11169dd2012-12-18 14:30:41 +00005639 return C;
5640
5641 // Declaration kinds that don't make any sense here, but are
5642 // nonetheless harmless.
David Blaikief005d3c2013-02-22 17:44:58 +00005643 case Decl::Empty:
Guy Benyei11169dd2012-12-18 14:30:41 +00005644 case Decl::TranslationUnit:
Richard Smithf19e1272015-03-07 00:04:49 +00005645 case Decl::ExternCContext:
Guy Benyei11169dd2012-12-18 14:30:41 +00005646 break;
5647
5648 // Declaration kinds for which the definition is not resolvable.
5649 case Decl::UnresolvedUsingTypename:
5650 case Decl::UnresolvedUsingValue:
5651 break;
5652
5653 case Decl::UsingDirective:
5654 return MakeCXCursor(cast<UsingDirectiveDecl>(D)->getNominatedNamespace(),
5655 TU);
5656
5657 case Decl::NamespaceAlias:
5658 return MakeCXCursor(cast<NamespaceAliasDecl>(D)->getNamespace(), TU);
5659
5660 case Decl::Enum:
5661 case Decl::Record:
5662 case Decl::CXXRecord:
5663 case Decl::ClassTemplateSpecialization:
5664 case Decl::ClassTemplatePartialSpecialization:
5665 if (TagDecl *Def = cast<TagDecl>(D)->getDefinition())
5666 return MakeCXCursor(Def, TU);
5667 return clang_getNullCursor();
5668
5669 case Decl::Function:
5670 case Decl::CXXMethod:
5671 case Decl::CXXConstructor:
5672 case Decl::CXXDestructor:
5673 case Decl::CXXConversion: {
Craig Topper69186e72014-06-08 08:38:04 +00005674 const FunctionDecl *Def = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005675 if (cast<FunctionDecl>(D)->getBody(Def))
Dmitri Gribenko9c256e32013-01-14 00:46:27 +00005676 return MakeCXCursor(Def, TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005677 return clang_getNullCursor();
5678 }
5679
Larisse Voufo39a1e502013-08-06 01:03:05 +00005680 case Decl::Var:
5681 case Decl::VarTemplateSpecialization:
5682 case Decl::VarTemplatePartialSpecialization: {
Guy Benyei11169dd2012-12-18 14:30:41 +00005683 // Ask the variable if it has a definition.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005684 if (const VarDecl *Def = cast<VarDecl>(D)->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005685 return MakeCXCursor(Def, TU);
5686 return clang_getNullCursor();
5687 }
5688
5689 case Decl::FunctionTemplate: {
Craig Topper69186e72014-06-08 08:38:04 +00005690 const FunctionDecl *Def = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005691 if (cast<FunctionTemplateDecl>(D)->getTemplatedDecl()->getBody(Def))
5692 return MakeCXCursor(Def->getDescribedFunctionTemplate(), TU);
5693 return clang_getNullCursor();
5694 }
5695
5696 case Decl::ClassTemplate: {
5697 if (RecordDecl *Def = cast<ClassTemplateDecl>(D)->getTemplatedDecl()
5698 ->getDefinition())
5699 return MakeCXCursor(cast<CXXRecordDecl>(Def)->getDescribedClassTemplate(),
5700 TU);
5701 return clang_getNullCursor();
5702 }
5703
Larisse Voufo39a1e502013-08-06 01:03:05 +00005704 case Decl::VarTemplate: {
5705 if (VarDecl *Def =
5706 cast<VarTemplateDecl>(D)->getTemplatedDecl()->getDefinition())
5707 return MakeCXCursor(cast<VarDecl>(Def)->getDescribedVarTemplate(), TU);
5708 return clang_getNullCursor();
5709 }
5710
Guy Benyei11169dd2012-12-18 14:30:41 +00005711 case Decl::Using:
5712 return MakeCursorOverloadedDeclRef(cast<UsingDecl>(D),
5713 D->getLocation(), TU);
5714
5715 case Decl::UsingShadow:
5716 return clang_getCursorDefinition(
5717 MakeCXCursor(cast<UsingShadowDecl>(D)->getTargetDecl(),
5718 TU));
5719
5720 case Decl::ObjCMethod: {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005721 const ObjCMethodDecl *Method = cast<ObjCMethodDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00005722 if (Method->isThisDeclarationADefinition())
5723 return C;
5724
5725 // Dig out the method definition in the associated
5726 // @implementation, if we have it.
5727 // FIXME: The ASTs should make finding the definition easier.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005728 if (const ObjCInterfaceDecl *Class
Guy Benyei11169dd2012-12-18 14:30:41 +00005729 = dyn_cast<ObjCInterfaceDecl>(Method->getDeclContext()))
5730 if (ObjCImplementationDecl *ClassImpl = Class->getImplementation())
5731 if (ObjCMethodDecl *Def = ClassImpl->getMethod(Method->getSelector(),
5732 Method->isInstanceMethod()))
5733 if (Def->isThisDeclarationADefinition())
5734 return MakeCXCursor(Def, TU);
5735
5736 return clang_getNullCursor();
5737 }
5738
5739 case Decl::ObjCCategory:
5740 if (ObjCCategoryImplDecl *Impl
5741 = cast<ObjCCategoryDecl>(D)->getImplementation())
5742 return MakeCXCursor(Impl, TU);
5743 return clang_getNullCursor();
5744
5745 case Decl::ObjCProtocol:
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005746 if (const ObjCProtocolDecl *Def = cast<ObjCProtocolDecl>(D)->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005747 return MakeCXCursor(Def, TU);
5748 return clang_getNullCursor();
5749
5750 case Decl::ObjCInterface: {
5751 // There are two notions of a "definition" for an Objective-C
5752 // class: the interface and its implementation. When we resolved a
5753 // reference to an Objective-C class, produce the @interface as
5754 // the definition; when we were provided with the interface,
5755 // produce the @implementation as the definition.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005756 const ObjCInterfaceDecl *IFace = cast<ObjCInterfaceDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00005757 if (WasReference) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005758 if (const ObjCInterfaceDecl *Def = IFace->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005759 return MakeCXCursor(Def, TU);
5760 } else if (ObjCImplementationDecl *Impl = IFace->getImplementation())
5761 return MakeCXCursor(Impl, TU);
5762 return clang_getNullCursor();
5763 }
5764
5765 case Decl::ObjCProperty:
5766 // FIXME: We don't really know where to find the
5767 // ObjCPropertyImplDecls that implement this property.
5768 return clang_getNullCursor();
5769
5770 case Decl::ObjCCompatibleAlias:
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005771 if (const ObjCInterfaceDecl *Class
Guy Benyei11169dd2012-12-18 14:30:41 +00005772 = cast<ObjCCompatibleAliasDecl>(D)->getClassInterface())
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005773 if (const ObjCInterfaceDecl *Def = Class->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005774 return MakeCXCursor(Def, TU);
5775
5776 return clang_getNullCursor();
5777
5778 case Decl::Friend:
5779 if (NamedDecl *Friend = cast<FriendDecl>(D)->getFriendDecl())
5780 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
5781 return clang_getNullCursor();
5782
5783 case Decl::FriendTemplate:
5784 if (NamedDecl *Friend = cast<FriendTemplateDecl>(D)->getFriendDecl())
5785 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
5786 return clang_getNullCursor();
5787 }
5788
5789 return clang_getNullCursor();
5790}
5791
5792unsigned clang_isCursorDefinition(CXCursor C) {
5793 if (!clang_isDeclaration(C.kind))
5794 return 0;
5795
5796 return clang_getCursorDefinition(C) == C;
5797}
5798
5799CXCursor clang_getCanonicalCursor(CXCursor C) {
5800 if (!clang_isDeclaration(C.kind))
5801 return C;
5802
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005803 if (const Decl *D = getCursorDecl(C)) {
5804 if (const ObjCCategoryImplDecl *CatImplD = dyn_cast<ObjCCategoryImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00005805 if (ObjCCategoryDecl *CatD = CatImplD->getCategoryDecl())
5806 return MakeCXCursor(CatD, getCursorTU(C));
5807
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005808 if (const ObjCImplDecl *ImplD = dyn_cast<ObjCImplDecl>(D))
5809 if (const ObjCInterfaceDecl *IFD = ImplD->getClassInterface())
Guy Benyei11169dd2012-12-18 14:30:41 +00005810 return MakeCXCursor(IFD, getCursorTU(C));
5811
5812 return MakeCXCursor(D->getCanonicalDecl(), getCursorTU(C));
5813 }
5814
5815 return C;
5816}
5817
5818int clang_Cursor_getObjCSelectorIndex(CXCursor cursor) {
5819 return cxcursor::getSelectorIdentifierIndexAndLoc(cursor).first;
5820}
5821
5822unsigned clang_getNumOverloadedDecls(CXCursor C) {
5823 if (C.kind != CXCursor_OverloadedDeclRef)
5824 return 0;
5825
5826 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005827 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Guy Benyei11169dd2012-12-18 14:30:41 +00005828 return E->getNumDecls();
5829
5830 if (OverloadedTemplateStorage *S
5831 = Storage.dyn_cast<OverloadedTemplateStorage*>())
5832 return S->size();
5833
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005834 const Decl *D = Storage.get<const Decl *>();
5835 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00005836 return Using->shadow_size();
5837
5838 return 0;
5839}
5840
5841CXCursor clang_getOverloadedDecl(CXCursor cursor, unsigned index) {
5842 if (cursor.kind != CXCursor_OverloadedDeclRef)
5843 return clang_getNullCursor();
5844
5845 if (index >= clang_getNumOverloadedDecls(cursor))
5846 return clang_getNullCursor();
5847
5848 CXTranslationUnit TU = getCursorTU(cursor);
5849 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(cursor).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005850 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Guy Benyei11169dd2012-12-18 14:30:41 +00005851 return MakeCXCursor(E->decls_begin()[index], TU);
5852
5853 if (OverloadedTemplateStorage *S
5854 = Storage.dyn_cast<OverloadedTemplateStorage*>())
5855 return MakeCXCursor(S->begin()[index], TU);
5856
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005857 const Decl *D = Storage.get<const Decl *>();
5858 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005859 // FIXME: This is, unfortunately, linear time.
5860 UsingDecl::shadow_iterator Pos = Using->shadow_begin();
5861 std::advance(Pos, index);
5862 return MakeCXCursor(cast<UsingShadowDecl>(*Pos)->getTargetDecl(), TU);
5863 }
5864
5865 return clang_getNullCursor();
5866}
5867
5868void clang_getDefinitionSpellingAndExtent(CXCursor C,
5869 const char **startBuf,
5870 const char **endBuf,
5871 unsigned *startLine,
5872 unsigned *startColumn,
5873 unsigned *endLine,
5874 unsigned *endColumn) {
5875 assert(getCursorDecl(C) && "CXCursor has null decl");
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005876 const FunctionDecl *FD = dyn_cast<FunctionDecl>(getCursorDecl(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00005877 CompoundStmt *Body = dyn_cast<CompoundStmt>(FD->getBody());
5878
5879 SourceManager &SM = FD->getASTContext().getSourceManager();
5880 *startBuf = SM.getCharacterData(Body->getLBracLoc());
5881 *endBuf = SM.getCharacterData(Body->getRBracLoc());
5882 *startLine = SM.getSpellingLineNumber(Body->getLBracLoc());
5883 *startColumn = SM.getSpellingColumnNumber(Body->getLBracLoc());
5884 *endLine = SM.getSpellingLineNumber(Body->getRBracLoc());
5885 *endColumn = SM.getSpellingColumnNumber(Body->getRBracLoc());
5886}
5887
5888
5889CXSourceRange clang_getCursorReferenceNameRange(CXCursor C, unsigned NameFlags,
5890 unsigned PieceIndex) {
5891 RefNamePieces Pieces;
5892
5893 switch (C.kind) {
5894 case CXCursor_MemberRefExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005895 if (const MemberExpr *E = dyn_cast<MemberExpr>(getCursorExpr(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00005896 Pieces = buildPieces(NameFlags, true, E->getMemberNameInfo(),
5897 E->getQualifierLoc().getSourceRange());
5898 break;
5899
5900 case CXCursor_DeclRefExpr:
James Y Knight04ec5bf2015-12-24 02:59:37 +00005901 if (const DeclRefExpr *E = dyn_cast<DeclRefExpr>(getCursorExpr(C))) {
5902 SourceRange TemplateArgLoc(E->getLAngleLoc(), E->getRAngleLoc());
5903 Pieces =
5904 buildPieces(NameFlags, false, E->getNameInfo(),
5905 E->getQualifierLoc().getSourceRange(), &TemplateArgLoc);
5906 }
Guy Benyei11169dd2012-12-18 14:30:41 +00005907 break;
5908
5909 case CXCursor_CallExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005910 if (const CXXOperatorCallExpr *OCE =
Guy Benyei11169dd2012-12-18 14:30:41 +00005911 dyn_cast<CXXOperatorCallExpr>(getCursorExpr(C))) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005912 const Expr *Callee = OCE->getCallee();
5913 if (const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Callee))
Guy Benyei11169dd2012-12-18 14:30:41 +00005914 Callee = ICE->getSubExpr();
5915
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005916 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(Callee))
Guy Benyei11169dd2012-12-18 14:30:41 +00005917 Pieces = buildPieces(NameFlags, false, DRE->getNameInfo(),
5918 DRE->getQualifierLoc().getSourceRange());
5919 }
5920 break;
5921
5922 default:
5923 break;
5924 }
5925
5926 if (Pieces.empty()) {
5927 if (PieceIndex == 0)
5928 return clang_getCursorExtent(C);
5929 } else if (PieceIndex < Pieces.size()) {
5930 SourceRange R = Pieces[PieceIndex];
5931 if (R.isValid())
5932 return cxloc::translateSourceRange(getCursorContext(C), R);
5933 }
5934
5935 return clang_getNullRange();
5936}
5937
5938void clang_enableStackTraces(void) {
5939 llvm::sys::PrintStackTraceOnErrorSignal();
5940}
5941
5942void clang_executeOnThread(void (*fn)(void*), void *user_data,
5943 unsigned stack_size) {
5944 llvm::llvm_execute_on_thread(fn, user_data, stack_size);
5945}
5946
5947} // end: extern "C"
5948
5949//===----------------------------------------------------------------------===//
5950// Token-based Operations.
5951//===----------------------------------------------------------------------===//
5952
5953/* CXToken layout:
5954 * int_data[0]: a CXTokenKind
5955 * int_data[1]: starting token location
5956 * int_data[2]: token length
5957 * int_data[3]: reserved
5958 * ptr_data: for identifiers and keywords, an IdentifierInfo*.
5959 * otherwise unused.
5960 */
5961extern "C" {
5962
5963CXTokenKind clang_getTokenKind(CXToken CXTok) {
5964 return static_cast<CXTokenKind>(CXTok.int_data[0]);
5965}
5966
5967CXString clang_getTokenSpelling(CXTranslationUnit TU, CXToken CXTok) {
5968 switch (clang_getTokenKind(CXTok)) {
5969 case CXToken_Identifier:
5970 case CXToken_Keyword:
5971 // We know we have an IdentifierInfo*, so use that.
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005972 return cxstring::createRef(static_cast<IdentifierInfo *>(CXTok.ptr_data)
Guy Benyei11169dd2012-12-18 14:30:41 +00005973 ->getNameStart());
5974
5975 case CXToken_Literal: {
5976 // We have stashed the starting pointer in the ptr_data field. Use it.
5977 const char *Text = static_cast<const char *>(CXTok.ptr_data);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00005978 return cxstring::createDup(StringRef(Text, CXTok.int_data[2]));
Guy Benyei11169dd2012-12-18 14:30:41 +00005979 }
5980
5981 case CXToken_Punctuation:
5982 case CXToken_Comment:
5983 break;
5984 }
5985
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005986 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005987 LOG_BAD_TU(TU);
5988 return cxstring::createEmpty();
5989 }
5990
Guy Benyei11169dd2012-12-18 14:30:41 +00005991 // We have to find the starting buffer pointer the hard way, by
5992 // deconstructing the source location.
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005993 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005994 if (!CXXUnit)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00005995 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00005996
5997 SourceLocation Loc = SourceLocation::getFromRawEncoding(CXTok.int_data[1]);
5998 std::pair<FileID, unsigned> LocInfo
5999 = CXXUnit->getSourceManager().getDecomposedSpellingLoc(Loc);
6000 bool Invalid = false;
6001 StringRef Buffer
6002 = CXXUnit->getSourceManager().getBufferData(LocInfo.first, &Invalid);
6003 if (Invalid)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006004 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006005
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006006 return cxstring::createDup(Buffer.substr(LocInfo.second, CXTok.int_data[2]));
Guy Benyei11169dd2012-12-18 14:30:41 +00006007}
6008
6009CXSourceLocation clang_getTokenLocation(CXTranslationUnit TU, CXToken CXTok) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006010 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006011 LOG_BAD_TU(TU);
6012 return clang_getNullLocation();
6013 }
6014
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006015 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00006016 if (!CXXUnit)
6017 return clang_getNullLocation();
6018
6019 return cxloc::translateSourceLocation(CXXUnit->getASTContext(),
6020 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
6021}
6022
6023CXSourceRange clang_getTokenExtent(CXTranslationUnit TU, CXToken CXTok) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006024 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006025 LOG_BAD_TU(TU);
6026 return clang_getNullRange();
6027 }
6028
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006029 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00006030 if (!CXXUnit)
6031 return clang_getNullRange();
6032
6033 return cxloc::translateSourceRange(CXXUnit->getASTContext(),
6034 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
6035}
6036
6037static void getTokens(ASTUnit *CXXUnit, SourceRange Range,
6038 SmallVectorImpl<CXToken> &CXTokens) {
6039 SourceManager &SourceMgr = CXXUnit->getSourceManager();
6040 std::pair<FileID, unsigned> BeginLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00006041 = SourceMgr.getDecomposedSpellingLoc(Range.getBegin());
Guy Benyei11169dd2012-12-18 14:30:41 +00006042 std::pair<FileID, unsigned> EndLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00006043 = SourceMgr.getDecomposedSpellingLoc(Range.getEnd());
Guy Benyei11169dd2012-12-18 14:30:41 +00006044
6045 // Cannot tokenize across files.
6046 if (BeginLocInfo.first != EndLocInfo.first)
6047 return;
6048
6049 // Create a lexer
6050 bool Invalid = false;
6051 StringRef Buffer
6052 = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
6053 if (Invalid)
6054 return;
6055
6056 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
6057 CXXUnit->getASTContext().getLangOpts(),
6058 Buffer.begin(), Buffer.data() + BeginLocInfo.second, Buffer.end());
6059 Lex.SetCommentRetentionState(true);
6060
6061 // Lex tokens until we hit the end of the range.
6062 const char *EffectiveBufferEnd = Buffer.data() + EndLocInfo.second;
6063 Token Tok;
6064 bool previousWasAt = false;
6065 do {
6066 // Lex the next token
6067 Lex.LexFromRawLexer(Tok);
6068 if (Tok.is(tok::eof))
6069 break;
6070
6071 // Initialize the CXToken.
6072 CXToken CXTok;
6073
6074 // - Common fields
6075 CXTok.int_data[1] = Tok.getLocation().getRawEncoding();
6076 CXTok.int_data[2] = Tok.getLength();
6077 CXTok.int_data[3] = 0;
6078
6079 // - Kind-specific fields
6080 if (Tok.isLiteral()) {
6081 CXTok.int_data[0] = CXToken_Literal;
Dmitri Gribenkof9304482013-01-23 15:56:07 +00006082 CXTok.ptr_data = const_cast<char *>(Tok.getLiteralData());
Guy Benyei11169dd2012-12-18 14:30:41 +00006083 } else if (Tok.is(tok::raw_identifier)) {
6084 // Lookup the identifier to determine whether we have a keyword.
6085 IdentifierInfo *II
6086 = CXXUnit->getPreprocessor().LookUpIdentifierInfo(Tok);
6087
6088 if ((II->getObjCKeywordID() != tok::objc_not_keyword) && previousWasAt) {
6089 CXTok.int_data[0] = CXToken_Keyword;
6090 }
6091 else {
6092 CXTok.int_data[0] = Tok.is(tok::identifier)
6093 ? CXToken_Identifier
6094 : CXToken_Keyword;
6095 }
6096 CXTok.ptr_data = II;
6097 } else if (Tok.is(tok::comment)) {
6098 CXTok.int_data[0] = CXToken_Comment;
Craig Topper69186e72014-06-08 08:38:04 +00006099 CXTok.ptr_data = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006100 } else {
6101 CXTok.int_data[0] = CXToken_Punctuation;
Craig Topper69186e72014-06-08 08:38:04 +00006102 CXTok.ptr_data = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006103 }
6104 CXTokens.push_back(CXTok);
6105 previousWasAt = Tok.is(tok::at);
6106 } while (Lex.getBufferLocation() <= EffectiveBufferEnd);
6107}
6108
6109void clang_tokenize(CXTranslationUnit TU, CXSourceRange Range,
6110 CXToken **Tokens, unsigned *NumTokens) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006111 LOG_FUNC_SECTION {
6112 *Log << TU << ' ' << Range;
6113 }
6114
Guy Benyei11169dd2012-12-18 14:30:41 +00006115 if (Tokens)
Craig Topper69186e72014-06-08 08:38:04 +00006116 *Tokens = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006117 if (NumTokens)
6118 *NumTokens = 0;
6119
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006120 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006121 LOG_BAD_TU(TU);
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00006122 return;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006123 }
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00006124
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006125 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00006126 if (!CXXUnit || !Tokens || !NumTokens)
6127 return;
6128
6129 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
6130
6131 SourceRange R = cxloc::translateCXSourceRange(Range);
6132 if (R.isInvalid())
6133 return;
6134
6135 SmallVector<CXToken, 32> CXTokens;
6136 getTokens(CXXUnit, R, CXTokens);
6137
6138 if (CXTokens.empty())
6139 return;
6140
6141 *Tokens = (CXToken *)malloc(sizeof(CXToken) * CXTokens.size());
6142 memmove(*Tokens, CXTokens.data(), sizeof(CXToken) * CXTokens.size());
6143 *NumTokens = CXTokens.size();
6144}
6145
6146void clang_disposeTokens(CXTranslationUnit TU,
6147 CXToken *Tokens, unsigned NumTokens) {
6148 free(Tokens);
6149}
6150
6151} // end: extern "C"
6152
6153//===----------------------------------------------------------------------===//
6154// Token annotation APIs.
6155//===----------------------------------------------------------------------===//
6156
Guy Benyei11169dd2012-12-18 14:30:41 +00006157static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
6158 CXCursor parent,
6159 CXClientData client_data);
6160static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
6161 CXClientData client_data);
6162
6163namespace {
6164class AnnotateTokensWorker {
Guy Benyei11169dd2012-12-18 14:30:41 +00006165 CXToken *Tokens;
6166 CXCursor *Cursors;
6167 unsigned NumTokens;
6168 unsigned TokIdx;
6169 unsigned PreprocessingTokIdx;
6170 CursorVisitor AnnotateVis;
6171 SourceManager &SrcMgr;
6172 bool HasContextSensitiveKeywords;
6173
6174 struct PostChildrenInfo {
6175 CXCursor Cursor;
6176 SourceRange CursorRange;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00006177 unsigned BeforeReachingCursorIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00006178 unsigned BeforeChildrenTokenIdx;
6179 };
Dmitri Gribenkof8579502013-01-12 19:30:44 +00006180 SmallVector<PostChildrenInfo, 8> PostChildrenInfos;
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00006181
6182 CXToken &getTok(unsigned Idx) {
6183 assert(Idx < NumTokens);
6184 return Tokens[Idx];
6185 }
6186 const CXToken &getTok(unsigned Idx) const {
6187 assert(Idx < NumTokens);
6188 return Tokens[Idx];
6189 }
Guy Benyei11169dd2012-12-18 14:30:41 +00006190 bool MoreTokens() const { return TokIdx < NumTokens; }
6191 unsigned NextToken() const { return TokIdx; }
6192 void AdvanceToken() { ++TokIdx; }
6193 SourceLocation GetTokenLoc(unsigned tokI) {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00006194 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[1]);
Guy Benyei11169dd2012-12-18 14:30:41 +00006195 }
6196 bool isFunctionMacroToken(unsigned tokI) const {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00006197 return getTok(tokI).int_data[3] != 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00006198 }
6199 SourceLocation getFunctionMacroTokenLoc(unsigned tokI) const {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00006200 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[3]);
Guy Benyei11169dd2012-12-18 14:30:41 +00006201 }
6202
6203 void annotateAndAdvanceTokens(CXCursor, RangeComparisonResult, SourceRange);
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00006204 bool annotateAndAdvanceFunctionMacroTokens(CXCursor, RangeComparisonResult,
Guy Benyei11169dd2012-12-18 14:30:41 +00006205 SourceRange);
6206
6207public:
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006208 AnnotateTokensWorker(CXToken *tokens, CXCursor *cursors, unsigned numTokens,
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006209 CXTranslationUnit TU, SourceRange RegionOfInterest)
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006210 : Tokens(tokens), Cursors(cursors),
Guy Benyei11169dd2012-12-18 14:30:41 +00006211 NumTokens(numTokens), TokIdx(0), PreprocessingTokIdx(0),
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006212 AnnotateVis(TU,
Guy Benyei11169dd2012-12-18 14:30:41 +00006213 AnnotateTokensVisitor, this,
6214 /*VisitPreprocessorLast=*/true,
6215 /*VisitIncludedEntities=*/false,
6216 RegionOfInterest,
6217 /*VisitDeclsOnly=*/false,
6218 AnnotateTokensPostChildrenVisitor),
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006219 SrcMgr(cxtu::getASTUnit(TU)->getSourceManager()),
Guy Benyei11169dd2012-12-18 14:30:41 +00006220 HasContextSensitiveKeywords(false) { }
6221
6222 void VisitChildren(CXCursor C) { AnnotateVis.VisitChildren(C); }
6223 enum CXChildVisitResult Visit(CXCursor cursor, CXCursor parent);
6224 bool postVisitChildren(CXCursor cursor);
6225 void AnnotateTokens();
6226
6227 /// \brief Determine whether the annotator saw any cursors that have
6228 /// context-sensitive keywords.
6229 bool hasContextSensitiveKeywords() const {
6230 return HasContextSensitiveKeywords;
6231 }
6232
6233 ~AnnotateTokensWorker() {
6234 assert(PostChildrenInfos.empty());
6235 }
6236};
Alexander Kornienkoab9db512015-06-22 23:07:51 +00006237}
Guy Benyei11169dd2012-12-18 14:30:41 +00006238
6239void AnnotateTokensWorker::AnnotateTokens() {
6240 // Walk the AST within the region of interest, annotating tokens
6241 // along the way.
6242 AnnotateVis.visitFileRegion();
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006243}
Guy Benyei11169dd2012-12-18 14:30:41 +00006244
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006245static inline void updateCursorAnnotation(CXCursor &Cursor,
6246 const CXCursor &updateC) {
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00006247 if (clang_isInvalid(updateC.kind) || !clang_isInvalid(Cursor.kind))
Guy Benyei11169dd2012-12-18 14:30:41 +00006248 return;
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006249 Cursor = updateC;
Guy Benyei11169dd2012-12-18 14:30:41 +00006250}
6251
6252/// \brief It annotates and advances tokens with a cursor until the comparison
6253//// between the cursor location and the source range is the same as
6254/// \arg compResult.
6255///
6256/// Pass RangeBefore to annotate tokens with a cursor until a range is reached.
6257/// Pass RangeOverlap to annotate tokens inside a range.
6258void AnnotateTokensWorker::annotateAndAdvanceTokens(CXCursor updateC,
6259 RangeComparisonResult compResult,
6260 SourceRange range) {
6261 while (MoreTokens()) {
6262 const unsigned I = NextToken();
6263 if (isFunctionMacroToken(I))
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00006264 if (!annotateAndAdvanceFunctionMacroTokens(updateC, compResult, range))
6265 return;
Guy Benyei11169dd2012-12-18 14:30:41 +00006266
6267 SourceLocation TokLoc = GetTokenLoc(I);
6268 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006269 updateCursorAnnotation(Cursors[I], updateC);
Guy Benyei11169dd2012-12-18 14:30:41 +00006270 AdvanceToken();
6271 continue;
6272 }
6273 break;
6274 }
6275}
6276
6277/// \brief Special annotation handling for macro argument tokens.
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00006278/// \returns true if it advanced beyond all macro tokens, false otherwise.
6279bool AnnotateTokensWorker::annotateAndAdvanceFunctionMacroTokens(
Guy Benyei11169dd2012-12-18 14:30:41 +00006280 CXCursor updateC,
6281 RangeComparisonResult compResult,
6282 SourceRange range) {
6283 assert(MoreTokens());
6284 assert(isFunctionMacroToken(NextToken()) &&
6285 "Should be called only for macro arg tokens");
6286
6287 // This works differently than annotateAndAdvanceTokens; because expanded
6288 // macro arguments can have arbitrary translation-unit source order, we do not
6289 // advance the token index one by one until a token fails the range test.
6290 // We only advance once past all of the macro arg tokens if all of them
6291 // pass the range test. If one of them fails we keep the token index pointing
6292 // at the start of the macro arg tokens so that the failing token will be
6293 // annotated by a subsequent annotation try.
6294
6295 bool atLeastOneCompFail = false;
6296
6297 unsigned I = NextToken();
6298 for (; I < NumTokens && isFunctionMacroToken(I); ++I) {
6299 SourceLocation TokLoc = getFunctionMacroTokenLoc(I);
6300 if (TokLoc.isFileID())
6301 continue; // not macro arg token, it's parens or comma.
6302 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
6303 if (clang_isInvalid(clang_getCursorKind(Cursors[I])))
6304 Cursors[I] = updateC;
6305 } else
6306 atLeastOneCompFail = true;
6307 }
6308
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00006309 if (atLeastOneCompFail)
6310 return false;
6311
6312 TokIdx = I; // All of the tokens were handled, advance beyond all of them.
6313 return true;
Guy Benyei11169dd2012-12-18 14:30:41 +00006314}
6315
6316enum CXChildVisitResult
6317AnnotateTokensWorker::Visit(CXCursor cursor, CXCursor parent) {
Guy Benyei11169dd2012-12-18 14:30:41 +00006318 SourceRange cursorRange = getRawCursorExtent(cursor);
6319 if (cursorRange.isInvalid())
6320 return CXChildVisit_Recurse;
6321
6322 if (!HasContextSensitiveKeywords) {
6323 // Objective-C properties can have context-sensitive keywords.
6324 if (cursor.kind == CXCursor_ObjCPropertyDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006325 if (const ObjCPropertyDecl *Property
Guy Benyei11169dd2012-12-18 14:30:41 +00006326 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(cursor)))
6327 HasContextSensitiveKeywords = Property->getPropertyAttributesAsWritten() != 0;
6328 }
6329 // Objective-C methods can have context-sensitive keywords.
6330 else if (cursor.kind == CXCursor_ObjCInstanceMethodDecl ||
6331 cursor.kind == CXCursor_ObjCClassMethodDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006332 if (const ObjCMethodDecl *Method
Guy Benyei11169dd2012-12-18 14:30:41 +00006333 = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
6334 if (Method->getObjCDeclQualifier())
6335 HasContextSensitiveKeywords = true;
6336 else {
Aaron Ballman43b68be2014-03-07 17:50:17 +00006337 for (const auto *P : Method->params()) {
6338 if (P->getObjCDeclQualifier()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00006339 HasContextSensitiveKeywords = true;
6340 break;
6341 }
6342 }
6343 }
6344 }
6345 }
6346 // C++ methods can have context-sensitive keywords.
6347 else if (cursor.kind == CXCursor_CXXMethod) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006348 if (const CXXMethodDecl *Method
Guy Benyei11169dd2012-12-18 14:30:41 +00006349 = dyn_cast_or_null<CXXMethodDecl>(getCursorDecl(cursor))) {
6350 if (Method->hasAttr<FinalAttr>() || Method->hasAttr<OverrideAttr>())
6351 HasContextSensitiveKeywords = true;
6352 }
6353 }
6354 // C++ classes can have context-sensitive keywords.
6355 else if (cursor.kind == CXCursor_StructDecl ||
6356 cursor.kind == CXCursor_ClassDecl ||
6357 cursor.kind == CXCursor_ClassTemplate ||
6358 cursor.kind == CXCursor_ClassTemplatePartialSpecialization) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006359 if (const Decl *D = getCursorDecl(cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +00006360 if (D->hasAttr<FinalAttr>())
6361 HasContextSensitiveKeywords = true;
6362 }
6363 }
Argyrios Kyrtzidis990b3862013-06-04 18:24:30 +00006364
6365 // Don't override a property annotation with its getter/setter method.
6366 if (cursor.kind == CXCursor_ObjCInstanceMethodDecl &&
6367 parent.kind == CXCursor_ObjCPropertyDecl)
6368 return CXChildVisit_Continue;
Guy Benyei11169dd2012-12-18 14:30:41 +00006369
6370 if (clang_isPreprocessing(cursor.kind)) {
6371 // Items in the preprocessing record are kept separate from items in
6372 // declarations, so we keep a separate token index.
6373 unsigned SavedTokIdx = TokIdx;
6374 TokIdx = PreprocessingTokIdx;
6375
6376 // Skip tokens up until we catch up to the beginning of the preprocessing
6377 // entry.
6378 while (MoreTokens()) {
6379 const unsigned I = NextToken();
6380 SourceLocation TokLoc = GetTokenLoc(I);
6381 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
6382 case RangeBefore:
6383 AdvanceToken();
6384 continue;
6385 case RangeAfter:
6386 case RangeOverlap:
6387 break;
6388 }
6389 break;
6390 }
6391
6392 // Look at all of the tokens within this range.
6393 while (MoreTokens()) {
6394 const unsigned I = NextToken();
6395 SourceLocation TokLoc = GetTokenLoc(I);
6396 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
6397 case RangeBefore:
6398 llvm_unreachable("Infeasible");
6399 case RangeAfter:
6400 break;
6401 case RangeOverlap:
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00006402 // For macro expansions, just note where the beginning of the macro
6403 // expansion occurs.
6404 if (cursor.kind == CXCursor_MacroExpansion) {
6405 if (TokLoc == cursorRange.getBegin())
6406 Cursors[I] = cursor;
6407 AdvanceToken();
6408 break;
6409 }
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006410 // We may have already annotated macro names inside macro definitions.
6411 if (Cursors[I].kind != CXCursor_MacroExpansion)
6412 Cursors[I] = cursor;
Guy Benyei11169dd2012-12-18 14:30:41 +00006413 AdvanceToken();
Guy Benyei11169dd2012-12-18 14:30:41 +00006414 continue;
6415 }
6416 break;
6417 }
6418
6419 // Save the preprocessing token index; restore the non-preprocessing
6420 // token index.
6421 PreprocessingTokIdx = TokIdx;
6422 TokIdx = SavedTokIdx;
6423 return CXChildVisit_Recurse;
6424 }
6425
6426 if (cursorRange.isInvalid())
6427 return CXChildVisit_Continue;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00006428
6429 unsigned BeforeReachingCursorIdx = NextToken();
Guy Benyei11169dd2012-12-18 14:30:41 +00006430 const enum CXCursorKind cursorK = clang_getCursorKind(cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00006431 const enum CXCursorKind K = clang_getCursorKind(parent);
6432 const CXCursor updateC =
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00006433 (clang_isInvalid(K) || K == CXCursor_TranslationUnit ||
6434 // Attributes are annotated out-of-order, skip tokens until we reach it.
6435 clang_isAttribute(cursor.kind))
Guy Benyei11169dd2012-12-18 14:30:41 +00006436 ? clang_getNullCursor() : parent;
6437
6438 annotateAndAdvanceTokens(updateC, RangeBefore, cursorRange);
6439
6440 // Avoid having the cursor of an expression "overwrite" the annotation of the
6441 // variable declaration that it belongs to.
6442 // This can happen for C++ constructor expressions whose range generally
6443 // include the variable declaration, e.g.:
6444 // MyCXXClass foo; // Make sure we don't annotate 'foo' as a CallExpr cursor.
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00006445 if (clang_isExpression(cursorK) && MoreTokens()) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00006446 const Expr *E = getCursorExpr(cursor);
Dmitri Gribenkoa1691182013-01-26 18:12:08 +00006447 if (const Decl *D = getCursorParentDecl(cursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00006448 const unsigned I = NextToken();
6449 if (E->getLocStart().isValid() && D->getLocation().isValid() &&
6450 E->getLocStart() == D->getLocation() &&
6451 E->getLocStart() == GetTokenLoc(I)) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006452 updateCursorAnnotation(Cursors[I], updateC);
Guy Benyei11169dd2012-12-18 14:30:41 +00006453 AdvanceToken();
6454 }
6455 }
6456 }
6457
6458 // Before recursing into the children keep some state that we are going
6459 // to use in the AnnotateTokensWorker::postVisitChildren callback to do some
6460 // extra work after the child nodes are visited.
6461 // Note that we don't call VisitChildren here to avoid traversing statements
6462 // code-recursively which can blow the stack.
6463
6464 PostChildrenInfo Info;
6465 Info.Cursor = cursor;
6466 Info.CursorRange = cursorRange;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00006467 Info.BeforeReachingCursorIdx = BeforeReachingCursorIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00006468 Info.BeforeChildrenTokenIdx = NextToken();
6469 PostChildrenInfos.push_back(Info);
6470
6471 return CXChildVisit_Recurse;
6472}
6473
6474bool AnnotateTokensWorker::postVisitChildren(CXCursor cursor) {
6475 if (PostChildrenInfos.empty())
6476 return false;
6477 const PostChildrenInfo &Info = PostChildrenInfos.back();
6478 if (!clang_equalCursors(Info.Cursor, cursor))
6479 return false;
6480
6481 const unsigned BeforeChildren = Info.BeforeChildrenTokenIdx;
6482 const unsigned AfterChildren = NextToken();
6483 SourceRange cursorRange = Info.CursorRange;
6484
6485 // Scan the tokens that are at the end of the cursor, but are not captured
6486 // but the child cursors.
6487 annotateAndAdvanceTokens(cursor, RangeOverlap, cursorRange);
6488
6489 // Scan the tokens that are at the beginning of the cursor, but are not
6490 // capture by the child cursors.
6491 for (unsigned I = BeforeChildren; I != AfterChildren; ++I) {
6492 if (!clang_isInvalid(clang_getCursorKind(Cursors[I])))
6493 break;
6494
6495 Cursors[I] = cursor;
6496 }
6497
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00006498 // Attributes are annotated out-of-order, rewind TokIdx to when we first
6499 // encountered the attribute cursor.
6500 if (clang_isAttribute(cursor.kind))
6501 TokIdx = Info.BeforeReachingCursorIdx;
6502
Guy Benyei11169dd2012-12-18 14:30:41 +00006503 PostChildrenInfos.pop_back();
6504 return false;
6505}
6506
6507static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
6508 CXCursor parent,
6509 CXClientData client_data) {
6510 return static_cast<AnnotateTokensWorker*>(client_data)->Visit(cursor, parent);
6511}
6512
6513static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
6514 CXClientData client_data) {
6515 return static_cast<AnnotateTokensWorker*>(client_data)->
6516 postVisitChildren(cursor);
6517}
6518
6519namespace {
6520
6521/// \brief Uses the macro expansions in the preprocessing record to find
6522/// and mark tokens that are macro arguments. This info is used by the
6523/// AnnotateTokensWorker.
6524class MarkMacroArgTokensVisitor {
6525 SourceManager &SM;
6526 CXToken *Tokens;
6527 unsigned NumTokens;
6528 unsigned CurIdx;
6529
6530public:
6531 MarkMacroArgTokensVisitor(SourceManager &SM,
6532 CXToken *tokens, unsigned numTokens)
6533 : SM(SM), Tokens(tokens), NumTokens(numTokens), CurIdx(0) { }
6534
6535 CXChildVisitResult visit(CXCursor cursor, CXCursor parent) {
6536 if (cursor.kind != CXCursor_MacroExpansion)
6537 return CXChildVisit_Continue;
6538
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006539 SourceRange macroRange = getCursorMacroExpansion(cursor).getSourceRange();
Guy Benyei11169dd2012-12-18 14:30:41 +00006540 if (macroRange.getBegin() == macroRange.getEnd())
6541 return CXChildVisit_Continue; // it's not a function macro.
6542
6543 for (; CurIdx < NumTokens; ++CurIdx) {
6544 if (!SM.isBeforeInTranslationUnit(getTokenLoc(CurIdx),
6545 macroRange.getBegin()))
6546 break;
6547 }
6548
6549 if (CurIdx == NumTokens)
6550 return CXChildVisit_Break;
6551
6552 for (; CurIdx < NumTokens; ++CurIdx) {
6553 SourceLocation tokLoc = getTokenLoc(CurIdx);
6554 if (!SM.isBeforeInTranslationUnit(tokLoc, macroRange.getEnd()))
6555 break;
6556
6557 setFunctionMacroTokenLoc(CurIdx, SM.getMacroArgExpandedLocation(tokLoc));
6558 }
6559
6560 if (CurIdx == NumTokens)
6561 return CXChildVisit_Break;
6562
6563 return CXChildVisit_Continue;
6564 }
6565
6566private:
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00006567 CXToken &getTok(unsigned Idx) {
6568 assert(Idx < NumTokens);
6569 return Tokens[Idx];
6570 }
6571 const CXToken &getTok(unsigned Idx) const {
6572 assert(Idx < NumTokens);
6573 return Tokens[Idx];
6574 }
6575
Guy Benyei11169dd2012-12-18 14:30:41 +00006576 SourceLocation getTokenLoc(unsigned tokI) {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00006577 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[1]);
Guy Benyei11169dd2012-12-18 14:30:41 +00006578 }
6579
6580 void setFunctionMacroTokenLoc(unsigned tokI, SourceLocation loc) {
6581 // The third field is reserved and currently not used. Use it here
6582 // to mark macro arg expanded tokens with their expanded locations.
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00006583 getTok(tokI).int_data[3] = loc.getRawEncoding();
Guy Benyei11169dd2012-12-18 14:30:41 +00006584 }
6585};
6586
6587} // end anonymous namespace
6588
6589static CXChildVisitResult
6590MarkMacroArgTokensVisitorDelegate(CXCursor cursor, CXCursor parent,
6591 CXClientData client_data) {
6592 return static_cast<MarkMacroArgTokensVisitor*>(client_data)->visit(cursor,
6593 parent);
6594}
6595
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006596/// \brief Used by \c annotatePreprocessorTokens.
6597/// \returns true if lexing was finished, false otherwise.
6598static bool lexNext(Lexer &Lex, Token &Tok,
6599 unsigned &NextIdx, unsigned NumTokens) {
6600 if (NextIdx >= NumTokens)
6601 return true;
6602
6603 ++NextIdx;
6604 Lex.LexFromRawLexer(Tok);
Alexander Kornienko1a9f1842015-12-28 15:24:08 +00006605 return Tok.is(tok::eof);
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006606}
6607
Guy Benyei11169dd2012-12-18 14:30:41 +00006608static void annotatePreprocessorTokens(CXTranslationUnit TU,
6609 SourceRange RegionOfInterest,
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006610 CXCursor *Cursors,
6611 CXToken *Tokens,
6612 unsigned NumTokens) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006613 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00006614
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006615 Preprocessor &PP = CXXUnit->getPreprocessor();
Guy Benyei11169dd2012-12-18 14:30:41 +00006616 SourceManager &SourceMgr = CXXUnit->getSourceManager();
6617 std::pair<FileID, unsigned> BeginLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00006618 = SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getBegin());
Guy Benyei11169dd2012-12-18 14:30:41 +00006619 std::pair<FileID, unsigned> EndLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00006620 = SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getEnd());
Guy Benyei11169dd2012-12-18 14:30:41 +00006621
6622 if (BeginLocInfo.first != EndLocInfo.first)
6623 return;
6624
6625 StringRef Buffer;
6626 bool Invalid = false;
6627 Buffer = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
6628 if (Buffer.empty() || Invalid)
6629 return;
6630
6631 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
6632 CXXUnit->getASTContext().getLangOpts(),
6633 Buffer.begin(), Buffer.data() + BeginLocInfo.second,
6634 Buffer.end());
6635 Lex.SetCommentRetentionState(true);
6636
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006637 unsigned NextIdx = 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00006638 // Lex tokens in raw mode until we hit the end of the range, to avoid
6639 // entering #includes or expanding macros.
6640 while (true) {
6641 Token Tok;
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006642 if (lexNext(Lex, Tok, NextIdx, NumTokens))
6643 break;
6644 unsigned TokIdx = NextIdx-1;
6645 assert(Tok.getLocation() ==
6646 SourceLocation::getFromRawEncoding(Tokens[TokIdx].int_data[1]));
Guy Benyei11169dd2012-12-18 14:30:41 +00006647
6648 reprocess:
6649 if (Tok.is(tok::hash) && Tok.isAtStartOfLine()) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006650 // We have found a preprocessing directive. Annotate the tokens
6651 // appropriately.
Guy Benyei11169dd2012-12-18 14:30:41 +00006652 //
6653 // FIXME: Some simple tests here could identify macro definitions and
6654 // #undefs, to provide specific cursor kinds for those.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006655
6656 SourceLocation BeginLoc = Tok.getLocation();
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006657 if (lexNext(Lex, Tok, NextIdx, NumTokens))
6658 break;
6659
Craig Topper69186e72014-06-08 08:38:04 +00006660 MacroInfo *MI = nullptr;
Alp Toker2d57cea2014-05-17 04:53:25 +00006661 if (Tok.is(tok::raw_identifier) && Tok.getRawIdentifier() == "define") {
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006662 if (lexNext(Lex, Tok, NextIdx, NumTokens))
6663 break;
6664
6665 if (Tok.is(tok::raw_identifier)) {
Alp Toker2d57cea2014-05-17 04:53:25 +00006666 IdentifierInfo &II =
6667 PP.getIdentifierTable().get(Tok.getRawIdentifier());
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006668 SourceLocation MappedTokLoc =
6669 CXXUnit->mapLocationToPreamble(Tok.getLocation());
6670 MI = getMacroInfo(II, MappedTokLoc, TU);
6671 }
6672 }
6673
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006674 bool finished = false;
Guy Benyei11169dd2012-12-18 14:30:41 +00006675 do {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006676 if (lexNext(Lex, Tok, NextIdx, NumTokens)) {
6677 finished = true;
6678 break;
6679 }
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006680 // If we are in a macro definition, check if the token was ever a
6681 // macro name and annotate it if that's the case.
6682 if (MI) {
6683 SourceLocation SaveLoc = Tok.getLocation();
6684 Tok.setLocation(CXXUnit->mapLocationToPreamble(SaveLoc));
Richard Smith66a81862015-05-04 02:25:31 +00006685 MacroDefinitionRecord *MacroDef =
6686 checkForMacroInMacroDefinition(MI, Tok, TU);
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006687 Tok.setLocation(SaveLoc);
6688 if (MacroDef)
Richard Smith66a81862015-05-04 02:25:31 +00006689 Cursors[NextIdx - 1] =
6690 MakeMacroExpansionCursor(MacroDef, Tok.getLocation(), TU);
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006691 }
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006692 } while (!Tok.isAtStartOfLine());
6693
6694 unsigned LastIdx = finished ? NextIdx-1 : NextIdx-2;
6695 assert(TokIdx <= LastIdx);
6696 SourceLocation EndLoc =
6697 SourceLocation::getFromRawEncoding(Tokens[LastIdx].int_data[1]);
6698 CXCursor Cursor =
6699 MakePreprocessingDirectiveCursor(SourceRange(BeginLoc, EndLoc), TU);
6700
6701 for (; TokIdx <= LastIdx; ++TokIdx)
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006702 updateCursorAnnotation(Cursors[TokIdx], Cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00006703
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006704 if (finished)
6705 break;
6706 goto reprocess;
Guy Benyei11169dd2012-12-18 14:30:41 +00006707 }
Guy Benyei11169dd2012-12-18 14:30:41 +00006708 }
6709}
6710
6711// This gets run a separate thread to avoid stack blowout.
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00006712static void clang_annotateTokensImpl(CXTranslationUnit TU, ASTUnit *CXXUnit,
6713 CXToken *Tokens, unsigned NumTokens,
6714 CXCursor *Cursors) {
Dmitri Gribenko183436e2013-01-26 21:49:50 +00006715 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00006716 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
6717 setThreadBackgroundPriority();
6718
6719 // Determine the region of interest, which contains all of the tokens.
6720 SourceRange RegionOfInterest;
6721 RegionOfInterest.setBegin(
6722 cxloc::translateSourceLocation(clang_getTokenLocation(TU, Tokens[0])));
6723 RegionOfInterest.setEnd(
6724 cxloc::translateSourceLocation(clang_getTokenLocation(TU,
6725 Tokens[NumTokens-1])));
6726
Guy Benyei11169dd2012-12-18 14:30:41 +00006727 // Relex the tokens within the source range to look for preprocessing
6728 // directives.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006729 annotatePreprocessorTokens(TU, RegionOfInterest, Cursors, Tokens, NumTokens);
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00006730
6731 // If begin location points inside a macro argument, set it to the expansion
6732 // location so we can have the full context when annotating semantically.
6733 {
6734 SourceManager &SM = CXXUnit->getSourceManager();
6735 SourceLocation Loc =
6736 SM.getMacroArgExpandedLocation(RegionOfInterest.getBegin());
6737 if (Loc.isMacroID())
6738 RegionOfInterest.setBegin(SM.getExpansionLoc(Loc));
6739 }
6740
Guy Benyei11169dd2012-12-18 14:30:41 +00006741 if (CXXUnit->getPreprocessor().getPreprocessingRecord()) {
6742 // Search and mark tokens that are macro argument expansions.
6743 MarkMacroArgTokensVisitor Visitor(CXXUnit->getSourceManager(),
6744 Tokens, NumTokens);
6745 CursorVisitor MacroArgMarker(TU,
6746 MarkMacroArgTokensVisitorDelegate, &Visitor,
6747 /*VisitPreprocessorLast=*/true,
6748 /*VisitIncludedEntities=*/false,
6749 RegionOfInterest);
6750 MacroArgMarker.visitPreprocessedEntitiesInRegion();
6751 }
6752
6753 // Annotate all of the source locations in the region of interest that map to
6754 // a specific cursor.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006755 AnnotateTokensWorker W(Tokens, Cursors, NumTokens, TU, RegionOfInterest);
Guy Benyei11169dd2012-12-18 14:30:41 +00006756
6757 // FIXME: We use a ridiculous stack size here because the data-recursion
6758 // algorithm uses a large stack frame than the non-data recursive version,
6759 // and AnnotationTokensWorker currently transforms the data-recursion
6760 // algorithm back into a traditional recursion by explicitly calling
6761 // VisitChildren(). We will need to remove this explicit recursive call.
6762 W.AnnotateTokens();
6763
6764 // If we ran into any entities that involve context-sensitive keywords,
6765 // take another pass through the tokens to mark them as such.
6766 if (W.hasContextSensitiveKeywords()) {
6767 for (unsigned I = 0; I != NumTokens; ++I) {
6768 if (clang_getTokenKind(Tokens[I]) != CXToken_Identifier)
6769 continue;
6770
6771 if (Cursors[I].kind == CXCursor_ObjCPropertyDecl) {
6772 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006773 if (const ObjCPropertyDecl *Property
Guy Benyei11169dd2012-12-18 14:30:41 +00006774 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(Cursors[I]))) {
6775 if (Property->getPropertyAttributesAsWritten() != 0 &&
6776 llvm::StringSwitch<bool>(II->getName())
6777 .Case("readonly", true)
6778 .Case("assign", true)
6779 .Case("unsafe_unretained", true)
6780 .Case("readwrite", true)
6781 .Case("retain", true)
6782 .Case("copy", true)
6783 .Case("nonatomic", true)
6784 .Case("atomic", true)
6785 .Case("getter", true)
6786 .Case("setter", true)
6787 .Case("strong", true)
6788 .Case("weak", true)
6789 .Default(false))
6790 Tokens[I].int_data[0] = CXToken_Keyword;
6791 }
6792 continue;
6793 }
6794
6795 if (Cursors[I].kind == CXCursor_ObjCInstanceMethodDecl ||
6796 Cursors[I].kind == CXCursor_ObjCClassMethodDecl) {
6797 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
6798 if (llvm::StringSwitch<bool>(II->getName())
6799 .Case("in", true)
6800 .Case("out", true)
6801 .Case("inout", true)
6802 .Case("oneway", true)
6803 .Case("bycopy", true)
6804 .Case("byref", true)
6805 .Default(false))
6806 Tokens[I].int_data[0] = CXToken_Keyword;
6807 continue;
6808 }
6809
6810 if (Cursors[I].kind == CXCursor_CXXFinalAttr ||
6811 Cursors[I].kind == CXCursor_CXXOverrideAttr) {
6812 Tokens[I].int_data[0] = CXToken_Keyword;
6813 continue;
6814 }
6815 }
6816 }
6817}
6818
6819extern "C" {
6820
6821void clang_annotateTokens(CXTranslationUnit TU,
6822 CXToken *Tokens, unsigned NumTokens,
6823 CXCursor *Cursors) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006824 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006825 LOG_BAD_TU(TU);
6826 return;
6827 }
6828 if (NumTokens == 0 || !Tokens || !Cursors) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006829 LOG_FUNC_SECTION { *Log << "<null input>"; }
Guy Benyei11169dd2012-12-18 14:30:41 +00006830 return;
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006831 }
6832
6833 LOG_FUNC_SECTION {
6834 *Log << TU << ' ';
6835 CXSourceLocation bloc = clang_getTokenLocation(TU, Tokens[0]);
6836 CXSourceLocation eloc = clang_getTokenLocation(TU, Tokens[NumTokens-1]);
6837 *Log << clang_getRange(bloc, eloc);
6838 }
Guy Benyei11169dd2012-12-18 14:30:41 +00006839
6840 // Any token we don't specifically annotate will have a NULL cursor.
6841 CXCursor C = clang_getNullCursor();
6842 for (unsigned I = 0; I != NumTokens; ++I)
6843 Cursors[I] = C;
6844
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006845 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00006846 if (!CXXUnit)
6847 return;
6848
6849 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00006850
6851 auto AnnotateTokensImpl = [=]() {
6852 clang_annotateTokensImpl(TU, CXXUnit, Tokens, NumTokens, Cursors);
6853 };
Guy Benyei11169dd2012-12-18 14:30:41 +00006854 llvm::CrashRecoveryContext CRC;
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00006855 if (!RunSafely(CRC, AnnotateTokensImpl, GetSafetyThreadStackSize() * 2)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00006856 fprintf(stderr, "libclang: crash detected while annotating tokens\n");
6857 }
6858}
6859
6860} // end: extern "C"
6861
6862//===----------------------------------------------------------------------===//
6863// Operations for querying linkage of a cursor.
6864//===----------------------------------------------------------------------===//
6865
6866extern "C" {
6867CXLinkageKind clang_getCursorLinkage(CXCursor cursor) {
6868 if (!clang_isDeclaration(cursor.kind))
6869 return CXLinkage_Invalid;
6870
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006871 const Decl *D = cxcursor::getCursorDecl(cursor);
6872 if (const NamedDecl *ND = dyn_cast_or_null<NamedDecl>(D))
Rafael Espindola3ae00052013-05-13 00:12:11 +00006873 switch (ND->getLinkageInternal()) {
Rafael Espindola50df3a02013-05-25 17:16:20 +00006874 case NoLinkage:
6875 case VisibleNoLinkage: return CXLinkage_NoLinkage;
Guy Benyei11169dd2012-12-18 14:30:41 +00006876 case InternalLinkage: return CXLinkage_Internal;
6877 case UniqueExternalLinkage: return CXLinkage_UniqueExternal;
6878 case ExternalLinkage: return CXLinkage_External;
6879 };
6880
6881 return CXLinkage_Invalid;
6882}
6883} // end: extern "C"
6884
6885//===----------------------------------------------------------------------===//
Ehsan Akhgari93697fa2015-11-23 19:56:46 +00006886// Operations for querying visibility of a cursor.
6887//===----------------------------------------------------------------------===//
6888
6889extern "C" {
6890CXVisibilityKind clang_getCursorVisibility(CXCursor cursor) {
6891 if (!clang_isDeclaration(cursor.kind))
6892 return CXVisibility_Invalid;
6893
6894 const Decl *D = cxcursor::getCursorDecl(cursor);
6895 if (const NamedDecl *ND = dyn_cast_or_null<NamedDecl>(D))
6896 switch (ND->getVisibility()) {
6897 case HiddenVisibility: return CXVisibility_Hidden;
6898 case ProtectedVisibility: return CXVisibility_Protected;
6899 case DefaultVisibility: return CXVisibility_Default;
6900 };
6901
6902 return CXVisibility_Invalid;
6903}
6904} // end: extern "C"
6905
6906//===----------------------------------------------------------------------===//
Guy Benyei11169dd2012-12-18 14:30:41 +00006907// Operations for querying language of a cursor.
6908//===----------------------------------------------------------------------===//
6909
6910static CXLanguageKind getDeclLanguage(const Decl *D) {
6911 if (!D)
6912 return CXLanguage_C;
6913
6914 switch (D->getKind()) {
6915 default:
6916 break;
6917 case Decl::ImplicitParam:
6918 case Decl::ObjCAtDefsField:
6919 case Decl::ObjCCategory:
6920 case Decl::ObjCCategoryImpl:
6921 case Decl::ObjCCompatibleAlias:
6922 case Decl::ObjCImplementation:
6923 case Decl::ObjCInterface:
6924 case Decl::ObjCIvar:
6925 case Decl::ObjCMethod:
6926 case Decl::ObjCProperty:
6927 case Decl::ObjCPropertyImpl:
6928 case Decl::ObjCProtocol:
Douglas Gregor85f3f952015-07-07 03:57:15 +00006929 case Decl::ObjCTypeParam:
Guy Benyei11169dd2012-12-18 14:30:41 +00006930 return CXLanguage_ObjC;
6931 case Decl::CXXConstructor:
6932 case Decl::CXXConversion:
6933 case Decl::CXXDestructor:
6934 case Decl::CXXMethod:
6935 case Decl::CXXRecord:
6936 case Decl::ClassTemplate:
6937 case Decl::ClassTemplatePartialSpecialization:
6938 case Decl::ClassTemplateSpecialization:
6939 case Decl::Friend:
6940 case Decl::FriendTemplate:
6941 case Decl::FunctionTemplate:
6942 case Decl::LinkageSpec:
6943 case Decl::Namespace:
6944 case Decl::NamespaceAlias:
6945 case Decl::NonTypeTemplateParm:
6946 case Decl::StaticAssert:
6947 case Decl::TemplateTemplateParm:
6948 case Decl::TemplateTypeParm:
6949 case Decl::UnresolvedUsingTypename:
6950 case Decl::UnresolvedUsingValue:
6951 case Decl::Using:
6952 case Decl::UsingDirective:
6953 case Decl::UsingShadow:
6954 return CXLanguage_CPlusPlus;
6955 }
6956
6957 return CXLanguage_C;
6958}
6959
6960extern "C" {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006961
6962static CXAvailabilityKind getCursorAvailabilityForDecl(const Decl *D) {
6963 if (isa<FunctionDecl>(D) && cast<FunctionDecl>(D)->isDeleted())
Manuel Klimek8e3a7ed2015-09-25 17:53:16 +00006964 return CXAvailability_NotAvailable;
Guy Benyei11169dd2012-12-18 14:30:41 +00006965
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006966 switch (D->getAvailability()) {
6967 case AR_Available:
6968 case AR_NotYetIntroduced:
6969 if (const EnumConstantDecl *EnumConst = dyn_cast<EnumConstantDecl>(D))
Benjamin Kramer656363d2013-10-15 18:53:18 +00006970 return getCursorAvailabilityForDecl(
6971 cast<Decl>(EnumConst->getDeclContext()));
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006972 return CXAvailability_Available;
6973
6974 case AR_Deprecated:
6975 return CXAvailability_Deprecated;
6976
6977 case AR_Unavailable:
6978 return CXAvailability_NotAvailable;
6979 }
Benjamin Kramer656363d2013-10-15 18:53:18 +00006980
6981 llvm_unreachable("Unknown availability kind!");
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006982}
6983
Guy Benyei11169dd2012-12-18 14:30:41 +00006984enum CXAvailabilityKind clang_getCursorAvailability(CXCursor cursor) {
6985 if (clang_isDeclaration(cursor.kind))
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006986 if (const Decl *D = cxcursor::getCursorDecl(cursor))
6987 return getCursorAvailabilityForDecl(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00006988
6989 return CXAvailability_Available;
6990}
6991
6992static CXVersion convertVersion(VersionTuple In) {
6993 CXVersion Out = { -1, -1, -1 };
6994 if (In.empty())
6995 return Out;
6996
6997 Out.Major = In.getMajor();
6998
NAKAMURA Takumic2b5d1f2013-02-21 02:32:34 +00006999 Optional<unsigned> Minor = In.getMinor();
7000 if (Minor.hasValue())
Guy Benyei11169dd2012-12-18 14:30:41 +00007001 Out.Minor = *Minor;
7002 else
7003 return Out;
7004
NAKAMURA Takumic2b5d1f2013-02-21 02:32:34 +00007005 Optional<unsigned> Subminor = In.getSubminor();
7006 if (Subminor.hasValue())
Guy Benyei11169dd2012-12-18 14:30:41 +00007007 Out.Subminor = *Subminor;
7008
7009 return Out;
7010}
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00007011
7012static int getCursorPlatformAvailabilityForDecl(const Decl *D,
7013 int *always_deprecated,
7014 CXString *deprecated_message,
7015 int *always_unavailable,
7016 CXString *unavailable_message,
7017 CXPlatformAvailability *availability,
7018 int availability_size) {
7019 bool HadAvailAttr = false;
7020 int N = 0;
Aaron Ballmanb97112e2014-03-08 22:19:01 +00007021 for (auto A : D->attrs()) {
7022 if (DeprecatedAttr *Deprecated = dyn_cast<DeprecatedAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00007023 HadAvailAttr = true;
7024 if (always_deprecated)
7025 *always_deprecated = 1;
Nico Weberaacf0312014-04-24 05:16:45 +00007026 if (deprecated_message) {
Argyrios Kyrtzidisedfe07f2014-04-24 06:05:40 +00007027 clang_disposeString(*deprecated_message);
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00007028 *deprecated_message = cxstring::createDup(Deprecated->getMessage());
Nico Weberaacf0312014-04-24 05:16:45 +00007029 }
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00007030 continue;
7031 }
7032
Aaron Ballmanb97112e2014-03-08 22:19:01 +00007033 if (UnavailableAttr *Unavailable = dyn_cast<UnavailableAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00007034 HadAvailAttr = true;
7035 if (always_unavailable)
7036 *always_unavailable = 1;
7037 if (unavailable_message) {
Argyrios Kyrtzidisedfe07f2014-04-24 06:05:40 +00007038 clang_disposeString(*unavailable_message);
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00007039 *unavailable_message = cxstring::createDup(Unavailable->getMessage());
7040 }
7041 continue;
7042 }
7043
Aaron Ballmanb97112e2014-03-08 22:19:01 +00007044 if (AvailabilityAttr *Avail = dyn_cast<AvailabilityAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00007045 HadAvailAttr = true;
7046 if (N < availability_size) {
7047 availability[N].Platform
7048 = cxstring::createDup(Avail->getPlatform()->getName());
7049 availability[N].Introduced = convertVersion(Avail->getIntroduced());
7050 availability[N].Deprecated = convertVersion(Avail->getDeprecated());
7051 availability[N].Obsoleted = convertVersion(Avail->getObsoleted());
7052 availability[N].Unavailable = Avail->getUnavailable();
7053 availability[N].Message = cxstring::createDup(Avail->getMessage());
7054 }
7055 ++N;
7056 }
7057 }
7058
7059 if (!HadAvailAttr)
7060 if (const EnumConstantDecl *EnumConst = dyn_cast<EnumConstantDecl>(D))
7061 return getCursorPlatformAvailabilityForDecl(
7062 cast<Decl>(EnumConst->getDeclContext()),
7063 always_deprecated,
7064 deprecated_message,
7065 always_unavailable,
7066 unavailable_message,
7067 availability,
7068 availability_size);
Guy Benyei11169dd2012-12-18 14:30:41 +00007069
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00007070 return N;
7071}
7072
Guy Benyei11169dd2012-12-18 14:30:41 +00007073int clang_getCursorPlatformAvailability(CXCursor cursor,
7074 int *always_deprecated,
7075 CXString *deprecated_message,
7076 int *always_unavailable,
7077 CXString *unavailable_message,
7078 CXPlatformAvailability *availability,
7079 int availability_size) {
7080 if (always_deprecated)
7081 *always_deprecated = 0;
7082 if (deprecated_message)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00007083 *deprecated_message = cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00007084 if (always_unavailable)
7085 *always_unavailable = 0;
7086 if (unavailable_message)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00007087 *unavailable_message = cxstring::createEmpty();
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00007088
Guy Benyei11169dd2012-12-18 14:30:41 +00007089 if (!clang_isDeclaration(cursor.kind))
7090 return 0;
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00007091
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00007092 const Decl *D = cxcursor::getCursorDecl(cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00007093 if (!D)
7094 return 0;
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00007095
7096 return getCursorPlatformAvailabilityForDecl(D, always_deprecated,
7097 deprecated_message,
7098 always_unavailable,
7099 unavailable_message,
7100 availability,
7101 availability_size);
Guy Benyei11169dd2012-12-18 14:30:41 +00007102}
7103
7104void clang_disposeCXPlatformAvailability(CXPlatformAvailability *availability) {
7105 clang_disposeString(availability->Platform);
7106 clang_disposeString(availability->Message);
7107}
7108
7109CXLanguageKind clang_getCursorLanguage(CXCursor cursor) {
7110 if (clang_isDeclaration(cursor.kind))
7111 return getDeclLanguage(cxcursor::getCursorDecl(cursor));
7112
7113 return CXLanguage_Invalid;
7114}
7115
7116 /// \brief If the given cursor is the "templated" declaration
7117 /// descibing a class or function template, return the class or
7118 /// function template.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00007119static const Decl *maybeGetTemplateCursor(const Decl *D) {
Guy Benyei11169dd2012-12-18 14:30:41 +00007120 if (!D)
Craig Topper69186e72014-06-08 08:38:04 +00007121 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00007122
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00007123 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00007124 if (FunctionTemplateDecl *FunTmpl = FD->getDescribedFunctionTemplate())
7125 return FunTmpl;
7126
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00007127 if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00007128 if (ClassTemplateDecl *ClassTmpl = RD->getDescribedClassTemplate())
7129 return ClassTmpl;
7130
7131 return D;
7132}
7133
Argyrios Kyrtzidis4e0854f2014-10-15 17:05:31 +00007134
7135enum CX_StorageClass clang_Cursor_getStorageClass(CXCursor C) {
7136 StorageClass sc = SC_None;
7137 const Decl *D = getCursorDecl(C);
7138 if (D) {
7139 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
7140 sc = FD->getStorageClass();
7141 } else if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
7142 sc = VD->getStorageClass();
7143 } else {
7144 return CX_SC_Invalid;
7145 }
7146 } else {
7147 return CX_SC_Invalid;
7148 }
7149 switch (sc) {
7150 case SC_None:
7151 return CX_SC_None;
7152 case SC_Extern:
7153 return CX_SC_Extern;
7154 case SC_Static:
7155 return CX_SC_Static;
7156 case SC_PrivateExtern:
7157 return CX_SC_PrivateExtern;
Argyrios Kyrtzidis4e0854f2014-10-15 17:05:31 +00007158 case SC_Auto:
7159 return CX_SC_Auto;
7160 case SC_Register:
7161 return CX_SC_Register;
Argyrios Kyrtzidis4e0854f2014-10-15 17:05:31 +00007162 }
Kaelyn Takataab61e702014-10-15 18:03:26 +00007163 llvm_unreachable("Unhandled storage class!");
Argyrios Kyrtzidis4e0854f2014-10-15 17:05:31 +00007164}
7165
Guy Benyei11169dd2012-12-18 14:30:41 +00007166CXCursor clang_getCursorSemanticParent(CXCursor cursor) {
7167 if (clang_isDeclaration(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00007168 if (const Decl *D = getCursorDecl(cursor)) {
7169 const DeclContext *DC = D->getDeclContext();
Guy Benyei11169dd2012-12-18 14:30:41 +00007170 if (!DC)
7171 return clang_getNullCursor();
7172
7173 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
7174 getCursorTU(cursor));
7175 }
7176 }
7177
7178 if (clang_isStatement(cursor.kind) || clang_isExpression(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00007179 if (const Decl *D = getCursorDecl(cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +00007180 return MakeCXCursor(D, getCursorTU(cursor));
7181 }
7182
7183 return clang_getNullCursor();
7184}
7185
7186CXCursor clang_getCursorLexicalParent(CXCursor cursor) {
7187 if (clang_isDeclaration(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00007188 if (const Decl *D = getCursorDecl(cursor)) {
7189 const DeclContext *DC = D->getLexicalDeclContext();
Guy Benyei11169dd2012-12-18 14:30:41 +00007190 if (!DC)
7191 return clang_getNullCursor();
7192
7193 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
7194 getCursorTU(cursor));
7195 }
7196 }
7197
7198 // FIXME: Note that we can't easily compute the lexical context of a
7199 // statement or expression, so we return nothing.
7200 return clang_getNullCursor();
7201}
7202
7203CXFile clang_getIncludedFile(CXCursor cursor) {
7204 if (cursor.kind != CXCursor_InclusionDirective)
Craig Topper69186e72014-06-08 08:38:04 +00007205 return nullptr;
7206
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00007207 const InclusionDirective *ID = getCursorInclusionDirective(cursor);
Dmitri Gribenkof9304482013-01-23 15:56:07 +00007208 return const_cast<FileEntry *>(ID->getFile());
Guy Benyei11169dd2012-12-18 14:30:41 +00007209}
7210
Argyrios Kyrtzidis9adfd8a2013-04-18 22:15:49 +00007211unsigned clang_Cursor_getObjCPropertyAttributes(CXCursor C, unsigned reserved) {
7212 if (C.kind != CXCursor_ObjCPropertyDecl)
7213 return CXObjCPropertyAttr_noattr;
7214
7215 unsigned Result = CXObjCPropertyAttr_noattr;
7216 const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(getCursorDecl(C));
7217 ObjCPropertyDecl::PropertyAttributeKind Attr =
7218 PD->getPropertyAttributesAsWritten();
7219
7220#define SET_CXOBJCPROP_ATTR(A) \
7221 if (Attr & ObjCPropertyDecl::OBJC_PR_##A) \
7222 Result |= CXObjCPropertyAttr_##A
7223 SET_CXOBJCPROP_ATTR(readonly);
7224 SET_CXOBJCPROP_ATTR(getter);
7225 SET_CXOBJCPROP_ATTR(assign);
7226 SET_CXOBJCPROP_ATTR(readwrite);
7227 SET_CXOBJCPROP_ATTR(retain);
7228 SET_CXOBJCPROP_ATTR(copy);
7229 SET_CXOBJCPROP_ATTR(nonatomic);
7230 SET_CXOBJCPROP_ATTR(setter);
7231 SET_CXOBJCPROP_ATTR(atomic);
7232 SET_CXOBJCPROP_ATTR(weak);
7233 SET_CXOBJCPROP_ATTR(strong);
7234 SET_CXOBJCPROP_ATTR(unsafe_unretained);
7235#undef SET_CXOBJCPROP_ATTR
7236
7237 return Result;
7238}
7239
Argyrios Kyrtzidis9d9bc012013-04-18 23:29:12 +00007240unsigned clang_Cursor_getObjCDeclQualifiers(CXCursor C) {
7241 if (!clang_isDeclaration(C.kind))
7242 return CXObjCDeclQualifier_None;
7243
7244 Decl::ObjCDeclQualifier QT = Decl::OBJC_TQ_None;
7245 const Decl *D = getCursorDecl(C);
7246 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
7247 QT = MD->getObjCDeclQualifier();
7248 else if (const ParmVarDecl *PD = dyn_cast<ParmVarDecl>(D))
7249 QT = PD->getObjCDeclQualifier();
7250 if (QT == Decl::OBJC_TQ_None)
7251 return CXObjCDeclQualifier_None;
7252
7253 unsigned Result = CXObjCDeclQualifier_None;
7254 if (QT & Decl::OBJC_TQ_In) Result |= CXObjCDeclQualifier_In;
7255 if (QT & Decl::OBJC_TQ_Inout) Result |= CXObjCDeclQualifier_Inout;
7256 if (QT & Decl::OBJC_TQ_Out) Result |= CXObjCDeclQualifier_Out;
7257 if (QT & Decl::OBJC_TQ_Bycopy) Result |= CXObjCDeclQualifier_Bycopy;
7258 if (QT & Decl::OBJC_TQ_Byref) Result |= CXObjCDeclQualifier_Byref;
7259 if (QT & Decl::OBJC_TQ_Oneway) Result |= CXObjCDeclQualifier_Oneway;
7260
7261 return Result;
7262}
7263
Argyrios Kyrtzidis7b50fc52013-07-05 20:44:37 +00007264unsigned clang_Cursor_isObjCOptional(CXCursor C) {
7265 if (!clang_isDeclaration(C.kind))
7266 return 0;
7267
7268 const Decl *D = getCursorDecl(C);
7269 if (const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(D))
7270 return PD->getPropertyImplementation() == ObjCPropertyDecl::Optional;
7271 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
7272 return MD->getImplementationControl() == ObjCMethodDecl::Optional;
7273
7274 return 0;
7275}
7276
Argyrios Kyrtzidis23814e42013-04-18 23:53:05 +00007277unsigned clang_Cursor_isVariadic(CXCursor C) {
7278 if (!clang_isDeclaration(C.kind))
7279 return 0;
7280
7281 const Decl *D = getCursorDecl(C);
7282 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
7283 return FD->isVariadic();
7284 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
7285 return MD->isVariadic();
7286
7287 return 0;
7288}
7289
Guy Benyei11169dd2012-12-18 14:30:41 +00007290CXSourceRange clang_Cursor_getCommentRange(CXCursor C) {
7291 if (!clang_isDeclaration(C.kind))
7292 return clang_getNullRange();
7293
7294 const Decl *D = getCursorDecl(C);
7295 ASTContext &Context = getCursorContext(C);
7296 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
7297 if (!RC)
7298 return clang_getNullRange();
7299
7300 return cxloc::translateSourceRange(Context, RC->getSourceRange());
7301}
7302
7303CXString clang_Cursor_getRawCommentText(CXCursor C) {
7304 if (!clang_isDeclaration(C.kind))
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00007305 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00007306
7307 const Decl *D = getCursorDecl(C);
7308 ASTContext &Context = getCursorContext(C);
7309 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
7310 StringRef RawText = RC ? RC->getRawText(Context.getSourceManager()) :
7311 StringRef();
7312
7313 // Don't duplicate the string because RawText points directly into source
7314 // code.
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00007315 return cxstring::createRef(RawText);
Guy Benyei11169dd2012-12-18 14:30:41 +00007316}
7317
7318CXString clang_Cursor_getBriefCommentText(CXCursor C) {
7319 if (!clang_isDeclaration(C.kind))
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00007320 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00007321
7322 const Decl *D = getCursorDecl(C);
7323 const ASTContext &Context = getCursorContext(C);
7324 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
7325
7326 if (RC) {
7327 StringRef BriefText = RC->getBriefText(Context);
7328
7329 // Don't duplicate the string because RawComment ensures that this memory
7330 // will not go away.
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00007331 return cxstring::createRef(BriefText);
Guy Benyei11169dd2012-12-18 14:30:41 +00007332 }
7333
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00007334 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00007335}
7336
Guy Benyei11169dd2012-12-18 14:30:41 +00007337CXModule clang_Cursor_getModule(CXCursor C) {
7338 if (C.kind == CXCursor_ModuleImportDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00007339 if (const ImportDecl *ImportD =
7340 dyn_cast_or_null<ImportDecl>(getCursorDecl(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00007341 return ImportD->getImportedModule();
7342 }
7343
Craig Topper69186e72014-06-08 08:38:04 +00007344 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00007345}
7346
Argyrios Kyrtzidisf6d49c32014-05-14 23:14:37 +00007347CXModule clang_getModuleForFile(CXTranslationUnit TU, CXFile File) {
7348 if (isNotUsableTU(TU)) {
7349 LOG_BAD_TU(TU);
7350 return nullptr;
7351 }
7352 if (!File)
7353 return nullptr;
7354 FileEntry *FE = static_cast<FileEntry *>(File);
7355
7356 ASTUnit &Unit = *cxtu::getASTUnit(TU);
7357 HeaderSearch &HS = Unit.getPreprocessor().getHeaderSearchInfo();
7358 ModuleMap::KnownHeader Header = HS.findModuleForHeader(FE);
7359
Richard Smithfeb54b62014-10-23 02:01:19 +00007360 return Header.getModule();
Argyrios Kyrtzidisf6d49c32014-05-14 23:14:37 +00007361}
7362
Argyrios Kyrtzidis12fdb9e2013-04-26 22:47:49 +00007363CXFile clang_Module_getASTFile(CXModule CXMod) {
7364 if (!CXMod)
Craig Topper69186e72014-06-08 08:38:04 +00007365 return nullptr;
Argyrios Kyrtzidis12fdb9e2013-04-26 22:47:49 +00007366 Module *Mod = static_cast<Module*>(CXMod);
7367 return const_cast<FileEntry *>(Mod->getASTFile());
7368}
7369
Guy Benyei11169dd2012-12-18 14:30:41 +00007370CXModule clang_Module_getParent(CXModule CXMod) {
7371 if (!CXMod)
Craig Topper69186e72014-06-08 08:38:04 +00007372 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00007373 Module *Mod = static_cast<Module*>(CXMod);
7374 return Mod->Parent;
7375}
7376
7377CXString clang_Module_getName(CXModule CXMod) {
7378 if (!CXMod)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00007379 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00007380 Module *Mod = static_cast<Module*>(CXMod);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00007381 return cxstring::createDup(Mod->Name);
Guy Benyei11169dd2012-12-18 14:30:41 +00007382}
7383
7384CXString clang_Module_getFullName(CXModule CXMod) {
7385 if (!CXMod)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00007386 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00007387 Module *Mod = static_cast<Module*>(CXMod);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00007388 return cxstring::createDup(Mod->getFullModuleName());
Guy Benyei11169dd2012-12-18 14:30:41 +00007389}
7390
Argyrios Kyrtzidis884337f2014-05-15 04:44:25 +00007391int clang_Module_isSystem(CXModule CXMod) {
7392 if (!CXMod)
7393 return 0;
7394 Module *Mod = static_cast<Module*>(CXMod);
7395 return Mod->IsSystem;
7396}
7397
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00007398unsigned clang_Module_getNumTopLevelHeaders(CXTranslationUnit TU,
7399 CXModule CXMod) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00007400 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00007401 LOG_BAD_TU(TU);
7402 return 0;
7403 }
7404 if (!CXMod)
Guy Benyei11169dd2012-12-18 14:30:41 +00007405 return 0;
7406 Module *Mod = static_cast<Module*>(CXMod);
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00007407 FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
7408 ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
7409 return TopHeaders.size();
Guy Benyei11169dd2012-12-18 14:30:41 +00007410}
7411
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00007412CXFile clang_Module_getTopLevelHeader(CXTranslationUnit TU,
7413 CXModule CXMod, unsigned Index) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00007414 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00007415 LOG_BAD_TU(TU);
Craig Topper69186e72014-06-08 08:38:04 +00007416 return nullptr;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00007417 }
7418 if (!CXMod)
Craig Topper69186e72014-06-08 08:38:04 +00007419 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00007420 Module *Mod = static_cast<Module*>(CXMod);
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00007421 FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
Guy Benyei11169dd2012-12-18 14:30:41 +00007422
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00007423 ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
7424 if (Index < TopHeaders.size())
7425 return const_cast<FileEntry *>(TopHeaders[Index]);
Guy Benyei11169dd2012-12-18 14:30:41 +00007426
Craig Topper69186e72014-06-08 08:38:04 +00007427 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00007428}
7429
7430} // end: extern "C"
7431
7432//===----------------------------------------------------------------------===//
7433// C++ AST instrospection.
7434//===----------------------------------------------------------------------===//
7435
7436extern "C" {
Saleem Abdulrasool6ea75db2015-10-27 15:50:22 +00007437unsigned clang_CXXField_isMutable(CXCursor C) {
7438 if (!clang_isDeclaration(C.kind))
7439 return 0;
7440
7441 if (const auto D = cxcursor::getCursorDecl(C))
7442 if (const auto FD = dyn_cast_or_null<FieldDecl>(D))
7443 return FD->isMutable() ? 1 : 0;
7444 return 0;
7445}
7446
Dmitri Gribenko62770be2013-05-17 18:38:35 +00007447unsigned clang_CXXMethod_isPureVirtual(CXCursor C) {
7448 if (!clang_isDeclaration(C.kind))
7449 return 0;
7450
Dmitri Gribenko62770be2013-05-17 18:38:35 +00007451 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00007452 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00007453 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Dmitri Gribenko62770be2013-05-17 18:38:35 +00007454 return (Method && Method->isVirtual() && Method->isPure()) ? 1 : 0;
7455}
7456
Dmitri Gribenkoe570ede2014-04-07 14:59:13 +00007457unsigned clang_CXXMethod_isConst(CXCursor C) {
7458 if (!clang_isDeclaration(C.kind))
7459 return 0;
7460
7461 const Decl *D = cxcursor::getCursorDecl(C);
7462 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00007463 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Dmitri Gribenkoe570ede2014-04-07 14:59:13 +00007464 return (Method && (Method->getTypeQualifiers() & Qualifiers::Const)) ? 1 : 0;
7465}
7466
Guy Benyei11169dd2012-12-18 14:30:41 +00007467unsigned clang_CXXMethod_isStatic(CXCursor C) {
7468 if (!clang_isDeclaration(C.kind))
7469 return 0;
7470
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00007471 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00007472 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00007473 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00007474 return (Method && Method->isStatic()) ? 1 : 0;
7475}
7476
7477unsigned clang_CXXMethod_isVirtual(CXCursor C) {
7478 if (!clang_isDeclaration(C.kind))
7479 return 0;
7480
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00007481 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00007482 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00007483 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00007484 return (Method && Method->isVirtual()) ? 1 : 0;
7485}
7486} // end: extern "C"
7487
7488//===----------------------------------------------------------------------===//
7489// Attribute introspection.
7490//===----------------------------------------------------------------------===//
7491
7492extern "C" {
7493CXType clang_getIBOutletCollectionType(CXCursor C) {
7494 if (C.kind != CXCursor_IBOutletCollectionAttr)
7495 return cxtype::MakeCXType(QualType(), cxcursor::getCursorTU(C));
7496
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00007497 const IBOutletCollectionAttr *A =
Guy Benyei11169dd2012-12-18 14:30:41 +00007498 cast<IBOutletCollectionAttr>(cxcursor::getCursorAttr(C));
7499
7500 return cxtype::MakeCXType(A->getInterface(), cxcursor::getCursorTU(C));
7501}
7502} // end: extern "C"
7503
7504//===----------------------------------------------------------------------===//
7505// Inspecting memory usage.
7506//===----------------------------------------------------------------------===//
7507
7508typedef std::vector<CXTUResourceUsageEntry> MemUsageEntries;
7509
7510static inline void createCXTUResourceUsageEntry(MemUsageEntries &entries,
7511 enum CXTUResourceUsageKind k,
7512 unsigned long amount) {
7513 CXTUResourceUsageEntry entry = { k, amount };
7514 entries.push_back(entry);
7515}
7516
7517extern "C" {
7518
7519const char *clang_getTUResourceUsageName(CXTUResourceUsageKind kind) {
7520 const char *str = "";
7521 switch (kind) {
7522 case CXTUResourceUsage_AST:
7523 str = "ASTContext: expressions, declarations, and types";
7524 break;
7525 case CXTUResourceUsage_Identifiers:
7526 str = "ASTContext: identifiers";
7527 break;
7528 case CXTUResourceUsage_Selectors:
7529 str = "ASTContext: selectors";
7530 break;
7531 case CXTUResourceUsage_GlobalCompletionResults:
7532 str = "Code completion: cached global results";
7533 break;
7534 case CXTUResourceUsage_SourceManagerContentCache:
7535 str = "SourceManager: content cache allocator";
7536 break;
7537 case CXTUResourceUsage_AST_SideTables:
7538 str = "ASTContext: side tables";
7539 break;
7540 case CXTUResourceUsage_SourceManager_Membuffer_Malloc:
7541 str = "SourceManager: malloc'ed memory buffers";
7542 break;
7543 case CXTUResourceUsage_SourceManager_Membuffer_MMap:
7544 str = "SourceManager: mmap'ed memory buffers";
7545 break;
7546 case CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc:
7547 str = "ExternalASTSource: malloc'ed memory buffers";
7548 break;
7549 case CXTUResourceUsage_ExternalASTSource_Membuffer_MMap:
7550 str = "ExternalASTSource: mmap'ed memory buffers";
7551 break;
7552 case CXTUResourceUsage_Preprocessor:
7553 str = "Preprocessor: malloc'ed memory";
7554 break;
7555 case CXTUResourceUsage_PreprocessingRecord:
7556 str = "Preprocessor: PreprocessingRecord";
7557 break;
7558 case CXTUResourceUsage_SourceManager_DataStructures:
7559 str = "SourceManager: data structures and tables";
7560 break;
7561 case CXTUResourceUsage_Preprocessor_HeaderSearch:
7562 str = "Preprocessor: header search tables";
7563 break;
7564 }
7565 return str;
7566}
7567
7568CXTUResourceUsage clang_getCXTUResourceUsage(CXTranslationUnit TU) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00007569 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00007570 LOG_BAD_TU(TU);
Craig Topper69186e72014-06-08 08:38:04 +00007571 CXTUResourceUsage usage = { (void*) nullptr, 0, nullptr };
Guy Benyei11169dd2012-12-18 14:30:41 +00007572 return usage;
7573 }
7574
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007575 ASTUnit *astUnit = cxtu::getASTUnit(TU);
Ahmed Charlesb8984322014-03-07 20:03:18 +00007576 std::unique_ptr<MemUsageEntries> entries(new MemUsageEntries());
Guy Benyei11169dd2012-12-18 14:30:41 +00007577 ASTContext &astContext = astUnit->getASTContext();
7578
7579 // How much memory is used by AST nodes and types?
7580 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST,
7581 (unsigned long) astContext.getASTAllocatedMemory());
7582
7583 // How much memory is used by identifiers?
7584 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Identifiers,
7585 (unsigned long) astContext.Idents.getAllocator().getTotalMemory());
7586
7587 // How much memory is used for selectors?
7588 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Selectors,
7589 (unsigned long) astContext.Selectors.getTotalMemory());
7590
7591 // How much memory is used by ASTContext's side tables?
7592 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST_SideTables,
7593 (unsigned long) astContext.getSideTableAllocatedMemory());
7594
7595 // How much memory is used for caching global code completion results?
7596 unsigned long completionBytes = 0;
7597 if (GlobalCodeCompletionAllocator *completionAllocator =
Alp Tokerf994cef2014-07-05 03:08:06 +00007598 astUnit->getCachedCompletionAllocator().get()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00007599 completionBytes = completionAllocator->getTotalMemory();
7600 }
7601 createCXTUResourceUsageEntry(*entries,
7602 CXTUResourceUsage_GlobalCompletionResults,
7603 completionBytes);
7604
7605 // How much memory is being used by SourceManager's content cache?
7606 createCXTUResourceUsageEntry(*entries,
7607 CXTUResourceUsage_SourceManagerContentCache,
7608 (unsigned long) astContext.getSourceManager().getContentCacheSize());
7609
7610 // How much memory is being used by the MemoryBuffer's in SourceManager?
7611 const SourceManager::MemoryBufferSizes &srcBufs =
7612 astUnit->getSourceManager().getMemoryBufferSizes();
7613
7614 createCXTUResourceUsageEntry(*entries,
7615 CXTUResourceUsage_SourceManager_Membuffer_Malloc,
7616 (unsigned long) srcBufs.malloc_bytes);
7617 createCXTUResourceUsageEntry(*entries,
7618 CXTUResourceUsage_SourceManager_Membuffer_MMap,
7619 (unsigned long) srcBufs.mmap_bytes);
7620 createCXTUResourceUsageEntry(*entries,
7621 CXTUResourceUsage_SourceManager_DataStructures,
7622 (unsigned long) astContext.getSourceManager()
7623 .getDataStructureSizes());
7624
7625 // How much memory is being used by the ExternalASTSource?
7626 if (ExternalASTSource *esrc = astContext.getExternalSource()) {
7627 const ExternalASTSource::MemoryBufferSizes &sizes =
7628 esrc->getMemoryBufferSizes();
7629
7630 createCXTUResourceUsageEntry(*entries,
7631 CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc,
7632 (unsigned long) sizes.malloc_bytes);
7633 createCXTUResourceUsageEntry(*entries,
7634 CXTUResourceUsage_ExternalASTSource_Membuffer_MMap,
7635 (unsigned long) sizes.mmap_bytes);
7636 }
7637
7638 // How much memory is being used by the Preprocessor?
7639 Preprocessor &pp = astUnit->getPreprocessor();
7640 createCXTUResourceUsageEntry(*entries,
7641 CXTUResourceUsage_Preprocessor,
7642 pp.getTotalMemory());
7643
7644 if (PreprocessingRecord *pRec = pp.getPreprocessingRecord()) {
7645 createCXTUResourceUsageEntry(*entries,
7646 CXTUResourceUsage_PreprocessingRecord,
7647 pRec->getTotalMemory());
7648 }
7649
7650 createCXTUResourceUsageEntry(*entries,
7651 CXTUResourceUsage_Preprocessor_HeaderSearch,
7652 pp.getHeaderSearchInfo().getTotalMemory());
Craig Topper69186e72014-06-08 08:38:04 +00007653
Guy Benyei11169dd2012-12-18 14:30:41 +00007654 CXTUResourceUsage usage = { (void*) entries.get(),
7655 (unsigned) entries->size(),
Alexander Kornienko6ee521c2015-01-23 15:36:10 +00007656 !entries->empty() ? &(*entries)[0] : nullptr };
Ahmed Charles9a16beb2014-03-07 19:33:25 +00007657 entries.release();
Guy Benyei11169dd2012-12-18 14:30:41 +00007658 return usage;
7659}
7660
7661void clang_disposeCXTUResourceUsage(CXTUResourceUsage usage) {
7662 if (usage.data)
7663 delete (MemUsageEntries*) usage.data;
7664}
7665
Argyrios Kyrtzidis0e282ef2013-12-06 18:55:45 +00007666CXSourceRangeList *clang_getSkippedRanges(CXTranslationUnit TU, CXFile file) {
7667 CXSourceRangeList *skipped = new CXSourceRangeList;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00007668 skipped->count = 0;
Craig Topper69186e72014-06-08 08:38:04 +00007669 skipped->ranges = nullptr;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00007670
Dmitri Gribenko852d6222014-02-11 15:02:48 +00007671 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00007672 LOG_BAD_TU(TU);
7673 return skipped;
7674 }
7675
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00007676 if (!file)
7677 return skipped;
7678
7679 ASTUnit *astUnit = cxtu::getASTUnit(TU);
7680 PreprocessingRecord *ppRec = astUnit->getPreprocessor().getPreprocessingRecord();
7681 if (!ppRec)
7682 return skipped;
7683
7684 ASTContext &Ctx = astUnit->getASTContext();
7685 SourceManager &sm = Ctx.getSourceManager();
7686 FileEntry *fileEntry = static_cast<FileEntry *>(file);
7687 FileID wantedFileID = sm.translateFile(fileEntry);
7688
7689 const std::vector<SourceRange> &SkippedRanges = ppRec->getSkippedRanges();
7690 std::vector<SourceRange> wantedRanges;
7691 for (std::vector<SourceRange>::const_iterator i = SkippedRanges.begin(), ei = SkippedRanges.end();
7692 i != ei; ++i) {
7693 if (sm.getFileID(i->getBegin()) == wantedFileID || sm.getFileID(i->getEnd()) == wantedFileID)
7694 wantedRanges.push_back(*i);
7695 }
7696
7697 skipped->count = wantedRanges.size();
7698 skipped->ranges = new CXSourceRange[skipped->count];
7699 for (unsigned i = 0, ei = skipped->count; i != ei; ++i)
7700 skipped->ranges[i] = cxloc::translateSourceRange(Ctx, wantedRanges[i]);
7701
7702 return skipped;
7703}
7704
Argyrios Kyrtzidis0e282ef2013-12-06 18:55:45 +00007705void clang_disposeSourceRangeList(CXSourceRangeList *ranges) {
7706 if (ranges) {
7707 delete[] ranges->ranges;
7708 delete ranges;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00007709 }
7710}
7711
Guy Benyei11169dd2012-12-18 14:30:41 +00007712} // end extern "C"
7713
7714void clang::PrintLibclangResourceUsage(CXTranslationUnit TU) {
7715 CXTUResourceUsage Usage = clang_getCXTUResourceUsage(TU);
7716 for (unsigned I = 0; I != Usage.numEntries; ++I)
7717 fprintf(stderr, " %s: %lu\n",
7718 clang_getTUResourceUsageName(Usage.entries[I].kind),
7719 Usage.entries[I].amount);
7720
7721 clang_disposeCXTUResourceUsage(Usage);
7722}
7723
7724//===----------------------------------------------------------------------===//
7725// Misc. utility functions.
7726//===----------------------------------------------------------------------===//
7727
7728/// Default to using an 8 MB stack size on "safety" threads.
7729static unsigned SafetyStackThreadSize = 8 << 20;
7730
7731namespace clang {
7732
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00007733bool RunSafely(llvm::CrashRecoveryContext &CRC, llvm::function_ref<void()> Fn,
Guy Benyei11169dd2012-12-18 14:30:41 +00007734 unsigned Size) {
7735 if (!Size)
7736 Size = GetSafetyThreadStackSize();
7737 if (Size)
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00007738 return CRC.RunSafelyOnThread(Fn, Size);
7739 return CRC.RunSafely(Fn);
Guy Benyei11169dd2012-12-18 14:30:41 +00007740}
7741
7742unsigned GetSafetyThreadStackSize() {
7743 return SafetyStackThreadSize;
7744}
7745
7746void SetSafetyThreadStackSize(unsigned Value) {
7747 SafetyStackThreadSize = Value;
7748}
7749
Alexander Kornienkoab9db512015-06-22 23:07:51 +00007750}
Guy Benyei11169dd2012-12-18 14:30:41 +00007751
7752void clang::setThreadBackgroundPriority() {
7753 if (getenv("LIBCLANG_BGPRIO_DISABLE"))
7754 return;
7755
Alp Toker1a86ad22014-07-06 06:24:00 +00007756#ifdef USE_DARWIN_THREADS
Guy Benyei11169dd2012-12-18 14:30:41 +00007757 setpriority(PRIO_DARWIN_THREAD, 0, PRIO_DARWIN_BG);
7758#endif
7759}
7760
7761void cxindex::printDiagsToStderr(ASTUnit *Unit) {
7762 if (!Unit)
7763 return;
7764
7765 for (ASTUnit::stored_diag_iterator D = Unit->stored_diag_begin(),
7766 DEnd = Unit->stored_diag_end();
7767 D != DEnd; ++D) {
Ben Langmuir749323f2014-04-22 17:40:12 +00007768 CXStoredDiagnostic Diag(*D, Unit->getLangOpts());
Guy Benyei11169dd2012-12-18 14:30:41 +00007769 CXString Msg = clang_formatDiagnostic(&Diag,
7770 clang_defaultDiagnosticDisplayOptions());
7771 fprintf(stderr, "%s\n", clang_getCString(Msg));
7772 clang_disposeString(Msg);
7773 }
7774#ifdef LLVM_ON_WIN32
7775 // On Windows, force a flush, since there may be multiple copies of
7776 // stderr and stdout in the file system, all with different buffers
7777 // but writing to the same device.
7778 fflush(stderr);
7779#endif
7780}
7781
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007782MacroInfo *cxindex::getMacroInfo(const IdentifierInfo &II,
7783 SourceLocation MacroDefLoc,
7784 CXTranslationUnit TU){
7785 if (MacroDefLoc.isInvalid() || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00007786 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007787 if (!II.hadMacroDefinition())
Craig Topper69186e72014-06-08 08:38:04 +00007788 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007789
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007790 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00007791 Preprocessor &PP = Unit->getPreprocessor();
Richard Smith20e883e2015-04-29 23:20:19 +00007792 MacroDirective *MD = PP.getLocalMacroDirectiveHistory(&II);
Argyrios Kyrtzidisb6210df2013-03-26 17:17:01 +00007793 if (MD) {
7794 for (MacroDirective::DefInfo
7795 Def = MD->getDefinition(); Def; Def = Def.getPreviousDefinition()) {
7796 if (MacroDefLoc == Def.getMacroInfo()->getDefinitionLoc())
7797 return Def.getMacroInfo();
7798 }
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007799 }
7800
Craig Topper69186e72014-06-08 08:38:04 +00007801 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007802}
7803
Richard Smith66a81862015-05-04 02:25:31 +00007804const MacroInfo *cxindex::getMacroInfo(const MacroDefinitionRecord *MacroDef,
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00007805 CXTranslationUnit TU) {
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007806 if (!MacroDef || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00007807 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007808 const IdentifierInfo *II = MacroDef->getName();
7809 if (!II)
Craig Topper69186e72014-06-08 08:38:04 +00007810 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007811
7812 return getMacroInfo(*II, MacroDef->getLocation(), TU);
7813}
7814
Richard Smith66a81862015-05-04 02:25:31 +00007815MacroDefinitionRecord *
7816cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI, const Token &Tok,
7817 CXTranslationUnit TU) {
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007818 if (!MI || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00007819 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007820 if (Tok.isNot(tok::raw_identifier))
Craig Topper69186e72014-06-08 08:38:04 +00007821 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007822
7823 if (MI->getNumTokens() == 0)
Craig Topper69186e72014-06-08 08:38:04 +00007824 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007825 SourceRange DefRange(MI->getReplacementToken(0).getLocation(),
7826 MI->getDefinitionEndLoc());
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007827 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007828
7829 // Check that the token is inside the definition and not its argument list.
7830 SourceManager &SM = Unit->getSourceManager();
7831 if (SM.isBeforeInTranslationUnit(Tok.getLocation(), DefRange.getBegin()))
Craig Topper69186e72014-06-08 08:38:04 +00007832 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007833 if (SM.isBeforeInTranslationUnit(DefRange.getEnd(), Tok.getLocation()))
Craig Topper69186e72014-06-08 08:38:04 +00007834 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007835
7836 Preprocessor &PP = Unit->getPreprocessor();
7837 PreprocessingRecord *PPRec = PP.getPreprocessingRecord();
7838 if (!PPRec)
Craig Topper69186e72014-06-08 08:38:04 +00007839 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007840
Alp Toker2d57cea2014-05-17 04:53:25 +00007841 IdentifierInfo &II = PP.getIdentifierTable().get(Tok.getRawIdentifier());
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007842 if (!II.hadMacroDefinition())
Craig Topper69186e72014-06-08 08:38:04 +00007843 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007844
7845 // Check that the identifier is not one of the macro arguments.
7846 if (std::find(MI->arg_begin(), MI->arg_end(), &II) != MI->arg_end())
Craig Topper69186e72014-06-08 08:38:04 +00007847 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007848
Richard Smith20e883e2015-04-29 23:20:19 +00007849 MacroDirective *InnerMD = PP.getLocalMacroDirectiveHistory(&II);
Argyrios Kyrtzidis09c9e812013-02-20 00:54:57 +00007850 if (!InnerMD)
Craig Topper69186e72014-06-08 08:38:04 +00007851 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007852
Argyrios Kyrtzidisb6210df2013-03-26 17:17:01 +00007853 return PPRec->findMacroDefinition(InnerMD->getMacroInfo());
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007854}
7855
Richard Smith66a81862015-05-04 02:25:31 +00007856MacroDefinitionRecord *
7857cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI, SourceLocation Loc,
7858 CXTranslationUnit TU) {
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007859 if (Loc.isInvalid() || !MI || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00007860 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007861
7862 if (MI->getNumTokens() == 0)
Craig Topper69186e72014-06-08 08:38:04 +00007863 return nullptr;
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007864 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007865 Preprocessor &PP = Unit->getPreprocessor();
7866 if (!PP.getPreprocessingRecord())
Craig Topper69186e72014-06-08 08:38:04 +00007867 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007868 Loc = Unit->getSourceManager().getSpellingLoc(Loc);
7869 Token Tok;
7870 if (PP.getRawToken(Loc, Tok))
Craig Topper69186e72014-06-08 08:38:04 +00007871 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007872
7873 return checkForMacroInMacroDefinition(MI, Tok, TU);
7874}
7875
Guy Benyei11169dd2012-12-18 14:30:41 +00007876extern "C" {
7877
7878CXString clang_getClangVersion() {
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00007879 return cxstring::createDup(getClangFullVersion());
Guy Benyei11169dd2012-12-18 14:30:41 +00007880}
7881
7882} // end: extern "C"
7883
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007884Logger &cxindex::Logger::operator<<(CXTranslationUnit TU) {
7885 if (TU) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007886 if (ASTUnit *Unit = cxtu::getASTUnit(TU)) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007887 LogOS << '<' << Unit->getMainFileName() << '>';
Argyrios Kyrtzidis37f2ab42013-03-05 20:21:14 +00007888 if (Unit->isMainFileAST())
7889 LogOS << " (" << Unit->getASTFileName() << ')';
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007890 return *this;
7891 }
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00007892 } else {
7893 LogOS << "<NULL TU>";
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007894 }
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007895 return *this;
7896}
7897
Argyrios Kyrtzidisba4b5f82013-03-08 02:32:26 +00007898Logger &cxindex::Logger::operator<<(const FileEntry *FE) {
7899 *this << FE->getName();
7900 return *this;
7901}
7902
7903Logger &cxindex::Logger::operator<<(CXCursor cursor) {
7904 CXString cursorName = clang_getCursorDisplayName(cursor);
7905 *this << cursorName << "@" << clang_getCursorLocation(cursor);
7906 clang_disposeString(cursorName);
7907 return *this;
7908}
7909
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007910Logger &cxindex::Logger::operator<<(CXSourceLocation Loc) {
7911 CXFile File;
7912 unsigned Line, Column;
Craig Topper69186e72014-06-08 08:38:04 +00007913 clang_getFileLocation(Loc, &File, &Line, &Column, nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007914 CXString FileName = clang_getFileName(File);
7915 *this << llvm::format("(%s:%d:%d)", clang_getCString(FileName), Line, Column);
7916 clang_disposeString(FileName);
7917 return *this;
7918}
7919
7920Logger &cxindex::Logger::operator<<(CXSourceRange range) {
7921 CXSourceLocation BLoc = clang_getRangeStart(range);
7922 CXSourceLocation ELoc = clang_getRangeEnd(range);
7923
7924 CXFile BFile;
7925 unsigned BLine, BColumn;
Craig Topper69186e72014-06-08 08:38:04 +00007926 clang_getFileLocation(BLoc, &BFile, &BLine, &BColumn, nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007927
7928 CXFile EFile;
7929 unsigned ELine, EColumn;
Craig Topper69186e72014-06-08 08:38:04 +00007930 clang_getFileLocation(ELoc, &EFile, &ELine, &EColumn, nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007931
7932 CXString BFileName = clang_getFileName(BFile);
7933 if (BFile == EFile) {
7934 *this << llvm::format("[%s %d:%d-%d:%d]", clang_getCString(BFileName),
7935 BLine, BColumn, ELine, EColumn);
7936 } else {
7937 CXString EFileName = clang_getFileName(EFile);
7938 *this << llvm::format("[%s:%d:%d - ", clang_getCString(BFileName),
7939 BLine, BColumn)
7940 << llvm::format("%s:%d:%d]", clang_getCString(EFileName),
7941 ELine, EColumn);
7942 clang_disposeString(EFileName);
7943 }
7944 clang_disposeString(BFileName);
7945 return *this;
7946}
7947
7948Logger &cxindex::Logger::operator<<(CXString Str) {
7949 *this << clang_getCString(Str);
7950 return *this;
7951}
7952
7953Logger &cxindex::Logger::operator<<(const llvm::format_object_base &Fmt) {
7954 LogOS << Fmt;
7955 return *this;
7956}
7957
Chandler Carruth37ad2582014-06-27 15:14:39 +00007958static llvm::ManagedStatic<llvm::sys::Mutex> LoggingMutex;
7959
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007960cxindex::Logger::~Logger() {
Chandler Carruth37ad2582014-06-27 15:14:39 +00007961 llvm::sys::ScopedLock L(*LoggingMutex);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007962
7963 static llvm::TimeRecord sBeginTR = llvm::TimeRecord::getCurrentTime();
7964
Dmitri Gribenkof8579502013-01-12 19:30:44 +00007965 raw_ostream &OS = llvm::errs();
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007966 OS << "[libclang:" << Name << ':';
7967
Alp Toker1a86ad22014-07-06 06:24:00 +00007968#ifdef USE_DARWIN_THREADS
7969 // TODO: Portability.
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007970 mach_port_t tid = pthread_mach_thread_np(pthread_self());
7971 OS << tid << ':';
7972#endif
7973
7974 llvm::TimeRecord TR = llvm::TimeRecord::getCurrentTime();
7975 OS << llvm::format("%7.4f] ", TR.getWallTime() - sBeginTR.getWallTime());
Yaron Keren09fb7c62015-03-10 07:33:23 +00007976 OS << Msg << '\n';
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007977
7978 if (Trace) {
Zachary Turner1fe2a8d2015-03-05 19:15:09 +00007979 llvm::sys::PrintStackTrace(OS);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007980 OS << "--------------------------------------------------\n";
7981 }
7982}