blob: 486d24a5fb97e2113b8696e360400744a142822c [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 }
720
721 if (ShouldVisitBody && VisitCXXRecordDecl(D))
722 return true;
723
724 return false;
725}
726
727bool CursorVisitor::VisitClassTemplatePartialSpecializationDecl(
728 ClassTemplatePartialSpecializationDecl *D) {
729 // FIXME: Visit the "outer" template parameter lists on the TagDecl
730 // before visiting these template parameters.
731 if (VisitTemplateParameters(D->getTemplateParameters()))
732 return true;
733
734 // Visit the partial specialization arguments.
Enea Zaffanella6dbe1872013-08-10 07:24:53 +0000735 const ASTTemplateArgumentListInfo *Info = D->getTemplateArgsAsWritten();
736 const TemplateArgumentLoc *TemplateArgs = Info->getTemplateArgs();
737 for (unsigned I = 0, N = Info->NumTemplateArgs; I != N; ++I)
Guy Benyei11169dd2012-12-18 14:30:41 +0000738 if (VisitTemplateArgumentLoc(TemplateArgs[I]))
739 return true;
740
741 return VisitCXXRecordDecl(D);
742}
743
744bool CursorVisitor::VisitTemplateTypeParmDecl(TemplateTypeParmDecl *D) {
745 // Visit the default argument.
746 if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited())
747 if (TypeSourceInfo *DefArg = D->getDefaultArgumentInfo())
748 if (Visit(DefArg->getTypeLoc()))
749 return true;
750
751 return false;
752}
753
754bool CursorVisitor::VisitEnumConstantDecl(EnumConstantDecl *D) {
755 if (Expr *Init = D->getInitExpr())
756 return Visit(MakeCXCursor(Init, StmtParent, TU, RegionOfInterest));
757 return false;
758}
759
760bool CursorVisitor::VisitDeclaratorDecl(DeclaratorDecl *DD) {
Argyrios Kyrtzidis2ec76742013-04-05 21:04:10 +0000761 unsigned NumParamList = DD->getNumTemplateParameterLists();
762 for (unsigned i = 0; i < NumParamList; i++) {
763 TemplateParameterList* Params = DD->getTemplateParameterList(i);
764 if (VisitTemplateParameters(Params))
765 return true;
766 }
767
Guy Benyei11169dd2012-12-18 14:30:41 +0000768 if (TypeSourceInfo *TSInfo = DD->getTypeSourceInfo())
769 if (Visit(TSInfo->getTypeLoc()))
770 return true;
771
772 // Visit the nested-name-specifier, if present.
773 if (NestedNameSpecifierLoc QualifierLoc = DD->getQualifierLoc())
774 if (VisitNestedNameSpecifierLoc(QualifierLoc))
775 return true;
776
777 return false;
778}
779
Benjamin Kramer4cadf292014-03-07 21:51:58 +0000780/// \brief Compare two base or member initializers based on their source order.
781static int CompareCXXCtorInitializers(CXXCtorInitializer *const *X,
782 CXXCtorInitializer *const *Y) {
783 return (*X)->getSourceOrder() - (*Y)->getSourceOrder();
784}
785
Guy Benyei11169dd2012-12-18 14:30:41 +0000786bool CursorVisitor::VisitFunctionDecl(FunctionDecl *ND) {
Argyrios Kyrtzidis2ec76742013-04-05 21:04:10 +0000787 unsigned NumParamList = ND->getNumTemplateParameterLists();
788 for (unsigned i = 0; i < NumParamList; i++) {
789 TemplateParameterList* Params = ND->getTemplateParameterList(i);
790 if (VisitTemplateParameters(Params))
791 return true;
792 }
793
Guy Benyei11169dd2012-12-18 14:30:41 +0000794 if (TypeSourceInfo *TSInfo = ND->getTypeSourceInfo()) {
795 // Visit the function declaration's syntactic components in the order
796 // written. This requires a bit of work.
797 TypeLoc TL = TSInfo->getTypeLoc().IgnoreParens();
David Blaikie6adc78e2013-02-18 22:06:02 +0000798 FunctionTypeLoc FTL = TL.getAs<FunctionTypeLoc>();
Guy Benyei11169dd2012-12-18 14:30:41 +0000799
800 // If we have a function declared directly (without the use of a typedef),
801 // visit just the return type. Otherwise, just visit the function's type
802 // now.
Alp Toker42a16a62014-01-25 23:51:36 +0000803 if ((FTL && !isa<CXXConversionDecl>(ND) && Visit(FTL.getReturnLoc())) ||
Guy Benyei11169dd2012-12-18 14:30:41 +0000804 (!FTL && Visit(TL)))
805 return true;
806
807 // Visit the nested-name-specifier, if present.
808 if (NestedNameSpecifierLoc QualifierLoc = ND->getQualifierLoc())
809 if (VisitNestedNameSpecifierLoc(QualifierLoc))
810 return true;
811
812 // Visit the declaration name.
Argyrios Kyrtzidis4a4d2b42014-02-09 08:13:47 +0000813 if (!isa<CXXDestructorDecl>(ND))
814 if (VisitDeclarationNameInfo(ND->getNameInfo()))
815 return true;
Guy Benyei11169dd2012-12-18 14:30:41 +0000816
817 // FIXME: Visit explicitly-specified template arguments!
818
819 // Visit the function parameters, if we have a function type.
David Blaikie6adc78e2013-02-18 22:06:02 +0000820 if (FTL && VisitFunctionTypeLoc(FTL, true))
Guy Benyei11169dd2012-12-18 14:30:41 +0000821 return true;
822
Bill Wendling44426052012-12-20 19:22:21 +0000823 // FIXME: Attributes?
Guy Benyei11169dd2012-12-18 14:30:41 +0000824 }
825
826 if (ND->doesThisDeclarationHaveABody() && !ND->isLateTemplateParsed()) {
827 if (CXXConstructorDecl *Constructor = dyn_cast<CXXConstructorDecl>(ND)) {
828 // Find the initializers that were written in the source.
829 SmallVector<CXXCtorInitializer *, 4> WrittenInits;
Aaron Ballman0ad78302014-03-13 17:34:31 +0000830 for (auto *I : Constructor->inits()) {
831 if (!I->isWritten())
Guy Benyei11169dd2012-12-18 14:30:41 +0000832 continue;
833
Aaron Ballman0ad78302014-03-13 17:34:31 +0000834 WrittenInits.push_back(I);
Guy Benyei11169dd2012-12-18 14:30:41 +0000835 }
836
837 // Sort the initializers in source order
Benjamin Kramer4cadf292014-03-07 21:51:58 +0000838 llvm::array_pod_sort(WrittenInits.begin(), WrittenInits.end(),
839 &CompareCXXCtorInitializers);
840
Guy Benyei11169dd2012-12-18 14:30:41 +0000841 // Visit the initializers in source order
842 for (unsigned I = 0, N = WrittenInits.size(); I != N; ++I) {
843 CXXCtorInitializer *Init = WrittenInits[I];
844 if (Init->isAnyMemberInitializer()) {
845 if (Visit(MakeCursorMemberRef(Init->getAnyMember(),
846 Init->getMemberLocation(), TU)))
847 return true;
848 } else if (TypeSourceInfo *TInfo = Init->getTypeSourceInfo()) {
849 if (Visit(TInfo->getTypeLoc()))
850 return true;
851 }
852
853 // Visit the initializer value.
854 if (Expr *Initializer = Init->getInit())
855 if (Visit(MakeCXCursor(Initializer, ND, TU, RegionOfInterest)))
856 return true;
857 }
858 }
859
860 if (Visit(MakeCXCursor(ND->getBody(), StmtParent, TU, RegionOfInterest)))
861 return true;
862 }
863
864 return false;
865}
866
867bool CursorVisitor::VisitFieldDecl(FieldDecl *D) {
868 if (VisitDeclaratorDecl(D))
869 return true;
870
871 if (Expr *BitWidth = D->getBitWidth())
872 return Visit(MakeCXCursor(BitWidth, StmtParent, TU, RegionOfInterest));
873
874 return false;
875}
876
877bool CursorVisitor::VisitVarDecl(VarDecl *D) {
878 if (VisitDeclaratorDecl(D))
879 return true;
880
881 if (Expr *Init = D->getInit())
882 return Visit(MakeCXCursor(Init, StmtParent, TU, RegionOfInterest));
883
884 return false;
885}
886
887bool CursorVisitor::VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl *D) {
888 if (VisitDeclaratorDecl(D))
889 return true;
890
891 if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited())
892 if (Expr *DefArg = D->getDefaultArgument())
893 return Visit(MakeCXCursor(DefArg, StmtParent, TU, RegionOfInterest));
894
895 return false;
896}
897
898bool CursorVisitor::VisitFunctionTemplateDecl(FunctionTemplateDecl *D) {
899 // FIXME: Visit the "outer" template parameter lists on the FunctionDecl
900 // before visiting these template parameters.
901 if (VisitTemplateParameters(D->getTemplateParameters()))
902 return true;
903
904 return VisitFunctionDecl(D->getTemplatedDecl());
905}
906
907bool CursorVisitor::VisitClassTemplateDecl(ClassTemplateDecl *D) {
908 // FIXME: Visit the "outer" template parameter lists on the TagDecl
909 // before visiting these template parameters.
910 if (VisitTemplateParameters(D->getTemplateParameters()))
911 return true;
912
913 return VisitCXXRecordDecl(D->getTemplatedDecl());
914}
915
916bool CursorVisitor::VisitTemplateTemplateParmDecl(TemplateTemplateParmDecl *D) {
917 if (VisitTemplateParameters(D->getTemplateParameters()))
918 return true;
919
920 if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited() &&
921 VisitTemplateArgumentLoc(D->getDefaultArgument()))
922 return true;
923
924 return false;
925}
926
Douglas Gregor9bda6cf2015-07-07 03:58:14 +0000927bool CursorVisitor::VisitObjCTypeParamDecl(ObjCTypeParamDecl *D) {
928 // Visit the bound, if it's explicit.
929 if (D->hasExplicitBound()) {
930 if (auto TInfo = D->getTypeSourceInfo()) {
931 if (Visit(TInfo->getTypeLoc()))
932 return true;
933 }
934 }
935
936 return false;
937}
938
Guy Benyei11169dd2012-12-18 14:30:41 +0000939bool CursorVisitor::VisitObjCMethodDecl(ObjCMethodDecl *ND) {
Alp Toker314cc812014-01-25 16:55:45 +0000940 if (TypeSourceInfo *TSInfo = ND->getReturnTypeSourceInfo())
Guy Benyei11169dd2012-12-18 14:30:41 +0000941 if (Visit(TSInfo->getTypeLoc()))
942 return true;
943
Aaron Ballman43b68be2014-03-07 17:50:17 +0000944 for (const auto *P : ND->params()) {
945 if (Visit(MakeCXCursor(P, TU, RegionOfInterest)))
Guy Benyei11169dd2012-12-18 14:30:41 +0000946 return true;
947 }
948
949 if (ND->isThisDeclarationADefinition() &&
950 Visit(MakeCXCursor(ND->getBody(), StmtParent, TU, RegionOfInterest)))
951 return true;
952
953 return false;
954}
955
956template <typename DeclIt>
957static void addRangedDeclsInContainer(DeclIt *DI_current, DeclIt DE_current,
958 SourceManager &SM, SourceLocation EndLoc,
959 SmallVectorImpl<Decl *> &Decls) {
960 DeclIt next = *DI_current;
961 while (++next != DE_current) {
962 Decl *D_next = *next;
963 if (!D_next)
964 break;
965 SourceLocation L = D_next->getLocStart();
966 if (!L.isValid())
967 break;
968 if (SM.isBeforeInTranslationUnit(L, EndLoc)) {
969 *DI_current = next;
970 Decls.push_back(D_next);
971 continue;
972 }
973 break;
974 }
975}
976
Guy Benyei11169dd2012-12-18 14:30:41 +0000977bool CursorVisitor::VisitObjCContainerDecl(ObjCContainerDecl *D) {
978 // FIXME: Eventually convert back to just 'VisitDeclContext()'. Essentially
979 // an @implementation can lexically contain Decls that are not properly
980 // nested in the AST. When we identify such cases, we need to retrofit
981 // this nesting here.
982 if (!DI_current && !FileDI_current)
983 return VisitDeclContext(D);
984
985 // Scan the Decls that immediately come after the container
986 // in the current DeclContext. If any fall within the
987 // container's lexical region, stash them into a vector
988 // for later processing.
989 SmallVector<Decl *, 24> DeclsInContainer;
990 SourceLocation EndLoc = D->getSourceRange().getEnd();
991 SourceManager &SM = AU->getSourceManager();
992 if (EndLoc.isValid()) {
993 if (DI_current) {
994 addRangedDeclsInContainer(DI_current, DE_current, SM, EndLoc,
995 DeclsInContainer);
996 } else {
997 addRangedDeclsInContainer(FileDI_current, FileDE_current, SM, EndLoc,
998 DeclsInContainer);
999 }
1000 }
1001
1002 // The common case.
1003 if (DeclsInContainer.empty())
1004 return VisitDeclContext(D);
1005
1006 // Get all the Decls in the DeclContext, and sort them with the
1007 // additional ones we've collected. Then visit them.
Aaron Ballman629afae2014-03-07 19:56:05 +00001008 for (auto *SubDecl : D->decls()) {
1009 if (!SubDecl || SubDecl->getLexicalDeclContext() != D ||
1010 SubDecl->getLocStart().isInvalid())
Guy Benyei11169dd2012-12-18 14:30:41 +00001011 continue;
Aaron Ballman629afae2014-03-07 19:56:05 +00001012 DeclsInContainer.push_back(SubDecl);
Guy Benyei11169dd2012-12-18 14:30:41 +00001013 }
1014
1015 // Now sort the Decls so that they appear in lexical order.
1016 std::sort(DeclsInContainer.begin(), DeclsInContainer.end(),
Benjamin Kramerbbdd7642014-03-01 14:48:57 +00001017 [&SM](Decl *A, Decl *B) {
1018 SourceLocation L_A = A->getLocStart();
1019 SourceLocation L_B = B->getLocStart();
1020 assert(L_A.isValid() && L_B.isValid());
1021 return SM.isBeforeInTranslationUnit(L_A, L_B);
1022 });
Guy Benyei11169dd2012-12-18 14:30:41 +00001023
1024 // Now visit the decls.
1025 for (SmallVectorImpl<Decl*>::iterator I = DeclsInContainer.begin(),
1026 E = DeclsInContainer.end(); I != E; ++I) {
1027 CXCursor Cursor = MakeCXCursor(*I, TU, RegionOfInterest);
Ted Kremenek03325582013-02-21 01:29:01 +00001028 const Optional<bool> &V = shouldVisitCursor(Cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00001029 if (!V.hasValue())
1030 continue;
1031 if (!V.getValue())
1032 return false;
1033 if (Visit(Cursor, true))
1034 return true;
1035 }
1036 return false;
1037}
1038
1039bool CursorVisitor::VisitObjCCategoryDecl(ObjCCategoryDecl *ND) {
1040 if (Visit(MakeCursorObjCClassRef(ND->getClassInterface(), ND->getLocation(),
1041 TU)))
1042 return true;
1043
Douglas Gregore9d95f12015-07-07 03:57:35 +00001044 if (VisitObjCTypeParamList(ND->getTypeParamList()))
1045 return true;
1046
Guy Benyei11169dd2012-12-18 14:30:41 +00001047 ObjCCategoryDecl::protocol_loc_iterator PL = ND->protocol_loc_begin();
1048 for (ObjCCategoryDecl::protocol_iterator I = ND->protocol_begin(),
1049 E = ND->protocol_end(); I != E; ++I, ++PL)
1050 if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
1051 return true;
1052
1053 return VisitObjCContainerDecl(ND);
1054}
1055
1056bool CursorVisitor::VisitObjCProtocolDecl(ObjCProtocolDecl *PID) {
1057 if (!PID->isThisDeclarationADefinition())
1058 return Visit(MakeCursorObjCProtocolRef(PID, PID->getLocation(), TU));
1059
1060 ObjCProtocolDecl::protocol_loc_iterator PL = PID->protocol_loc_begin();
1061 for (ObjCProtocolDecl::protocol_iterator I = PID->protocol_begin(),
1062 E = PID->protocol_end(); I != E; ++I, ++PL)
1063 if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
1064 return true;
1065
1066 return VisitObjCContainerDecl(PID);
1067}
1068
1069bool CursorVisitor::VisitObjCPropertyDecl(ObjCPropertyDecl *PD) {
1070 if (PD->getTypeSourceInfo() && Visit(PD->getTypeSourceInfo()->getTypeLoc()))
1071 return true;
1072
1073 // FIXME: This implements a workaround with @property declarations also being
1074 // installed in the DeclContext for the @interface. Eventually this code
1075 // should be removed.
1076 ObjCCategoryDecl *CDecl = dyn_cast<ObjCCategoryDecl>(PD->getDeclContext());
1077 if (!CDecl || !CDecl->IsClassExtension())
1078 return false;
1079
1080 ObjCInterfaceDecl *ID = CDecl->getClassInterface();
1081 if (!ID)
1082 return false;
1083
1084 IdentifierInfo *PropertyId = PD->getIdentifier();
1085 ObjCPropertyDecl *prevDecl =
1086 ObjCPropertyDecl::findPropertyDecl(cast<DeclContext>(ID), PropertyId);
1087
1088 if (!prevDecl)
1089 return false;
1090
1091 // Visit synthesized methods since they will be skipped when visiting
1092 // the @interface.
1093 if (ObjCMethodDecl *MD = prevDecl->getGetterMethodDecl())
1094 if (MD->isPropertyAccessor() && MD->getLexicalDeclContext() == CDecl)
1095 if (Visit(MakeCXCursor(MD, TU, RegionOfInterest)))
1096 return true;
1097
1098 if (ObjCMethodDecl *MD = prevDecl->getSetterMethodDecl())
1099 if (MD->isPropertyAccessor() && MD->getLexicalDeclContext() == CDecl)
1100 if (Visit(MakeCXCursor(MD, TU, RegionOfInterest)))
1101 return true;
1102
1103 return false;
1104}
1105
Douglas Gregore9d95f12015-07-07 03:57:35 +00001106bool CursorVisitor::VisitObjCTypeParamList(ObjCTypeParamList *typeParamList) {
1107 if (!typeParamList)
1108 return false;
1109
1110 for (auto *typeParam : *typeParamList) {
1111 // Visit the type parameter.
1112 if (Visit(MakeCXCursor(typeParam, TU, RegionOfInterest)))
1113 return true;
Douglas Gregore9d95f12015-07-07 03:57:35 +00001114 }
1115
1116 return false;
1117}
1118
Guy Benyei11169dd2012-12-18 14:30:41 +00001119bool CursorVisitor::VisitObjCInterfaceDecl(ObjCInterfaceDecl *D) {
1120 if (!D->isThisDeclarationADefinition()) {
1121 // Forward declaration is treated like a reference.
1122 return Visit(MakeCursorObjCClassRef(D, D->getLocation(), TU));
1123 }
1124
Douglas Gregore9d95f12015-07-07 03:57:35 +00001125 // Objective-C type parameters.
1126 if (VisitObjCTypeParamList(D->getTypeParamListAsWritten()))
1127 return true;
1128
Guy Benyei11169dd2012-12-18 14:30:41 +00001129 // Issue callbacks for super class.
1130 if (D->getSuperClass() &&
1131 Visit(MakeCursorObjCSuperClassRef(D->getSuperClass(),
1132 D->getSuperClassLoc(),
1133 TU)))
1134 return true;
1135
Douglas Gregore9d95f12015-07-07 03:57:35 +00001136 if (TypeSourceInfo *SuperClassTInfo = D->getSuperClassTInfo())
1137 if (Visit(SuperClassTInfo->getTypeLoc()))
1138 return true;
1139
Guy Benyei11169dd2012-12-18 14:30:41 +00001140 ObjCInterfaceDecl::protocol_loc_iterator PL = D->protocol_loc_begin();
1141 for (ObjCInterfaceDecl::protocol_iterator I = D->protocol_begin(),
1142 E = D->protocol_end(); I != E; ++I, ++PL)
1143 if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
1144 return true;
1145
1146 return VisitObjCContainerDecl(D);
1147}
1148
1149bool CursorVisitor::VisitObjCImplDecl(ObjCImplDecl *D) {
1150 return VisitObjCContainerDecl(D);
1151}
1152
1153bool CursorVisitor::VisitObjCCategoryImplDecl(ObjCCategoryImplDecl *D) {
1154 // 'ID' could be null when dealing with invalid code.
1155 if (ObjCInterfaceDecl *ID = D->getClassInterface())
1156 if (Visit(MakeCursorObjCClassRef(ID, D->getLocation(), TU)))
1157 return true;
1158
1159 return VisitObjCImplDecl(D);
1160}
1161
1162bool CursorVisitor::VisitObjCImplementationDecl(ObjCImplementationDecl *D) {
1163#if 0
1164 // Issue callbacks for super class.
1165 // FIXME: No source location information!
1166 if (D->getSuperClass() &&
1167 Visit(MakeCursorObjCSuperClassRef(D->getSuperClass(),
1168 D->getSuperClassLoc(),
1169 TU)))
1170 return true;
1171#endif
1172
1173 return VisitObjCImplDecl(D);
1174}
1175
1176bool CursorVisitor::VisitObjCPropertyImplDecl(ObjCPropertyImplDecl *PD) {
1177 if (ObjCIvarDecl *Ivar = PD->getPropertyIvarDecl())
1178 if (PD->isIvarNameSpecified())
1179 return Visit(MakeCursorMemberRef(Ivar, PD->getPropertyIvarDeclLoc(), TU));
1180
1181 return false;
1182}
1183
1184bool CursorVisitor::VisitNamespaceDecl(NamespaceDecl *D) {
1185 return VisitDeclContext(D);
1186}
1187
1188bool CursorVisitor::VisitNamespaceAliasDecl(NamespaceAliasDecl *D) {
1189 // Visit nested-name-specifier.
1190 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1191 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1192 return true;
1193
1194 return Visit(MakeCursorNamespaceRef(D->getAliasedNamespace(),
1195 D->getTargetNameLoc(), TU));
1196}
1197
1198bool CursorVisitor::VisitUsingDecl(UsingDecl *D) {
1199 // Visit nested-name-specifier.
1200 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc()) {
1201 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1202 return true;
1203 }
1204
1205 if (Visit(MakeCursorOverloadedDeclRef(D, D->getLocation(), TU)))
1206 return true;
1207
1208 return VisitDeclarationNameInfo(D->getNameInfo());
1209}
1210
1211bool CursorVisitor::VisitUsingDirectiveDecl(UsingDirectiveDecl *D) {
1212 // Visit nested-name-specifier.
1213 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1214 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1215 return true;
1216
1217 return Visit(MakeCursorNamespaceRef(D->getNominatedNamespaceAsWritten(),
1218 D->getIdentLocation(), TU));
1219}
1220
1221bool CursorVisitor::VisitUnresolvedUsingValueDecl(UnresolvedUsingValueDecl *D) {
1222 // Visit nested-name-specifier.
1223 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc()) {
1224 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1225 return true;
1226 }
1227
1228 return VisitDeclarationNameInfo(D->getNameInfo());
1229}
1230
1231bool CursorVisitor::VisitUnresolvedUsingTypenameDecl(
1232 UnresolvedUsingTypenameDecl *D) {
1233 // Visit nested-name-specifier.
1234 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1235 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1236 return true;
1237
1238 return false;
1239}
1240
1241bool CursorVisitor::VisitDeclarationNameInfo(DeclarationNameInfo Name) {
1242 switch (Name.getName().getNameKind()) {
1243 case clang::DeclarationName::Identifier:
1244 case clang::DeclarationName::CXXLiteralOperatorName:
1245 case clang::DeclarationName::CXXOperatorName:
1246 case clang::DeclarationName::CXXUsingDirective:
1247 return false;
1248
1249 case clang::DeclarationName::CXXConstructorName:
1250 case clang::DeclarationName::CXXDestructorName:
1251 case clang::DeclarationName::CXXConversionFunctionName:
1252 if (TypeSourceInfo *TSInfo = Name.getNamedTypeInfo())
1253 return Visit(TSInfo->getTypeLoc());
1254 return false;
1255
1256 case clang::DeclarationName::ObjCZeroArgSelector:
1257 case clang::DeclarationName::ObjCOneArgSelector:
1258 case clang::DeclarationName::ObjCMultiArgSelector:
1259 // FIXME: Per-identifier location info?
1260 return false;
1261 }
1262
1263 llvm_unreachable("Invalid DeclarationName::Kind!");
1264}
1265
1266bool CursorVisitor::VisitNestedNameSpecifier(NestedNameSpecifier *NNS,
1267 SourceRange Range) {
1268 // FIXME: This whole routine is a hack to work around the lack of proper
1269 // source information in nested-name-specifiers (PR5791). Since we do have
1270 // a beginning source location, we can visit the first component of the
1271 // nested-name-specifier, if it's a single-token component.
1272 if (!NNS)
1273 return false;
1274
1275 // Get the first component in the nested-name-specifier.
1276 while (NestedNameSpecifier *Prefix = NNS->getPrefix())
1277 NNS = Prefix;
1278
1279 switch (NNS->getKind()) {
1280 case NestedNameSpecifier::Namespace:
1281 return Visit(MakeCursorNamespaceRef(NNS->getAsNamespace(), Range.getBegin(),
1282 TU));
1283
1284 case NestedNameSpecifier::NamespaceAlias:
1285 return Visit(MakeCursorNamespaceRef(NNS->getAsNamespaceAlias(),
1286 Range.getBegin(), TU));
1287
1288 case NestedNameSpecifier::TypeSpec: {
1289 // If the type has a form where we know that the beginning of the source
1290 // range matches up with a reference cursor. Visit the appropriate reference
1291 // cursor.
1292 const Type *T = NNS->getAsType();
1293 if (const TypedefType *Typedef = dyn_cast<TypedefType>(T))
1294 return Visit(MakeCursorTypeRef(Typedef->getDecl(), Range.getBegin(), TU));
1295 if (const TagType *Tag = dyn_cast<TagType>(T))
1296 return Visit(MakeCursorTypeRef(Tag->getDecl(), Range.getBegin(), TU));
1297 if (const TemplateSpecializationType *TST
1298 = dyn_cast<TemplateSpecializationType>(T))
1299 return VisitTemplateName(TST->getTemplateName(), Range.getBegin());
1300 break;
1301 }
1302
1303 case NestedNameSpecifier::TypeSpecWithTemplate:
1304 case NestedNameSpecifier::Global:
1305 case NestedNameSpecifier::Identifier:
Nikola Smiljanic67860242014-09-26 00:28:20 +00001306 case NestedNameSpecifier::Super:
Guy Benyei11169dd2012-12-18 14:30:41 +00001307 break;
1308 }
1309
1310 return false;
1311}
1312
1313bool
1314CursorVisitor::VisitNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier) {
1315 SmallVector<NestedNameSpecifierLoc, 4> Qualifiers;
1316 for (; Qualifier; Qualifier = Qualifier.getPrefix())
1317 Qualifiers.push_back(Qualifier);
1318
1319 while (!Qualifiers.empty()) {
1320 NestedNameSpecifierLoc Q = Qualifiers.pop_back_val();
1321 NestedNameSpecifier *NNS = Q.getNestedNameSpecifier();
1322 switch (NNS->getKind()) {
1323 case NestedNameSpecifier::Namespace:
1324 if (Visit(MakeCursorNamespaceRef(NNS->getAsNamespace(),
1325 Q.getLocalBeginLoc(),
1326 TU)))
1327 return true;
1328
1329 break;
1330
1331 case NestedNameSpecifier::NamespaceAlias:
1332 if (Visit(MakeCursorNamespaceRef(NNS->getAsNamespaceAlias(),
1333 Q.getLocalBeginLoc(),
1334 TU)))
1335 return true;
1336
1337 break;
1338
1339 case NestedNameSpecifier::TypeSpec:
1340 case NestedNameSpecifier::TypeSpecWithTemplate:
1341 if (Visit(Q.getTypeLoc()))
1342 return true;
1343
1344 break;
1345
1346 case NestedNameSpecifier::Global:
1347 case NestedNameSpecifier::Identifier:
Nikola Smiljanic67860242014-09-26 00:28:20 +00001348 case NestedNameSpecifier::Super:
Guy Benyei11169dd2012-12-18 14:30:41 +00001349 break;
1350 }
1351 }
1352
1353 return false;
1354}
1355
1356bool CursorVisitor::VisitTemplateParameters(
1357 const TemplateParameterList *Params) {
1358 if (!Params)
1359 return false;
1360
1361 for (TemplateParameterList::const_iterator P = Params->begin(),
1362 PEnd = Params->end();
1363 P != PEnd; ++P) {
1364 if (Visit(MakeCXCursor(*P, TU, RegionOfInterest)))
1365 return true;
1366 }
1367
1368 return false;
1369}
1370
1371bool CursorVisitor::VisitTemplateName(TemplateName Name, SourceLocation Loc) {
1372 switch (Name.getKind()) {
1373 case TemplateName::Template:
1374 return Visit(MakeCursorTemplateRef(Name.getAsTemplateDecl(), Loc, TU));
1375
1376 case TemplateName::OverloadedTemplate:
1377 // Visit the overloaded template set.
1378 if (Visit(MakeCursorOverloadedDeclRef(Name, Loc, TU)))
1379 return true;
1380
1381 return false;
1382
1383 case TemplateName::DependentTemplate:
1384 // FIXME: Visit nested-name-specifier.
1385 return false;
1386
1387 case TemplateName::QualifiedTemplate:
1388 // FIXME: Visit nested-name-specifier.
1389 return Visit(MakeCursorTemplateRef(
1390 Name.getAsQualifiedTemplateName()->getDecl(),
1391 Loc, TU));
1392
1393 case TemplateName::SubstTemplateTemplateParm:
1394 return Visit(MakeCursorTemplateRef(
1395 Name.getAsSubstTemplateTemplateParm()->getParameter(),
1396 Loc, TU));
1397
1398 case TemplateName::SubstTemplateTemplateParmPack:
1399 return Visit(MakeCursorTemplateRef(
1400 Name.getAsSubstTemplateTemplateParmPack()->getParameterPack(),
1401 Loc, TU));
1402 }
1403
1404 llvm_unreachable("Invalid TemplateName::Kind!");
1405}
1406
1407bool CursorVisitor::VisitTemplateArgumentLoc(const TemplateArgumentLoc &TAL) {
1408 switch (TAL.getArgument().getKind()) {
1409 case TemplateArgument::Null:
1410 case TemplateArgument::Integral:
1411 case TemplateArgument::Pack:
1412 return false;
1413
1414 case TemplateArgument::Type:
1415 if (TypeSourceInfo *TSInfo = TAL.getTypeSourceInfo())
1416 return Visit(TSInfo->getTypeLoc());
1417 return false;
1418
1419 case TemplateArgument::Declaration:
1420 if (Expr *E = TAL.getSourceDeclExpression())
1421 return Visit(MakeCXCursor(E, StmtParent, TU, RegionOfInterest));
1422 return false;
1423
1424 case TemplateArgument::NullPtr:
1425 if (Expr *E = TAL.getSourceNullPtrExpression())
1426 return Visit(MakeCXCursor(E, StmtParent, TU, RegionOfInterest));
1427 return false;
1428
1429 case TemplateArgument::Expression:
1430 if (Expr *E = TAL.getSourceExpression())
1431 return Visit(MakeCXCursor(E, StmtParent, TU, RegionOfInterest));
1432 return false;
1433
1434 case TemplateArgument::Template:
1435 case TemplateArgument::TemplateExpansion:
1436 if (VisitNestedNameSpecifierLoc(TAL.getTemplateQualifierLoc()))
1437 return true;
1438
1439 return VisitTemplateName(TAL.getArgument().getAsTemplateOrTemplatePattern(),
1440 TAL.getTemplateNameLoc());
1441 }
1442
1443 llvm_unreachable("Invalid TemplateArgument::Kind!");
1444}
1445
1446bool CursorVisitor::VisitLinkageSpecDecl(LinkageSpecDecl *D) {
1447 return VisitDeclContext(D);
1448}
1449
1450bool CursorVisitor::VisitQualifiedTypeLoc(QualifiedTypeLoc TL) {
1451 return Visit(TL.getUnqualifiedLoc());
1452}
1453
1454bool CursorVisitor::VisitBuiltinTypeLoc(BuiltinTypeLoc TL) {
1455 ASTContext &Context = AU->getASTContext();
1456
1457 // Some builtin types (such as Objective-C's "id", "sel", and
1458 // "Class") have associated declarations. Create cursors for those.
1459 QualType VisitType;
1460 switch (TL.getTypePtr()->getKind()) {
1461
1462 case BuiltinType::Void:
1463 case BuiltinType::NullPtr:
1464 case BuiltinType::Dependent:
Guy Benyeid8a08ea2012-12-18 14:38:23 +00001465 case BuiltinType::OCLImage1d:
1466 case BuiltinType::OCLImage1dArray:
1467 case BuiltinType::OCLImage1dBuffer:
1468 case BuiltinType::OCLImage2d:
1469 case BuiltinType::OCLImage2dArray:
Alexey Bader9c8453f2015-09-15 11:18:52 +00001470 case BuiltinType::OCLImage2dDepth:
1471 case BuiltinType::OCLImage2dArrayDepth:
1472 case BuiltinType::OCLImage2dMSAA:
1473 case BuiltinType::OCLImage2dArrayMSAA:
1474 case BuiltinType::OCLImage2dMSAADepth:
1475 case BuiltinType::OCLImage2dArrayMSAADepth:
Guy Benyeid8a08ea2012-12-18 14:38:23 +00001476 case BuiltinType::OCLImage3d:
NAKAMURA Takumi288c42e2013-02-07 12:47:42 +00001477 case BuiltinType::OCLSampler:
Guy Benyei1b4fb3e2013-01-20 12:31:11 +00001478 case BuiltinType::OCLEvent:
Alexey Bader9c8453f2015-09-15 11:18:52 +00001479 case BuiltinType::OCLClkEvent:
1480 case BuiltinType::OCLQueue:
1481 case BuiltinType::OCLNDRange:
1482 case BuiltinType::OCLReserveID:
Guy Benyei11169dd2012-12-18 14:30:41 +00001483#define BUILTIN_TYPE(Id, SingletonId)
1484#define SIGNED_TYPE(Id, SingletonId) case BuiltinType::Id:
1485#define UNSIGNED_TYPE(Id, SingletonId) case BuiltinType::Id:
1486#define FLOATING_TYPE(Id, SingletonId) case BuiltinType::Id:
1487#define PLACEHOLDER_TYPE(Id, SingletonId) case BuiltinType::Id:
1488#include "clang/AST/BuiltinTypes.def"
1489 break;
1490
1491 case BuiltinType::ObjCId:
1492 VisitType = Context.getObjCIdType();
1493 break;
1494
1495 case BuiltinType::ObjCClass:
1496 VisitType = Context.getObjCClassType();
1497 break;
1498
1499 case BuiltinType::ObjCSel:
1500 VisitType = Context.getObjCSelType();
1501 break;
1502 }
1503
1504 if (!VisitType.isNull()) {
1505 if (const TypedefType *Typedef = VisitType->getAs<TypedefType>())
1506 return Visit(MakeCursorTypeRef(Typedef->getDecl(), TL.getBuiltinLoc(),
1507 TU));
1508 }
1509
1510 return false;
1511}
1512
1513bool CursorVisitor::VisitTypedefTypeLoc(TypedefTypeLoc TL) {
1514 return Visit(MakeCursorTypeRef(TL.getTypedefNameDecl(), TL.getNameLoc(), TU));
1515}
1516
1517bool CursorVisitor::VisitUnresolvedUsingTypeLoc(UnresolvedUsingTypeLoc TL) {
1518 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1519}
1520
1521bool CursorVisitor::VisitTagTypeLoc(TagTypeLoc TL) {
1522 if (TL.isDefinition())
1523 return Visit(MakeCXCursor(TL.getDecl(), TU, RegionOfInterest));
1524
1525 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1526}
1527
1528bool CursorVisitor::VisitTemplateTypeParmTypeLoc(TemplateTypeParmTypeLoc TL) {
1529 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1530}
1531
1532bool CursorVisitor::VisitObjCInterfaceTypeLoc(ObjCInterfaceTypeLoc TL) {
Hans Wennborg59dbe862015-09-29 20:56:43 +00001533 return Visit(MakeCursorObjCClassRef(TL.getIFaceDecl(), TL.getNameLoc(), TU));
Guy Benyei11169dd2012-12-18 14:30:41 +00001534}
1535
1536bool CursorVisitor::VisitObjCObjectTypeLoc(ObjCObjectTypeLoc TL) {
1537 if (TL.hasBaseTypeAsWritten() && Visit(TL.getBaseLoc()))
1538 return true;
1539
Douglas Gregore9d95f12015-07-07 03:57:35 +00001540 for (unsigned I = 0, N = TL.getNumTypeArgs(); I != N; ++I) {
1541 if (Visit(TL.getTypeArgTInfo(I)->getTypeLoc()))
1542 return true;
1543 }
1544
Guy Benyei11169dd2012-12-18 14:30:41 +00001545 for (unsigned I = 0, N = TL.getNumProtocols(); I != N; ++I) {
1546 if (Visit(MakeCursorObjCProtocolRef(TL.getProtocol(I), TL.getProtocolLoc(I),
1547 TU)))
1548 return true;
1549 }
1550
1551 return false;
1552}
1553
1554bool CursorVisitor::VisitObjCObjectPointerTypeLoc(ObjCObjectPointerTypeLoc TL) {
1555 return Visit(TL.getPointeeLoc());
1556}
1557
1558bool CursorVisitor::VisitParenTypeLoc(ParenTypeLoc TL) {
1559 return Visit(TL.getInnerLoc());
1560}
1561
1562bool CursorVisitor::VisitPointerTypeLoc(PointerTypeLoc TL) {
1563 return Visit(TL.getPointeeLoc());
1564}
1565
1566bool CursorVisitor::VisitBlockPointerTypeLoc(BlockPointerTypeLoc TL) {
1567 return Visit(TL.getPointeeLoc());
1568}
1569
1570bool CursorVisitor::VisitMemberPointerTypeLoc(MemberPointerTypeLoc TL) {
1571 return Visit(TL.getPointeeLoc());
1572}
1573
1574bool CursorVisitor::VisitLValueReferenceTypeLoc(LValueReferenceTypeLoc TL) {
1575 return Visit(TL.getPointeeLoc());
1576}
1577
1578bool CursorVisitor::VisitRValueReferenceTypeLoc(RValueReferenceTypeLoc TL) {
1579 return Visit(TL.getPointeeLoc());
1580}
1581
1582bool CursorVisitor::VisitAttributedTypeLoc(AttributedTypeLoc TL) {
1583 return Visit(TL.getModifiedLoc());
1584}
1585
1586bool CursorVisitor::VisitFunctionTypeLoc(FunctionTypeLoc TL,
1587 bool SkipResultType) {
Alp Toker42a16a62014-01-25 23:51:36 +00001588 if (!SkipResultType && Visit(TL.getReturnLoc()))
Guy Benyei11169dd2012-12-18 14:30:41 +00001589 return true;
1590
Alp Tokerb3fd5cf2014-01-21 00:32:38 +00001591 for (unsigned I = 0, N = TL.getNumParams(); I != N; ++I)
1592 if (Decl *D = TL.getParam(I))
Guy Benyei11169dd2012-12-18 14:30:41 +00001593 if (Visit(MakeCXCursor(D, TU, RegionOfInterest)))
1594 return true;
1595
1596 return false;
1597}
1598
1599bool CursorVisitor::VisitArrayTypeLoc(ArrayTypeLoc TL) {
1600 if (Visit(TL.getElementLoc()))
1601 return true;
1602
1603 if (Expr *Size = TL.getSizeExpr())
1604 return Visit(MakeCXCursor(Size, StmtParent, TU, RegionOfInterest));
1605
1606 return false;
1607}
1608
Reid Kleckner8a365022013-06-24 17:51:48 +00001609bool CursorVisitor::VisitDecayedTypeLoc(DecayedTypeLoc TL) {
1610 return Visit(TL.getOriginalLoc());
1611}
1612
Reid Kleckner0503a872013-12-05 01:23:43 +00001613bool CursorVisitor::VisitAdjustedTypeLoc(AdjustedTypeLoc TL) {
1614 return Visit(TL.getOriginalLoc());
1615}
1616
Guy Benyei11169dd2012-12-18 14:30:41 +00001617bool CursorVisitor::VisitTemplateSpecializationTypeLoc(
1618 TemplateSpecializationTypeLoc TL) {
1619 // Visit the template name.
1620 if (VisitTemplateName(TL.getTypePtr()->getTemplateName(),
1621 TL.getTemplateNameLoc()))
1622 return true;
1623
1624 // Visit the template arguments.
1625 for (unsigned I = 0, N = TL.getNumArgs(); I != N; ++I)
1626 if (VisitTemplateArgumentLoc(TL.getArgLoc(I)))
1627 return true;
1628
1629 return false;
1630}
1631
1632bool CursorVisitor::VisitTypeOfExprTypeLoc(TypeOfExprTypeLoc TL) {
1633 return Visit(MakeCXCursor(TL.getUnderlyingExpr(), StmtParent, TU));
1634}
1635
1636bool CursorVisitor::VisitTypeOfTypeLoc(TypeOfTypeLoc TL) {
1637 if (TypeSourceInfo *TSInfo = TL.getUnderlyingTInfo())
1638 return Visit(TSInfo->getTypeLoc());
1639
1640 return false;
1641}
1642
1643bool CursorVisitor::VisitUnaryTransformTypeLoc(UnaryTransformTypeLoc TL) {
1644 if (TypeSourceInfo *TSInfo = TL.getUnderlyingTInfo())
1645 return Visit(TSInfo->getTypeLoc());
1646
1647 return false;
1648}
1649
1650bool CursorVisitor::VisitDependentNameTypeLoc(DependentNameTypeLoc TL) {
Hans Wennborg59dbe862015-09-29 20:56:43 +00001651 return VisitNestedNameSpecifierLoc(TL.getQualifierLoc());
Guy Benyei11169dd2012-12-18 14:30:41 +00001652}
1653
1654bool CursorVisitor::VisitDependentTemplateSpecializationTypeLoc(
1655 DependentTemplateSpecializationTypeLoc TL) {
1656 // Visit the nested-name-specifier, if there is one.
1657 if (TL.getQualifierLoc() &&
1658 VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
1659 return true;
1660
1661 // Visit the template arguments.
1662 for (unsigned I = 0, N = TL.getNumArgs(); I != N; ++I)
1663 if (VisitTemplateArgumentLoc(TL.getArgLoc(I)))
1664 return true;
1665
1666 return false;
1667}
1668
1669bool CursorVisitor::VisitElaboratedTypeLoc(ElaboratedTypeLoc TL) {
1670 if (VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
1671 return true;
1672
1673 return Visit(TL.getNamedTypeLoc());
1674}
1675
1676bool CursorVisitor::VisitPackExpansionTypeLoc(PackExpansionTypeLoc TL) {
1677 return Visit(TL.getPatternLoc());
1678}
1679
1680bool CursorVisitor::VisitDecltypeTypeLoc(DecltypeTypeLoc TL) {
1681 if (Expr *E = TL.getUnderlyingExpr())
1682 return Visit(MakeCXCursor(E, StmtParent, TU));
1683
1684 return false;
1685}
1686
1687bool CursorVisitor::VisitInjectedClassNameTypeLoc(InjectedClassNameTypeLoc TL) {
1688 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1689}
1690
1691bool CursorVisitor::VisitAtomicTypeLoc(AtomicTypeLoc TL) {
1692 return Visit(TL.getValueLoc());
1693}
1694
1695#define DEFAULT_TYPELOC_IMPL(CLASS, PARENT) \
1696bool CursorVisitor::Visit##CLASS##TypeLoc(CLASS##TypeLoc TL) { \
1697 return Visit##PARENT##Loc(TL); \
1698}
1699
1700DEFAULT_TYPELOC_IMPL(Complex, Type)
1701DEFAULT_TYPELOC_IMPL(ConstantArray, ArrayType)
1702DEFAULT_TYPELOC_IMPL(IncompleteArray, ArrayType)
1703DEFAULT_TYPELOC_IMPL(VariableArray, ArrayType)
1704DEFAULT_TYPELOC_IMPL(DependentSizedArray, ArrayType)
1705DEFAULT_TYPELOC_IMPL(DependentSizedExtVector, Type)
1706DEFAULT_TYPELOC_IMPL(Vector, Type)
1707DEFAULT_TYPELOC_IMPL(ExtVector, VectorType)
1708DEFAULT_TYPELOC_IMPL(FunctionProto, FunctionType)
1709DEFAULT_TYPELOC_IMPL(FunctionNoProto, FunctionType)
1710DEFAULT_TYPELOC_IMPL(Record, TagType)
1711DEFAULT_TYPELOC_IMPL(Enum, TagType)
1712DEFAULT_TYPELOC_IMPL(SubstTemplateTypeParm, Type)
1713DEFAULT_TYPELOC_IMPL(SubstTemplateTypeParmPack, Type)
1714DEFAULT_TYPELOC_IMPL(Auto, Type)
1715
1716bool CursorVisitor::VisitCXXRecordDecl(CXXRecordDecl *D) {
1717 // Visit the nested-name-specifier, if present.
1718 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1719 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1720 return true;
1721
1722 if (D->isCompleteDefinition()) {
Aaron Ballman574705e2014-03-13 15:41:46 +00001723 for (const auto &I : D->bases()) {
1724 if (Visit(cxcursor::MakeCursorCXXBaseSpecifier(&I, TU)))
Guy Benyei11169dd2012-12-18 14:30:41 +00001725 return true;
1726 }
1727 }
1728
1729 return VisitTagDecl(D);
1730}
1731
1732bool CursorVisitor::VisitAttributes(Decl *D) {
Aaron Ballmanb97112e2014-03-08 22:19:01 +00001733 for (const auto *I : D->attrs())
1734 if (Visit(MakeCXCursor(I, D, TU)))
Guy Benyei11169dd2012-12-18 14:30:41 +00001735 return true;
1736
1737 return false;
1738}
1739
1740//===----------------------------------------------------------------------===//
1741// Data-recursive visitor methods.
1742//===----------------------------------------------------------------------===//
1743
1744namespace {
1745#define DEF_JOB(NAME, DATA, KIND)\
1746class NAME : public VisitorJob {\
1747public:\
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001748 NAME(const DATA *d, CXCursor parent) : \
1749 VisitorJob(parent, VisitorJob::KIND, d) {} \
Guy Benyei11169dd2012-12-18 14:30:41 +00001750 static bool classof(const VisitorJob *VJ) { return VJ->getKind() == KIND; }\
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001751 const DATA *get() const { return static_cast<const DATA*>(data[0]); }\
Guy Benyei11169dd2012-12-18 14:30:41 +00001752};
1753
1754DEF_JOB(StmtVisit, Stmt, StmtVisitKind)
1755DEF_JOB(MemberExprParts, MemberExpr, MemberExprPartsKind)
1756DEF_JOB(DeclRefExprParts, DeclRefExpr, DeclRefExprPartsKind)
1757DEF_JOB(OverloadExprParts, OverloadExpr, OverloadExprPartsKind)
1758DEF_JOB(ExplicitTemplateArgsVisit, ASTTemplateArgumentListInfo,
1759 ExplicitTemplateArgsVisitKind)
1760DEF_JOB(SizeOfPackExprParts, SizeOfPackExpr, SizeOfPackExprPartsKind)
1761DEF_JOB(LambdaExprParts, LambdaExpr, LambdaExprPartsKind)
1762DEF_JOB(PostChildrenVisit, void, PostChildrenVisitKind)
1763#undef DEF_JOB
1764
1765class DeclVisit : public VisitorJob {
1766public:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001767 DeclVisit(const Decl *D, CXCursor parent, bool isFirst) :
Guy Benyei11169dd2012-12-18 14:30:41 +00001768 VisitorJob(parent, VisitorJob::DeclVisitKind,
Craig Topper69186e72014-06-08 08:38:04 +00001769 D, isFirst ? (void*) 1 : (void*) nullptr) {}
Guy Benyei11169dd2012-12-18 14:30:41 +00001770 static bool classof(const VisitorJob *VJ) {
1771 return VJ->getKind() == DeclVisitKind;
1772 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001773 const Decl *get() const { return static_cast<const Decl *>(data[0]); }
Dmitri Gribenkoe5423a72015-03-23 19:23:50 +00001774 bool isFirst() const { return data[1] != nullptr; }
Guy Benyei11169dd2012-12-18 14:30:41 +00001775};
1776class TypeLocVisit : public VisitorJob {
1777public:
1778 TypeLocVisit(TypeLoc tl, CXCursor parent) :
1779 VisitorJob(parent, VisitorJob::TypeLocVisitKind,
1780 tl.getType().getAsOpaquePtr(), tl.getOpaqueData()) {}
1781
1782 static bool classof(const VisitorJob *VJ) {
1783 return VJ->getKind() == TypeLocVisitKind;
1784 }
1785
1786 TypeLoc get() const {
1787 QualType T = QualType::getFromOpaquePtr(data[0]);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001788 return TypeLoc(T, const_cast<void *>(data[1]));
Guy Benyei11169dd2012-12-18 14:30:41 +00001789 }
1790};
1791
1792class LabelRefVisit : public VisitorJob {
1793public:
1794 LabelRefVisit(LabelDecl *LD, SourceLocation labelLoc, CXCursor parent)
1795 : VisitorJob(parent, VisitorJob::LabelRefVisitKind, LD,
1796 labelLoc.getPtrEncoding()) {}
1797
1798 static bool classof(const VisitorJob *VJ) {
1799 return VJ->getKind() == VisitorJob::LabelRefVisitKind;
1800 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001801 const LabelDecl *get() const {
1802 return static_cast<const LabelDecl *>(data[0]);
1803 }
Guy Benyei11169dd2012-12-18 14:30:41 +00001804 SourceLocation getLoc() const {
1805 return SourceLocation::getFromPtrEncoding(data[1]); }
1806};
1807
1808class NestedNameSpecifierLocVisit : public VisitorJob {
1809public:
1810 NestedNameSpecifierLocVisit(NestedNameSpecifierLoc Qualifier, CXCursor parent)
1811 : VisitorJob(parent, VisitorJob::NestedNameSpecifierLocVisitKind,
1812 Qualifier.getNestedNameSpecifier(),
1813 Qualifier.getOpaqueData()) { }
1814
1815 static bool classof(const VisitorJob *VJ) {
1816 return VJ->getKind() == VisitorJob::NestedNameSpecifierLocVisitKind;
1817 }
1818
1819 NestedNameSpecifierLoc get() const {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001820 return NestedNameSpecifierLoc(
1821 const_cast<NestedNameSpecifier *>(
1822 static_cast<const NestedNameSpecifier *>(data[0])),
1823 const_cast<void *>(data[1]));
Guy Benyei11169dd2012-12-18 14:30:41 +00001824 }
1825};
1826
1827class DeclarationNameInfoVisit : public VisitorJob {
1828public:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001829 DeclarationNameInfoVisit(const Stmt *S, CXCursor parent)
Dmitri Gribenkodd7dacf2013-02-03 13:19:54 +00001830 : VisitorJob(parent, VisitorJob::DeclarationNameInfoVisitKind, S) {}
Guy Benyei11169dd2012-12-18 14:30:41 +00001831 static bool classof(const VisitorJob *VJ) {
1832 return VJ->getKind() == VisitorJob::DeclarationNameInfoVisitKind;
1833 }
1834 DeclarationNameInfo get() const {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001835 const Stmt *S = static_cast<const Stmt *>(data[0]);
Guy Benyei11169dd2012-12-18 14:30:41 +00001836 switch (S->getStmtClass()) {
1837 default:
1838 llvm_unreachable("Unhandled Stmt");
1839 case clang::Stmt::MSDependentExistsStmtClass:
1840 return cast<MSDependentExistsStmt>(S)->getNameInfo();
1841 case Stmt::CXXDependentScopeMemberExprClass:
1842 return cast<CXXDependentScopeMemberExpr>(S)->getMemberNameInfo();
1843 case Stmt::DependentScopeDeclRefExprClass:
1844 return cast<DependentScopeDeclRefExpr>(S)->getNameInfo();
Alexander Musmand9ed09f2014-07-21 09:42:05 +00001845 case Stmt::OMPCriticalDirectiveClass:
1846 return cast<OMPCriticalDirective>(S)->getDirectiveName();
Guy Benyei11169dd2012-12-18 14:30:41 +00001847 }
1848 }
1849};
1850class MemberRefVisit : public VisitorJob {
1851public:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001852 MemberRefVisit(const FieldDecl *D, SourceLocation L, CXCursor parent)
Guy Benyei11169dd2012-12-18 14:30:41 +00001853 : VisitorJob(parent, VisitorJob::MemberRefVisitKind, D,
1854 L.getPtrEncoding()) {}
1855 static bool classof(const VisitorJob *VJ) {
1856 return VJ->getKind() == VisitorJob::MemberRefVisitKind;
1857 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001858 const FieldDecl *get() const {
1859 return static_cast<const FieldDecl *>(data[0]);
Guy Benyei11169dd2012-12-18 14:30:41 +00001860 }
1861 SourceLocation getLoc() const {
1862 return SourceLocation::getFromRawEncoding((unsigned)(uintptr_t) data[1]);
1863 }
1864};
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001865class EnqueueVisitor : public ConstStmtVisitor<EnqueueVisitor, void> {
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001866 friend class OMPClauseEnqueue;
Guy Benyei11169dd2012-12-18 14:30:41 +00001867 VisitorWorkList &WL;
1868 CXCursor Parent;
1869public:
1870 EnqueueVisitor(VisitorWorkList &wl, CXCursor parent)
1871 : WL(wl), Parent(parent) {}
1872
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001873 void VisitAddrLabelExpr(const AddrLabelExpr *E);
1874 void VisitBlockExpr(const BlockExpr *B);
1875 void VisitCompoundLiteralExpr(const CompoundLiteralExpr *E);
1876 void VisitCompoundStmt(const CompoundStmt *S);
1877 void VisitCXXDefaultArgExpr(const CXXDefaultArgExpr *E) { /* Do nothing. */ }
1878 void VisitMSDependentExistsStmt(const MSDependentExistsStmt *S);
1879 void VisitCXXDependentScopeMemberExpr(const CXXDependentScopeMemberExpr *E);
1880 void VisitCXXNewExpr(const CXXNewExpr *E);
1881 void VisitCXXScalarValueInitExpr(const CXXScalarValueInitExpr *E);
1882 void VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *E);
1883 void VisitCXXPseudoDestructorExpr(const CXXPseudoDestructorExpr *E);
1884 void VisitCXXTemporaryObjectExpr(const CXXTemporaryObjectExpr *E);
1885 void VisitCXXTypeidExpr(const CXXTypeidExpr *E);
1886 void VisitCXXUnresolvedConstructExpr(const CXXUnresolvedConstructExpr *E);
1887 void VisitCXXUuidofExpr(const CXXUuidofExpr *E);
1888 void VisitCXXCatchStmt(const CXXCatchStmt *S);
Argyrios Kyrtzidis99891242014-11-13 09:03:21 +00001889 void VisitCXXForRangeStmt(const CXXForRangeStmt *S);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001890 void VisitDeclRefExpr(const DeclRefExpr *D);
1891 void VisitDeclStmt(const DeclStmt *S);
1892 void VisitDependentScopeDeclRefExpr(const DependentScopeDeclRefExpr *E);
1893 void VisitDesignatedInitExpr(const DesignatedInitExpr *E);
1894 void VisitExplicitCastExpr(const ExplicitCastExpr *E);
1895 void VisitForStmt(const ForStmt *FS);
1896 void VisitGotoStmt(const GotoStmt *GS);
1897 void VisitIfStmt(const IfStmt *If);
1898 void VisitInitListExpr(const InitListExpr *IE);
1899 void VisitMemberExpr(const MemberExpr *M);
1900 void VisitOffsetOfExpr(const OffsetOfExpr *E);
1901 void VisitObjCEncodeExpr(const ObjCEncodeExpr *E);
1902 void VisitObjCMessageExpr(const ObjCMessageExpr *M);
1903 void VisitOverloadExpr(const OverloadExpr *E);
1904 void VisitUnaryExprOrTypeTraitExpr(const UnaryExprOrTypeTraitExpr *E);
1905 void VisitStmt(const Stmt *S);
1906 void VisitSwitchStmt(const SwitchStmt *S);
1907 void VisitWhileStmt(const WhileStmt *W);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001908 void VisitTypeTraitExpr(const TypeTraitExpr *E);
1909 void VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *E);
1910 void VisitExpressionTraitExpr(const ExpressionTraitExpr *E);
1911 void VisitUnresolvedMemberExpr(const UnresolvedMemberExpr *U);
1912 void VisitVAArgExpr(const VAArgExpr *E);
1913 void VisitSizeOfPackExpr(const SizeOfPackExpr *E);
1914 void VisitPseudoObjectExpr(const PseudoObjectExpr *E);
1915 void VisitOpaqueValueExpr(const OpaqueValueExpr *E);
1916 void VisitLambdaExpr(const LambdaExpr *E);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001917 void VisitOMPExecutableDirective(const OMPExecutableDirective *D);
Alexander Musman3aaab662014-08-19 11:27:13 +00001918 void VisitOMPLoopDirective(const OMPLoopDirective *D);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001919 void VisitOMPParallelDirective(const OMPParallelDirective *D);
Alexey Bataev1b59ab52014-02-27 08:29:12 +00001920 void VisitOMPSimdDirective(const OMPSimdDirective *D);
Alexey Bataevf29276e2014-06-18 04:14:57 +00001921 void VisitOMPForDirective(const OMPForDirective *D);
Alexander Musmanf82886e2014-09-18 05:12:34 +00001922 void VisitOMPForSimdDirective(const OMPForSimdDirective *D);
Alexey Bataevd3f8dd22014-06-25 11:44:49 +00001923 void VisitOMPSectionsDirective(const OMPSectionsDirective *D);
Alexey Bataev1e0498a2014-06-26 08:21:58 +00001924 void VisitOMPSectionDirective(const OMPSectionDirective *D);
Alexey Bataevd1e40fb2014-06-26 12:05:45 +00001925 void VisitOMPSingleDirective(const OMPSingleDirective *D);
Alexander Musman80c22892014-07-17 08:54:58 +00001926 void VisitOMPMasterDirective(const OMPMasterDirective *D);
Alexander Musmand9ed09f2014-07-21 09:42:05 +00001927 void VisitOMPCriticalDirective(const OMPCriticalDirective *D);
Alexey Bataev4acb8592014-07-07 13:01:15 +00001928 void VisitOMPParallelForDirective(const OMPParallelForDirective *D);
Alexander Musmane4e893b2014-09-23 09:33:00 +00001929 void VisitOMPParallelForSimdDirective(const OMPParallelForSimdDirective *D);
Alexey Bataev84d0b3e2014-07-08 08:12:03 +00001930 void VisitOMPParallelSectionsDirective(const OMPParallelSectionsDirective *D);
Alexey Bataev9c2e8ee2014-07-11 11:25:16 +00001931 void VisitOMPTaskDirective(const OMPTaskDirective *D);
Alexey Bataev68446b72014-07-18 07:47:19 +00001932 void VisitOMPTaskyieldDirective(const OMPTaskyieldDirective *D);
Alexey Bataev4d1dfea2014-07-18 09:11:51 +00001933 void VisitOMPBarrierDirective(const OMPBarrierDirective *D);
Alexey Bataev2df347a2014-07-18 10:17:07 +00001934 void VisitOMPTaskwaitDirective(const OMPTaskwaitDirective *D);
Alexey Bataevc30dd2d2015-06-18 12:14:09 +00001935 void VisitOMPTaskgroupDirective(const OMPTaskgroupDirective *D);
Alexey Bataev6d4ed052015-07-01 06:57:41 +00001936 void
1937 VisitOMPCancellationPointDirective(const OMPCancellationPointDirective *D);
Alexey Bataev80909872015-07-02 11:25:17 +00001938 void VisitOMPCancelDirective(const OMPCancelDirective *D);
Alexey Bataev6125da92014-07-21 11:26:11 +00001939 void VisitOMPFlushDirective(const OMPFlushDirective *D);
Alexey Bataev9fb6e642014-07-22 06:45:04 +00001940 void VisitOMPOrderedDirective(const OMPOrderedDirective *D);
Alexey Bataev0162e452014-07-22 10:10:35 +00001941 void VisitOMPAtomicDirective(const OMPAtomicDirective *D);
Alexey Bataev0bd520b2014-09-19 08:19:49 +00001942 void VisitOMPTargetDirective(const OMPTargetDirective *D);
Michael Wong65f367f2015-07-21 13:44:28 +00001943 void VisitOMPTargetDataDirective(const OMPTargetDataDirective *D);
Alexey Bataev13314bf2014-10-09 04:18:56 +00001944 void VisitOMPTeamsDirective(const OMPTeamsDirective *D);
Alexey Bataev49f6e782015-12-01 04:18:41 +00001945 void VisitOMPTaskLoopDirective(const OMPTaskLoopDirective *D);
Alexey Bataev0a6ed842015-12-03 09:40:15 +00001946 void VisitOMPTaskLoopSimdDirective(const OMPTaskLoopSimdDirective *D);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001947
Guy Benyei11169dd2012-12-18 14:30:41 +00001948private:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001949 void AddDeclarationNameInfo(const Stmt *S);
Guy Benyei11169dd2012-12-18 14:30:41 +00001950 void AddNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier);
1951 void AddExplicitTemplateArgs(const ASTTemplateArgumentListInfo *A);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001952 void AddMemberRef(const FieldDecl *D, SourceLocation L);
1953 void AddStmt(const Stmt *S);
1954 void AddDecl(const Decl *D, bool isFirst = true);
Guy Benyei11169dd2012-12-18 14:30:41 +00001955 void AddTypeLoc(TypeSourceInfo *TI);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001956 void EnqueueChildren(const Stmt *S);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001957 void EnqueueChildren(const OMPClause *S);
Guy Benyei11169dd2012-12-18 14:30:41 +00001958};
Alexander Kornienkoab9db512015-06-22 23:07:51 +00001959} // end anonyous namespace
Guy Benyei11169dd2012-12-18 14:30:41 +00001960
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001961void EnqueueVisitor::AddDeclarationNameInfo(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001962 // 'S' should always be non-null, since it comes from the
1963 // statement we are visiting.
1964 WL.push_back(DeclarationNameInfoVisit(S, Parent));
1965}
1966
1967void
1968EnqueueVisitor::AddNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier) {
1969 if (Qualifier)
1970 WL.push_back(NestedNameSpecifierLocVisit(Qualifier, Parent));
1971}
1972
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001973void EnqueueVisitor::AddStmt(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001974 if (S)
1975 WL.push_back(StmtVisit(S, Parent));
1976}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001977void EnqueueVisitor::AddDecl(const Decl *D, bool isFirst) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001978 if (D)
1979 WL.push_back(DeclVisit(D, Parent, isFirst));
1980}
1981void EnqueueVisitor::
1982 AddExplicitTemplateArgs(const ASTTemplateArgumentListInfo *A) {
1983 if (A)
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001984 WL.push_back(ExplicitTemplateArgsVisit(A, Parent));
Guy Benyei11169dd2012-12-18 14:30:41 +00001985}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001986void EnqueueVisitor::AddMemberRef(const FieldDecl *D, SourceLocation L) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001987 if (D)
1988 WL.push_back(MemberRefVisit(D, L, Parent));
1989}
1990void EnqueueVisitor::AddTypeLoc(TypeSourceInfo *TI) {
1991 if (TI)
1992 WL.push_back(TypeLocVisit(TI->getTypeLoc(), Parent));
1993 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001994void EnqueueVisitor::EnqueueChildren(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001995 unsigned size = WL.size();
Benjamin Kramer642f1732015-07-02 21:03:14 +00001996 for (const Stmt *SubStmt : S->children()) {
1997 AddStmt(SubStmt);
Guy Benyei11169dd2012-12-18 14:30:41 +00001998 }
1999 if (size == WL.size())
2000 return;
2001 // Now reverse the entries we just added. This will match the DFS
2002 // ordering performed by the worklist.
2003 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
2004 std::reverse(I, E);
2005}
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002006namespace {
2007class OMPClauseEnqueue : public ConstOMPClauseVisitor<OMPClauseEnqueue> {
2008 EnqueueVisitor *Visitor;
Alexey Bataev756c1962013-09-24 03:17:45 +00002009 /// \brief Process clauses with list of variables.
2010 template <typename T>
2011 void VisitOMPClauseList(T *Node);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002012public:
2013 OMPClauseEnqueue(EnqueueVisitor *Visitor) : Visitor(Visitor) { }
2014#define OPENMP_CLAUSE(Name, Class) \
2015 void Visit##Class(const Class *C);
2016#include "clang/Basic/OpenMPKinds.def"
2017};
2018
Alexey Bataevaadd52e2014-02-13 05:29:23 +00002019void OMPClauseEnqueue::VisitOMPIfClause(const OMPIfClause *C) {
2020 Visitor->AddStmt(C->getCondition());
2021}
2022
Alexey Bataev3778b602014-07-17 07:32:53 +00002023void OMPClauseEnqueue::VisitOMPFinalClause(const OMPFinalClause *C) {
2024 Visitor->AddStmt(C->getCondition());
2025}
2026
Alexey Bataev568a8332014-03-06 06:15:19 +00002027void OMPClauseEnqueue::VisitOMPNumThreadsClause(const OMPNumThreadsClause *C) {
2028 Visitor->AddStmt(C->getNumThreads());
2029}
2030
Alexey Bataev62c87d22014-03-21 04:51:18 +00002031void OMPClauseEnqueue::VisitOMPSafelenClause(const OMPSafelenClause *C) {
2032 Visitor->AddStmt(C->getSafelen());
2033}
2034
Alexey Bataev66b15b52015-08-21 11:14:16 +00002035void OMPClauseEnqueue::VisitOMPSimdlenClause(const OMPSimdlenClause *C) {
2036 Visitor->AddStmt(C->getSimdlen());
2037}
2038
Alexander Musman8bd31e62014-05-27 15:12:19 +00002039void OMPClauseEnqueue::VisitOMPCollapseClause(const OMPCollapseClause *C) {
2040 Visitor->AddStmt(C->getNumForLoops());
2041}
2042
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002043void OMPClauseEnqueue::VisitOMPDefaultClause(const OMPDefaultClause *C) { }
Alexey Bataev756c1962013-09-24 03:17:45 +00002044
Alexey Bataevbcbadb62014-05-06 06:04:14 +00002045void OMPClauseEnqueue::VisitOMPProcBindClause(const OMPProcBindClause *C) { }
2046
Alexey Bataev56dafe82014-06-20 07:16:17 +00002047void OMPClauseEnqueue::VisitOMPScheduleClause(const OMPScheduleClause *C) {
2048 Visitor->AddStmt(C->getChunkSize());
Alexey Bataev040d5402015-05-12 08:35:28 +00002049 Visitor->AddStmt(C->getHelperChunkSize());
Alexey Bataev56dafe82014-06-20 07:16:17 +00002050}
2051
Alexey Bataev10e775f2015-07-30 11:36:16 +00002052void OMPClauseEnqueue::VisitOMPOrderedClause(const OMPOrderedClause *C) {
2053 Visitor->AddStmt(C->getNumForLoops());
2054}
Alexey Bataev142e1fc2014-06-20 09:44:06 +00002055
Alexey Bataev236070f2014-06-20 11:19:47 +00002056void OMPClauseEnqueue::VisitOMPNowaitClause(const OMPNowaitClause *) {}
2057
Alexey Bataev7aea99a2014-07-17 12:19:31 +00002058void OMPClauseEnqueue::VisitOMPUntiedClause(const OMPUntiedClause *) {}
2059
Alexey Bataev74ba3a52014-07-17 12:47:03 +00002060void OMPClauseEnqueue::VisitOMPMergeableClause(const OMPMergeableClause *) {}
2061
Alexey Bataevf98b00c2014-07-23 02:27:21 +00002062void OMPClauseEnqueue::VisitOMPReadClause(const OMPReadClause *) {}
2063
Alexey Bataevdea47612014-07-23 07:46:59 +00002064void OMPClauseEnqueue::VisitOMPWriteClause(const OMPWriteClause *) {}
2065
Alexey Bataev67a4f222014-07-23 10:25:33 +00002066void OMPClauseEnqueue::VisitOMPUpdateClause(const OMPUpdateClause *) {}
2067
Alexey Bataev459dec02014-07-24 06:46:57 +00002068void OMPClauseEnqueue::VisitOMPCaptureClause(const OMPCaptureClause *) {}
2069
Alexey Bataev82bad8b2014-07-24 08:55:34 +00002070void OMPClauseEnqueue::VisitOMPSeqCstClause(const OMPSeqCstClause *) {}
2071
Alexey Bataev346265e2015-09-25 10:37:12 +00002072void OMPClauseEnqueue::VisitOMPThreadsClause(const OMPThreadsClause *) {}
2073
Alexey Bataevd14d1e62015-09-28 06:39:35 +00002074void OMPClauseEnqueue::VisitOMPSIMDClause(const OMPSIMDClause *) {}
2075
Alexey Bataevb825de12015-12-07 10:51:44 +00002076void OMPClauseEnqueue::VisitOMPNogroupClause(const OMPNogroupClause *) {}
2077
Michael Wonge710d542015-08-07 16:16:36 +00002078void OMPClauseEnqueue::VisitOMPDeviceClause(const OMPDeviceClause *C) {
2079 Visitor->AddStmt(C->getDevice());
2080}
2081
Kelvin Li099bb8c2015-11-24 20:50:12 +00002082void OMPClauseEnqueue::VisitOMPNumTeamsClause(const OMPNumTeamsClause *C) {
2083 Visitor->AddStmt(C->getNumTeams());
2084}
2085
Kelvin Lia15fb1a2015-11-27 18:47:36 +00002086void OMPClauseEnqueue::VisitOMPThreadLimitClause(const OMPThreadLimitClause *C) {
2087 Visitor->AddStmt(C->getThreadLimit());
2088}
2089
Alexey Bataeva0569352015-12-01 10:17:31 +00002090void OMPClauseEnqueue::VisitOMPPriorityClause(const OMPPriorityClause *C) {
2091 Visitor->AddStmt(C->getPriority());
2092}
2093
Alexey Bataev1fd4aed2015-12-07 12:52:51 +00002094void OMPClauseEnqueue::VisitOMPGrainsizeClause(const OMPGrainsizeClause *C) {
2095 Visitor->AddStmt(C->getGrainsize());
2096}
2097
Alexey Bataev382967a2015-12-08 12:06:20 +00002098void OMPClauseEnqueue::VisitOMPNumTasksClause(const OMPNumTasksClause *C) {
2099 Visitor->AddStmt(C->getNumTasks());
2100}
2101
Alexey Bataev756c1962013-09-24 03:17:45 +00002102template<typename T>
2103void OMPClauseEnqueue::VisitOMPClauseList(T *Node) {
Alexey Bataev03b340a2014-10-21 03:16:40 +00002104 for (const auto *I : Node->varlists()) {
Aaron Ballman2205d2a2014-03-14 15:55:35 +00002105 Visitor->AddStmt(I);
Alexey Bataev03b340a2014-10-21 03:16:40 +00002106 }
Alexey Bataev756c1962013-09-24 03:17:45 +00002107}
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002108
2109void OMPClauseEnqueue::VisitOMPPrivateClause(const OMPPrivateClause *C) {
Alexey Bataev756c1962013-09-24 03:17:45 +00002110 VisitOMPClauseList(C);
Alexey Bataev03b340a2014-10-21 03:16:40 +00002111 for (const auto *E : C->private_copies()) {
2112 Visitor->AddStmt(E);
2113 }
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002114}
Alexey Bataevd5af8e42013-10-01 05:32:34 +00002115void OMPClauseEnqueue::VisitOMPFirstprivateClause(
2116 const OMPFirstprivateClause *C) {
2117 VisitOMPClauseList(C);
2118}
Alexander Musman1bb328c2014-06-04 13:06:39 +00002119void OMPClauseEnqueue::VisitOMPLastprivateClause(
2120 const OMPLastprivateClause *C) {
2121 VisitOMPClauseList(C);
Alexey Bataev38e89532015-04-16 04:54:05 +00002122 for (auto *E : C->private_copies()) {
2123 Visitor->AddStmt(E);
2124 }
2125 for (auto *E : C->source_exprs()) {
2126 Visitor->AddStmt(E);
2127 }
2128 for (auto *E : C->destination_exprs()) {
2129 Visitor->AddStmt(E);
2130 }
2131 for (auto *E : C->assignment_ops()) {
2132 Visitor->AddStmt(E);
2133 }
Alexander Musman1bb328c2014-06-04 13:06:39 +00002134}
Alexey Bataev758e55e2013-09-06 18:03:48 +00002135void OMPClauseEnqueue::VisitOMPSharedClause(const OMPSharedClause *C) {
Alexey Bataev756c1962013-09-24 03:17:45 +00002136 VisitOMPClauseList(C);
Alexey Bataev758e55e2013-09-06 18:03:48 +00002137}
Alexey Bataevc5e02582014-06-16 07:08:35 +00002138void OMPClauseEnqueue::VisitOMPReductionClause(const OMPReductionClause *C) {
2139 VisitOMPClauseList(C);
Alexey Bataevf24e7b12015-10-08 09:10:53 +00002140 for (auto *E : C->privates()) {
2141 Visitor->AddStmt(E);
2142 }
Alexey Bataev794ba0d2015-04-10 10:43:45 +00002143 for (auto *E : C->lhs_exprs()) {
2144 Visitor->AddStmt(E);
2145 }
2146 for (auto *E : C->rhs_exprs()) {
2147 Visitor->AddStmt(E);
2148 }
2149 for (auto *E : C->reduction_ops()) {
2150 Visitor->AddStmt(E);
2151 }
Alexey Bataevc5e02582014-06-16 07:08:35 +00002152}
Alexander Musman8dba6642014-04-22 13:09:42 +00002153void OMPClauseEnqueue::VisitOMPLinearClause(const OMPLinearClause *C) {
2154 VisitOMPClauseList(C);
Alexey Bataevbd9fec12015-08-18 06:47:21 +00002155 for (const auto *E : C->privates()) {
2156 Visitor->AddStmt(E);
2157 }
Alexander Musman3276a272015-03-21 10:12:56 +00002158 for (const auto *E : C->inits()) {
2159 Visitor->AddStmt(E);
2160 }
2161 for (const auto *E : C->updates()) {
2162 Visitor->AddStmt(E);
2163 }
2164 for (const auto *E : C->finals()) {
2165 Visitor->AddStmt(E);
2166 }
Alexander Musman8dba6642014-04-22 13:09:42 +00002167 Visitor->AddStmt(C->getStep());
Alexander Musman3276a272015-03-21 10:12:56 +00002168 Visitor->AddStmt(C->getCalcStep());
Alexander Musman8dba6642014-04-22 13:09:42 +00002169}
Alexander Musmanf0d76e72014-05-29 14:36:25 +00002170void OMPClauseEnqueue::VisitOMPAlignedClause(const OMPAlignedClause *C) {
2171 VisitOMPClauseList(C);
2172 Visitor->AddStmt(C->getAlignment());
2173}
Alexey Bataevd48bcd82014-03-31 03:36:38 +00002174void OMPClauseEnqueue::VisitOMPCopyinClause(const OMPCopyinClause *C) {
2175 VisitOMPClauseList(C);
Alexey Bataevf56f98c2015-04-16 05:39:01 +00002176 for (auto *E : C->source_exprs()) {
2177 Visitor->AddStmt(E);
2178 }
2179 for (auto *E : C->destination_exprs()) {
2180 Visitor->AddStmt(E);
2181 }
2182 for (auto *E : C->assignment_ops()) {
2183 Visitor->AddStmt(E);
2184 }
Alexey Bataevd48bcd82014-03-31 03:36:38 +00002185}
Alexey Bataevbae9a792014-06-27 10:37:06 +00002186void
2187OMPClauseEnqueue::VisitOMPCopyprivateClause(const OMPCopyprivateClause *C) {
2188 VisitOMPClauseList(C);
Alexey Bataeva63048e2015-03-23 06:18:07 +00002189 for (auto *E : C->source_exprs()) {
2190 Visitor->AddStmt(E);
2191 }
2192 for (auto *E : C->destination_exprs()) {
2193 Visitor->AddStmt(E);
2194 }
2195 for (auto *E : C->assignment_ops()) {
2196 Visitor->AddStmt(E);
2197 }
Alexey Bataevbae9a792014-06-27 10:37:06 +00002198}
Alexey Bataev6125da92014-07-21 11:26:11 +00002199void OMPClauseEnqueue::VisitOMPFlushClause(const OMPFlushClause *C) {
2200 VisitOMPClauseList(C);
2201}
Alexey Bataev1c2cfbc2015-06-23 14:25:19 +00002202void OMPClauseEnqueue::VisitOMPDependClause(const OMPDependClause *C) {
2203 VisitOMPClauseList(C);
2204}
Kelvin Li0bff7af2015-11-23 05:32:03 +00002205void OMPClauseEnqueue::VisitOMPMapClause(const OMPMapClause *C) {
2206 VisitOMPClauseList(C);
2207}
Alexander Kornienkoab9db512015-06-22 23:07:51 +00002208}
Alexey Bataev756c1962013-09-24 03:17:45 +00002209
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002210void EnqueueVisitor::EnqueueChildren(const OMPClause *S) {
2211 unsigned size = WL.size();
2212 OMPClauseEnqueue Visitor(this);
2213 Visitor.Visit(S);
2214 if (size == WL.size())
2215 return;
2216 // Now reverse the entries we just added. This will match the DFS
2217 // ordering performed by the worklist.
2218 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
2219 std::reverse(I, E);
2220}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002221void EnqueueVisitor::VisitAddrLabelExpr(const AddrLabelExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002222 WL.push_back(LabelRefVisit(E->getLabel(), E->getLabelLoc(), Parent));
2223}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002224void EnqueueVisitor::VisitBlockExpr(const BlockExpr *B) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002225 AddDecl(B->getBlockDecl());
2226}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002227void EnqueueVisitor::VisitCompoundLiteralExpr(const CompoundLiteralExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002228 EnqueueChildren(E);
2229 AddTypeLoc(E->getTypeSourceInfo());
2230}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002231void EnqueueVisitor::VisitCompoundStmt(const CompoundStmt *S) {
Pete Cooper57d3f142015-07-30 17:22:52 +00002232 for (auto &I : llvm::reverse(S->body()))
2233 AddStmt(I);
Guy Benyei11169dd2012-12-18 14:30:41 +00002234}
2235void EnqueueVisitor::
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002236VisitMSDependentExistsStmt(const MSDependentExistsStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002237 AddStmt(S->getSubStmt());
2238 AddDeclarationNameInfo(S);
2239 if (NestedNameSpecifierLoc QualifierLoc = S->getQualifierLoc())
2240 AddNestedNameSpecifierLoc(QualifierLoc);
2241}
2242
2243void EnqueueVisitor::
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002244VisitCXXDependentScopeMemberExpr(const CXXDependentScopeMemberExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002245 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
2246 AddDeclarationNameInfo(E);
2247 if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
2248 AddNestedNameSpecifierLoc(QualifierLoc);
2249 if (!E->isImplicitAccess())
2250 AddStmt(E->getBase());
2251}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002252void EnqueueVisitor::VisitCXXNewExpr(const CXXNewExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002253 // Enqueue the initializer , if any.
2254 AddStmt(E->getInitializer());
2255 // Enqueue the array size, if any.
2256 AddStmt(E->getArraySize());
2257 // Enqueue the allocated type.
2258 AddTypeLoc(E->getAllocatedTypeSourceInfo());
2259 // Enqueue the placement arguments.
2260 for (unsigned I = E->getNumPlacementArgs(); I > 0; --I)
2261 AddStmt(E->getPlacementArg(I-1));
2262}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002263void EnqueueVisitor::VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *CE) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002264 for (unsigned I = CE->getNumArgs(); I > 1 /* Yes, this is 1 */; --I)
2265 AddStmt(CE->getArg(I-1));
2266 AddStmt(CE->getCallee());
2267 AddStmt(CE->getArg(0));
2268}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002269void EnqueueVisitor::VisitCXXPseudoDestructorExpr(
2270 const CXXPseudoDestructorExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002271 // Visit the name of the type being destroyed.
2272 AddTypeLoc(E->getDestroyedTypeInfo());
2273 // Visit the scope type that looks disturbingly like the nested-name-specifier
2274 // but isn't.
2275 AddTypeLoc(E->getScopeTypeInfo());
2276 // Visit the nested-name-specifier.
2277 if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
2278 AddNestedNameSpecifierLoc(QualifierLoc);
2279 // Visit base expression.
2280 AddStmt(E->getBase());
2281}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002282void EnqueueVisitor::VisitCXXScalarValueInitExpr(
2283 const CXXScalarValueInitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002284 AddTypeLoc(E->getTypeSourceInfo());
2285}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002286void EnqueueVisitor::VisitCXXTemporaryObjectExpr(
2287 const CXXTemporaryObjectExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002288 EnqueueChildren(E);
2289 AddTypeLoc(E->getTypeSourceInfo());
2290}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002291void EnqueueVisitor::VisitCXXTypeidExpr(const CXXTypeidExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002292 EnqueueChildren(E);
2293 if (E->isTypeOperand())
2294 AddTypeLoc(E->getTypeOperandSourceInfo());
2295}
2296
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002297void EnqueueVisitor::VisitCXXUnresolvedConstructExpr(
2298 const CXXUnresolvedConstructExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002299 EnqueueChildren(E);
2300 AddTypeLoc(E->getTypeSourceInfo());
2301}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002302void EnqueueVisitor::VisitCXXUuidofExpr(const CXXUuidofExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002303 EnqueueChildren(E);
2304 if (E->isTypeOperand())
2305 AddTypeLoc(E->getTypeOperandSourceInfo());
2306}
2307
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002308void EnqueueVisitor::VisitCXXCatchStmt(const CXXCatchStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002309 EnqueueChildren(S);
2310 AddDecl(S->getExceptionDecl());
2311}
2312
Argyrios Kyrtzidis99891242014-11-13 09:03:21 +00002313void EnqueueVisitor::VisitCXXForRangeStmt(const CXXForRangeStmt *S) {
Argyrios Kyrtzidiscde70692014-11-13 09:50:19 +00002314 AddStmt(S->getBody());
Argyrios Kyrtzidis99891242014-11-13 09:03:21 +00002315 AddStmt(S->getRangeInit());
Argyrios Kyrtzidiscde70692014-11-13 09:50:19 +00002316 AddDecl(S->getLoopVariable());
Argyrios Kyrtzidis99891242014-11-13 09:03:21 +00002317}
2318
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002319void EnqueueVisitor::VisitDeclRefExpr(const DeclRefExpr *DR) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002320 if (DR->hasExplicitTemplateArgs()) {
2321 AddExplicitTemplateArgs(&DR->getExplicitTemplateArgs());
2322 }
2323 WL.push_back(DeclRefExprParts(DR, Parent));
2324}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002325void EnqueueVisitor::VisitDependentScopeDeclRefExpr(
2326 const DependentScopeDeclRefExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002327 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
2328 AddDeclarationNameInfo(E);
2329 AddNestedNameSpecifierLoc(E->getQualifierLoc());
2330}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002331void EnqueueVisitor::VisitDeclStmt(const DeclStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002332 unsigned size = WL.size();
2333 bool isFirst = true;
Aaron Ballman535bbcc2014-03-14 17:01:24 +00002334 for (const auto *D : S->decls()) {
2335 AddDecl(D, isFirst);
Guy Benyei11169dd2012-12-18 14:30:41 +00002336 isFirst = false;
2337 }
2338 if (size == WL.size())
2339 return;
2340 // Now reverse the entries we just added. This will match the DFS
2341 // ordering performed by the worklist.
2342 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
2343 std::reverse(I, E);
2344}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002345void EnqueueVisitor::VisitDesignatedInitExpr(const DesignatedInitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002346 AddStmt(E->getInit());
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002347 for (DesignatedInitExpr::const_reverse_designators_iterator
Guy Benyei11169dd2012-12-18 14:30:41 +00002348 D = E->designators_rbegin(), DEnd = E->designators_rend();
2349 D != DEnd; ++D) {
2350 if (D->isFieldDesignator()) {
2351 if (FieldDecl *Field = D->getField())
2352 AddMemberRef(Field, D->getFieldLoc());
2353 continue;
2354 }
2355 if (D->isArrayDesignator()) {
2356 AddStmt(E->getArrayIndex(*D));
2357 continue;
2358 }
2359 assert(D->isArrayRangeDesignator() && "Unknown designator kind");
2360 AddStmt(E->getArrayRangeEnd(*D));
2361 AddStmt(E->getArrayRangeStart(*D));
2362 }
2363}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002364void EnqueueVisitor::VisitExplicitCastExpr(const ExplicitCastExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002365 EnqueueChildren(E);
2366 AddTypeLoc(E->getTypeInfoAsWritten());
2367}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002368void EnqueueVisitor::VisitForStmt(const ForStmt *FS) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002369 AddStmt(FS->getBody());
2370 AddStmt(FS->getInc());
2371 AddStmt(FS->getCond());
2372 AddDecl(FS->getConditionVariable());
2373 AddStmt(FS->getInit());
2374}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002375void EnqueueVisitor::VisitGotoStmt(const GotoStmt *GS) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002376 WL.push_back(LabelRefVisit(GS->getLabel(), GS->getLabelLoc(), Parent));
2377}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002378void EnqueueVisitor::VisitIfStmt(const IfStmt *If) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002379 AddStmt(If->getElse());
2380 AddStmt(If->getThen());
2381 AddStmt(If->getCond());
2382 AddDecl(If->getConditionVariable());
2383}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002384void EnqueueVisitor::VisitInitListExpr(const InitListExpr *IE) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002385 // We care about the syntactic form of the initializer list, only.
2386 if (InitListExpr *Syntactic = IE->getSyntacticForm())
2387 IE = Syntactic;
2388 EnqueueChildren(IE);
2389}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002390void EnqueueVisitor::VisitMemberExpr(const MemberExpr *M) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002391 WL.push_back(MemberExprParts(M, Parent));
2392
2393 // If the base of the member access expression is an implicit 'this', don't
2394 // visit it.
2395 // FIXME: If we ever want to show these implicit accesses, this will be
2396 // unfortunate. However, clang_getCursor() relies on this behavior.
Argyrios Kyrtzidis58d0e7a2015-03-13 04:40:07 +00002397 if (M->isImplicitAccess())
2398 return;
2399
2400 // Ignore base anonymous struct/union fields, otherwise they will shadow the
2401 // real field that that we are interested in.
2402 if (auto *SubME = dyn_cast<MemberExpr>(M->getBase())) {
2403 if (auto *FD = dyn_cast_or_null<FieldDecl>(SubME->getMemberDecl())) {
2404 if (FD->isAnonymousStructOrUnion()) {
2405 AddStmt(SubME->getBase());
2406 return;
2407 }
2408 }
2409 }
2410
2411 AddStmt(M->getBase());
Guy Benyei11169dd2012-12-18 14:30:41 +00002412}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002413void EnqueueVisitor::VisitObjCEncodeExpr(const ObjCEncodeExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002414 AddTypeLoc(E->getEncodedTypeSourceInfo());
2415}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002416void EnqueueVisitor::VisitObjCMessageExpr(const ObjCMessageExpr *M) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002417 EnqueueChildren(M);
2418 AddTypeLoc(M->getClassReceiverTypeInfo());
2419}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002420void EnqueueVisitor::VisitOffsetOfExpr(const OffsetOfExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002421 // Visit the components of the offsetof expression.
2422 for (unsigned N = E->getNumComponents(), I = N; I > 0; --I) {
2423 typedef OffsetOfExpr::OffsetOfNode OffsetOfNode;
2424 const OffsetOfNode &Node = E->getComponent(I-1);
2425 switch (Node.getKind()) {
2426 case OffsetOfNode::Array:
2427 AddStmt(E->getIndexExpr(Node.getArrayExprIndex()));
2428 break;
2429 case OffsetOfNode::Field:
2430 AddMemberRef(Node.getField(), Node.getSourceRange().getEnd());
2431 break;
2432 case OffsetOfNode::Identifier:
2433 case OffsetOfNode::Base:
2434 continue;
2435 }
2436 }
2437 // Visit the type into which we're computing the offset.
2438 AddTypeLoc(E->getTypeSourceInfo());
2439}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002440void EnqueueVisitor::VisitOverloadExpr(const OverloadExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002441 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
2442 WL.push_back(OverloadExprParts(E, Parent));
2443}
2444void EnqueueVisitor::VisitUnaryExprOrTypeTraitExpr(
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002445 const UnaryExprOrTypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002446 EnqueueChildren(E);
2447 if (E->isArgumentType())
2448 AddTypeLoc(E->getArgumentTypeInfo());
2449}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002450void EnqueueVisitor::VisitStmt(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002451 EnqueueChildren(S);
2452}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002453void EnqueueVisitor::VisitSwitchStmt(const SwitchStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002454 AddStmt(S->getBody());
2455 AddStmt(S->getCond());
2456 AddDecl(S->getConditionVariable());
2457}
2458
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002459void EnqueueVisitor::VisitWhileStmt(const WhileStmt *W) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002460 AddStmt(W->getBody());
2461 AddStmt(W->getCond());
2462 AddDecl(W->getConditionVariable());
2463}
2464
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002465void EnqueueVisitor::VisitTypeTraitExpr(const TypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002466 for (unsigned I = E->getNumArgs(); I > 0; --I)
2467 AddTypeLoc(E->getArg(I-1));
2468}
2469
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002470void EnqueueVisitor::VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002471 AddTypeLoc(E->getQueriedTypeSourceInfo());
2472}
2473
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002474void EnqueueVisitor::VisitExpressionTraitExpr(const ExpressionTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002475 EnqueueChildren(E);
2476}
2477
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002478void EnqueueVisitor::VisitUnresolvedMemberExpr(const UnresolvedMemberExpr *U) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002479 VisitOverloadExpr(U);
2480 if (!U->isImplicitAccess())
2481 AddStmt(U->getBase());
2482}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002483void EnqueueVisitor::VisitVAArgExpr(const VAArgExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002484 AddStmt(E->getSubExpr());
2485 AddTypeLoc(E->getWrittenTypeInfo());
2486}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002487void EnqueueVisitor::VisitSizeOfPackExpr(const SizeOfPackExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002488 WL.push_back(SizeOfPackExprParts(E, Parent));
2489}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002490void EnqueueVisitor::VisitOpaqueValueExpr(const OpaqueValueExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002491 // If the opaque value has a source expression, just transparently
2492 // visit that. This is useful for (e.g.) pseudo-object expressions.
2493 if (Expr *SourceExpr = E->getSourceExpr())
2494 return Visit(SourceExpr);
2495}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002496void EnqueueVisitor::VisitLambdaExpr(const LambdaExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002497 AddStmt(E->getBody());
2498 WL.push_back(LambdaExprParts(E, Parent));
2499}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002500void EnqueueVisitor::VisitPseudoObjectExpr(const PseudoObjectExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002501 // Treat the expression like its syntactic form.
2502 Visit(E->getSyntacticForm());
2503}
2504
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002505void EnqueueVisitor::VisitOMPExecutableDirective(
2506 const OMPExecutableDirective *D) {
2507 EnqueueChildren(D);
2508 for (ArrayRef<OMPClause *>::iterator I = D->clauses().begin(),
2509 E = D->clauses().end();
2510 I != E; ++I)
2511 EnqueueChildren(*I);
2512}
2513
Alexander Musman3aaab662014-08-19 11:27:13 +00002514void EnqueueVisitor::VisitOMPLoopDirective(const OMPLoopDirective *D) {
2515 VisitOMPExecutableDirective(D);
2516}
2517
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002518void EnqueueVisitor::VisitOMPParallelDirective(const OMPParallelDirective *D) {
2519 VisitOMPExecutableDirective(D);
2520}
2521
Alexey Bataev1b59ab52014-02-27 08:29:12 +00002522void EnqueueVisitor::VisitOMPSimdDirective(const OMPSimdDirective *D) {
Alexander Musman3aaab662014-08-19 11:27:13 +00002523 VisitOMPLoopDirective(D);
Alexey Bataev1b59ab52014-02-27 08:29:12 +00002524}
2525
Alexey Bataevf29276e2014-06-18 04:14:57 +00002526void EnqueueVisitor::VisitOMPForDirective(const OMPForDirective *D) {
Alexander Musman3aaab662014-08-19 11:27:13 +00002527 VisitOMPLoopDirective(D);
Alexey Bataevf29276e2014-06-18 04:14:57 +00002528}
2529
Alexander Musmanf82886e2014-09-18 05:12:34 +00002530void EnqueueVisitor::VisitOMPForSimdDirective(const OMPForSimdDirective *D) {
2531 VisitOMPLoopDirective(D);
2532}
2533
Alexey Bataevd3f8dd22014-06-25 11:44:49 +00002534void EnqueueVisitor::VisitOMPSectionsDirective(const OMPSectionsDirective *D) {
2535 VisitOMPExecutableDirective(D);
2536}
2537
Alexey Bataev1e0498a2014-06-26 08:21:58 +00002538void EnqueueVisitor::VisitOMPSectionDirective(const OMPSectionDirective *D) {
2539 VisitOMPExecutableDirective(D);
2540}
2541
Alexey Bataevd1e40fb2014-06-26 12:05:45 +00002542void EnqueueVisitor::VisitOMPSingleDirective(const OMPSingleDirective *D) {
2543 VisitOMPExecutableDirective(D);
2544}
2545
Alexander Musman80c22892014-07-17 08:54:58 +00002546void EnqueueVisitor::VisitOMPMasterDirective(const OMPMasterDirective *D) {
2547 VisitOMPExecutableDirective(D);
2548}
2549
Alexander Musmand9ed09f2014-07-21 09:42:05 +00002550void EnqueueVisitor::VisitOMPCriticalDirective(const OMPCriticalDirective *D) {
2551 VisitOMPExecutableDirective(D);
2552 AddDeclarationNameInfo(D);
2553}
2554
Alexey Bataev4acb8592014-07-07 13:01:15 +00002555void
2556EnqueueVisitor::VisitOMPParallelForDirective(const OMPParallelForDirective *D) {
Alexander Musman3aaab662014-08-19 11:27:13 +00002557 VisitOMPLoopDirective(D);
Alexey Bataev4acb8592014-07-07 13:01:15 +00002558}
2559
Alexander Musmane4e893b2014-09-23 09:33:00 +00002560void EnqueueVisitor::VisitOMPParallelForSimdDirective(
2561 const OMPParallelForSimdDirective *D) {
2562 VisitOMPLoopDirective(D);
2563}
2564
Alexey Bataev84d0b3e2014-07-08 08:12:03 +00002565void EnqueueVisitor::VisitOMPParallelSectionsDirective(
2566 const OMPParallelSectionsDirective *D) {
2567 VisitOMPExecutableDirective(D);
2568}
2569
Alexey Bataev9c2e8ee2014-07-11 11:25:16 +00002570void EnqueueVisitor::VisitOMPTaskDirective(const OMPTaskDirective *D) {
2571 VisitOMPExecutableDirective(D);
2572}
2573
Alexey Bataev68446b72014-07-18 07:47:19 +00002574void
2575EnqueueVisitor::VisitOMPTaskyieldDirective(const OMPTaskyieldDirective *D) {
2576 VisitOMPExecutableDirective(D);
2577}
2578
Alexey Bataev4d1dfea2014-07-18 09:11:51 +00002579void EnqueueVisitor::VisitOMPBarrierDirective(const OMPBarrierDirective *D) {
2580 VisitOMPExecutableDirective(D);
2581}
2582
Alexey Bataev2df347a2014-07-18 10:17:07 +00002583void EnqueueVisitor::VisitOMPTaskwaitDirective(const OMPTaskwaitDirective *D) {
2584 VisitOMPExecutableDirective(D);
2585}
2586
Alexey Bataevc30dd2d2015-06-18 12:14:09 +00002587void EnqueueVisitor::VisitOMPTaskgroupDirective(
2588 const OMPTaskgroupDirective *D) {
2589 VisitOMPExecutableDirective(D);
2590}
2591
Alexey Bataev6125da92014-07-21 11:26:11 +00002592void EnqueueVisitor::VisitOMPFlushDirective(const OMPFlushDirective *D) {
2593 VisitOMPExecutableDirective(D);
2594}
2595
Alexey Bataev9fb6e642014-07-22 06:45:04 +00002596void EnqueueVisitor::VisitOMPOrderedDirective(const OMPOrderedDirective *D) {
2597 VisitOMPExecutableDirective(D);
2598}
2599
Alexey Bataev0162e452014-07-22 10:10:35 +00002600void EnqueueVisitor::VisitOMPAtomicDirective(const OMPAtomicDirective *D) {
2601 VisitOMPExecutableDirective(D);
2602}
2603
Alexey Bataev0bd520b2014-09-19 08:19:49 +00002604void EnqueueVisitor::VisitOMPTargetDirective(const OMPTargetDirective *D) {
2605 VisitOMPExecutableDirective(D);
2606}
2607
Michael Wong65f367f2015-07-21 13:44:28 +00002608void EnqueueVisitor::VisitOMPTargetDataDirective(const
2609 OMPTargetDataDirective *D) {
2610 VisitOMPExecutableDirective(D);
2611}
2612
Alexey Bataev13314bf2014-10-09 04:18:56 +00002613void EnqueueVisitor::VisitOMPTeamsDirective(const OMPTeamsDirective *D) {
2614 VisitOMPExecutableDirective(D);
2615}
2616
Alexey Bataev6d4ed052015-07-01 06:57:41 +00002617void EnqueueVisitor::VisitOMPCancellationPointDirective(
2618 const OMPCancellationPointDirective *D) {
2619 VisitOMPExecutableDirective(D);
2620}
2621
Alexey Bataev80909872015-07-02 11:25:17 +00002622void EnqueueVisitor::VisitOMPCancelDirective(const OMPCancelDirective *D) {
2623 VisitOMPExecutableDirective(D);
2624}
2625
Alexey Bataev49f6e782015-12-01 04:18:41 +00002626void EnqueueVisitor::VisitOMPTaskLoopDirective(const OMPTaskLoopDirective *D) {
2627 VisitOMPLoopDirective(D);
2628}
2629
Alexey Bataev0a6ed842015-12-03 09:40:15 +00002630void EnqueueVisitor::VisitOMPTaskLoopSimdDirective(
2631 const OMPTaskLoopSimdDirective *D) {
2632 VisitOMPLoopDirective(D);
2633}
2634
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002635void CursorVisitor::EnqueueWorkList(VisitorWorkList &WL, const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002636 EnqueueVisitor(WL, MakeCXCursor(S, StmtParent, TU,RegionOfInterest)).Visit(S);
2637}
2638
2639bool CursorVisitor::IsInRegionOfInterest(CXCursor C) {
2640 if (RegionOfInterest.isValid()) {
2641 SourceRange Range = getRawCursorExtent(C);
2642 if (Range.isInvalid() || CompareRegionOfInterest(Range))
2643 return false;
2644 }
2645 return true;
2646}
2647
2648bool CursorVisitor::RunVisitorWorkList(VisitorWorkList &WL) {
2649 while (!WL.empty()) {
2650 // Dequeue the worklist item.
Robert Wilhelm25284cc2013-08-23 16:11:15 +00002651 VisitorJob LI = WL.pop_back_val();
Guy Benyei11169dd2012-12-18 14:30:41 +00002652
2653 // Set the Parent field, then back to its old value once we're done.
2654 SetParentRAII SetParent(Parent, StmtParent, LI.getParent());
2655
2656 switch (LI.getKind()) {
2657 case VisitorJob::DeclVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002658 const Decl *D = cast<DeclVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002659 if (!D)
2660 continue;
2661
2662 // For now, perform default visitation for Decls.
2663 if (Visit(MakeCXCursor(D, TU, RegionOfInterest,
2664 cast<DeclVisit>(&LI)->isFirst())))
2665 return true;
2666
2667 continue;
2668 }
2669 case VisitorJob::ExplicitTemplateArgsVisitKind: {
2670 const ASTTemplateArgumentListInfo *ArgList =
2671 cast<ExplicitTemplateArgsVisit>(&LI)->get();
2672 for (const TemplateArgumentLoc *Arg = ArgList->getTemplateArgs(),
2673 *ArgEnd = Arg + ArgList->NumTemplateArgs;
2674 Arg != ArgEnd; ++Arg) {
2675 if (VisitTemplateArgumentLoc(*Arg))
2676 return true;
2677 }
2678 continue;
2679 }
2680 case VisitorJob::TypeLocVisitKind: {
2681 // Perform default visitation for TypeLocs.
2682 if (Visit(cast<TypeLocVisit>(&LI)->get()))
2683 return true;
2684 continue;
2685 }
2686 case VisitorJob::LabelRefVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002687 const LabelDecl *LS = cast<LabelRefVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002688 if (LabelStmt *stmt = LS->getStmt()) {
2689 if (Visit(MakeCursorLabelRef(stmt, cast<LabelRefVisit>(&LI)->getLoc(),
2690 TU))) {
2691 return true;
2692 }
2693 }
2694 continue;
2695 }
2696
2697 case VisitorJob::NestedNameSpecifierLocVisitKind: {
2698 NestedNameSpecifierLocVisit *V = cast<NestedNameSpecifierLocVisit>(&LI);
2699 if (VisitNestedNameSpecifierLoc(V->get()))
2700 return true;
2701 continue;
2702 }
2703
2704 case VisitorJob::DeclarationNameInfoVisitKind: {
2705 if (VisitDeclarationNameInfo(cast<DeclarationNameInfoVisit>(&LI)
2706 ->get()))
2707 return true;
2708 continue;
2709 }
2710 case VisitorJob::MemberRefVisitKind: {
2711 MemberRefVisit *V = cast<MemberRefVisit>(&LI);
2712 if (Visit(MakeCursorMemberRef(V->get(), V->getLoc(), TU)))
2713 return true;
2714 continue;
2715 }
2716 case VisitorJob::StmtVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002717 const Stmt *S = cast<StmtVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002718 if (!S)
2719 continue;
2720
2721 // Update the current cursor.
2722 CXCursor Cursor = MakeCXCursor(S, StmtParent, TU, RegionOfInterest);
2723 if (!IsInRegionOfInterest(Cursor))
2724 continue;
2725 switch (Visitor(Cursor, Parent, ClientData)) {
2726 case CXChildVisit_Break: return true;
2727 case CXChildVisit_Continue: break;
2728 case CXChildVisit_Recurse:
2729 if (PostChildrenVisitor)
Craig Topper69186e72014-06-08 08:38:04 +00002730 WL.push_back(PostChildrenVisit(nullptr, Cursor));
Guy Benyei11169dd2012-12-18 14:30:41 +00002731 EnqueueWorkList(WL, S);
2732 break;
2733 }
2734 continue;
2735 }
2736 case VisitorJob::MemberExprPartsKind: {
2737 // Handle the other pieces in the MemberExpr besides the base.
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002738 const MemberExpr *M = cast<MemberExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002739
2740 // Visit the nested-name-specifier
2741 if (NestedNameSpecifierLoc QualifierLoc = M->getQualifierLoc())
2742 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2743 return true;
2744
2745 // Visit the declaration name.
2746 if (VisitDeclarationNameInfo(M->getMemberNameInfo()))
2747 return true;
2748
2749 // Visit the explicitly-specified template arguments, if any.
2750 if (M->hasExplicitTemplateArgs()) {
2751 for (const TemplateArgumentLoc *Arg = M->getTemplateArgs(),
2752 *ArgEnd = Arg + M->getNumTemplateArgs();
2753 Arg != ArgEnd; ++Arg) {
2754 if (VisitTemplateArgumentLoc(*Arg))
2755 return true;
2756 }
2757 }
2758 continue;
2759 }
2760 case VisitorJob::DeclRefExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002761 const DeclRefExpr *DR = cast<DeclRefExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002762 // Visit nested-name-specifier, if present.
2763 if (NestedNameSpecifierLoc QualifierLoc = DR->getQualifierLoc())
2764 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2765 return true;
2766 // Visit declaration name.
2767 if (VisitDeclarationNameInfo(DR->getNameInfo()))
2768 return true;
2769 continue;
2770 }
2771 case VisitorJob::OverloadExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002772 const OverloadExpr *O = cast<OverloadExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002773 // Visit the nested-name-specifier.
2774 if (NestedNameSpecifierLoc QualifierLoc = O->getQualifierLoc())
2775 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2776 return true;
2777 // Visit the declaration name.
2778 if (VisitDeclarationNameInfo(O->getNameInfo()))
2779 return true;
2780 // Visit the overloaded declaration reference.
2781 if (Visit(MakeCursorOverloadedDeclRef(O, TU)))
2782 return true;
2783 continue;
2784 }
2785 case VisitorJob::SizeOfPackExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002786 const SizeOfPackExpr *E = cast<SizeOfPackExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002787 NamedDecl *Pack = E->getPack();
2788 if (isa<TemplateTypeParmDecl>(Pack)) {
2789 if (Visit(MakeCursorTypeRef(cast<TemplateTypeParmDecl>(Pack),
2790 E->getPackLoc(), TU)))
2791 return true;
2792
2793 continue;
2794 }
2795
2796 if (isa<TemplateTemplateParmDecl>(Pack)) {
2797 if (Visit(MakeCursorTemplateRef(cast<TemplateTemplateParmDecl>(Pack),
2798 E->getPackLoc(), TU)))
2799 return true;
2800
2801 continue;
2802 }
2803
2804 // Non-type template parameter packs and function parameter packs are
2805 // treated like DeclRefExpr cursors.
2806 continue;
2807 }
2808
2809 case VisitorJob::LambdaExprPartsKind: {
2810 // Visit captures.
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002811 const LambdaExpr *E = cast<LambdaExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002812 for (LambdaExpr::capture_iterator C = E->explicit_capture_begin(),
2813 CEnd = E->explicit_capture_end();
2814 C != CEnd; ++C) {
Richard Smithba71c082013-05-16 06:20:58 +00002815 // FIXME: Lambda init-captures.
2816 if (!C->capturesVariable())
Guy Benyei11169dd2012-12-18 14:30:41 +00002817 continue;
Richard Smithba71c082013-05-16 06:20:58 +00002818
Guy Benyei11169dd2012-12-18 14:30:41 +00002819 if (Visit(MakeCursorVariableRef(C->getCapturedVar(),
2820 C->getLocation(),
2821 TU)))
2822 return true;
2823 }
2824
2825 // Visit parameters and return type, if present.
2826 if (E->hasExplicitParameters() || E->hasExplicitResultType()) {
2827 TypeLoc TL = E->getCallOperator()->getTypeSourceInfo()->getTypeLoc();
2828 if (E->hasExplicitParameters() && E->hasExplicitResultType()) {
2829 // Visit the whole type.
2830 if (Visit(TL))
2831 return true;
David Blaikie6adc78e2013-02-18 22:06:02 +00002832 } else if (FunctionProtoTypeLoc Proto =
2833 TL.getAs<FunctionProtoTypeLoc>()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002834 if (E->hasExplicitParameters()) {
2835 // Visit parameters.
Alp Tokerb3fd5cf2014-01-21 00:32:38 +00002836 for (unsigned I = 0, N = Proto.getNumParams(); I != N; ++I)
2837 if (Visit(MakeCXCursor(Proto.getParam(I), TU)))
Guy Benyei11169dd2012-12-18 14:30:41 +00002838 return true;
2839 } else {
2840 // Visit result type.
Alp Toker42a16a62014-01-25 23:51:36 +00002841 if (Visit(Proto.getReturnLoc()))
Guy Benyei11169dd2012-12-18 14:30:41 +00002842 return true;
2843 }
2844 }
2845 }
2846 break;
2847 }
2848
2849 case VisitorJob::PostChildrenVisitKind:
2850 if (PostChildrenVisitor(Parent, ClientData))
2851 return true;
2852 break;
2853 }
2854 }
2855 return false;
2856}
2857
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002858bool CursorVisitor::Visit(const Stmt *S) {
Craig Topper69186e72014-06-08 08:38:04 +00002859 VisitorWorkList *WL = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00002860 if (!WorkListFreeList.empty()) {
2861 WL = WorkListFreeList.back();
2862 WL->clear();
2863 WorkListFreeList.pop_back();
2864 }
2865 else {
2866 WL = new VisitorWorkList();
2867 WorkListCache.push_back(WL);
2868 }
2869 EnqueueWorkList(*WL, S);
2870 bool result = RunVisitorWorkList(*WL);
2871 WorkListFreeList.push_back(WL);
2872 return result;
2873}
2874
2875namespace {
Dmitri Gribenkof8579502013-01-12 19:30:44 +00002876typedef SmallVector<SourceRange, 4> RefNamePieces;
Craig Topper69186e72014-06-08 08:38:04 +00002877RefNamePieces
2878buildPieces(unsigned NameFlags, bool IsMemberRefExpr,
Craig Toppere335f252015-10-04 04:53:55 +00002879 const DeclarationNameInfo &NI, SourceRange QLoc,
Craig Topper69186e72014-06-08 08:38:04 +00002880 const ASTTemplateArgumentListInfo *TemplateArgs = nullptr) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002881 const bool WantQualifier = NameFlags & CXNameRange_WantQualifier;
2882 const bool WantTemplateArgs = NameFlags & CXNameRange_WantTemplateArgs;
2883 const bool WantSinglePiece = NameFlags & CXNameRange_WantSinglePiece;
2884
2885 const DeclarationName::NameKind Kind = NI.getName().getNameKind();
2886
2887 RefNamePieces Pieces;
2888
2889 if (WantQualifier && QLoc.isValid())
2890 Pieces.push_back(QLoc);
2891
2892 if (Kind != DeclarationName::CXXOperatorName || IsMemberRefExpr)
2893 Pieces.push_back(NI.getLoc());
2894
2895 if (WantTemplateArgs && TemplateArgs)
2896 Pieces.push_back(SourceRange(TemplateArgs->LAngleLoc,
2897 TemplateArgs->RAngleLoc));
2898
2899 if (Kind == DeclarationName::CXXOperatorName) {
2900 Pieces.push_back(SourceLocation::getFromRawEncoding(
2901 NI.getInfo().CXXOperatorName.BeginOpNameLoc));
2902 Pieces.push_back(SourceLocation::getFromRawEncoding(
2903 NI.getInfo().CXXOperatorName.EndOpNameLoc));
2904 }
2905
2906 if (WantSinglePiece) {
2907 SourceRange R(Pieces.front().getBegin(), Pieces.back().getEnd());
2908 Pieces.clear();
2909 Pieces.push_back(R);
2910 }
2911
2912 return Pieces;
2913}
Alexander Kornienkoab9db512015-06-22 23:07:51 +00002914}
Guy Benyei11169dd2012-12-18 14:30:41 +00002915
2916//===----------------------------------------------------------------------===//
2917// Misc. API hooks.
2918//===----------------------------------------------------------------------===//
2919
Chad Rosier05c71aa2013-03-27 18:28:23 +00002920static void fatal_error_handler(void *user_data, const std::string& reason,
2921 bool gen_crash_diag) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002922 // Write the result out to stderr avoiding errs() because raw_ostreams can
2923 // call report_fatal_error.
2924 fprintf(stderr, "LIBCLANG FATAL ERROR: %s\n", reason.c_str());
2925 ::abort();
2926}
2927
Chandler Carruth66660742014-06-27 16:37:27 +00002928namespace {
2929struct RegisterFatalErrorHandler {
2930 RegisterFatalErrorHandler() {
2931 llvm::install_fatal_error_handler(fatal_error_handler, nullptr);
2932 }
2933};
2934}
2935
2936static llvm::ManagedStatic<RegisterFatalErrorHandler> RegisterFatalErrorHandlerOnce;
2937
Guy Benyei11169dd2012-12-18 14:30:41 +00002938extern "C" {
2939CXIndex clang_createIndex(int excludeDeclarationsFromPCH,
2940 int displayDiagnostics) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002941 // We use crash recovery to make some of our APIs more reliable, implicitly
2942 // enable it.
Argyrios Kyrtzidis3701f542013-11-27 08:58:09 +00002943 if (!getenv("LIBCLANG_DISABLE_CRASH_RECOVERY"))
2944 llvm::CrashRecoveryContext::Enable();
Guy Benyei11169dd2012-12-18 14:30:41 +00002945
Chandler Carruth66660742014-06-27 16:37:27 +00002946 // Look through the managed static to trigger construction of the managed
2947 // static which registers our fatal error handler. This ensures it is only
2948 // registered once.
2949 (void)*RegisterFatalErrorHandlerOnce;
Guy Benyei11169dd2012-12-18 14:30:41 +00002950
Adrian Prantlbc068582015-07-08 01:00:30 +00002951 // Initialize targets for clang module support.
2952 llvm::InitializeAllTargets();
2953 llvm::InitializeAllTargetMCs();
2954 llvm::InitializeAllAsmPrinters();
2955 llvm::InitializeAllAsmParsers();
2956
Adrian Prantlfb2398d2015-07-17 01:19:54 +00002957 CIndexer *CIdxr = new CIndexer();
2958
Guy Benyei11169dd2012-12-18 14:30:41 +00002959 if (excludeDeclarationsFromPCH)
2960 CIdxr->setOnlyLocalDecls();
2961 if (displayDiagnostics)
2962 CIdxr->setDisplayDiagnostics();
2963
2964 if (getenv("LIBCLANG_BGPRIO_INDEX"))
2965 CIdxr->setCXGlobalOptFlags(CIdxr->getCXGlobalOptFlags() |
2966 CXGlobalOpt_ThreadBackgroundPriorityForIndexing);
2967 if (getenv("LIBCLANG_BGPRIO_EDIT"))
2968 CIdxr->setCXGlobalOptFlags(CIdxr->getCXGlobalOptFlags() |
2969 CXGlobalOpt_ThreadBackgroundPriorityForEditing);
2970
2971 return CIdxr;
2972}
2973
2974void clang_disposeIndex(CXIndex CIdx) {
2975 if (CIdx)
2976 delete static_cast<CIndexer *>(CIdx);
2977}
2978
2979void clang_CXIndex_setGlobalOptions(CXIndex CIdx, unsigned options) {
2980 if (CIdx)
2981 static_cast<CIndexer *>(CIdx)->setCXGlobalOptFlags(options);
2982}
2983
2984unsigned clang_CXIndex_getGlobalOptions(CXIndex CIdx) {
2985 if (CIdx)
2986 return static_cast<CIndexer *>(CIdx)->getCXGlobalOptFlags();
2987 return 0;
2988}
2989
2990void clang_toggleCrashRecovery(unsigned isEnabled) {
2991 if (isEnabled)
2992 llvm::CrashRecoveryContext::Enable();
2993 else
2994 llvm::CrashRecoveryContext::Disable();
2995}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002996
Guy Benyei11169dd2012-12-18 14:30:41 +00002997CXTranslationUnit clang_createTranslationUnit(CXIndex CIdx,
2998 const char *ast_filename) {
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00002999 CXTranslationUnit TU;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003000 enum CXErrorCode Result =
3001 clang_createTranslationUnit2(CIdx, ast_filename, &TU);
Reid Klecknerfd48fc62014-02-12 23:56:20 +00003002 (void)Result;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003003 assert((TU && Result == CXError_Success) ||
3004 (!TU && Result != CXError_Success));
3005 return TU;
3006}
3007
3008enum CXErrorCode clang_createTranslationUnit2(CXIndex CIdx,
3009 const char *ast_filename,
3010 CXTranslationUnit *out_TU) {
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00003011 if (out_TU)
Craig Topper69186e72014-06-08 08:38:04 +00003012 *out_TU = nullptr;
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00003013
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003014 if (!CIdx || !ast_filename || !out_TU)
3015 return CXError_InvalidArguments;
Guy Benyei11169dd2012-12-18 14:30:41 +00003016
Argyrios Kyrtzidis27021012013-05-24 22:24:07 +00003017 LOG_FUNC_SECTION {
3018 *Log << ast_filename;
3019 }
3020
Guy Benyei11169dd2012-12-18 14:30:41 +00003021 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
3022 FileSystemOptions FileSystemOpts;
3023
Justin Bognerd512c1e2014-10-15 00:33:06 +00003024 IntrusiveRefCntPtr<DiagnosticsEngine> Diags =
3025 CompilerInstance::createDiagnostics(new DiagnosticOptions());
David Blaikie6f7382d2014-08-10 19:08:04 +00003026 std::unique_ptr<ASTUnit> AU = ASTUnit::LoadFromASTFile(
Adrian Prantlfb2398d2015-07-17 01:19:54 +00003027 ast_filename, CXXIdx->getPCHContainerOperations()->getRawReader(), Diags,
Adrian Prantl6b21ab22015-08-27 19:46:20 +00003028 FileSystemOpts, /*UseDebugInfo=*/false,
3029 CXXIdx->getOnlyLocalDecls(), None,
David Blaikie6f7382d2014-08-10 19:08:04 +00003030 /*CaptureDiagnostics=*/true,
3031 /*AllowPCHWithCompilerErrors=*/true,
3032 /*UserFilesAreVolatile=*/true);
3033 *out_TU = MakeCXTranslationUnit(CXXIdx, AU.release());
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003034 return *out_TU ? CXError_Success : CXError_Failure;
Guy Benyei11169dd2012-12-18 14:30:41 +00003035}
3036
3037unsigned clang_defaultEditingTranslationUnitOptions() {
3038 return CXTranslationUnit_PrecompiledPreamble |
3039 CXTranslationUnit_CacheCompletionResults;
3040}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003041
Guy Benyei11169dd2012-12-18 14:30:41 +00003042CXTranslationUnit
3043clang_createTranslationUnitFromSourceFile(CXIndex CIdx,
3044 const char *source_filename,
3045 int num_command_line_args,
3046 const char * const *command_line_args,
3047 unsigned num_unsaved_files,
3048 struct CXUnsavedFile *unsaved_files) {
3049 unsigned Options = CXTranslationUnit_DetailedPreprocessingRecord;
3050 return clang_parseTranslationUnit(CIdx, source_filename,
3051 command_line_args, num_command_line_args,
3052 unsaved_files, num_unsaved_files,
3053 Options);
3054}
3055
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003056static CXErrorCode
3057clang_parseTranslationUnit_Impl(CXIndex CIdx, const char *source_filename,
3058 const char *const *command_line_args,
3059 int num_command_line_args,
3060 ArrayRef<CXUnsavedFile> unsaved_files,
3061 unsigned options, CXTranslationUnit *out_TU) {
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00003062 // Set up the initial return values.
3063 if (out_TU)
Craig Topper69186e72014-06-08 08:38:04 +00003064 *out_TU = nullptr;
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00003065
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003066 // Check arguments.
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003067 if (!CIdx || !out_TU)
3068 return CXError_InvalidArguments;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003069
Guy Benyei11169dd2012-12-18 14:30:41 +00003070 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
3071
3072 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
3073 setThreadBackgroundPriority();
3074
3075 bool PrecompilePreamble = options & CXTranslationUnit_PrecompiledPreamble;
3076 // FIXME: Add a flag for modules.
3077 TranslationUnitKind TUKind
3078 = (options & CXTranslationUnit_Incomplete)? TU_Prefix : TU_Complete;
Alp Toker8c8a8752013-12-03 06:53:35 +00003079 bool CacheCodeCompletionResults
Guy Benyei11169dd2012-12-18 14:30:41 +00003080 = options & CXTranslationUnit_CacheCompletionResults;
3081 bool IncludeBriefCommentsInCodeCompletion
3082 = options & CXTranslationUnit_IncludeBriefCommentsInCodeCompletion;
3083 bool SkipFunctionBodies = options & CXTranslationUnit_SkipFunctionBodies;
3084 bool ForSerialization = options & CXTranslationUnit_ForSerialization;
3085
3086 // Configure the diagnostics.
3087 IntrusiveRefCntPtr<DiagnosticsEngine>
Sean Silvaf1b49e22013-01-20 01:58:28 +00003088 Diags(CompilerInstance::createDiagnostics(new DiagnosticOptions));
Guy Benyei11169dd2012-12-18 14:30:41 +00003089
3090 // Recover resources if we crash before exiting this function.
3091 llvm::CrashRecoveryContextCleanupRegistrar<DiagnosticsEngine,
3092 llvm::CrashRecoveryContextReleaseRefCleanup<DiagnosticsEngine> >
Alp Tokerf994cef2014-07-05 03:08:06 +00003093 DiagCleanup(Diags.get());
Guy Benyei11169dd2012-12-18 14:30:41 +00003094
Ahmed Charlesb8984322014-03-07 20:03:18 +00003095 std::unique_ptr<std::vector<ASTUnit::RemappedFile>> RemappedFiles(
3096 new std::vector<ASTUnit::RemappedFile>());
Guy Benyei11169dd2012-12-18 14:30:41 +00003097
3098 // Recover resources if we crash before exiting this function.
3099 llvm::CrashRecoveryContextCleanupRegistrar<
3100 std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
3101
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003102 for (auto &UF : unsaved_files) {
Rafael Espindolad87f8d72014-08-27 20:03:29 +00003103 std::unique_ptr<llvm::MemoryBuffer> MB =
Alp Toker9d85b182014-07-07 01:23:14 +00003104 llvm::MemoryBuffer::getMemBufferCopy(getContents(UF), UF.Filename);
Rafael Espindolad87f8d72014-08-27 20:03:29 +00003105 RemappedFiles->push_back(std::make_pair(UF.Filename, MB.release()));
Guy Benyei11169dd2012-12-18 14:30:41 +00003106 }
3107
Ahmed Charlesb8984322014-03-07 20:03:18 +00003108 std::unique_ptr<std::vector<const char *>> Args(
3109 new std::vector<const char *>());
Guy Benyei11169dd2012-12-18 14:30:41 +00003110
3111 // Recover resources if we crash before exiting this method.
3112 llvm::CrashRecoveryContextCleanupRegistrar<std::vector<const char*> >
3113 ArgsCleanup(Args.get());
3114
3115 // Since the Clang C library is primarily used by batch tools dealing with
3116 // (often very broken) source code, where spell-checking can have a
3117 // significant negative impact on performance (particularly when
3118 // precompiled headers are involved), we disable it by default.
3119 // Only do this if we haven't found a spell-checking-related argument.
3120 bool FoundSpellCheckingArgument = false;
3121 for (int I = 0; I != num_command_line_args; ++I) {
3122 if (strcmp(command_line_args[I], "-fno-spell-checking") == 0 ||
3123 strcmp(command_line_args[I], "-fspell-checking") == 0) {
3124 FoundSpellCheckingArgument = true;
3125 break;
3126 }
3127 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003128 Args->insert(Args->end(), command_line_args,
3129 command_line_args + num_command_line_args);
3130
Benjamin Kramerc02670e2015-11-18 16:14:27 +00003131 if (!FoundSpellCheckingArgument)
3132 Args->insert(Args->begin() + 1, "-fno-spell-checking");
3133
Guy Benyei11169dd2012-12-18 14:30:41 +00003134 // The 'source_filename' argument is optional. If the caller does not
3135 // specify it then it is assumed that the source file is specified
3136 // in the actual argument list.
3137 // Put the source file after command_line_args otherwise if '-x' flag is
3138 // present it will be unused.
3139 if (source_filename)
3140 Args->push_back(source_filename);
3141
3142 // Do we need the detailed preprocessing record?
3143 if (options & CXTranslationUnit_DetailedPreprocessingRecord) {
3144 Args->push_back("-Xclang");
3145 Args->push_back("-detailed-preprocessing-record");
3146 }
3147
3148 unsigned NumErrors = Diags->getClient()->getNumErrors();
Ahmed Charlesb8984322014-03-07 20:03:18 +00003149 std::unique_ptr<ASTUnit> ErrUnit;
3150 std::unique_ptr<ASTUnit> Unit(ASTUnit::LoadFromCommandLine(
Adrian Prantlbb165fb2015-06-20 18:53:08 +00003151 Args->data(), Args->data() + Args->size(),
3152 CXXIdx->getPCHContainerOperations(), Diags,
Ahmed Charlesb8984322014-03-07 20:03:18 +00003153 CXXIdx->getClangResourcesPath(), CXXIdx->getOnlyLocalDecls(),
3154 /*CaptureDiagnostics=*/true, *RemappedFiles.get(),
3155 /*RemappedFilesKeepOriginalName=*/true, PrecompilePreamble, TUKind,
3156 CacheCodeCompletionResults, IncludeBriefCommentsInCodeCompletion,
3157 /*AllowPCHWithCompilerErrors=*/true, SkipFunctionBodies,
Argyrios Kyrtzidisa3e2ff12015-11-20 03:36:21 +00003158 /*UserFilesAreVolatile=*/true, ForSerialization,
3159 CXXIdx->getPCHContainerOperations()->getRawReader().getFormat(),
3160 &ErrUnit));
Guy Benyei11169dd2012-12-18 14:30:41 +00003161
Artem Belevich0ff05cd2015-07-13 23:27:56 +00003162 // Early failures in LoadFromCommandLine may return with ErrUnit unset.
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003163 if (!Unit && !ErrUnit)
3164 return CXError_ASTReadError;
Artem Belevich0ff05cd2015-07-13 23:27:56 +00003165
Guy Benyei11169dd2012-12-18 14:30:41 +00003166 if (NumErrors != Diags->getClient()->getNumErrors()) {
3167 // Make sure to check that 'Unit' is non-NULL.
3168 if (CXXIdx->getDisplayDiagnostics())
3169 printDiagsToStderr(Unit ? Unit.get() : ErrUnit.get());
3170 }
3171
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003172 if (isASTReadError(Unit ? Unit.get() : ErrUnit.get()))
3173 return CXError_ASTReadError;
3174
3175 *out_TU = MakeCXTranslationUnit(CXXIdx, Unit.release());
3176 return *out_TU ? CXError_Success : CXError_Failure;
Guy Benyei11169dd2012-12-18 14:30:41 +00003177}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003178
3179CXTranslationUnit
3180clang_parseTranslationUnit(CXIndex CIdx,
3181 const char *source_filename,
3182 const char *const *command_line_args,
3183 int num_command_line_args,
3184 struct CXUnsavedFile *unsaved_files,
3185 unsigned num_unsaved_files,
3186 unsigned options) {
3187 CXTranslationUnit TU;
3188 enum CXErrorCode Result = clang_parseTranslationUnit2(
3189 CIdx, source_filename, command_line_args, num_command_line_args,
3190 unsaved_files, num_unsaved_files, options, &TU);
Reid Kleckner6eaf05a2014-02-13 01:19:59 +00003191 (void)Result;
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00003192 assert((TU && Result == CXError_Success) ||
3193 (!TU && Result != CXError_Success));
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003194 return TU;
3195}
3196
3197enum CXErrorCode clang_parseTranslationUnit2(
Benjamin Kramerc02670e2015-11-18 16:14:27 +00003198 CXIndex CIdx, const char *source_filename,
3199 const char *const *command_line_args, int num_command_line_args,
3200 struct CXUnsavedFile *unsaved_files, unsigned num_unsaved_files,
3201 unsigned options, CXTranslationUnit *out_TU) {
3202 SmallVector<const char *, 4> Args;
3203 Args.push_back("clang");
3204 Args.append(command_line_args, command_line_args + num_command_line_args);
3205 return clang_parseTranslationUnit2FullArgv(
3206 CIdx, source_filename, Args.data(), Args.size(), unsaved_files,
3207 num_unsaved_files, options, out_TU);
3208}
3209
3210enum CXErrorCode clang_parseTranslationUnit2FullArgv(
3211 CXIndex CIdx, const char *source_filename,
3212 const char *const *command_line_args, int num_command_line_args,
3213 struct CXUnsavedFile *unsaved_files, unsigned num_unsaved_files,
3214 unsigned options, CXTranslationUnit *out_TU) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00003215 LOG_FUNC_SECTION {
3216 *Log << source_filename << ": ";
3217 for (int i = 0; i != num_command_line_args; ++i)
3218 *Log << command_line_args[i] << " ";
3219 }
3220
Alp Toker9d85b182014-07-07 01:23:14 +00003221 if (num_unsaved_files && !unsaved_files)
3222 return CXError_InvalidArguments;
3223
Alp Toker5c532982014-07-07 22:42:03 +00003224 CXErrorCode result = CXError_Failure;
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003225 auto ParseTranslationUnitImpl = [=, &result] {
3226 result = clang_parseTranslationUnit_Impl(
3227 CIdx, source_filename, command_line_args, num_command_line_args,
3228 llvm::makeArrayRef(unsaved_files, num_unsaved_files), options, out_TU);
3229 };
Guy Benyei11169dd2012-12-18 14:30:41 +00003230 llvm::CrashRecoveryContext CRC;
3231
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003232 if (!RunSafely(CRC, ParseTranslationUnitImpl)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003233 fprintf(stderr, "libclang: crash detected during parsing: {\n");
3234 fprintf(stderr, " 'source_filename' : '%s'\n", source_filename);
3235 fprintf(stderr, " 'command_line_args' : [");
3236 for (int i = 0; i != num_command_line_args; ++i) {
3237 if (i)
3238 fprintf(stderr, ", ");
3239 fprintf(stderr, "'%s'", command_line_args[i]);
3240 }
3241 fprintf(stderr, "],\n");
3242 fprintf(stderr, " 'unsaved_files' : [");
3243 for (unsigned i = 0; i != num_unsaved_files; ++i) {
3244 if (i)
3245 fprintf(stderr, ", ");
3246 fprintf(stderr, "('%s', '...', %ld)", unsaved_files[i].Filename,
3247 unsaved_files[i].Length);
3248 }
3249 fprintf(stderr, "],\n");
3250 fprintf(stderr, " 'options' : %d,\n", options);
3251 fprintf(stderr, "}\n");
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003252
3253 return CXError_Crashed;
Guy Benyei11169dd2012-12-18 14:30:41 +00003254 } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003255 if (CXTranslationUnit *TU = out_TU)
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003256 PrintLibclangResourceUsage(*TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003257 }
Alp Toker5c532982014-07-07 22:42:03 +00003258
3259 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003260}
3261
3262unsigned clang_defaultSaveOptions(CXTranslationUnit TU) {
3263 return CXSaveTranslationUnit_None;
3264}
3265
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003266static CXSaveError clang_saveTranslationUnit_Impl(CXTranslationUnit TU,
3267 const char *FileName,
3268 unsigned options) {
3269 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00003270 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
3271 setThreadBackgroundPriority();
3272
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003273 bool hadError = cxtu::getASTUnit(TU)->Save(FileName);
3274 return hadError ? CXSaveError_Unknown : CXSaveError_None;
Guy Benyei11169dd2012-12-18 14:30:41 +00003275}
3276
3277int clang_saveTranslationUnit(CXTranslationUnit TU, const char *FileName,
3278 unsigned options) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00003279 LOG_FUNC_SECTION {
3280 *Log << TU << ' ' << FileName;
3281 }
3282
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003283 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003284 LOG_BAD_TU(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003285 return CXSaveError_InvalidTU;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003286 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003287
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003288 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003289 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
3290 if (!CXXUnit->hasSema())
3291 return CXSaveError_InvalidTU;
3292
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003293 CXSaveError result;
3294 auto SaveTranslationUnitImpl = [=, &result]() {
3295 result = clang_saveTranslationUnit_Impl(TU, FileName, options);
3296 };
Guy Benyei11169dd2012-12-18 14:30:41 +00003297
3298 if (!CXXUnit->getDiagnostics().hasUnrecoverableErrorOccurred() ||
3299 getenv("LIBCLANG_NOTHREADS")) {
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003300 SaveTranslationUnitImpl();
Guy Benyei11169dd2012-12-18 14:30:41 +00003301
3302 if (getenv("LIBCLANG_RESOURCE_USAGE"))
3303 PrintLibclangResourceUsage(TU);
3304
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003305 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003306 }
3307
3308 // We have an AST that has invalid nodes due to compiler errors.
3309 // Use a crash recovery thread for protection.
3310
3311 llvm::CrashRecoveryContext CRC;
3312
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003313 if (!RunSafely(CRC, SaveTranslationUnitImpl)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003314 fprintf(stderr, "libclang: crash detected during AST saving: {\n");
3315 fprintf(stderr, " 'filename' : '%s'\n", FileName);
3316 fprintf(stderr, " 'options' : %d,\n", options);
3317 fprintf(stderr, "}\n");
3318
3319 return CXSaveError_Unknown;
3320
3321 } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
3322 PrintLibclangResourceUsage(TU);
3323 }
3324
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003325 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003326}
3327
3328void clang_disposeTranslationUnit(CXTranslationUnit CTUnit) {
3329 if (CTUnit) {
3330 // If the translation unit has been marked as unsafe to free, just discard
3331 // it.
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003332 ASTUnit *Unit = cxtu::getASTUnit(CTUnit);
3333 if (Unit && Unit->isUnsafeToFree())
Guy Benyei11169dd2012-12-18 14:30:41 +00003334 return;
3335
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003336 delete cxtu::getASTUnit(CTUnit);
Dmitri Gribenkob95b3f12013-01-26 22:44:19 +00003337 delete CTUnit->StringPool;
Guy Benyei11169dd2012-12-18 14:30:41 +00003338 delete static_cast<CXDiagnosticSetImpl *>(CTUnit->Diagnostics);
3339 disposeOverridenCXCursorsPool(CTUnit->OverridenCursorsPool);
Dmitri Gribenko9e605112013-11-13 22:16:51 +00003340 delete CTUnit->CommentToXML;
Guy Benyei11169dd2012-12-18 14:30:41 +00003341 delete CTUnit;
3342 }
3343}
3344
3345unsigned clang_defaultReparseOptions(CXTranslationUnit TU) {
3346 return CXReparse_None;
3347}
3348
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003349static CXErrorCode
3350clang_reparseTranslationUnit_Impl(CXTranslationUnit TU,
3351 ArrayRef<CXUnsavedFile> unsaved_files,
3352 unsigned options) {
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003353 // Check arguments.
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003354 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003355 LOG_BAD_TU(TU);
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003356 return CXError_InvalidArguments;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003357 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003358
3359 // Reset the associated diagnostics.
3360 delete static_cast<CXDiagnosticSetImpl*>(TU->Diagnostics);
Craig Topper69186e72014-06-08 08:38:04 +00003361 TU->Diagnostics = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00003362
Dmitri Gribenko183436e2013-01-26 21:49:50 +00003363 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00003364 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
3365 setThreadBackgroundPriority();
3366
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003367 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003368 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
Ahmed Charlesb8984322014-03-07 20:03:18 +00003369
3370 std::unique_ptr<std::vector<ASTUnit::RemappedFile>> RemappedFiles(
3371 new std::vector<ASTUnit::RemappedFile>());
3372
Guy Benyei11169dd2012-12-18 14:30:41 +00003373 // Recover resources if we crash before exiting this function.
3374 llvm::CrashRecoveryContextCleanupRegistrar<
3375 std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
Alp Toker9d85b182014-07-07 01:23:14 +00003376
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003377 for (auto &UF : unsaved_files) {
Rafael Espindolad87f8d72014-08-27 20:03:29 +00003378 std::unique_ptr<llvm::MemoryBuffer> MB =
Alp Toker9d85b182014-07-07 01:23:14 +00003379 llvm::MemoryBuffer::getMemBufferCopy(getContents(UF), UF.Filename);
Rafael Espindolad87f8d72014-08-27 20:03:29 +00003380 RemappedFiles->push_back(std::make_pair(UF.Filename, MB.release()));
Guy Benyei11169dd2012-12-18 14:30:41 +00003381 }
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003382
Adrian Prantlbb165fb2015-06-20 18:53:08 +00003383 if (!CXXUnit->Reparse(CXXIdx->getPCHContainerOperations(),
3384 *RemappedFiles.get()))
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003385 return CXError_Success;
3386 if (isASTReadError(CXXUnit))
3387 return CXError_ASTReadError;
3388 return CXError_Failure;
Guy Benyei11169dd2012-12-18 14:30:41 +00003389}
3390
3391int clang_reparseTranslationUnit(CXTranslationUnit TU,
3392 unsigned num_unsaved_files,
3393 struct CXUnsavedFile *unsaved_files,
3394 unsigned options) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00003395 LOG_FUNC_SECTION {
3396 *Log << TU;
3397 }
3398
Alp Toker9d85b182014-07-07 01:23:14 +00003399 if (num_unsaved_files && !unsaved_files)
3400 return CXError_InvalidArguments;
3401
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003402 CXErrorCode result;
3403 auto ReparseTranslationUnitImpl = [=, &result]() {
3404 result = clang_reparseTranslationUnit_Impl(
3405 TU, llvm::makeArrayRef(unsaved_files, num_unsaved_files), options);
3406 };
Guy Benyei11169dd2012-12-18 14:30:41 +00003407
3408 if (getenv("LIBCLANG_NOTHREADS")) {
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003409 ReparseTranslationUnitImpl();
Alp Toker5c532982014-07-07 22:42:03 +00003410 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003411 }
3412
3413 llvm::CrashRecoveryContext CRC;
3414
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003415 if (!RunSafely(CRC, ReparseTranslationUnitImpl)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003416 fprintf(stderr, "libclang: crash detected during reparsing\n");
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003417 cxtu::getASTUnit(TU)->setUnsafeToFree(true);
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003418 return CXError_Crashed;
Guy Benyei11169dd2012-12-18 14:30:41 +00003419 } else if (getenv("LIBCLANG_RESOURCE_USAGE"))
3420 PrintLibclangResourceUsage(TU);
3421
Alp Toker5c532982014-07-07 22:42:03 +00003422 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003423}
3424
3425
3426CXString clang_getTranslationUnitSpelling(CXTranslationUnit CTUnit) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003427 if (isNotUsableTU(CTUnit)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003428 LOG_BAD_TU(CTUnit);
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003429 return cxstring::createEmpty();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003430 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003431
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003432 ASTUnit *CXXUnit = cxtu::getASTUnit(CTUnit);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003433 return cxstring::createDup(CXXUnit->getOriginalSourceFileName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003434}
3435
3436CXCursor clang_getTranslationUnitCursor(CXTranslationUnit TU) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003437 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003438 LOG_BAD_TU(TU);
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00003439 return clang_getNullCursor();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003440 }
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00003441
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003442 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003443 return MakeCXCursor(CXXUnit->getASTContext().getTranslationUnitDecl(), TU);
3444}
3445
3446} // end: extern "C"
3447
3448//===----------------------------------------------------------------------===//
3449// CXFile Operations.
3450//===----------------------------------------------------------------------===//
3451
3452extern "C" {
3453CXString clang_getFileName(CXFile SFile) {
3454 if (!SFile)
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00003455 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00003456
3457 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003458 return cxstring::createRef(FEnt->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003459}
3460
3461time_t clang_getFileTime(CXFile SFile) {
3462 if (!SFile)
3463 return 0;
3464
3465 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
3466 return FEnt->getModificationTime();
3467}
3468
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003469CXFile clang_getFile(CXTranslationUnit TU, const char *file_name) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003470 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003471 LOG_BAD_TU(TU);
Craig Topper69186e72014-06-08 08:38:04 +00003472 return nullptr;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003473 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003474
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003475 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003476
3477 FileManager &FMgr = CXXUnit->getFileManager();
3478 return const_cast<FileEntry *>(FMgr.getFile(file_name));
3479}
3480
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003481unsigned clang_isFileMultipleIncludeGuarded(CXTranslationUnit TU,
3482 CXFile file) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003483 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003484 LOG_BAD_TU(TU);
3485 return 0;
3486 }
3487
3488 if (!file)
Guy Benyei11169dd2012-12-18 14:30:41 +00003489 return 0;
3490
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003491 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003492 FileEntry *FEnt = static_cast<FileEntry *>(file);
3493 return CXXUnit->getPreprocessor().getHeaderSearchInfo()
3494 .isFileMultipleIncludeGuarded(FEnt);
3495}
3496
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003497int clang_getFileUniqueID(CXFile file, CXFileUniqueID *outID) {
3498 if (!file || !outID)
3499 return 1;
3500
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003501 FileEntry *FEnt = static_cast<FileEntry *>(file);
Rafael Espindolaf8f91b82013-08-01 21:42:11 +00003502 const llvm::sys::fs::UniqueID &ID = FEnt->getUniqueID();
3503 outID->data[0] = ID.getDevice();
3504 outID->data[1] = ID.getFile();
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003505 outID->data[2] = FEnt->getModificationTime();
3506 return 0;
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003507}
3508
Argyrios Kyrtzidisac3997e2014-08-16 00:26:19 +00003509int clang_File_isEqual(CXFile file1, CXFile file2) {
3510 if (file1 == file2)
3511 return true;
3512
3513 if (!file1 || !file2)
3514 return false;
3515
3516 FileEntry *FEnt1 = static_cast<FileEntry *>(file1);
3517 FileEntry *FEnt2 = static_cast<FileEntry *>(file2);
3518 return FEnt1->getUniqueID() == FEnt2->getUniqueID();
3519}
3520
Guy Benyei11169dd2012-12-18 14:30:41 +00003521} // end: extern "C"
3522
3523//===----------------------------------------------------------------------===//
3524// CXCursor Operations.
3525//===----------------------------------------------------------------------===//
3526
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003527static const Decl *getDeclFromExpr(const Stmt *E) {
3528 if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003529 return getDeclFromExpr(CE->getSubExpr());
3530
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003531 if (const DeclRefExpr *RefExpr = dyn_cast<DeclRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003532 return RefExpr->getDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003533 if (const MemberExpr *ME = dyn_cast<MemberExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003534 return ME->getMemberDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003535 if (const ObjCIvarRefExpr *RE = dyn_cast<ObjCIvarRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003536 return RE->getDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003537 if (const ObjCPropertyRefExpr *PRE = dyn_cast<ObjCPropertyRefExpr>(E)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003538 if (PRE->isExplicitProperty())
3539 return PRE->getExplicitProperty();
3540 // It could be messaging both getter and setter as in:
3541 // ++myobj.myprop;
3542 // in which case prefer to associate the setter since it is less obvious
3543 // from inspecting the source that the setter is going to get called.
3544 if (PRE->isMessagingSetter())
3545 return PRE->getImplicitPropertySetter();
3546 return PRE->getImplicitPropertyGetter();
3547 }
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003548 if (const PseudoObjectExpr *POE = dyn_cast<PseudoObjectExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003549 return getDeclFromExpr(POE->getSyntacticForm());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003550 if (const OpaqueValueExpr *OVE = dyn_cast<OpaqueValueExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003551 if (Expr *Src = OVE->getSourceExpr())
3552 return getDeclFromExpr(Src);
3553
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003554 if (const CallExpr *CE = dyn_cast<CallExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003555 return getDeclFromExpr(CE->getCallee());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003556 if (const CXXConstructExpr *CE = dyn_cast<CXXConstructExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003557 if (!CE->isElidable())
3558 return CE->getConstructor();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003559 if (const ObjCMessageExpr *OME = dyn_cast<ObjCMessageExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003560 return OME->getMethodDecl();
3561
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003562 if (const ObjCProtocolExpr *PE = dyn_cast<ObjCProtocolExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003563 return PE->getProtocol();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003564 if (const SubstNonTypeTemplateParmPackExpr *NTTP
Guy Benyei11169dd2012-12-18 14:30:41 +00003565 = dyn_cast<SubstNonTypeTemplateParmPackExpr>(E))
3566 return NTTP->getParameterPack();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003567 if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003568 if (isa<NonTypeTemplateParmDecl>(SizeOfPack->getPack()) ||
3569 isa<ParmVarDecl>(SizeOfPack->getPack()))
3570 return SizeOfPack->getPack();
Craig Topper69186e72014-06-08 08:38:04 +00003571
3572 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00003573}
3574
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003575static SourceLocation getLocationFromExpr(const Expr *E) {
3576 if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003577 return getLocationFromExpr(CE->getSubExpr());
3578
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003579 if (const ObjCMessageExpr *Msg = dyn_cast<ObjCMessageExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003580 return /*FIXME:*/Msg->getLeftLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003581 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003582 return DRE->getLocation();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003583 if (const MemberExpr *Member = dyn_cast<MemberExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003584 return Member->getMemberLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003585 if (const ObjCIvarRefExpr *Ivar = dyn_cast<ObjCIvarRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003586 return Ivar->getLocation();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003587 if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003588 return SizeOfPack->getPackLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003589 if (const ObjCPropertyRefExpr *PropRef = dyn_cast<ObjCPropertyRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003590 return PropRef->getLocation();
3591
3592 return E->getLocStart();
3593}
3594
Aaron Ballmana85d3f82015-11-12 15:25:06 +00003595static std::string getMangledStructor(std::unique_ptr<MangleContext> &M,
3596 std::unique_ptr<llvm::DataLayout> &DL,
3597 const NamedDecl *ND,
3598 unsigned StructorType) {
3599 std::string FrontendBuf;
3600 llvm::raw_string_ostream FOS(FrontendBuf);
3601
3602 if (const auto *CD = dyn_cast_or_null<CXXConstructorDecl>(ND))
3603 M->mangleCXXCtor(CD, static_cast<CXXCtorType>(StructorType), FOS);
3604 else if (const auto *DD = dyn_cast_or_null<CXXDestructorDecl>(ND))
3605 M->mangleCXXDtor(DD, static_cast<CXXDtorType>(StructorType), FOS);
3606
3607 std::string BackendBuf;
3608 llvm::raw_string_ostream BOS(BackendBuf);
3609
3610 llvm::Mangler::getNameWithPrefix(BOS, llvm::Twine(FOS.str()), *DL);
3611
3612 return BOS.str();
3613}
3614
Guy Benyei11169dd2012-12-18 14:30:41 +00003615extern "C" {
3616
3617unsigned clang_visitChildren(CXCursor parent,
3618 CXCursorVisitor visitor,
3619 CXClientData client_data) {
3620 CursorVisitor CursorVis(getCursorTU(parent), visitor, client_data,
3621 /*VisitPreprocessorLast=*/false);
3622 return CursorVis.VisitChildren(parent);
3623}
3624
3625#ifndef __has_feature
3626#define __has_feature(x) 0
3627#endif
3628#if __has_feature(blocks)
3629typedef enum CXChildVisitResult
3630 (^CXCursorVisitorBlock)(CXCursor cursor, CXCursor parent);
3631
3632static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
3633 CXClientData client_data) {
3634 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
3635 return block(cursor, parent);
3636}
3637#else
3638// If we are compiled with a compiler that doesn't have native blocks support,
3639// define and call the block manually, so the
3640typedef struct _CXChildVisitResult
3641{
3642 void *isa;
3643 int flags;
3644 int reserved;
3645 enum CXChildVisitResult(*invoke)(struct _CXChildVisitResult*, CXCursor,
3646 CXCursor);
3647} *CXCursorVisitorBlock;
3648
3649static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
3650 CXClientData client_data) {
3651 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
3652 return block->invoke(block, cursor, parent);
3653}
3654#endif
3655
3656
3657unsigned clang_visitChildrenWithBlock(CXCursor parent,
3658 CXCursorVisitorBlock block) {
3659 return clang_visitChildren(parent, visitWithBlock, block);
3660}
3661
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003662static CXString getDeclSpelling(const Decl *D) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003663 if (!D)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003664 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003665
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003666 const NamedDecl *ND = dyn_cast<NamedDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00003667 if (!ND) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003668 if (const ObjCPropertyImplDecl *PropImpl =
3669 dyn_cast<ObjCPropertyImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00003670 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003671 return cxstring::createDup(Property->getIdentifier()->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003672
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003673 if (const ImportDecl *ImportD = dyn_cast<ImportDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00003674 if (Module *Mod = ImportD->getImportedModule())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003675 return cxstring::createDup(Mod->getFullModuleName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003676
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003677 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003678 }
3679
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003680 if (const ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(ND))
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003681 return cxstring::createDup(OMD->getSelector().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003682
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003683 if (const ObjCCategoryImplDecl *CIMP = dyn_cast<ObjCCategoryImplDecl>(ND))
Guy Benyei11169dd2012-12-18 14:30:41 +00003684 // No, this isn't the same as the code below. getIdentifier() is non-virtual
3685 // and returns different names. NamedDecl returns the class name and
3686 // ObjCCategoryImplDecl returns the category name.
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003687 return cxstring::createRef(CIMP->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003688
3689 if (isa<UsingDirectiveDecl>(D))
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003690 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003691
3692 SmallString<1024> S;
3693 llvm::raw_svector_ostream os(S);
3694 ND->printName(os);
3695
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003696 return cxstring::createDup(os.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003697}
3698
3699CXString clang_getCursorSpelling(CXCursor C) {
3700 if (clang_isTranslationUnit(C.kind))
Dmitri Gribenko2c173b42013-01-11 19:28:44 +00003701 return clang_getTranslationUnitSpelling(getCursorTU(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00003702
3703 if (clang_isReference(C.kind)) {
3704 switch (C.kind) {
3705 case CXCursor_ObjCSuperClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003706 const ObjCInterfaceDecl *Super = getCursorObjCSuperClassRef(C).first;
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003707 return cxstring::createRef(Super->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003708 }
3709 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003710 const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003711 return cxstring::createRef(Class->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003712 }
3713 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003714 const ObjCProtocolDecl *OID = getCursorObjCProtocolRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003715 assert(OID && "getCursorSpelling(): Missing protocol decl");
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003716 return cxstring::createRef(OID->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003717 }
3718 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003719 const CXXBaseSpecifier *B = getCursorCXXBaseSpecifier(C);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003720 return cxstring::createDup(B->getType().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003721 }
3722 case CXCursor_TypeRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003723 const TypeDecl *Type = getCursorTypeRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003724 assert(Type && "Missing type decl");
3725
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003726 return cxstring::createDup(getCursorContext(C).getTypeDeclType(Type).
Guy Benyei11169dd2012-12-18 14:30:41 +00003727 getAsString());
3728 }
3729 case CXCursor_TemplateRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003730 const TemplateDecl *Template = getCursorTemplateRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003731 assert(Template && "Missing template decl");
3732
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003733 return cxstring::createDup(Template->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003734 }
3735
3736 case CXCursor_NamespaceRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003737 const NamedDecl *NS = getCursorNamespaceRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003738 assert(NS && "Missing namespace decl");
3739
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003740 return cxstring::createDup(NS->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003741 }
3742
3743 case CXCursor_MemberRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003744 const FieldDecl *Field = getCursorMemberRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003745 assert(Field && "Missing member decl");
3746
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003747 return cxstring::createDup(Field->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003748 }
3749
3750 case CXCursor_LabelRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003751 const LabelStmt *Label = getCursorLabelRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003752 assert(Label && "Missing label");
3753
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003754 return cxstring::createRef(Label->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003755 }
3756
3757 case CXCursor_OverloadedDeclRef: {
3758 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003759 if (const Decl *D = Storage.dyn_cast<const Decl *>()) {
3760 if (const NamedDecl *ND = dyn_cast<NamedDecl>(D))
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003761 return cxstring::createDup(ND->getNameAsString());
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003762 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003763 }
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003764 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003765 return cxstring::createDup(E->getName().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003766 OverloadedTemplateStorage *Ovl
3767 = Storage.get<OverloadedTemplateStorage*>();
3768 if (Ovl->size() == 0)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003769 return cxstring::createEmpty();
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003770 return cxstring::createDup((*Ovl->begin())->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003771 }
3772
3773 case CXCursor_VariableRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003774 const VarDecl *Var = getCursorVariableRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003775 assert(Var && "Missing variable decl");
3776
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003777 return cxstring::createDup(Var->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003778 }
3779
3780 default:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003781 return cxstring::createRef("<not implemented>");
Guy Benyei11169dd2012-12-18 14:30:41 +00003782 }
3783 }
3784
3785 if (clang_isExpression(C.kind)) {
Argyrios Kyrtzidis3227d862014-03-03 19:40:52 +00003786 const Expr *E = getCursorExpr(C);
3787
3788 if (C.kind == CXCursor_ObjCStringLiteral ||
3789 C.kind == CXCursor_StringLiteral) {
3790 const StringLiteral *SLit;
3791 if (const ObjCStringLiteral *OSL = dyn_cast<ObjCStringLiteral>(E)) {
3792 SLit = OSL->getString();
3793 } else {
3794 SLit = cast<StringLiteral>(E);
3795 }
3796 SmallString<256> Buf;
3797 llvm::raw_svector_ostream OS(Buf);
3798 SLit->outputString(OS);
3799 return cxstring::createDup(OS.str());
3800 }
3801
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003802 const Decl *D = getDeclFromExpr(getCursorExpr(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00003803 if (D)
3804 return getDeclSpelling(D);
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003805 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003806 }
3807
3808 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003809 const Stmt *S = getCursorStmt(C);
3810 if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S))
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003811 return cxstring::createRef(Label->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003812
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003813 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003814 }
3815
3816 if (C.kind == CXCursor_MacroExpansion)
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003817 return cxstring::createRef(getCursorMacroExpansion(C).getName()
Guy Benyei11169dd2012-12-18 14:30:41 +00003818 ->getNameStart());
3819
3820 if (C.kind == CXCursor_MacroDefinition)
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003821 return cxstring::createRef(getCursorMacroDefinition(C)->getName()
Guy Benyei11169dd2012-12-18 14:30:41 +00003822 ->getNameStart());
3823
3824 if (C.kind == CXCursor_InclusionDirective)
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003825 return cxstring::createDup(getCursorInclusionDirective(C)->getFileName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003826
3827 if (clang_isDeclaration(C.kind))
3828 return getDeclSpelling(getCursorDecl(C));
3829
3830 if (C.kind == CXCursor_AnnotateAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00003831 const AnnotateAttr *AA = cast<AnnotateAttr>(cxcursor::getCursorAttr(C));
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003832 return cxstring::createDup(AA->getAnnotation());
Guy Benyei11169dd2012-12-18 14:30:41 +00003833 }
3834
3835 if (C.kind == CXCursor_AsmLabelAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00003836 const AsmLabelAttr *AA = cast<AsmLabelAttr>(cxcursor::getCursorAttr(C));
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003837 return cxstring::createDup(AA->getLabel());
Guy Benyei11169dd2012-12-18 14:30:41 +00003838 }
3839
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00003840 if (C.kind == CXCursor_PackedAttr) {
3841 return cxstring::createRef("packed");
3842 }
3843
Saleem Abdulrasool79c69712015-09-05 18:53:43 +00003844 if (C.kind == CXCursor_VisibilityAttr) {
3845 const VisibilityAttr *AA = cast<VisibilityAttr>(cxcursor::getCursorAttr(C));
3846 switch (AA->getVisibility()) {
3847 case VisibilityAttr::VisibilityType::Default:
3848 return cxstring::createRef("default");
3849 case VisibilityAttr::VisibilityType::Hidden:
3850 return cxstring::createRef("hidden");
3851 case VisibilityAttr::VisibilityType::Protected:
3852 return cxstring::createRef("protected");
3853 }
3854 llvm_unreachable("unknown visibility type");
3855 }
3856
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003857 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003858}
3859
3860CXSourceRange clang_Cursor_getSpellingNameRange(CXCursor C,
3861 unsigned pieceIndex,
3862 unsigned options) {
3863 if (clang_Cursor_isNull(C))
3864 return clang_getNullRange();
3865
3866 ASTContext &Ctx = getCursorContext(C);
3867
3868 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003869 const Stmt *S = getCursorStmt(C);
3870 if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003871 if (pieceIndex > 0)
3872 return clang_getNullRange();
3873 return cxloc::translateSourceRange(Ctx, Label->getIdentLoc());
3874 }
3875
3876 return clang_getNullRange();
3877 }
3878
3879 if (C.kind == CXCursor_ObjCMessageExpr) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003880 if (const ObjCMessageExpr *
Guy Benyei11169dd2012-12-18 14:30:41 +00003881 ME = dyn_cast_or_null<ObjCMessageExpr>(getCursorExpr(C))) {
3882 if (pieceIndex >= ME->getNumSelectorLocs())
3883 return clang_getNullRange();
3884 return cxloc::translateSourceRange(Ctx, ME->getSelectorLoc(pieceIndex));
3885 }
3886 }
3887
3888 if (C.kind == CXCursor_ObjCInstanceMethodDecl ||
3889 C.kind == CXCursor_ObjCClassMethodDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003890 if (const ObjCMethodDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003891 MD = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(C))) {
3892 if (pieceIndex >= MD->getNumSelectorLocs())
3893 return clang_getNullRange();
3894 return cxloc::translateSourceRange(Ctx, MD->getSelectorLoc(pieceIndex));
3895 }
3896 }
3897
3898 if (C.kind == CXCursor_ObjCCategoryDecl ||
3899 C.kind == CXCursor_ObjCCategoryImplDecl) {
3900 if (pieceIndex > 0)
3901 return clang_getNullRange();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003902 if (const ObjCCategoryDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003903 CD = dyn_cast_or_null<ObjCCategoryDecl>(getCursorDecl(C)))
3904 return cxloc::translateSourceRange(Ctx, CD->getCategoryNameLoc());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003905 if (const ObjCCategoryImplDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003906 CID = dyn_cast_or_null<ObjCCategoryImplDecl>(getCursorDecl(C)))
3907 return cxloc::translateSourceRange(Ctx, CID->getCategoryNameLoc());
3908 }
3909
3910 if (C.kind == CXCursor_ModuleImportDecl) {
3911 if (pieceIndex > 0)
3912 return clang_getNullRange();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003913 if (const ImportDecl *ImportD =
3914 dyn_cast_or_null<ImportDecl>(getCursorDecl(C))) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003915 ArrayRef<SourceLocation> Locs = ImportD->getIdentifierLocs();
3916 if (!Locs.empty())
3917 return cxloc::translateSourceRange(Ctx,
3918 SourceRange(Locs.front(), Locs.back()));
3919 }
3920 return clang_getNullRange();
3921 }
3922
Argyrios Kyrtzidisa2a1e532014-08-26 20:23:26 +00003923 if (C.kind == CXCursor_CXXMethod || C.kind == CXCursor_Destructor ||
3924 C.kind == CXCursor_ConversionFunction) {
3925 if (pieceIndex > 0)
3926 return clang_getNullRange();
3927 if (const FunctionDecl *FD =
3928 dyn_cast_or_null<FunctionDecl>(getCursorDecl(C))) {
3929 DeclarationNameInfo FunctionName = FD->getNameInfo();
3930 return cxloc::translateSourceRange(Ctx, FunctionName.getSourceRange());
3931 }
3932 return clang_getNullRange();
3933 }
3934
Guy Benyei11169dd2012-12-18 14:30:41 +00003935 // FIXME: A CXCursor_InclusionDirective should give the location of the
3936 // filename, but we don't keep track of this.
3937
3938 // FIXME: A CXCursor_AnnotateAttr should give the location of the annotation
3939 // but we don't keep track of this.
3940
3941 // FIXME: A CXCursor_AsmLabelAttr should give the location of the label
3942 // but we don't keep track of this.
3943
3944 // Default handling, give the location of the cursor.
3945
3946 if (pieceIndex > 0)
3947 return clang_getNullRange();
3948
3949 CXSourceLocation CXLoc = clang_getCursorLocation(C);
3950 SourceLocation Loc = cxloc::translateSourceLocation(CXLoc);
3951 return cxloc::translateSourceRange(Ctx, Loc);
3952}
3953
Eli Bendersky44a206f2014-07-31 18:04:56 +00003954CXString clang_Cursor_getMangling(CXCursor C) {
3955 if (clang_isInvalid(C.kind) || !clang_isDeclaration(C.kind))
3956 return cxstring::createEmpty();
3957
Eli Bendersky44a206f2014-07-31 18:04:56 +00003958 // Mangling only works for functions and variables.
Eli Bendersky79759592014-08-01 15:01:10 +00003959 const Decl *D = getCursorDecl(C);
Eli Bendersky44a206f2014-07-31 18:04:56 +00003960 if (!D || !(isa<FunctionDecl>(D) || isa<VarDecl>(D)))
3961 return cxstring::createEmpty();
3962
Eli Bendersky79759592014-08-01 15:01:10 +00003963 // First apply frontend mangling.
Eli Bendersky44a206f2014-07-31 18:04:56 +00003964 const NamedDecl *ND = cast<NamedDecl>(D);
Eli Bendersky79759592014-08-01 15:01:10 +00003965 ASTContext &Ctx = ND->getASTContext();
3966 std::unique_ptr<MangleContext> MC(Ctx.createMangleContext());
Eli Bendersky44a206f2014-07-31 18:04:56 +00003967
Eli Bendersky79759592014-08-01 15:01:10 +00003968 std::string FrontendBuf;
3969 llvm::raw_string_ostream FrontendBufOS(FrontendBuf);
Ehsan Akhgarif8d44de2015-10-08 00:01:20 +00003970 if (MC->shouldMangleDeclName(ND)) {
3971 MC->mangleName(ND, FrontendBufOS);
3972 } else {
3973 ND->printName(FrontendBufOS);
3974 }
Eli Bendersky44a206f2014-07-31 18:04:56 +00003975
Eli Bendersky79759592014-08-01 15:01:10 +00003976 // Now apply backend mangling.
3977 std::unique_ptr<llvm::DataLayout> DL(
Eric Christopher964a5f32015-08-05 23:48:05 +00003978 new llvm::DataLayout(Ctx.getTargetInfo().getDataLayoutString()));
Eli Bendersky79759592014-08-01 15:01:10 +00003979
3980 std::string FinalBuf;
3981 llvm::raw_string_ostream FinalBufOS(FinalBuf);
Rafael Espindolab633d202015-06-23 13:59:36 +00003982 llvm::Mangler::getNameWithPrefix(FinalBufOS, llvm::Twine(FrontendBufOS.str()),
3983 *DL);
Eli Bendersky79759592014-08-01 15:01:10 +00003984
3985 return cxstring::createDup(FinalBufOS.str());
Eli Bendersky44a206f2014-07-31 18:04:56 +00003986}
3987
Saleem Abdulrasool60034432015-11-12 03:57:22 +00003988CXStringSet *clang_Cursor_getCXXManglings(CXCursor C) {
3989 if (clang_isInvalid(C.kind) || !clang_isDeclaration(C.kind))
3990 return nullptr;
3991
3992 const Decl *D = getCursorDecl(C);
3993 if (!(isa<CXXRecordDecl>(D) || isa<CXXMethodDecl>(D)))
3994 return nullptr;
3995
3996 const NamedDecl *ND = cast<NamedDecl>(D);
3997
3998 ASTContext &Ctx = ND->getASTContext();
3999 std::unique_ptr<MangleContext> M(Ctx.createMangleContext());
4000 std::unique_ptr<llvm::DataLayout> DL(
4001 new llvm::DataLayout(Ctx.getTargetInfo().getDataLayoutString()));
4002
4003 std::vector<std::string> Manglings;
4004
4005 auto hasDefaultCXXMethodCC = [](ASTContext &C, const CXXMethodDecl *MD) {
4006 auto DefaultCC = C.getDefaultCallingConvention(/*IsVariadic=*/false,
4007 /*IsCSSMethod=*/true);
4008 auto CC = MD->getType()->getAs<FunctionProtoType>()->getCallConv();
4009 return CC == DefaultCC;
4010 };
4011
4012 if (const auto *CD = dyn_cast_or_null<CXXConstructorDecl>(ND)) {
4013 Manglings.emplace_back(getMangledStructor(M, DL, CD, Ctor_Base));
4014
4015 if (Ctx.getTargetInfo().getCXXABI().isItaniumFamily())
4016 if (!CD->getParent()->isAbstract())
4017 Manglings.emplace_back(getMangledStructor(M, DL, CD, Ctor_Complete));
4018
4019 if (Ctx.getTargetInfo().getCXXABI().isMicrosoft())
4020 if (CD->hasAttr<DLLExportAttr>() && CD->isDefaultConstructor())
4021 if (!(hasDefaultCXXMethodCC(Ctx, CD) && CD->getNumParams() == 0))
4022 Manglings.emplace_back(getMangledStructor(M, DL, CD,
4023 Ctor_DefaultClosure));
4024 } else if (const auto *DD = dyn_cast_or_null<CXXDestructorDecl>(ND)) {
4025 Manglings.emplace_back(getMangledStructor(M, DL, DD, Dtor_Base));
4026 if (Ctx.getTargetInfo().getCXXABI().isItaniumFamily()) {
4027 Manglings.emplace_back(getMangledStructor(M, DL, DD, Dtor_Complete));
Saleem Abdulrasoold5af8ae2015-12-10 06:30:23 +00004028 if (DD->isVirtual())
Saleem Abdulrasool60034432015-11-12 03:57:22 +00004029 Manglings.emplace_back(getMangledStructor(M, DL, DD, Dtor_Deleting));
4030 }
4031 }
4032
4033 return cxstring::createSet(Manglings);
4034}
4035
Guy Benyei11169dd2012-12-18 14:30:41 +00004036CXString clang_getCursorDisplayName(CXCursor C) {
4037 if (!clang_isDeclaration(C.kind))
4038 return clang_getCursorSpelling(C);
4039
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004040 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004041 if (!D)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00004042 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00004043
4044 PrintingPolicy Policy = getCursorContext(C).getPrintingPolicy();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004045 if (const FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004046 D = FunTmpl->getTemplatedDecl();
4047
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004048 if (const FunctionDecl *Function = dyn_cast<FunctionDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004049 SmallString<64> Str;
4050 llvm::raw_svector_ostream OS(Str);
4051 OS << *Function;
4052 if (Function->getPrimaryTemplate())
4053 OS << "<>";
4054 OS << "(";
4055 for (unsigned I = 0, N = Function->getNumParams(); I != N; ++I) {
4056 if (I)
4057 OS << ", ";
4058 OS << Function->getParamDecl(I)->getType().getAsString(Policy);
4059 }
4060
4061 if (Function->isVariadic()) {
4062 if (Function->getNumParams())
4063 OS << ", ";
4064 OS << "...";
4065 }
4066 OS << ")";
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004067 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00004068 }
4069
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004070 if (const ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004071 SmallString<64> Str;
4072 llvm::raw_svector_ostream OS(Str);
4073 OS << *ClassTemplate;
4074 OS << "<";
4075 TemplateParameterList *Params = ClassTemplate->getTemplateParameters();
4076 for (unsigned I = 0, N = Params->size(); I != N; ++I) {
4077 if (I)
4078 OS << ", ";
4079
4080 NamedDecl *Param = Params->getParam(I);
4081 if (Param->getIdentifier()) {
4082 OS << Param->getIdentifier()->getName();
4083 continue;
4084 }
4085
4086 // There is no parameter name, which makes this tricky. Try to come up
4087 // with something useful that isn't too long.
4088 if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(Param))
4089 OS << (TTP->wasDeclaredWithTypename()? "typename" : "class");
4090 else if (NonTypeTemplateParmDecl *NTTP
4091 = dyn_cast<NonTypeTemplateParmDecl>(Param))
4092 OS << NTTP->getType().getAsString(Policy);
4093 else
4094 OS << "template<...> class";
4095 }
4096
4097 OS << ">";
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004098 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00004099 }
4100
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004101 if (const ClassTemplateSpecializationDecl *ClassSpec
Guy Benyei11169dd2012-12-18 14:30:41 +00004102 = dyn_cast<ClassTemplateSpecializationDecl>(D)) {
4103 // If the type was explicitly written, use that.
4104 if (TypeSourceInfo *TSInfo = ClassSpec->getTypeAsWritten())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004105 return cxstring::createDup(TSInfo->getType().getAsString(Policy));
Guy Benyei11169dd2012-12-18 14:30:41 +00004106
Benjamin Kramer9170e912013-02-22 15:46:01 +00004107 SmallString<128> Str;
Guy Benyei11169dd2012-12-18 14:30:41 +00004108 llvm::raw_svector_ostream OS(Str);
4109 OS << *ClassSpec;
Benjamin Kramer9170e912013-02-22 15:46:01 +00004110 TemplateSpecializationType::PrintTemplateArgumentList(OS,
Guy Benyei11169dd2012-12-18 14:30:41 +00004111 ClassSpec->getTemplateArgs().data(),
4112 ClassSpec->getTemplateArgs().size(),
4113 Policy);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004114 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00004115 }
4116
4117 return clang_getCursorSpelling(C);
4118}
4119
4120CXString clang_getCursorKindSpelling(enum CXCursorKind Kind) {
4121 switch (Kind) {
4122 case CXCursor_FunctionDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004123 return cxstring::createRef("FunctionDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004124 case CXCursor_TypedefDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004125 return cxstring::createRef("TypedefDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004126 case CXCursor_EnumDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004127 return cxstring::createRef("EnumDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004128 case CXCursor_EnumConstantDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004129 return cxstring::createRef("EnumConstantDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004130 case CXCursor_StructDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004131 return cxstring::createRef("StructDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004132 case CXCursor_UnionDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004133 return cxstring::createRef("UnionDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004134 case CXCursor_ClassDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004135 return cxstring::createRef("ClassDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004136 case CXCursor_FieldDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004137 return cxstring::createRef("FieldDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004138 case CXCursor_VarDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004139 return cxstring::createRef("VarDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004140 case CXCursor_ParmDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004141 return cxstring::createRef("ParmDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004142 case CXCursor_ObjCInterfaceDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004143 return cxstring::createRef("ObjCInterfaceDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004144 case CXCursor_ObjCCategoryDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004145 return cxstring::createRef("ObjCCategoryDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004146 case CXCursor_ObjCProtocolDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004147 return cxstring::createRef("ObjCProtocolDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004148 case CXCursor_ObjCPropertyDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004149 return cxstring::createRef("ObjCPropertyDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004150 case CXCursor_ObjCIvarDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004151 return cxstring::createRef("ObjCIvarDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004152 case CXCursor_ObjCInstanceMethodDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004153 return cxstring::createRef("ObjCInstanceMethodDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004154 case CXCursor_ObjCClassMethodDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004155 return cxstring::createRef("ObjCClassMethodDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004156 case CXCursor_ObjCImplementationDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004157 return cxstring::createRef("ObjCImplementationDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004158 case CXCursor_ObjCCategoryImplDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004159 return cxstring::createRef("ObjCCategoryImplDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004160 case CXCursor_CXXMethod:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004161 return cxstring::createRef("CXXMethod");
Guy Benyei11169dd2012-12-18 14:30:41 +00004162 case CXCursor_UnexposedDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004163 return cxstring::createRef("UnexposedDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004164 case CXCursor_ObjCSuperClassRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004165 return cxstring::createRef("ObjCSuperClassRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004166 case CXCursor_ObjCProtocolRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004167 return cxstring::createRef("ObjCProtocolRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004168 case CXCursor_ObjCClassRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004169 return cxstring::createRef("ObjCClassRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004170 case CXCursor_TypeRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004171 return cxstring::createRef("TypeRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004172 case CXCursor_TemplateRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004173 return cxstring::createRef("TemplateRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004174 case CXCursor_NamespaceRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004175 return cxstring::createRef("NamespaceRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004176 case CXCursor_MemberRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004177 return cxstring::createRef("MemberRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004178 case CXCursor_LabelRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004179 return cxstring::createRef("LabelRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004180 case CXCursor_OverloadedDeclRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004181 return cxstring::createRef("OverloadedDeclRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004182 case CXCursor_VariableRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004183 return cxstring::createRef("VariableRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004184 case CXCursor_IntegerLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004185 return cxstring::createRef("IntegerLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00004186 case CXCursor_FloatingLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004187 return cxstring::createRef("FloatingLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00004188 case CXCursor_ImaginaryLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004189 return cxstring::createRef("ImaginaryLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00004190 case CXCursor_StringLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004191 return cxstring::createRef("StringLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00004192 case CXCursor_CharacterLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004193 return cxstring::createRef("CharacterLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00004194 case CXCursor_ParenExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004195 return cxstring::createRef("ParenExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004196 case CXCursor_UnaryOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004197 return cxstring::createRef("UnaryOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00004198 case CXCursor_ArraySubscriptExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004199 return cxstring::createRef("ArraySubscriptExpr");
Alexey Bataev1a3320e2015-08-25 14:24:04 +00004200 case CXCursor_OMPArraySectionExpr:
4201 return cxstring::createRef("OMPArraySectionExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004202 case CXCursor_BinaryOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004203 return cxstring::createRef("BinaryOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00004204 case CXCursor_CompoundAssignOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004205 return cxstring::createRef("CompoundAssignOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00004206 case CXCursor_ConditionalOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004207 return cxstring::createRef("ConditionalOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00004208 case CXCursor_CStyleCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004209 return cxstring::createRef("CStyleCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004210 case CXCursor_CompoundLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004211 return cxstring::createRef("CompoundLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004212 case CXCursor_InitListExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004213 return cxstring::createRef("InitListExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004214 case CXCursor_AddrLabelExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004215 return cxstring::createRef("AddrLabelExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004216 case CXCursor_StmtExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004217 return cxstring::createRef("StmtExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004218 case CXCursor_GenericSelectionExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004219 return cxstring::createRef("GenericSelectionExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004220 case CXCursor_GNUNullExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004221 return cxstring::createRef("GNUNullExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004222 case CXCursor_CXXStaticCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004223 return cxstring::createRef("CXXStaticCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004224 case CXCursor_CXXDynamicCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004225 return cxstring::createRef("CXXDynamicCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004226 case CXCursor_CXXReinterpretCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004227 return cxstring::createRef("CXXReinterpretCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004228 case CXCursor_CXXConstCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004229 return cxstring::createRef("CXXConstCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004230 case CXCursor_CXXFunctionalCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004231 return cxstring::createRef("CXXFunctionalCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004232 case CXCursor_CXXTypeidExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004233 return cxstring::createRef("CXXTypeidExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004234 case CXCursor_CXXBoolLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004235 return cxstring::createRef("CXXBoolLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004236 case CXCursor_CXXNullPtrLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004237 return cxstring::createRef("CXXNullPtrLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004238 case CXCursor_CXXThisExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004239 return cxstring::createRef("CXXThisExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004240 case CXCursor_CXXThrowExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004241 return cxstring::createRef("CXXThrowExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004242 case CXCursor_CXXNewExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004243 return cxstring::createRef("CXXNewExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004244 case CXCursor_CXXDeleteExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004245 return cxstring::createRef("CXXDeleteExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004246 case CXCursor_UnaryExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004247 return cxstring::createRef("UnaryExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004248 case CXCursor_ObjCStringLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004249 return cxstring::createRef("ObjCStringLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00004250 case CXCursor_ObjCBoolLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004251 return cxstring::createRef("ObjCBoolLiteralExpr");
Argyrios Kyrtzidisc2233be2013-04-23 17:57:17 +00004252 case CXCursor_ObjCSelfExpr:
4253 return cxstring::createRef("ObjCSelfExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004254 case CXCursor_ObjCEncodeExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004255 return cxstring::createRef("ObjCEncodeExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004256 case CXCursor_ObjCSelectorExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004257 return cxstring::createRef("ObjCSelectorExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004258 case CXCursor_ObjCProtocolExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004259 return cxstring::createRef("ObjCProtocolExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004260 case CXCursor_ObjCBridgedCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004261 return cxstring::createRef("ObjCBridgedCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004262 case CXCursor_BlockExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004263 return cxstring::createRef("BlockExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004264 case CXCursor_PackExpansionExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004265 return cxstring::createRef("PackExpansionExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004266 case CXCursor_SizeOfPackExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004267 return cxstring::createRef("SizeOfPackExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004268 case CXCursor_LambdaExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004269 return cxstring::createRef("LambdaExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004270 case CXCursor_UnexposedExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004271 return cxstring::createRef("UnexposedExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004272 case CXCursor_DeclRefExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004273 return cxstring::createRef("DeclRefExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004274 case CXCursor_MemberRefExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004275 return cxstring::createRef("MemberRefExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004276 case CXCursor_CallExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004277 return cxstring::createRef("CallExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004278 case CXCursor_ObjCMessageExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004279 return cxstring::createRef("ObjCMessageExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004280 case CXCursor_UnexposedStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004281 return cxstring::createRef("UnexposedStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004282 case CXCursor_DeclStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004283 return cxstring::createRef("DeclStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004284 case CXCursor_LabelStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004285 return cxstring::createRef("LabelStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004286 case CXCursor_CompoundStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004287 return cxstring::createRef("CompoundStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004288 case CXCursor_CaseStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004289 return cxstring::createRef("CaseStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004290 case CXCursor_DefaultStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004291 return cxstring::createRef("DefaultStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004292 case CXCursor_IfStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004293 return cxstring::createRef("IfStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004294 case CXCursor_SwitchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004295 return cxstring::createRef("SwitchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004296 case CXCursor_WhileStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004297 return cxstring::createRef("WhileStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004298 case CXCursor_DoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004299 return cxstring::createRef("DoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004300 case CXCursor_ForStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004301 return cxstring::createRef("ForStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004302 case CXCursor_GotoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004303 return cxstring::createRef("GotoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004304 case CXCursor_IndirectGotoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004305 return cxstring::createRef("IndirectGotoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004306 case CXCursor_ContinueStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004307 return cxstring::createRef("ContinueStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004308 case CXCursor_BreakStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004309 return cxstring::createRef("BreakStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004310 case CXCursor_ReturnStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004311 return cxstring::createRef("ReturnStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004312 case CXCursor_GCCAsmStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004313 return cxstring::createRef("GCCAsmStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004314 case CXCursor_MSAsmStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004315 return cxstring::createRef("MSAsmStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004316 case CXCursor_ObjCAtTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004317 return cxstring::createRef("ObjCAtTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004318 case CXCursor_ObjCAtCatchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004319 return cxstring::createRef("ObjCAtCatchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004320 case CXCursor_ObjCAtFinallyStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004321 return cxstring::createRef("ObjCAtFinallyStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004322 case CXCursor_ObjCAtThrowStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004323 return cxstring::createRef("ObjCAtThrowStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004324 case CXCursor_ObjCAtSynchronizedStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004325 return cxstring::createRef("ObjCAtSynchronizedStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004326 case CXCursor_ObjCAutoreleasePoolStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004327 return cxstring::createRef("ObjCAutoreleasePoolStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004328 case CXCursor_ObjCForCollectionStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004329 return cxstring::createRef("ObjCForCollectionStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004330 case CXCursor_CXXCatchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004331 return cxstring::createRef("CXXCatchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004332 case CXCursor_CXXTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004333 return cxstring::createRef("CXXTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004334 case CXCursor_CXXForRangeStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004335 return cxstring::createRef("CXXForRangeStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004336 case CXCursor_SEHTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004337 return cxstring::createRef("SEHTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004338 case CXCursor_SEHExceptStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004339 return cxstring::createRef("SEHExceptStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004340 case CXCursor_SEHFinallyStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004341 return cxstring::createRef("SEHFinallyStmt");
Nico Weber9b982072014-07-07 00:12:30 +00004342 case CXCursor_SEHLeaveStmt:
4343 return cxstring::createRef("SEHLeaveStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004344 case CXCursor_NullStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004345 return cxstring::createRef("NullStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004346 case CXCursor_InvalidFile:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004347 return cxstring::createRef("InvalidFile");
Guy Benyei11169dd2012-12-18 14:30:41 +00004348 case CXCursor_InvalidCode:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004349 return cxstring::createRef("InvalidCode");
Guy Benyei11169dd2012-12-18 14:30:41 +00004350 case CXCursor_NoDeclFound:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004351 return cxstring::createRef("NoDeclFound");
Guy Benyei11169dd2012-12-18 14:30:41 +00004352 case CXCursor_NotImplemented:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004353 return cxstring::createRef("NotImplemented");
Guy Benyei11169dd2012-12-18 14:30:41 +00004354 case CXCursor_TranslationUnit:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004355 return cxstring::createRef("TranslationUnit");
Guy Benyei11169dd2012-12-18 14:30:41 +00004356 case CXCursor_UnexposedAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004357 return cxstring::createRef("UnexposedAttr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004358 case CXCursor_IBActionAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004359 return cxstring::createRef("attribute(ibaction)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004360 case CXCursor_IBOutletAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004361 return cxstring::createRef("attribute(iboutlet)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004362 case CXCursor_IBOutletCollectionAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004363 return cxstring::createRef("attribute(iboutletcollection)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004364 case CXCursor_CXXFinalAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004365 return cxstring::createRef("attribute(final)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004366 case CXCursor_CXXOverrideAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004367 return cxstring::createRef("attribute(override)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004368 case CXCursor_AnnotateAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004369 return cxstring::createRef("attribute(annotate)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004370 case CXCursor_AsmLabelAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004371 return cxstring::createRef("asm label");
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00004372 case CXCursor_PackedAttr:
4373 return cxstring::createRef("attribute(packed)");
Joey Gouly81228382014-05-01 15:41:58 +00004374 case CXCursor_PureAttr:
4375 return cxstring::createRef("attribute(pure)");
4376 case CXCursor_ConstAttr:
4377 return cxstring::createRef("attribute(const)");
4378 case CXCursor_NoDuplicateAttr:
4379 return cxstring::createRef("attribute(noduplicate)");
Eli Bendersky2581e662014-05-28 19:29:58 +00004380 case CXCursor_CUDAConstantAttr:
4381 return cxstring::createRef("attribute(constant)");
4382 case CXCursor_CUDADeviceAttr:
4383 return cxstring::createRef("attribute(device)");
4384 case CXCursor_CUDAGlobalAttr:
4385 return cxstring::createRef("attribute(global)");
4386 case CXCursor_CUDAHostAttr:
4387 return cxstring::createRef("attribute(host)");
Eli Bendersky9b071472014-08-08 14:59:00 +00004388 case CXCursor_CUDASharedAttr:
4389 return cxstring::createRef("attribute(shared)");
Saleem Abdulrasool79c69712015-09-05 18:53:43 +00004390 case CXCursor_VisibilityAttr:
4391 return cxstring::createRef("attribute(visibility)");
Saleem Abdulrasool8aa0b802015-12-10 18:45:18 +00004392 case CXCursor_DLLExport:
4393 return cxstring::createRef("attribute(dllexport)");
4394 case CXCursor_DLLImport:
4395 return cxstring::createRef("attribute(dllimport)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004396 case CXCursor_PreprocessingDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004397 return cxstring::createRef("preprocessing directive");
Guy Benyei11169dd2012-12-18 14:30:41 +00004398 case CXCursor_MacroDefinition:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004399 return cxstring::createRef("macro definition");
Guy Benyei11169dd2012-12-18 14:30:41 +00004400 case CXCursor_MacroExpansion:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004401 return cxstring::createRef("macro expansion");
Guy Benyei11169dd2012-12-18 14:30:41 +00004402 case CXCursor_InclusionDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004403 return cxstring::createRef("inclusion directive");
Guy Benyei11169dd2012-12-18 14:30:41 +00004404 case CXCursor_Namespace:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004405 return cxstring::createRef("Namespace");
Guy Benyei11169dd2012-12-18 14:30:41 +00004406 case CXCursor_LinkageSpec:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004407 return cxstring::createRef("LinkageSpec");
Guy Benyei11169dd2012-12-18 14:30:41 +00004408 case CXCursor_CXXBaseSpecifier:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004409 return cxstring::createRef("C++ base class specifier");
Guy Benyei11169dd2012-12-18 14:30:41 +00004410 case CXCursor_Constructor:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004411 return cxstring::createRef("CXXConstructor");
Guy Benyei11169dd2012-12-18 14:30:41 +00004412 case CXCursor_Destructor:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004413 return cxstring::createRef("CXXDestructor");
Guy Benyei11169dd2012-12-18 14:30:41 +00004414 case CXCursor_ConversionFunction:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004415 return cxstring::createRef("CXXConversion");
Guy Benyei11169dd2012-12-18 14:30:41 +00004416 case CXCursor_TemplateTypeParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004417 return cxstring::createRef("TemplateTypeParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00004418 case CXCursor_NonTypeTemplateParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004419 return cxstring::createRef("NonTypeTemplateParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00004420 case CXCursor_TemplateTemplateParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004421 return cxstring::createRef("TemplateTemplateParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00004422 case CXCursor_FunctionTemplate:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004423 return cxstring::createRef("FunctionTemplate");
Guy Benyei11169dd2012-12-18 14:30:41 +00004424 case CXCursor_ClassTemplate:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004425 return cxstring::createRef("ClassTemplate");
Guy Benyei11169dd2012-12-18 14:30:41 +00004426 case CXCursor_ClassTemplatePartialSpecialization:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004427 return cxstring::createRef("ClassTemplatePartialSpecialization");
Guy Benyei11169dd2012-12-18 14:30:41 +00004428 case CXCursor_NamespaceAlias:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004429 return cxstring::createRef("NamespaceAlias");
Guy Benyei11169dd2012-12-18 14:30:41 +00004430 case CXCursor_UsingDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004431 return cxstring::createRef("UsingDirective");
Guy Benyei11169dd2012-12-18 14:30:41 +00004432 case CXCursor_UsingDeclaration:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004433 return cxstring::createRef("UsingDeclaration");
Guy Benyei11169dd2012-12-18 14:30:41 +00004434 case CXCursor_TypeAliasDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004435 return cxstring::createRef("TypeAliasDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004436 case CXCursor_ObjCSynthesizeDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004437 return cxstring::createRef("ObjCSynthesizeDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004438 case CXCursor_ObjCDynamicDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004439 return cxstring::createRef("ObjCDynamicDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004440 case CXCursor_CXXAccessSpecifier:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004441 return cxstring::createRef("CXXAccessSpecifier");
Guy Benyei11169dd2012-12-18 14:30:41 +00004442 case CXCursor_ModuleImportDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004443 return cxstring::createRef("ModuleImport");
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00004444 case CXCursor_OMPParallelDirective:
Alexey Bataev1b59ab52014-02-27 08:29:12 +00004445 return cxstring::createRef("OMPParallelDirective");
4446 case CXCursor_OMPSimdDirective:
4447 return cxstring::createRef("OMPSimdDirective");
Alexey Bataevf29276e2014-06-18 04:14:57 +00004448 case CXCursor_OMPForDirective:
4449 return cxstring::createRef("OMPForDirective");
Alexander Musmanf82886e2014-09-18 05:12:34 +00004450 case CXCursor_OMPForSimdDirective:
4451 return cxstring::createRef("OMPForSimdDirective");
Alexey Bataevd3f8dd22014-06-25 11:44:49 +00004452 case CXCursor_OMPSectionsDirective:
4453 return cxstring::createRef("OMPSectionsDirective");
Alexey Bataev1e0498a2014-06-26 08:21:58 +00004454 case CXCursor_OMPSectionDirective:
4455 return cxstring::createRef("OMPSectionDirective");
Alexey Bataevd1e40fb2014-06-26 12:05:45 +00004456 case CXCursor_OMPSingleDirective:
4457 return cxstring::createRef("OMPSingleDirective");
Alexander Musman80c22892014-07-17 08:54:58 +00004458 case CXCursor_OMPMasterDirective:
4459 return cxstring::createRef("OMPMasterDirective");
Alexander Musmand9ed09f2014-07-21 09:42:05 +00004460 case CXCursor_OMPCriticalDirective:
4461 return cxstring::createRef("OMPCriticalDirective");
Alexey Bataev4acb8592014-07-07 13:01:15 +00004462 case CXCursor_OMPParallelForDirective:
4463 return cxstring::createRef("OMPParallelForDirective");
Alexander Musmane4e893b2014-09-23 09:33:00 +00004464 case CXCursor_OMPParallelForSimdDirective:
4465 return cxstring::createRef("OMPParallelForSimdDirective");
Alexey Bataev84d0b3e2014-07-08 08:12:03 +00004466 case CXCursor_OMPParallelSectionsDirective:
4467 return cxstring::createRef("OMPParallelSectionsDirective");
Alexey Bataev9c2e8ee2014-07-11 11:25:16 +00004468 case CXCursor_OMPTaskDirective:
4469 return cxstring::createRef("OMPTaskDirective");
Alexey Bataev68446b72014-07-18 07:47:19 +00004470 case CXCursor_OMPTaskyieldDirective:
4471 return cxstring::createRef("OMPTaskyieldDirective");
Alexey Bataev4d1dfea2014-07-18 09:11:51 +00004472 case CXCursor_OMPBarrierDirective:
4473 return cxstring::createRef("OMPBarrierDirective");
Alexey Bataev2df347a2014-07-18 10:17:07 +00004474 case CXCursor_OMPTaskwaitDirective:
4475 return cxstring::createRef("OMPTaskwaitDirective");
Alexey Bataevc30dd2d2015-06-18 12:14:09 +00004476 case CXCursor_OMPTaskgroupDirective:
4477 return cxstring::createRef("OMPTaskgroupDirective");
Alexey Bataev6125da92014-07-21 11:26:11 +00004478 case CXCursor_OMPFlushDirective:
4479 return cxstring::createRef("OMPFlushDirective");
Alexey Bataev9fb6e642014-07-22 06:45:04 +00004480 case CXCursor_OMPOrderedDirective:
4481 return cxstring::createRef("OMPOrderedDirective");
Alexey Bataev0162e452014-07-22 10:10:35 +00004482 case CXCursor_OMPAtomicDirective:
4483 return cxstring::createRef("OMPAtomicDirective");
Alexey Bataev0bd520b2014-09-19 08:19:49 +00004484 case CXCursor_OMPTargetDirective:
4485 return cxstring::createRef("OMPTargetDirective");
Michael Wong65f367f2015-07-21 13:44:28 +00004486 case CXCursor_OMPTargetDataDirective:
4487 return cxstring::createRef("OMPTargetDataDirective");
Alexey Bataev13314bf2014-10-09 04:18:56 +00004488 case CXCursor_OMPTeamsDirective:
4489 return cxstring::createRef("OMPTeamsDirective");
Alexey Bataev6d4ed052015-07-01 06:57:41 +00004490 case CXCursor_OMPCancellationPointDirective:
4491 return cxstring::createRef("OMPCancellationPointDirective");
Alexey Bataev80909872015-07-02 11:25:17 +00004492 case CXCursor_OMPCancelDirective:
4493 return cxstring::createRef("OMPCancelDirective");
Alexey Bataev49f6e782015-12-01 04:18:41 +00004494 case CXCursor_OMPTaskLoopDirective:
4495 return cxstring::createRef("OMPTaskLoopDirective");
Alexey Bataev0a6ed842015-12-03 09:40:15 +00004496 case CXCursor_OMPTaskLoopSimdDirective:
4497 return cxstring::createRef("OMPTaskLoopSimdDirective");
Francisco Lopes da Silva975a9f62015-01-21 16:24:11 +00004498 case CXCursor_OverloadCandidate:
4499 return cxstring::createRef("OverloadCandidate");
Sergey Kalinichev8f3b1872015-11-15 13:48:32 +00004500 case CXCursor_TypeAliasTemplateDecl:
4501 return cxstring::createRef("TypeAliasTemplateDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004502 }
4503
4504 llvm_unreachable("Unhandled CXCursorKind");
4505}
4506
4507struct GetCursorData {
4508 SourceLocation TokenBeginLoc;
4509 bool PointsAtMacroArgExpansion;
4510 bool VisitedObjCPropertyImplDecl;
4511 SourceLocation VisitedDeclaratorDeclStartLoc;
4512 CXCursor &BestCursor;
4513
4514 GetCursorData(SourceManager &SM,
4515 SourceLocation tokenBegin, CXCursor &outputCursor)
4516 : TokenBeginLoc(tokenBegin), BestCursor(outputCursor) {
4517 PointsAtMacroArgExpansion = SM.isMacroArgExpansion(tokenBegin);
4518 VisitedObjCPropertyImplDecl = false;
4519 }
4520};
4521
4522static enum CXChildVisitResult GetCursorVisitor(CXCursor cursor,
4523 CXCursor parent,
4524 CXClientData client_data) {
4525 GetCursorData *Data = static_cast<GetCursorData *>(client_data);
4526 CXCursor *BestCursor = &Data->BestCursor;
4527
4528 // If we point inside a macro argument we should provide info of what the
4529 // token is so use the actual cursor, don't replace it with a macro expansion
4530 // cursor.
4531 if (cursor.kind == CXCursor_MacroExpansion && Data->PointsAtMacroArgExpansion)
4532 return CXChildVisit_Recurse;
4533
4534 if (clang_isDeclaration(cursor.kind)) {
4535 // Avoid having the implicit methods override the property decls.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004536 if (const ObjCMethodDecl *MD
Guy Benyei11169dd2012-12-18 14:30:41 +00004537 = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
4538 if (MD->isImplicit())
4539 return CXChildVisit_Break;
4540
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004541 } else if (const ObjCInterfaceDecl *ID
Guy Benyei11169dd2012-12-18 14:30:41 +00004542 = dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(cursor))) {
4543 // Check that when we have multiple @class references in the same line,
4544 // that later ones do not override the previous ones.
4545 // If we have:
4546 // @class Foo, Bar;
4547 // source ranges for both start at '@', so 'Bar' will end up overriding
4548 // 'Foo' even though the cursor location was at 'Foo'.
4549 if (BestCursor->kind == CXCursor_ObjCInterfaceDecl ||
4550 BestCursor->kind == CXCursor_ObjCClassRef)
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004551 if (const ObjCInterfaceDecl *PrevID
Guy Benyei11169dd2012-12-18 14:30:41 +00004552 = dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(*BestCursor))){
4553 if (PrevID != ID &&
4554 !PrevID->isThisDeclarationADefinition() &&
4555 !ID->isThisDeclarationADefinition())
4556 return CXChildVisit_Break;
4557 }
4558
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004559 } else if (const DeclaratorDecl *DD
Guy Benyei11169dd2012-12-18 14:30:41 +00004560 = dyn_cast_or_null<DeclaratorDecl>(getCursorDecl(cursor))) {
4561 SourceLocation StartLoc = DD->getSourceRange().getBegin();
4562 // Check that when we have multiple declarators in the same line,
4563 // that later ones do not override the previous ones.
4564 // If we have:
4565 // int Foo, Bar;
4566 // source ranges for both start at 'int', so 'Bar' will end up overriding
4567 // 'Foo' even though the cursor location was at 'Foo'.
4568 if (Data->VisitedDeclaratorDeclStartLoc == StartLoc)
4569 return CXChildVisit_Break;
4570 Data->VisitedDeclaratorDeclStartLoc = StartLoc;
4571
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004572 } else if (const ObjCPropertyImplDecl *PropImp
Guy Benyei11169dd2012-12-18 14:30:41 +00004573 = dyn_cast_or_null<ObjCPropertyImplDecl>(getCursorDecl(cursor))) {
4574 (void)PropImp;
4575 // Check that when we have multiple @synthesize in the same line,
4576 // that later ones do not override the previous ones.
4577 // If we have:
4578 // @synthesize Foo, Bar;
4579 // source ranges for both start at '@', so 'Bar' will end up overriding
4580 // 'Foo' even though the cursor location was at 'Foo'.
4581 if (Data->VisitedObjCPropertyImplDecl)
4582 return CXChildVisit_Break;
4583 Data->VisitedObjCPropertyImplDecl = true;
4584 }
4585 }
4586
4587 if (clang_isExpression(cursor.kind) &&
4588 clang_isDeclaration(BestCursor->kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004589 if (const Decl *D = getCursorDecl(*BestCursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004590 // Avoid having the cursor of an expression replace the declaration cursor
4591 // when the expression source range overlaps the declaration range.
4592 // This can happen for C++ constructor expressions whose range generally
4593 // include the variable declaration, e.g.:
4594 // MyCXXClass foo; // Make sure pointing at 'foo' returns a VarDecl cursor.
4595 if (D->getLocation().isValid() && Data->TokenBeginLoc.isValid() &&
4596 D->getLocation() == Data->TokenBeginLoc)
4597 return CXChildVisit_Break;
4598 }
4599 }
4600
4601 // If our current best cursor is the construction of a temporary object,
4602 // don't replace that cursor with a type reference, because we want
4603 // clang_getCursor() to point at the constructor.
4604 if (clang_isExpression(BestCursor->kind) &&
4605 isa<CXXTemporaryObjectExpr>(getCursorExpr(*BestCursor)) &&
4606 cursor.kind == CXCursor_TypeRef) {
4607 // Keep the cursor pointing at CXXTemporaryObjectExpr but also mark it
4608 // as having the actual point on the type reference.
4609 *BestCursor = getTypeRefedCallExprCursor(*BestCursor);
4610 return CXChildVisit_Recurse;
4611 }
Douglas Gregore9d95f12015-07-07 03:57:35 +00004612
4613 // If we already have an Objective-C superclass reference, don't
4614 // update it further.
4615 if (BestCursor->kind == CXCursor_ObjCSuperClassRef)
4616 return CXChildVisit_Break;
4617
Guy Benyei11169dd2012-12-18 14:30:41 +00004618 *BestCursor = cursor;
4619 return CXChildVisit_Recurse;
4620}
4621
4622CXCursor clang_getCursor(CXTranslationUnit TU, CXSourceLocation Loc) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00004623 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004624 LOG_BAD_TU(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004625 return clang_getNullCursor();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004626 }
Guy Benyei11169dd2012-12-18 14:30:41 +00004627
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004628 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004629 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
4630
4631 SourceLocation SLoc = cxloc::translateSourceLocation(Loc);
4632 CXCursor Result = cxcursor::getCursor(TU, SLoc);
4633
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004634 LOG_FUNC_SECTION {
Guy Benyei11169dd2012-12-18 14:30:41 +00004635 CXFile SearchFile;
4636 unsigned SearchLine, SearchColumn;
4637 CXFile ResultFile;
4638 unsigned ResultLine, ResultColumn;
4639 CXString SearchFileName, ResultFileName, KindSpelling, USR;
4640 const char *IsDef = clang_isCursorDefinition(Result)? " (Definition)" : "";
4641 CXSourceLocation ResultLoc = clang_getCursorLocation(Result);
Craig Topper69186e72014-06-08 08:38:04 +00004642
4643 clang_getFileLocation(Loc, &SearchFile, &SearchLine, &SearchColumn,
4644 nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004645 clang_getFileLocation(ResultLoc, &ResultFile, &ResultLine,
Craig Topper69186e72014-06-08 08:38:04 +00004646 &ResultColumn, nullptr);
Guy Benyei11169dd2012-12-18 14:30:41 +00004647 SearchFileName = clang_getFileName(SearchFile);
4648 ResultFileName = clang_getFileName(ResultFile);
4649 KindSpelling = clang_getCursorKindSpelling(Result.kind);
4650 USR = clang_getCursorUSR(Result);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004651 *Log << llvm::format("(%s:%d:%d) = %s",
4652 clang_getCString(SearchFileName), SearchLine, SearchColumn,
4653 clang_getCString(KindSpelling))
4654 << llvm::format("(%s:%d:%d):%s%s",
4655 clang_getCString(ResultFileName), ResultLine, ResultColumn,
4656 clang_getCString(USR), IsDef);
Guy Benyei11169dd2012-12-18 14:30:41 +00004657 clang_disposeString(SearchFileName);
4658 clang_disposeString(ResultFileName);
4659 clang_disposeString(KindSpelling);
4660 clang_disposeString(USR);
4661
4662 CXCursor Definition = clang_getCursorDefinition(Result);
4663 if (!clang_equalCursors(Definition, clang_getNullCursor())) {
4664 CXSourceLocation DefinitionLoc = clang_getCursorLocation(Definition);
4665 CXString DefinitionKindSpelling
4666 = clang_getCursorKindSpelling(Definition.kind);
4667 CXFile DefinitionFile;
4668 unsigned DefinitionLine, DefinitionColumn;
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004669 clang_getFileLocation(DefinitionLoc, &DefinitionFile,
Craig Topper69186e72014-06-08 08:38:04 +00004670 &DefinitionLine, &DefinitionColumn, nullptr);
Guy Benyei11169dd2012-12-18 14:30:41 +00004671 CXString DefinitionFileName = clang_getFileName(DefinitionFile);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004672 *Log << llvm::format(" -> %s(%s:%d:%d)",
4673 clang_getCString(DefinitionKindSpelling),
4674 clang_getCString(DefinitionFileName),
4675 DefinitionLine, DefinitionColumn);
Guy Benyei11169dd2012-12-18 14:30:41 +00004676 clang_disposeString(DefinitionFileName);
4677 clang_disposeString(DefinitionKindSpelling);
4678 }
4679 }
4680
4681 return Result;
4682}
4683
4684CXCursor clang_getNullCursor(void) {
4685 return MakeCXCursorInvalid(CXCursor_InvalidFile);
4686}
4687
4688unsigned clang_equalCursors(CXCursor X, CXCursor Y) {
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00004689 // Clear out the "FirstInDeclGroup" part in a declaration cursor, since we
4690 // can't set consistently. For example, when visiting a DeclStmt we will set
4691 // it but we don't set it on the result of clang_getCursorDefinition for
4692 // a reference of the same declaration.
4693 // FIXME: Setting "FirstInDeclGroup" in CXCursors is a hack that only works
4694 // when visiting a DeclStmt currently, the AST should be enhanced to be able
4695 // to provide that kind of info.
4696 if (clang_isDeclaration(X.kind))
Craig Topper69186e72014-06-08 08:38:04 +00004697 X.data[1] = nullptr;
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00004698 if (clang_isDeclaration(Y.kind))
Craig Topper69186e72014-06-08 08:38:04 +00004699 Y.data[1] = nullptr;
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00004700
Guy Benyei11169dd2012-12-18 14:30:41 +00004701 return X == Y;
4702}
4703
4704unsigned clang_hashCursor(CXCursor C) {
4705 unsigned Index = 0;
4706 if (clang_isExpression(C.kind) || clang_isStatement(C.kind))
4707 Index = 1;
4708
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004709 return llvm::DenseMapInfo<std::pair<unsigned, const void*> >::getHashValue(
Guy Benyei11169dd2012-12-18 14:30:41 +00004710 std::make_pair(C.kind, C.data[Index]));
4711}
4712
4713unsigned clang_isInvalid(enum CXCursorKind K) {
4714 return K >= CXCursor_FirstInvalid && K <= CXCursor_LastInvalid;
4715}
4716
4717unsigned clang_isDeclaration(enum CXCursorKind K) {
4718 return (K >= CXCursor_FirstDecl && K <= CXCursor_LastDecl) ||
4719 (K >= CXCursor_FirstExtraDecl && K <= CXCursor_LastExtraDecl);
4720}
4721
4722unsigned clang_isReference(enum CXCursorKind K) {
4723 return K >= CXCursor_FirstRef && K <= CXCursor_LastRef;
4724}
4725
4726unsigned clang_isExpression(enum CXCursorKind K) {
4727 return K >= CXCursor_FirstExpr && K <= CXCursor_LastExpr;
4728}
4729
4730unsigned clang_isStatement(enum CXCursorKind K) {
4731 return K >= CXCursor_FirstStmt && K <= CXCursor_LastStmt;
4732}
4733
4734unsigned clang_isAttribute(enum CXCursorKind K) {
4735 return K >= CXCursor_FirstAttr && K <= CXCursor_LastAttr;
4736}
4737
4738unsigned clang_isTranslationUnit(enum CXCursorKind K) {
4739 return K == CXCursor_TranslationUnit;
4740}
4741
4742unsigned clang_isPreprocessing(enum CXCursorKind K) {
4743 return K >= CXCursor_FirstPreprocessing && K <= CXCursor_LastPreprocessing;
4744}
4745
4746unsigned clang_isUnexposed(enum CXCursorKind K) {
4747 switch (K) {
4748 case CXCursor_UnexposedDecl:
4749 case CXCursor_UnexposedExpr:
4750 case CXCursor_UnexposedStmt:
4751 case CXCursor_UnexposedAttr:
4752 return true;
4753 default:
4754 return false;
4755 }
4756}
4757
4758CXCursorKind clang_getCursorKind(CXCursor C) {
4759 return C.kind;
4760}
4761
4762CXSourceLocation clang_getCursorLocation(CXCursor C) {
4763 if (clang_isReference(C.kind)) {
4764 switch (C.kind) {
4765 case CXCursor_ObjCSuperClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004766 std::pair<const ObjCInterfaceDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004767 = getCursorObjCSuperClassRef(C);
4768 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4769 }
4770
4771 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004772 std::pair<const ObjCProtocolDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004773 = getCursorObjCProtocolRef(C);
4774 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4775 }
4776
4777 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004778 std::pair<const ObjCInterfaceDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004779 = getCursorObjCClassRef(C);
4780 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4781 }
4782
4783 case CXCursor_TypeRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004784 std::pair<const TypeDecl *, SourceLocation> P = getCursorTypeRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004785 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4786 }
4787
4788 case CXCursor_TemplateRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004789 std::pair<const TemplateDecl *, SourceLocation> P =
4790 getCursorTemplateRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004791 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4792 }
4793
4794 case CXCursor_NamespaceRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004795 std::pair<const NamedDecl *, SourceLocation> P = getCursorNamespaceRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004796 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4797 }
4798
4799 case CXCursor_MemberRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004800 std::pair<const FieldDecl *, SourceLocation> P = getCursorMemberRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004801 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4802 }
4803
4804 case CXCursor_VariableRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004805 std::pair<const VarDecl *, SourceLocation> P = getCursorVariableRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004806 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4807 }
4808
4809 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004810 const CXXBaseSpecifier *BaseSpec = getCursorCXXBaseSpecifier(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004811 if (!BaseSpec)
4812 return clang_getNullLocation();
4813
4814 if (TypeSourceInfo *TSInfo = BaseSpec->getTypeSourceInfo())
4815 return cxloc::translateSourceLocation(getCursorContext(C),
4816 TSInfo->getTypeLoc().getBeginLoc());
4817
4818 return cxloc::translateSourceLocation(getCursorContext(C),
4819 BaseSpec->getLocStart());
4820 }
4821
4822 case CXCursor_LabelRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004823 std::pair<const LabelStmt *, SourceLocation> P = getCursorLabelRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004824 return cxloc::translateSourceLocation(getCursorContext(C), P.second);
4825 }
4826
4827 case CXCursor_OverloadedDeclRef:
4828 return cxloc::translateSourceLocation(getCursorContext(C),
4829 getCursorOverloadedDeclRef(C).second);
4830
4831 default:
4832 // FIXME: Need a way to enumerate all non-reference cases.
4833 llvm_unreachable("Missed a reference kind");
4834 }
4835 }
4836
4837 if (clang_isExpression(C.kind))
4838 return cxloc::translateSourceLocation(getCursorContext(C),
4839 getLocationFromExpr(getCursorExpr(C)));
4840
4841 if (clang_isStatement(C.kind))
4842 return cxloc::translateSourceLocation(getCursorContext(C),
4843 getCursorStmt(C)->getLocStart());
4844
4845 if (C.kind == CXCursor_PreprocessingDirective) {
4846 SourceLocation L = cxcursor::getCursorPreprocessingDirective(C).getBegin();
4847 return cxloc::translateSourceLocation(getCursorContext(C), L);
4848 }
4849
4850 if (C.kind == CXCursor_MacroExpansion) {
4851 SourceLocation L
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00004852 = cxcursor::getCursorMacroExpansion(C).getSourceRange().getBegin();
Guy Benyei11169dd2012-12-18 14:30:41 +00004853 return cxloc::translateSourceLocation(getCursorContext(C), L);
4854 }
4855
4856 if (C.kind == CXCursor_MacroDefinition) {
4857 SourceLocation L = cxcursor::getCursorMacroDefinition(C)->getLocation();
4858 return cxloc::translateSourceLocation(getCursorContext(C), L);
4859 }
4860
4861 if (C.kind == CXCursor_InclusionDirective) {
4862 SourceLocation L
4863 = cxcursor::getCursorInclusionDirective(C)->getSourceRange().getBegin();
4864 return cxloc::translateSourceLocation(getCursorContext(C), L);
4865 }
4866
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00004867 if (clang_isAttribute(C.kind)) {
4868 SourceLocation L
4869 = cxcursor::getCursorAttr(C)->getLocation();
4870 return cxloc::translateSourceLocation(getCursorContext(C), L);
4871 }
4872
Guy Benyei11169dd2012-12-18 14:30:41 +00004873 if (!clang_isDeclaration(C.kind))
4874 return clang_getNullLocation();
4875
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004876 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004877 if (!D)
4878 return clang_getNullLocation();
4879
4880 SourceLocation Loc = D->getLocation();
4881 // FIXME: Multiple variables declared in a single declaration
4882 // currently lack the information needed to correctly determine their
4883 // ranges when accounting for the type-specifier. We use context
4884 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4885 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004886 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004887 if (!cxcursor::isFirstInDeclGroup(C))
4888 Loc = VD->getLocation();
4889 }
4890
4891 // For ObjC methods, give the start location of the method name.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004892 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004893 Loc = MD->getSelectorStartLoc();
4894
4895 return cxloc::translateSourceLocation(getCursorContext(C), Loc);
4896}
4897
4898} // end extern "C"
4899
4900CXCursor cxcursor::getCursor(CXTranslationUnit TU, SourceLocation SLoc) {
4901 assert(TU);
4902
4903 // Guard against an invalid SourceLocation, or we may assert in one
4904 // of the following calls.
4905 if (SLoc.isInvalid())
4906 return clang_getNullCursor();
4907
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004908 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004909
4910 // Translate the given source location to make it point at the beginning of
4911 // the token under the cursor.
4912 SLoc = Lexer::GetBeginningOfToken(SLoc, CXXUnit->getSourceManager(),
4913 CXXUnit->getASTContext().getLangOpts());
4914
4915 CXCursor Result = MakeCXCursorInvalid(CXCursor_NoDeclFound);
4916 if (SLoc.isValid()) {
4917 GetCursorData ResultData(CXXUnit->getSourceManager(), SLoc, Result);
4918 CursorVisitor CursorVis(TU, GetCursorVisitor, &ResultData,
4919 /*VisitPreprocessorLast=*/true,
4920 /*VisitIncludedEntities=*/false,
4921 SourceLocation(SLoc));
4922 CursorVis.visitFileRegion();
4923 }
4924
4925 return Result;
4926}
4927
4928static SourceRange getRawCursorExtent(CXCursor C) {
4929 if (clang_isReference(C.kind)) {
4930 switch (C.kind) {
4931 case CXCursor_ObjCSuperClassRef:
4932 return getCursorObjCSuperClassRef(C).second;
4933
4934 case CXCursor_ObjCProtocolRef:
4935 return getCursorObjCProtocolRef(C).second;
4936
4937 case CXCursor_ObjCClassRef:
4938 return getCursorObjCClassRef(C).second;
4939
4940 case CXCursor_TypeRef:
4941 return getCursorTypeRef(C).second;
4942
4943 case CXCursor_TemplateRef:
4944 return getCursorTemplateRef(C).second;
4945
4946 case CXCursor_NamespaceRef:
4947 return getCursorNamespaceRef(C).second;
4948
4949 case CXCursor_MemberRef:
4950 return getCursorMemberRef(C).second;
4951
4952 case CXCursor_CXXBaseSpecifier:
4953 return getCursorCXXBaseSpecifier(C)->getSourceRange();
4954
4955 case CXCursor_LabelRef:
4956 return getCursorLabelRef(C).second;
4957
4958 case CXCursor_OverloadedDeclRef:
4959 return getCursorOverloadedDeclRef(C).second;
4960
4961 case CXCursor_VariableRef:
4962 return getCursorVariableRef(C).second;
4963
4964 default:
4965 // FIXME: Need a way to enumerate all non-reference cases.
4966 llvm_unreachable("Missed a reference kind");
4967 }
4968 }
4969
4970 if (clang_isExpression(C.kind))
4971 return getCursorExpr(C)->getSourceRange();
4972
4973 if (clang_isStatement(C.kind))
4974 return getCursorStmt(C)->getSourceRange();
4975
4976 if (clang_isAttribute(C.kind))
4977 return getCursorAttr(C)->getRange();
4978
4979 if (C.kind == CXCursor_PreprocessingDirective)
4980 return cxcursor::getCursorPreprocessingDirective(C);
4981
4982 if (C.kind == CXCursor_MacroExpansion) {
4983 ASTUnit *TU = getCursorASTUnit(C);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00004984 SourceRange Range = cxcursor::getCursorMacroExpansion(C).getSourceRange();
Guy Benyei11169dd2012-12-18 14:30:41 +00004985 return TU->mapRangeFromPreamble(Range);
4986 }
4987
4988 if (C.kind == CXCursor_MacroDefinition) {
4989 ASTUnit *TU = getCursorASTUnit(C);
4990 SourceRange Range = cxcursor::getCursorMacroDefinition(C)->getSourceRange();
4991 return TU->mapRangeFromPreamble(Range);
4992 }
4993
4994 if (C.kind == CXCursor_InclusionDirective) {
4995 ASTUnit *TU = getCursorASTUnit(C);
4996 SourceRange Range = cxcursor::getCursorInclusionDirective(C)->getSourceRange();
4997 return TU->mapRangeFromPreamble(Range);
4998 }
4999
5000 if (C.kind == CXCursor_TranslationUnit) {
5001 ASTUnit *TU = getCursorASTUnit(C);
5002 FileID MainID = TU->getSourceManager().getMainFileID();
5003 SourceLocation Start = TU->getSourceManager().getLocForStartOfFile(MainID);
5004 SourceLocation End = TU->getSourceManager().getLocForEndOfFile(MainID);
5005 return SourceRange(Start, End);
5006 }
5007
5008 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005009 const Decl *D = cxcursor::getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005010 if (!D)
5011 return SourceRange();
5012
5013 SourceRange R = D->getSourceRange();
5014 // FIXME: Multiple variables declared in a single declaration
5015 // currently lack the information needed to correctly determine their
5016 // ranges when accounting for the type-specifier. We use context
5017 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
5018 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005019 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005020 if (!cxcursor::isFirstInDeclGroup(C))
5021 R.setBegin(VD->getLocation());
5022 }
5023 return R;
5024 }
5025 return SourceRange();
5026}
5027
5028/// \brief Retrieves the "raw" cursor extent, which is then extended to include
5029/// the decl-specifier-seq for declarations.
5030static SourceRange getFullCursorExtent(CXCursor C, SourceManager &SrcMgr) {
5031 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005032 const Decl *D = cxcursor::getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005033 if (!D)
5034 return SourceRange();
5035
5036 SourceRange R = D->getSourceRange();
5037
5038 // Adjust the start of the location for declarations preceded by
5039 // declaration specifiers.
5040 SourceLocation StartLoc;
5041 if (const DeclaratorDecl *DD = dyn_cast<DeclaratorDecl>(D)) {
5042 if (TypeSourceInfo *TI = DD->getTypeSourceInfo())
5043 StartLoc = TI->getTypeLoc().getLocStart();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005044 } else if (const TypedefDecl *Typedef = dyn_cast<TypedefDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005045 if (TypeSourceInfo *TI = Typedef->getTypeSourceInfo())
5046 StartLoc = TI->getTypeLoc().getLocStart();
5047 }
5048
5049 if (StartLoc.isValid() && R.getBegin().isValid() &&
5050 SrcMgr.isBeforeInTranslationUnit(StartLoc, R.getBegin()))
5051 R.setBegin(StartLoc);
5052
5053 // FIXME: Multiple variables declared in a single declaration
5054 // currently lack the information needed to correctly determine their
5055 // ranges when accounting for the type-specifier. We use context
5056 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
5057 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005058 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005059 if (!cxcursor::isFirstInDeclGroup(C))
5060 R.setBegin(VD->getLocation());
5061 }
5062
5063 return R;
5064 }
5065
5066 return getRawCursorExtent(C);
5067}
5068
5069extern "C" {
5070
5071CXSourceRange clang_getCursorExtent(CXCursor C) {
5072 SourceRange R = getRawCursorExtent(C);
5073 if (R.isInvalid())
5074 return clang_getNullRange();
5075
5076 return cxloc::translateSourceRange(getCursorContext(C), R);
5077}
5078
5079CXCursor clang_getCursorReferenced(CXCursor C) {
5080 if (clang_isInvalid(C.kind))
5081 return clang_getNullCursor();
5082
5083 CXTranslationUnit tu = getCursorTU(C);
5084 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005085 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005086 if (!D)
5087 return clang_getNullCursor();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005088 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00005089 return MakeCursorOverloadedDeclRef(Using, D->getLocation(), tu);
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005090 if (const ObjCPropertyImplDecl *PropImpl =
5091 dyn_cast<ObjCPropertyImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00005092 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
5093 return MakeCXCursor(Property, tu);
5094
5095 return C;
5096 }
5097
5098 if (clang_isExpression(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005099 const Expr *E = getCursorExpr(C);
5100 const Decl *D = getDeclFromExpr(E);
Guy Benyei11169dd2012-12-18 14:30:41 +00005101 if (D) {
5102 CXCursor declCursor = MakeCXCursor(D, tu);
5103 declCursor = getSelectorIdentifierCursor(getSelectorIdentifierIndex(C),
5104 declCursor);
5105 return declCursor;
5106 }
5107
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005108 if (const OverloadExpr *Ovl = dyn_cast_or_null<OverloadExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00005109 return MakeCursorOverloadedDeclRef(Ovl, tu);
5110
5111 return clang_getNullCursor();
5112 }
5113
5114 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005115 const Stmt *S = getCursorStmt(C);
5116 if (const GotoStmt *Goto = dyn_cast_or_null<GotoStmt>(S))
Guy Benyei11169dd2012-12-18 14:30:41 +00005117 if (LabelDecl *label = Goto->getLabel())
5118 if (LabelStmt *labelS = label->getStmt())
5119 return MakeCXCursor(labelS, getCursorDecl(C), tu);
5120
5121 return clang_getNullCursor();
5122 }
Richard Smith66a81862015-05-04 02:25:31 +00005123
Guy Benyei11169dd2012-12-18 14:30:41 +00005124 if (C.kind == CXCursor_MacroExpansion) {
Richard Smith66a81862015-05-04 02:25:31 +00005125 if (const MacroDefinitionRecord *Def =
5126 getCursorMacroExpansion(C).getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005127 return MakeMacroDefinitionCursor(Def, tu);
5128 }
5129
5130 if (!clang_isReference(C.kind))
5131 return clang_getNullCursor();
5132
5133 switch (C.kind) {
5134 case CXCursor_ObjCSuperClassRef:
5135 return MakeCXCursor(getCursorObjCSuperClassRef(C).first, tu);
5136
5137 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005138 const ObjCProtocolDecl *Prot = getCursorObjCProtocolRef(C).first;
5139 if (const ObjCProtocolDecl *Def = Prot->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005140 return MakeCXCursor(Def, tu);
5141
5142 return MakeCXCursor(Prot, tu);
5143 }
5144
5145 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005146 const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
5147 if (const ObjCInterfaceDecl *Def = Class->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005148 return MakeCXCursor(Def, tu);
5149
5150 return MakeCXCursor(Class, tu);
5151 }
5152
5153 case CXCursor_TypeRef:
5154 return MakeCXCursor(getCursorTypeRef(C).first, tu );
5155
5156 case CXCursor_TemplateRef:
5157 return MakeCXCursor(getCursorTemplateRef(C).first, tu );
5158
5159 case CXCursor_NamespaceRef:
5160 return MakeCXCursor(getCursorNamespaceRef(C).first, tu );
5161
5162 case CXCursor_MemberRef:
5163 return MakeCXCursor(getCursorMemberRef(C).first, tu );
5164
5165 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005166 const CXXBaseSpecifier *B = cxcursor::getCursorCXXBaseSpecifier(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005167 return clang_getTypeDeclaration(cxtype::MakeCXType(B->getType(),
5168 tu ));
5169 }
5170
5171 case CXCursor_LabelRef:
5172 // FIXME: We end up faking the "parent" declaration here because we
5173 // don't want to make CXCursor larger.
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005174 return MakeCXCursor(getCursorLabelRef(C).first,
5175 cxtu::getASTUnit(tu)->getASTContext()
5176 .getTranslationUnitDecl(),
Guy Benyei11169dd2012-12-18 14:30:41 +00005177 tu);
5178
5179 case CXCursor_OverloadedDeclRef:
5180 return C;
5181
5182 case CXCursor_VariableRef:
5183 return MakeCXCursor(getCursorVariableRef(C).first, tu);
5184
5185 default:
5186 // We would prefer to enumerate all non-reference cursor kinds here.
5187 llvm_unreachable("Unhandled reference cursor kind");
5188 }
5189}
5190
5191CXCursor clang_getCursorDefinition(CXCursor C) {
5192 if (clang_isInvalid(C.kind))
5193 return clang_getNullCursor();
5194
5195 CXTranslationUnit TU = getCursorTU(C);
5196
5197 bool WasReference = false;
5198 if (clang_isReference(C.kind) || clang_isExpression(C.kind)) {
5199 C = clang_getCursorReferenced(C);
5200 WasReference = true;
5201 }
5202
5203 if (C.kind == CXCursor_MacroExpansion)
5204 return clang_getCursorReferenced(C);
5205
5206 if (!clang_isDeclaration(C.kind))
5207 return clang_getNullCursor();
5208
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005209 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005210 if (!D)
5211 return clang_getNullCursor();
5212
5213 switch (D->getKind()) {
5214 // Declaration kinds that don't really separate the notions of
5215 // declaration and definition.
5216 case Decl::Namespace:
5217 case Decl::Typedef:
5218 case Decl::TypeAlias:
5219 case Decl::TypeAliasTemplate:
5220 case Decl::TemplateTypeParm:
5221 case Decl::EnumConstant:
5222 case Decl::Field:
John McCall5e77d762013-04-16 07:28:30 +00005223 case Decl::MSProperty:
Guy Benyei11169dd2012-12-18 14:30:41 +00005224 case Decl::IndirectField:
5225 case Decl::ObjCIvar:
5226 case Decl::ObjCAtDefsField:
5227 case Decl::ImplicitParam:
5228 case Decl::ParmVar:
5229 case Decl::NonTypeTemplateParm:
5230 case Decl::TemplateTemplateParm:
5231 case Decl::ObjCCategoryImpl:
5232 case Decl::ObjCImplementation:
5233 case Decl::AccessSpec:
5234 case Decl::LinkageSpec:
5235 case Decl::ObjCPropertyImpl:
5236 case Decl::FileScopeAsm:
5237 case Decl::StaticAssert:
5238 case Decl::Block:
Tareq A. Siraj6dfa25a2013-04-16 19:37:38 +00005239 case Decl::Captured:
Guy Benyei11169dd2012-12-18 14:30:41 +00005240 case Decl::Label: // FIXME: Is this right??
5241 case Decl::ClassScopeFunctionSpecialization:
5242 case Decl::Import:
Alexey Bataeva769e072013-03-22 06:34:35 +00005243 case Decl::OMPThreadPrivate:
Douglas Gregor85f3f952015-07-07 03:57:15 +00005244 case Decl::ObjCTypeParam:
David Majnemerd9b1a4f2015-11-04 03:40:30 +00005245 case Decl::BuiltinTemplate:
Guy Benyei11169dd2012-12-18 14:30:41 +00005246 return C;
5247
5248 // Declaration kinds that don't make any sense here, but are
5249 // nonetheless harmless.
David Blaikief005d3c2013-02-22 17:44:58 +00005250 case Decl::Empty:
Guy Benyei11169dd2012-12-18 14:30:41 +00005251 case Decl::TranslationUnit:
Richard Smithf19e1272015-03-07 00:04:49 +00005252 case Decl::ExternCContext:
Guy Benyei11169dd2012-12-18 14:30:41 +00005253 break;
5254
5255 // Declaration kinds for which the definition is not resolvable.
5256 case Decl::UnresolvedUsingTypename:
5257 case Decl::UnresolvedUsingValue:
5258 break;
5259
5260 case Decl::UsingDirective:
5261 return MakeCXCursor(cast<UsingDirectiveDecl>(D)->getNominatedNamespace(),
5262 TU);
5263
5264 case Decl::NamespaceAlias:
5265 return MakeCXCursor(cast<NamespaceAliasDecl>(D)->getNamespace(), TU);
5266
5267 case Decl::Enum:
5268 case Decl::Record:
5269 case Decl::CXXRecord:
5270 case Decl::ClassTemplateSpecialization:
5271 case Decl::ClassTemplatePartialSpecialization:
5272 if (TagDecl *Def = cast<TagDecl>(D)->getDefinition())
5273 return MakeCXCursor(Def, TU);
5274 return clang_getNullCursor();
5275
5276 case Decl::Function:
5277 case Decl::CXXMethod:
5278 case Decl::CXXConstructor:
5279 case Decl::CXXDestructor:
5280 case Decl::CXXConversion: {
Craig Topper69186e72014-06-08 08:38:04 +00005281 const FunctionDecl *Def = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005282 if (cast<FunctionDecl>(D)->getBody(Def))
Dmitri Gribenko9c256e32013-01-14 00:46:27 +00005283 return MakeCXCursor(Def, TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005284 return clang_getNullCursor();
5285 }
5286
Larisse Voufo39a1e502013-08-06 01:03:05 +00005287 case Decl::Var:
5288 case Decl::VarTemplateSpecialization:
5289 case Decl::VarTemplatePartialSpecialization: {
Guy Benyei11169dd2012-12-18 14:30:41 +00005290 // Ask the variable if it has a definition.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005291 if (const VarDecl *Def = cast<VarDecl>(D)->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005292 return MakeCXCursor(Def, TU);
5293 return clang_getNullCursor();
5294 }
5295
5296 case Decl::FunctionTemplate: {
Craig Topper69186e72014-06-08 08:38:04 +00005297 const FunctionDecl *Def = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005298 if (cast<FunctionTemplateDecl>(D)->getTemplatedDecl()->getBody(Def))
5299 return MakeCXCursor(Def->getDescribedFunctionTemplate(), TU);
5300 return clang_getNullCursor();
5301 }
5302
5303 case Decl::ClassTemplate: {
5304 if (RecordDecl *Def = cast<ClassTemplateDecl>(D)->getTemplatedDecl()
5305 ->getDefinition())
5306 return MakeCXCursor(cast<CXXRecordDecl>(Def)->getDescribedClassTemplate(),
5307 TU);
5308 return clang_getNullCursor();
5309 }
5310
Larisse Voufo39a1e502013-08-06 01:03:05 +00005311 case Decl::VarTemplate: {
5312 if (VarDecl *Def =
5313 cast<VarTemplateDecl>(D)->getTemplatedDecl()->getDefinition())
5314 return MakeCXCursor(cast<VarDecl>(Def)->getDescribedVarTemplate(), TU);
5315 return clang_getNullCursor();
5316 }
5317
Guy Benyei11169dd2012-12-18 14:30:41 +00005318 case Decl::Using:
5319 return MakeCursorOverloadedDeclRef(cast<UsingDecl>(D),
5320 D->getLocation(), TU);
5321
5322 case Decl::UsingShadow:
5323 return clang_getCursorDefinition(
5324 MakeCXCursor(cast<UsingShadowDecl>(D)->getTargetDecl(),
5325 TU));
5326
5327 case Decl::ObjCMethod: {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005328 const ObjCMethodDecl *Method = cast<ObjCMethodDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00005329 if (Method->isThisDeclarationADefinition())
5330 return C;
5331
5332 // Dig out the method definition in the associated
5333 // @implementation, if we have it.
5334 // FIXME: The ASTs should make finding the definition easier.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005335 if (const ObjCInterfaceDecl *Class
Guy Benyei11169dd2012-12-18 14:30:41 +00005336 = dyn_cast<ObjCInterfaceDecl>(Method->getDeclContext()))
5337 if (ObjCImplementationDecl *ClassImpl = Class->getImplementation())
5338 if (ObjCMethodDecl *Def = ClassImpl->getMethod(Method->getSelector(),
5339 Method->isInstanceMethod()))
5340 if (Def->isThisDeclarationADefinition())
5341 return MakeCXCursor(Def, TU);
5342
5343 return clang_getNullCursor();
5344 }
5345
5346 case Decl::ObjCCategory:
5347 if (ObjCCategoryImplDecl *Impl
5348 = cast<ObjCCategoryDecl>(D)->getImplementation())
5349 return MakeCXCursor(Impl, TU);
5350 return clang_getNullCursor();
5351
5352 case Decl::ObjCProtocol:
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005353 if (const ObjCProtocolDecl *Def = cast<ObjCProtocolDecl>(D)->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005354 return MakeCXCursor(Def, TU);
5355 return clang_getNullCursor();
5356
5357 case Decl::ObjCInterface: {
5358 // There are two notions of a "definition" for an Objective-C
5359 // class: the interface and its implementation. When we resolved a
5360 // reference to an Objective-C class, produce the @interface as
5361 // the definition; when we were provided with the interface,
5362 // produce the @implementation as the definition.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005363 const ObjCInterfaceDecl *IFace = cast<ObjCInterfaceDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00005364 if (WasReference) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005365 if (const ObjCInterfaceDecl *Def = IFace->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005366 return MakeCXCursor(Def, TU);
5367 } else if (ObjCImplementationDecl *Impl = IFace->getImplementation())
5368 return MakeCXCursor(Impl, TU);
5369 return clang_getNullCursor();
5370 }
5371
5372 case Decl::ObjCProperty:
5373 // FIXME: We don't really know where to find the
5374 // ObjCPropertyImplDecls that implement this property.
5375 return clang_getNullCursor();
5376
5377 case Decl::ObjCCompatibleAlias:
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005378 if (const ObjCInterfaceDecl *Class
Guy Benyei11169dd2012-12-18 14:30:41 +00005379 = cast<ObjCCompatibleAliasDecl>(D)->getClassInterface())
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005380 if (const ObjCInterfaceDecl *Def = Class->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005381 return MakeCXCursor(Def, TU);
5382
5383 return clang_getNullCursor();
5384
5385 case Decl::Friend:
5386 if (NamedDecl *Friend = cast<FriendDecl>(D)->getFriendDecl())
5387 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
5388 return clang_getNullCursor();
5389
5390 case Decl::FriendTemplate:
5391 if (NamedDecl *Friend = cast<FriendTemplateDecl>(D)->getFriendDecl())
5392 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
5393 return clang_getNullCursor();
5394 }
5395
5396 return clang_getNullCursor();
5397}
5398
5399unsigned clang_isCursorDefinition(CXCursor C) {
5400 if (!clang_isDeclaration(C.kind))
5401 return 0;
5402
5403 return clang_getCursorDefinition(C) == C;
5404}
5405
5406CXCursor clang_getCanonicalCursor(CXCursor C) {
5407 if (!clang_isDeclaration(C.kind))
5408 return C;
5409
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005410 if (const Decl *D = getCursorDecl(C)) {
5411 if (const ObjCCategoryImplDecl *CatImplD = dyn_cast<ObjCCategoryImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00005412 if (ObjCCategoryDecl *CatD = CatImplD->getCategoryDecl())
5413 return MakeCXCursor(CatD, getCursorTU(C));
5414
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005415 if (const ObjCImplDecl *ImplD = dyn_cast<ObjCImplDecl>(D))
5416 if (const ObjCInterfaceDecl *IFD = ImplD->getClassInterface())
Guy Benyei11169dd2012-12-18 14:30:41 +00005417 return MakeCXCursor(IFD, getCursorTU(C));
5418
5419 return MakeCXCursor(D->getCanonicalDecl(), getCursorTU(C));
5420 }
5421
5422 return C;
5423}
5424
5425int clang_Cursor_getObjCSelectorIndex(CXCursor cursor) {
5426 return cxcursor::getSelectorIdentifierIndexAndLoc(cursor).first;
5427}
5428
5429unsigned clang_getNumOverloadedDecls(CXCursor C) {
5430 if (C.kind != CXCursor_OverloadedDeclRef)
5431 return 0;
5432
5433 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005434 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Guy Benyei11169dd2012-12-18 14:30:41 +00005435 return E->getNumDecls();
5436
5437 if (OverloadedTemplateStorage *S
5438 = Storage.dyn_cast<OverloadedTemplateStorage*>())
5439 return S->size();
5440
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005441 const Decl *D = Storage.get<const Decl *>();
5442 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00005443 return Using->shadow_size();
5444
5445 return 0;
5446}
5447
5448CXCursor clang_getOverloadedDecl(CXCursor cursor, unsigned index) {
5449 if (cursor.kind != CXCursor_OverloadedDeclRef)
5450 return clang_getNullCursor();
5451
5452 if (index >= clang_getNumOverloadedDecls(cursor))
5453 return clang_getNullCursor();
5454
5455 CXTranslationUnit TU = getCursorTU(cursor);
5456 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(cursor).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005457 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Guy Benyei11169dd2012-12-18 14:30:41 +00005458 return MakeCXCursor(E->decls_begin()[index], TU);
5459
5460 if (OverloadedTemplateStorage *S
5461 = Storage.dyn_cast<OverloadedTemplateStorage*>())
5462 return MakeCXCursor(S->begin()[index], TU);
5463
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005464 const Decl *D = Storage.get<const Decl *>();
5465 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005466 // FIXME: This is, unfortunately, linear time.
5467 UsingDecl::shadow_iterator Pos = Using->shadow_begin();
5468 std::advance(Pos, index);
5469 return MakeCXCursor(cast<UsingShadowDecl>(*Pos)->getTargetDecl(), TU);
5470 }
5471
5472 return clang_getNullCursor();
5473}
5474
5475void clang_getDefinitionSpellingAndExtent(CXCursor C,
5476 const char **startBuf,
5477 const char **endBuf,
5478 unsigned *startLine,
5479 unsigned *startColumn,
5480 unsigned *endLine,
5481 unsigned *endColumn) {
5482 assert(getCursorDecl(C) && "CXCursor has null decl");
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005483 const FunctionDecl *FD = dyn_cast<FunctionDecl>(getCursorDecl(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00005484 CompoundStmt *Body = dyn_cast<CompoundStmt>(FD->getBody());
5485
5486 SourceManager &SM = FD->getASTContext().getSourceManager();
5487 *startBuf = SM.getCharacterData(Body->getLBracLoc());
5488 *endBuf = SM.getCharacterData(Body->getRBracLoc());
5489 *startLine = SM.getSpellingLineNumber(Body->getLBracLoc());
5490 *startColumn = SM.getSpellingColumnNumber(Body->getLBracLoc());
5491 *endLine = SM.getSpellingLineNumber(Body->getRBracLoc());
5492 *endColumn = SM.getSpellingColumnNumber(Body->getRBracLoc());
5493}
5494
5495
5496CXSourceRange clang_getCursorReferenceNameRange(CXCursor C, unsigned NameFlags,
5497 unsigned PieceIndex) {
5498 RefNamePieces Pieces;
5499
5500 switch (C.kind) {
5501 case CXCursor_MemberRefExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005502 if (const MemberExpr *E = dyn_cast<MemberExpr>(getCursorExpr(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00005503 Pieces = buildPieces(NameFlags, true, E->getMemberNameInfo(),
5504 E->getQualifierLoc().getSourceRange());
5505 break;
5506
5507 case CXCursor_DeclRefExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005508 if (const DeclRefExpr *E = dyn_cast<DeclRefExpr>(getCursorExpr(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00005509 Pieces = buildPieces(NameFlags, false, E->getNameInfo(),
5510 E->getQualifierLoc().getSourceRange(),
5511 E->getOptionalExplicitTemplateArgs());
5512 break;
5513
5514 case CXCursor_CallExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005515 if (const CXXOperatorCallExpr *OCE =
Guy Benyei11169dd2012-12-18 14:30:41 +00005516 dyn_cast<CXXOperatorCallExpr>(getCursorExpr(C))) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005517 const Expr *Callee = OCE->getCallee();
5518 if (const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Callee))
Guy Benyei11169dd2012-12-18 14:30:41 +00005519 Callee = ICE->getSubExpr();
5520
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005521 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(Callee))
Guy Benyei11169dd2012-12-18 14:30:41 +00005522 Pieces = buildPieces(NameFlags, false, DRE->getNameInfo(),
5523 DRE->getQualifierLoc().getSourceRange());
5524 }
5525 break;
5526
5527 default:
5528 break;
5529 }
5530
5531 if (Pieces.empty()) {
5532 if (PieceIndex == 0)
5533 return clang_getCursorExtent(C);
5534 } else if (PieceIndex < Pieces.size()) {
5535 SourceRange R = Pieces[PieceIndex];
5536 if (R.isValid())
5537 return cxloc::translateSourceRange(getCursorContext(C), R);
5538 }
5539
5540 return clang_getNullRange();
5541}
5542
5543void clang_enableStackTraces(void) {
5544 llvm::sys::PrintStackTraceOnErrorSignal();
5545}
5546
5547void clang_executeOnThread(void (*fn)(void*), void *user_data,
5548 unsigned stack_size) {
5549 llvm::llvm_execute_on_thread(fn, user_data, stack_size);
5550}
5551
5552} // end: extern "C"
5553
5554//===----------------------------------------------------------------------===//
5555// Token-based Operations.
5556//===----------------------------------------------------------------------===//
5557
5558/* CXToken layout:
5559 * int_data[0]: a CXTokenKind
5560 * int_data[1]: starting token location
5561 * int_data[2]: token length
5562 * int_data[3]: reserved
5563 * ptr_data: for identifiers and keywords, an IdentifierInfo*.
5564 * otherwise unused.
5565 */
5566extern "C" {
5567
5568CXTokenKind clang_getTokenKind(CXToken CXTok) {
5569 return static_cast<CXTokenKind>(CXTok.int_data[0]);
5570}
5571
5572CXString clang_getTokenSpelling(CXTranslationUnit TU, CXToken CXTok) {
5573 switch (clang_getTokenKind(CXTok)) {
5574 case CXToken_Identifier:
5575 case CXToken_Keyword:
5576 // We know we have an IdentifierInfo*, so use that.
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005577 return cxstring::createRef(static_cast<IdentifierInfo *>(CXTok.ptr_data)
Guy Benyei11169dd2012-12-18 14:30:41 +00005578 ->getNameStart());
5579
5580 case CXToken_Literal: {
5581 // We have stashed the starting pointer in the ptr_data field. Use it.
5582 const char *Text = static_cast<const char *>(CXTok.ptr_data);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00005583 return cxstring::createDup(StringRef(Text, CXTok.int_data[2]));
Guy Benyei11169dd2012-12-18 14:30:41 +00005584 }
5585
5586 case CXToken_Punctuation:
5587 case CXToken_Comment:
5588 break;
5589 }
5590
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005591 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005592 LOG_BAD_TU(TU);
5593 return cxstring::createEmpty();
5594 }
5595
Guy Benyei11169dd2012-12-18 14:30:41 +00005596 // We have to find the starting buffer pointer the hard way, by
5597 // deconstructing the source location.
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005598 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005599 if (!CXXUnit)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00005600 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00005601
5602 SourceLocation Loc = SourceLocation::getFromRawEncoding(CXTok.int_data[1]);
5603 std::pair<FileID, unsigned> LocInfo
5604 = CXXUnit->getSourceManager().getDecomposedSpellingLoc(Loc);
5605 bool Invalid = false;
5606 StringRef Buffer
5607 = CXXUnit->getSourceManager().getBufferData(LocInfo.first, &Invalid);
5608 if (Invalid)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00005609 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00005610
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00005611 return cxstring::createDup(Buffer.substr(LocInfo.second, CXTok.int_data[2]));
Guy Benyei11169dd2012-12-18 14:30:41 +00005612}
5613
5614CXSourceLocation clang_getTokenLocation(CXTranslationUnit TU, CXToken CXTok) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005615 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005616 LOG_BAD_TU(TU);
5617 return clang_getNullLocation();
5618 }
5619
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005620 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005621 if (!CXXUnit)
5622 return clang_getNullLocation();
5623
5624 return cxloc::translateSourceLocation(CXXUnit->getASTContext(),
5625 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
5626}
5627
5628CXSourceRange clang_getTokenExtent(CXTranslationUnit TU, CXToken CXTok) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005629 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005630 LOG_BAD_TU(TU);
5631 return clang_getNullRange();
5632 }
5633
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005634 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005635 if (!CXXUnit)
5636 return clang_getNullRange();
5637
5638 return cxloc::translateSourceRange(CXXUnit->getASTContext(),
5639 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
5640}
5641
5642static void getTokens(ASTUnit *CXXUnit, SourceRange Range,
5643 SmallVectorImpl<CXToken> &CXTokens) {
5644 SourceManager &SourceMgr = CXXUnit->getSourceManager();
5645 std::pair<FileID, unsigned> BeginLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005646 = SourceMgr.getDecomposedSpellingLoc(Range.getBegin());
Guy Benyei11169dd2012-12-18 14:30:41 +00005647 std::pair<FileID, unsigned> EndLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005648 = SourceMgr.getDecomposedSpellingLoc(Range.getEnd());
Guy Benyei11169dd2012-12-18 14:30:41 +00005649
5650 // Cannot tokenize across files.
5651 if (BeginLocInfo.first != EndLocInfo.first)
5652 return;
5653
5654 // Create a lexer
5655 bool Invalid = false;
5656 StringRef Buffer
5657 = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
5658 if (Invalid)
5659 return;
5660
5661 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
5662 CXXUnit->getASTContext().getLangOpts(),
5663 Buffer.begin(), Buffer.data() + BeginLocInfo.second, Buffer.end());
5664 Lex.SetCommentRetentionState(true);
5665
5666 // Lex tokens until we hit the end of the range.
5667 const char *EffectiveBufferEnd = Buffer.data() + EndLocInfo.second;
5668 Token Tok;
5669 bool previousWasAt = false;
5670 do {
5671 // Lex the next token
5672 Lex.LexFromRawLexer(Tok);
5673 if (Tok.is(tok::eof))
5674 break;
5675
5676 // Initialize the CXToken.
5677 CXToken CXTok;
5678
5679 // - Common fields
5680 CXTok.int_data[1] = Tok.getLocation().getRawEncoding();
5681 CXTok.int_data[2] = Tok.getLength();
5682 CXTok.int_data[3] = 0;
5683
5684 // - Kind-specific fields
5685 if (Tok.isLiteral()) {
5686 CXTok.int_data[0] = CXToken_Literal;
Dmitri Gribenkof9304482013-01-23 15:56:07 +00005687 CXTok.ptr_data = const_cast<char *>(Tok.getLiteralData());
Guy Benyei11169dd2012-12-18 14:30:41 +00005688 } else if (Tok.is(tok::raw_identifier)) {
5689 // Lookup the identifier to determine whether we have a keyword.
5690 IdentifierInfo *II
5691 = CXXUnit->getPreprocessor().LookUpIdentifierInfo(Tok);
5692
5693 if ((II->getObjCKeywordID() != tok::objc_not_keyword) && previousWasAt) {
5694 CXTok.int_data[0] = CXToken_Keyword;
5695 }
5696 else {
5697 CXTok.int_data[0] = Tok.is(tok::identifier)
5698 ? CXToken_Identifier
5699 : CXToken_Keyword;
5700 }
5701 CXTok.ptr_data = II;
5702 } else if (Tok.is(tok::comment)) {
5703 CXTok.int_data[0] = CXToken_Comment;
Craig Topper69186e72014-06-08 08:38:04 +00005704 CXTok.ptr_data = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005705 } else {
5706 CXTok.int_data[0] = CXToken_Punctuation;
Craig Topper69186e72014-06-08 08:38:04 +00005707 CXTok.ptr_data = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005708 }
5709 CXTokens.push_back(CXTok);
5710 previousWasAt = Tok.is(tok::at);
5711 } while (Lex.getBufferLocation() <= EffectiveBufferEnd);
5712}
5713
5714void clang_tokenize(CXTranslationUnit TU, CXSourceRange Range,
5715 CXToken **Tokens, unsigned *NumTokens) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00005716 LOG_FUNC_SECTION {
5717 *Log << TU << ' ' << Range;
5718 }
5719
Guy Benyei11169dd2012-12-18 14:30:41 +00005720 if (Tokens)
Craig Topper69186e72014-06-08 08:38:04 +00005721 *Tokens = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005722 if (NumTokens)
5723 *NumTokens = 0;
5724
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005725 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005726 LOG_BAD_TU(TU);
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00005727 return;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005728 }
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00005729
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005730 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005731 if (!CXXUnit || !Tokens || !NumTokens)
5732 return;
5733
5734 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
5735
5736 SourceRange R = cxloc::translateCXSourceRange(Range);
5737 if (R.isInvalid())
5738 return;
5739
5740 SmallVector<CXToken, 32> CXTokens;
5741 getTokens(CXXUnit, R, CXTokens);
5742
5743 if (CXTokens.empty())
5744 return;
5745
5746 *Tokens = (CXToken *)malloc(sizeof(CXToken) * CXTokens.size());
5747 memmove(*Tokens, CXTokens.data(), sizeof(CXToken) * CXTokens.size());
5748 *NumTokens = CXTokens.size();
5749}
5750
5751void clang_disposeTokens(CXTranslationUnit TU,
5752 CXToken *Tokens, unsigned NumTokens) {
5753 free(Tokens);
5754}
5755
5756} // end: extern "C"
5757
5758//===----------------------------------------------------------------------===//
5759// Token annotation APIs.
5760//===----------------------------------------------------------------------===//
5761
Guy Benyei11169dd2012-12-18 14:30:41 +00005762static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
5763 CXCursor parent,
5764 CXClientData client_data);
5765static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
5766 CXClientData client_data);
5767
5768namespace {
5769class AnnotateTokensWorker {
Guy Benyei11169dd2012-12-18 14:30:41 +00005770 CXToken *Tokens;
5771 CXCursor *Cursors;
5772 unsigned NumTokens;
5773 unsigned TokIdx;
5774 unsigned PreprocessingTokIdx;
5775 CursorVisitor AnnotateVis;
5776 SourceManager &SrcMgr;
5777 bool HasContextSensitiveKeywords;
5778
5779 struct PostChildrenInfo {
5780 CXCursor Cursor;
5781 SourceRange CursorRange;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005782 unsigned BeforeReachingCursorIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00005783 unsigned BeforeChildrenTokenIdx;
5784 };
Dmitri Gribenkof8579502013-01-12 19:30:44 +00005785 SmallVector<PostChildrenInfo, 8> PostChildrenInfos;
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005786
5787 CXToken &getTok(unsigned Idx) {
5788 assert(Idx < NumTokens);
5789 return Tokens[Idx];
5790 }
5791 const CXToken &getTok(unsigned Idx) const {
5792 assert(Idx < NumTokens);
5793 return Tokens[Idx];
5794 }
Guy Benyei11169dd2012-12-18 14:30:41 +00005795 bool MoreTokens() const { return TokIdx < NumTokens; }
5796 unsigned NextToken() const { return TokIdx; }
5797 void AdvanceToken() { ++TokIdx; }
5798 SourceLocation GetTokenLoc(unsigned tokI) {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005799 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[1]);
Guy Benyei11169dd2012-12-18 14:30:41 +00005800 }
5801 bool isFunctionMacroToken(unsigned tokI) const {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005802 return getTok(tokI).int_data[3] != 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00005803 }
5804 SourceLocation getFunctionMacroTokenLoc(unsigned tokI) const {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005805 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[3]);
Guy Benyei11169dd2012-12-18 14:30:41 +00005806 }
5807
5808 void annotateAndAdvanceTokens(CXCursor, RangeComparisonResult, SourceRange);
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005809 bool annotateAndAdvanceFunctionMacroTokens(CXCursor, RangeComparisonResult,
Guy Benyei11169dd2012-12-18 14:30:41 +00005810 SourceRange);
5811
5812public:
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005813 AnnotateTokensWorker(CXToken *tokens, CXCursor *cursors, unsigned numTokens,
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005814 CXTranslationUnit TU, SourceRange RegionOfInterest)
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005815 : Tokens(tokens), Cursors(cursors),
Guy Benyei11169dd2012-12-18 14:30:41 +00005816 NumTokens(numTokens), TokIdx(0), PreprocessingTokIdx(0),
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005817 AnnotateVis(TU,
Guy Benyei11169dd2012-12-18 14:30:41 +00005818 AnnotateTokensVisitor, this,
5819 /*VisitPreprocessorLast=*/true,
5820 /*VisitIncludedEntities=*/false,
5821 RegionOfInterest,
5822 /*VisitDeclsOnly=*/false,
5823 AnnotateTokensPostChildrenVisitor),
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005824 SrcMgr(cxtu::getASTUnit(TU)->getSourceManager()),
Guy Benyei11169dd2012-12-18 14:30:41 +00005825 HasContextSensitiveKeywords(false) { }
5826
5827 void VisitChildren(CXCursor C) { AnnotateVis.VisitChildren(C); }
5828 enum CXChildVisitResult Visit(CXCursor cursor, CXCursor parent);
5829 bool postVisitChildren(CXCursor cursor);
5830 void AnnotateTokens();
5831
5832 /// \brief Determine whether the annotator saw any cursors that have
5833 /// context-sensitive keywords.
5834 bool hasContextSensitiveKeywords() const {
5835 return HasContextSensitiveKeywords;
5836 }
5837
5838 ~AnnotateTokensWorker() {
5839 assert(PostChildrenInfos.empty());
5840 }
5841};
Alexander Kornienkoab9db512015-06-22 23:07:51 +00005842}
Guy Benyei11169dd2012-12-18 14:30:41 +00005843
5844void AnnotateTokensWorker::AnnotateTokens() {
5845 // Walk the AST within the region of interest, annotating tokens
5846 // along the way.
5847 AnnotateVis.visitFileRegion();
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005848}
Guy Benyei11169dd2012-12-18 14:30:41 +00005849
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005850static inline void updateCursorAnnotation(CXCursor &Cursor,
5851 const CXCursor &updateC) {
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005852 if (clang_isInvalid(updateC.kind) || !clang_isInvalid(Cursor.kind))
Guy Benyei11169dd2012-12-18 14:30:41 +00005853 return;
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005854 Cursor = updateC;
Guy Benyei11169dd2012-12-18 14:30:41 +00005855}
5856
5857/// \brief It annotates and advances tokens with a cursor until the comparison
5858//// between the cursor location and the source range is the same as
5859/// \arg compResult.
5860///
5861/// Pass RangeBefore to annotate tokens with a cursor until a range is reached.
5862/// Pass RangeOverlap to annotate tokens inside a range.
5863void AnnotateTokensWorker::annotateAndAdvanceTokens(CXCursor updateC,
5864 RangeComparisonResult compResult,
5865 SourceRange range) {
5866 while (MoreTokens()) {
5867 const unsigned I = NextToken();
5868 if (isFunctionMacroToken(I))
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005869 if (!annotateAndAdvanceFunctionMacroTokens(updateC, compResult, range))
5870 return;
Guy Benyei11169dd2012-12-18 14:30:41 +00005871
5872 SourceLocation TokLoc = GetTokenLoc(I);
5873 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005874 updateCursorAnnotation(Cursors[I], updateC);
Guy Benyei11169dd2012-12-18 14:30:41 +00005875 AdvanceToken();
5876 continue;
5877 }
5878 break;
5879 }
5880}
5881
5882/// \brief Special annotation handling for macro argument tokens.
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005883/// \returns true if it advanced beyond all macro tokens, false otherwise.
5884bool AnnotateTokensWorker::annotateAndAdvanceFunctionMacroTokens(
Guy Benyei11169dd2012-12-18 14:30:41 +00005885 CXCursor updateC,
5886 RangeComparisonResult compResult,
5887 SourceRange range) {
5888 assert(MoreTokens());
5889 assert(isFunctionMacroToken(NextToken()) &&
5890 "Should be called only for macro arg tokens");
5891
5892 // This works differently than annotateAndAdvanceTokens; because expanded
5893 // macro arguments can have arbitrary translation-unit source order, we do not
5894 // advance the token index one by one until a token fails the range test.
5895 // We only advance once past all of the macro arg tokens if all of them
5896 // pass the range test. If one of them fails we keep the token index pointing
5897 // at the start of the macro arg tokens so that the failing token will be
5898 // annotated by a subsequent annotation try.
5899
5900 bool atLeastOneCompFail = false;
5901
5902 unsigned I = NextToken();
5903 for (; I < NumTokens && isFunctionMacroToken(I); ++I) {
5904 SourceLocation TokLoc = getFunctionMacroTokenLoc(I);
5905 if (TokLoc.isFileID())
5906 continue; // not macro arg token, it's parens or comma.
5907 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
5908 if (clang_isInvalid(clang_getCursorKind(Cursors[I])))
5909 Cursors[I] = updateC;
5910 } else
5911 atLeastOneCompFail = true;
5912 }
5913
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005914 if (atLeastOneCompFail)
5915 return false;
5916
5917 TokIdx = I; // All of the tokens were handled, advance beyond all of them.
5918 return true;
Guy Benyei11169dd2012-12-18 14:30:41 +00005919}
5920
5921enum CXChildVisitResult
5922AnnotateTokensWorker::Visit(CXCursor cursor, CXCursor parent) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005923 SourceRange cursorRange = getRawCursorExtent(cursor);
5924 if (cursorRange.isInvalid())
5925 return CXChildVisit_Recurse;
5926
5927 if (!HasContextSensitiveKeywords) {
5928 // Objective-C properties can have context-sensitive keywords.
5929 if (cursor.kind == CXCursor_ObjCPropertyDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005930 if (const ObjCPropertyDecl *Property
Guy Benyei11169dd2012-12-18 14:30:41 +00005931 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(cursor)))
5932 HasContextSensitiveKeywords = Property->getPropertyAttributesAsWritten() != 0;
5933 }
5934 // Objective-C methods can have context-sensitive keywords.
5935 else if (cursor.kind == CXCursor_ObjCInstanceMethodDecl ||
5936 cursor.kind == CXCursor_ObjCClassMethodDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005937 if (const ObjCMethodDecl *Method
Guy Benyei11169dd2012-12-18 14:30:41 +00005938 = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
5939 if (Method->getObjCDeclQualifier())
5940 HasContextSensitiveKeywords = true;
5941 else {
Aaron Ballman43b68be2014-03-07 17:50:17 +00005942 for (const auto *P : Method->params()) {
5943 if (P->getObjCDeclQualifier()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005944 HasContextSensitiveKeywords = true;
5945 break;
5946 }
5947 }
5948 }
5949 }
5950 }
5951 // C++ methods can have context-sensitive keywords.
5952 else if (cursor.kind == CXCursor_CXXMethod) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005953 if (const CXXMethodDecl *Method
Guy Benyei11169dd2012-12-18 14:30:41 +00005954 = dyn_cast_or_null<CXXMethodDecl>(getCursorDecl(cursor))) {
5955 if (Method->hasAttr<FinalAttr>() || Method->hasAttr<OverrideAttr>())
5956 HasContextSensitiveKeywords = true;
5957 }
5958 }
5959 // C++ classes can have context-sensitive keywords.
5960 else if (cursor.kind == CXCursor_StructDecl ||
5961 cursor.kind == CXCursor_ClassDecl ||
5962 cursor.kind == CXCursor_ClassTemplate ||
5963 cursor.kind == CXCursor_ClassTemplatePartialSpecialization) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005964 if (const Decl *D = getCursorDecl(cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +00005965 if (D->hasAttr<FinalAttr>())
5966 HasContextSensitiveKeywords = true;
5967 }
5968 }
Argyrios Kyrtzidis990b3862013-06-04 18:24:30 +00005969
5970 // Don't override a property annotation with its getter/setter method.
5971 if (cursor.kind == CXCursor_ObjCInstanceMethodDecl &&
5972 parent.kind == CXCursor_ObjCPropertyDecl)
5973 return CXChildVisit_Continue;
Guy Benyei11169dd2012-12-18 14:30:41 +00005974
5975 if (clang_isPreprocessing(cursor.kind)) {
5976 // Items in the preprocessing record are kept separate from items in
5977 // declarations, so we keep a separate token index.
5978 unsigned SavedTokIdx = TokIdx;
5979 TokIdx = PreprocessingTokIdx;
5980
5981 // Skip tokens up until we catch up to the beginning of the preprocessing
5982 // entry.
5983 while (MoreTokens()) {
5984 const unsigned I = NextToken();
5985 SourceLocation TokLoc = GetTokenLoc(I);
5986 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
5987 case RangeBefore:
5988 AdvanceToken();
5989 continue;
5990 case RangeAfter:
5991 case RangeOverlap:
5992 break;
5993 }
5994 break;
5995 }
5996
5997 // Look at all of the tokens within this range.
5998 while (MoreTokens()) {
5999 const unsigned I = NextToken();
6000 SourceLocation TokLoc = GetTokenLoc(I);
6001 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
6002 case RangeBefore:
6003 llvm_unreachable("Infeasible");
6004 case RangeAfter:
6005 break;
6006 case RangeOverlap:
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00006007 // For macro expansions, just note where the beginning of the macro
6008 // expansion occurs.
6009 if (cursor.kind == CXCursor_MacroExpansion) {
6010 if (TokLoc == cursorRange.getBegin())
6011 Cursors[I] = cursor;
6012 AdvanceToken();
6013 break;
6014 }
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006015 // We may have already annotated macro names inside macro definitions.
6016 if (Cursors[I].kind != CXCursor_MacroExpansion)
6017 Cursors[I] = cursor;
Guy Benyei11169dd2012-12-18 14:30:41 +00006018 AdvanceToken();
Guy Benyei11169dd2012-12-18 14:30:41 +00006019 continue;
6020 }
6021 break;
6022 }
6023
6024 // Save the preprocessing token index; restore the non-preprocessing
6025 // token index.
6026 PreprocessingTokIdx = TokIdx;
6027 TokIdx = SavedTokIdx;
6028 return CXChildVisit_Recurse;
6029 }
6030
6031 if (cursorRange.isInvalid())
6032 return CXChildVisit_Continue;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00006033
6034 unsigned BeforeReachingCursorIdx = NextToken();
Guy Benyei11169dd2012-12-18 14:30:41 +00006035 const enum CXCursorKind cursorK = clang_getCursorKind(cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00006036 const enum CXCursorKind K = clang_getCursorKind(parent);
6037 const CXCursor updateC =
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00006038 (clang_isInvalid(K) || K == CXCursor_TranslationUnit ||
6039 // Attributes are annotated out-of-order, skip tokens until we reach it.
6040 clang_isAttribute(cursor.kind))
Guy Benyei11169dd2012-12-18 14:30:41 +00006041 ? clang_getNullCursor() : parent;
6042
6043 annotateAndAdvanceTokens(updateC, RangeBefore, cursorRange);
6044
6045 // Avoid having the cursor of an expression "overwrite" the annotation of the
6046 // variable declaration that it belongs to.
6047 // This can happen for C++ constructor expressions whose range generally
6048 // include the variable declaration, e.g.:
6049 // MyCXXClass foo; // Make sure we don't annotate 'foo' as a CallExpr cursor.
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00006050 if (clang_isExpression(cursorK) && MoreTokens()) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00006051 const Expr *E = getCursorExpr(cursor);
Dmitri Gribenkoa1691182013-01-26 18:12:08 +00006052 if (const Decl *D = getCursorParentDecl(cursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00006053 const unsigned I = NextToken();
6054 if (E->getLocStart().isValid() && D->getLocation().isValid() &&
6055 E->getLocStart() == D->getLocation() &&
6056 E->getLocStart() == GetTokenLoc(I)) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006057 updateCursorAnnotation(Cursors[I], updateC);
Guy Benyei11169dd2012-12-18 14:30:41 +00006058 AdvanceToken();
6059 }
6060 }
6061 }
6062
6063 // Before recursing into the children keep some state that we are going
6064 // to use in the AnnotateTokensWorker::postVisitChildren callback to do some
6065 // extra work after the child nodes are visited.
6066 // Note that we don't call VisitChildren here to avoid traversing statements
6067 // code-recursively which can blow the stack.
6068
6069 PostChildrenInfo Info;
6070 Info.Cursor = cursor;
6071 Info.CursorRange = cursorRange;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00006072 Info.BeforeReachingCursorIdx = BeforeReachingCursorIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00006073 Info.BeforeChildrenTokenIdx = NextToken();
6074 PostChildrenInfos.push_back(Info);
6075
6076 return CXChildVisit_Recurse;
6077}
6078
6079bool AnnotateTokensWorker::postVisitChildren(CXCursor cursor) {
6080 if (PostChildrenInfos.empty())
6081 return false;
6082 const PostChildrenInfo &Info = PostChildrenInfos.back();
6083 if (!clang_equalCursors(Info.Cursor, cursor))
6084 return false;
6085
6086 const unsigned BeforeChildren = Info.BeforeChildrenTokenIdx;
6087 const unsigned AfterChildren = NextToken();
6088 SourceRange cursorRange = Info.CursorRange;
6089
6090 // Scan the tokens that are at the end of the cursor, but are not captured
6091 // but the child cursors.
6092 annotateAndAdvanceTokens(cursor, RangeOverlap, cursorRange);
6093
6094 // Scan the tokens that are at the beginning of the cursor, but are not
6095 // capture by the child cursors.
6096 for (unsigned I = BeforeChildren; I != AfterChildren; ++I) {
6097 if (!clang_isInvalid(clang_getCursorKind(Cursors[I])))
6098 break;
6099
6100 Cursors[I] = cursor;
6101 }
6102
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00006103 // Attributes are annotated out-of-order, rewind TokIdx to when we first
6104 // encountered the attribute cursor.
6105 if (clang_isAttribute(cursor.kind))
6106 TokIdx = Info.BeforeReachingCursorIdx;
6107
Guy Benyei11169dd2012-12-18 14:30:41 +00006108 PostChildrenInfos.pop_back();
6109 return false;
6110}
6111
6112static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
6113 CXCursor parent,
6114 CXClientData client_data) {
6115 return static_cast<AnnotateTokensWorker*>(client_data)->Visit(cursor, parent);
6116}
6117
6118static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
6119 CXClientData client_data) {
6120 return static_cast<AnnotateTokensWorker*>(client_data)->
6121 postVisitChildren(cursor);
6122}
6123
6124namespace {
6125
6126/// \brief Uses the macro expansions in the preprocessing record to find
6127/// and mark tokens that are macro arguments. This info is used by the
6128/// AnnotateTokensWorker.
6129class MarkMacroArgTokensVisitor {
6130 SourceManager &SM;
6131 CXToken *Tokens;
6132 unsigned NumTokens;
6133 unsigned CurIdx;
6134
6135public:
6136 MarkMacroArgTokensVisitor(SourceManager &SM,
6137 CXToken *tokens, unsigned numTokens)
6138 : SM(SM), Tokens(tokens), NumTokens(numTokens), CurIdx(0) { }
6139
6140 CXChildVisitResult visit(CXCursor cursor, CXCursor parent) {
6141 if (cursor.kind != CXCursor_MacroExpansion)
6142 return CXChildVisit_Continue;
6143
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006144 SourceRange macroRange = getCursorMacroExpansion(cursor).getSourceRange();
Guy Benyei11169dd2012-12-18 14:30:41 +00006145 if (macroRange.getBegin() == macroRange.getEnd())
6146 return CXChildVisit_Continue; // it's not a function macro.
6147
6148 for (; CurIdx < NumTokens; ++CurIdx) {
6149 if (!SM.isBeforeInTranslationUnit(getTokenLoc(CurIdx),
6150 macroRange.getBegin()))
6151 break;
6152 }
6153
6154 if (CurIdx == NumTokens)
6155 return CXChildVisit_Break;
6156
6157 for (; CurIdx < NumTokens; ++CurIdx) {
6158 SourceLocation tokLoc = getTokenLoc(CurIdx);
6159 if (!SM.isBeforeInTranslationUnit(tokLoc, macroRange.getEnd()))
6160 break;
6161
6162 setFunctionMacroTokenLoc(CurIdx, SM.getMacroArgExpandedLocation(tokLoc));
6163 }
6164
6165 if (CurIdx == NumTokens)
6166 return CXChildVisit_Break;
6167
6168 return CXChildVisit_Continue;
6169 }
6170
6171private:
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00006172 CXToken &getTok(unsigned Idx) {
6173 assert(Idx < NumTokens);
6174 return Tokens[Idx];
6175 }
6176 const CXToken &getTok(unsigned Idx) const {
6177 assert(Idx < NumTokens);
6178 return Tokens[Idx];
6179 }
6180
Guy Benyei11169dd2012-12-18 14:30:41 +00006181 SourceLocation getTokenLoc(unsigned tokI) {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00006182 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[1]);
Guy Benyei11169dd2012-12-18 14:30:41 +00006183 }
6184
6185 void setFunctionMacroTokenLoc(unsigned tokI, SourceLocation loc) {
6186 // The third field is reserved and currently not used. Use it here
6187 // to mark macro arg expanded tokens with their expanded locations.
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00006188 getTok(tokI).int_data[3] = loc.getRawEncoding();
Guy Benyei11169dd2012-12-18 14:30:41 +00006189 }
6190};
6191
6192} // end anonymous namespace
6193
6194static CXChildVisitResult
6195MarkMacroArgTokensVisitorDelegate(CXCursor cursor, CXCursor parent,
6196 CXClientData client_data) {
6197 return static_cast<MarkMacroArgTokensVisitor*>(client_data)->visit(cursor,
6198 parent);
6199}
6200
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006201/// \brief Used by \c annotatePreprocessorTokens.
6202/// \returns true if lexing was finished, false otherwise.
6203static bool lexNext(Lexer &Lex, Token &Tok,
6204 unsigned &NextIdx, unsigned NumTokens) {
6205 if (NextIdx >= NumTokens)
6206 return true;
6207
6208 ++NextIdx;
6209 Lex.LexFromRawLexer(Tok);
6210 if (Tok.is(tok::eof))
6211 return true;
6212
6213 return false;
6214}
6215
Guy Benyei11169dd2012-12-18 14:30:41 +00006216static void annotatePreprocessorTokens(CXTranslationUnit TU,
6217 SourceRange RegionOfInterest,
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006218 CXCursor *Cursors,
6219 CXToken *Tokens,
6220 unsigned NumTokens) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006221 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00006222
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006223 Preprocessor &PP = CXXUnit->getPreprocessor();
Guy Benyei11169dd2012-12-18 14:30:41 +00006224 SourceManager &SourceMgr = CXXUnit->getSourceManager();
6225 std::pair<FileID, unsigned> BeginLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00006226 = SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getBegin());
Guy Benyei11169dd2012-12-18 14:30:41 +00006227 std::pair<FileID, unsigned> EndLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00006228 = SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getEnd());
Guy Benyei11169dd2012-12-18 14:30:41 +00006229
6230 if (BeginLocInfo.first != EndLocInfo.first)
6231 return;
6232
6233 StringRef Buffer;
6234 bool Invalid = false;
6235 Buffer = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
6236 if (Buffer.empty() || Invalid)
6237 return;
6238
6239 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
6240 CXXUnit->getASTContext().getLangOpts(),
6241 Buffer.begin(), Buffer.data() + BeginLocInfo.second,
6242 Buffer.end());
6243 Lex.SetCommentRetentionState(true);
6244
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006245 unsigned NextIdx = 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00006246 // Lex tokens in raw mode until we hit the end of the range, to avoid
6247 // entering #includes or expanding macros.
6248 while (true) {
6249 Token Tok;
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006250 if (lexNext(Lex, Tok, NextIdx, NumTokens))
6251 break;
6252 unsigned TokIdx = NextIdx-1;
6253 assert(Tok.getLocation() ==
6254 SourceLocation::getFromRawEncoding(Tokens[TokIdx].int_data[1]));
Guy Benyei11169dd2012-12-18 14:30:41 +00006255
6256 reprocess:
6257 if (Tok.is(tok::hash) && Tok.isAtStartOfLine()) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006258 // We have found a preprocessing directive. Annotate the tokens
6259 // appropriately.
Guy Benyei11169dd2012-12-18 14:30:41 +00006260 //
6261 // FIXME: Some simple tests here could identify macro definitions and
6262 // #undefs, to provide specific cursor kinds for those.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006263
6264 SourceLocation BeginLoc = Tok.getLocation();
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006265 if (lexNext(Lex, Tok, NextIdx, NumTokens))
6266 break;
6267
Craig Topper69186e72014-06-08 08:38:04 +00006268 MacroInfo *MI = nullptr;
Alp Toker2d57cea2014-05-17 04:53:25 +00006269 if (Tok.is(tok::raw_identifier) && Tok.getRawIdentifier() == "define") {
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006270 if (lexNext(Lex, Tok, NextIdx, NumTokens))
6271 break;
6272
6273 if (Tok.is(tok::raw_identifier)) {
Alp Toker2d57cea2014-05-17 04:53:25 +00006274 IdentifierInfo &II =
6275 PP.getIdentifierTable().get(Tok.getRawIdentifier());
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006276 SourceLocation MappedTokLoc =
6277 CXXUnit->mapLocationToPreamble(Tok.getLocation());
6278 MI = getMacroInfo(II, MappedTokLoc, TU);
6279 }
6280 }
6281
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006282 bool finished = false;
Guy Benyei11169dd2012-12-18 14:30:41 +00006283 do {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006284 if (lexNext(Lex, Tok, NextIdx, NumTokens)) {
6285 finished = true;
6286 break;
6287 }
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006288 // If we are in a macro definition, check if the token was ever a
6289 // macro name and annotate it if that's the case.
6290 if (MI) {
6291 SourceLocation SaveLoc = Tok.getLocation();
6292 Tok.setLocation(CXXUnit->mapLocationToPreamble(SaveLoc));
Richard Smith66a81862015-05-04 02:25:31 +00006293 MacroDefinitionRecord *MacroDef =
6294 checkForMacroInMacroDefinition(MI, Tok, TU);
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006295 Tok.setLocation(SaveLoc);
6296 if (MacroDef)
Richard Smith66a81862015-05-04 02:25:31 +00006297 Cursors[NextIdx - 1] =
6298 MakeMacroExpansionCursor(MacroDef, Tok.getLocation(), TU);
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006299 }
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006300 } while (!Tok.isAtStartOfLine());
6301
6302 unsigned LastIdx = finished ? NextIdx-1 : NextIdx-2;
6303 assert(TokIdx <= LastIdx);
6304 SourceLocation EndLoc =
6305 SourceLocation::getFromRawEncoding(Tokens[LastIdx].int_data[1]);
6306 CXCursor Cursor =
6307 MakePreprocessingDirectiveCursor(SourceRange(BeginLoc, EndLoc), TU);
6308
6309 for (; TokIdx <= LastIdx; ++TokIdx)
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006310 updateCursorAnnotation(Cursors[TokIdx], Cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00006311
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006312 if (finished)
6313 break;
6314 goto reprocess;
Guy Benyei11169dd2012-12-18 14:30:41 +00006315 }
Guy Benyei11169dd2012-12-18 14:30:41 +00006316 }
6317}
6318
6319// This gets run a separate thread to avoid stack blowout.
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00006320static void clang_annotateTokensImpl(CXTranslationUnit TU, ASTUnit *CXXUnit,
6321 CXToken *Tokens, unsigned NumTokens,
6322 CXCursor *Cursors) {
Dmitri Gribenko183436e2013-01-26 21:49:50 +00006323 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00006324 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
6325 setThreadBackgroundPriority();
6326
6327 // Determine the region of interest, which contains all of the tokens.
6328 SourceRange RegionOfInterest;
6329 RegionOfInterest.setBegin(
6330 cxloc::translateSourceLocation(clang_getTokenLocation(TU, Tokens[0])));
6331 RegionOfInterest.setEnd(
6332 cxloc::translateSourceLocation(clang_getTokenLocation(TU,
6333 Tokens[NumTokens-1])));
6334
Guy Benyei11169dd2012-12-18 14:30:41 +00006335 // Relex the tokens within the source range to look for preprocessing
6336 // directives.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006337 annotatePreprocessorTokens(TU, RegionOfInterest, Cursors, Tokens, NumTokens);
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00006338
6339 // If begin location points inside a macro argument, set it to the expansion
6340 // location so we can have the full context when annotating semantically.
6341 {
6342 SourceManager &SM = CXXUnit->getSourceManager();
6343 SourceLocation Loc =
6344 SM.getMacroArgExpandedLocation(RegionOfInterest.getBegin());
6345 if (Loc.isMacroID())
6346 RegionOfInterest.setBegin(SM.getExpansionLoc(Loc));
6347 }
6348
Guy Benyei11169dd2012-12-18 14:30:41 +00006349 if (CXXUnit->getPreprocessor().getPreprocessingRecord()) {
6350 // Search and mark tokens that are macro argument expansions.
6351 MarkMacroArgTokensVisitor Visitor(CXXUnit->getSourceManager(),
6352 Tokens, NumTokens);
6353 CursorVisitor MacroArgMarker(TU,
6354 MarkMacroArgTokensVisitorDelegate, &Visitor,
6355 /*VisitPreprocessorLast=*/true,
6356 /*VisitIncludedEntities=*/false,
6357 RegionOfInterest);
6358 MacroArgMarker.visitPreprocessedEntitiesInRegion();
6359 }
6360
6361 // Annotate all of the source locations in the region of interest that map to
6362 // a specific cursor.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006363 AnnotateTokensWorker W(Tokens, Cursors, NumTokens, TU, RegionOfInterest);
Guy Benyei11169dd2012-12-18 14:30:41 +00006364
6365 // FIXME: We use a ridiculous stack size here because the data-recursion
6366 // algorithm uses a large stack frame than the non-data recursive version,
6367 // and AnnotationTokensWorker currently transforms the data-recursion
6368 // algorithm back into a traditional recursion by explicitly calling
6369 // VisitChildren(). We will need to remove this explicit recursive call.
6370 W.AnnotateTokens();
6371
6372 // If we ran into any entities that involve context-sensitive keywords,
6373 // take another pass through the tokens to mark them as such.
6374 if (W.hasContextSensitiveKeywords()) {
6375 for (unsigned I = 0; I != NumTokens; ++I) {
6376 if (clang_getTokenKind(Tokens[I]) != CXToken_Identifier)
6377 continue;
6378
6379 if (Cursors[I].kind == CXCursor_ObjCPropertyDecl) {
6380 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006381 if (const ObjCPropertyDecl *Property
Guy Benyei11169dd2012-12-18 14:30:41 +00006382 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(Cursors[I]))) {
6383 if (Property->getPropertyAttributesAsWritten() != 0 &&
6384 llvm::StringSwitch<bool>(II->getName())
6385 .Case("readonly", true)
6386 .Case("assign", true)
6387 .Case("unsafe_unretained", true)
6388 .Case("readwrite", true)
6389 .Case("retain", true)
6390 .Case("copy", true)
6391 .Case("nonatomic", true)
6392 .Case("atomic", true)
6393 .Case("getter", true)
6394 .Case("setter", true)
6395 .Case("strong", true)
6396 .Case("weak", true)
6397 .Default(false))
6398 Tokens[I].int_data[0] = CXToken_Keyword;
6399 }
6400 continue;
6401 }
6402
6403 if (Cursors[I].kind == CXCursor_ObjCInstanceMethodDecl ||
6404 Cursors[I].kind == CXCursor_ObjCClassMethodDecl) {
6405 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
6406 if (llvm::StringSwitch<bool>(II->getName())
6407 .Case("in", true)
6408 .Case("out", true)
6409 .Case("inout", true)
6410 .Case("oneway", true)
6411 .Case("bycopy", true)
6412 .Case("byref", true)
6413 .Default(false))
6414 Tokens[I].int_data[0] = CXToken_Keyword;
6415 continue;
6416 }
6417
6418 if (Cursors[I].kind == CXCursor_CXXFinalAttr ||
6419 Cursors[I].kind == CXCursor_CXXOverrideAttr) {
6420 Tokens[I].int_data[0] = CXToken_Keyword;
6421 continue;
6422 }
6423 }
6424 }
6425}
6426
6427extern "C" {
6428
6429void clang_annotateTokens(CXTranslationUnit TU,
6430 CXToken *Tokens, unsigned NumTokens,
6431 CXCursor *Cursors) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006432 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006433 LOG_BAD_TU(TU);
6434 return;
6435 }
6436 if (NumTokens == 0 || !Tokens || !Cursors) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006437 LOG_FUNC_SECTION { *Log << "<null input>"; }
Guy Benyei11169dd2012-12-18 14:30:41 +00006438 return;
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006439 }
6440
6441 LOG_FUNC_SECTION {
6442 *Log << TU << ' ';
6443 CXSourceLocation bloc = clang_getTokenLocation(TU, Tokens[0]);
6444 CXSourceLocation eloc = clang_getTokenLocation(TU, Tokens[NumTokens-1]);
6445 *Log << clang_getRange(bloc, eloc);
6446 }
Guy Benyei11169dd2012-12-18 14:30:41 +00006447
6448 // Any token we don't specifically annotate will have a NULL cursor.
6449 CXCursor C = clang_getNullCursor();
6450 for (unsigned I = 0; I != NumTokens; ++I)
6451 Cursors[I] = C;
6452
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006453 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00006454 if (!CXXUnit)
6455 return;
6456
6457 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00006458
6459 auto AnnotateTokensImpl = [=]() {
6460 clang_annotateTokensImpl(TU, CXXUnit, Tokens, NumTokens, Cursors);
6461 };
Guy Benyei11169dd2012-12-18 14:30:41 +00006462 llvm::CrashRecoveryContext CRC;
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00006463 if (!RunSafely(CRC, AnnotateTokensImpl, GetSafetyThreadStackSize() * 2)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00006464 fprintf(stderr, "libclang: crash detected while annotating tokens\n");
6465 }
6466}
6467
6468} // end: extern "C"
6469
6470//===----------------------------------------------------------------------===//
6471// Operations for querying linkage of a cursor.
6472//===----------------------------------------------------------------------===//
6473
6474extern "C" {
6475CXLinkageKind clang_getCursorLinkage(CXCursor cursor) {
6476 if (!clang_isDeclaration(cursor.kind))
6477 return CXLinkage_Invalid;
6478
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006479 const Decl *D = cxcursor::getCursorDecl(cursor);
6480 if (const NamedDecl *ND = dyn_cast_or_null<NamedDecl>(D))
Rafael Espindola3ae00052013-05-13 00:12:11 +00006481 switch (ND->getLinkageInternal()) {
Rafael Espindola50df3a02013-05-25 17:16:20 +00006482 case NoLinkage:
6483 case VisibleNoLinkage: return CXLinkage_NoLinkage;
Guy Benyei11169dd2012-12-18 14:30:41 +00006484 case InternalLinkage: return CXLinkage_Internal;
6485 case UniqueExternalLinkage: return CXLinkage_UniqueExternal;
6486 case ExternalLinkage: return CXLinkage_External;
6487 };
6488
6489 return CXLinkage_Invalid;
6490}
6491} // end: extern "C"
6492
6493//===----------------------------------------------------------------------===//
Ehsan Akhgari93697fa2015-11-23 19:56:46 +00006494// Operations for querying visibility of a cursor.
6495//===----------------------------------------------------------------------===//
6496
6497extern "C" {
6498CXVisibilityKind clang_getCursorVisibility(CXCursor cursor) {
6499 if (!clang_isDeclaration(cursor.kind))
6500 return CXVisibility_Invalid;
6501
6502 const Decl *D = cxcursor::getCursorDecl(cursor);
6503 if (const NamedDecl *ND = dyn_cast_or_null<NamedDecl>(D))
6504 switch (ND->getVisibility()) {
6505 case HiddenVisibility: return CXVisibility_Hidden;
6506 case ProtectedVisibility: return CXVisibility_Protected;
6507 case DefaultVisibility: return CXVisibility_Default;
6508 };
6509
6510 return CXVisibility_Invalid;
6511}
6512} // end: extern "C"
6513
6514//===----------------------------------------------------------------------===//
Guy Benyei11169dd2012-12-18 14:30:41 +00006515// Operations for querying language of a cursor.
6516//===----------------------------------------------------------------------===//
6517
6518static CXLanguageKind getDeclLanguage(const Decl *D) {
6519 if (!D)
6520 return CXLanguage_C;
6521
6522 switch (D->getKind()) {
6523 default:
6524 break;
6525 case Decl::ImplicitParam:
6526 case Decl::ObjCAtDefsField:
6527 case Decl::ObjCCategory:
6528 case Decl::ObjCCategoryImpl:
6529 case Decl::ObjCCompatibleAlias:
6530 case Decl::ObjCImplementation:
6531 case Decl::ObjCInterface:
6532 case Decl::ObjCIvar:
6533 case Decl::ObjCMethod:
6534 case Decl::ObjCProperty:
6535 case Decl::ObjCPropertyImpl:
6536 case Decl::ObjCProtocol:
Douglas Gregor85f3f952015-07-07 03:57:15 +00006537 case Decl::ObjCTypeParam:
Guy Benyei11169dd2012-12-18 14:30:41 +00006538 return CXLanguage_ObjC;
6539 case Decl::CXXConstructor:
6540 case Decl::CXXConversion:
6541 case Decl::CXXDestructor:
6542 case Decl::CXXMethod:
6543 case Decl::CXXRecord:
6544 case Decl::ClassTemplate:
6545 case Decl::ClassTemplatePartialSpecialization:
6546 case Decl::ClassTemplateSpecialization:
6547 case Decl::Friend:
6548 case Decl::FriendTemplate:
6549 case Decl::FunctionTemplate:
6550 case Decl::LinkageSpec:
6551 case Decl::Namespace:
6552 case Decl::NamespaceAlias:
6553 case Decl::NonTypeTemplateParm:
6554 case Decl::StaticAssert:
6555 case Decl::TemplateTemplateParm:
6556 case Decl::TemplateTypeParm:
6557 case Decl::UnresolvedUsingTypename:
6558 case Decl::UnresolvedUsingValue:
6559 case Decl::Using:
6560 case Decl::UsingDirective:
6561 case Decl::UsingShadow:
6562 return CXLanguage_CPlusPlus;
6563 }
6564
6565 return CXLanguage_C;
6566}
6567
6568extern "C" {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006569
6570static CXAvailabilityKind getCursorAvailabilityForDecl(const Decl *D) {
6571 if (isa<FunctionDecl>(D) && cast<FunctionDecl>(D)->isDeleted())
Manuel Klimek8e3a7ed2015-09-25 17:53:16 +00006572 return CXAvailability_NotAvailable;
Guy Benyei11169dd2012-12-18 14:30:41 +00006573
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006574 switch (D->getAvailability()) {
6575 case AR_Available:
6576 case AR_NotYetIntroduced:
6577 if (const EnumConstantDecl *EnumConst = dyn_cast<EnumConstantDecl>(D))
Benjamin Kramer656363d2013-10-15 18:53:18 +00006578 return getCursorAvailabilityForDecl(
6579 cast<Decl>(EnumConst->getDeclContext()));
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006580 return CXAvailability_Available;
6581
6582 case AR_Deprecated:
6583 return CXAvailability_Deprecated;
6584
6585 case AR_Unavailable:
6586 return CXAvailability_NotAvailable;
6587 }
Benjamin Kramer656363d2013-10-15 18:53:18 +00006588
6589 llvm_unreachable("Unknown availability kind!");
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006590}
6591
Guy Benyei11169dd2012-12-18 14:30:41 +00006592enum CXAvailabilityKind clang_getCursorAvailability(CXCursor cursor) {
6593 if (clang_isDeclaration(cursor.kind))
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006594 if (const Decl *D = cxcursor::getCursorDecl(cursor))
6595 return getCursorAvailabilityForDecl(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00006596
6597 return CXAvailability_Available;
6598}
6599
6600static CXVersion convertVersion(VersionTuple In) {
6601 CXVersion Out = { -1, -1, -1 };
6602 if (In.empty())
6603 return Out;
6604
6605 Out.Major = In.getMajor();
6606
NAKAMURA Takumic2b5d1f2013-02-21 02:32:34 +00006607 Optional<unsigned> Minor = In.getMinor();
6608 if (Minor.hasValue())
Guy Benyei11169dd2012-12-18 14:30:41 +00006609 Out.Minor = *Minor;
6610 else
6611 return Out;
6612
NAKAMURA Takumic2b5d1f2013-02-21 02:32:34 +00006613 Optional<unsigned> Subminor = In.getSubminor();
6614 if (Subminor.hasValue())
Guy Benyei11169dd2012-12-18 14:30:41 +00006615 Out.Subminor = *Subminor;
6616
6617 return Out;
6618}
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006619
6620static int getCursorPlatformAvailabilityForDecl(const Decl *D,
6621 int *always_deprecated,
6622 CXString *deprecated_message,
6623 int *always_unavailable,
6624 CXString *unavailable_message,
6625 CXPlatformAvailability *availability,
6626 int availability_size) {
6627 bool HadAvailAttr = false;
6628 int N = 0;
Aaron Ballmanb97112e2014-03-08 22:19:01 +00006629 for (auto A : D->attrs()) {
6630 if (DeprecatedAttr *Deprecated = dyn_cast<DeprecatedAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006631 HadAvailAttr = true;
6632 if (always_deprecated)
6633 *always_deprecated = 1;
Nico Weberaacf0312014-04-24 05:16:45 +00006634 if (deprecated_message) {
Argyrios Kyrtzidisedfe07f2014-04-24 06:05:40 +00006635 clang_disposeString(*deprecated_message);
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006636 *deprecated_message = cxstring::createDup(Deprecated->getMessage());
Nico Weberaacf0312014-04-24 05:16:45 +00006637 }
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006638 continue;
6639 }
6640
Aaron Ballmanb97112e2014-03-08 22:19:01 +00006641 if (UnavailableAttr *Unavailable = dyn_cast<UnavailableAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006642 HadAvailAttr = true;
6643 if (always_unavailable)
6644 *always_unavailable = 1;
6645 if (unavailable_message) {
Argyrios Kyrtzidisedfe07f2014-04-24 06:05:40 +00006646 clang_disposeString(*unavailable_message);
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006647 *unavailable_message = cxstring::createDup(Unavailable->getMessage());
6648 }
6649 continue;
6650 }
6651
Aaron Ballmanb97112e2014-03-08 22:19:01 +00006652 if (AvailabilityAttr *Avail = dyn_cast<AvailabilityAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006653 HadAvailAttr = true;
6654 if (N < availability_size) {
6655 availability[N].Platform
6656 = cxstring::createDup(Avail->getPlatform()->getName());
6657 availability[N].Introduced = convertVersion(Avail->getIntroduced());
6658 availability[N].Deprecated = convertVersion(Avail->getDeprecated());
6659 availability[N].Obsoleted = convertVersion(Avail->getObsoleted());
6660 availability[N].Unavailable = Avail->getUnavailable();
6661 availability[N].Message = cxstring::createDup(Avail->getMessage());
6662 }
6663 ++N;
6664 }
6665 }
6666
6667 if (!HadAvailAttr)
6668 if (const EnumConstantDecl *EnumConst = dyn_cast<EnumConstantDecl>(D))
6669 return getCursorPlatformAvailabilityForDecl(
6670 cast<Decl>(EnumConst->getDeclContext()),
6671 always_deprecated,
6672 deprecated_message,
6673 always_unavailable,
6674 unavailable_message,
6675 availability,
6676 availability_size);
Guy Benyei11169dd2012-12-18 14:30:41 +00006677
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006678 return N;
6679}
6680
Guy Benyei11169dd2012-12-18 14:30:41 +00006681int clang_getCursorPlatformAvailability(CXCursor cursor,
6682 int *always_deprecated,
6683 CXString *deprecated_message,
6684 int *always_unavailable,
6685 CXString *unavailable_message,
6686 CXPlatformAvailability *availability,
6687 int availability_size) {
6688 if (always_deprecated)
6689 *always_deprecated = 0;
6690 if (deprecated_message)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006691 *deprecated_message = cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006692 if (always_unavailable)
6693 *always_unavailable = 0;
6694 if (unavailable_message)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006695 *unavailable_message = cxstring::createEmpty();
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006696
Guy Benyei11169dd2012-12-18 14:30:41 +00006697 if (!clang_isDeclaration(cursor.kind))
6698 return 0;
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006699
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006700 const Decl *D = cxcursor::getCursorDecl(cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00006701 if (!D)
6702 return 0;
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006703
6704 return getCursorPlatformAvailabilityForDecl(D, always_deprecated,
6705 deprecated_message,
6706 always_unavailable,
6707 unavailable_message,
6708 availability,
6709 availability_size);
Guy Benyei11169dd2012-12-18 14:30:41 +00006710}
6711
6712void clang_disposeCXPlatformAvailability(CXPlatformAvailability *availability) {
6713 clang_disposeString(availability->Platform);
6714 clang_disposeString(availability->Message);
6715}
6716
6717CXLanguageKind clang_getCursorLanguage(CXCursor cursor) {
6718 if (clang_isDeclaration(cursor.kind))
6719 return getDeclLanguage(cxcursor::getCursorDecl(cursor));
6720
6721 return CXLanguage_Invalid;
6722}
6723
6724 /// \brief If the given cursor is the "templated" declaration
6725 /// descibing a class or function template, return the class or
6726 /// function template.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006727static const Decl *maybeGetTemplateCursor(const Decl *D) {
Guy Benyei11169dd2012-12-18 14:30:41 +00006728 if (!D)
Craig Topper69186e72014-06-08 08:38:04 +00006729 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006730
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006731 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00006732 if (FunctionTemplateDecl *FunTmpl = FD->getDescribedFunctionTemplate())
6733 return FunTmpl;
6734
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006735 if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00006736 if (ClassTemplateDecl *ClassTmpl = RD->getDescribedClassTemplate())
6737 return ClassTmpl;
6738
6739 return D;
6740}
6741
Argyrios Kyrtzidis4e0854f2014-10-15 17:05:31 +00006742
6743enum CX_StorageClass clang_Cursor_getStorageClass(CXCursor C) {
6744 StorageClass sc = SC_None;
6745 const Decl *D = getCursorDecl(C);
6746 if (D) {
6747 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
6748 sc = FD->getStorageClass();
6749 } else if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
6750 sc = VD->getStorageClass();
6751 } else {
6752 return CX_SC_Invalid;
6753 }
6754 } else {
6755 return CX_SC_Invalid;
6756 }
6757 switch (sc) {
6758 case SC_None:
6759 return CX_SC_None;
6760 case SC_Extern:
6761 return CX_SC_Extern;
6762 case SC_Static:
6763 return CX_SC_Static;
6764 case SC_PrivateExtern:
6765 return CX_SC_PrivateExtern;
Argyrios Kyrtzidis4e0854f2014-10-15 17:05:31 +00006766 case SC_Auto:
6767 return CX_SC_Auto;
6768 case SC_Register:
6769 return CX_SC_Register;
Argyrios Kyrtzidis4e0854f2014-10-15 17:05:31 +00006770 }
Kaelyn Takataab61e702014-10-15 18:03:26 +00006771 llvm_unreachable("Unhandled storage class!");
Argyrios Kyrtzidis4e0854f2014-10-15 17:05:31 +00006772}
6773
Guy Benyei11169dd2012-12-18 14:30:41 +00006774CXCursor clang_getCursorSemanticParent(CXCursor cursor) {
6775 if (clang_isDeclaration(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006776 if (const Decl *D = getCursorDecl(cursor)) {
6777 const DeclContext *DC = D->getDeclContext();
Guy Benyei11169dd2012-12-18 14:30:41 +00006778 if (!DC)
6779 return clang_getNullCursor();
6780
6781 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
6782 getCursorTU(cursor));
6783 }
6784 }
6785
6786 if (clang_isStatement(cursor.kind) || clang_isExpression(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006787 if (const Decl *D = getCursorDecl(cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +00006788 return MakeCXCursor(D, getCursorTU(cursor));
6789 }
6790
6791 return clang_getNullCursor();
6792}
6793
6794CXCursor clang_getCursorLexicalParent(CXCursor cursor) {
6795 if (clang_isDeclaration(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006796 if (const Decl *D = getCursorDecl(cursor)) {
6797 const DeclContext *DC = D->getLexicalDeclContext();
Guy Benyei11169dd2012-12-18 14:30:41 +00006798 if (!DC)
6799 return clang_getNullCursor();
6800
6801 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
6802 getCursorTU(cursor));
6803 }
6804 }
6805
6806 // FIXME: Note that we can't easily compute the lexical context of a
6807 // statement or expression, so we return nothing.
6808 return clang_getNullCursor();
6809}
6810
6811CXFile clang_getIncludedFile(CXCursor cursor) {
6812 if (cursor.kind != CXCursor_InclusionDirective)
Craig Topper69186e72014-06-08 08:38:04 +00006813 return nullptr;
6814
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00006815 const InclusionDirective *ID = getCursorInclusionDirective(cursor);
Dmitri Gribenkof9304482013-01-23 15:56:07 +00006816 return const_cast<FileEntry *>(ID->getFile());
Guy Benyei11169dd2012-12-18 14:30:41 +00006817}
6818
Argyrios Kyrtzidis9adfd8a2013-04-18 22:15:49 +00006819unsigned clang_Cursor_getObjCPropertyAttributes(CXCursor C, unsigned reserved) {
6820 if (C.kind != CXCursor_ObjCPropertyDecl)
6821 return CXObjCPropertyAttr_noattr;
6822
6823 unsigned Result = CXObjCPropertyAttr_noattr;
6824 const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(getCursorDecl(C));
6825 ObjCPropertyDecl::PropertyAttributeKind Attr =
6826 PD->getPropertyAttributesAsWritten();
6827
6828#define SET_CXOBJCPROP_ATTR(A) \
6829 if (Attr & ObjCPropertyDecl::OBJC_PR_##A) \
6830 Result |= CXObjCPropertyAttr_##A
6831 SET_CXOBJCPROP_ATTR(readonly);
6832 SET_CXOBJCPROP_ATTR(getter);
6833 SET_CXOBJCPROP_ATTR(assign);
6834 SET_CXOBJCPROP_ATTR(readwrite);
6835 SET_CXOBJCPROP_ATTR(retain);
6836 SET_CXOBJCPROP_ATTR(copy);
6837 SET_CXOBJCPROP_ATTR(nonatomic);
6838 SET_CXOBJCPROP_ATTR(setter);
6839 SET_CXOBJCPROP_ATTR(atomic);
6840 SET_CXOBJCPROP_ATTR(weak);
6841 SET_CXOBJCPROP_ATTR(strong);
6842 SET_CXOBJCPROP_ATTR(unsafe_unretained);
6843#undef SET_CXOBJCPROP_ATTR
6844
6845 return Result;
6846}
6847
Argyrios Kyrtzidis9d9bc012013-04-18 23:29:12 +00006848unsigned clang_Cursor_getObjCDeclQualifiers(CXCursor C) {
6849 if (!clang_isDeclaration(C.kind))
6850 return CXObjCDeclQualifier_None;
6851
6852 Decl::ObjCDeclQualifier QT = Decl::OBJC_TQ_None;
6853 const Decl *D = getCursorDecl(C);
6854 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6855 QT = MD->getObjCDeclQualifier();
6856 else if (const ParmVarDecl *PD = dyn_cast<ParmVarDecl>(D))
6857 QT = PD->getObjCDeclQualifier();
6858 if (QT == Decl::OBJC_TQ_None)
6859 return CXObjCDeclQualifier_None;
6860
6861 unsigned Result = CXObjCDeclQualifier_None;
6862 if (QT & Decl::OBJC_TQ_In) Result |= CXObjCDeclQualifier_In;
6863 if (QT & Decl::OBJC_TQ_Inout) Result |= CXObjCDeclQualifier_Inout;
6864 if (QT & Decl::OBJC_TQ_Out) Result |= CXObjCDeclQualifier_Out;
6865 if (QT & Decl::OBJC_TQ_Bycopy) Result |= CXObjCDeclQualifier_Bycopy;
6866 if (QT & Decl::OBJC_TQ_Byref) Result |= CXObjCDeclQualifier_Byref;
6867 if (QT & Decl::OBJC_TQ_Oneway) Result |= CXObjCDeclQualifier_Oneway;
6868
6869 return Result;
6870}
6871
Argyrios Kyrtzidis7b50fc52013-07-05 20:44:37 +00006872unsigned clang_Cursor_isObjCOptional(CXCursor C) {
6873 if (!clang_isDeclaration(C.kind))
6874 return 0;
6875
6876 const Decl *D = getCursorDecl(C);
6877 if (const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(D))
6878 return PD->getPropertyImplementation() == ObjCPropertyDecl::Optional;
6879 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6880 return MD->getImplementationControl() == ObjCMethodDecl::Optional;
6881
6882 return 0;
6883}
6884
Argyrios Kyrtzidis23814e42013-04-18 23:53:05 +00006885unsigned clang_Cursor_isVariadic(CXCursor C) {
6886 if (!clang_isDeclaration(C.kind))
6887 return 0;
6888
6889 const Decl *D = getCursorDecl(C);
6890 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
6891 return FD->isVariadic();
6892 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6893 return MD->isVariadic();
6894
6895 return 0;
6896}
6897
Guy Benyei11169dd2012-12-18 14:30:41 +00006898CXSourceRange clang_Cursor_getCommentRange(CXCursor C) {
6899 if (!clang_isDeclaration(C.kind))
6900 return clang_getNullRange();
6901
6902 const Decl *D = getCursorDecl(C);
6903 ASTContext &Context = getCursorContext(C);
6904 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6905 if (!RC)
6906 return clang_getNullRange();
6907
6908 return cxloc::translateSourceRange(Context, RC->getSourceRange());
6909}
6910
6911CXString clang_Cursor_getRawCommentText(CXCursor C) {
6912 if (!clang_isDeclaration(C.kind))
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006913 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006914
6915 const Decl *D = getCursorDecl(C);
6916 ASTContext &Context = getCursorContext(C);
6917 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6918 StringRef RawText = RC ? RC->getRawText(Context.getSourceManager()) :
6919 StringRef();
6920
6921 // Don't duplicate the string because RawText points directly into source
6922 // code.
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006923 return cxstring::createRef(RawText);
Guy Benyei11169dd2012-12-18 14:30:41 +00006924}
6925
6926CXString clang_Cursor_getBriefCommentText(CXCursor C) {
6927 if (!clang_isDeclaration(C.kind))
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006928 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006929
6930 const Decl *D = getCursorDecl(C);
6931 const ASTContext &Context = getCursorContext(C);
6932 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6933
6934 if (RC) {
6935 StringRef BriefText = RC->getBriefText(Context);
6936
6937 // Don't duplicate the string because RawComment ensures that this memory
6938 // will not go away.
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006939 return cxstring::createRef(BriefText);
Guy Benyei11169dd2012-12-18 14:30:41 +00006940 }
6941
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006942 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006943}
6944
Guy Benyei11169dd2012-12-18 14:30:41 +00006945CXModule clang_Cursor_getModule(CXCursor C) {
6946 if (C.kind == CXCursor_ModuleImportDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006947 if (const ImportDecl *ImportD =
6948 dyn_cast_or_null<ImportDecl>(getCursorDecl(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00006949 return ImportD->getImportedModule();
6950 }
6951
Craig Topper69186e72014-06-08 08:38:04 +00006952 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006953}
6954
Argyrios Kyrtzidisf6d49c32014-05-14 23:14:37 +00006955CXModule clang_getModuleForFile(CXTranslationUnit TU, CXFile File) {
6956 if (isNotUsableTU(TU)) {
6957 LOG_BAD_TU(TU);
6958 return nullptr;
6959 }
6960 if (!File)
6961 return nullptr;
6962 FileEntry *FE = static_cast<FileEntry *>(File);
6963
6964 ASTUnit &Unit = *cxtu::getASTUnit(TU);
6965 HeaderSearch &HS = Unit.getPreprocessor().getHeaderSearchInfo();
6966 ModuleMap::KnownHeader Header = HS.findModuleForHeader(FE);
6967
Richard Smithfeb54b62014-10-23 02:01:19 +00006968 return Header.getModule();
Argyrios Kyrtzidisf6d49c32014-05-14 23:14:37 +00006969}
6970
Argyrios Kyrtzidis12fdb9e2013-04-26 22:47:49 +00006971CXFile clang_Module_getASTFile(CXModule CXMod) {
6972 if (!CXMod)
Craig Topper69186e72014-06-08 08:38:04 +00006973 return nullptr;
Argyrios Kyrtzidis12fdb9e2013-04-26 22:47:49 +00006974 Module *Mod = static_cast<Module*>(CXMod);
6975 return const_cast<FileEntry *>(Mod->getASTFile());
6976}
6977
Guy Benyei11169dd2012-12-18 14:30:41 +00006978CXModule clang_Module_getParent(CXModule CXMod) {
6979 if (!CXMod)
Craig Topper69186e72014-06-08 08:38:04 +00006980 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006981 Module *Mod = static_cast<Module*>(CXMod);
6982 return Mod->Parent;
6983}
6984
6985CXString clang_Module_getName(CXModule CXMod) {
6986 if (!CXMod)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006987 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006988 Module *Mod = static_cast<Module*>(CXMod);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006989 return cxstring::createDup(Mod->Name);
Guy Benyei11169dd2012-12-18 14:30:41 +00006990}
6991
6992CXString clang_Module_getFullName(CXModule CXMod) {
6993 if (!CXMod)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006994 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006995 Module *Mod = static_cast<Module*>(CXMod);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006996 return cxstring::createDup(Mod->getFullModuleName());
Guy Benyei11169dd2012-12-18 14:30:41 +00006997}
6998
Argyrios Kyrtzidis884337f2014-05-15 04:44:25 +00006999int clang_Module_isSystem(CXModule CXMod) {
7000 if (!CXMod)
7001 return 0;
7002 Module *Mod = static_cast<Module*>(CXMod);
7003 return Mod->IsSystem;
7004}
7005
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00007006unsigned clang_Module_getNumTopLevelHeaders(CXTranslationUnit TU,
7007 CXModule CXMod) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00007008 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00007009 LOG_BAD_TU(TU);
7010 return 0;
7011 }
7012 if (!CXMod)
Guy Benyei11169dd2012-12-18 14:30:41 +00007013 return 0;
7014 Module *Mod = static_cast<Module*>(CXMod);
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00007015 FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
7016 ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
7017 return TopHeaders.size();
Guy Benyei11169dd2012-12-18 14:30:41 +00007018}
7019
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00007020CXFile clang_Module_getTopLevelHeader(CXTranslationUnit TU,
7021 CXModule CXMod, unsigned Index) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00007022 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00007023 LOG_BAD_TU(TU);
Craig Topper69186e72014-06-08 08:38:04 +00007024 return nullptr;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00007025 }
7026 if (!CXMod)
Craig Topper69186e72014-06-08 08:38:04 +00007027 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00007028 Module *Mod = static_cast<Module*>(CXMod);
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00007029 FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
Guy Benyei11169dd2012-12-18 14:30:41 +00007030
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00007031 ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
7032 if (Index < TopHeaders.size())
7033 return const_cast<FileEntry *>(TopHeaders[Index]);
Guy Benyei11169dd2012-12-18 14:30:41 +00007034
Craig Topper69186e72014-06-08 08:38:04 +00007035 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00007036}
7037
7038} // end: extern "C"
7039
7040//===----------------------------------------------------------------------===//
7041// C++ AST instrospection.
7042//===----------------------------------------------------------------------===//
7043
7044extern "C" {
Saleem Abdulrasool6ea75db2015-10-27 15:50:22 +00007045unsigned clang_CXXField_isMutable(CXCursor C) {
7046 if (!clang_isDeclaration(C.kind))
7047 return 0;
7048
7049 if (const auto D = cxcursor::getCursorDecl(C))
7050 if (const auto FD = dyn_cast_or_null<FieldDecl>(D))
7051 return FD->isMutable() ? 1 : 0;
7052 return 0;
7053}
7054
Dmitri Gribenko62770be2013-05-17 18:38:35 +00007055unsigned clang_CXXMethod_isPureVirtual(CXCursor C) {
7056 if (!clang_isDeclaration(C.kind))
7057 return 0;
7058
Dmitri Gribenko62770be2013-05-17 18:38:35 +00007059 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00007060 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00007061 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Dmitri Gribenko62770be2013-05-17 18:38:35 +00007062 return (Method && Method->isVirtual() && Method->isPure()) ? 1 : 0;
7063}
7064
Dmitri Gribenkoe570ede2014-04-07 14:59:13 +00007065unsigned clang_CXXMethod_isConst(CXCursor C) {
7066 if (!clang_isDeclaration(C.kind))
7067 return 0;
7068
7069 const Decl *D = cxcursor::getCursorDecl(C);
7070 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00007071 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Dmitri Gribenkoe570ede2014-04-07 14:59:13 +00007072 return (Method && (Method->getTypeQualifiers() & Qualifiers::Const)) ? 1 : 0;
7073}
7074
Guy Benyei11169dd2012-12-18 14:30:41 +00007075unsigned clang_CXXMethod_isStatic(CXCursor C) {
7076 if (!clang_isDeclaration(C.kind))
7077 return 0;
7078
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00007079 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00007080 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00007081 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00007082 return (Method && Method->isStatic()) ? 1 : 0;
7083}
7084
7085unsigned clang_CXXMethod_isVirtual(CXCursor C) {
7086 if (!clang_isDeclaration(C.kind))
7087 return 0;
7088
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00007089 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00007090 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00007091 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00007092 return (Method && Method->isVirtual()) ? 1 : 0;
7093}
7094} // end: extern "C"
7095
7096//===----------------------------------------------------------------------===//
7097// Attribute introspection.
7098//===----------------------------------------------------------------------===//
7099
7100extern "C" {
7101CXType clang_getIBOutletCollectionType(CXCursor C) {
7102 if (C.kind != CXCursor_IBOutletCollectionAttr)
7103 return cxtype::MakeCXType(QualType(), cxcursor::getCursorTU(C));
7104
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00007105 const IBOutletCollectionAttr *A =
Guy Benyei11169dd2012-12-18 14:30:41 +00007106 cast<IBOutletCollectionAttr>(cxcursor::getCursorAttr(C));
7107
7108 return cxtype::MakeCXType(A->getInterface(), cxcursor::getCursorTU(C));
7109}
7110} // end: extern "C"
7111
7112//===----------------------------------------------------------------------===//
7113// Inspecting memory usage.
7114//===----------------------------------------------------------------------===//
7115
7116typedef std::vector<CXTUResourceUsageEntry> MemUsageEntries;
7117
7118static inline void createCXTUResourceUsageEntry(MemUsageEntries &entries,
7119 enum CXTUResourceUsageKind k,
7120 unsigned long amount) {
7121 CXTUResourceUsageEntry entry = { k, amount };
7122 entries.push_back(entry);
7123}
7124
7125extern "C" {
7126
7127const char *clang_getTUResourceUsageName(CXTUResourceUsageKind kind) {
7128 const char *str = "";
7129 switch (kind) {
7130 case CXTUResourceUsage_AST:
7131 str = "ASTContext: expressions, declarations, and types";
7132 break;
7133 case CXTUResourceUsage_Identifiers:
7134 str = "ASTContext: identifiers";
7135 break;
7136 case CXTUResourceUsage_Selectors:
7137 str = "ASTContext: selectors";
7138 break;
7139 case CXTUResourceUsage_GlobalCompletionResults:
7140 str = "Code completion: cached global results";
7141 break;
7142 case CXTUResourceUsage_SourceManagerContentCache:
7143 str = "SourceManager: content cache allocator";
7144 break;
7145 case CXTUResourceUsage_AST_SideTables:
7146 str = "ASTContext: side tables";
7147 break;
7148 case CXTUResourceUsage_SourceManager_Membuffer_Malloc:
7149 str = "SourceManager: malloc'ed memory buffers";
7150 break;
7151 case CXTUResourceUsage_SourceManager_Membuffer_MMap:
7152 str = "SourceManager: mmap'ed memory buffers";
7153 break;
7154 case CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc:
7155 str = "ExternalASTSource: malloc'ed memory buffers";
7156 break;
7157 case CXTUResourceUsage_ExternalASTSource_Membuffer_MMap:
7158 str = "ExternalASTSource: mmap'ed memory buffers";
7159 break;
7160 case CXTUResourceUsage_Preprocessor:
7161 str = "Preprocessor: malloc'ed memory";
7162 break;
7163 case CXTUResourceUsage_PreprocessingRecord:
7164 str = "Preprocessor: PreprocessingRecord";
7165 break;
7166 case CXTUResourceUsage_SourceManager_DataStructures:
7167 str = "SourceManager: data structures and tables";
7168 break;
7169 case CXTUResourceUsage_Preprocessor_HeaderSearch:
7170 str = "Preprocessor: header search tables";
7171 break;
7172 }
7173 return str;
7174}
7175
7176CXTUResourceUsage clang_getCXTUResourceUsage(CXTranslationUnit TU) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00007177 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00007178 LOG_BAD_TU(TU);
Craig Topper69186e72014-06-08 08:38:04 +00007179 CXTUResourceUsage usage = { (void*) nullptr, 0, nullptr };
Guy Benyei11169dd2012-12-18 14:30:41 +00007180 return usage;
7181 }
7182
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007183 ASTUnit *astUnit = cxtu::getASTUnit(TU);
Ahmed Charlesb8984322014-03-07 20:03:18 +00007184 std::unique_ptr<MemUsageEntries> entries(new MemUsageEntries());
Guy Benyei11169dd2012-12-18 14:30:41 +00007185 ASTContext &astContext = astUnit->getASTContext();
7186
7187 // How much memory is used by AST nodes and types?
7188 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST,
7189 (unsigned long) astContext.getASTAllocatedMemory());
7190
7191 // How much memory is used by identifiers?
7192 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Identifiers,
7193 (unsigned long) astContext.Idents.getAllocator().getTotalMemory());
7194
7195 // How much memory is used for selectors?
7196 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Selectors,
7197 (unsigned long) astContext.Selectors.getTotalMemory());
7198
7199 // How much memory is used by ASTContext's side tables?
7200 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST_SideTables,
7201 (unsigned long) astContext.getSideTableAllocatedMemory());
7202
7203 // How much memory is used for caching global code completion results?
7204 unsigned long completionBytes = 0;
7205 if (GlobalCodeCompletionAllocator *completionAllocator =
Alp Tokerf994cef2014-07-05 03:08:06 +00007206 astUnit->getCachedCompletionAllocator().get()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00007207 completionBytes = completionAllocator->getTotalMemory();
7208 }
7209 createCXTUResourceUsageEntry(*entries,
7210 CXTUResourceUsage_GlobalCompletionResults,
7211 completionBytes);
7212
7213 // How much memory is being used by SourceManager's content cache?
7214 createCXTUResourceUsageEntry(*entries,
7215 CXTUResourceUsage_SourceManagerContentCache,
7216 (unsigned long) astContext.getSourceManager().getContentCacheSize());
7217
7218 // How much memory is being used by the MemoryBuffer's in SourceManager?
7219 const SourceManager::MemoryBufferSizes &srcBufs =
7220 astUnit->getSourceManager().getMemoryBufferSizes();
7221
7222 createCXTUResourceUsageEntry(*entries,
7223 CXTUResourceUsage_SourceManager_Membuffer_Malloc,
7224 (unsigned long) srcBufs.malloc_bytes);
7225 createCXTUResourceUsageEntry(*entries,
7226 CXTUResourceUsage_SourceManager_Membuffer_MMap,
7227 (unsigned long) srcBufs.mmap_bytes);
7228 createCXTUResourceUsageEntry(*entries,
7229 CXTUResourceUsage_SourceManager_DataStructures,
7230 (unsigned long) astContext.getSourceManager()
7231 .getDataStructureSizes());
7232
7233 // How much memory is being used by the ExternalASTSource?
7234 if (ExternalASTSource *esrc = astContext.getExternalSource()) {
7235 const ExternalASTSource::MemoryBufferSizes &sizes =
7236 esrc->getMemoryBufferSizes();
7237
7238 createCXTUResourceUsageEntry(*entries,
7239 CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc,
7240 (unsigned long) sizes.malloc_bytes);
7241 createCXTUResourceUsageEntry(*entries,
7242 CXTUResourceUsage_ExternalASTSource_Membuffer_MMap,
7243 (unsigned long) sizes.mmap_bytes);
7244 }
7245
7246 // How much memory is being used by the Preprocessor?
7247 Preprocessor &pp = astUnit->getPreprocessor();
7248 createCXTUResourceUsageEntry(*entries,
7249 CXTUResourceUsage_Preprocessor,
7250 pp.getTotalMemory());
7251
7252 if (PreprocessingRecord *pRec = pp.getPreprocessingRecord()) {
7253 createCXTUResourceUsageEntry(*entries,
7254 CXTUResourceUsage_PreprocessingRecord,
7255 pRec->getTotalMemory());
7256 }
7257
7258 createCXTUResourceUsageEntry(*entries,
7259 CXTUResourceUsage_Preprocessor_HeaderSearch,
7260 pp.getHeaderSearchInfo().getTotalMemory());
Craig Topper69186e72014-06-08 08:38:04 +00007261
Guy Benyei11169dd2012-12-18 14:30:41 +00007262 CXTUResourceUsage usage = { (void*) entries.get(),
7263 (unsigned) entries->size(),
Alexander Kornienko6ee521c2015-01-23 15:36:10 +00007264 !entries->empty() ? &(*entries)[0] : nullptr };
Ahmed Charles9a16beb2014-03-07 19:33:25 +00007265 entries.release();
Guy Benyei11169dd2012-12-18 14:30:41 +00007266 return usage;
7267}
7268
7269void clang_disposeCXTUResourceUsage(CXTUResourceUsage usage) {
7270 if (usage.data)
7271 delete (MemUsageEntries*) usage.data;
7272}
7273
Argyrios Kyrtzidis0e282ef2013-12-06 18:55:45 +00007274CXSourceRangeList *clang_getSkippedRanges(CXTranslationUnit TU, CXFile file) {
7275 CXSourceRangeList *skipped = new CXSourceRangeList;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00007276 skipped->count = 0;
Craig Topper69186e72014-06-08 08:38:04 +00007277 skipped->ranges = nullptr;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00007278
Dmitri Gribenko852d6222014-02-11 15:02:48 +00007279 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00007280 LOG_BAD_TU(TU);
7281 return skipped;
7282 }
7283
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00007284 if (!file)
7285 return skipped;
7286
7287 ASTUnit *astUnit = cxtu::getASTUnit(TU);
7288 PreprocessingRecord *ppRec = astUnit->getPreprocessor().getPreprocessingRecord();
7289 if (!ppRec)
7290 return skipped;
7291
7292 ASTContext &Ctx = astUnit->getASTContext();
7293 SourceManager &sm = Ctx.getSourceManager();
7294 FileEntry *fileEntry = static_cast<FileEntry *>(file);
7295 FileID wantedFileID = sm.translateFile(fileEntry);
7296
7297 const std::vector<SourceRange> &SkippedRanges = ppRec->getSkippedRanges();
7298 std::vector<SourceRange> wantedRanges;
7299 for (std::vector<SourceRange>::const_iterator i = SkippedRanges.begin(), ei = SkippedRanges.end();
7300 i != ei; ++i) {
7301 if (sm.getFileID(i->getBegin()) == wantedFileID || sm.getFileID(i->getEnd()) == wantedFileID)
7302 wantedRanges.push_back(*i);
7303 }
7304
7305 skipped->count = wantedRanges.size();
7306 skipped->ranges = new CXSourceRange[skipped->count];
7307 for (unsigned i = 0, ei = skipped->count; i != ei; ++i)
7308 skipped->ranges[i] = cxloc::translateSourceRange(Ctx, wantedRanges[i]);
7309
7310 return skipped;
7311}
7312
Argyrios Kyrtzidis0e282ef2013-12-06 18:55:45 +00007313void clang_disposeSourceRangeList(CXSourceRangeList *ranges) {
7314 if (ranges) {
7315 delete[] ranges->ranges;
7316 delete ranges;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00007317 }
7318}
7319
Guy Benyei11169dd2012-12-18 14:30:41 +00007320} // end extern "C"
7321
7322void clang::PrintLibclangResourceUsage(CXTranslationUnit TU) {
7323 CXTUResourceUsage Usage = clang_getCXTUResourceUsage(TU);
7324 for (unsigned I = 0; I != Usage.numEntries; ++I)
7325 fprintf(stderr, " %s: %lu\n",
7326 clang_getTUResourceUsageName(Usage.entries[I].kind),
7327 Usage.entries[I].amount);
7328
7329 clang_disposeCXTUResourceUsage(Usage);
7330}
7331
7332//===----------------------------------------------------------------------===//
7333// Misc. utility functions.
7334//===----------------------------------------------------------------------===//
7335
7336/// Default to using an 8 MB stack size on "safety" threads.
7337static unsigned SafetyStackThreadSize = 8 << 20;
7338
7339namespace clang {
7340
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00007341bool RunSafely(llvm::CrashRecoveryContext &CRC, llvm::function_ref<void()> Fn,
Guy Benyei11169dd2012-12-18 14:30:41 +00007342 unsigned Size) {
7343 if (!Size)
7344 Size = GetSafetyThreadStackSize();
7345 if (Size)
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00007346 return CRC.RunSafelyOnThread(Fn, Size);
7347 return CRC.RunSafely(Fn);
Guy Benyei11169dd2012-12-18 14:30:41 +00007348}
7349
7350unsigned GetSafetyThreadStackSize() {
7351 return SafetyStackThreadSize;
7352}
7353
7354void SetSafetyThreadStackSize(unsigned Value) {
7355 SafetyStackThreadSize = Value;
7356}
7357
Alexander Kornienkoab9db512015-06-22 23:07:51 +00007358}
Guy Benyei11169dd2012-12-18 14:30:41 +00007359
7360void clang::setThreadBackgroundPriority() {
7361 if (getenv("LIBCLANG_BGPRIO_DISABLE"))
7362 return;
7363
Alp Toker1a86ad22014-07-06 06:24:00 +00007364#ifdef USE_DARWIN_THREADS
Guy Benyei11169dd2012-12-18 14:30:41 +00007365 setpriority(PRIO_DARWIN_THREAD, 0, PRIO_DARWIN_BG);
7366#endif
7367}
7368
7369void cxindex::printDiagsToStderr(ASTUnit *Unit) {
7370 if (!Unit)
7371 return;
7372
7373 for (ASTUnit::stored_diag_iterator D = Unit->stored_diag_begin(),
7374 DEnd = Unit->stored_diag_end();
7375 D != DEnd; ++D) {
Ben Langmuir749323f2014-04-22 17:40:12 +00007376 CXStoredDiagnostic Diag(*D, Unit->getLangOpts());
Guy Benyei11169dd2012-12-18 14:30:41 +00007377 CXString Msg = clang_formatDiagnostic(&Diag,
7378 clang_defaultDiagnosticDisplayOptions());
7379 fprintf(stderr, "%s\n", clang_getCString(Msg));
7380 clang_disposeString(Msg);
7381 }
7382#ifdef LLVM_ON_WIN32
7383 // On Windows, force a flush, since there may be multiple copies of
7384 // stderr and stdout in the file system, all with different buffers
7385 // but writing to the same device.
7386 fflush(stderr);
7387#endif
7388}
7389
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007390MacroInfo *cxindex::getMacroInfo(const IdentifierInfo &II,
7391 SourceLocation MacroDefLoc,
7392 CXTranslationUnit TU){
7393 if (MacroDefLoc.isInvalid() || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00007394 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007395 if (!II.hadMacroDefinition())
Craig Topper69186e72014-06-08 08:38:04 +00007396 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007397
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007398 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00007399 Preprocessor &PP = Unit->getPreprocessor();
Richard Smith20e883e2015-04-29 23:20:19 +00007400 MacroDirective *MD = PP.getLocalMacroDirectiveHistory(&II);
Argyrios Kyrtzidisb6210df2013-03-26 17:17:01 +00007401 if (MD) {
7402 for (MacroDirective::DefInfo
7403 Def = MD->getDefinition(); Def; Def = Def.getPreviousDefinition()) {
7404 if (MacroDefLoc == Def.getMacroInfo()->getDefinitionLoc())
7405 return Def.getMacroInfo();
7406 }
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007407 }
7408
Craig Topper69186e72014-06-08 08:38:04 +00007409 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007410}
7411
Richard Smith66a81862015-05-04 02:25:31 +00007412const MacroInfo *cxindex::getMacroInfo(const MacroDefinitionRecord *MacroDef,
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00007413 CXTranslationUnit TU) {
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007414 if (!MacroDef || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00007415 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007416 const IdentifierInfo *II = MacroDef->getName();
7417 if (!II)
Craig Topper69186e72014-06-08 08:38:04 +00007418 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007419
7420 return getMacroInfo(*II, MacroDef->getLocation(), TU);
7421}
7422
Richard Smith66a81862015-05-04 02:25:31 +00007423MacroDefinitionRecord *
7424cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI, const Token &Tok,
7425 CXTranslationUnit TU) {
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007426 if (!MI || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00007427 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007428 if (Tok.isNot(tok::raw_identifier))
Craig Topper69186e72014-06-08 08:38:04 +00007429 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007430
7431 if (MI->getNumTokens() == 0)
Craig Topper69186e72014-06-08 08:38:04 +00007432 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007433 SourceRange DefRange(MI->getReplacementToken(0).getLocation(),
7434 MI->getDefinitionEndLoc());
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007435 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007436
7437 // Check that the token is inside the definition and not its argument list.
7438 SourceManager &SM = Unit->getSourceManager();
7439 if (SM.isBeforeInTranslationUnit(Tok.getLocation(), DefRange.getBegin()))
Craig Topper69186e72014-06-08 08:38:04 +00007440 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007441 if (SM.isBeforeInTranslationUnit(DefRange.getEnd(), Tok.getLocation()))
Craig Topper69186e72014-06-08 08:38:04 +00007442 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007443
7444 Preprocessor &PP = Unit->getPreprocessor();
7445 PreprocessingRecord *PPRec = PP.getPreprocessingRecord();
7446 if (!PPRec)
Craig Topper69186e72014-06-08 08:38:04 +00007447 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007448
Alp Toker2d57cea2014-05-17 04:53:25 +00007449 IdentifierInfo &II = PP.getIdentifierTable().get(Tok.getRawIdentifier());
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007450 if (!II.hadMacroDefinition())
Craig Topper69186e72014-06-08 08:38:04 +00007451 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007452
7453 // Check that the identifier is not one of the macro arguments.
7454 if (std::find(MI->arg_begin(), MI->arg_end(), &II) != MI->arg_end())
Craig Topper69186e72014-06-08 08:38:04 +00007455 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007456
Richard Smith20e883e2015-04-29 23:20:19 +00007457 MacroDirective *InnerMD = PP.getLocalMacroDirectiveHistory(&II);
Argyrios Kyrtzidis09c9e812013-02-20 00:54:57 +00007458 if (!InnerMD)
Craig Topper69186e72014-06-08 08:38:04 +00007459 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007460
Argyrios Kyrtzidisb6210df2013-03-26 17:17:01 +00007461 return PPRec->findMacroDefinition(InnerMD->getMacroInfo());
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007462}
7463
Richard Smith66a81862015-05-04 02:25:31 +00007464MacroDefinitionRecord *
7465cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI, SourceLocation Loc,
7466 CXTranslationUnit TU) {
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007467 if (Loc.isInvalid() || !MI || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00007468 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007469
7470 if (MI->getNumTokens() == 0)
Craig Topper69186e72014-06-08 08:38:04 +00007471 return nullptr;
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007472 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007473 Preprocessor &PP = Unit->getPreprocessor();
7474 if (!PP.getPreprocessingRecord())
Craig Topper69186e72014-06-08 08:38:04 +00007475 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007476 Loc = Unit->getSourceManager().getSpellingLoc(Loc);
7477 Token Tok;
7478 if (PP.getRawToken(Loc, Tok))
Craig Topper69186e72014-06-08 08:38:04 +00007479 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007480
7481 return checkForMacroInMacroDefinition(MI, Tok, TU);
7482}
7483
Guy Benyei11169dd2012-12-18 14:30:41 +00007484extern "C" {
7485
7486CXString clang_getClangVersion() {
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00007487 return cxstring::createDup(getClangFullVersion());
Guy Benyei11169dd2012-12-18 14:30:41 +00007488}
7489
7490} // end: extern "C"
7491
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007492Logger &cxindex::Logger::operator<<(CXTranslationUnit TU) {
7493 if (TU) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007494 if (ASTUnit *Unit = cxtu::getASTUnit(TU)) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007495 LogOS << '<' << Unit->getMainFileName() << '>';
Argyrios Kyrtzidis37f2ab42013-03-05 20:21:14 +00007496 if (Unit->isMainFileAST())
7497 LogOS << " (" << Unit->getASTFileName() << ')';
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007498 return *this;
7499 }
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00007500 } else {
7501 LogOS << "<NULL TU>";
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007502 }
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007503 return *this;
7504}
7505
Argyrios Kyrtzidisba4b5f82013-03-08 02:32:26 +00007506Logger &cxindex::Logger::operator<<(const FileEntry *FE) {
7507 *this << FE->getName();
7508 return *this;
7509}
7510
7511Logger &cxindex::Logger::operator<<(CXCursor cursor) {
7512 CXString cursorName = clang_getCursorDisplayName(cursor);
7513 *this << cursorName << "@" << clang_getCursorLocation(cursor);
7514 clang_disposeString(cursorName);
7515 return *this;
7516}
7517
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007518Logger &cxindex::Logger::operator<<(CXSourceLocation Loc) {
7519 CXFile File;
7520 unsigned Line, Column;
Craig Topper69186e72014-06-08 08:38:04 +00007521 clang_getFileLocation(Loc, &File, &Line, &Column, nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007522 CXString FileName = clang_getFileName(File);
7523 *this << llvm::format("(%s:%d:%d)", clang_getCString(FileName), Line, Column);
7524 clang_disposeString(FileName);
7525 return *this;
7526}
7527
7528Logger &cxindex::Logger::operator<<(CXSourceRange range) {
7529 CXSourceLocation BLoc = clang_getRangeStart(range);
7530 CXSourceLocation ELoc = clang_getRangeEnd(range);
7531
7532 CXFile BFile;
7533 unsigned BLine, BColumn;
Craig Topper69186e72014-06-08 08:38:04 +00007534 clang_getFileLocation(BLoc, &BFile, &BLine, &BColumn, nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007535
7536 CXFile EFile;
7537 unsigned ELine, EColumn;
Craig Topper69186e72014-06-08 08:38:04 +00007538 clang_getFileLocation(ELoc, &EFile, &ELine, &EColumn, nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007539
7540 CXString BFileName = clang_getFileName(BFile);
7541 if (BFile == EFile) {
7542 *this << llvm::format("[%s %d:%d-%d:%d]", clang_getCString(BFileName),
7543 BLine, BColumn, ELine, EColumn);
7544 } else {
7545 CXString EFileName = clang_getFileName(EFile);
7546 *this << llvm::format("[%s:%d:%d - ", clang_getCString(BFileName),
7547 BLine, BColumn)
7548 << llvm::format("%s:%d:%d]", clang_getCString(EFileName),
7549 ELine, EColumn);
7550 clang_disposeString(EFileName);
7551 }
7552 clang_disposeString(BFileName);
7553 return *this;
7554}
7555
7556Logger &cxindex::Logger::operator<<(CXString Str) {
7557 *this << clang_getCString(Str);
7558 return *this;
7559}
7560
7561Logger &cxindex::Logger::operator<<(const llvm::format_object_base &Fmt) {
7562 LogOS << Fmt;
7563 return *this;
7564}
7565
Chandler Carruth37ad2582014-06-27 15:14:39 +00007566static llvm::ManagedStatic<llvm::sys::Mutex> LoggingMutex;
7567
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007568cxindex::Logger::~Logger() {
Chandler Carruth37ad2582014-06-27 15:14:39 +00007569 llvm::sys::ScopedLock L(*LoggingMutex);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007570
7571 static llvm::TimeRecord sBeginTR = llvm::TimeRecord::getCurrentTime();
7572
Dmitri Gribenkof8579502013-01-12 19:30:44 +00007573 raw_ostream &OS = llvm::errs();
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007574 OS << "[libclang:" << Name << ':';
7575
Alp Toker1a86ad22014-07-06 06:24:00 +00007576#ifdef USE_DARWIN_THREADS
7577 // TODO: Portability.
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007578 mach_port_t tid = pthread_mach_thread_np(pthread_self());
7579 OS << tid << ':';
7580#endif
7581
7582 llvm::TimeRecord TR = llvm::TimeRecord::getCurrentTime();
7583 OS << llvm::format("%7.4f] ", TR.getWallTime() - sBeginTR.getWallTime());
Yaron Keren09fb7c62015-03-10 07:33:23 +00007584 OS << Msg << '\n';
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007585
7586 if (Trace) {
Zachary Turner1fe2a8d2015-03-05 19:15:09 +00007587 llvm::sys::PrintStackTrace(OS);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007588 OS << "--------------------------------------------------\n";
7589 }
7590}