blob: a49437b73865e8bab688d9a8d18f371e568969fc [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);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001945
Guy Benyei11169dd2012-12-18 14:30:41 +00001946private:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001947 void AddDeclarationNameInfo(const Stmt *S);
Guy Benyei11169dd2012-12-18 14:30:41 +00001948 void AddNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier);
1949 void AddExplicitTemplateArgs(const ASTTemplateArgumentListInfo *A);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001950 void AddMemberRef(const FieldDecl *D, SourceLocation L);
1951 void AddStmt(const Stmt *S);
1952 void AddDecl(const Decl *D, bool isFirst = true);
Guy Benyei11169dd2012-12-18 14:30:41 +00001953 void AddTypeLoc(TypeSourceInfo *TI);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001954 void EnqueueChildren(const Stmt *S);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001955 void EnqueueChildren(const OMPClause *S);
Guy Benyei11169dd2012-12-18 14:30:41 +00001956};
Alexander Kornienkoab9db512015-06-22 23:07:51 +00001957} // end anonyous namespace
Guy Benyei11169dd2012-12-18 14:30:41 +00001958
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001959void EnqueueVisitor::AddDeclarationNameInfo(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001960 // 'S' should always be non-null, since it comes from the
1961 // statement we are visiting.
1962 WL.push_back(DeclarationNameInfoVisit(S, Parent));
1963}
1964
1965void
1966EnqueueVisitor::AddNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier) {
1967 if (Qualifier)
1968 WL.push_back(NestedNameSpecifierLocVisit(Qualifier, Parent));
1969}
1970
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001971void EnqueueVisitor::AddStmt(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001972 if (S)
1973 WL.push_back(StmtVisit(S, Parent));
1974}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001975void EnqueueVisitor::AddDecl(const Decl *D, bool isFirst) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001976 if (D)
1977 WL.push_back(DeclVisit(D, Parent, isFirst));
1978}
1979void EnqueueVisitor::
1980 AddExplicitTemplateArgs(const ASTTemplateArgumentListInfo *A) {
1981 if (A)
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001982 WL.push_back(ExplicitTemplateArgsVisit(A, Parent));
Guy Benyei11169dd2012-12-18 14:30:41 +00001983}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001984void EnqueueVisitor::AddMemberRef(const FieldDecl *D, SourceLocation L) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001985 if (D)
1986 WL.push_back(MemberRefVisit(D, L, Parent));
1987}
1988void EnqueueVisitor::AddTypeLoc(TypeSourceInfo *TI) {
1989 if (TI)
1990 WL.push_back(TypeLocVisit(TI->getTypeLoc(), Parent));
1991 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001992void EnqueueVisitor::EnqueueChildren(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001993 unsigned size = WL.size();
Benjamin Kramer642f1732015-07-02 21:03:14 +00001994 for (const Stmt *SubStmt : S->children()) {
1995 AddStmt(SubStmt);
Guy Benyei11169dd2012-12-18 14:30:41 +00001996 }
1997 if (size == WL.size())
1998 return;
1999 // Now reverse the entries we just added. This will match the DFS
2000 // ordering performed by the worklist.
2001 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
2002 std::reverse(I, E);
2003}
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002004namespace {
2005class OMPClauseEnqueue : public ConstOMPClauseVisitor<OMPClauseEnqueue> {
2006 EnqueueVisitor *Visitor;
Alexey Bataev756c1962013-09-24 03:17:45 +00002007 /// \brief Process clauses with list of variables.
2008 template <typename T>
2009 void VisitOMPClauseList(T *Node);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002010public:
2011 OMPClauseEnqueue(EnqueueVisitor *Visitor) : Visitor(Visitor) { }
2012#define OPENMP_CLAUSE(Name, Class) \
2013 void Visit##Class(const Class *C);
2014#include "clang/Basic/OpenMPKinds.def"
2015};
2016
Alexey Bataevaadd52e2014-02-13 05:29:23 +00002017void OMPClauseEnqueue::VisitOMPIfClause(const OMPIfClause *C) {
2018 Visitor->AddStmt(C->getCondition());
2019}
2020
Alexey Bataev3778b602014-07-17 07:32:53 +00002021void OMPClauseEnqueue::VisitOMPFinalClause(const OMPFinalClause *C) {
2022 Visitor->AddStmt(C->getCondition());
2023}
2024
Alexey Bataev568a8332014-03-06 06:15:19 +00002025void OMPClauseEnqueue::VisitOMPNumThreadsClause(const OMPNumThreadsClause *C) {
2026 Visitor->AddStmt(C->getNumThreads());
2027}
2028
Alexey Bataev62c87d22014-03-21 04:51:18 +00002029void OMPClauseEnqueue::VisitOMPSafelenClause(const OMPSafelenClause *C) {
2030 Visitor->AddStmt(C->getSafelen());
2031}
2032
Alexey Bataev66b15b52015-08-21 11:14:16 +00002033void OMPClauseEnqueue::VisitOMPSimdlenClause(const OMPSimdlenClause *C) {
2034 Visitor->AddStmt(C->getSimdlen());
2035}
2036
Alexander Musman8bd31e62014-05-27 15:12:19 +00002037void OMPClauseEnqueue::VisitOMPCollapseClause(const OMPCollapseClause *C) {
2038 Visitor->AddStmt(C->getNumForLoops());
2039}
2040
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002041void OMPClauseEnqueue::VisitOMPDefaultClause(const OMPDefaultClause *C) { }
Alexey Bataev756c1962013-09-24 03:17:45 +00002042
Alexey Bataevbcbadb62014-05-06 06:04:14 +00002043void OMPClauseEnqueue::VisitOMPProcBindClause(const OMPProcBindClause *C) { }
2044
Alexey Bataev56dafe82014-06-20 07:16:17 +00002045void OMPClauseEnqueue::VisitOMPScheduleClause(const OMPScheduleClause *C) {
2046 Visitor->AddStmt(C->getChunkSize());
Alexey Bataev040d5402015-05-12 08:35:28 +00002047 Visitor->AddStmt(C->getHelperChunkSize());
Alexey Bataev56dafe82014-06-20 07:16:17 +00002048}
2049
Alexey Bataev10e775f2015-07-30 11:36:16 +00002050void OMPClauseEnqueue::VisitOMPOrderedClause(const OMPOrderedClause *C) {
2051 Visitor->AddStmt(C->getNumForLoops());
2052}
Alexey Bataev142e1fc2014-06-20 09:44:06 +00002053
Alexey Bataev236070f2014-06-20 11:19:47 +00002054void OMPClauseEnqueue::VisitOMPNowaitClause(const OMPNowaitClause *) {}
2055
Alexey Bataev7aea99a2014-07-17 12:19:31 +00002056void OMPClauseEnqueue::VisitOMPUntiedClause(const OMPUntiedClause *) {}
2057
Alexey Bataev74ba3a52014-07-17 12:47:03 +00002058void OMPClauseEnqueue::VisitOMPMergeableClause(const OMPMergeableClause *) {}
2059
Alexey Bataevf98b00c2014-07-23 02:27:21 +00002060void OMPClauseEnqueue::VisitOMPReadClause(const OMPReadClause *) {}
2061
Alexey Bataevdea47612014-07-23 07:46:59 +00002062void OMPClauseEnqueue::VisitOMPWriteClause(const OMPWriteClause *) {}
2063
Alexey Bataev67a4f222014-07-23 10:25:33 +00002064void OMPClauseEnqueue::VisitOMPUpdateClause(const OMPUpdateClause *) {}
2065
Alexey Bataev459dec02014-07-24 06:46:57 +00002066void OMPClauseEnqueue::VisitOMPCaptureClause(const OMPCaptureClause *) {}
2067
Alexey Bataev82bad8b2014-07-24 08:55:34 +00002068void OMPClauseEnqueue::VisitOMPSeqCstClause(const OMPSeqCstClause *) {}
2069
Alexey Bataev346265e2015-09-25 10:37:12 +00002070void OMPClauseEnqueue::VisitOMPThreadsClause(const OMPThreadsClause *) {}
2071
Alexey Bataevd14d1e62015-09-28 06:39:35 +00002072void OMPClauseEnqueue::VisitOMPSIMDClause(const OMPSIMDClause *) {}
2073
Michael Wonge710d542015-08-07 16:16:36 +00002074void OMPClauseEnqueue::VisitOMPDeviceClause(const OMPDeviceClause *C) {
2075 Visitor->AddStmt(C->getDevice());
2076}
2077
Alexey Bataev756c1962013-09-24 03:17:45 +00002078template<typename T>
2079void OMPClauseEnqueue::VisitOMPClauseList(T *Node) {
Alexey Bataev03b340a2014-10-21 03:16:40 +00002080 for (const auto *I : Node->varlists()) {
Aaron Ballman2205d2a2014-03-14 15:55:35 +00002081 Visitor->AddStmt(I);
Alexey Bataev03b340a2014-10-21 03:16:40 +00002082 }
Alexey Bataev756c1962013-09-24 03:17:45 +00002083}
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002084
2085void OMPClauseEnqueue::VisitOMPPrivateClause(const OMPPrivateClause *C) {
Alexey Bataev756c1962013-09-24 03:17:45 +00002086 VisitOMPClauseList(C);
Alexey Bataev03b340a2014-10-21 03:16:40 +00002087 for (const auto *E : C->private_copies()) {
2088 Visitor->AddStmt(E);
2089 }
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002090}
Alexey Bataevd5af8e42013-10-01 05:32:34 +00002091void OMPClauseEnqueue::VisitOMPFirstprivateClause(
2092 const OMPFirstprivateClause *C) {
2093 VisitOMPClauseList(C);
2094}
Alexander Musman1bb328c2014-06-04 13:06:39 +00002095void OMPClauseEnqueue::VisitOMPLastprivateClause(
2096 const OMPLastprivateClause *C) {
2097 VisitOMPClauseList(C);
Alexey Bataev38e89532015-04-16 04:54:05 +00002098 for (auto *E : C->private_copies()) {
2099 Visitor->AddStmt(E);
2100 }
2101 for (auto *E : C->source_exprs()) {
2102 Visitor->AddStmt(E);
2103 }
2104 for (auto *E : C->destination_exprs()) {
2105 Visitor->AddStmt(E);
2106 }
2107 for (auto *E : C->assignment_ops()) {
2108 Visitor->AddStmt(E);
2109 }
Alexander Musman1bb328c2014-06-04 13:06:39 +00002110}
Alexey Bataev758e55e2013-09-06 18:03:48 +00002111void OMPClauseEnqueue::VisitOMPSharedClause(const OMPSharedClause *C) {
Alexey Bataev756c1962013-09-24 03:17:45 +00002112 VisitOMPClauseList(C);
Alexey Bataev758e55e2013-09-06 18:03:48 +00002113}
Alexey Bataevc5e02582014-06-16 07:08:35 +00002114void OMPClauseEnqueue::VisitOMPReductionClause(const OMPReductionClause *C) {
2115 VisitOMPClauseList(C);
Alexey Bataevf24e7b12015-10-08 09:10:53 +00002116 for (auto *E : C->privates()) {
2117 Visitor->AddStmt(E);
2118 }
Alexey Bataev794ba0d2015-04-10 10:43:45 +00002119 for (auto *E : C->lhs_exprs()) {
2120 Visitor->AddStmt(E);
2121 }
2122 for (auto *E : C->rhs_exprs()) {
2123 Visitor->AddStmt(E);
2124 }
2125 for (auto *E : C->reduction_ops()) {
2126 Visitor->AddStmt(E);
2127 }
Alexey Bataevc5e02582014-06-16 07:08:35 +00002128}
Alexander Musman8dba6642014-04-22 13:09:42 +00002129void OMPClauseEnqueue::VisitOMPLinearClause(const OMPLinearClause *C) {
2130 VisitOMPClauseList(C);
Alexey Bataevbd9fec12015-08-18 06:47:21 +00002131 for (const auto *E : C->privates()) {
2132 Visitor->AddStmt(E);
2133 }
Alexander Musman3276a272015-03-21 10:12:56 +00002134 for (const auto *E : C->inits()) {
2135 Visitor->AddStmt(E);
2136 }
2137 for (const auto *E : C->updates()) {
2138 Visitor->AddStmt(E);
2139 }
2140 for (const auto *E : C->finals()) {
2141 Visitor->AddStmt(E);
2142 }
Alexander Musman8dba6642014-04-22 13:09:42 +00002143 Visitor->AddStmt(C->getStep());
Alexander Musman3276a272015-03-21 10:12:56 +00002144 Visitor->AddStmt(C->getCalcStep());
Alexander Musman8dba6642014-04-22 13:09:42 +00002145}
Alexander Musmanf0d76e72014-05-29 14:36:25 +00002146void OMPClauseEnqueue::VisitOMPAlignedClause(const OMPAlignedClause *C) {
2147 VisitOMPClauseList(C);
2148 Visitor->AddStmt(C->getAlignment());
2149}
Alexey Bataevd48bcd82014-03-31 03:36:38 +00002150void OMPClauseEnqueue::VisitOMPCopyinClause(const OMPCopyinClause *C) {
2151 VisitOMPClauseList(C);
Alexey Bataevf56f98c2015-04-16 05:39:01 +00002152 for (auto *E : C->source_exprs()) {
2153 Visitor->AddStmt(E);
2154 }
2155 for (auto *E : C->destination_exprs()) {
2156 Visitor->AddStmt(E);
2157 }
2158 for (auto *E : C->assignment_ops()) {
2159 Visitor->AddStmt(E);
2160 }
Alexey Bataevd48bcd82014-03-31 03:36:38 +00002161}
Alexey Bataevbae9a792014-06-27 10:37:06 +00002162void
2163OMPClauseEnqueue::VisitOMPCopyprivateClause(const OMPCopyprivateClause *C) {
2164 VisitOMPClauseList(C);
Alexey Bataeva63048e2015-03-23 06:18:07 +00002165 for (auto *E : C->source_exprs()) {
2166 Visitor->AddStmt(E);
2167 }
2168 for (auto *E : C->destination_exprs()) {
2169 Visitor->AddStmt(E);
2170 }
2171 for (auto *E : C->assignment_ops()) {
2172 Visitor->AddStmt(E);
2173 }
Alexey Bataevbae9a792014-06-27 10:37:06 +00002174}
Alexey Bataev6125da92014-07-21 11:26:11 +00002175void OMPClauseEnqueue::VisitOMPFlushClause(const OMPFlushClause *C) {
2176 VisitOMPClauseList(C);
2177}
Alexey Bataev1c2cfbc2015-06-23 14:25:19 +00002178void OMPClauseEnqueue::VisitOMPDependClause(const OMPDependClause *C) {
2179 VisitOMPClauseList(C);
2180}
Alexander Kornienkoab9db512015-06-22 23:07:51 +00002181}
Alexey Bataev756c1962013-09-24 03:17:45 +00002182
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002183void EnqueueVisitor::EnqueueChildren(const OMPClause *S) {
2184 unsigned size = WL.size();
2185 OMPClauseEnqueue Visitor(this);
2186 Visitor.Visit(S);
2187 if (size == WL.size())
2188 return;
2189 // Now reverse the entries we just added. This will match the DFS
2190 // ordering performed by the worklist.
2191 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
2192 std::reverse(I, E);
2193}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002194void EnqueueVisitor::VisitAddrLabelExpr(const AddrLabelExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002195 WL.push_back(LabelRefVisit(E->getLabel(), E->getLabelLoc(), Parent));
2196}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002197void EnqueueVisitor::VisitBlockExpr(const BlockExpr *B) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002198 AddDecl(B->getBlockDecl());
2199}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002200void EnqueueVisitor::VisitCompoundLiteralExpr(const CompoundLiteralExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002201 EnqueueChildren(E);
2202 AddTypeLoc(E->getTypeSourceInfo());
2203}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002204void EnqueueVisitor::VisitCompoundStmt(const CompoundStmt *S) {
Pete Cooper57d3f142015-07-30 17:22:52 +00002205 for (auto &I : llvm::reverse(S->body()))
2206 AddStmt(I);
Guy Benyei11169dd2012-12-18 14:30:41 +00002207}
2208void EnqueueVisitor::
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002209VisitMSDependentExistsStmt(const MSDependentExistsStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002210 AddStmt(S->getSubStmt());
2211 AddDeclarationNameInfo(S);
2212 if (NestedNameSpecifierLoc QualifierLoc = S->getQualifierLoc())
2213 AddNestedNameSpecifierLoc(QualifierLoc);
2214}
2215
2216void EnqueueVisitor::
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002217VisitCXXDependentScopeMemberExpr(const CXXDependentScopeMemberExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002218 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
2219 AddDeclarationNameInfo(E);
2220 if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
2221 AddNestedNameSpecifierLoc(QualifierLoc);
2222 if (!E->isImplicitAccess())
2223 AddStmt(E->getBase());
2224}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002225void EnqueueVisitor::VisitCXXNewExpr(const CXXNewExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002226 // Enqueue the initializer , if any.
2227 AddStmt(E->getInitializer());
2228 // Enqueue the array size, if any.
2229 AddStmt(E->getArraySize());
2230 // Enqueue the allocated type.
2231 AddTypeLoc(E->getAllocatedTypeSourceInfo());
2232 // Enqueue the placement arguments.
2233 for (unsigned I = E->getNumPlacementArgs(); I > 0; --I)
2234 AddStmt(E->getPlacementArg(I-1));
2235}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002236void EnqueueVisitor::VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *CE) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002237 for (unsigned I = CE->getNumArgs(); I > 1 /* Yes, this is 1 */; --I)
2238 AddStmt(CE->getArg(I-1));
2239 AddStmt(CE->getCallee());
2240 AddStmt(CE->getArg(0));
2241}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002242void EnqueueVisitor::VisitCXXPseudoDestructorExpr(
2243 const CXXPseudoDestructorExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002244 // Visit the name of the type being destroyed.
2245 AddTypeLoc(E->getDestroyedTypeInfo());
2246 // Visit the scope type that looks disturbingly like the nested-name-specifier
2247 // but isn't.
2248 AddTypeLoc(E->getScopeTypeInfo());
2249 // Visit the nested-name-specifier.
2250 if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
2251 AddNestedNameSpecifierLoc(QualifierLoc);
2252 // Visit base expression.
2253 AddStmt(E->getBase());
2254}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002255void EnqueueVisitor::VisitCXXScalarValueInitExpr(
2256 const CXXScalarValueInitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002257 AddTypeLoc(E->getTypeSourceInfo());
2258}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002259void EnqueueVisitor::VisitCXXTemporaryObjectExpr(
2260 const CXXTemporaryObjectExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002261 EnqueueChildren(E);
2262 AddTypeLoc(E->getTypeSourceInfo());
2263}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002264void EnqueueVisitor::VisitCXXTypeidExpr(const CXXTypeidExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002265 EnqueueChildren(E);
2266 if (E->isTypeOperand())
2267 AddTypeLoc(E->getTypeOperandSourceInfo());
2268}
2269
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002270void EnqueueVisitor::VisitCXXUnresolvedConstructExpr(
2271 const CXXUnresolvedConstructExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002272 EnqueueChildren(E);
2273 AddTypeLoc(E->getTypeSourceInfo());
2274}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002275void EnqueueVisitor::VisitCXXUuidofExpr(const CXXUuidofExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002276 EnqueueChildren(E);
2277 if (E->isTypeOperand())
2278 AddTypeLoc(E->getTypeOperandSourceInfo());
2279}
2280
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002281void EnqueueVisitor::VisitCXXCatchStmt(const CXXCatchStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002282 EnqueueChildren(S);
2283 AddDecl(S->getExceptionDecl());
2284}
2285
Argyrios Kyrtzidis99891242014-11-13 09:03:21 +00002286void EnqueueVisitor::VisitCXXForRangeStmt(const CXXForRangeStmt *S) {
Argyrios Kyrtzidiscde70692014-11-13 09:50:19 +00002287 AddStmt(S->getBody());
Argyrios Kyrtzidis99891242014-11-13 09:03:21 +00002288 AddStmt(S->getRangeInit());
Argyrios Kyrtzidiscde70692014-11-13 09:50:19 +00002289 AddDecl(S->getLoopVariable());
Argyrios Kyrtzidis99891242014-11-13 09:03:21 +00002290}
2291
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002292void EnqueueVisitor::VisitDeclRefExpr(const DeclRefExpr *DR) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002293 if (DR->hasExplicitTemplateArgs()) {
2294 AddExplicitTemplateArgs(&DR->getExplicitTemplateArgs());
2295 }
2296 WL.push_back(DeclRefExprParts(DR, Parent));
2297}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002298void EnqueueVisitor::VisitDependentScopeDeclRefExpr(
2299 const DependentScopeDeclRefExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002300 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
2301 AddDeclarationNameInfo(E);
2302 AddNestedNameSpecifierLoc(E->getQualifierLoc());
2303}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002304void EnqueueVisitor::VisitDeclStmt(const DeclStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002305 unsigned size = WL.size();
2306 bool isFirst = true;
Aaron Ballman535bbcc2014-03-14 17:01:24 +00002307 for (const auto *D : S->decls()) {
2308 AddDecl(D, isFirst);
Guy Benyei11169dd2012-12-18 14:30:41 +00002309 isFirst = false;
2310 }
2311 if (size == WL.size())
2312 return;
2313 // Now reverse the entries we just added. This will match the DFS
2314 // ordering performed by the worklist.
2315 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
2316 std::reverse(I, E);
2317}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002318void EnqueueVisitor::VisitDesignatedInitExpr(const DesignatedInitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002319 AddStmt(E->getInit());
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002320 for (DesignatedInitExpr::const_reverse_designators_iterator
Guy Benyei11169dd2012-12-18 14:30:41 +00002321 D = E->designators_rbegin(), DEnd = E->designators_rend();
2322 D != DEnd; ++D) {
2323 if (D->isFieldDesignator()) {
2324 if (FieldDecl *Field = D->getField())
2325 AddMemberRef(Field, D->getFieldLoc());
2326 continue;
2327 }
2328 if (D->isArrayDesignator()) {
2329 AddStmt(E->getArrayIndex(*D));
2330 continue;
2331 }
2332 assert(D->isArrayRangeDesignator() && "Unknown designator kind");
2333 AddStmt(E->getArrayRangeEnd(*D));
2334 AddStmt(E->getArrayRangeStart(*D));
2335 }
2336}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002337void EnqueueVisitor::VisitExplicitCastExpr(const ExplicitCastExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002338 EnqueueChildren(E);
2339 AddTypeLoc(E->getTypeInfoAsWritten());
2340}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002341void EnqueueVisitor::VisitForStmt(const ForStmt *FS) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002342 AddStmt(FS->getBody());
2343 AddStmt(FS->getInc());
2344 AddStmt(FS->getCond());
2345 AddDecl(FS->getConditionVariable());
2346 AddStmt(FS->getInit());
2347}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002348void EnqueueVisitor::VisitGotoStmt(const GotoStmt *GS) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002349 WL.push_back(LabelRefVisit(GS->getLabel(), GS->getLabelLoc(), Parent));
2350}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002351void EnqueueVisitor::VisitIfStmt(const IfStmt *If) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002352 AddStmt(If->getElse());
2353 AddStmt(If->getThen());
2354 AddStmt(If->getCond());
2355 AddDecl(If->getConditionVariable());
2356}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002357void EnqueueVisitor::VisitInitListExpr(const InitListExpr *IE) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002358 // We care about the syntactic form of the initializer list, only.
2359 if (InitListExpr *Syntactic = IE->getSyntacticForm())
2360 IE = Syntactic;
2361 EnqueueChildren(IE);
2362}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002363void EnqueueVisitor::VisitMemberExpr(const MemberExpr *M) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002364 WL.push_back(MemberExprParts(M, Parent));
2365
2366 // If the base of the member access expression is an implicit 'this', don't
2367 // visit it.
2368 // FIXME: If we ever want to show these implicit accesses, this will be
2369 // unfortunate. However, clang_getCursor() relies on this behavior.
Argyrios Kyrtzidis58d0e7a2015-03-13 04:40:07 +00002370 if (M->isImplicitAccess())
2371 return;
2372
2373 // Ignore base anonymous struct/union fields, otherwise they will shadow the
2374 // real field that that we are interested in.
2375 if (auto *SubME = dyn_cast<MemberExpr>(M->getBase())) {
2376 if (auto *FD = dyn_cast_or_null<FieldDecl>(SubME->getMemberDecl())) {
2377 if (FD->isAnonymousStructOrUnion()) {
2378 AddStmt(SubME->getBase());
2379 return;
2380 }
2381 }
2382 }
2383
2384 AddStmt(M->getBase());
Guy Benyei11169dd2012-12-18 14:30:41 +00002385}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002386void EnqueueVisitor::VisitObjCEncodeExpr(const ObjCEncodeExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002387 AddTypeLoc(E->getEncodedTypeSourceInfo());
2388}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002389void EnqueueVisitor::VisitObjCMessageExpr(const ObjCMessageExpr *M) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002390 EnqueueChildren(M);
2391 AddTypeLoc(M->getClassReceiverTypeInfo());
2392}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002393void EnqueueVisitor::VisitOffsetOfExpr(const OffsetOfExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002394 // Visit the components of the offsetof expression.
2395 for (unsigned N = E->getNumComponents(), I = N; I > 0; --I) {
2396 typedef OffsetOfExpr::OffsetOfNode OffsetOfNode;
2397 const OffsetOfNode &Node = E->getComponent(I-1);
2398 switch (Node.getKind()) {
2399 case OffsetOfNode::Array:
2400 AddStmt(E->getIndexExpr(Node.getArrayExprIndex()));
2401 break;
2402 case OffsetOfNode::Field:
2403 AddMemberRef(Node.getField(), Node.getSourceRange().getEnd());
2404 break;
2405 case OffsetOfNode::Identifier:
2406 case OffsetOfNode::Base:
2407 continue;
2408 }
2409 }
2410 // Visit the type into which we're computing the offset.
2411 AddTypeLoc(E->getTypeSourceInfo());
2412}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002413void EnqueueVisitor::VisitOverloadExpr(const OverloadExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002414 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
2415 WL.push_back(OverloadExprParts(E, Parent));
2416}
2417void EnqueueVisitor::VisitUnaryExprOrTypeTraitExpr(
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002418 const UnaryExprOrTypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002419 EnqueueChildren(E);
2420 if (E->isArgumentType())
2421 AddTypeLoc(E->getArgumentTypeInfo());
2422}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002423void EnqueueVisitor::VisitStmt(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002424 EnqueueChildren(S);
2425}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002426void EnqueueVisitor::VisitSwitchStmt(const SwitchStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002427 AddStmt(S->getBody());
2428 AddStmt(S->getCond());
2429 AddDecl(S->getConditionVariable());
2430}
2431
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002432void EnqueueVisitor::VisitWhileStmt(const WhileStmt *W) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002433 AddStmt(W->getBody());
2434 AddStmt(W->getCond());
2435 AddDecl(W->getConditionVariable());
2436}
2437
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002438void EnqueueVisitor::VisitTypeTraitExpr(const TypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002439 for (unsigned I = E->getNumArgs(); I > 0; --I)
2440 AddTypeLoc(E->getArg(I-1));
2441}
2442
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002443void EnqueueVisitor::VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002444 AddTypeLoc(E->getQueriedTypeSourceInfo());
2445}
2446
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002447void EnqueueVisitor::VisitExpressionTraitExpr(const ExpressionTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002448 EnqueueChildren(E);
2449}
2450
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002451void EnqueueVisitor::VisitUnresolvedMemberExpr(const UnresolvedMemberExpr *U) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002452 VisitOverloadExpr(U);
2453 if (!U->isImplicitAccess())
2454 AddStmt(U->getBase());
2455}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002456void EnqueueVisitor::VisitVAArgExpr(const VAArgExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002457 AddStmt(E->getSubExpr());
2458 AddTypeLoc(E->getWrittenTypeInfo());
2459}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002460void EnqueueVisitor::VisitSizeOfPackExpr(const SizeOfPackExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002461 WL.push_back(SizeOfPackExprParts(E, Parent));
2462}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002463void EnqueueVisitor::VisitOpaqueValueExpr(const OpaqueValueExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002464 // If the opaque value has a source expression, just transparently
2465 // visit that. This is useful for (e.g.) pseudo-object expressions.
2466 if (Expr *SourceExpr = E->getSourceExpr())
2467 return Visit(SourceExpr);
2468}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002469void EnqueueVisitor::VisitLambdaExpr(const LambdaExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002470 AddStmt(E->getBody());
2471 WL.push_back(LambdaExprParts(E, Parent));
2472}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002473void EnqueueVisitor::VisitPseudoObjectExpr(const PseudoObjectExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002474 // Treat the expression like its syntactic form.
2475 Visit(E->getSyntacticForm());
2476}
2477
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002478void EnqueueVisitor::VisitOMPExecutableDirective(
2479 const OMPExecutableDirective *D) {
2480 EnqueueChildren(D);
2481 for (ArrayRef<OMPClause *>::iterator I = D->clauses().begin(),
2482 E = D->clauses().end();
2483 I != E; ++I)
2484 EnqueueChildren(*I);
2485}
2486
Alexander Musman3aaab662014-08-19 11:27:13 +00002487void EnqueueVisitor::VisitOMPLoopDirective(const OMPLoopDirective *D) {
2488 VisitOMPExecutableDirective(D);
2489}
2490
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002491void EnqueueVisitor::VisitOMPParallelDirective(const OMPParallelDirective *D) {
2492 VisitOMPExecutableDirective(D);
2493}
2494
Alexey Bataev1b59ab52014-02-27 08:29:12 +00002495void EnqueueVisitor::VisitOMPSimdDirective(const OMPSimdDirective *D) {
Alexander Musman3aaab662014-08-19 11:27:13 +00002496 VisitOMPLoopDirective(D);
Alexey Bataev1b59ab52014-02-27 08:29:12 +00002497}
2498
Alexey Bataevf29276e2014-06-18 04:14:57 +00002499void EnqueueVisitor::VisitOMPForDirective(const OMPForDirective *D) {
Alexander Musman3aaab662014-08-19 11:27:13 +00002500 VisitOMPLoopDirective(D);
Alexey Bataevf29276e2014-06-18 04:14:57 +00002501}
2502
Alexander Musmanf82886e2014-09-18 05:12:34 +00002503void EnqueueVisitor::VisitOMPForSimdDirective(const OMPForSimdDirective *D) {
2504 VisitOMPLoopDirective(D);
2505}
2506
Alexey Bataevd3f8dd22014-06-25 11:44:49 +00002507void EnqueueVisitor::VisitOMPSectionsDirective(const OMPSectionsDirective *D) {
2508 VisitOMPExecutableDirective(D);
2509}
2510
Alexey Bataev1e0498a2014-06-26 08:21:58 +00002511void EnqueueVisitor::VisitOMPSectionDirective(const OMPSectionDirective *D) {
2512 VisitOMPExecutableDirective(D);
2513}
2514
Alexey Bataevd1e40fb2014-06-26 12:05:45 +00002515void EnqueueVisitor::VisitOMPSingleDirective(const OMPSingleDirective *D) {
2516 VisitOMPExecutableDirective(D);
2517}
2518
Alexander Musman80c22892014-07-17 08:54:58 +00002519void EnqueueVisitor::VisitOMPMasterDirective(const OMPMasterDirective *D) {
2520 VisitOMPExecutableDirective(D);
2521}
2522
Alexander Musmand9ed09f2014-07-21 09:42:05 +00002523void EnqueueVisitor::VisitOMPCriticalDirective(const OMPCriticalDirective *D) {
2524 VisitOMPExecutableDirective(D);
2525 AddDeclarationNameInfo(D);
2526}
2527
Alexey Bataev4acb8592014-07-07 13:01:15 +00002528void
2529EnqueueVisitor::VisitOMPParallelForDirective(const OMPParallelForDirective *D) {
Alexander Musman3aaab662014-08-19 11:27:13 +00002530 VisitOMPLoopDirective(D);
Alexey Bataev4acb8592014-07-07 13:01:15 +00002531}
2532
Alexander Musmane4e893b2014-09-23 09:33:00 +00002533void EnqueueVisitor::VisitOMPParallelForSimdDirective(
2534 const OMPParallelForSimdDirective *D) {
2535 VisitOMPLoopDirective(D);
2536}
2537
Alexey Bataev84d0b3e2014-07-08 08:12:03 +00002538void EnqueueVisitor::VisitOMPParallelSectionsDirective(
2539 const OMPParallelSectionsDirective *D) {
2540 VisitOMPExecutableDirective(D);
2541}
2542
Alexey Bataev9c2e8ee2014-07-11 11:25:16 +00002543void EnqueueVisitor::VisitOMPTaskDirective(const OMPTaskDirective *D) {
2544 VisitOMPExecutableDirective(D);
2545}
2546
Alexey Bataev68446b72014-07-18 07:47:19 +00002547void
2548EnqueueVisitor::VisitOMPTaskyieldDirective(const OMPTaskyieldDirective *D) {
2549 VisitOMPExecutableDirective(D);
2550}
2551
Alexey Bataev4d1dfea2014-07-18 09:11:51 +00002552void EnqueueVisitor::VisitOMPBarrierDirective(const OMPBarrierDirective *D) {
2553 VisitOMPExecutableDirective(D);
2554}
2555
Alexey Bataev2df347a2014-07-18 10:17:07 +00002556void EnqueueVisitor::VisitOMPTaskwaitDirective(const OMPTaskwaitDirective *D) {
2557 VisitOMPExecutableDirective(D);
2558}
2559
Alexey Bataevc30dd2d2015-06-18 12:14:09 +00002560void EnqueueVisitor::VisitOMPTaskgroupDirective(
2561 const OMPTaskgroupDirective *D) {
2562 VisitOMPExecutableDirective(D);
2563}
2564
Alexey Bataev6125da92014-07-21 11:26:11 +00002565void EnqueueVisitor::VisitOMPFlushDirective(const OMPFlushDirective *D) {
2566 VisitOMPExecutableDirective(D);
2567}
2568
Alexey Bataev9fb6e642014-07-22 06:45:04 +00002569void EnqueueVisitor::VisitOMPOrderedDirective(const OMPOrderedDirective *D) {
2570 VisitOMPExecutableDirective(D);
2571}
2572
Alexey Bataev0162e452014-07-22 10:10:35 +00002573void EnqueueVisitor::VisitOMPAtomicDirective(const OMPAtomicDirective *D) {
2574 VisitOMPExecutableDirective(D);
2575}
2576
Alexey Bataev0bd520b2014-09-19 08:19:49 +00002577void EnqueueVisitor::VisitOMPTargetDirective(const OMPTargetDirective *D) {
2578 VisitOMPExecutableDirective(D);
2579}
2580
Michael Wong65f367f2015-07-21 13:44:28 +00002581void EnqueueVisitor::VisitOMPTargetDataDirective(const
2582 OMPTargetDataDirective *D) {
2583 VisitOMPExecutableDirective(D);
2584}
2585
Alexey Bataev13314bf2014-10-09 04:18:56 +00002586void EnqueueVisitor::VisitOMPTeamsDirective(const OMPTeamsDirective *D) {
2587 VisitOMPExecutableDirective(D);
2588}
2589
Alexey Bataev6d4ed052015-07-01 06:57:41 +00002590void EnqueueVisitor::VisitOMPCancellationPointDirective(
2591 const OMPCancellationPointDirective *D) {
2592 VisitOMPExecutableDirective(D);
2593}
2594
Alexey Bataev80909872015-07-02 11:25:17 +00002595void EnqueueVisitor::VisitOMPCancelDirective(const OMPCancelDirective *D) {
2596 VisitOMPExecutableDirective(D);
2597}
2598
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002599void CursorVisitor::EnqueueWorkList(VisitorWorkList &WL, const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002600 EnqueueVisitor(WL, MakeCXCursor(S, StmtParent, TU,RegionOfInterest)).Visit(S);
2601}
2602
2603bool CursorVisitor::IsInRegionOfInterest(CXCursor C) {
2604 if (RegionOfInterest.isValid()) {
2605 SourceRange Range = getRawCursorExtent(C);
2606 if (Range.isInvalid() || CompareRegionOfInterest(Range))
2607 return false;
2608 }
2609 return true;
2610}
2611
2612bool CursorVisitor::RunVisitorWorkList(VisitorWorkList &WL) {
2613 while (!WL.empty()) {
2614 // Dequeue the worklist item.
Robert Wilhelm25284cc2013-08-23 16:11:15 +00002615 VisitorJob LI = WL.pop_back_val();
Guy Benyei11169dd2012-12-18 14:30:41 +00002616
2617 // Set the Parent field, then back to its old value once we're done.
2618 SetParentRAII SetParent(Parent, StmtParent, LI.getParent());
2619
2620 switch (LI.getKind()) {
2621 case VisitorJob::DeclVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002622 const Decl *D = cast<DeclVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002623 if (!D)
2624 continue;
2625
2626 // For now, perform default visitation for Decls.
2627 if (Visit(MakeCXCursor(D, TU, RegionOfInterest,
2628 cast<DeclVisit>(&LI)->isFirst())))
2629 return true;
2630
2631 continue;
2632 }
2633 case VisitorJob::ExplicitTemplateArgsVisitKind: {
2634 const ASTTemplateArgumentListInfo *ArgList =
2635 cast<ExplicitTemplateArgsVisit>(&LI)->get();
2636 for (const TemplateArgumentLoc *Arg = ArgList->getTemplateArgs(),
2637 *ArgEnd = Arg + ArgList->NumTemplateArgs;
2638 Arg != ArgEnd; ++Arg) {
2639 if (VisitTemplateArgumentLoc(*Arg))
2640 return true;
2641 }
2642 continue;
2643 }
2644 case VisitorJob::TypeLocVisitKind: {
2645 // Perform default visitation for TypeLocs.
2646 if (Visit(cast<TypeLocVisit>(&LI)->get()))
2647 return true;
2648 continue;
2649 }
2650 case VisitorJob::LabelRefVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002651 const LabelDecl *LS = cast<LabelRefVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002652 if (LabelStmt *stmt = LS->getStmt()) {
2653 if (Visit(MakeCursorLabelRef(stmt, cast<LabelRefVisit>(&LI)->getLoc(),
2654 TU))) {
2655 return true;
2656 }
2657 }
2658 continue;
2659 }
2660
2661 case VisitorJob::NestedNameSpecifierLocVisitKind: {
2662 NestedNameSpecifierLocVisit *V = cast<NestedNameSpecifierLocVisit>(&LI);
2663 if (VisitNestedNameSpecifierLoc(V->get()))
2664 return true;
2665 continue;
2666 }
2667
2668 case VisitorJob::DeclarationNameInfoVisitKind: {
2669 if (VisitDeclarationNameInfo(cast<DeclarationNameInfoVisit>(&LI)
2670 ->get()))
2671 return true;
2672 continue;
2673 }
2674 case VisitorJob::MemberRefVisitKind: {
2675 MemberRefVisit *V = cast<MemberRefVisit>(&LI);
2676 if (Visit(MakeCursorMemberRef(V->get(), V->getLoc(), TU)))
2677 return true;
2678 continue;
2679 }
2680 case VisitorJob::StmtVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002681 const Stmt *S = cast<StmtVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002682 if (!S)
2683 continue;
2684
2685 // Update the current cursor.
2686 CXCursor Cursor = MakeCXCursor(S, StmtParent, TU, RegionOfInterest);
2687 if (!IsInRegionOfInterest(Cursor))
2688 continue;
2689 switch (Visitor(Cursor, Parent, ClientData)) {
2690 case CXChildVisit_Break: return true;
2691 case CXChildVisit_Continue: break;
2692 case CXChildVisit_Recurse:
2693 if (PostChildrenVisitor)
Craig Topper69186e72014-06-08 08:38:04 +00002694 WL.push_back(PostChildrenVisit(nullptr, Cursor));
Guy Benyei11169dd2012-12-18 14:30:41 +00002695 EnqueueWorkList(WL, S);
2696 break;
2697 }
2698 continue;
2699 }
2700 case VisitorJob::MemberExprPartsKind: {
2701 // Handle the other pieces in the MemberExpr besides the base.
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002702 const MemberExpr *M = cast<MemberExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002703
2704 // Visit the nested-name-specifier
2705 if (NestedNameSpecifierLoc QualifierLoc = M->getQualifierLoc())
2706 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2707 return true;
2708
2709 // Visit the declaration name.
2710 if (VisitDeclarationNameInfo(M->getMemberNameInfo()))
2711 return true;
2712
2713 // Visit the explicitly-specified template arguments, if any.
2714 if (M->hasExplicitTemplateArgs()) {
2715 for (const TemplateArgumentLoc *Arg = M->getTemplateArgs(),
2716 *ArgEnd = Arg + M->getNumTemplateArgs();
2717 Arg != ArgEnd; ++Arg) {
2718 if (VisitTemplateArgumentLoc(*Arg))
2719 return true;
2720 }
2721 }
2722 continue;
2723 }
2724 case VisitorJob::DeclRefExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002725 const DeclRefExpr *DR = cast<DeclRefExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002726 // Visit nested-name-specifier, if present.
2727 if (NestedNameSpecifierLoc QualifierLoc = DR->getQualifierLoc())
2728 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2729 return true;
2730 // Visit declaration name.
2731 if (VisitDeclarationNameInfo(DR->getNameInfo()))
2732 return true;
2733 continue;
2734 }
2735 case VisitorJob::OverloadExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002736 const OverloadExpr *O = cast<OverloadExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002737 // Visit the nested-name-specifier.
2738 if (NestedNameSpecifierLoc QualifierLoc = O->getQualifierLoc())
2739 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2740 return true;
2741 // Visit the declaration name.
2742 if (VisitDeclarationNameInfo(O->getNameInfo()))
2743 return true;
2744 // Visit the overloaded declaration reference.
2745 if (Visit(MakeCursorOverloadedDeclRef(O, TU)))
2746 return true;
2747 continue;
2748 }
2749 case VisitorJob::SizeOfPackExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002750 const SizeOfPackExpr *E = cast<SizeOfPackExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002751 NamedDecl *Pack = E->getPack();
2752 if (isa<TemplateTypeParmDecl>(Pack)) {
2753 if (Visit(MakeCursorTypeRef(cast<TemplateTypeParmDecl>(Pack),
2754 E->getPackLoc(), TU)))
2755 return true;
2756
2757 continue;
2758 }
2759
2760 if (isa<TemplateTemplateParmDecl>(Pack)) {
2761 if (Visit(MakeCursorTemplateRef(cast<TemplateTemplateParmDecl>(Pack),
2762 E->getPackLoc(), TU)))
2763 return true;
2764
2765 continue;
2766 }
2767
2768 // Non-type template parameter packs and function parameter packs are
2769 // treated like DeclRefExpr cursors.
2770 continue;
2771 }
2772
2773 case VisitorJob::LambdaExprPartsKind: {
2774 // Visit captures.
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002775 const LambdaExpr *E = cast<LambdaExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002776 for (LambdaExpr::capture_iterator C = E->explicit_capture_begin(),
2777 CEnd = E->explicit_capture_end();
2778 C != CEnd; ++C) {
Richard Smithba71c082013-05-16 06:20:58 +00002779 // FIXME: Lambda init-captures.
2780 if (!C->capturesVariable())
Guy Benyei11169dd2012-12-18 14:30:41 +00002781 continue;
Richard Smithba71c082013-05-16 06:20:58 +00002782
Guy Benyei11169dd2012-12-18 14:30:41 +00002783 if (Visit(MakeCursorVariableRef(C->getCapturedVar(),
2784 C->getLocation(),
2785 TU)))
2786 return true;
2787 }
2788
2789 // Visit parameters and return type, if present.
2790 if (E->hasExplicitParameters() || E->hasExplicitResultType()) {
2791 TypeLoc TL = E->getCallOperator()->getTypeSourceInfo()->getTypeLoc();
2792 if (E->hasExplicitParameters() && E->hasExplicitResultType()) {
2793 // Visit the whole type.
2794 if (Visit(TL))
2795 return true;
David Blaikie6adc78e2013-02-18 22:06:02 +00002796 } else if (FunctionProtoTypeLoc Proto =
2797 TL.getAs<FunctionProtoTypeLoc>()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002798 if (E->hasExplicitParameters()) {
2799 // Visit parameters.
Alp Tokerb3fd5cf2014-01-21 00:32:38 +00002800 for (unsigned I = 0, N = Proto.getNumParams(); I != N; ++I)
2801 if (Visit(MakeCXCursor(Proto.getParam(I), TU)))
Guy Benyei11169dd2012-12-18 14:30:41 +00002802 return true;
2803 } else {
2804 // Visit result type.
Alp Toker42a16a62014-01-25 23:51:36 +00002805 if (Visit(Proto.getReturnLoc()))
Guy Benyei11169dd2012-12-18 14:30:41 +00002806 return true;
2807 }
2808 }
2809 }
2810 break;
2811 }
2812
2813 case VisitorJob::PostChildrenVisitKind:
2814 if (PostChildrenVisitor(Parent, ClientData))
2815 return true;
2816 break;
2817 }
2818 }
2819 return false;
2820}
2821
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002822bool CursorVisitor::Visit(const Stmt *S) {
Craig Topper69186e72014-06-08 08:38:04 +00002823 VisitorWorkList *WL = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00002824 if (!WorkListFreeList.empty()) {
2825 WL = WorkListFreeList.back();
2826 WL->clear();
2827 WorkListFreeList.pop_back();
2828 }
2829 else {
2830 WL = new VisitorWorkList();
2831 WorkListCache.push_back(WL);
2832 }
2833 EnqueueWorkList(*WL, S);
2834 bool result = RunVisitorWorkList(*WL);
2835 WorkListFreeList.push_back(WL);
2836 return result;
2837}
2838
2839namespace {
Dmitri Gribenkof8579502013-01-12 19:30:44 +00002840typedef SmallVector<SourceRange, 4> RefNamePieces;
Craig Topper69186e72014-06-08 08:38:04 +00002841RefNamePieces
2842buildPieces(unsigned NameFlags, bool IsMemberRefExpr,
Craig Toppere335f252015-10-04 04:53:55 +00002843 const DeclarationNameInfo &NI, SourceRange QLoc,
Craig Topper69186e72014-06-08 08:38:04 +00002844 const ASTTemplateArgumentListInfo *TemplateArgs = nullptr) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002845 const bool WantQualifier = NameFlags & CXNameRange_WantQualifier;
2846 const bool WantTemplateArgs = NameFlags & CXNameRange_WantTemplateArgs;
2847 const bool WantSinglePiece = NameFlags & CXNameRange_WantSinglePiece;
2848
2849 const DeclarationName::NameKind Kind = NI.getName().getNameKind();
2850
2851 RefNamePieces Pieces;
2852
2853 if (WantQualifier && QLoc.isValid())
2854 Pieces.push_back(QLoc);
2855
2856 if (Kind != DeclarationName::CXXOperatorName || IsMemberRefExpr)
2857 Pieces.push_back(NI.getLoc());
2858
2859 if (WantTemplateArgs && TemplateArgs)
2860 Pieces.push_back(SourceRange(TemplateArgs->LAngleLoc,
2861 TemplateArgs->RAngleLoc));
2862
2863 if (Kind == DeclarationName::CXXOperatorName) {
2864 Pieces.push_back(SourceLocation::getFromRawEncoding(
2865 NI.getInfo().CXXOperatorName.BeginOpNameLoc));
2866 Pieces.push_back(SourceLocation::getFromRawEncoding(
2867 NI.getInfo().CXXOperatorName.EndOpNameLoc));
2868 }
2869
2870 if (WantSinglePiece) {
2871 SourceRange R(Pieces.front().getBegin(), Pieces.back().getEnd());
2872 Pieces.clear();
2873 Pieces.push_back(R);
2874 }
2875
2876 return Pieces;
2877}
Alexander Kornienkoab9db512015-06-22 23:07:51 +00002878}
Guy Benyei11169dd2012-12-18 14:30:41 +00002879
2880//===----------------------------------------------------------------------===//
2881// Misc. API hooks.
2882//===----------------------------------------------------------------------===//
2883
Chad Rosier05c71aa2013-03-27 18:28:23 +00002884static void fatal_error_handler(void *user_data, const std::string& reason,
2885 bool gen_crash_diag) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002886 // Write the result out to stderr avoiding errs() because raw_ostreams can
2887 // call report_fatal_error.
2888 fprintf(stderr, "LIBCLANG FATAL ERROR: %s\n", reason.c_str());
2889 ::abort();
2890}
2891
Chandler Carruth66660742014-06-27 16:37:27 +00002892namespace {
2893struct RegisterFatalErrorHandler {
2894 RegisterFatalErrorHandler() {
2895 llvm::install_fatal_error_handler(fatal_error_handler, nullptr);
2896 }
2897};
2898}
2899
2900static llvm::ManagedStatic<RegisterFatalErrorHandler> RegisterFatalErrorHandlerOnce;
2901
Guy Benyei11169dd2012-12-18 14:30:41 +00002902extern "C" {
2903CXIndex clang_createIndex(int excludeDeclarationsFromPCH,
2904 int displayDiagnostics) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002905 // We use crash recovery to make some of our APIs more reliable, implicitly
2906 // enable it.
Argyrios Kyrtzidis3701f542013-11-27 08:58:09 +00002907 if (!getenv("LIBCLANG_DISABLE_CRASH_RECOVERY"))
2908 llvm::CrashRecoveryContext::Enable();
Guy Benyei11169dd2012-12-18 14:30:41 +00002909
Chandler Carruth66660742014-06-27 16:37:27 +00002910 // Look through the managed static to trigger construction of the managed
2911 // static which registers our fatal error handler. This ensures it is only
2912 // registered once.
2913 (void)*RegisterFatalErrorHandlerOnce;
Guy Benyei11169dd2012-12-18 14:30:41 +00002914
Adrian Prantlbc068582015-07-08 01:00:30 +00002915 // Initialize targets for clang module support.
2916 llvm::InitializeAllTargets();
2917 llvm::InitializeAllTargetMCs();
2918 llvm::InitializeAllAsmPrinters();
2919 llvm::InitializeAllAsmParsers();
2920
Adrian Prantlfb2398d2015-07-17 01:19:54 +00002921 CIndexer *CIdxr = new CIndexer();
2922
Guy Benyei11169dd2012-12-18 14:30:41 +00002923 if (excludeDeclarationsFromPCH)
2924 CIdxr->setOnlyLocalDecls();
2925 if (displayDiagnostics)
2926 CIdxr->setDisplayDiagnostics();
2927
2928 if (getenv("LIBCLANG_BGPRIO_INDEX"))
2929 CIdxr->setCXGlobalOptFlags(CIdxr->getCXGlobalOptFlags() |
2930 CXGlobalOpt_ThreadBackgroundPriorityForIndexing);
2931 if (getenv("LIBCLANG_BGPRIO_EDIT"))
2932 CIdxr->setCXGlobalOptFlags(CIdxr->getCXGlobalOptFlags() |
2933 CXGlobalOpt_ThreadBackgroundPriorityForEditing);
2934
2935 return CIdxr;
2936}
2937
2938void clang_disposeIndex(CXIndex CIdx) {
2939 if (CIdx)
2940 delete static_cast<CIndexer *>(CIdx);
2941}
2942
2943void clang_CXIndex_setGlobalOptions(CXIndex CIdx, unsigned options) {
2944 if (CIdx)
2945 static_cast<CIndexer *>(CIdx)->setCXGlobalOptFlags(options);
2946}
2947
2948unsigned clang_CXIndex_getGlobalOptions(CXIndex CIdx) {
2949 if (CIdx)
2950 return static_cast<CIndexer *>(CIdx)->getCXGlobalOptFlags();
2951 return 0;
2952}
2953
2954void clang_toggleCrashRecovery(unsigned isEnabled) {
2955 if (isEnabled)
2956 llvm::CrashRecoveryContext::Enable();
2957 else
2958 llvm::CrashRecoveryContext::Disable();
2959}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002960
Guy Benyei11169dd2012-12-18 14:30:41 +00002961CXTranslationUnit clang_createTranslationUnit(CXIndex CIdx,
2962 const char *ast_filename) {
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00002963 CXTranslationUnit TU;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002964 enum CXErrorCode Result =
2965 clang_createTranslationUnit2(CIdx, ast_filename, &TU);
Reid Klecknerfd48fc62014-02-12 23:56:20 +00002966 (void)Result;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002967 assert((TU && Result == CXError_Success) ||
2968 (!TU && Result != CXError_Success));
2969 return TU;
2970}
2971
2972enum CXErrorCode clang_createTranslationUnit2(CXIndex CIdx,
2973 const char *ast_filename,
2974 CXTranslationUnit *out_TU) {
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00002975 if (out_TU)
Craig Topper69186e72014-06-08 08:38:04 +00002976 *out_TU = nullptr;
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00002977
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002978 if (!CIdx || !ast_filename || !out_TU)
2979 return CXError_InvalidArguments;
Guy Benyei11169dd2012-12-18 14:30:41 +00002980
Argyrios Kyrtzidis27021012013-05-24 22:24:07 +00002981 LOG_FUNC_SECTION {
2982 *Log << ast_filename;
2983 }
2984
Guy Benyei11169dd2012-12-18 14:30:41 +00002985 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
2986 FileSystemOptions FileSystemOpts;
2987
Justin Bognerd512c1e2014-10-15 00:33:06 +00002988 IntrusiveRefCntPtr<DiagnosticsEngine> Diags =
2989 CompilerInstance::createDiagnostics(new DiagnosticOptions());
David Blaikie6f7382d2014-08-10 19:08:04 +00002990 std::unique_ptr<ASTUnit> AU = ASTUnit::LoadFromASTFile(
Adrian Prantlfb2398d2015-07-17 01:19:54 +00002991 ast_filename, CXXIdx->getPCHContainerOperations()->getRawReader(), Diags,
Adrian Prantl6b21ab22015-08-27 19:46:20 +00002992 FileSystemOpts, /*UseDebugInfo=*/false,
2993 CXXIdx->getOnlyLocalDecls(), None,
David Blaikie6f7382d2014-08-10 19:08:04 +00002994 /*CaptureDiagnostics=*/true,
2995 /*AllowPCHWithCompilerErrors=*/true,
2996 /*UserFilesAreVolatile=*/true);
2997 *out_TU = MakeCXTranslationUnit(CXXIdx, AU.release());
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002998 return *out_TU ? CXError_Success : CXError_Failure;
Guy Benyei11169dd2012-12-18 14:30:41 +00002999}
3000
3001unsigned clang_defaultEditingTranslationUnitOptions() {
3002 return CXTranslationUnit_PrecompiledPreamble |
3003 CXTranslationUnit_CacheCompletionResults;
3004}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003005
Guy Benyei11169dd2012-12-18 14:30:41 +00003006CXTranslationUnit
3007clang_createTranslationUnitFromSourceFile(CXIndex CIdx,
3008 const char *source_filename,
3009 int num_command_line_args,
3010 const char * const *command_line_args,
3011 unsigned num_unsaved_files,
3012 struct CXUnsavedFile *unsaved_files) {
3013 unsigned Options = CXTranslationUnit_DetailedPreprocessingRecord;
3014 return clang_parseTranslationUnit(CIdx, source_filename,
3015 command_line_args, num_command_line_args,
3016 unsaved_files, num_unsaved_files,
3017 Options);
3018}
3019
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003020static CXErrorCode
3021clang_parseTranslationUnit_Impl(CXIndex CIdx, const char *source_filename,
3022 const char *const *command_line_args,
3023 int num_command_line_args,
3024 ArrayRef<CXUnsavedFile> unsaved_files,
3025 unsigned options, CXTranslationUnit *out_TU) {
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00003026 // Set up the initial return values.
3027 if (out_TU)
Craig Topper69186e72014-06-08 08:38:04 +00003028 *out_TU = nullptr;
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00003029
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003030 // Check arguments.
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003031 if (!CIdx || !out_TU)
3032 return CXError_InvalidArguments;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003033
Guy Benyei11169dd2012-12-18 14:30:41 +00003034 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
3035
3036 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
3037 setThreadBackgroundPriority();
3038
3039 bool PrecompilePreamble = options & CXTranslationUnit_PrecompiledPreamble;
3040 // FIXME: Add a flag for modules.
3041 TranslationUnitKind TUKind
3042 = (options & CXTranslationUnit_Incomplete)? TU_Prefix : TU_Complete;
Alp Toker8c8a8752013-12-03 06:53:35 +00003043 bool CacheCodeCompletionResults
Guy Benyei11169dd2012-12-18 14:30:41 +00003044 = options & CXTranslationUnit_CacheCompletionResults;
3045 bool IncludeBriefCommentsInCodeCompletion
3046 = options & CXTranslationUnit_IncludeBriefCommentsInCodeCompletion;
3047 bool SkipFunctionBodies = options & CXTranslationUnit_SkipFunctionBodies;
3048 bool ForSerialization = options & CXTranslationUnit_ForSerialization;
3049
3050 // Configure the diagnostics.
3051 IntrusiveRefCntPtr<DiagnosticsEngine>
Sean Silvaf1b49e22013-01-20 01:58:28 +00003052 Diags(CompilerInstance::createDiagnostics(new DiagnosticOptions));
Guy Benyei11169dd2012-12-18 14:30:41 +00003053
3054 // Recover resources if we crash before exiting this function.
3055 llvm::CrashRecoveryContextCleanupRegistrar<DiagnosticsEngine,
3056 llvm::CrashRecoveryContextReleaseRefCleanup<DiagnosticsEngine> >
Alp Tokerf994cef2014-07-05 03:08:06 +00003057 DiagCleanup(Diags.get());
Guy Benyei11169dd2012-12-18 14:30:41 +00003058
Ahmed Charlesb8984322014-03-07 20:03:18 +00003059 std::unique_ptr<std::vector<ASTUnit::RemappedFile>> RemappedFiles(
3060 new std::vector<ASTUnit::RemappedFile>());
Guy Benyei11169dd2012-12-18 14:30:41 +00003061
3062 // Recover resources if we crash before exiting this function.
3063 llvm::CrashRecoveryContextCleanupRegistrar<
3064 std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
3065
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003066 for (auto &UF : unsaved_files) {
Rafael Espindolad87f8d72014-08-27 20:03:29 +00003067 std::unique_ptr<llvm::MemoryBuffer> MB =
Alp Toker9d85b182014-07-07 01:23:14 +00003068 llvm::MemoryBuffer::getMemBufferCopy(getContents(UF), UF.Filename);
Rafael Espindolad87f8d72014-08-27 20:03:29 +00003069 RemappedFiles->push_back(std::make_pair(UF.Filename, MB.release()));
Guy Benyei11169dd2012-12-18 14:30:41 +00003070 }
3071
Ahmed Charlesb8984322014-03-07 20:03:18 +00003072 std::unique_ptr<std::vector<const char *>> Args(
3073 new std::vector<const char *>());
Guy Benyei11169dd2012-12-18 14:30:41 +00003074
3075 // Recover resources if we crash before exiting this method.
3076 llvm::CrashRecoveryContextCleanupRegistrar<std::vector<const char*> >
3077 ArgsCleanup(Args.get());
3078
3079 // Since the Clang C library is primarily used by batch tools dealing with
3080 // (often very broken) source code, where spell-checking can have a
3081 // significant negative impact on performance (particularly when
3082 // precompiled headers are involved), we disable it by default.
3083 // Only do this if we haven't found a spell-checking-related argument.
3084 bool FoundSpellCheckingArgument = false;
3085 for (int I = 0; I != num_command_line_args; ++I) {
3086 if (strcmp(command_line_args[I], "-fno-spell-checking") == 0 ||
3087 strcmp(command_line_args[I], "-fspell-checking") == 0) {
3088 FoundSpellCheckingArgument = true;
3089 break;
3090 }
3091 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003092 Args->insert(Args->end(), command_line_args,
3093 command_line_args + num_command_line_args);
3094
Benjamin Kramerc02670e2015-11-18 16:14:27 +00003095 if (!FoundSpellCheckingArgument)
3096 Args->insert(Args->begin() + 1, "-fno-spell-checking");
3097
Guy Benyei11169dd2012-12-18 14:30:41 +00003098 // The 'source_filename' argument is optional. If the caller does not
3099 // specify it then it is assumed that the source file is specified
3100 // in the actual argument list.
3101 // Put the source file after command_line_args otherwise if '-x' flag is
3102 // present it will be unused.
3103 if (source_filename)
3104 Args->push_back(source_filename);
3105
3106 // Do we need the detailed preprocessing record?
3107 if (options & CXTranslationUnit_DetailedPreprocessingRecord) {
3108 Args->push_back("-Xclang");
3109 Args->push_back("-detailed-preprocessing-record");
3110 }
3111
3112 unsigned NumErrors = Diags->getClient()->getNumErrors();
Ahmed Charlesb8984322014-03-07 20:03:18 +00003113 std::unique_ptr<ASTUnit> ErrUnit;
3114 std::unique_ptr<ASTUnit> Unit(ASTUnit::LoadFromCommandLine(
Adrian Prantlbb165fb2015-06-20 18:53:08 +00003115 Args->data(), Args->data() + Args->size(),
3116 CXXIdx->getPCHContainerOperations(), Diags,
Ahmed Charlesb8984322014-03-07 20:03:18 +00003117 CXXIdx->getClangResourcesPath(), CXXIdx->getOnlyLocalDecls(),
3118 /*CaptureDiagnostics=*/true, *RemappedFiles.get(),
3119 /*RemappedFilesKeepOriginalName=*/true, PrecompilePreamble, TUKind,
3120 CacheCodeCompletionResults, IncludeBriefCommentsInCodeCompletion,
3121 /*AllowPCHWithCompilerErrors=*/true, SkipFunctionBodies,
Argyrios Kyrtzidisa3e2ff12015-11-20 03:36:21 +00003122 /*UserFilesAreVolatile=*/true, ForSerialization,
3123 CXXIdx->getPCHContainerOperations()->getRawReader().getFormat(),
3124 &ErrUnit));
Guy Benyei11169dd2012-12-18 14:30:41 +00003125
Artem Belevich0ff05cd2015-07-13 23:27:56 +00003126 // Early failures in LoadFromCommandLine may return with ErrUnit unset.
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003127 if (!Unit && !ErrUnit)
3128 return CXError_ASTReadError;
Artem Belevich0ff05cd2015-07-13 23:27:56 +00003129
Guy Benyei11169dd2012-12-18 14:30:41 +00003130 if (NumErrors != Diags->getClient()->getNumErrors()) {
3131 // Make sure to check that 'Unit' is non-NULL.
3132 if (CXXIdx->getDisplayDiagnostics())
3133 printDiagsToStderr(Unit ? Unit.get() : ErrUnit.get());
3134 }
3135
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003136 if (isASTReadError(Unit ? Unit.get() : ErrUnit.get()))
3137 return CXError_ASTReadError;
3138
3139 *out_TU = MakeCXTranslationUnit(CXXIdx, Unit.release());
3140 return *out_TU ? CXError_Success : CXError_Failure;
Guy Benyei11169dd2012-12-18 14:30:41 +00003141}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003142
3143CXTranslationUnit
3144clang_parseTranslationUnit(CXIndex CIdx,
3145 const char *source_filename,
3146 const char *const *command_line_args,
3147 int num_command_line_args,
3148 struct CXUnsavedFile *unsaved_files,
3149 unsigned num_unsaved_files,
3150 unsigned options) {
3151 CXTranslationUnit TU;
3152 enum CXErrorCode Result = clang_parseTranslationUnit2(
3153 CIdx, source_filename, command_line_args, num_command_line_args,
3154 unsaved_files, num_unsaved_files, options, &TU);
Reid Kleckner6eaf05a2014-02-13 01:19:59 +00003155 (void)Result;
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00003156 assert((TU && Result == CXError_Success) ||
3157 (!TU && Result != CXError_Success));
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003158 return TU;
3159}
3160
3161enum CXErrorCode clang_parseTranslationUnit2(
Benjamin Kramerc02670e2015-11-18 16:14:27 +00003162 CXIndex CIdx, const char *source_filename,
3163 const char *const *command_line_args, int num_command_line_args,
3164 struct CXUnsavedFile *unsaved_files, unsigned num_unsaved_files,
3165 unsigned options, CXTranslationUnit *out_TU) {
3166 SmallVector<const char *, 4> Args;
3167 Args.push_back("clang");
3168 Args.append(command_line_args, command_line_args + num_command_line_args);
3169 return clang_parseTranslationUnit2FullArgv(
3170 CIdx, source_filename, Args.data(), Args.size(), unsaved_files,
3171 num_unsaved_files, options, out_TU);
3172}
3173
3174enum CXErrorCode clang_parseTranslationUnit2FullArgv(
3175 CXIndex CIdx, const char *source_filename,
3176 const char *const *command_line_args, int num_command_line_args,
3177 struct CXUnsavedFile *unsaved_files, unsigned num_unsaved_files,
3178 unsigned options, CXTranslationUnit *out_TU) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00003179 LOG_FUNC_SECTION {
3180 *Log << source_filename << ": ";
3181 for (int i = 0; i != num_command_line_args; ++i)
3182 *Log << command_line_args[i] << " ";
3183 }
3184
Alp Toker9d85b182014-07-07 01:23:14 +00003185 if (num_unsaved_files && !unsaved_files)
3186 return CXError_InvalidArguments;
3187
Alp Toker5c532982014-07-07 22:42:03 +00003188 CXErrorCode result = CXError_Failure;
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003189 auto ParseTranslationUnitImpl = [=, &result] {
3190 result = clang_parseTranslationUnit_Impl(
3191 CIdx, source_filename, command_line_args, num_command_line_args,
3192 llvm::makeArrayRef(unsaved_files, num_unsaved_files), options, out_TU);
3193 };
Guy Benyei11169dd2012-12-18 14:30:41 +00003194 llvm::CrashRecoveryContext CRC;
3195
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003196 if (!RunSafely(CRC, ParseTranslationUnitImpl)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003197 fprintf(stderr, "libclang: crash detected during parsing: {\n");
3198 fprintf(stderr, " 'source_filename' : '%s'\n", source_filename);
3199 fprintf(stderr, " 'command_line_args' : [");
3200 for (int i = 0; i != num_command_line_args; ++i) {
3201 if (i)
3202 fprintf(stderr, ", ");
3203 fprintf(stderr, "'%s'", command_line_args[i]);
3204 }
3205 fprintf(stderr, "],\n");
3206 fprintf(stderr, " 'unsaved_files' : [");
3207 for (unsigned i = 0; i != num_unsaved_files; ++i) {
3208 if (i)
3209 fprintf(stderr, ", ");
3210 fprintf(stderr, "('%s', '...', %ld)", unsaved_files[i].Filename,
3211 unsaved_files[i].Length);
3212 }
3213 fprintf(stderr, "],\n");
3214 fprintf(stderr, " 'options' : %d,\n", options);
3215 fprintf(stderr, "}\n");
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003216
3217 return CXError_Crashed;
Guy Benyei11169dd2012-12-18 14:30:41 +00003218 } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003219 if (CXTranslationUnit *TU = out_TU)
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003220 PrintLibclangResourceUsage(*TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003221 }
Alp Toker5c532982014-07-07 22:42:03 +00003222
3223 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003224}
3225
3226unsigned clang_defaultSaveOptions(CXTranslationUnit TU) {
3227 return CXSaveTranslationUnit_None;
3228}
3229
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003230static CXSaveError clang_saveTranslationUnit_Impl(CXTranslationUnit TU,
3231 const char *FileName,
3232 unsigned options) {
3233 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00003234 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
3235 setThreadBackgroundPriority();
3236
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003237 bool hadError = cxtu::getASTUnit(TU)->Save(FileName);
3238 return hadError ? CXSaveError_Unknown : CXSaveError_None;
Guy Benyei11169dd2012-12-18 14:30:41 +00003239}
3240
3241int clang_saveTranslationUnit(CXTranslationUnit TU, const char *FileName,
3242 unsigned options) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00003243 LOG_FUNC_SECTION {
3244 *Log << TU << ' ' << FileName;
3245 }
3246
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003247 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003248 LOG_BAD_TU(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003249 return CXSaveError_InvalidTU;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003250 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003251
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003252 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003253 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
3254 if (!CXXUnit->hasSema())
3255 return CXSaveError_InvalidTU;
3256
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003257 CXSaveError result;
3258 auto SaveTranslationUnitImpl = [=, &result]() {
3259 result = clang_saveTranslationUnit_Impl(TU, FileName, options);
3260 };
Guy Benyei11169dd2012-12-18 14:30:41 +00003261
3262 if (!CXXUnit->getDiagnostics().hasUnrecoverableErrorOccurred() ||
3263 getenv("LIBCLANG_NOTHREADS")) {
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003264 SaveTranslationUnitImpl();
Guy Benyei11169dd2012-12-18 14:30:41 +00003265
3266 if (getenv("LIBCLANG_RESOURCE_USAGE"))
3267 PrintLibclangResourceUsage(TU);
3268
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003269 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003270 }
3271
3272 // We have an AST that has invalid nodes due to compiler errors.
3273 // Use a crash recovery thread for protection.
3274
3275 llvm::CrashRecoveryContext CRC;
3276
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003277 if (!RunSafely(CRC, SaveTranslationUnitImpl)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003278 fprintf(stderr, "libclang: crash detected during AST saving: {\n");
3279 fprintf(stderr, " 'filename' : '%s'\n", FileName);
3280 fprintf(stderr, " 'options' : %d,\n", options);
3281 fprintf(stderr, "}\n");
3282
3283 return CXSaveError_Unknown;
3284
3285 } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
3286 PrintLibclangResourceUsage(TU);
3287 }
3288
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003289 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003290}
3291
3292void clang_disposeTranslationUnit(CXTranslationUnit CTUnit) {
3293 if (CTUnit) {
3294 // If the translation unit has been marked as unsafe to free, just discard
3295 // it.
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003296 ASTUnit *Unit = cxtu::getASTUnit(CTUnit);
3297 if (Unit && Unit->isUnsafeToFree())
Guy Benyei11169dd2012-12-18 14:30:41 +00003298 return;
3299
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003300 delete cxtu::getASTUnit(CTUnit);
Dmitri Gribenkob95b3f12013-01-26 22:44:19 +00003301 delete CTUnit->StringPool;
Guy Benyei11169dd2012-12-18 14:30:41 +00003302 delete static_cast<CXDiagnosticSetImpl *>(CTUnit->Diagnostics);
3303 disposeOverridenCXCursorsPool(CTUnit->OverridenCursorsPool);
Dmitri Gribenko9e605112013-11-13 22:16:51 +00003304 delete CTUnit->CommentToXML;
Guy Benyei11169dd2012-12-18 14:30:41 +00003305 delete CTUnit;
3306 }
3307}
3308
3309unsigned clang_defaultReparseOptions(CXTranslationUnit TU) {
3310 return CXReparse_None;
3311}
3312
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003313static CXErrorCode
3314clang_reparseTranslationUnit_Impl(CXTranslationUnit TU,
3315 ArrayRef<CXUnsavedFile> unsaved_files,
3316 unsigned options) {
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003317 // Check arguments.
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003318 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003319 LOG_BAD_TU(TU);
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003320 return CXError_InvalidArguments;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003321 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003322
3323 // Reset the associated diagnostics.
3324 delete static_cast<CXDiagnosticSetImpl*>(TU->Diagnostics);
Craig Topper69186e72014-06-08 08:38:04 +00003325 TU->Diagnostics = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00003326
Dmitri Gribenko183436e2013-01-26 21:49:50 +00003327 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00003328 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
3329 setThreadBackgroundPriority();
3330
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003331 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003332 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
Ahmed Charlesb8984322014-03-07 20:03:18 +00003333
3334 std::unique_ptr<std::vector<ASTUnit::RemappedFile>> RemappedFiles(
3335 new std::vector<ASTUnit::RemappedFile>());
3336
Guy Benyei11169dd2012-12-18 14:30:41 +00003337 // Recover resources if we crash before exiting this function.
3338 llvm::CrashRecoveryContextCleanupRegistrar<
3339 std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
Alp Toker9d85b182014-07-07 01:23:14 +00003340
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003341 for (auto &UF : unsaved_files) {
Rafael Espindolad87f8d72014-08-27 20:03:29 +00003342 std::unique_ptr<llvm::MemoryBuffer> MB =
Alp Toker9d85b182014-07-07 01:23:14 +00003343 llvm::MemoryBuffer::getMemBufferCopy(getContents(UF), UF.Filename);
Rafael Espindolad87f8d72014-08-27 20:03:29 +00003344 RemappedFiles->push_back(std::make_pair(UF.Filename, MB.release()));
Guy Benyei11169dd2012-12-18 14:30:41 +00003345 }
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003346
Adrian Prantlbb165fb2015-06-20 18:53:08 +00003347 if (!CXXUnit->Reparse(CXXIdx->getPCHContainerOperations(),
3348 *RemappedFiles.get()))
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003349 return CXError_Success;
3350 if (isASTReadError(CXXUnit))
3351 return CXError_ASTReadError;
3352 return CXError_Failure;
Guy Benyei11169dd2012-12-18 14:30:41 +00003353}
3354
3355int clang_reparseTranslationUnit(CXTranslationUnit TU,
3356 unsigned num_unsaved_files,
3357 struct CXUnsavedFile *unsaved_files,
3358 unsigned options) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00003359 LOG_FUNC_SECTION {
3360 *Log << TU;
3361 }
3362
Alp Toker9d85b182014-07-07 01:23:14 +00003363 if (num_unsaved_files && !unsaved_files)
3364 return CXError_InvalidArguments;
3365
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003366 CXErrorCode result;
3367 auto ReparseTranslationUnitImpl = [=, &result]() {
3368 result = clang_reparseTranslationUnit_Impl(
3369 TU, llvm::makeArrayRef(unsaved_files, num_unsaved_files), options);
3370 };
Guy Benyei11169dd2012-12-18 14:30:41 +00003371
3372 if (getenv("LIBCLANG_NOTHREADS")) {
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003373 ReparseTranslationUnitImpl();
Alp Toker5c532982014-07-07 22:42:03 +00003374 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003375 }
3376
3377 llvm::CrashRecoveryContext CRC;
3378
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003379 if (!RunSafely(CRC, ReparseTranslationUnitImpl)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003380 fprintf(stderr, "libclang: crash detected during reparsing\n");
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003381 cxtu::getASTUnit(TU)->setUnsafeToFree(true);
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003382 return CXError_Crashed;
Guy Benyei11169dd2012-12-18 14:30:41 +00003383 } else if (getenv("LIBCLANG_RESOURCE_USAGE"))
3384 PrintLibclangResourceUsage(TU);
3385
Alp Toker5c532982014-07-07 22:42:03 +00003386 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003387}
3388
3389
3390CXString clang_getTranslationUnitSpelling(CXTranslationUnit CTUnit) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003391 if (isNotUsableTU(CTUnit)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003392 LOG_BAD_TU(CTUnit);
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003393 return cxstring::createEmpty();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003394 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003395
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003396 ASTUnit *CXXUnit = cxtu::getASTUnit(CTUnit);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003397 return cxstring::createDup(CXXUnit->getOriginalSourceFileName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003398}
3399
3400CXCursor clang_getTranslationUnitCursor(CXTranslationUnit TU) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003401 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003402 LOG_BAD_TU(TU);
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00003403 return clang_getNullCursor();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003404 }
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00003405
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003406 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003407 return MakeCXCursor(CXXUnit->getASTContext().getTranslationUnitDecl(), TU);
3408}
3409
3410} // end: extern "C"
3411
3412//===----------------------------------------------------------------------===//
3413// CXFile Operations.
3414//===----------------------------------------------------------------------===//
3415
3416extern "C" {
3417CXString clang_getFileName(CXFile SFile) {
3418 if (!SFile)
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00003419 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00003420
3421 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003422 return cxstring::createRef(FEnt->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003423}
3424
3425time_t clang_getFileTime(CXFile SFile) {
3426 if (!SFile)
3427 return 0;
3428
3429 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
3430 return FEnt->getModificationTime();
3431}
3432
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003433CXFile clang_getFile(CXTranslationUnit TU, const char *file_name) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003434 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003435 LOG_BAD_TU(TU);
Craig Topper69186e72014-06-08 08:38:04 +00003436 return nullptr;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003437 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003438
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003439 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003440
3441 FileManager &FMgr = CXXUnit->getFileManager();
3442 return const_cast<FileEntry *>(FMgr.getFile(file_name));
3443}
3444
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003445unsigned clang_isFileMultipleIncludeGuarded(CXTranslationUnit TU,
3446 CXFile file) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003447 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003448 LOG_BAD_TU(TU);
3449 return 0;
3450 }
3451
3452 if (!file)
Guy Benyei11169dd2012-12-18 14:30:41 +00003453 return 0;
3454
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003455 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003456 FileEntry *FEnt = static_cast<FileEntry *>(file);
3457 return CXXUnit->getPreprocessor().getHeaderSearchInfo()
3458 .isFileMultipleIncludeGuarded(FEnt);
3459}
3460
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003461int clang_getFileUniqueID(CXFile file, CXFileUniqueID *outID) {
3462 if (!file || !outID)
3463 return 1;
3464
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003465 FileEntry *FEnt = static_cast<FileEntry *>(file);
Rafael Espindolaf8f91b82013-08-01 21:42:11 +00003466 const llvm::sys::fs::UniqueID &ID = FEnt->getUniqueID();
3467 outID->data[0] = ID.getDevice();
3468 outID->data[1] = ID.getFile();
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003469 outID->data[2] = FEnt->getModificationTime();
3470 return 0;
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003471}
3472
Argyrios Kyrtzidisac3997e2014-08-16 00:26:19 +00003473int clang_File_isEqual(CXFile file1, CXFile file2) {
3474 if (file1 == file2)
3475 return true;
3476
3477 if (!file1 || !file2)
3478 return false;
3479
3480 FileEntry *FEnt1 = static_cast<FileEntry *>(file1);
3481 FileEntry *FEnt2 = static_cast<FileEntry *>(file2);
3482 return FEnt1->getUniqueID() == FEnt2->getUniqueID();
3483}
3484
Guy Benyei11169dd2012-12-18 14:30:41 +00003485} // end: extern "C"
3486
3487//===----------------------------------------------------------------------===//
3488// CXCursor Operations.
3489//===----------------------------------------------------------------------===//
3490
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003491static const Decl *getDeclFromExpr(const Stmt *E) {
3492 if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003493 return getDeclFromExpr(CE->getSubExpr());
3494
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003495 if (const DeclRefExpr *RefExpr = dyn_cast<DeclRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003496 return RefExpr->getDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003497 if (const MemberExpr *ME = dyn_cast<MemberExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003498 return ME->getMemberDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003499 if (const ObjCIvarRefExpr *RE = dyn_cast<ObjCIvarRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003500 return RE->getDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003501 if (const ObjCPropertyRefExpr *PRE = dyn_cast<ObjCPropertyRefExpr>(E)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003502 if (PRE->isExplicitProperty())
3503 return PRE->getExplicitProperty();
3504 // It could be messaging both getter and setter as in:
3505 // ++myobj.myprop;
3506 // in which case prefer to associate the setter since it is less obvious
3507 // from inspecting the source that the setter is going to get called.
3508 if (PRE->isMessagingSetter())
3509 return PRE->getImplicitPropertySetter();
3510 return PRE->getImplicitPropertyGetter();
3511 }
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003512 if (const PseudoObjectExpr *POE = dyn_cast<PseudoObjectExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003513 return getDeclFromExpr(POE->getSyntacticForm());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003514 if (const OpaqueValueExpr *OVE = dyn_cast<OpaqueValueExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003515 if (Expr *Src = OVE->getSourceExpr())
3516 return getDeclFromExpr(Src);
3517
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003518 if (const CallExpr *CE = dyn_cast<CallExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003519 return getDeclFromExpr(CE->getCallee());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003520 if (const CXXConstructExpr *CE = dyn_cast<CXXConstructExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003521 if (!CE->isElidable())
3522 return CE->getConstructor();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003523 if (const ObjCMessageExpr *OME = dyn_cast<ObjCMessageExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003524 return OME->getMethodDecl();
3525
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003526 if (const ObjCProtocolExpr *PE = dyn_cast<ObjCProtocolExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003527 return PE->getProtocol();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003528 if (const SubstNonTypeTemplateParmPackExpr *NTTP
Guy Benyei11169dd2012-12-18 14:30:41 +00003529 = dyn_cast<SubstNonTypeTemplateParmPackExpr>(E))
3530 return NTTP->getParameterPack();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003531 if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003532 if (isa<NonTypeTemplateParmDecl>(SizeOfPack->getPack()) ||
3533 isa<ParmVarDecl>(SizeOfPack->getPack()))
3534 return SizeOfPack->getPack();
Craig Topper69186e72014-06-08 08:38:04 +00003535
3536 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00003537}
3538
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003539static SourceLocation getLocationFromExpr(const Expr *E) {
3540 if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003541 return getLocationFromExpr(CE->getSubExpr());
3542
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003543 if (const ObjCMessageExpr *Msg = dyn_cast<ObjCMessageExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003544 return /*FIXME:*/Msg->getLeftLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003545 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003546 return DRE->getLocation();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003547 if (const MemberExpr *Member = dyn_cast<MemberExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003548 return Member->getMemberLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003549 if (const ObjCIvarRefExpr *Ivar = dyn_cast<ObjCIvarRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003550 return Ivar->getLocation();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003551 if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003552 return SizeOfPack->getPackLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003553 if (const ObjCPropertyRefExpr *PropRef = dyn_cast<ObjCPropertyRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003554 return PropRef->getLocation();
3555
3556 return E->getLocStart();
3557}
3558
Aaron Ballmana85d3f82015-11-12 15:25:06 +00003559static std::string getMangledStructor(std::unique_ptr<MangleContext> &M,
3560 std::unique_ptr<llvm::DataLayout> &DL,
3561 const NamedDecl *ND,
3562 unsigned StructorType) {
3563 std::string FrontendBuf;
3564 llvm::raw_string_ostream FOS(FrontendBuf);
3565
3566 if (const auto *CD = dyn_cast_or_null<CXXConstructorDecl>(ND))
3567 M->mangleCXXCtor(CD, static_cast<CXXCtorType>(StructorType), FOS);
3568 else if (const auto *DD = dyn_cast_or_null<CXXDestructorDecl>(ND))
3569 M->mangleCXXDtor(DD, static_cast<CXXDtorType>(StructorType), FOS);
3570
3571 std::string BackendBuf;
3572 llvm::raw_string_ostream BOS(BackendBuf);
3573
3574 llvm::Mangler::getNameWithPrefix(BOS, llvm::Twine(FOS.str()), *DL);
3575
3576 return BOS.str();
3577}
3578
Guy Benyei11169dd2012-12-18 14:30:41 +00003579extern "C" {
3580
3581unsigned clang_visitChildren(CXCursor parent,
3582 CXCursorVisitor visitor,
3583 CXClientData client_data) {
3584 CursorVisitor CursorVis(getCursorTU(parent), visitor, client_data,
3585 /*VisitPreprocessorLast=*/false);
3586 return CursorVis.VisitChildren(parent);
3587}
3588
3589#ifndef __has_feature
3590#define __has_feature(x) 0
3591#endif
3592#if __has_feature(blocks)
3593typedef enum CXChildVisitResult
3594 (^CXCursorVisitorBlock)(CXCursor cursor, CXCursor parent);
3595
3596static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
3597 CXClientData client_data) {
3598 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
3599 return block(cursor, parent);
3600}
3601#else
3602// If we are compiled with a compiler that doesn't have native blocks support,
3603// define and call the block manually, so the
3604typedef struct _CXChildVisitResult
3605{
3606 void *isa;
3607 int flags;
3608 int reserved;
3609 enum CXChildVisitResult(*invoke)(struct _CXChildVisitResult*, CXCursor,
3610 CXCursor);
3611} *CXCursorVisitorBlock;
3612
3613static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
3614 CXClientData client_data) {
3615 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
3616 return block->invoke(block, cursor, parent);
3617}
3618#endif
3619
3620
3621unsigned clang_visitChildrenWithBlock(CXCursor parent,
3622 CXCursorVisitorBlock block) {
3623 return clang_visitChildren(parent, visitWithBlock, block);
3624}
3625
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003626static CXString getDeclSpelling(const Decl *D) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003627 if (!D)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003628 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003629
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003630 const NamedDecl *ND = dyn_cast<NamedDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00003631 if (!ND) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003632 if (const ObjCPropertyImplDecl *PropImpl =
3633 dyn_cast<ObjCPropertyImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00003634 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003635 return cxstring::createDup(Property->getIdentifier()->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003636
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003637 if (const ImportDecl *ImportD = dyn_cast<ImportDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00003638 if (Module *Mod = ImportD->getImportedModule())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003639 return cxstring::createDup(Mod->getFullModuleName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003640
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003641 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003642 }
3643
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003644 if (const ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(ND))
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003645 return cxstring::createDup(OMD->getSelector().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003646
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003647 if (const ObjCCategoryImplDecl *CIMP = dyn_cast<ObjCCategoryImplDecl>(ND))
Guy Benyei11169dd2012-12-18 14:30:41 +00003648 // No, this isn't the same as the code below. getIdentifier() is non-virtual
3649 // and returns different names. NamedDecl returns the class name and
3650 // ObjCCategoryImplDecl returns the category name.
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003651 return cxstring::createRef(CIMP->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003652
3653 if (isa<UsingDirectiveDecl>(D))
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003654 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003655
3656 SmallString<1024> S;
3657 llvm::raw_svector_ostream os(S);
3658 ND->printName(os);
3659
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003660 return cxstring::createDup(os.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003661}
3662
3663CXString clang_getCursorSpelling(CXCursor C) {
3664 if (clang_isTranslationUnit(C.kind))
Dmitri Gribenko2c173b42013-01-11 19:28:44 +00003665 return clang_getTranslationUnitSpelling(getCursorTU(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00003666
3667 if (clang_isReference(C.kind)) {
3668 switch (C.kind) {
3669 case CXCursor_ObjCSuperClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003670 const ObjCInterfaceDecl *Super = getCursorObjCSuperClassRef(C).first;
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003671 return cxstring::createRef(Super->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003672 }
3673 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003674 const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003675 return cxstring::createRef(Class->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003676 }
3677 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003678 const ObjCProtocolDecl *OID = getCursorObjCProtocolRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003679 assert(OID && "getCursorSpelling(): Missing protocol decl");
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003680 return cxstring::createRef(OID->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003681 }
3682 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003683 const CXXBaseSpecifier *B = getCursorCXXBaseSpecifier(C);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003684 return cxstring::createDup(B->getType().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003685 }
3686 case CXCursor_TypeRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003687 const TypeDecl *Type = getCursorTypeRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003688 assert(Type && "Missing type decl");
3689
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003690 return cxstring::createDup(getCursorContext(C).getTypeDeclType(Type).
Guy Benyei11169dd2012-12-18 14:30:41 +00003691 getAsString());
3692 }
3693 case CXCursor_TemplateRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003694 const TemplateDecl *Template = getCursorTemplateRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003695 assert(Template && "Missing template decl");
3696
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003697 return cxstring::createDup(Template->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003698 }
3699
3700 case CXCursor_NamespaceRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003701 const NamedDecl *NS = getCursorNamespaceRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003702 assert(NS && "Missing namespace decl");
3703
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003704 return cxstring::createDup(NS->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003705 }
3706
3707 case CXCursor_MemberRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003708 const FieldDecl *Field = getCursorMemberRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003709 assert(Field && "Missing member decl");
3710
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003711 return cxstring::createDup(Field->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003712 }
3713
3714 case CXCursor_LabelRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003715 const LabelStmt *Label = getCursorLabelRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003716 assert(Label && "Missing label");
3717
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003718 return cxstring::createRef(Label->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003719 }
3720
3721 case CXCursor_OverloadedDeclRef: {
3722 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003723 if (const Decl *D = Storage.dyn_cast<const Decl *>()) {
3724 if (const NamedDecl *ND = dyn_cast<NamedDecl>(D))
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003725 return cxstring::createDup(ND->getNameAsString());
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003726 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003727 }
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003728 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003729 return cxstring::createDup(E->getName().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003730 OverloadedTemplateStorage *Ovl
3731 = Storage.get<OverloadedTemplateStorage*>();
3732 if (Ovl->size() == 0)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003733 return cxstring::createEmpty();
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003734 return cxstring::createDup((*Ovl->begin())->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003735 }
3736
3737 case CXCursor_VariableRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003738 const VarDecl *Var = getCursorVariableRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003739 assert(Var && "Missing variable decl");
3740
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003741 return cxstring::createDup(Var->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003742 }
3743
3744 default:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003745 return cxstring::createRef("<not implemented>");
Guy Benyei11169dd2012-12-18 14:30:41 +00003746 }
3747 }
3748
3749 if (clang_isExpression(C.kind)) {
Argyrios Kyrtzidis3227d862014-03-03 19:40:52 +00003750 const Expr *E = getCursorExpr(C);
3751
3752 if (C.kind == CXCursor_ObjCStringLiteral ||
3753 C.kind == CXCursor_StringLiteral) {
3754 const StringLiteral *SLit;
3755 if (const ObjCStringLiteral *OSL = dyn_cast<ObjCStringLiteral>(E)) {
3756 SLit = OSL->getString();
3757 } else {
3758 SLit = cast<StringLiteral>(E);
3759 }
3760 SmallString<256> Buf;
3761 llvm::raw_svector_ostream OS(Buf);
3762 SLit->outputString(OS);
3763 return cxstring::createDup(OS.str());
3764 }
3765
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003766 const Decl *D = getDeclFromExpr(getCursorExpr(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00003767 if (D)
3768 return getDeclSpelling(D);
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003769 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003770 }
3771
3772 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003773 const Stmt *S = getCursorStmt(C);
3774 if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S))
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003775 return cxstring::createRef(Label->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003776
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003777 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003778 }
3779
3780 if (C.kind == CXCursor_MacroExpansion)
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003781 return cxstring::createRef(getCursorMacroExpansion(C).getName()
Guy Benyei11169dd2012-12-18 14:30:41 +00003782 ->getNameStart());
3783
3784 if (C.kind == CXCursor_MacroDefinition)
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003785 return cxstring::createRef(getCursorMacroDefinition(C)->getName()
Guy Benyei11169dd2012-12-18 14:30:41 +00003786 ->getNameStart());
3787
3788 if (C.kind == CXCursor_InclusionDirective)
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003789 return cxstring::createDup(getCursorInclusionDirective(C)->getFileName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003790
3791 if (clang_isDeclaration(C.kind))
3792 return getDeclSpelling(getCursorDecl(C));
3793
3794 if (C.kind == CXCursor_AnnotateAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00003795 const AnnotateAttr *AA = cast<AnnotateAttr>(cxcursor::getCursorAttr(C));
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003796 return cxstring::createDup(AA->getAnnotation());
Guy Benyei11169dd2012-12-18 14:30:41 +00003797 }
3798
3799 if (C.kind == CXCursor_AsmLabelAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00003800 const AsmLabelAttr *AA = cast<AsmLabelAttr>(cxcursor::getCursorAttr(C));
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003801 return cxstring::createDup(AA->getLabel());
Guy Benyei11169dd2012-12-18 14:30:41 +00003802 }
3803
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00003804 if (C.kind == CXCursor_PackedAttr) {
3805 return cxstring::createRef("packed");
3806 }
3807
Saleem Abdulrasool79c69712015-09-05 18:53:43 +00003808 if (C.kind == CXCursor_VisibilityAttr) {
3809 const VisibilityAttr *AA = cast<VisibilityAttr>(cxcursor::getCursorAttr(C));
3810 switch (AA->getVisibility()) {
3811 case VisibilityAttr::VisibilityType::Default:
3812 return cxstring::createRef("default");
3813 case VisibilityAttr::VisibilityType::Hidden:
3814 return cxstring::createRef("hidden");
3815 case VisibilityAttr::VisibilityType::Protected:
3816 return cxstring::createRef("protected");
3817 }
3818 llvm_unreachable("unknown visibility type");
3819 }
3820
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003821 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003822}
3823
3824CXSourceRange clang_Cursor_getSpellingNameRange(CXCursor C,
3825 unsigned pieceIndex,
3826 unsigned options) {
3827 if (clang_Cursor_isNull(C))
3828 return clang_getNullRange();
3829
3830 ASTContext &Ctx = getCursorContext(C);
3831
3832 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003833 const Stmt *S = getCursorStmt(C);
3834 if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003835 if (pieceIndex > 0)
3836 return clang_getNullRange();
3837 return cxloc::translateSourceRange(Ctx, Label->getIdentLoc());
3838 }
3839
3840 return clang_getNullRange();
3841 }
3842
3843 if (C.kind == CXCursor_ObjCMessageExpr) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003844 if (const ObjCMessageExpr *
Guy Benyei11169dd2012-12-18 14:30:41 +00003845 ME = dyn_cast_or_null<ObjCMessageExpr>(getCursorExpr(C))) {
3846 if (pieceIndex >= ME->getNumSelectorLocs())
3847 return clang_getNullRange();
3848 return cxloc::translateSourceRange(Ctx, ME->getSelectorLoc(pieceIndex));
3849 }
3850 }
3851
3852 if (C.kind == CXCursor_ObjCInstanceMethodDecl ||
3853 C.kind == CXCursor_ObjCClassMethodDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003854 if (const ObjCMethodDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003855 MD = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(C))) {
3856 if (pieceIndex >= MD->getNumSelectorLocs())
3857 return clang_getNullRange();
3858 return cxloc::translateSourceRange(Ctx, MD->getSelectorLoc(pieceIndex));
3859 }
3860 }
3861
3862 if (C.kind == CXCursor_ObjCCategoryDecl ||
3863 C.kind == CXCursor_ObjCCategoryImplDecl) {
3864 if (pieceIndex > 0)
3865 return clang_getNullRange();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003866 if (const ObjCCategoryDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003867 CD = dyn_cast_or_null<ObjCCategoryDecl>(getCursorDecl(C)))
3868 return cxloc::translateSourceRange(Ctx, CD->getCategoryNameLoc());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003869 if (const ObjCCategoryImplDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003870 CID = dyn_cast_or_null<ObjCCategoryImplDecl>(getCursorDecl(C)))
3871 return cxloc::translateSourceRange(Ctx, CID->getCategoryNameLoc());
3872 }
3873
3874 if (C.kind == CXCursor_ModuleImportDecl) {
3875 if (pieceIndex > 0)
3876 return clang_getNullRange();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003877 if (const ImportDecl *ImportD =
3878 dyn_cast_or_null<ImportDecl>(getCursorDecl(C))) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003879 ArrayRef<SourceLocation> Locs = ImportD->getIdentifierLocs();
3880 if (!Locs.empty())
3881 return cxloc::translateSourceRange(Ctx,
3882 SourceRange(Locs.front(), Locs.back()));
3883 }
3884 return clang_getNullRange();
3885 }
3886
Argyrios Kyrtzidisa2a1e532014-08-26 20:23:26 +00003887 if (C.kind == CXCursor_CXXMethod || C.kind == CXCursor_Destructor ||
3888 C.kind == CXCursor_ConversionFunction) {
3889 if (pieceIndex > 0)
3890 return clang_getNullRange();
3891 if (const FunctionDecl *FD =
3892 dyn_cast_or_null<FunctionDecl>(getCursorDecl(C))) {
3893 DeclarationNameInfo FunctionName = FD->getNameInfo();
3894 return cxloc::translateSourceRange(Ctx, FunctionName.getSourceRange());
3895 }
3896 return clang_getNullRange();
3897 }
3898
Guy Benyei11169dd2012-12-18 14:30:41 +00003899 // FIXME: A CXCursor_InclusionDirective should give the location of the
3900 // filename, but we don't keep track of this.
3901
3902 // FIXME: A CXCursor_AnnotateAttr should give the location of the annotation
3903 // but we don't keep track of this.
3904
3905 // FIXME: A CXCursor_AsmLabelAttr should give the location of the label
3906 // but we don't keep track of this.
3907
3908 // Default handling, give the location of the cursor.
3909
3910 if (pieceIndex > 0)
3911 return clang_getNullRange();
3912
3913 CXSourceLocation CXLoc = clang_getCursorLocation(C);
3914 SourceLocation Loc = cxloc::translateSourceLocation(CXLoc);
3915 return cxloc::translateSourceRange(Ctx, Loc);
3916}
3917
Eli Bendersky44a206f2014-07-31 18:04:56 +00003918CXString clang_Cursor_getMangling(CXCursor C) {
3919 if (clang_isInvalid(C.kind) || !clang_isDeclaration(C.kind))
3920 return cxstring::createEmpty();
3921
Eli Bendersky44a206f2014-07-31 18:04:56 +00003922 // Mangling only works for functions and variables.
Eli Bendersky79759592014-08-01 15:01:10 +00003923 const Decl *D = getCursorDecl(C);
Eli Bendersky44a206f2014-07-31 18:04:56 +00003924 if (!D || !(isa<FunctionDecl>(D) || isa<VarDecl>(D)))
3925 return cxstring::createEmpty();
3926
Eli Bendersky79759592014-08-01 15:01:10 +00003927 // First apply frontend mangling.
Eli Bendersky44a206f2014-07-31 18:04:56 +00003928 const NamedDecl *ND = cast<NamedDecl>(D);
Eli Bendersky79759592014-08-01 15:01:10 +00003929 ASTContext &Ctx = ND->getASTContext();
3930 std::unique_ptr<MangleContext> MC(Ctx.createMangleContext());
Eli Bendersky44a206f2014-07-31 18:04:56 +00003931
Eli Bendersky79759592014-08-01 15:01:10 +00003932 std::string FrontendBuf;
3933 llvm::raw_string_ostream FrontendBufOS(FrontendBuf);
Ehsan Akhgarif8d44de2015-10-08 00:01:20 +00003934 if (MC->shouldMangleDeclName(ND)) {
3935 MC->mangleName(ND, FrontendBufOS);
3936 } else {
3937 ND->printName(FrontendBufOS);
3938 }
Eli Bendersky44a206f2014-07-31 18:04:56 +00003939
Eli Bendersky79759592014-08-01 15:01:10 +00003940 // Now apply backend mangling.
3941 std::unique_ptr<llvm::DataLayout> DL(
Eric Christopher964a5f32015-08-05 23:48:05 +00003942 new llvm::DataLayout(Ctx.getTargetInfo().getDataLayoutString()));
Eli Bendersky79759592014-08-01 15:01:10 +00003943
3944 std::string FinalBuf;
3945 llvm::raw_string_ostream FinalBufOS(FinalBuf);
Rafael Espindolab633d202015-06-23 13:59:36 +00003946 llvm::Mangler::getNameWithPrefix(FinalBufOS, llvm::Twine(FrontendBufOS.str()),
3947 *DL);
Eli Bendersky79759592014-08-01 15:01:10 +00003948
3949 return cxstring::createDup(FinalBufOS.str());
Eli Bendersky44a206f2014-07-31 18:04:56 +00003950}
3951
Saleem Abdulrasool60034432015-11-12 03:57:22 +00003952CXStringSet *clang_Cursor_getCXXManglings(CXCursor C) {
3953 if (clang_isInvalid(C.kind) || !clang_isDeclaration(C.kind))
3954 return nullptr;
3955
3956 const Decl *D = getCursorDecl(C);
3957 if (!(isa<CXXRecordDecl>(D) || isa<CXXMethodDecl>(D)))
3958 return nullptr;
3959
3960 const NamedDecl *ND = cast<NamedDecl>(D);
3961
3962 ASTContext &Ctx = ND->getASTContext();
3963 std::unique_ptr<MangleContext> M(Ctx.createMangleContext());
3964 std::unique_ptr<llvm::DataLayout> DL(
3965 new llvm::DataLayout(Ctx.getTargetInfo().getDataLayoutString()));
3966
3967 std::vector<std::string> Manglings;
3968
3969 auto hasDefaultCXXMethodCC = [](ASTContext &C, const CXXMethodDecl *MD) {
3970 auto DefaultCC = C.getDefaultCallingConvention(/*IsVariadic=*/false,
3971 /*IsCSSMethod=*/true);
3972 auto CC = MD->getType()->getAs<FunctionProtoType>()->getCallConv();
3973 return CC == DefaultCC;
3974 };
3975
3976 if (const auto *CD = dyn_cast_or_null<CXXConstructorDecl>(ND)) {
3977 Manglings.emplace_back(getMangledStructor(M, DL, CD, Ctor_Base));
3978
3979 if (Ctx.getTargetInfo().getCXXABI().isItaniumFamily())
3980 if (!CD->getParent()->isAbstract())
3981 Manglings.emplace_back(getMangledStructor(M, DL, CD, Ctor_Complete));
3982
3983 if (Ctx.getTargetInfo().getCXXABI().isMicrosoft())
3984 if (CD->hasAttr<DLLExportAttr>() && CD->isDefaultConstructor())
3985 if (!(hasDefaultCXXMethodCC(Ctx, CD) && CD->getNumParams() == 0))
3986 Manglings.emplace_back(getMangledStructor(M, DL, CD,
3987 Ctor_DefaultClosure));
3988 } else if (const auto *DD = dyn_cast_or_null<CXXDestructorDecl>(ND)) {
3989 Manglings.emplace_back(getMangledStructor(M, DL, DD, Dtor_Base));
3990 if (Ctx.getTargetInfo().getCXXABI().isItaniumFamily()) {
3991 Manglings.emplace_back(getMangledStructor(M, DL, DD, Dtor_Complete));
3992
3993 if (!DD->isVirtual())
3994 Manglings.emplace_back(getMangledStructor(M, DL, DD, Dtor_Deleting));
3995 }
3996 }
3997
3998 return cxstring::createSet(Manglings);
3999}
4000
Guy Benyei11169dd2012-12-18 14:30:41 +00004001CXString clang_getCursorDisplayName(CXCursor C) {
4002 if (!clang_isDeclaration(C.kind))
4003 return clang_getCursorSpelling(C);
4004
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004005 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004006 if (!D)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00004007 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00004008
4009 PrintingPolicy Policy = getCursorContext(C).getPrintingPolicy();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004010 if (const FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004011 D = FunTmpl->getTemplatedDecl();
4012
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004013 if (const FunctionDecl *Function = dyn_cast<FunctionDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004014 SmallString<64> Str;
4015 llvm::raw_svector_ostream OS(Str);
4016 OS << *Function;
4017 if (Function->getPrimaryTemplate())
4018 OS << "<>";
4019 OS << "(";
4020 for (unsigned I = 0, N = Function->getNumParams(); I != N; ++I) {
4021 if (I)
4022 OS << ", ";
4023 OS << Function->getParamDecl(I)->getType().getAsString(Policy);
4024 }
4025
4026 if (Function->isVariadic()) {
4027 if (Function->getNumParams())
4028 OS << ", ";
4029 OS << "...";
4030 }
4031 OS << ")";
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004032 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00004033 }
4034
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004035 if (const ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004036 SmallString<64> Str;
4037 llvm::raw_svector_ostream OS(Str);
4038 OS << *ClassTemplate;
4039 OS << "<";
4040 TemplateParameterList *Params = ClassTemplate->getTemplateParameters();
4041 for (unsigned I = 0, N = Params->size(); I != N; ++I) {
4042 if (I)
4043 OS << ", ";
4044
4045 NamedDecl *Param = Params->getParam(I);
4046 if (Param->getIdentifier()) {
4047 OS << Param->getIdentifier()->getName();
4048 continue;
4049 }
4050
4051 // There is no parameter name, which makes this tricky. Try to come up
4052 // with something useful that isn't too long.
4053 if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(Param))
4054 OS << (TTP->wasDeclaredWithTypename()? "typename" : "class");
4055 else if (NonTypeTemplateParmDecl *NTTP
4056 = dyn_cast<NonTypeTemplateParmDecl>(Param))
4057 OS << NTTP->getType().getAsString(Policy);
4058 else
4059 OS << "template<...> class";
4060 }
4061
4062 OS << ">";
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004063 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00004064 }
4065
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004066 if (const ClassTemplateSpecializationDecl *ClassSpec
Guy Benyei11169dd2012-12-18 14:30:41 +00004067 = dyn_cast<ClassTemplateSpecializationDecl>(D)) {
4068 // If the type was explicitly written, use that.
4069 if (TypeSourceInfo *TSInfo = ClassSpec->getTypeAsWritten())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004070 return cxstring::createDup(TSInfo->getType().getAsString(Policy));
Guy Benyei11169dd2012-12-18 14:30:41 +00004071
Benjamin Kramer9170e912013-02-22 15:46:01 +00004072 SmallString<128> Str;
Guy Benyei11169dd2012-12-18 14:30:41 +00004073 llvm::raw_svector_ostream OS(Str);
4074 OS << *ClassSpec;
Benjamin Kramer9170e912013-02-22 15:46:01 +00004075 TemplateSpecializationType::PrintTemplateArgumentList(OS,
Guy Benyei11169dd2012-12-18 14:30:41 +00004076 ClassSpec->getTemplateArgs().data(),
4077 ClassSpec->getTemplateArgs().size(),
4078 Policy);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004079 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00004080 }
4081
4082 return clang_getCursorSpelling(C);
4083}
4084
4085CXString clang_getCursorKindSpelling(enum CXCursorKind Kind) {
4086 switch (Kind) {
4087 case CXCursor_FunctionDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004088 return cxstring::createRef("FunctionDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004089 case CXCursor_TypedefDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004090 return cxstring::createRef("TypedefDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004091 case CXCursor_EnumDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004092 return cxstring::createRef("EnumDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004093 case CXCursor_EnumConstantDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004094 return cxstring::createRef("EnumConstantDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004095 case CXCursor_StructDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004096 return cxstring::createRef("StructDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004097 case CXCursor_UnionDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004098 return cxstring::createRef("UnionDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004099 case CXCursor_ClassDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004100 return cxstring::createRef("ClassDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004101 case CXCursor_FieldDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004102 return cxstring::createRef("FieldDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004103 case CXCursor_VarDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004104 return cxstring::createRef("VarDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004105 case CXCursor_ParmDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004106 return cxstring::createRef("ParmDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004107 case CXCursor_ObjCInterfaceDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004108 return cxstring::createRef("ObjCInterfaceDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004109 case CXCursor_ObjCCategoryDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004110 return cxstring::createRef("ObjCCategoryDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004111 case CXCursor_ObjCProtocolDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004112 return cxstring::createRef("ObjCProtocolDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004113 case CXCursor_ObjCPropertyDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004114 return cxstring::createRef("ObjCPropertyDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004115 case CXCursor_ObjCIvarDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004116 return cxstring::createRef("ObjCIvarDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004117 case CXCursor_ObjCInstanceMethodDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004118 return cxstring::createRef("ObjCInstanceMethodDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004119 case CXCursor_ObjCClassMethodDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004120 return cxstring::createRef("ObjCClassMethodDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004121 case CXCursor_ObjCImplementationDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004122 return cxstring::createRef("ObjCImplementationDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004123 case CXCursor_ObjCCategoryImplDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004124 return cxstring::createRef("ObjCCategoryImplDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004125 case CXCursor_CXXMethod:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004126 return cxstring::createRef("CXXMethod");
Guy Benyei11169dd2012-12-18 14:30:41 +00004127 case CXCursor_UnexposedDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004128 return cxstring::createRef("UnexposedDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004129 case CXCursor_ObjCSuperClassRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004130 return cxstring::createRef("ObjCSuperClassRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004131 case CXCursor_ObjCProtocolRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004132 return cxstring::createRef("ObjCProtocolRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004133 case CXCursor_ObjCClassRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004134 return cxstring::createRef("ObjCClassRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004135 case CXCursor_TypeRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004136 return cxstring::createRef("TypeRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004137 case CXCursor_TemplateRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004138 return cxstring::createRef("TemplateRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004139 case CXCursor_NamespaceRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004140 return cxstring::createRef("NamespaceRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004141 case CXCursor_MemberRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004142 return cxstring::createRef("MemberRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004143 case CXCursor_LabelRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004144 return cxstring::createRef("LabelRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004145 case CXCursor_OverloadedDeclRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004146 return cxstring::createRef("OverloadedDeclRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004147 case CXCursor_VariableRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004148 return cxstring::createRef("VariableRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004149 case CXCursor_IntegerLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004150 return cxstring::createRef("IntegerLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00004151 case CXCursor_FloatingLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004152 return cxstring::createRef("FloatingLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00004153 case CXCursor_ImaginaryLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004154 return cxstring::createRef("ImaginaryLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00004155 case CXCursor_StringLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004156 return cxstring::createRef("StringLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00004157 case CXCursor_CharacterLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004158 return cxstring::createRef("CharacterLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00004159 case CXCursor_ParenExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004160 return cxstring::createRef("ParenExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004161 case CXCursor_UnaryOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004162 return cxstring::createRef("UnaryOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00004163 case CXCursor_ArraySubscriptExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004164 return cxstring::createRef("ArraySubscriptExpr");
Alexey Bataev1a3320e2015-08-25 14:24:04 +00004165 case CXCursor_OMPArraySectionExpr:
4166 return cxstring::createRef("OMPArraySectionExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004167 case CXCursor_BinaryOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004168 return cxstring::createRef("BinaryOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00004169 case CXCursor_CompoundAssignOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004170 return cxstring::createRef("CompoundAssignOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00004171 case CXCursor_ConditionalOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004172 return cxstring::createRef("ConditionalOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00004173 case CXCursor_CStyleCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004174 return cxstring::createRef("CStyleCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004175 case CXCursor_CompoundLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004176 return cxstring::createRef("CompoundLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004177 case CXCursor_InitListExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004178 return cxstring::createRef("InitListExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004179 case CXCursor_AddrLabelExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004180 return cxstring::createRef("AddrLabelExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004181 case CXCursor_StmtExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004182 return cxstring::createRef("StmtExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004183 case CXCursor_GenericSelectionExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004184 return cxstring::createRef("GenericSelectionExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004185 case CXCursor_GNUNullExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004186 return cxstring::createRef("GNUNullExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004187 case CXCursor_CXXStaticCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004188 return cxstring::createRef("CXXStaticCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004189 case CXCursor_CXXDynamicCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004190 return cxstring::createRef("CXXDynamicCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004191 case CXCursor_CXXReinterpretCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004192 return cxstring::createRef("CXXReinterpretCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004193 case CXCursor_CXXConstCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004194 return cxstring::createRef("CXXConstCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004195 case CXCursor_CXXFunctionalCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004196 return cxstring::createRef("CXXFunctionalCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004197 case CXCursor_CXXTypeidExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004198 return cxstring::createRef("CXXTypeidExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004199 case CXCursor_CXXBoolLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004200 return cxstring::createRef("CXXBoolLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004201 case CXCursor_CXXNullPtrLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004202 return cxstring::createRef("CXXNullPtrLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004203 case CXCursor_CXXThisExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004204 return cxstring::createRef("CXXThisExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004205 case CXCursor_CXXThrowExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004206 return cxstring::createRef("CXXThrowExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004207 case CXCursor_CXXNewExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004208 return cxstring::createRef("CXXNewExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004209 case CXCursor_CXXDeleteExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004210 return cxstring::createRef("CXXDeleteExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004211 case CXCursor_UnaryExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004212 return cxstring::createRef("UnaryExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004213 case CXCursor_ObjCStringLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004214 return cxstring::createRef("ObjCStringLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00004215 case CXCursor_ObjCBoolLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004216 return cxstring::createRef("ObjCBoolLiteralExpr");
Argyrios Kyrtzidisc2233be2013-04-23 17:57:17 +00004217 case CXCursor_ObjCSelfExpr:
4218 return cxstring::createRef("ObjCSelfExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004219 case CXCursor_ObjCEncodeExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004220 return cxstring::createRef("ObjCEncodeExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004221 case CXCursor_ObjCSelectorExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004222 return cxstring::createRef("ObjCSelectorExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004223 case CXCursor_ObjCProtocolExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004224 return cxstring::createRef("ObjCProtocolExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004225 case CXCursor_ObjCBridgedCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004226 return cxstring::createRef("ObjCBridgedCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004227 case CXCursor_BlockExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004228 return cxstring::createRef("BlockExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004229 case CXCursor_PackExpansionExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004230 return cxstring::createRef("PackExpansionExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004231 case CXCursor_SizeOfPackExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004232 return cxstring::createRef("SizeOfPackExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004233 case CXCursor_LambdaExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004234 return cxstring::createRef("LambdaExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004235 case CXCursor_UnexposedExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004236 return cxstring::createRef("UnexposedExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004237 case CXCursor_DeclRefExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004238 return cxstring::createRef("DeclRefExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004239 case CXCursor_MemberRefExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004240 return cxstring::createRef("MemberRefExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004241 case CXCursor_CallExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004242 return cxstring::createRef("CallExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004243 case CXCursor_ObjCMessageExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004244 return cxstring::createRef("ObjCMessageExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004245 case CXCursor_UnexposedStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004246 return cxstring::createRef("UnexposedStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004247 case CXCursor_DeclStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004248 return cxstring::createRef("DeclStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004249 case CXCursor_LabelStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004250 return cxstring::createRef("LabelStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004251 case CXCursor_CompoundStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004252 return cxstring::createRef("CompoundStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004253 case CXCursor_CaseStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004254 return cxstring::createRef("CaseStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004255 case CXCursor_DefaultStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004256 return cxstring::createRef("DefaultStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004257 case CXCursor_IfStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004258 return cxstring::createRef("IfStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004259 case CXCursor_SwitchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004260 return cxstring::createRef("SwitchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004261 case CXCursor_WhileStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004262 return cxstring::createRef("WhileStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004263 case CXCursor_DoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004264 return cxstring::createRef("DoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004265 case CXCursor_ForStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004266 return cxstring::createRef("ForStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004267 case CXCursor_GotoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004268 return cxstring::createRef("GotoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004269 case CXCursor_IndirectGotoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004270 return cxstring::createRef("IndirectGotoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004271 case CXCursor_ContinueStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004272 return cxstring::createRef("ContinueStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004273 case CXCursor_BreakStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004274 return cxstring::createRef("BreakStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004275 case CXCursor_ReturnStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004276 return cxstring::createRef("ReturnStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004277 case CXCursor_GCCAsmStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004278 return cxstring::createRef("GCCAsmStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004279 case CXCursor_MSAsmStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004280 return cxstring::createRef("MSAsmStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004281 case CXCursor_ObjCAtTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004282 return cxstring::createRef("ObjCAtTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004283 case CXCursor_ObjCAtCatchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004284 return cxstring::createRef("ObjCAtCatchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004285 case CXCursor_ObjCAtFinallyStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004286 return cxstring::createRef("ObjCAtFinallyStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004287 case CXCursor_ObjCAtThrowStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004288 return cxstring::createRef("ObjCAtThrowStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004289 case CXCursor_ObjCAtSynchronizedStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004290 return cxstring::createRef("ObjCAtSynchronizedStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004291 case CXCursor_ObjCAutoreleasePoolStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004292 return cxstring::createRef("ObjCAutoreleasePoolStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004293 case CXCursor_ObjCForCollectionStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004294 return cxstring::createRef("ObjCForCollectionStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004295 case CXCursor_CXXCatchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004296 return cxstring::createRef("CXXCatchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004297 case CXCursor_CXXTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004298 return cxstring::createRef("CXXTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004299 case CXCursor_CXXForRangeStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004300 return cxstring::createRef("CXXForRangeStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004301 case CXCursor_SEHTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004302 return cxstring::createRef("SEHTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004303 case CXCursor_SEHExceptStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004304 return cxstring::createRef("SEHExceptStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004305 case CXCursor_SEHFinallyStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004306 return cxstring::createRef("SEHFinallyStmt");
Nico Weber9b982072014-07-07 00:12:30 +00004307 case CXCursor_SEHLeaveStmt:
4308 return cxstring::createRef("SEHLeaveStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004309 case CXCursor_NullStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004310 return cxstring::createRef("NullStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004311 case CXCursor_InvalidFile:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004312 return cxstring::createRef("InvalidFile");
Guy Benyei11169dd2012-12-18 14:30:41 +00004313 case CXCursor_InvalidCode:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004314 return cxstring::createRef("InvalidCode");
Guy Benyei11169dd2012-12-18 14:30:41 +00004315 case CXCursor_NoDeclFound:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004316 return cxstring::createRef("NoDeclFound");
Guy Benyei11169dd2012-12-18 14:30:41 +00004317 case CXCursor_NotImplemented:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004318 return cxstring::createRef("NotImplemented");
Guy Benyei11169dd2012-12-18 14:30:41 +00004319 case CXCursor_TranslationUnit:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004320 return cxstring::createRef("TranslationUnit");
Guy Benyei11169dd2012-12-18 14:30:41 +00004321 case CXCursor_UnexposedAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004322 return cxstring::createRef("UnexposedAttr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004323 case CXCursor_IBActionAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004324 return cxstring::createRef("attribute(ibaction)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004325 case CXCursor_IBOutletAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004326 return cxstring::createRef("attribute(iboutlet)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004327 case CXCursor_IBOutletCollectionAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004328 return cxstring::createRef("attribute(iboutletcollection)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004329 case CXCursor_CXXFinalAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004330 return cxstring::createRef("attribute(final)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004331 case CXCursor_CXXOverrideAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004332 return cxstring::createRef("attribute(override)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004333 case CXCursor_AnnotateAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004334 return cxstring::createRef("attribute(annotate)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004335 case CXCursor_AsmLabelAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004336 return cxstring::createRef("asm label");
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00004337 case CXCursor_PackedAttr:
4338 return cxstring::createRef("attribute(packed)");
Joey Gouly81228382014-05-01 15:41:58 +00004339 case CXCursor_PureAttr:
4340 return cxstring::createRef("attribute(pure)");
4341 case CXCursor_ConstAttr:
4342 return cxstring::createRef("attribute(const)");
4343 case CXCursor_NoDuplicateAttr:
4344 return cxstring::createRef("attribute(noduplicate)");
Eli Bendersky2581e662014-05-28 19:29:58 +00004345 case CXCursor_CUDAConstantAttr:
4346 return cxstring::createRef("attribute(constant)");
4347 case CXCursor_CUDADeviceAttr:
4348 return cxstring::createRef("attribute(device)");
4349 case CXCursor_CUDAGlobalAttr:
4350 return cxstring::createRef("attribute(global)");
4351 case CXCursor_CUDAHostAttr:
4352 return cxstring::createRef("attribute(host)");
Eli Bendersky9b071472014-08-08 14:59:00 +00004353 case CXCursor_CUDASharedAttr:
4354 return cxstring::createRef("attribute(shared)");
Saleem Abdulrasool79c69712015-09-05 18:53:43 +00004355 case CXCursor_VisibilityAttr:
4356 return cxstring::createRef("attribute(visibility)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004357 case CXCursor_PreprocessingDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004358 return cxstring::createRef("preprocessing directive");
Guy Benyei11169dd2012-12-18 14:30:41 +00004359 case CXCursor_MacroDefinition:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004360 return cxstring::createRef("macro definition");
Guy Benyei11169dd2012-12-18 14:30:41 +00004361 case CXCursor_MacroExpansion:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004362 return cxstring::createRef("macro expansion");
Guy Benyei11169dd2012-12-18 14:30:41 +00004363 case CXCursor_InclusionDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004364 return cxstring::createRef("inclusion directive");
Guy Benyei11169dd2012-12-18 14:30:41 +00004365 case CXCursor_Namespace:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004366 return cxstring::createRef("Namespace");
Guy Benyei11169dd2012-12-18 14:30:41 +00004367 case CXCursor_LinkageSpec:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004368 return cxstring::createRef("LinkageSpec");
Guy Benyei11169dd2012-12-18 14:30:41 +00004369 case CXCursor_CXXBaseSpecifier:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004370 return cxstring::createRef("C++ base class specifier");
Guy Benyei11169dd2012-12-18 14:30:41 +00004371 case CXCursor_Constructor:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004372 return cxstring::createRef("CXXConstructor");
Guy Benyei11169dd2012-12-18 14:30:41 +00004373 case CXCursor_Destructor:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004374 return cxstring::createRef("CXXDestructor");
Guy Benyei11169dd2012-12-18 14:30:41 +00004375 case CXCursor_ConversionFunction:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004376 return cxstring::createRef("CXXConversion");
Guy Benyei11169dd2012-12-18 14:30:41 +00004377 case CXCursor_TemplateTypeParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004378 return cxstring::createRef("TemplateTypeParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00004379 case CXCursor_NonTypeTemplateParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004380 return cxstring::createRef("NonTypeTemplateParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00004381 case CXCursor_TemplateTemplateParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004382 return cxstring::createRef("TemplateTemplateParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00004383 case CXCursor_FunctionTemplate:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004384 return cxstring::createRef("FunctionTemplate");
Guy Benyei11169dd2012-12-18 14:30:41 +00004385 case CXCursor_ClassTemplate:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004386 return cxstring::createRef("ClassTemplate");
Guy Benyei11169dd2012-12-18 14:30:41 +00004387 case CXCursor_ClassTemplatePartialSpecialization:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004388 return cxstring::createRef("ClassTemplatePartialSpecialization");
Guy Benyei11169dd2012-12-18 14:30:41 +00004389 case CXCursor_NamespaceAlias:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004390 return cxstring::createRef("NamespaceAlias");
Guy Benyei11169dd2012-12-18 14:30:41 +00004391 case CXCursor_UsingDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004392 return cxstring::createRef("UsingDirective");
Guy Benyei11169dd2012-12-18 14:30:41 +00004393 case CXCursor_UsingDeclaration:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004394 return cxstring::createRef("UsingDeclaration");
Guy Benyei11169dd2012-12-18 14:30:41 +00004395 case CXCursor_TypeAliasDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004396 return cxstring::createRef("TypeAliasDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004397 case CXCursor_ObjCSynthesizeDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004398 return cxstring::createRef("ObjCSynthesizeDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004399 case CXCursor_ObjCDynamicDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004400 return cxstring::createRef("ObjCDynamicDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004401 case CXCursor_CXXAccessSpecifier:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004402 return cxstring::createRef("CXXAccessSpecifier");
Guy Benyei11169dd2012-12-18 14:30:41 +00004403 case CXCursor_ModuleImportDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004404 return cxstring::createRef("ModuleImport");
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00004405 case CXCursor_OMPParallelDirective:
Alexey Bataev1b59ab52014-02-27 08:29:12 +00004406 return cxstring::createRef("OMPParallelDirective");
4407 case CXCursor_OMPSimdDirective:
4408 return cxstring::createRef("OMPSimdDirective");
Alexey Bataevf29276e2014-06-18 04:14:57 +00004409 case CXCursor_OMPForDirective:
4410 return cxstring::createRef("OMPForDirective");
Alexander Musmanf82886e2014-09-18 05:12:34 +00004411 case CXCursor_OMPForSimdDirective:
4412 return cxstring::createRef("OMPForSimdDirective");
Alexey Bataevd3f8dd22014-06-25 11:44:49 +00004413 case CXCursor_OMPSectionsDirective:
4414 return cxstring::createRef("OMPSectionsDirective");
Alexey Bataev1e0498a2014-06-26 08:21:58 +00004415 case CXCursor_OMPSectionDirective:
4416 return cxstring::createRef("OMPSectionDirective");
Alexey Bataevd1e40fb2014-06-26 12:05:45 +00004417 case CXCursor_OMPSingleDirective:
4418 return cxstring::createRef("OMPSingleDirective");
Alexander Musman80c22892014-07-17 08:54:58 +00004419 case CXCursor_OMPMasterDirective:
4420 return cxstring::createRef("OMPMasterDirective");
Alexander Musmand9ed09f2014-07-21 09:42:05 +00004421 case CXCursor_OMPCriticalDirective:
4422 return cxstring::createRef("OMPCriticalDirective");
Alexey Bataev4acb8592014-07-07 13:01:15 +00004423 case CXCursor_OMPParallelForDirective:
4424 return cxstring::createRef("OMPParallelForDirective");
Alexander Musmane4e893b2014-09-23 09:33:00 +00004425 case CXCursor_OMPParallelForSimdDirective:
4426 return cxstring::createRef("OMPParallelForSimdDirective");
Alexey Bataev84d0b3e2014-07-08 08:12:03 +00004427 case CXCursor_OMPParallelSectionsDirective:
4428 return cxstring::createRef("OMPParallelSectionsDirective");
Alexey Bataev9c2e8ee2014-07-11 11:25:16 +00004429 case CXCursor_OMPTaskDirective:
4430 return cxstring::createRef("OMPTaskDirective");
Alexey Bataev68446b72014-07-18 07:47:19 +00004431 case CXCursor_OMPTaskyieldDirective:
4432 return cxstring::createRef("OMPTaskyieldDirective");
Alexey Bataev4d1dfea2014-07-18 09:11:51 +00004433 case CXCursor_OMPBarrierDirective:
4434 return cxstring::createRef("OMPBarrierDirective");
Alexey Bataev2df347a2014-07-18 10:17:07 +00004435 case CXCursor_OMPTaskwaitDirective:
4436 return cxstring::createRef("OMPTaskwaitDirective");
Alexey Bataevc30dd2d2015-06-18 12:14:09 +00004437 case CXCursor_OMPTaskgroupDirective:
4438 return cxstring::createRef("OMPTaskgroupDirective");
Alexey Bataev6125da92014-07-21 11:26:11 +00004439 case CXCursor_OMPFlushDirective:
4440 return cxstring::createRef("OMPFlushDirective");
Alexey Bataev9fb6e642014-07-22 06:45:04 +00004441 case CXCursor_OMPOrderedDirective:
4442 return cxstring::createRef("OMPOrderedDirective");
Alexey Bataev0162e452014-07-22 10:10:35 +00004443 case CXCursor_OMPAtomicDirective:
4444 return cxstring::createRef("OMPAtomicDirective");
Alexey Bataev0bd520b2014-09-19 08:19:49 +00004445 case CXCursor_OMPTargetDirective:
4446 return cxstring::createRef("OMPTargetDirective");
Michael Wong65f367f2015-07-21 13:44:28 +00004447 case CXCursor_OMPTargetDataDirective:
4448 return cxstring::createRef("OMPTargetDataDirective");
Alexey Bataev13314bf2014-10-09 04:18:56 +00004449 case CXCursor_OMPTeamsDirective:
4450 return cxstring::createRef("OMPTeamsDirective");
Alexey Bataev6d4ed052015-07-01 06:57:41 +00004451 case CXCursor_OMPCancellationPointDirective:
4452 return cxstring::createRef("OMPCancellationPointDirective");
Alexey Bataev80909872015-07-02 11:25:17 +00004453 case CXCursor_OMPCancelDirective:
4454 return cxstring::createRef("OMPCancelDirective");
Francisco Lopes da Silva975a9f62015-01-21 16:24:11 +00004455 case CXCursor_OverloadCandidate:
4456 return cxstring::createRef("OverloadCandidate");
Sergey Kalinichev8f3b1872015-11-15 13:48:32 +00004457 case CXCursor_TypeAliasTemplateDecl:
4458 return cxstring::createRef("TypeAliasTemplateDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004459 }
4460
4461 llvm_unreachable("Unhandled CXCursorKind");
4462}
4463
4464struct GetCursorData {
4465 SourceLocation TokenBeginLoc;
4466 bool PointsAtMacroArgExpansion;
4467 bool VisitedObjCPropertyImplDecl;
4468 SourceLocation VisitedDeclaratorDeclStartLoc;
4469 CXCursor &BestCursor;
4470
4471 GetCursorData(SourceManager &SM,
4472 SourceLocation tokenBegin, CXCursor &outputCursor)
4473 : TokenBeginLoc(tokenBegin), BestCursor(outputCursor) {
4474 PointsAtMacroArgExpansion = SM.isMacroArgExpansion(tokenBegin);
4475 VisitedObjCPropertyImplDecl = false;
4476 }
4477};
4478
4479static enum CXChildVisitResult GetCursorVisitor(CXCursor cursor,
4480 CXCursor parent,
4481 CXClientData client_data) {
4482 GetCursorData *Data = static_cast<GetCursorData *>(client_data);
4483 CXCursor *BestCursor = &Data->BestCursor;
4484
4485 // If we point inside a macro argument we should provide info of what the
4486 // token is so use the actual cursor, don't replace it with a macro expansion
4487 // cursor.
4488 if (cursor.kind == CXCursor_MacroExpansion && Data->PointsAtMacroArgExpansion)
4489 return CXChildVisit_Recurse;
4490
4491 if (clang_isDeclaration(cursor.kind)) {
4492 // Avoid having the implicit methods override the property decls.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004493 if (const ObjCMethodDecl *MD
Guy Benyei11169dd2012-12-18 14:30:41 +00004494 = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
4495 if (MD->isImplicit())
4496 return CXChildVisit_Break;
4497
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004498 } else if (const ObjCInterfaceDecl *ID
Guy Benyei11169dd2012-12-18 14:30:41 +00004499 = dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(cursor))) {
4500 // Check that when we have multiple @class references in the same line,
4501 // that later ones do not override the previous ones.
4502 // If we have:
4503 // @class Foo, Bar;
4504 // source ranges for both start at '@', so 'Bar' will end up overriding
4505 // 'Foo' even though the cursor location was at 'Foo'.
4506 if (BestCursor->kind == CXCursor_ObjCInterfaceDecl ||
4507 BestCursor->kind == CXCursor_ObjCClassRef)
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004508 if (const ObjCInterfaceDecl *PrevID
Guy Benyei11169dd2012-12-18 14:30:41 +00004509 = dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(*BestCursor))){
4510 if (PrevID != ID &&
4511 !PrevID->isThisDeclarationADefinition() &&
4512 !ID->isThisDeclarationADefinition())
4513 return CXChildVisit_Break;
4514 }
4515
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004516 } else if (const DeclaratorDecl *DD
Guy Benyei11169dd2012-12-18 14:30:41 +00004517 = dyn_cast_or_null<DeclaratorDecl>(getCursorDecl(cursor))) {
4518 SourceLocation StartLoc = DD->getSourceRange().getBegin();
4519 // Check that when we have multiple declarators in the same line,
4520 // that later ones do not override the previous ones.
4521 // If we have:
4522 // int Foo, Bar;
4523 // source ranges for both start at 'int', so 'Bar' will end up overriding
4524 // 'Foo' even though the cursor location was at 'Foo'.
4525 if (Data->VisitedDeclaratorDeclStartLoc == StartLoc)
4526 return CXChildVisit_Break;
4527 Data->VisitedDeclaratorDeclStartLoc = StartLoc;
4528
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004529 } else if (const ObjCPropertyImplDecl *PropImp
Guy Benyei11169dd2012-12-18 14:30:41 +00004530 = dyn_cast_or_null<ObjCPropertyImplDecl>(getCursorDecl(cursor))) {
4531 (void)PropImp;
4532 // Check that when we have multiple @synthesize in the same line,
4533 // that later ones do not override the previous ones.
4534 // If we have:
4535 // @synthesize Foo, Bar;
4536 // source ranges for both start at '@', so 'Bar' will end up overriding
4537 // 'Foo' even though the cursor location was at 'Foo'.
4538 if (Data->VisitedObjCPropertyImplDecl)
4539 return CXChildVisit_Break;
4540 Data->VisitedObjCPropertyImplDecl = true;
4541 }
4542 }
4543
4544 if (clang_isExpression(cursor.kind) &&
4545 clang_isDeclaration(BestCursor->kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004546 if (const Decl *D = getCursorDecl(*BestCursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004547 // Avoid having the cursor of an expression replace the declaration cursor
4548 // when the expression source range overlaps the declaration range.
4549 // This can happen for C++ constructor expressions whose range generally
4550 // include the variable declaration, e.g.:
4551 // MyCXXClass foo; // Make sure pointing at 'foo' returns a VarDecl cursor.
4552 if (D->getLocation().isValid() && Data->TokenBeginLoc.isValid() &&
4553 D->getLocation() == Data->TokenBeginLoc)
4554 return CXChildVisit_Break;
4555 }
4556 }
4557
4558 // If our current best cursor is the construction of a temporary object,
4559 // don't replace that cursor with a type reference, because we want
4560 // clang_getCursor() to point at the constructor.
4561 if (clang_isExpression(BestCursor->kind) &&
4562 isa<CXXTemporaryObjectExpr>(getCursorExpr(*BestCursor)) &&
4563 cursor.kind == CXCursor_TypeRef) {
4564 // Keep the cursor pointing at CXXTemporaryObjectExpr but also mark it
4565 // as having the actual point on the type reference.
4566 *BestCursor = getTypeRefedCallExprCursor(*BestCursor);
4567 return CXChildVisit_Recurse;
4568 }
Douglas Gregore9d95f12015-07-07 03:57:35 +00004569
4570 // If we already have an Objective-C superclass reference, don't
4571 // update it further.
4572 if (BestCursor->kind == CXCursor_ObjCSuperClassRef)
4573 return CXChildVisit_Break;
4574
Guy Benyei11169dd2012-12-18 14:30:41 +00004575 *BestCursor = cursor;
4576 return CXChildVisit_Recurse;
4577}
4578
4579CXCursor clang_getCursor(CXTranslationUnit TU, CXSourceLocation Loc) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00004580 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004581 LOG_BAD_TU(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004582 return clang_getNullCursor();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004583 }
Guy Benyei11169dd2012-12-18 14:30:41 +00004584
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004585 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004586 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
4587
4588 SourceLocation SLoc = cxloc::translateSourceLocation(Loc);
4589 CXCursor Result = cxcursor::getCursor(TU, SLoc);
4590
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004591 LOG_FUNC_SECTION {
Guy Benyei11169dd2012-12-18 14:30:41 +00004592 CXFile SearchFile;
4593 unsigned SearchLine, SearchColumn;
4594 CXFile ResultFile;
4595 unsigned ResultLine, ResultColumn;
4596 CXString SearchFileName, ResultFileName, KindSpelling, USR;
4597 const char *IsDef = clang_isCursorDefinition(Result)? " (Definition)" : "";
4598 CXSourceLocation ResultLoc = clang_getCursorLocation(Result);
Craig Topper69186e72014-06-08 08:38:04 +00004599
4600 clang_getFileLocation(Loc, &SearchFile, &SearchLine, &SearchColumn,
4601 nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004602 clang_getFileLocation(ResultLoc, &ResultFile, &ResultLine,
Craig Topper69186e72014-06-08 08:38:04 +00004603 &ResultColumn, nullptr);
Guy Benyei11169dd2012-12-18 14:30:41 +00004604 SearchFileName = clang_getFileName(SearchFile);
4605 ResultFileName = clang_getFileName(ResultFile);
4606 KindSpelling = clang_getCursorKindSpelling(Result.kind);
4607 USR = clang_getCursorUSR(Result);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004608 *Log << llvm::format("(%s:%d:%d) = %s",
4609 clang_getCString(SearchFileName), SearchLine, SearchColumn,
4610 clang_getCString(KindSpelling))
4611 << llvm::format("(%s:%d:%d):%s%s",
4612 clang_getCString(ResultFileName), ResultLine, ResultColumn,
4613 clang_getCString(USR), IsDef);
Guy Benyei11169dd2012-12-18 14:30:41 +00004614 clang_disposeString(SearchFileName);
4615 clang_disposeString(ResultFileName);
4616 clang_disposeString(KindSpelling);
4617 clang_disposeString(USR);
4618
4619 CXCursor Definition = clang_getCursorDefinition(Result);
4620 if (!clang_equalCursors(Definition, clang_getNullCursor())) {
4621 CXSourceLocation DefinitionLoc = clang_getCursorLocation(Definition);
4622 CXString DefinitionKindSpelling
4623 = clang_getCursorKindSpelling(Definition.kind);
4624 CXFile DefinitionFile;
4625 unsigned DefinitionLine, DefinitionColumn;
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004626 clang_getFileLocation(DefinitionLoc, &DefinitionFile,
Craig Topper69186e72014-06-08 08:38:04 +00004627 &DefinitionLine, &DefinitionColumn, nullptr);
Guy Benyei11169dd2012-12-18 14:30:41 +00004628 CXString DefinitionFileName = clang_getFileName(DefinitionFile);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004629 *Log << llvm::format(" -> %s(%s:%d:%d)",
4630 clang_getCString(DefinitionKindSpelling),
4631 clang_getCString(DefinitionFileName),
4632 DefinitionLine, DefinitionColumn);
Guy Benyei11169dd2012-12-18 14:30:41 +00004633 clang_disposeString(DefinitionFileName);
4634 clang_disposeString(DefinitionKindSpelling);
4635 }
4636 }
4637
4638 return Result;
4639}
4640
4641CXCursor clang_getNullCursor(void) {
4642 return MakeCXCursorInvalid(CXCursor_InvalidFile);
4643}
4644
4645unsigned clang_equalCursors(CXCursor X, CXCursor Y) {
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00004646 // Clear out the "FirstInDeclGroup" part in a declaration cursor, since we
4647 // can't set consistently. For example, when visiting a DeclStmt we will set
4648 // it but we don't set it on the result of clang_getCursorDefinition for
4649 // a reference of the same declaration.
4650 // FIXME: Setting "FirstInDeclGroup" in CXCursors is a hack that only works
4651 // when visiting a DeclStmt currently, the AST should be enhanced to be able
4652 // to provide that kind of info.
4653 if (clang_isDeclaration(X.kind))
Craig Topper69186e72014-06-08 08:38:04 +00004654 X.data[1] = nullptr;
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00004655 if (clang_isDeclaration(Y.kind))
Craig Topper69186e72014-06-08 08:38:04 +00004656 Y.data[1] = nullptr;
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00004657
Guy Benyei11169dd2012-12-18 14:30:41 +00004658 return X == Y;
4659}
4660
4661unsigned clang_hashCursor(CXCursor C) {
4662 unsigned Index = 0;
4663 if (clang_isExpression(C.kind) || clang_isStatement(C.kind))
4664 Index = 1;
4665
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004666 return llvm::DenseMapInfo<std::pair<unsigned, const void*> >::getHashValue(
Guy Benyei11169dd2012-12-18 14:30:41 +00004667 std::make_pair(C.kind, C.data[Index]));
4668}
4669
4670unsigned clang_isInvalid(enum CXCursorKind K) {
4671 return K >= CXCursor_FirstInvalid && K <= CXCursor_LastInvalid;
4672}
4673
4674unsigned clang_isDeclaration(enum CXCursorKind K) {
4675 return (K >= CXCursor_FirstDecl && K <= CXCursor_LastDecl) ||
4676 (K >= CXCursor_FirstExtraDecl && K <= CXCursor_LastExtraDecl);
4677}
4678
4679unsigned clang_isReference(enum CXCursorKind K) {
4680 return K >= CXCursor_FirstRef && K <= CXCursor_LastRef;
4681}
4682
4683unsigned clang_isExpression(enum CXCursorKind K) {
4684 return K >= CXCursor_FirstExpr && K <= CXCursor_LastExpr;
4685}
4686
4687unsigned clang_isStatement(enum CXCursorKind K) {
4688 return K >= CXCursor_FirstStmt && K <= CXCursor_LastStmt;
4689}
4690
4691unsigned clang_isAttribute(enum CXCursorKind K) {
4692 return K >= CXCursor_FirstAttr && K <= CXCursor_LastAttr;
4693}
4694
4695unsigned clang_isTranslationUnit(enum CXCursorKind K) {
4696 return K == CXCursor_TranslationUnit;
4697}
4698
4699unsigned clang_isPreprocessing(enum CXCursorKind K) {
4700 return K >= CXCursor_FirstPreprocessing && K <= CXCursor_LastPreprocessing;
4701}
4702
4703unsigned clang_isUnexposed(enum CXCursorKind K) {
4704 switch (K) {
4705 case CXCursor_UnexposedDecl:
4706 case CXCursor_UnexposedExpr:
4707 case CXCursor_UnexposedStmt:
4708 case CXCursor_UnexposedAttr:
4709 return true;
4710 default:
4711 return false;
4712 }
4713}
4714
4715CXCursorKind clang_getCursorKind(CXCursor C) {
4716 return C.kind;
4717}
4718
4719CXSourceLocation clang_getCursorLocation(CXCursor C) {
4720 if (clang_isReference(C.kind)) {
4721 switch (C.kind) {
4722 case CXCursor_ObjCSuperClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004723 std::pair<const ObjCInterfaceDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004724 = getCursorObjCSuperClassRef(C);
4725 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4726 }
4727
4728 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004729 std::pair<const ObjCProtocolDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004730 = getCursorObjCProtocolRef(C);
4731 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4732 }
4733
4734 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004735 std::pair<const ObjCInterfaceDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004736 = getCursorObjCClassRef(C);
4737 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4738 }
4739
4740 case CXCursor_TypeRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004741 std::pair<const TypeDecl *, SourceLocation> P = getCursorTypeRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004742 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4743 }
4744
4745 case CXCursor_TemplateRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004746 std::pair<const TemplateDecl *, SourceLocation> P =
4747 getCursorTemplateRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004748 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4749 }
4750
4751 case CXCursor_NamespaceRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004752 std::pair<const NamedDecl *, SourceLocation> P = getCursorNamespaceRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004753 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4754 }
4755
4756 case CXCursor_MemberRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004757 std::pair<const FieldDecl *, SourceLocation> P = getCursorMemberRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004758 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4759 }
4760
4761 case CXCursor_VariableRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004762 std::pair<const VarDecl *, SourceLocation> P = getCursorVariableRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004763 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4764 }
4765
4766 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004767 const CXXBaseSpecifier *BaseSpec = getCursorCXXBaseSpecifier(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004768 if (!BaseSpec)
4769 return clang_getNullLocation();
4770
4771 if (TypeSourceInfo *TSInfo = BaseSpec->getTypeSourceInfo())
4772 return cxloc::translateSourceLocation(getCursorContext(C),
4773 TSInfo->getTypeLoc().getBeginLoc());
4774
4775 return cxloc::translateSourceLocation(getCursorContext(C),
4776 BaseSpec->getLocStart());
4777 }
4778
4779 case CXCursor_LabelRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004780 std::pair<const LabelStmt *, SourceLocation> P = getCursorLabelRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004781 return cxloc::translateSourceLocation(getCursorContext(C), P.second);
4782 }
4783
4784 case CXCursor_OverloadedDeclRef:
4785 return cxloc::translateSourceLocation(getCursorContext(C),
4786 getCursorOverloadedDeclRef(C).second);
4787
4788 default:
4789 // FIXME: Need a way to enumerate all non-reference cases.
4790 llvm_unreachable("Missed a reference kind");
4791 }
4792 }
4793
4794 if (clang_isExpression(C.kind))
4795 return cxloc::translateSourceLocation(getCursorContext(C),
4796 getLocationFromExpr(getCursorExpr(C)));
4797
4798 if (clang_isStatement(C.kind))
4799 return cxloc::translateSourceLocation(getCursorContext(C),
4800 getCursorStmt(C)->getLocStart());
4801
4802 if (C.kind == CXCursor_PreprocessingDirective) {
4803 SourceLocation L = cxcursor::getCursorPreprocessingDirective(C).getBegin();
4804 return cxloc::translateSourceLocation(getCursorContext(C), L);
4805 }
4806
4807 if (C.kind == CXCursor_MacroExpansion) {
4808 SourceLocation L
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00004809 = cxcursor::getCursorMacroExpansion(C).getSourceRange().getBegin();
Guy Benyei11169dd2012-12-18 14:30:41 +00004810 return cxloc::translateSourceLocation(getCursorContext(C), L);
4811 }
4812
4813 if (C.kind == CXCursor_MacroDefinition) {
4814 SourceLocation L = cxcursor::getCursorMacroDefinition(C)->getLocation();
4815 return cxloc::translateSourceLocation(getCursorContext(C), L);
4816 }
4817
4818 if (C.kind == CXCursor_InclusionDirective) {
4819 SourceLocation L
4820 = cxcursor::getCursorInclusionDirective(C)->getSourceRange().getBegin();
4821 return cxloc::translateSourceLocation(getCursorContext(C), L);
4822 }
4823
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00004824 if (clang_isAttribute(C.kind)) {
4825 SourceLocation L
4826 = cxcursor::getCursorAttr(C)->getLocation();
4827 return cxloc::translateSourceLocation(getCursorContext(C), L);
4828 }
4829
Guy Benyei11169dd2012-12-18 14:30:41 +00004830 if (!clang_isDeclaration(C.kind))
4831 return clang_getNullLocation();
4832
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004833 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004834 if (!D)
4835 return clang_getNullLocation();
4836
4837 SourceLocation Loc = D->getLocation();
4838 // FIXME: Multiple variables declared in a single declaration
4839 // currently lack the information needed to correctly determine their
4840 // ranges when accounting for the type-specifier. We use context
4841 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4842 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004843 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004844 if (!cxcursor::isFirstInDeclGroup(C))
4845 Loc = VD->getLocation();
4846 }
4847
4848 // For ObjC methods, give the start location of the method name.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004849 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004850 Loc = MD->getSelectorStartLoc();
4851
4852 return cxloc::translateSourceLocation(getCursorContext(C), Loc);
4853}
4854
4855} // end extern "C"
4856
4857CXCursor cxcursor::getCursor(CXTranslationUnit TU, SourceLocation SLoc) {
4858 assert(TU);
4859
4860 // Guard against an invalid SourceLocation, or we may assert in one
4861 // of the following calls.
4862 if (SLoc.isInvalid())
4863 return clang_getNullCursor();
4864
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004865 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004866
4867 // Translate the given source location to make it point at the beginning of
4868 // the token under the cursor.
4869 SLoc = Lexer::GetBeginningOfToken(SLoc, CXXUnit->getSourceManager(),
4870 CXXUnit->getASTContext().getLangOpts());
4871
4872 CXCursor Result = MakeCXCursorInvalid(CXCursor_NoDeclFound);
4873 if (SLoc.isValid()) {
4874 GetCursorData ResultData(CXXUnit->getSourceManager(), SLoc, Result);
4875 CursorVisitor CursorVis(TU, GetCursorVisitor, &ResultData,
4876 /*VisitPreprocessorLast=*/true,
4877 /*VisitIncludedEntities=*/false,
4878 SourceLocation(SLoc));
4879 CursorVis.visitFileRegion();
4880 }
4881
4882 return Result;
4883}
4884
4885static SourceRange getRawCursorExtent(CXCursor C) {
4886 if (clang_isReference(C.kind)) {
4887 switch (C.kind) {
4888 case CXCursor_ObjCSuperClassRef:
4889 return getCursorObjCSuperClassRef(C).second;
4890
4891 case CXCursor_ObjCProtocolRef:
4892 return getCursorObjCProtocolRef(C).second;
4893
4894 case CXCursor_ObjCClassRef:
4895 return getCursorObjCClassRef(C).second;
4896
4897 case CXCursor_TypeRef:
4898 return getCursorTypeRef(C).second;
4899
4900 case CXCursor_TemplateRef:
4901 return getCursorTemplateRef(C).second;
4902
4903 case CXCursor_NamespaceRef:
4904 return getCursorNamespaceRef(C).second;
4905
4906 case CXCursor_MemberRef:
4907 return getCursorMemberRef(C).second;
4908
4909 case CXCursor_CXXBaseSpecifier:
4910 return getCursorCXXBaseSpecifier(C)->getSourceRange();
4911
4912 case CXCursor_LabelRef:
4913 return getCursorLabelRef(C).second;
4914
4915 case CXCursor_OverloadedDeclRef:
4916 return getCursorOverloadedDeclRef(C).second;
4917
4918 case CXCursor_VariableRef:
4919 return getCursorVariableRef(C).second;
4920
4921 default:
4922 // FIXME: Need a way to enumerate all non-reference cases.
4923 llvm_unreachable("Missed a reference kind");
4924 }
4925 }
4926
4927 if (clang_isExpression(C.kind))
4928 return getCursorExpr(C)->getSourceRange();
4929
4930 if (clang_isStatement(C.kind))
4931 return getCursorStmt(C)->getSourceRange();
4932
4933 if (clang_isAttribute(C.kind))
4934 return getCursorAttr(C)->getRange();
4935
4936 if (C.kind == CXCursor_PreprocessingDirective)
4937 return cxcursor::getCursorPreprocessingDirective(C);
4938
4939 if (C.kind == CXCursor_MacroExpansion) {
4940 ASTUnit *TU = getCursorASTUnit(C);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00004941 SourceRange Range = cxcursor::getCursorMacroExpansion(C).getSourceRange();
Guy Benyei11169dd2012-12-18 14:30:41 +00004942 return TU->mapRangeFromPreamble(Range);
4943 }
4944
4945 if (C.kind == CXCursor_MacroDefinition) {
4946 ASTUnit *TU = getCursorASTUnit(C);
4947 SourceRange Range = cxcursor::getCursorMacroDefinition(C)->getSourceRange();
4948 return TU->mapRangeFromPreamble(Range);
4949 }
4950
4951 if (C.kind == CXCursor_InclusionDirective) {
4952 ASTUnit *TU = getCursorASTUnit(C);
4953 SourceRange Range = cxcursor::getCursorInclusionDirective(C)->getSourceRange();
4954 return TU->mapRangeFromPreamble(Range);
4955 }
4956
4957 if (C.kind == CXCursor_TranslationUnit) {
4958 ASTUnit *TU = getCursorASTUnit(C);
4959 FileID MainID = TU->getSourceManager().getMainFileID();
4960 SourceLocation Start = TU->getSourceManager().getLocForStartOfFile(MainID);
4961 SourceLocation End = TU->getSourceManager().getLocForEndOfFile(MainID);
4962 return SourceRange(Start, End);
4963 }
4964
4965 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004966 const Decl *D = cxcursor::getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004967 if (!D)
4968 return SourceRange();
4969
4970 SourceRange R = D->getSourceRange();
4971 // FIXME: Multiple variables declared in a single declaration
4972 // currently lack the information needed to correctly determine their
4973 // ranges when accounting for the type-specifier. We use context
4974 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4975 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004976 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004977 if (!cxcursor::isFirstInDeclGroup(C))
4978 R.setBegin(VD->getLocation());
4979 }
4980 return R;
4981 }
4982 return SourceRange();
4983}
4984
4985/// \brief Retrieves the "raw" cursor extent, which is then extended to include
4986/// the decl-specifier-seq for declarations.
4987static SourceRange getFullCursorExtent(CXCursor C, SourceManager &SrcMgr) {
4988 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004989 const Decl *D = cxcursor::getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004990 if (!D)
4991 return SourceRange();
4992
4993 SourceRange R = D->getSourceRange();
4994
4995 // Adjust the start of the location for declarations preceded by
4996 // declaration specifiers.
4997 SourceLocation StartLoc;
4998 if (const DeclaratorDecl *DD = dyn_cast<DeclaratorDecl>(D)) {
4999 if (TypeSourceInfo *TI = DD->getTypeSourceInfo())
5000 StartLoc = TI->getTypeLoc().getLocStart();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005001 } else if (const TypedefDecl *Typedef = dyn_cast<TypedefDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005002 if (TypeSourceInfo *TI = Typedef->getTypeSourceInfo())
5003 StartLoc = TI->getTypeLoc().getLocStart();
5004 }
5005
5006 if (StartLoc.isValid() && R.getBegin().isValid() &&
5007 SrcMgr.isBeforeInTranslationUnit(StartLoc, R.getBegin()))
5008 R.setBegin(StartLoc);
5009
5010 // FIXME: Multiple variables declared in a single declaration
5011 // currently lack the information needed to correctly determine their
5012 // ranges when accounting for the type-specifier. We use context
5013 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
5014 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005015 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005016 if (!cxcursor::isFirstInDeclGroup(C))
5017 R.setBegin(VD->getLocation());
5018 }
5019
5020 return R;
5021 }
5022
5023 return getRawCursorExtent(C);
5024}
5025
5026extern "C" {
5027
5028CXSourceRange clang_getCursorExtent(CXCursor C) {
5029 SourceRange R = getRawCursorExtent(C);
5030 if (R.isInvalid())
5031 return clang_getNullRange();
5032
5033 return cxloc::translateSourceRange(getCursorContext(C), R);
5034}
5035
5036CXCursor clang_getCursorReferenced(CXCursor C) {
5037 if (clang_isInvalid(C.kind))
5038 return clang_getNullCursor();
5039
5040 CXTranslationUnit tu = getCursorTU(C);
5041 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005042 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005043 if (!D)
5044 return clang_getNullCursor();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005045 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00005046 return MakeCursorOverloadedDeclRef(Using, D->getLocation(), tu);
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005047 if (const ObjCPropertyImplDecl *PropImpl =
5048 dyn_cast<ObjCPropertyImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00005049 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
5050 return MakeCXCursor(Property, tu);
5051
5052 return C;
5053 }
5054
5055 if (clang_isExpression(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005056 const Expr *E = getCursorExpr(C);
5057 const Decl *D = getDeclFromExpr(E);
Guy Benyei11169dd2012-12-18 14:30:41 +00005058 if (D) {
5059 CXCursor declCursor = MakeCXCursor(D, tu);
5060 declCursor = getSelectorIdentifierCursor(getSelectorIdentifierIndex(C),
5061 declCursor);
5062 return declCursor;
5063 }
5064
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005065 if (const OverloadExpr *Ovl = dyn_cast_or_null<OverloadExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00005066 return MakeCursorOverloadedDeclRef(Ovl, tu);
5067
5068 return clang_getNullCursor();
5069 }
5070
5071 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005072 const Stmt *S = getCursorStmt(C);
5073 if (const GotoStmt *Goto = dyn_cast_or_null<GotoStmt>(S))
Guy Benyei11169dd2012-12-18 14:30:41 +00005074 if (LabelDecl *label = Goto->getLabel())
5075 if (LabelStmt *labelS = label->getStmt())
5076 return MakeCXCursor(labelS, getCursorDecl(C), tu);
5077
5078 return clang_getNullCursor();
5079 }
Richard Smith66a81862015-05-04 02:25:31 +00005080
Guy Benyei11169dd2012-12-18 14:30:41 +00005081 if (C.kind == CXCursor_MacroExpansion) {
Richard Smith66a81862015-05-04 02:25:31 +00005082 if (const MacroDefinitionRecord *Def =
5083 getCursorMacroExpansion(C).getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005084 return MakeMacroDefinitionCursor(Def, tu);
5085 }
5086
5087 if (!clang_isReference(C.kind))
5088 return clang_getNullCursor();
5089
5090 switch (C.kind) {
5091 case CXCursor_ObjCSuperClassRef:
5092 return MakeCXCursor(getCursorObjCSuperClassRef(C).first, tu);
5093
5094 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005095 const ObjCProtocolDecl *Prot = getCursorObjCProtocolRef(C).first;
5096 if (const ObjCProtocolDecl *Def = Prot->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005097 return MakeCXCursor(Def, tu);
5098
5099 return MakeCXCursor(Prot, tu);
5100 }
5101
5102 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005103 const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
5104 if (const ObjCInterfaceDecl *Def = Class->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005105 return MakeCXCursor(Def, tu);
5106
5107 return MakeCXCursor(Class, tu);
5108 }
5109
5110 case CXCursor_TypeRef:
5111 return MakeCXCursor(getCursorTypeRef(C).first, tu );
5112
5113 case CXCursor_TemplateRef:
5114 return MakeCXCursor(getCursorTemplateRef(C).first, tu );
5115
5116 case CXCursor_NamespaceRef:
5117 return MakeCXCursor(getCursorNamespaceRef(C).first, tu );
5118
5119 case CXCursor_MemberRef:
5120 return MakeCXCursor(getCursorMemberRef(C).first, tu );
5121
5122 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005123 const CXXBaseSpecifier *B = cxcursor::getCursorCXXBaseSpecifier(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005124 return clang_getTypeDeclaration(cxtype::MakeCXType(B->getType(),
5125 tu ));
5126 }
5127
5128 case CXCursor_LabelRef:
5129 // FIXME: We end up faking the "parent" declaration here because we
5130 // don't want to make CXCursor larger.
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005131 return MakeCXCursor(getCursorLabelRef(C).first,
5132 cxtu::getASTUnit(tu)->getASTContext()
5133 .getTranslationUnitDecl(),
Guy Benyei11169dd2012-12-18 14:30:41 +00005134 tu);
5135
5136 case CXCursor_OverloadedDeclRef:
5137 return C;
5138
5139 case CXCursor_VariableRef:
5140 return MakeCXCursor(getCursorVariableRef(C).first, tu);
5141
5142 default:
5143 // We would prefer to enumerate all non-reference cursor kinds here.
5144 llvm_unreachable("Unhandled reference cursor kind");
5145 }
5146}
5147
5148CXCursor clang_getCursorDefinition(CXCursor C) {
5149 if (clang_isInvalid(C.kind))
5150 return clang_getNullCursor();
5151
5152 CXTranslationUnit TU = getCursorTU(C);
5153
5154 bool WasReference = false;
5155 if (clang_isReference(C.kind) || clang_isExpression(C.kind)) {
5156 C = clang_getCursorReferenced(C);
5157 WasReference = true;
5158 }
5159
5160 if (C.kind == CXCursor_MacroExpansion)
5161 return clang_getCursorReferenced(C);
5162
5163 if (!clang_isDeclaration(C.kind))
5164 return clang_getNullCursor();
5165
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005166 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005167 if (!D)
5168 return clang_getNullCursor();
5169
5170 switch (D->getKind()) {
5171 // Declaration kinds that don't really separate the notions of
5172 // declaration and definition.
5173 case Decl::Namespace:
5174 case Decl::Typedef:
5175 case Decl::TypeAlias:
5176 case Decl::TypeAliasTemplate:
5177 case Decl::TemplateTypeParm:
5178 case Decl::EnumConstant:
5179 case Decl::Field:
John McCall5e77d762013-04-16 07:28:30 +00005180 case Decl::MSProperty:
Guy Benyei11169dd2012-12-18 14:30:41 +00005181 case Decl::IndirectField:
5182 case Decl::ObjCIvar:
5183 case Decl::ObjCAtDefsField:
5184 case Decl::ImplicitParam:
5185 case Decl::ParmVar:
5186 case Decl::NonTypeTemplateParm:
5187 case Decl::TemplateTemplateParm:
5188 case Decl::ObjCCategoryImpl:
5189 case Decl::ObjCImplementation:
5190 case Decl::AccessSpec:
5191 case Decl::LinkageSpec:
5192 case Decl::ObjCPropertyImpl:
5193 case Decl::FileScopeAsm:
5194 case Decl::StaticAssert:
5195 case Decl::Block:
Tareq A. Siraj6dfa25a2013-04-16 19:37:38 +00005196 case Decl::Captured:
Guy Benyei11169dd2012-12-18 14:30:41 +00005197 case Decl::Label: // FIXME: Is this right??
5198 case Decl::ClassScopeFunctionSpecialization:
5199 case Decl::Import:
Alexey Bataeva769e072013-03-22 06:34:35 +00005200 case Decl::OMPThreadPrivate:
Douglas Gregor85f3f952015-07-07 03:57:15 +00005201 case Decl::ObjCTypeParam:
David Majnemerd9b1a4f2015-11-04 03:40:30 +00005202 case Decl::BuiltinTemplate:
Guy Benyei11169dd2012-12-18 14:30:41 +00005203 return C;
5204
5205 // Declaration kinds that don't make any sense here, but are
5206 // nonetheless harmless.
David Blaikief005d3c2013-02-22 17:44:58 +00005207 case Decl::Empty:
Guy Benyei11169dd2012-12-18 14:30:41 +00005208 case Decl::TranslationUnit:
Richard Smithf19e1272015-03-07 00:04:49 +00005209 case Decl::ExternCContext:
Guy Benyei11169dd2012-12-18 14:30:41 +00005210 break;
5211
5212 // Declaration kinds for which the definition is not resolvable.
5213 case Decl::UnresolvedUsingTypename:
5214 case Decl::UnresolvedUsingValue:
5215 break;
5216
5217 case Decl::UsingDirective:
5218 return MakeCXCursor(cast<UsingDirectiveDecl>(D)->getNominatedNamespace(),
5219 TU);
5220
5221 case Decl::NamespaceAlias:
5222 return MakeCXCursor(cast<NamespaceAliasDecl>(D)->getNamespace(), TU);
5223
5224 case Decl::Enum:
5225 case Decl::Record:
5226 case Decl::CXXRecord:
5227 case Decl::ClassTemplateSpecialization:
5228 case Decl::ClassTemplatePartialSpecialization:
5229 if (TagDecl *Def = cast<TagDecl>(D)->getDefinition())
5230 return MakeCXCursor(Def, TU);
5231 return clang_getNullCursor();
5232
5233 case Decl::Function:
5234 case Decl::CXXMethod:
5235 case Decl::CXXConstructor:
5236 case Decl::CXXDestructor:
5237 case Decl::CXXConversion: {
Craig Topper69186e72014-06-08 08:38:04 +00005238 const FunctionDecl *Def = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005239 if (cast<FunctionDecl>(D)->getBody(Def))
Dmitri Gribenko9c256e32013-01-14 00:46:27 +00005240 return MakeCXCursor(Def, TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005241 return clang_getNullCursor();
5242 }
5243
Larisse Voufo39a1e502013-08-06 01:03:05 +00005244 case Decl::Var:
5245 case Decl::VarTemplateSpecialization:
5246 case Decl::VarTemplatePartialSpecialization: {
Guy Benyei11169dd2012-12-18 14:30:41 +00005247 // Ask the variable if it has a definition.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005248 if (const VarDecl *Def = cast<VarDecl>(D)->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005249 return MakeCXCursor(Def, TU);
5250 return clang_getNullCursor();
5251 }
5252
5253 case Decl::FunctionTemplate: {
Craig Topper69186e72014-06-08 08:38:04 +00005254 const FunctionDecl *Def = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005255 if (cast<FunctionTemplateDecl>(D)->getTemplatedDecl()->getBody(Def))
5256 return MakeCXCursor(Def->getDescribedFunctionTemplate(), TU);
5257 return clang_getNullCursor();
5258 }
5259
5260 case Decl::ClassTemplate: {
5261 if (RecordDecl *Def = cast<ClassTemplateDecl>(D)->getTemplatedDecl()
5262 ->getDefinition())
5263 return MakeCXCursor(cast<CXXRecordDecl>(Def)->getDescribedClassTemplate(),
5264 TU);
5265 return clang_getNullCursor();
5266 }
5267
Larisse Voufo39a1e502013-08-06 01:03:05 +00005268 case Decl::VarTemplate: {
5269 if (VarDecl *Def =
5270 cast<VarTemplateDecl>(D)->getTemplatedDecl()->getDefinition())
5271 return MakeCXCursor(cast<VarDecl>(Def)->getDescribedVarTemplate(), TU);
5272 return clang_getNullCursor();
5273 }
5274
Guy Benyei11169dd2012-12-18 14:30:41 +00005275 case Decl::Using:
5276 return MakeCursorOverloadedDeclRef(cast<UsingDecl>(D),
5277 D->getLocation(), TU);
5278
5279 case Decl::UsingShadow:
5280 return clang_getCursorDefinition(
5281 MakeCXCursor(cast<UsingShadowDecl>(D)->getTargetDecl(),
5282 TU));
5283
5284 case Decl::ObjCMethod: {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005285 const ObjCMethodDecl *Method = cast<ObjCMethodDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00005286 if (Method->isThisDeclarationADefinition())
5287 return C;
5288
5289 // Dig out the method definition in the associated
5290 // @implementation, if we have it.
5291 // FIXME: The ASTs should make finding the definition easier.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005292 if (const ObjCInterfaceDecl *Class
Guy Benyei11169dd2012-12-18 14:30:41 +00005293 = dyn_cast<ObjCInterfaceDecl>(Method->getDeclContext()))
5294 if (ObjCImplementationDecl *ClassImpl = Class->getImplementation())
5295 if (ObjCMethodDecl *Def = ClassImpl->getMethod(Method->getSelector(),
5296 Method->isInstanceMethod()))
5297 if (Def->isThisDeclarationADefinition())
5298 return MakeCXCursor(Def, TU);
5299
5300 return clang_getNullCursor();
5301 }
5302
5303 case Decl::ObjCCategory:
5304 if (ObjCCategoryImplDecl *Impl
5305 = cast<ObjCCategoryDecl>(D)->getImplementation())
5306 return MakeCXCursor(Impl, TU);
5307 return clang_getNullCursor();
5308
5309 case Decl::ObjCProtocol:
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005310 if (const ObjCProtocolDecl *Def = cast<ObjCProtocolDecl>(D)->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005311 return MakeCXCursor(Def, TU);
5312 return clang_getNullCursor();
5313
5314 case Decl::ObjCInterface: {
5315 // There are two notions of a "definition" for an Objective-C
5316 // class: the interface and its implementation. When we resolved a
5317 // reference to an Objective-C class, produce the @interface as
5318 // the definition; when we were provided with the interface,
5319 // produce the @implementation as the definition.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005320 const ObjCInterfaceDecl *IFace = cast<ObjCInterfaceDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00005321 if (WasReference) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005322 if (const ObjCInterfaceDecl *Def = IFace->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005323 return MakeCXCursor(Def, TU);
5324 } else if (ObjCImplementationDecl *Impl = IFace->getImplementation())
5325 return MakeCXCursor(Impl, TU);
5326 return clang_getNullCursor();
5327 }
5328
5329 case Decl::ObjCProperty:
5330 // FIXME: We don't really know where to find the
5331 // ObjCPropertyImplDecls that implement this property.
5332 return clang_getNullCursor();
5333
5334 case Decl::ObjCCompatibleAlias:
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005335 if (const ObjCInterfaceDecl *Class
Guy Benyei11169dd2012-12-18 14:30:41 +00005336 = cast<ObjCCompatibleAliasDecl>(D)->getClassInterface())
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005337 if (const ObjCInterfaceDecl *Def = Class->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005338 return MakeCXCursor(Def, TU);
5339
5340 return clang_getNullCursor();
5341
5342 case Decl::Friend:
5343 if (NamedDecl *Friend = cast<FriendDecl>(D)->getFriendDecl())
5344 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
5345 return clang_getNullCursor();
5346
5347 case Decl::FriendTemplate:
5348 if (NamedDecl *Friend = cast<FriendTemplateDecl>(D)->getFriendDecl())
5349 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
5350 return clang_getNullCursor();
5351 }
5352
5353 return clang_getNullCursor();
5354}
5355
5356unsigned clang_isCursorDefinition(CXCursor C) {
5357 if (!clang_isDeclaration(C.kind))
5358 return 0;
5359
5360 return clang_getCursorDefinition(C) == C;
5361}
5362
5363CXCursor clang_getCanonicalCursor(CXCursor C) {
5364 if (!clang_isDeclaration(C.kind))
5365 return C;
5366
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005367 if (const Decl *D = getCursorDecl(C)) {
5368 if (const ObjCCategoryImplDecl *CatImplD = dyn_cast<ObjCCategoryImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00005369 if (ObjCCategoryDecl *CatD = CatImplD->getCategoryDecl())
5370 return MakeCXCursor(CatD, getCursorTU(C));
5371
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005372 if (const ObjCImplDecl *ImplD = dyn_cast<ObjCImplDecl>(D))
5373 if (const ObjCInterfaceDecl *IFD = ImplD->getClassInterface())
Guy Benyei11169dd2012-12-18 14:30:41 +00005374 return MakeCXCursor(IFD, getCursorTU(C));
5375
5376 return MakeCXCursor(D->getCanonicalDecl(), getCursorTU(C));
5377 }
5378
5379 return C;
5380}
5381
5382int clang_Cursor_getObjCSelectorIndex(CXCursor cursor) {
5383 return cxcursor::getSelectorIdentifierIndexAndLoc(cursor).first;
5384}
5385
5386unsigned clang_getNumOverloadedDecls(CXCursor C) {
5387 if (C.kind != CXCursor_OverloadedDeclRef)
5388 return 0;
5389
5390 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005391 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Guy Benyei11169dd2012-12-18 14:30:41 +00005392 return E->getNumDecls();
5393
5394 if (OverloadedTemplateStorage *S
5395 = Storage.dyn_cast<OverloadedTemplateStorage*>())
5396 return S->size();
5397
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005398 const Decl *D = Storage.get<const Decl *>();
5399 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00005400 return Using->shadow_size();
5401
5402 return 0;
5403}
5404
5405CXCursor clang_getOverloadedDecl(CXCursor cursor, unsigned index) {
5406 if (cursor.kind != CXCursor_OverloadedDeclRef)
5407 return clang_getNullCursor();
5408
5409 if (index >= clang_getNumOverloadedDecls(cursor))
5410 return clang_getNullCursor();
5411
5412 CXTranslationUnit TU = getCursorTU(cursor);
5413 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(cursor).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005414 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Guy Benyei11169dd2012-12-18 14:30:41 +00005415 return MakeCXCursor(E->decls_begin()[index], TU);
5416
5417 if (OverloadedTemplateStorage *S
5418 = Storage.dyn_cast<OverloadedTemplateStorage*>())
5419 return MakeCXCursor(S->begin()[index], TU);
5420
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005421 const Decl *D = Storage.get<const Decl *>();
5422 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005423 // FIXME: This is, unfortunately, linear time.
5424 UsingDecl::shadow_iterator Pos = Using->shadow_begin();
5425 std::advance(Pos, index);
5426 return MakeCXCursor(cast<UsingShadowDecl>(*Pos)->getTargetDecl(), TU);
5427 }
5428
5429 return clang_getNullCursor();
5430}
5431
5432void clang_getDefinitionSpellingAndExtent(CXCursor C,
5433 const char **startBuf,
5434 const char **endBuf,
5435 unsigned *startLine,
5436 unsigned *startColumn,
5437 unsigned *endLine,
5438 unsigned *endColumn) {
5439 assert(getCursorDecl(C) && "CXCursor has null decl");
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005440 const FunctionDecl *FD = dyn_cast<FunctionDecl>(getCursorDecl(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00005441 CompoundStmt *Body = dyn_cast<CompoundStmt>(FD->getBody());
5442
5443 SourceManager &SM = FD->getASTContext().getSourceManager();
5444 *startBuf = SM.getCharacterData(Body->getLBracLoc());
5445 *endBuf = SM.getCharacterData(Body->getRBracLoc());
5446 *startLine = SM.getSpellingLineNumber(Body->getLBracLoc());
5447 *startColumn = SM.getSpellingColumnNumber(Body->getLBracLoc());
5448 *endLine = SM.getSpellingLineNumber(Body->getRBracLoc());
5449 *endColumn = SM.getSpellingColumnNumber(Body->getRBracLoc());
5450}
5451
5452
5453CXSourceRange clang_getCursorReferenceNameRange(CXCursor C, unsigned NameFlags,
5454 unsigned PieceIndex) {
5455 RefNamePieces Pieces;
5456
5457 switch (C.kind) {
5458 case CXCursor_MemberRefExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005459 if (const MemberExpr *E = dyn_cast<MemberExpr>(getCursorExpr(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00005460 Pieces = buildPieces(NameFlags, true, E->getMemberNameInfo(),
5461 E->getQualifierLoc().getSourceRange());
5462 break;
5463
5464 case CXCursor_DeclRefExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005465 if (const DeclRefExpr *E = dyn_cast<DeclRefExpr>(getCursorExpr(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00005466 Pieces = buildPieces(NameFlags, false, E->getNameInfo(),
5467 E->getQualifierLoc().getSourceRange(),
5468 E->getOptionalExplicitTemplateArgs());
5469 break;
5470
5471 case CXCursor_CallExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005472 if (const CXXOperatorCallExpr *OCE =
Guy Benyei11169dd2012-12-18 14:30:41 +00005473 dyn_cast<CXXOperatorCallExpr>(getCursorExpr(C))) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005474 const Expr *Callee = OCE->getCallee();
5475 if (const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Callee))
Guy Benyei11169dd2012-12-18 14:30:41 +00005476 Callee = ICE->getSubExpr();
5477
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005478 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(Callee))
Guy Benyei11169dd2012-12-18 14:30:41 +00005479 Pieces = buildPieces(NameFlags, false, DRE->getNameInfo(),
5480 DRE->getQualifierLoc().getSourceRange());
5481 }
5482 break;
5483
5484 default:
5485 break;
5486 }
5487
5488 if (Pieces.empty()) {
5489 if (PieceIndex == 0)
5490 return clang_getCursorExtent(C);
5491 } else if (PieceIndex < Pieces.size()) {
5492 SourceRange R = Pieces[PieceIndex];
5493 if (R.isValid())
5494 return cxloc::translateSourceRange(getCursorContext(C), R);
5495 }
5496
5497 return clang_getNullRange();
5498}
5499
5500void clang_enableStackTraces(void) {
5501 llvm::sys::PrintStackTraceOnErrorSignal();
5502}
5503
5504void clang_executeOnThread(void (*fn)(void*), void *user_data,
5505 unsigned stack_size) {
5506 llvm::llvm_execute_on_thread(fn, user_data, stack_size);
5507}
5508
5509} // end: extern "C"
5510
5511//===----------------------------------------------------------------------===//
5512// Token-based Operations.
5513//===----------------------------------------------------------------------===//
5514
5515/* CXToken layout:
5516 * int_data[0]: a CXTokenKind
5517 * int_data[1]: starting token location
5518 * int_data[2]: token length
5519 * int_data[3]: reserved
5520 * ptr_data: for identifiers and keywords, an IdentifierInfo*.
5521 * otherwise unused.
5522 */
5523extern "C" {
5524
5525CXTokenKind clang_getTokenKind(CXToken CXTok) {
5526 return static_cast<CXTokenKind>(CXTok.int_data[0]);
5527}
5528
5529CXString clang_getTokenSpelling(CXTranslationUnit TU, CXToken CXTok) {
5530 switch (clang_getTokenKind(CXTok)) {
5531 case CXToken_Identifier:
5532 case CXToken_Keyword:
5533 // We know we have an IdentifierInfo*, so use that.
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005534 return cxstring::createRef(static_cast<IdentifierInfo *>(CXTok.ptr_data)
Guy Benyei11169dd2012-12-18 14:30:41 +00005535 ->getNameStart());
5536
5537 case CXToken_Literal: {
5538 // We have stashed the starting pointer in the ptr_data field. Use it.
5539 const char *Text = static_cast<const char *>(CXTok.ptr_data);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00005540 return cxstring::createDup(StringRef(Text, CXTok.int_data[2]));
Guy Benyei11169dd2012-12-18 14:30:41 +00005541 }
5542
5543 case CXToken_Punctuation:
5544 case CXToken_Comment:
5545 break;
5546 }
5547
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005548 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005549 LOG_BAD_TU(TU);
5550 return cxstring::createEmpty();
5551 }
5552
Guy Benyei11169dd2012-12-18 14:30:41 +00005553 // We have to find the starting buffer pointer the hard way, by
5554 // deconstructing the source location.
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005555 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005556 if (!CXXUnit)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00005557 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00005558
5559 SourceLocation Loc = SourceLocation::getFromRawEncoding(CXTok.int_data[1]);
5560 std::pair<FileID, unsigned> LocInfo
5561 = CXXUnit->getSourceManager().getDecomposedSpellingLoc(Loc);
5562 bool Invalid = false;
5563 StringRef Buffer
5564 = CXXUnit->getSourceManager().getBufferData(LocInfo.first, &Invalid);
5565 if (Invalid)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00005566 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00005567
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00005568 return cxstring::createDup(Buffer.substr(LocInfo.second, CXTok.int_data[2]));
Guy Benyei11169dd2012-12-18 14:30:41 +00005569}
5570
5571CXSourceLocation clang_getTokenLocation(CXTranslationUnit TU, CXToken CXTok) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005572 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005573 LOG_BAD_TU(TU);
5574 return clang_getNullLocation();
5575 }
5576
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005577 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005578 if (!CXXUnit)
5579 return clang_getNullLocation();
5580
5581 return cxloc::translateSourceLocation(CXXUnit->getASTContext(),
5582 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
5583}
5584
5585CXSourceRange clang_getTokenExtent(CXTranslationUnit TU, CXToken CXTok) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005586 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005587 LOG_BAD_TU(TU);
5588 return clang_getNullRange();
5589 }
5590
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005591 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005592 if (!CXXUnit)
5593 return clang_getNullRange();
5594
5595 return cxloc::translateSourceRange(CXXUnit->getASTContext(),
5596 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
5597}
5598
5599static void getTokens(ASTUnit *CXXUnit, SourceRange Range,
5600 SmallVectorImpl<CXToken> &CXTokens) {
5601 SourceManager &SourceMgr = CXXUnit->getSourceManager();
5602 std::pair<FileID, unsigned> BeginLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005603 = SourceMgr.getDecomposedSpellingLoc(Range.getBegin());
Guy Benyei11169dd2012-12-18 14:30:41 +00005604 std::pair<FileID, unsigned> EndLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005605 = SourceMgr.getDecomposedSpellingLoc(Range.getEnd());
Guy Benyei11169dd2012-12-18 14:30:41 +00005606
5607 // Cannot tokenize across files.
5608 if (BeginLocInfo.first != EndLocInfo.first)
5609 return;
5610
5611 // Create a lexer
5612 bool Invalid = false;
5613 StringRef Buffer
5614 = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
5615 if (Invalid)
5616 return;
5617
5618 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
5619 CXXUnit->getASTContext().getLangOpts(),
5620 Buffer.begin(), Buffer.data() + BeginLocInfo.second, Buffer.end());
5621 Lex.SetCommentRetentionState(true);
5622
5623 // Lex tokens until we hit the end of the range.
5624 const char *EffectiveBufferEnd = Buffer.data() + EndLocInfo.second;
5625 Token Tok;
5626 bool previousWasAt = false;
5627 do {
5628 // Lex the next token
5629 Lex.LexFromRawLexer(Tok);
5630 if (Tok.is(tok::eof))
5631 break;
5632
5633 // Initialize the CXToken.
5634 CXToken CXTok;
5635
5636 // - Common fields
5637 CXTok.int_data[1] = Tok.getLocation().getRawEncoding();
5638 CXTok.int_data[2] = Tok.getLength();
5639 CXTok.int_data[3] = 0;
5640
5641 // - Kind-specific fields
5642 if (Tok.isLiteral()) {
5643 CXTok.int_data[0] = CXToken_Literal;
Dmitri Gribenkof9304482013-01-23 15:56:07 +00005644 CXTok.ptr_data = const_cast<char *>(Tok.getLiteralData());
Guy Benyei11169dd2012-12-18 14:30:41 +00005645 } else if (Tok.is(tok::raw_identifier)) {
5646 // Lookup the identifier to determine whether we have a keyword.
5647 IdentifierInfo *II
5648 = CXXUnit->getPreprocessor().LookUpIdentifierInfo(Tok);
5649
5650 if ((II->getObjCKeywordID() != tok::objc_not_keyword) && previousWasAt) {
5651 CXTok.int_data[0] = CXToken_Keyword;
5652 }
5653 else {
5654 CXTok.int_data[0] = Tok.is(tok::identifier)
5655 ? CXToken_Identifier
5656 : CXToken_Keyword;
5657 }
5658 CXTok.ptr_data = II;
5659 } else if (Tok.is(tok::comment)) {
5660 CXTok.int_data[0] = CXToken_Comment;
Craig Topper69186e72014-06-08 08:38:04 +00005661 CXTok.ptr_data = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005662 } else {
5663 CXTok.int_data[0] = CXToken_Punctuation;
Craig Topper69186e72014-06-08 08:38:04 +00005664 CXTok.ptr_data = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005665 }
5666 CXTokens.push_back(CXTok);
5667 previousWasAt = Tok.is(tok::at);
5668 } while (Lex.getBufferLocation() <= EffectiveBufferEnd);
5669}
5670
5671void clang_tokenize(CXTranslationUnit TU, CXSourceRange Range,
5672 CXToken **Tokens, unsigned *NumTokens) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00005673 LOG_FUNC_SECTION {
5674 *Log << TU << ' ' << Range;
5675 }
5676
Guy Benyei11169dd2012-12-18 14:30:41 +00005677 if (Tokens)
Craig Topper69186e72014-06-08 08:38:04 +00005678 *Tokens = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005679 if (NumTokens)
5680 *NumTokens = 0;
5681
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005682 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005683 LOG_BAD_TU(TU);
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00005684 return;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005685 }
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00005686
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005687 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005688 if (!CXXUnit || !Tokens || !NumTokens)
5689 return;
5690
5691 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
5692
5693 SourceRange R = cxloc::translateCXSourceRange(Range);
5694 if (R.isInvalid())
5695 return;
5696
5697 SmallVector<CXToken, 32> CXTokens;
5698 getTokens(CXXUnit, R, CXTokens);
5699
5700 if (CXTokens.empty())
5701 return;
5702
5703 *Tokens = (CXToken *)malloc(sizeof(CXToken) * CXTokens.size());
5704 memmove(*Tokens, CXTokens.data(), sizeof(CXToken) * CXTokens.size());
5705 *NumTokens = CXTokens.size();
5706}
5707
5708void clang_disposeTokens(CXTranslationUnit TU,
5709 CXToken *Tokens, unsigned NumTokens) {
5710 free(Tokens);
5711}
5712
5713} // end: extern "C"
5714
5715//===----------------------------------------------------------------------===//
5716// Token annotation APIs.
5717//===----------------------------------------------------------------------===//
5718
Guy Benyei11169dd2012-12-18 14:30:41 +00005719static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
5720 CXCursor parent,
5721 CXClientData client_data);
5722static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
5723 CXClientData client_data);
5724
5725namespace {
5726class AnnotateTokensWorker {
Guy Benyei11169dd2012-12-18 14:30:41 +00005727 CXToken *Tokens;
5728 CXCursor *Cursors;
5729 unsigned NumTokens;
5730 unsigned TokIdx;
5731 unsigned PreprocessingTokIdx;
5732 CursorVisitor AnnotateVis;
5733 SourceManager &SrcMgr;
5734 bool HasContextSensitiveKeywords;
5735
5736 struct PostChildrenInfo {
5737 CXCursor Cursor;
5738 SourceRange CursorRange;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005739 unsigned BeforeReachingCursorIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00005740 unsigned BeforeChildrenTokenIdx;
5741 };
Dmitri Gribenkof8579502013-01-12 19:30:44 +00005742 SmallVector<PostChildrenInfo, 8> PostChildrenInfos;
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005743
5744 CXToken &getTok(unsigned Idx) {
5745 assert(Idx < NumTokens);
5746 return Tokens[Idx];
5747 }
5748 const CXToken &getTok(unsigned Idx) const {
5749 assert(Idx < NumTokens);
5750 return Tokens[Idx];
5751 }
Guy Benyei11169dd2012-12-18 14:30:41 +00005752 bool MoreTokens() const { return TokIdx < NumTokens; }
5753 unsigned NextToken() const { return TokIdx; }
5754 void AdvanceToken() { ++TokIdx; }
5755 SourceLocation GetTokenLoc(unsigned tokI) {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005756 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[1]);
Guy Benyei11169dd2012-12-18 14:30:41 +00005757 }
5758 bool isFunctionMacroToken(unsigned tokI) const {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005759 return getTok(tokI).int_data[3] != 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00005760 }
5761 SourceLocation getFunctionMacroTokenLoc(unsigned tokI) const {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005762 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[3]);
Guy Benyei11169dd2012-12-18 14:30:41 +00005763 }
5764
5765 void annotateAndAdvanceTokens(CXCursor, RangeComparisonResult, SourceRange);
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005766 bool annotateAndAdvanceFunctionMacroTokens(CXCursor, RangeComparisonResult,
Guy Benyei11169dd2012-12-18 14:30:41 +00005767 SourceRange);
5768
5769public:
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005770 AnnotateTokensWorker(CXToken *tokens, CXCursor *cursors, unsigned numTokens,
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005771 CXTranslationUnit TU, SourceRange RegionOfInterest)
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005772 : Tokens(tokens), Cursors(cursors),
Guy Benyei11169dd2012-12-18 14:30:41 +00005773 NumTokens(numTokens), TokIdx(0), PreprocessingTokIdx(0),
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005774 AnnotateVis(TU,
Guy Benyei11169dd2012-12-18 14:30:41 +00005775 AnnotateTokensVisitor, this,
5776 /*VisitPreprocessorLast=*/true,
5777 /*VisitIncludedEntities=*/false,
5778 RegionOfInterest,
5779 /*VisitDeclsOnly=*/false,
5780 AnnotateTokensPostChildrenVisitor),
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005781 SrcMgr(cxtu::getASTUnit(TU)->getSourceManager()),
Guy Benyei11169dd2012-12-18 14:30:41 +00005782 HasContextSensitiveKeywords(false) { }
5783
5784 void VisitChildren(CXCursor C) { AnnotateVis.VisitChildren(C); }
5785 enum CXChildVisitResult Visit(CXCursor cursor, CXCursor parent);
5786 bool postVisitChildren(CXCursor cursor);
5787 void AnnotateTokens();
5788
5789 /// \brief Determine whether the annotator saw any cursors that have
5790 /// context-sensitive keywords.
5791 bool hasContextSensitiveKeywords() const {
5792 return HasContextSensitiveKeywords;
5793 }
5794
5795 ~AnnotateTokensWorker() {
5796 assert(PostChildrenInfos.empty());
5797 }
5798};
Alexander Kornienkoab9db512015-06-22 23:07:51 +00005799}
Guy Benyei11169dd2012-12-18 14:30:41 +00005800
5801void AnnotateTokensWorker::AnnotateTokens() {
5802 // Walk the AST within the region of interest, annotating tokens
5803 // along the way.
5804 AnnotateVis.visitFileRegion();
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005805}
Guy Benyei11169dd2012-12-18 14:30:41 +00005806
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005807static inline void updateCursorAnnotation(CXCursor &Cursor,
5808 const CXCursor &updateC) {
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005809 if (clang_isInvalid(updateC.kind) || !clang_isInvalid(Cursor.kind))
Guy Benyei11169dd2012-12-18 14:30:41 +00005810 return;
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005811 Cursor = updateC;
Guy Benyei11169dd2012-12-18 14:30:41 +00005812}
5813
5814/// \brief It annotates and advances tokens with a cursor until the comparison
5815//// between the cursor location and the source range is the same as
5816/// \arg compResult.
5817///
5818/// Pass RangeBefore to annotate tokens with a cursor until a range is reached.
5819/// Pass RangeOverlap to annotate tokens inside a range.
5820void AnnotateTokensWorker::annotateAndAdvanceTokens(CXCursor updateC,
5821 RangeComparisonResult compResult,
5822 SourceRange range) {
5823 while (MoreTokens()) {
5824 const unsigned I = NextToken();
5825 if (isFunctionMacroToken(I))
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005826 if (!annotateAndAdvanceFunctionMacroTokens(updateC, compResult, range))
5827 return;
Guy Benyei11169dd2012-12-18 14:30:41 +00005828
5829 SourceLocation TokLoc = GetTokenLoc(I);
5830 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005831 updateCursorAnnotation(Cursors[I], updateC);
Guy Benyei11169dd2012-12-18 14:30:41 +00005832 AdvanceToken();
5833 continue;
5834 }
5835 break;
5836 }
5837}
5838
5839/// \brief Special annotation handling for macro argument tokens.
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005840/// \returns true if it advanced beyond all macro tokens, false otherwise.
5841bool AnnotateTokensWorker::annotateAndAdvanceFunctionMacroTokens(
Guy Benyei11169dd2012-12-18 14:30:41 +00005842 CXCursor updateC,
5843 RangeComparisonResult compResult,
5844 SourceRange range) {
5845 assert(MoreTokens());
5846 assert(isFunctionMacroToken(NextToken()) &&
5847 "Should be called only for macro arg tokens");
5848
5849 // This works differently than annotateAndAdvanceTokens; because expanded
5850 // macro arguments can have arbitrary translation-unit source order, we do not
5851 // advance the token index one by one until a token fails the range test.
5852 // We only advance once past all of the macro arg tokens if all of them
5853 // pass the range test. If one of them fails we keep the token index pointing
5854 // at the start of the macro arg tokens so that the failing token will be
5855 // annotated by a subsequent annotation try.
5856
5857 bool atLeastOneCompFail = false;
5858
5859 unsigned I = NextToken();
5860 for (; I < NumTokens && isFunctionMacroToken(I); ++I) {
5861 SourceLocation TokLoc = getFunctionMacroTokenLoc(I);
5862 if (TokLoc.isFileID())
5863 continue; // not macro arg token, it's parens or comma.
5864 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
5865 if (clang_isInvalid(clang_getCursorKind(Cursors[I])))
5866 Cursors[I] = updateC;
5867 } else
5868 atLeastOneCompFail = true;
5869 }
5870
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005871 if (atLeastOneCompFail)
5872 return false;
5873
5874 TokIdx = I; // All of the tokens were handled, advance beyond all of them.
5875 return true;
Guy Benyei11169dd2012-12-18 14:30:41 +00005876}
5877
5878enum CXChildVisitResult
5879AnnotateTokensWorker::Visit(CXCursor cursor, CXCursor parent) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005880 SourceRange cursorRange = getRawCursorExtent(cursor);
5881 if (cursorRange.isInvalid())
5882 return CXChildVisit_Recurse;
5883
5884 if (!HasContextSensitiveKeywords) {
5885 // Objective-C properties can have context-sensitive keywords.
5886 if (cursor.kind == CXCursor_ObjCPropertyDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005887 if (const ObjCPropertyDecl *Property
Guy Benyei11169dd2012-12-18 14:30:41 +00005888 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(cursor)))
5889 HasContextSensitiveKeywords = Property->getPropertyAttributesAsWritten() != 0;
5890 }
5891 // Objective-C methods can have context-sensitive keywords.
5892 else if (cursor.kind == CXCursor_ObjCInstanceMethodDecl ||
5893 cursor.kind == CXCursor_ObjCClassMethodDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005894 if (const ObjCMethodDecl *Method
Guy Benyei11169dd2012-12-18 14:30:41 +00005895 = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
5896 if (Method->getObjCDeclQualifier())
5897 HasContextSensitiveKeywords = true;
5898 else {
Aaron Ballman43b68be2014-03-07 17:50:17 +00005899 for (const auto *P : Method->params()) {
5900 if (P->getObjCDeclQualifier()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005901 HasContextSensitiveKeywords = true;
5902 break;
5903 }
5904 }
5905 }
5906 }
5907 }
5908 // C++ methods can have context-sensitive keywords.
5909 else if (cursor.kind == CXCursor_CXXMethod) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005910 if (const CXXMethodDecl *Method
Guy Benyei11169dd2012-12-18 14:30:41 +00005911 = dyn_cast_or_null<CXXMethodDecl>(getCursorDecl(cursor))) {
5912 if (Method->hasAttr<FinalAttr>() || Method->hasAttr<OverrideAttr>())
5913 HasContextSensitiveKeywords = true;
5914 }
5915 }
5916 // C++ classes can have context-sensitive keywords.
5917 else if (cursor.kind == CXCursor_StructDecl ||
5918 cursor.kind == CXCursor_ClassDecl ||
5919 cursor.kind == CXCursor_ClassTemplate ||
5920 cursor.kind == CXCursor_ClassTemplatePartialSpecialization) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005921 if (const Decl *D = getCursorDecl(cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +00005922 if (D->hasAttr<FinalAttr>())
5923 HasContextSensitiveKeywords = true;
5924 }
5925 }
Argyrios Kyrtzidis990b3862013-06-04 18:24:30 +00005926
5927 // Don't override a property annotation with its getter/setter method.
5928 if (cursor.kind == CXCursor_ObjCInstanceMethodDecl &&
5929 parent.kind == CXCursor_ObjCPropertyDecl)
5930 return CXChildVisit_Continue;
Guy Benyei11169dd2012-12-18 14:30:41 +00005931
5932 if (clang_isPreprocessing(cursor.kind)) {
5933 // Items in the preprocessing record are kept separate from items in
5934 // declarations, so we keep a separate token index.
5935 unsigned SavedTokIdx = TokIdx;
5936 TokIdx = PreprocessingTokIdx;
5937
5938 // Skip tokens up until we catch up to the beginning of the preprocessing
5939 // entry.
5940 while (MoreTokens()) {
5941 const unsigned I = NextToken();
5942 SourceLocation TokLoc = GetTokenLoc(I);
5943 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
5944 case RangeBefore:
5945 AdvanceToken();
5946 continue;
5947 case RangeAfter:
5948 case RangeOverlap:
5949 break;
5950 }
5951 break;
5952 }
5953
5954 // Look at all of the tokens within this range.
5955 while (MoreTokens()) {
5956 const unsigned I = NextToken();
5957 SourceLocation TokLoc = GetTokenLoc(I);
5958 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
5959 case RangeBefore:
5960 llvm_unreachable("Infeasible");
5961 case RangeAfter:
5962 break;
5963 case RangeOverlap:
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005964 // For macro expansions, just note where the beginning of the macro
5965 // expansion occurs.
5966 if (cursor.kind == CXCursor_MacroExpansion) {
5967 if (TokLoc == cursorRange.getBegin())
5968 Cursors[I] = cursor;
5969 AdvanceToken();
5970 break;
5971 }
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005972 // We may have already annotated macro names inside macro definitions.
5973 if (Cursors[I].kind != CXCursor_MacroExpansion)
5974 Cursors[I] = cursor;
Guy Benyei11169dd2012-12-18 14:30:41 +00005975 AdvanceToken();
Guy Benyei11169dd2012-12-18 14:30:41 +00005976 continue;
5977 }
5978 break;
5979 }
5980
5981 // Save the preprocessing token index; restore the non-preprocessing
5982 // token index.
5983 PreprocessingTokIdx = TokIdx;
5984 TokIdx = SavedTokIdx;
5985 return CXChildVisit_Recurse;
5986 }
5987
5988 if (cursorRange.isInvalid())
5989 return CXChildVisit_Continue;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005990
5991 unsigned BeforeReachingCursorIdx = NextToken();
Guy Benyei11169dd2012-12-18 14:30:41 +00005992 const enum CXCursorKind cursorK = clang_getCursorKind(cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00005993 const enum CXCursorKind K = clang_getCursorKind(parent);
5994 const CXCursor updateC =
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005995 (clang_isInvalid(K) || K == CXCursor_TranslationUnit ||
5996 // Attributes are annotated out-of-order, skip tokens until we reach it.
5997 clang_isAttribute(cursor.kind))
Guy Benyei11169dd2012-12-18 14:30:41 +00005998 ? clang_getNullCursor() : parent;
5999
6000 annotateAndAdvanceTokens(updateC, RangeBefore, cursorRange);
6001
6002 // Avoid having the cursor of an expression "overwrite" the annotation of the
6003 // variable declaration that it belongs to.
6004 // This can happen for C++ constructor expressions whose range generally
6005 // include the variable declaration, e.g.:
6006 // MyCXXClass foo; // Make sure we don't annotate 'foo' as a CallExpr cursor.
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00006007 if (clang_isExpression(cursorK) && MoreTokens()) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00006008 const Expr *E = getCursorExpr(cursor);
Dmitri Gribenkoa1691182013-01-26 18:12:08 +00006009 if (const Decl *D = getCursorParentDecl(cursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00006010 const unsigned I = NextToken();
6011 if (E->getLocStart().isValid() && D->getLocation().isValid() &&
6012 E->getLocStart() == D->getLocation() &&
6013 E->getLocStart() == GetTokenLoc(I)) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006014 updateCursorAnnotation(Cursors[I], updateC);
Guy Benyei11169dd2012-12-18 14:30:41 +00006015 AdvanceToken();
6016 }
6017 }
6018 }
6019
6020 // Before recursing into the children keep some state that we are going
6021 // to use in the AnnotateTokensWorker::postVisitChildren callback to do some
6022 // extra work after the child nodes are visited.
6023 // Note that we don't call VisitChildren here to avoid traversing statements
6024 // code-recursively which can blow the stack.
6025
6026 PostChildrenInfo Info;
6027 Info.Cursor = cursor;
6028 Info.CursorRange = cursorRange;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00006029 Info.BeforeReachingCursorIdx = BeforeReachingCursorIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00006030 Info.BeforeChildrenTokenIdx = NextToken();
6031 PostChildrenInfos.push_back(Info);
6032
6033 return CXChildVisit_Recurse;
6034}
6035
6036bool AnnotateTokensWorker::postVisitChildren(CXCursor cursor) {
6037 if (PostChildrenInfos.empty())
6038 return false;
6039 const PostChildrenInfo &Info = PostChildrenInfos.back();
6040 if (!clang_equalCursors(Info.Cursor, cursor))
6041 return false;
6042
6043 const unsigned BeforeChildren = Info.BeforeChildrenTokenIdx;
6044 const unsigned AfterChildren = NextToken();
6045 SourceRange cursorRange = Info.CursorRange;
6046
6047 // Scan the tokens that are at the end of the cursor, but are not captured
6048 // but the child cursors.
6049 annotateAndAdvanceTokens(cursor, RangeOverlap, cursorRange);
6050
6051 // Scan the tokens that are at the beginning of the cursor, but are not
6052 // capture by the child cursors.
6053 for (unsigned I = BeforeChildren; I != AfterChildren; ++I) {
6054 if (!clang_isInvalid(clang_getCursorKind(Cursors[I])))
6055 break;
6056
6057 Cursors[I] = cursor;
6058 }
6059
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00006060 // Attributes are annotated out-of-order, rewind TokIdx to when we first
6061 // encountered the attribute cursor.
6062 if (clang_isAttribute(cursor.kind))
6063 TokIdx = Info.BeforeReachingCursorIdx;
6064
Guy Benyei11169dd2012-12-18 14:30:41 +00006065 PostChildrenInfos.pop_back();
6066 return false;
6067}
6068
6069static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
6070 CXCursor parent,
6071 CXClientData client_data) {
6072 return static_cast<AnnotateTokensWorker*>(client_data)->Visit(cursor, parent);
6073}
6074
6075static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
6076 CXClientData client_data) {
6077 return static_cast<AnnotateTokensWorker*>(client_data)->
6078 postVisitChildren(cursor);
6079}
6080
6081namespace {
6082
6083/// \brief Uses the macro expansions in the preprocessing record to find
6084/// and mark tokens that are macro arguments. This info is used by the
6085/// AnnotateTokensWorker.
6086class MarkMacroArgTokensVisitor {
6087 SourceManager &SM;
6088 CXToken *Tokens;
6089 unsigned NumTokens;
6090 unsigned CurIdx;
6091
6092public:
6093 MarkMacroArgTokensVisitor(SourceManager &SM,
6094 CXToken *tokens, unsigned numTokens)
6095 : SM(SM), Tokens(tokens), NumTokens(numTokens), CurIdx(0) { }
6096
6097 CXChildVisitResult visit(CXCursor cursor, CXCursor parent) {
6098 if (cursor.kind != CXCursor_MacroExpansion)
6099 return CXChildVisit_Continue;
6100
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006101 SourceRange macroRange = getCursorMacroExpansion(cursor).getSourceRange();
Guy Benyei11169dd2012-12-18 14:30:41 +00006102 if (macroRange.getBegin() == macroRange.getEnd())
6103 return CXChildVisit_Continue; // it's not a function macro.
6104
6105 for (; CurIdx < NumTokens; ++CurIdx) {
6106 if (!SM.isBeforeInTranslationUnit(getTokenLoc(CurIdx),
6107 macroRange.getBegin()))
6108 break;
6109 }
6110
6111 if (CurIdx == NumTokens)
6112 return CXChildVisit_Break;
6113
6114 for (; CurIdx < NumTokens; ++CurIdx) {
6115 SourceLocation tokLoc = getTokenLoc(CurIdx);
6116 if (!SM.isBeforeInTranslationUnit(tokLoc, macroRange.getEnd()))
6117 break;
6118
6119 setFunctionMacroTokenLoc(CurIdx, SM.getMacroArgExpandedLocation(tokLoc));
6120 }
6121
6122 if (CurIdx == NumTokens)
6123 return CXChildVisit_Break;
6124
6125 return CXChildVisit_Continue;
6126 }
6127
6128private:
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00006129 CXToken &getTok(unsigned Idx) {
6130 assert(Idx < NumTokens);
6131 return Tokens[Idx];
6132 }
6133 const CXToken &getTok(unsigned Idx) const {
6134 assert(Idx < NumTokens);
6135 return Tokens[Idx];
6136 }
6137
Guy Benyei11169dd2012-12-18 14:30:41 +00006138 SourceLocation getTokenLoc(unsigned tokI) {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00006139 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[1]);
Guy Benyei11169dd2012-12-18 14:30:41 +00006140 }
6141
6142 void setFunctionMacroTokenLoc(unsigned tokI, SourceLocation loc) {
6143 // The third field is reserved and currently not used. Use it here
6144 // to mark macro arg expanded tokens with their expanded locations.
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00006145 getTok(tokI).int_data[3] = loc.getRawEncoding();
Guy Benyei11169dd2012-12-18 14:30:41 +00006146 }
6147};
6148
6149} // end anonymous namespace
6150
6151static CXChildVisitResult
6152MarkMacroArgTokensVisitorDelegate(CXCursor cursor, CXCursor parent,
6153 CXClientData client_data) {
6154 return static_cast<MarkMacroArgTokensVisitor*>(client_data)->visit(cursor,
6155 parent);
6156}
6157
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006158/// \brief Used by \c annotatePreprocessorTokens.
6159/// \returns true if lexing was finished, false otherwise.
6160static bool lexNext(Lexer &Lex, Token &Tok,
6161 unsigned &NextIdx, unsigned NumTokens) {
6162 if (NextIdx >= NumTokens)
6163 return true;
6164
6165 ++NextIdx;
6166 Lex.LexFromRawLexer(Tok);
6167 if (Tok.is(tok::eof))
6168 return true;
6169
6170 return false;
6171}
6172
Guy Benyei11169dd2012-12-18 14:30:41 +00006173static void annotatePreprocessorTokens(CXTranslationUnit TU,
6174 SourceRange RegionOfInterest,
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006175 CXCursor *Cursors,
6176 CXToken *Tokens,
6177 unsigned NumTokens) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006178 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00006179
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006180 Preprocessor &PP = CXXUnit->getPreprocessor();
Guy Benyei11169dd2012-12-18 14:30:41 +00006181 SourceManager &SourceMgr = CXXUnit->getSourceManager();
6182 std::pair<FileID, unsigned> BeginLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00006183 = SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getBegin());
Guy Benyei11169dd2012-12-18 14:30:41 +00006184 std::pair<FileID, unsigned> EndLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00006185 = SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getEnd());
Guy Benyei11169dd2012-12-18 14:30:41 +00006186
6187 if (BeginLocInfo.first != EndLocInfo.first)
6188 return;
6189
6190 StringRef Buffer;
6191 bool Invalid = false;
6192 Buffer = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
6193 if (Buffer.empty() || Invalid)
6194 return;
6195
6196 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
6197 CXXUnit->getASTContext().getLangOpts(),
6198 Buffer.begin(), Buffer.data() + BeginLocInfo.second,
6199 Buffer.end());
6200 Lex.SetCommentRetentionState(true);
6201
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006202 unsigned NextIdx = 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00006203 // Lex tokens in raw mode until we hit the end of the range, to avoid
6204 // entering #includes or expanding macros.
6205 while (true) {
6206 Token Tok;
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006207 if (lexNext(Lex, Tok, NextIdx, NumTokens))
6208 break;
6209 unsigned TokIdx = NextIdx-1;
6210 assert(Tok.getLocation() ==
6211 SourceLocation::getFromRawEncoding(Tokens[TokIdx].int_data[1]));
Guy Benyei11169dd2012-12-18 14:30:41 +00006212
6213 reprocess:
6214 if (Tok.is(tok::hash) && Tok.isAtStartOfLine()) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006215 // We have found a preprocessing directive. Annotate the tokens
6216 // appropriately.
Guy Benyei11169dd2012-12-18 14:30:41 +00006217 //
6218 // FIXME: Some simple tests here could identify macro definitions and
6219 // #undefs, to provide specific cursor kinds for those.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006220
6221 SourceLocation BeginLoc = Tok.getLocation();
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006222 if (lexNext(Lex, Tok, NextIdx, NumTokens))
6223 break;
6224
Craig Topper69186e72014-06-08 08:38:04 +00006225 MacroInfo *MI = nullptr;
Alp Toker2d57cea2014-05-17 04:53:25 +00006226 if (Tok.is(tok::raw_identifier) && Tok.getRawIdentifier() == "define") {
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006227 if (lexNext(Lex, Tok, NextIdx, NumTokens))
6228 break;
6229
6230 if (Tok.is(tok::raw_identifier)) {
Alp Toker2d57cea2014-05-17 04:53:25 +00006231 IdentifierInfo &II =
6232 PP.getIdentifierTable().get(Tok.getRawIdentifier());
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006233 SourceLocation MappedTokLoc =
6234 CXXUnit->mapLocationToPreamble(Tok.getLocation());
6235 MI = getMacroInfo(II, MappedTokLoc, TU);
6236 }
6237 }
6238
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006239 bool finished = false;
Guy Benyei11169dd2012-12-18 14:30:41 +00006240 do {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006241 if (lexNext(Lex, Tok, NextIdx, NumTokens)) {
6242 finished = true;
6243 break;
6244 }
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006245 // If we are in a macro definition, check if the token was ever a
6246 // macro name and annotate it if that's the case.
6247 if (MI) {
6248 SourceLocation SaveLoc = Tok.getLocation();
6249 Tok.setLocation(CXXUnit->mapLocationToPreamble(SaveLoc));
Richard Smith66a81862015-05-04 02:25:31 +00006250 MacroDefinitionRecord *MacroDef =
6251 checkForMacroInMacroDefinition(MI, Tok, TU);
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006252 Tok.setLocation(SaveLoc);
6253 if (MacroDef)
Richard Smith66a81862015-05-04 02:25:31 +00006254 Cursors[NextIdx - 1] =
6255 MakeMacroExpansionCursor(MacroDef, Tok.getLocation(), TU);
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006256 }
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006257 } while (!Tok.isAtStartOfLine());
6258
6259 unsigned LastIdx = finished ? NextIdx-1 : NextIdx-2;
6260 assert(TokIdx <= LastIdx);
6261 SourceLocation EndLoc =
6262 SourceLocation::getFromRawEncoding(Tokens[LastIdx].int_data[1]);
6263 CXCursor Cursor =
6264 MakePreprocessingDirectiveCursor(SourceRange(BeginLoc, EndLoc), TU);
6265
6266 for (; TokIdx <= LastIdx; ++TokIdx)
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006267 updateCursorAnnotation(Cursors[TokIdx], Cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00006268
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006269 if (finished)
6270 break;
6271 goto reprocess;
Guy Benyei11169dd2012-12-18 14:30:41 +00006272 }
Guy Benyei11169dd2012-12-18 14:30:41 +00006273 }
6274}
6275
6276// This gets run a separate thread to avoid stack blowout.
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00006277static void clang_annotateTokensImpl(CXTranslationUnit TU, ASTUnit *CXXUnit,
6278 CXToken *Tokens, unsigned NumTokens,
6279 CXCursor *Cursors) {
Dmitri Gribenko183436e2013-01-26 21:49:50 +00006280 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00006281 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
6282 setThreadBackgroundPriority();
6283
6284 // Determine the region of interest, which contains all of the tokens.
6285 SourceRange RegionOfInterest;
6286 RegionOfInterest.setBegin(
6287 cxloc::translateSourceLocation(clang_getTokenLocation(TU, Tokens[0])));
6288 RegionOfInterest.setEnd(
6289 cxloc::translateSourceLocation(clang_getTokenLocation(TU,
6290 Tokens[NumTokens-1])));
6291
Guy Benyei11169dd2012-12-18 14:30:41 +00006292 // Relex the tokens within the source range to look for preprocessing
6293 // directives.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006294 annotatePreprocessorTokens(TU, RegionOfInterest, Cursors, Tokens, NumTokens);
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00006295
6296 // If begin location points inside a macro argument, set it to the expansion
6297 // location so we can have the full context when annotating semantically.
6298 {
6299 SourceManager &SM = CXXUnit->getSourceManager();
6300 SourceLocation Loc =
6301 SM.getMacroArgExpandedLocation(RegionOfInterest.getBegin());
6302 if (Loc.isMacroID())
6303 RegionOfInterest.setBegin(SM.getExpansionLoc(Loc));
6304 }
6305
Guy Benyei11169dd2012-12-18 14:30:41 +00006306 if (CXXUnit->getPreprocessor().getPreprocessingRecord()) {
6307 // Search and mark tokens that are macro argument expansions.
6308 MarkMacroArgTokensVisitor Visitor(CXXUnit->getSourceManager(),
6309 Tokens, NumTokens);
6310 CursorVisitor MacroArgMarker(TU,
6311 MarkMacroArgTokensVisitorDelegate, &Visitor,
6312 /*VisitPreprocessorLast=*/true,
6313 /*VisitIncludedEntities=*/false,
6314 RegionOfInterest);
6315 MacroArgMarker.visitPreprocessedEntitiesInRegion();
6316 }
6317
6318 // Annotate all of the source locations in the region of interest that map to
6319 // a specific cursor.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006320 AnnotateTokensWorker W(Tokens, Cursors, NumTokens, TU, RegionOfInterest);
Guy Benyei11169dd2012-12-18 14:30:41 +00006321
6322 // FIXME: We use a ridiculous stack size here because the data-recursion
6323 // algorithm uses a large stack frame than the non-data recursive version,
6324 // and AnnotationTokensWorker currently transforms the data-recursion
6325 // algorithm back into a traditional recursion by explicitly calling
6326 // VisitChildren(). We will need to remove this explicit recursive call.
6327 W.AnnotateTokens();
6328
6329 // If we ran into any entities that involve context-sensitive keywords,
6330 // take another pass through the tokens to mark them as such.
6331 if (W.hasContextSensitiveKeywords()) {
6332 for (unsigned I = 0; I != NumTokens; ++I) {
6333 if (clang_getTokenKind(Tokens[I]) != CXToken_Identifier)
6334 continue;
6335
6336 if (Cursors[I].kind == CXCursor_ObjCPropertyDecl) {
6337 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006338 if (const ObjCPropertyDecl *Property
Guy Benyei11169dd2012-12-18 14:30:41 +00006339 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(Cursors[I]))) {
6340 if (Property->getPropertyAttributesAsWritten() != 0 &&
6341 llvm::StringSwitch<bool>(II->getName())
6342 .Case("readonly", true)
6343 .Case("assign", true)
6344 .Case("unsafe_unretained", true)
6345 .Case("readwrite", true)
6346 .Case("retain", true)
6347 .Case("copy", true)
6348 .Case("nonatomic", true)
6349 .Case("atomic", true)
6350 .Case("getter", true)
6351 .Case("setter", true)
6352 .Case("strong", true)
6353 .Case("weak", true)
6354 .Default(false))
6355 Tokens[I].int_data[0] = CXToken_Keyword;
6356 }
6357 continue;
6358 }
6359
6360 if (Cursors[I].kind == CXCursor_ObjCInstanceMethodDecl ||
6361 Cursors[I].kind == CXCursor_ObjCClassMethodDecl) {
6362 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
6363 if (llvm::StringSwitch<bool>(II->getName())
6364 .Case("in", true)
6365 .Case("out", true)
6366 .Case("inout", true)
6367 .Case("oneway", true)
6368 .Case("bycopy", true)
6369 .Case("byref", true)
6370 .Default(false))
6371 Tokens[I].int_data[0] = CXToken_Keyword;
6372 continue;
6373 }
6374
6375 if (Cursors[I].kind == CXCursor_CXXFinalAttr ||
6376 Cursors[I].kind == CXCursor_CXXOverrideAttr) {
6377 Tokens[I].int_data[0] = CXToken_Keyword;
6378 continue;
6379 }
6380 }
6381 }
6382}
6383
6384extern "C" {
6385
6386void clang_annotateTokens(CXTranslationUnit TU,
6387 CXToken *Tokens, unsigned NumTokens,
6388 CXCursor *Cursors) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006389 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006390 LOG_BAD_TU(TU);
6391 return;
6392 }
6393 if (NumTokens == 0 || !Tokens || !Cursors) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006394 LOG_FUNC_SECTION { *Log << "<null input>"; }
Guy Benyei11169dd2012-12-18 14:30:41 +00006395 return;
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006396 }
6397
6398 LOG_FUNC_SECTION {
6399 *Log << TU << ' ';
6400 CXSourceLocation bloc = clang_getTokenLocation(TU, Tokens[0]);
6401 CXSourceLocation eloc = clang_getTokenLocation(TU, Tokens[NumTokens-1]);
6402 *Log << clang_getRange(bloc, eloc);
6403 }
Guy Benyei11169dd2012-12-18 14:30:41 +00006404
6405 // Any token we don't specifically annotate will have a NULL cursor.
6406 CXCursor C = clang_getNullCursor();
6407 for (unsigned I = 0; I != NumTokens; ++I)
6408 Cursors[I] = C;
6409
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006410 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00006411 if (!CXXUnit)
6412 return;
6413
6414 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00006415
6416 auto AnnotateTokensImpl = [=]() {
6417 clang_annotateTokensImpl(TU, CXXUnit, Tokens, NumTokens, Cursors);
6418 };
Guy Benyei11169dd2012-12-18 14:30:41 +00006419 llvm::CrashRecoveryContext CRC;
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00006420 if (!RunSafely(CRC, AnnotateTokensImpl, GetSafetyThreadStackSize() * 2)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00006421 fprintf(stderr, "libclang: crash detected while annotating tokens\n");
6422 }
6423}
6424
6425} // end: extern "C"
6426
6427//===----------------------------------------------------------------------===//
6428// Operations for querying linkage of a cursor.
6429//===----------------------------------------------------------------------===//
6430
6431extern "C" {
6432CXLinkageKind clang_getCursorLinkage(CXCursor cursor) {
6433 if (!clang_isDeclaration(cursor.kind))
6434 return CXLinkage_Invalid;
6435
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006436 const Decl *D = cxcursor::getCursorDecl(cursor);
6437 if (const NamedDecl *ND = dyn_cast_or_null<NamedDecl>(D))
Rafael Espindola3ae00052013-05-13 00:12:11 +00006438 switch (ND->getLinkageInternal()) {
Rafael Espindola50df3a02013-05-25 17:16:20 +00006439 case NoLinkage:
6440 case VisibleNoLinkage: return CXLinkage_NoLinkage;
Guy Benyei11169dd2012-12-18 14:30:41 +00006441 case InternalLinkage: return CXLinkage_Internal;
6442 case UniqueExternalLinkage: return CXLinkage_UniqueExternal;
6443 case ExternalLinkage: return CXLinkage_External;
6444 };
6445
6446 return CXLinkage_Invalid;
6447}
6448} // end: extern "C"
6449
6450//===----------------------------------------------------------------------===//
6451// Operations for querying language of a cursor.
6452//===----------------------------------------------------------------------===//
6453
6454static CXLanguageKind getDeclLanguage(const Decl *D) {
6455 if (!D)
6456 return CXLanguage_C;
6457
6458 switch (D->getKind()) {
6459 default:
6460 break;
6461 case Decl::ImplicitParam:
6462 case Decl::ObjCAtDefsField:
6463 case Decl::ObjCCategory:
6464 case Decl::ObjCCategoryImpl:
6465 case Decl::ObjCCompatibleAlias:
6466 case Decl::ObjCImplementation:
6467 case Decl::ObjCInterface:
6468 case Decl::ObjCIvar:
6469 case Decl::ObjCMethod:
6470 case Decl::ObjCProperty:
6471 case Decl::ObjCPropertyImpl:
6472 case Decl::ObjCProtocol:
Douglas Gregor85f3f952015-07-07 03:57:15 +00006473 case Decl::ObjCTypeParam:
Guy Benyei11169dd2012-12-18 14:30:41 +00006474 return CXLanguage_ObjC;
6475 case Decl::CXXConstructor:
6476 case Decl::CXXConversion:
6477 case Decl::CXXDestructor:
6478 case Decl::CXXMethod:
6479 case Decl::CXXRecord:
6480 case Decl::ClassTemplate:
6481 case Decl::ClassTemplatePartialSpecialization:
6482 case Decl::ClassTemplateSpecialization:
6483 case Decl::Friend:
6484 case Decl::FriendTemplate:
6485 case Decl::FunctionTemplate:
6486 case Decl::LinkageSpec:
6487 case Decl::Namespace:
6488 case Decl::NamespaceAlias:
6489 case Decl::NonTypeTemplateParm:
6490 case Decl::StaticAssert:
6491 case Decl::TemplateTemplateParm:
6492 case Decl::TemplateTypeParm:
6493 case Decl::UnresolvedUsingTypename:
6494 case Decl::UnresolvedUsingValue:
6495 case Decl::Using:
6496 case Decl::UsingDirective:
6497 case Decl::UsingShadow:
6498 return CXLanguage_CPlusPlus;
6499 }
6500
6501 return CXLanguage_C;
6502}
6503
6504extern "C" {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006505
6506static CXAvailabilityKind getCursorAvailabilityForDecl(const Decl *D) {
6507 if (isa<FunctionDecl>(D) && cast<FunctionDecl>(D)->isDeleted())
Manuel Klimek8e3a7ed2015-09-25 17:53:16 +00006508 return CXAvailability_NotAvailable;
Guy Benyei11169dd2012-12-18 14:30:41 +00006509
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006510 switch (D->getAvailability()) {
6511 case AR_Available:
6512 case AR_NotYetIntroduced:
6513 if (const EnumConstantDecl *EnumConst = dyn_cast<EnumConstantDecl>(D))
Benjamin Kramer656363d2013-10-15 18:53:18 +00006514 return getCursorAvailabilityForDecl(
6515 cast<Decl>(EnumConst->getDeclContext()));
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006516 return CXAvailability_Available;
6517
6518 case AR_Deprecated:
6519 return CXAvailability_Deprecated;
6520
6521 case AR_Unavailable:
6522 return CXAvailability_NotAvailable;
6523 }
Benjamin Kramer656363d2013-10-15 18:53:18 +00006524
6525 llvm_unreachable("Unknown availability kind!");
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006526}
6527
Guy Benyei11169dd2012-12-18 14:30:41 +00006528enum CXAvailabilityKind clang_getCursorAvailability(CXCursor cursor) {
6529 if (clang_isDeclaration(cursor.kind))
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006530 if (const Decl *D = cxcursor::getCursorDecl(cursor))
6531 return getCursorAvailabilityForDecl(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00006532
6533 return CXAvailability_Available;
6534}
6535
6536static CXVersion convertVersion(VersionTuple In) {
6537 CXVersion Out = { -1, -1, -1 };
6538 if (In.empty())
6539 return Out;
6540
6541 Out.Major = In.getMajor();
6542
NAKAMURA Takumic2b5d1f2013-02-21 02:32:34 +00006543 Optional<unsigned> Minor = In.getMinor();
6544 if (Minor.hasValue())
Guy Benyei11169dd2012-12-18 14:30:41 +00006545 Out.Minor = *Minor;
6546 else
6547 return Out;
6548
NAKAMURA Takumic2b5d1f2013-02-21 02:32:34 +00006549 Optional<unsigned> Subminor = In.getSubminor();
6550 if (Subminor.hasValue())
Guy Benyei11169dd2012-12-18 14:30:41 +00006551 Out.Subminor = *Subminor;
6552
6553 return Out;
6554}
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006555
6556static int getCursorPlatformAvailabilityForDecl(const Decl *D,
6557 int *always_deprecated,
6558 CXString *deprecated_message,
6559 int *always_unavailable,
6560 CXString *unavailable_message,
6561 CXPlatformAvailability *availability,
6562 int availability_size) {
6563 bool HadAvailAttr = false;
6564 int N = 0;
Aaron Ballmanb97112e2014-03-08 22:19:01 +00006565 for (auto A : D->attrs()) {
6566 if (DeprecatedAttr *Deprecated = dyn_cast<DeprecatedAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006567 HadAvailAttr = true;
6568 if (always_deprecated)
6569 *always_deprecated = 1;
Nico Weberaacf0312014-04-24 05:16:45 +00006570 if (deprecated_message) {
Argyrios Kyrtzidisedfe07f2014-04-24 06:05:40 +00006571 clang_disposeString(*deprecated_message);
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006572 *deprecated_message = cxstring::createDup(Deprecated->getMessage());
Nico Weberaacf0312014-04-24 05:16:45 +00006573 }
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006574 continue;
6575 }
6576
Aaron Ballmanb97112e2014-03-08 22:19:01 +00006577 if (UnavailableAttr *Unavailable = dyn_cast<UnavailableAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006578 HadAvailAttr = true;
6579 if (always_unavailable)
6580 *always_unavailable = 1;
6581 if (unavailable_message) {
Argyrios Kyrtzidisedfe07f2014-04-24 06:05:40 +00006582 clang_disposeString(*unavailable_message);
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006583 *unavailable_message = cxstring::createDup(Unavailable->getMessage());
6584 }
6585 continue;
6586 }
6587
Aaron Ballmanb97112e2014-03-08 22:19:01 +00006588 if (AvailabilityAttr *Avail = dyn_cast<AvailabilityAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006589 HadAvailAttr = true;
6590 if (N < availability_size) {
6591 availability[N].Platform
6592 = cxstring::createDup(Avail->getPlatform()->getName());
6593 availability[N].Introduced = convertVersion(Avail->getIntroduced());
6594 availability[N].Deprecated = convertVersion(Avail->getDeprecated());
6595 availability[N].Obsoleted = convertVersion(Avail->getObsoleted());
6596 availability[N].Unavailable = Avail->getUnavailable();
6597 availability[N].Message = cxstring::createDup(Avail->getMessage());
6598 }
6599 ++N;
6600 }
6601 }
6602
6603 if (!HadAvailAttr)
6604 if (const EnumConstantDecl *EnumConst = dyn_cast<EnumConstantDecl>(D))
6605 return getCursorPlatformAvailabilityForDecl(
6606 cast<Decl>(EnumConst->getDeclContext()),
6607 always_deprecated,
6608 deprecated_message,
6609 always_unavailable,
6610 unavailable_message,
6611 availability,
6612 availability_size);
Guy Benyei11169dd2012-12-18 14:30:41 +00006613
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006614 return N;
6615}
6616
Guy Benyei11169dd2012-12-18 14:30:41 +00006617int clang_getCursorPlatformAvailability(CXCursor cursor,
6618 int *always_deprecated,
6619 CXString *deprecated_message,
6620 int *always_unavailable,
6621 CXString *unavailable_message,
6622 CXPlatformAvailability *availability,
6623 int availability_size) {
6624 if (always_deprecated)
6625 *always_deprecated = 0;
6626 if (deprecated_message)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006627 *deprecated_message = cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006628 if (always_unavailable)
6629 *always_unavailable = 0;
6630 if (unavailable_message)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006631 *unavailable_message = cxstring::createEmpty();
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006632
Guy Benyei11169dd2012-12-18 14:30:41 +00006633 if (!clang_isDeclaration(cursor.kind))
6634 return 0;
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006635
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006636 const Decl *D = cxcursor::getCursorDecl(cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00006637 if (!D)
6638 return 0;
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006639
6640 return getCursorPlatformAvailabilityForDecl(D, always_deprecated,
6641 deprecated_message,
6642 always_unavailable,
6643 unavailable_message,
6644 availability,
6645 availability_size);
Guy Benyei11169dd2012-12-18 14:30:41 +00006646}
6647
6648void clang_disposeCXPlatformAvailability(CXPlatformAvailability *availability) {
6649 clang_disposeString(availability->Platform);
6650 clang_disposeString(availability->Message);
6651}
6652
6653CXLanguageKind clang_getCursorLanguage(CXCursor cursor) {
6654 if (clang_isDeclaration(cursor.kind))
6655 return getDeclLanguage(cxcursor::getCursorDecl(cursor));
6656
6657 return CXLanguage_Invalid;
6658}
6659
6660 /// \brief If the given cursor is the "templated" declaration
6661 /// descibing a class or function template, return the class or
6662 /// function template.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006663static const Decl *maybeGetTemplateCursor(const Decl *D) {
Guy Benyei11169dd2012-12-18 14:30:41 +00006664 if (!D)
Craig Topper69186e72014-06-08 08:38:04 +00006665 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006666
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006667 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00006668 if (FunctionTemplateDecl *FunTmpl = FD->getDescribedFunctionTemplate())
6669 return FunTmpl;
6670
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006671 if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00006672 if (ClassTemplateDecl *ClassTmpl = RD->getDescribedClassTemplate())
6673 return ClassTmpl;
6674
6675 return D;
6676}
6677
Argyrios Kyrtzidis4e0854f2014-10-15 17:05:31 +00006678
6679enum CX_StorageClass clang_Cursor_getStorageClass(CXCursor C) {
6680 StorageClass sc = SC_None;
6681 const Decl *D = getCursorDecl(C);
6682 if (D) {
6683 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
6684 sc = FD->getStorageClass();
6685 } else if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
6686 sc = VD->getStorageClass();
6687 } else {
6688 return CX_SC_Invalid;
6689 }
6690 } else {
6691 return CX_SC_Invalid;
6692 }
6693 switch (sc) {
6694 case SC_None:
6695 return CX_SC_None;
6696 case SC_Extern:
6697 return CX_SC_Extern;
6698 case SC_Static:
6699 return CX_SC_Static;
6700 case SC_PrivateExtern:
6701 return CX_SC_PrivateExtern;
Argyrios Kyrtzidis4e0854f2014-10-15 17:05:31 +00006702 case SC_Auto:
6703 return CX_SC_Auto;
6704 case SC_Register:
6705 return CX_SC_Register;
Argyrios Kyrtzidis4e0854f2014-10-15 17:05:31 +00006706 }
Kaelyn Takataab61e702014-10-15 18:03:26 +00006707 llvm_unreachable("Unhandled storage class!");
Argyrios Kyrtzidis4e0854f2014-10-15 17:05:31 +00006708}
6709
Guy Benyei11169dd2012-12-18 14:30:41 +00006710CXCursor clang_getCursorSemanticParent(CXCursor cursor) {
6711 if (clang_isDeclaration(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006712 if (const Decl *D = getCursorDecl(cursor)) {
6713 const DeclContext *DC = D->getDeclContext();
Guy Benyei11169dd2012-12-18 14:30:41 +00006714 if (!DC)
6715 return clang_getNullCursor();
6716
6717 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
6718 getCursorTU(cursor));
6719 }
6720 }
6721
6722 if (clang_isStatement(cursor.kind) || clang_isExpression(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006723 if (const Decl *D = getCursorDecl(cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +00006724 return MakeCXCursor(D, getCursorTU(cursor));
6725 }
6726
6727 return clang_getNullCursor();
6728}
6729
6730CXCursor clang_getCursorLexicalParent(CXCursor cursor) {
6731 if (clang_isDeclaration(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006732 if (const Decl *D = getCursorDecl(cursor)) {
6733 const DeclContext *DC = D->getLexicalDeclContext();
Guy Benyei11169dd2012-12-18 14:30:41 +00006734 if (!DC)
6735 return clang_getNullCursor();
6736
6737 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
6738 getCursorTU(cursor));
6739 }
6740 }
6741
6742 // FIXME: Note that we can't easily compute the lexical context of a
6743 // statement or expression, so we return nothing.
6744 return clang_getNullCursor();
6745}
6746
6747CXFile clang_getIncludedFile(CXCursor cursor) {
6748 if (cursor.kind != CXCursor_InclusionDirective)
Craig Topper69186e72014-06-08 08:38:04 +00006749 return nullptr;
6750
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00006751 const InclusionDirective *ID = getCursorInclusionDirective(cursor);
Dmitri Gribenkof9304482013-01-23 15:56:07 +00006752 return const_cast<FileEntry *>(ID->getFile());
Guy Benyei11169dd2012-12-18 14:30:41 +00006753}
6754
Argyrios Kyrtzidis9adfd8a2013-04-18 22:15:49 +00006755unsigned clang_Cursor_getObjCPropertyAttributes(CXCursor C, unsigned reserved) {
6756 if (C.kind != CXCursor_ObjCPropertyDecl)
6757 return CXObjCPropertyAttr_noattr;
6758
6759 unsigned Result = CXObjCPropertyAttr_noattr;
6760 const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(getCursorDecl(C));
6761 ObjCPropertyDecl::PropertyAttributeKind Attr =
6762 PD->getPropertyAttributesAsWritten();
6763
6764#define SET_CXOBJCPROP_ATTR(A) \
6765 if (Attr & ObjCPropertyDecl::OBJC_PR_##A) \
6766 Result |= CXObjCPropertyAttr_##A
6767 SET_CXOBJCPROP_ATTR(readonly);
6768 SET_CXOBJCPROP_ATTR(getter);
6769 SET_CXOBJCPROP_ATTR(assign);
6770 SET_CXOBJCPROP_ATTR(readwrite);
6771 SET_CXOBJCPROP_ATTR(retain);
6772 SET_CXOBJCPROP_ATTR(copy);
6773 SET_CXOBJCPROP_ATTR(nonatomic);
6774 SET_CXOBJCPROP_ATTR(setter);
6775 SET_CXOBJCPROP_ATTR(atomic);
6776 SET_CXOBJCPROP_ATTR(weak);
6777 SET_CXOBJCPROP_ATTR(strong);
6778 SET_CXOBJCPROP_ATTR(unsafe_unretained);
6779#undef SET_CXOBJCPROP_ATTR
6780
6781 return Result;
6782}
6783
Argyrios Kyrtzidis9d9bc012013-04-18 23:29:12 +00006784unsigned clang_Cursor_getObjCDeclQualifiers(CXCursor C) {
6785 if (!clang_isDeclaration(C.kind))
6786 return CXObjCDeclQualifier_None;
6787
6788 Decl::ObjCDeclQualifier QT = Decl::OBJC_TQ_None;
6789 const Decl *D = getCursorDecl(C);
6790 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6791 QT = MD->getObjCDeclQualifier();
6792 else if (const ParmVarDecl *PD = dyn_cast<ParmVarDecl>(D))
6793 QT = PD->getObjCDeclQualifier();
6794 if (QT == Decl::OBJC_TQ_None)
6795 return CXObjCDeclQualifier_None;
6796
6797 unsigned Result = CXObjCDeclQualifier_None;
6798 if (QT & Decl::OBJC_TQ_In) Result |= CXObjCDeclQualifier_In;
6799 if (QT & Decl::OBJC_TQ_Inout) Result |= CXObjCDeclQualifier_Inout;
6800 if (QT & Decl::OBJC_TQ_Out) Result |= CXObjCDeclQualifier_Out;
6801 if (QT & Decl::OBJC_TQ_Bycopy) Result |= CXObjCDeclQualifier_Bycopy;
6802 if (QT & Decl::OBJC_TQ_Byref) Result |= CXObjCDeclQualifier_Byref;
6803 if (QT & Decl::OBJC_TQ_Oneway) Result |= CXObjCDeclQualifier_Oneway;
6804
6805 return Result;
6806}
6807
Argyrios Kyrtzidis7b50fc52013-07-05 20:44:37 +00006808unsigned clang_Cursor_isObjCOptional(CXCursor C) {
6809 if (!clang_isDeclaration(C.kind))
6810 return 0;
6811
6812 const Decl *D = getCursorDecl(C);
6813 if (const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(D))
6814 return PD->getPropertyImplementation() == ObjCPropertyDecl::Optional;
6815 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6816 return MD->getImplementationControl() == ObjCMethodDecl::Optional;
6817
6818 return 0;
6819}
6820
Argyrios Kyrtzidis23814e42013-04-18 23:53:05 +00006821unsigned clang_Cursor_isVariadic(CXCursor C) {
6822 if (!clang_isDeclaration(C.kind))
6823 return 0;
6824
6825 const Decl *D = getCursorDecl(C);
6826 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
6827 return FD->isVariadic();
6828 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6829 return MD->isVariadic();
6830
6831 return 0;
6832}
6833
Guy Benyei11169dd2012-12-18 14:30:41 +00006834CXSourceRange clang_Cursor_getCommentRange(CXCursor C) {
6835 if (!clang_isDeclaration(C.kind))
6836 return clang_getNullRange();
6837
6838 const Decl *D = getCursorDecl(C);
6839 ASTContext &Context = getCursorContext(C);
6840 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6841 if (!RC)
6842 return clang_getNullRange();
6843
6844 return cxloc::translateSourceRange(Context, RC->getSourceRange());
6845}
6846
6847CXString clang_Cursor_getRawCommentText(CXCursor C) {
6848 if (!clang_isDeclaration(C.kind))
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006849 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006850
6851 const Decl *D = getCursorDecl(C);
6852 ASTContext &Context = getCursorContext(C);
6853 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6854 StringRef RawText = RC ? RC->getRawText(Context.getSourceManager()) :
6855 StringRef();
6856
6857 // Don't duplicate the string because RawText points directly into source
6858 // code.
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006859 return cxstring::createRef(RawText);
Guy Benyei11169dd2012-12-18 14:30:41 +00006860}
6861
6862CXString clang_Cursor_getBriefCommentText(CXCursor C) {
6863 if (!clang_isDeclaration(C.kind))
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006864 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006865
6866 const Decl *D = getCursorDecl(C);
6867 const ASTContext &Context = getCursorContext(C);
6868 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6869
6870 if (RC) {
6871 StringRef BriefText = RC->getBriefText(Context);
6872
6873 // Don't duplicate the string because RawComment ensures that this memory
6874 // will not go away.
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006875 return cxstring::createRef(BriefText);
Guy Benyei11169dd2012-12-18 14:30:41 +00006876 }
6877
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006878 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006879}
6880
Guy Benyei11169dd2012-12-18 14:30:41 +00006881CXModule clang_Cursor_getModule(CXCursor C) {
6882 if (C.kind == CXCursor_ModuleImportDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006883 if (const ImportDecl *ImportD =
6884 dyn_cast_or_null<ImportDecl>(getCursorDecl(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00006885 return ImportD->getImportedModule();
6886 }
6887
Craig Topper69186e72014-06-08 08:38:04 +00006888 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006889}
6890
Argyrios Kyrtzidisf6d49c32014-05-14 23:14:37 +00006891CXModule clang_getModuleForFile(CXTranslationUnit TU, CXFile File) {
6892 if (isNotUsableTU(TU)) {
6893 LOG_BAD_TU(TU);
6894 return nullptr;
6895 }
6896 if (!File)
6897 return nullptr;
6898 FileEntry *FE = static_cast<FileEntry *>(File);
6899
6900 ASTUnit &Unit = *cxtu::getASTUnit(TU);
6901 HeaderSearch &HS = Unit.getPreprocessor().getHeaderSearchInfo();
6902 ModuleMap::KnownHeader Header = HS.findModuleForHeader(FE);
6903
Richard Smithfeb54b62014-10-23 02:01:19 +00006904 return Header.getModule();
Argyrios Kyrtzidisf6d49c32014-05-14 23:14:37 +00006905}
6906
Argyrios Kyrtzidis12fdb9e2013-04-26 22:47:49 +00006907CXFile clang_Module_getASTFile(CXModule CXMod) {
6908 if (!CXMod)
Craig Topper69186e72014-06-08 08:38:04 +00006909 return nullptr;
Argyrios Kyrtzidis12fdb9e2013-04-26 22:47:49 +00006910 Module *Mod = static_cast<Module*>(CXMod);
6911 return const_cast<FileEntry *>(Mod->getASTFile());
6912}
6913
Guy Benyei11169dd2012-12-18 14:30:41 +00006914CXModule clang_Module_getParent(CXModule CXMod) {
6915 if (!CXMod)
Craig Topper69186e72014-06-08 08:38:04 +00006916 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006917 Module *Mod = static_cast<Module*>(CXMod);
6918 return Mod->Parent;
6919}
6920
6921CXString clang_Module_getName(CXModule CXMod) {
6922 if (!CXMod)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006923 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006924 Module *Mod = static_cast<Module*>(CXMod);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006925 return cxstring::createDup(Mod->Name);
Guy Benyei11169dd2012-12-18 14:30:41 +00006926}
6927
6928CXString clang_Module_getFullName(CXModule CXMod) {
6929 if (!CXMod)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006930 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006931 Module *Mod = static_cast<Module*>(CXMod);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006932 return cxstring::createDup(Mod->getFullModuleName());
Guy Benyei11169dd2012-12-18 14:30:41 +00006933}
6934
Argyrios Kyrtzidis884337f2014-05-15 04:44:25 +00006935int clang_Module_isSystem(CXModule CXMod) {
6936 if (!CXMod)
6937 return 0;
6938 Module *Mod = static_cast<Module*>(CXMod);
6939 return Mod->IsSystem;
6940}
6941
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006942unsigned clang_Module_getNumTopLevelHeaders(CXTranslationUnit TU,
6943 CXModule CXMod) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006944 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006945 LOG_BAD_TU(TU);
6946 return 0;
6947 }
6948 if (!CXMod)
Guy Benyei11169dd2012-12-18 14:30:41 +00006949 return 0;
6950 Module *Mod = static_cast<Module*>(CXMod);
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006951 FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
6952 ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
6953 return TopHeaders.size();
Guy Benyei11169dd2012-12-18 14:30:41 +00006954}
6955
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006956CXFile clang_Module_getTopLevelHeader(CXTranslationUnit TU,
6957 CXModule CXMod, unsigned Index) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006958 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006959 LOG_BAD_TU(TU);
Craig Topper69186e72014-06-08 08:38:04 +00006960 return nullptr;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006961 }
6962 if (!CXMod)
Craig Topper69186e72014-06-08 08:38:04 +00006963 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006964 Module *Mod = static_cast<Module*>(CXMod);
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006965 FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
Guy Benyei11169dd2012-12-18 14:30:41 +00006966
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006967 ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
6968 if (Index < TopHeaders.size())
6969 return const_cast<FileEntry *>(TopHeaders[Index]);
Guy Benyei11169dd2012-12-18 14:30:41 +00006970
Craig Topper69186e72014-06-08 08:38:04 +00006971 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006972}
6973
6974} // end: extern "C"
6975
6976//===----------------------------------------------------------------------===//
6977// C++ AST instrospection.
6978//===----------------------------------------------------------------------===//
6979
6980extern "C" {
Saleem Abdulrasool6ea75db2015-10-27 15:50:22 +00006981unsigned clang_CXXField_isMutable(CXCursor C) {
6982 if (!clang_isDeclaration(C.kind))
6983 return 0;
6984
6985 if (const auto D = cxcursor::getCursorDecl(C))
6986 if (const auto FD = dyn_cast_or_null<FieldDecl>(D))
6987 return FD->isMutable() ? 1 : 0;
6988 return 0;
6989}
6990
Dmitri Gribenko62770be2013-05-17 18:38:35 +00006991unsigned clang_CXXMethod_isPureVirtual(CXCursor C) {
6992 if (!clang_isDeclaration(C.kind))
6993 return 0;
6994
Dmitri Gribenko62770be2013-05-17 18:38:35 +00006995 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00006996 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00006997 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Dmitri Gribenko62770be2013-05-17 18:38:35 +00006998 return (Method && Method->isVirtual() && Method->isPure()) ? 1 : 0;
6999}
7000
Dmitri Gribenkoe570ede2014-04-07 14:59:13 +00007001unsigned clang_CXXMethod_isConst(CXCursor C) {
7002 if (!clang_isDeclaration(C.kind))
7003 return 0;
7004
7005 const Decl *D = cxcursor::getCursorDecl(C);
7006 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00007007 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Dmitri Gribenkoe570ede2014-04-07 14:59:13 +00007008 return (Method && (Method->getTypeQualifiers() & Qualifiers::Const)) ? 1 : 0;
7009}
7010
Guy Benyei11169dd2012-12-18 14:30:41 +00007011unsigned clang_CXXMethod_isStatic(CXCursor C) {
7012 if (!clang_isDeclaration(C.kind))
7013 return 0;
7014
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00007015 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00007016 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00007017 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00007018 return (Method && Method->isStatic()) ? 1 : 0;
7019}
7020
7021unsigned clang_CXXMethod_isVirtual(CXCursor C) {
7022 if (!clang_isDeclaration(C.kind))
7023 return 0;
7024
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00007025 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00007026 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00007027 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00007028 return (Method && Method->isVirtual()) ? 1 : 0;
7029}
7030} // end: extern "C"
7031
7032//===----------------------------------------------------------------------===//
7033// Attribute introspection.
7034//===----------------------------------------------------------------------===//
7035
7036extern "C" {
7037CXType clang_getIBOutletCollectionType(CXCursor C) {
7038 if (C.kind != CXCursor_IBOutletCollectionAttr)
7039 return cxtype::MakeCXType(QualType(), cxcursor::getCursorTU(C));
7040
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00007041 const IBOutletCollectionAttr *A =
Guy Benyei11169dd2012-12-18 14:30:41 +00007042 cast<IBOutletCollectionAttr>(cxcursor::getCursorAttr(C));
7043
7044 return cxtype::MakeCXType(A->getInterface(), cxcursor::getCursorTU(C));
7045}
7046} // end: extern "C"
7047
7048//===----------------------------------------------------------------------===//
7049// Inspecting memory usage.
7050//===----------------------------------------------------------------------===//
7051
7052typedef std::vector<CXTUResourceUsageEntry> MemUsageEntries;
7053
7054static inline void createCXTUResourceUsageEntry(MemUsageEntries &entries,
7055 enum CXTUResourceUsageKind k,
7056 unsigned long amount) {
7057 CXTUResourceUsageEntry entry = { k, amount };
7058 entries.push_back(entry);
7059}
7060
7061extern "C" {
7062
7063const char *clang_getTUResourceUsageName(CXTUResourceUsageKind kind) {
7064 const char *str = "";
7065 switch (kind) {
7066 case CXTUResourceUsage_AST:
7067 str = "ASTContext: expressions, declarations, and types";
7068 break;
7069 case CXTUResourceUsage_Identifiers:
7070 str = "ASTContext: identifiers";
7071 break;
7072 case CXTUResourceUsage_Selectors:
7073 str = "ASTContext: selectors";
7074 break;
7075 case CXTUResourceUsage_GlobalCompletionResults:
7076 str = "Code completion: cached global results";
7077 break;
7078 case CXTUResourceUsage_SourceManagerContentCache:
7079 str = "SourceManager: content cache allocator";
7080 break;
7081 case CXTUResourceUsage_AST_SideTables:
7082 str = "ASTContext: side tables";
7083 break;
7084 case CXTUResourceUsage_SourceManager_Membuffer_Malloc:
7085 str = "SourceManager: malloc'ed memory buffers";
7086 break;
7087 case CXTUResourceUsage_SourceManager_Membuffer_MMap:
7088 str = "SourceManager: mmap'ed memory buffers";
7089 break;
7090 case CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc:
7091 str = "ExternalASTSource: malloc'ed memory buffers";
7092 break;
7093 case CXTUResourceUsage_ExternalASTSource_Membuffer_MMap:
7094 str = "ExternalASTSource: mmap'ed memory buffers";
7095 break;
7096 case CXTUResourceUsage_Preprocessor:
7097 str = "Preprocessor: malloc'ed memory";
7098 break;
7099 case CXTUResourceUsage_PreprocessingRecord:
7100 str = "Preprocessor: PreprocessingRecord";
7101 break;
7102 case CXTUResourceUsage_SourceManager_DataStructures:
7103 str = "SourceManager: data structures and tables";
7104 break;
7105 case CXTUResourceUsage_Preprocessor_HeaderSearch:
7106 str = "Preprocessor: header search tables";
7107 break;
7108 }
7109 return str;
7110}
7111
7112CXTUResourceUsage clang_getCXTUResourceUsage(CXTranslationUnit TU) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00007113 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00007114 LOG_BAD_TU(TU);
Craig Topper69186e72014-06-08 08:38:04 +00007115 CXTUResourceUsage usage = { (void*) nullptr, 0, nullptr };
Guy Benyei11169dd2012-12-18 14:30:41 +00007116 return usage;
7117 }
7118
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007119 ASTUnit *astUnit = cxtu::getASTUnit(TU);
Ahmed Charlesb8984322014-03-07 20:03:18 +00007120 std::unique_ptr<MemUsageEntries> entries(new MemUsageEntries());
Guy Benyei11169dd2012-12-18 14:30:41 +00007121 ASTContext &astContext = astUnit->getASTContext();
7122
7123 // How much memory is used by AST nodes and types?
7124 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST,
7125 (unsigned long) astContext.getASTAllocatedMemory());
7126
7127 // How much memory is used by identifiers?
7128 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Identifiers,
7129 (unsigned long) astContext.Idents.getAllocator().getTotalMemory());
7130
7131 // How much memory is used for selectors?
7132 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Selectors,
7133 (unsigned long) astContext.Selectors.getTotalMemory());
7134
7135 // How much memory is used by ASTContext's side tables?
7136 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST_SideTables,
7137 (unsigned long) astContext.getSideTableAllocatedMemory());
7138
7139 // How much memory is used for caching global code completion results?
7140 unsigned long completionBytes = 0;
7141 if (GlobalCodeCompletionAllocator *completionAllocator =
Alp Tokerf994cef2014-07-05 03:08:06 +00007142 astUnit->getCachedCompletionAllocator().get()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00007143 completionBytes = completionAllocator->getTotalMemory();
7144 }
7145 createCXTUResourceUsageEntry(*entries,
7146 CXTUResourceUsage_GlobalCompletionResults,
7147 completionBytes);
7148
7149 // How much memory is being used by SourceManager's content cache?
7150 createCXTUResourceUsageEntry(*entries,
7151 CXTUResourceUsage_SourceManagerContentCache,
7152 (unsigned long) astContext.getSourceManager().getContentCacheSize());
7153
7154 // How much memory is being used by the MemoryBuffer's in SourceManager?
7155 const SourceManager::MemoryBufferSizes &srcBufs =
7156 astUnit->getSourceManager().getMemoryBufferSizes();
7157
7158 createCXTUResourceUsageEntry(*entries,
7159 CXTUResourceUsage_SourceManager_Membuffer_Malloc,
7160 (unsigned long) srcBufs.malloc_bytes);
7161 createCXTUResourceUsageEntry(*entries,
7162 CXTUResourceUsage_SourceManager_Membuffer_MMap,
7163 (unsigned long) srcBufs.mmap_bytes);
7164 createCXTUResourceUsageEntry(*entries,
7165 CXTUResourceUsage_SourceManager_DataStructures,
7166 (unsigned long) astContext.getSourceManager()
7167 .getDataStructureSizes());
7168
7169 // How much memory is being used by the ExternalASTSource?
7170 if (ExternalASTSource *esrc = astContext.getExternalSource()) {
7171 const ExternalASTSource::MemoryBufferSizes &sizes =
7172 esrc->getMemoryBufferSizes();
7173
7174 createCXTUResourceUsageEntry(*entries,
7175 CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc,
7176 (unsigned long) sizes.malloc_bytes);
7177 createCXTUResourceUsageEntry(*entries,
7178 CXTUResourceUsage_ExternalASTSource_Membuffer_MMap,
7179 (unsigned long) sizes.mmap_bytes);
7180 }
7181
7182 // How much memory is being used by the Preprocessor?
7183 Preprocessor &pp = astUnit->getPreprocessor();
7184 createCXTUResourceUsageEntry(*entries,
7185 CXTUResourceUsage_Preprocessor,
7186 pp.getTotalMemory());
7187
7188 if (PreprocessingRecord *pRec = pp.getPreprocessingRecord()) {
7189 createCXTUResourceUsageEntry(*entries,
7190 CXTUResourceUsage_PreprocessingRecord,
7191 pRec->getTotalMemory());
7192 }
7193
7194 createCXTUResourceUsageEntry(*entries,
7195 CXTUResourceUsage_Preprocessor_HeaderSearch,
7196 pp.getHeaderSearchInfo().getTotalMemory());
Craig Topper69186e72014-06-08 08:38:04 +00007197
Guy Benyei11169dd2012-12-18 14:30:41 +00007198 CXTUResourceUsage usage = { (void*) entries.get(),
7199 (unsigned) entries->size(),
Alexander Kornienko6ee521c2015-01-23 15:36:10 +00007200 !entries->empty() ? &(*entries)[0] : nullptr };
Ahmed Charles9a16beb2014-03-07 19:33:25 +00007201 entries.release();
Guy Benyei11169dd2012-12-18 14:30:41 +00007202 return usage;
7203}
7204
7205void clang_disposeCXTUResourceUsage(CXTUResourceUsage usage) {
7206 if (usage.data)
7207 delete (MemUsageEntries*) usage.data;
7208}
7209
Argyrios Kyrtzidis0e282ef2013-12-06 18:55:45 +00007210CXSourceRangeList *clang_getSkippedRanges(CXTranslationUnit TU, CXFile file) {
7211 CXSourceRangeList *skipped = new CXSourceRangeList;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00007212 skipped->count = 0;
Craig Topper69186e72014-06-08 08:38:04 +00007213 skipped->ranges = nullptr;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00007214
Dmitri Gribenko852d6222014-02-11 15:02:48 +00007215 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00007216 LOG_BAD_TU(TU);
7217 return skipped;
7218 }
7219
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00007220 if (!file)
7221 return skipped;
7222
7223 ASTUnit *astUnit = cxtu::getASTUnit(TU);
7224 PreprocessingRecord *ppRec = astUnit->getPreprocessor().getPreprocessingRecord();
7225 if (!ppRec)
7226 return skipped;
7227
7228 ASTContext &Ctx = astUnit->getASTContext();
7229 SourceManager &sm = Ctx.getSourceManager();
7230 FileEntry *fileEntry = static_cast<FileEntry *>(file);
7231 FileID wantedFileID = sm.translateFile(fileEntry);
7232
7233 const std::vector<SourceRange> &SkippedRanges = ppRec->getSkippedRanges();
7234 std::vector<SourceRange> wantedRanges;
7235 for (std::vector<SourceRange>::const_iterator i = SkippedRanges.begin(), ei = SkippedRanges.end();
7236 i != ei; ++i) {
7237 if (sm.getFileID(i->getBegin()) == wantedFileID || sm.getFileID(i->getEnd()) == wantedFileID)
7238 wantedRanges.push_back(*i);
7239 }
7240
7241 skipped->count = wantedRanges.size();
7242 skipped->ranges = new CXSourceRange[skipped->count];
7243 for (unsigned i = 0, ei = skipped->count; i != ei; ++i)
7244 skipped->ranges[i] = cxloc::translateSourceRange(Ctx, wantedRanges[i]);
7245
7246 return skipped;
7247}
7248
Argyrios Kyrtzidis0e282ef2013-12-06 18:55:45 +00007249void clang_disposeSourceRangeList(CXSourceRangeList *ranges) {
7250 if (ranges) {
7251 delete[] ranges->ranges;
7252 delete ranges;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00007253 }
7254}
7255
Guy Benyei11169dd2012-12-18 14:30:41 +00007256} // end extern "C"
7257
7258void clang::PrintLibclangResourceUsage(CXTranslationUnit TU) {
7259 CXTUResourceUsage Usage = clang_getCXTUResourceUsage(TU);
7260 for (unsigned I = 0; I != Usage.numEntries; ++I)
7261 fprintf(stderr, " %s: %lu\n",
7262 clang_getTUResourceUsageName(Usage.entries[I].kind),
7263 Usage.entries[I].amount);
7264
7265 clang_disposeCXTUResourceUsage(Usage);
7266}
7267
7268//===----------------------------------------------------------------------===//
7269// Misc. utility functions.
7270//===----------------------------------------------------------------------===//
7271
7272/// Default to using an 8 MB stack size on "safety" threads.
7273static unsigned SafetyStackThreadSize = 8 << 20;
7274
7275namespace clang {
7276
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00007277bool RunSafely(llvm::CrashRecoveryContext &CRC, llvm::function_ref<void()> Fn,
Guy Benyei11169dd2012-12-18 14:30:41 +00007278 unsigned Size) {
7279 if (!Size)
7280 Size = GetSafetyThreadStackSize();
7281 if (Size)
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00007282 return CRC.RunSafelyOnThread(Fn, Size);
7283 return CRC.RunSafely(Fn);
Guy Benyei11169dd2012-12-18 14:30:41 +00007284}
7285
7286unsigned GetSafetyThreadStackSize() {
7287 return SafetyStackThreadSize;
7288}
7289
7290void SetSafetyThreadStackSize(unsigned Value) {
7291 SafetyStackThreadSize = Value;
7292}
7293
Alexander Kornienkoab9db512015-06-22 23:07:51 +00007294}
Guy Benyei11169dd2012-12-18 14:30:41 +00007295
7296void clang::setThreadBackgroundPriority() {
7297 if (getenv("LIBCLANG_BGPRIO_DISABLE"))
7298 return;
7299
Alp Toker1a86ad22014-07-06 06:24:00 +00007300#ifdef USE_DARWIN_THREADS
Guy Benyei11169dd2012-12-18 14:30:41 +00007301 setpriority(PRIO_DARWIN_THREAD, 0, PRIO_DARWIN_BG);
7302#endif
7303}
7304
7305void cxindex::printDiagsToStderr(ASTUnit *Unit) {
7306 if (!Unit)
7307 return;
7308
7309 for (ASTUnit::stored_diag_iterator D = Unit->stored_diag_begin(),
7310 DEnd = Unit->stored_diag_end();
7311 D != DEnd; ++D) {
Ben Langmuir749323f2014-04-22 17:40:12 +00007312 CXStoredDiagnostic Diag(*D, Unit->getLangOpts());
Guy Benyei11169dd2012-12-18 14:30:41 +00007313 CXString Msg = clang_formatDiagnostic(&Diag,
7314 clang_defaultDiagnosticDisplayOptions());
7315 fprintf(stderr, "%s\n", clang_getCString(Msg));
7316 clang_disposeString(Msg);
7317 }
7318#ifdef LLVM_ON_WIN32
7319 // On Windows, force a flush, since there may be multiple copies of
7320 // stderr and stdout in the file system, all with different buffers
7321 // but writing to the same device.
7322 fflush(stderr);
7323#endif
7324}
7325
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007326MacroInfo *cxindex::getMacroInfo(const IdentifierInfo &II,
7327 SourceLocation MacroDefLoc,
7328 CXTranslationUnit TU){
7329 if (MacroDefLoc.isInvalid() || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00007330 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007331 if (!II.hadMacroDefinition())
Craig Topper69186e72014-06-08 08:38:04 +00007332 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007333
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007334 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00007335 Preprocessor &PP = Unit->getPreprocessor();
Richard Smith20e883e2015-04-29 23:20:19 +00007336 MacroDirective *MD = PP.getLocalMacroDirectiveHistory(&II);
Argyrios Kyrtzidisb6210df2013-03-26 17:17:01 +00007337 if (MD) {
7338 for (MacroDirective::DefInfo
7339 Def = MD->getDefinition(); Def; Def = Def.getPreviousDefinition()) {
7340 if (MacroDefLoc == Def.getMacroInfo()->getDefinitionLoc())
7341 return Def.getMacroInfo();
7342 }
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007343 }
7344
Craig Topper69186e72014-06-08 08:38:04 +00007345 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007346}
7347
Richard Smith66a81862015-05-04 02:25:31 +00007348const MacroInfo *cxindex::getMacroInfo(const MacroDefinitionRecord *MacroDef,
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00007349 CXTranslationUnit TU) {
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007350 if (!MacroDef || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00007351 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007352 const IdentifierInfo *II = MacroDef->getName();
7353 if (!II)
Craig Topper69186e72014-06-08 08:38:04 +00007354 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007355
7356 return getMacroInfo(*II, MacroDef->getLocation(), TU);
7357}
7358
Richard Smith66a81862015-05-04 02:25:31 +00007359MacroDefinitionRecord *
7360cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI, const Token &Tok,
7361 CXTranslationUnit TU) {
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007362 if (!MI || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00007363 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007364 if (Tok.isNot(tok::raw_identifier))
Craig Topper69186e72014-06-08 08:38:04 +00007365 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007366
7367 if (MI->getNumTokens() == 0)
Craig Topper69186e72014-06-08 08:38:04 +00007368 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007369 SourceRange DefRange(MI->getReplacementToken(0).getLocation(),
7370 MI->getDefinitionEndLoc());
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007371 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007372
7373 // Check that the token is inside the definition and not its argument list.
7374 SourceManager &SM = Unit->getSourceManager();
7375 if (SM.isBeforeInTranslationUnit(Tok.getLocation(), DefRange.getBegin()))
Craig Topper69186e72014-06-08 08:38:04 +00007376 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007377 if (SM.isBeforeInTranslationUnit(DefRange.getEnd(), Tok.getLocation()))
Craig Topper69186e72014-06-08 08:38:04 +00007378 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007379
7380 Preprocessor &PP = Unit->getPreprocessor();
7381 PreprocessingRecord *PPRec = PP.getPreprocessingRecord();
7382 if (!PPRec)
Craig Topper69186e72014-06-08 08:38:04 +00007383 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007384
Alp Toker2d57cea2014-05-17 04:53:25 +00007385 IdentifierInfo &II = PP.getIdentifierTable().get(Tok.getRawIdentifier());
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007386 if (!II.hadMacroDefinition())
Craig Topper69186e72014-06-08 08:38:04 +00007387 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007388
7389 // Check that the identifier is not one of the macro arguments.
7390 if (std::find(MI->arg_begin(), MI->arg_end(), &II) != MI->arg_end())
Craig Topper69186e72014-06-08 08:38:04 +00007391 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007392
Richard Smith20e883e2015-04-29 23:20:19 +00007393 MacroDirective *InnerMD = PP.getLocalMacroDirectiveHistory(&II);
Argyrios Kyrtzidis09c9e812013-02-20 00:54:57 +00007394 if (!InnerMD)
Craig Topper69186e72014-06-08 08:38:04 +00007395 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007396
Argyrios Kyrtzidisb6210df2013-03-26 17:17:01 +00007397 return PPRec->findMacroDefinition(InnerMD->getMacroInfo());
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007398}
7399
Richard Smith66a81862015-05-04 02:25:31 +00007400MacroDefinitionRecord *
7401cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI, SourceLocation Loc,
7402 CXTranslationUnit TU) {
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007403 if (Loc.isInvalid() || !MI || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00007404 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007405
7406 if (MI->getNumTokens() == 0)
Craig Topper69186e72014-06-08 08:38:04 +00007407 return nullptr;
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007408 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007409 Preprocessor &PP = Unit->getPreprocessor();
7410 if (!PP.getPreprocessingRecord())
Craig Topper69186e72014-06-08 08:38:04 +00007411 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007412 Loc = Unit->getSourceManager().getSpellingLoc(Loc);
7413 Token Tok;
7414 if (PP.getRawToken(Loc, Tok))
Craig Topper69186e72014-06-08 08:38:04 +00007415 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007416
7417 return checkForMacroInMacroDefinition(MI, Tok, TU);
7418}
7419
Guy Benyei11169dd2012-12-18 14:30:41 +00007420extern "C" {
7421
7422CXString clang_getClangVersion() {
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00007423 return cxstring::createDup(getClangFullVersion());
Guy Benyei11169dd2012-12-18 14:30:41 +00007424}
7425
7426} // end: extern "C"
7427
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007428Logger &cxindex::Logger::operator<<(CXTranslationUnit TU) {
7429 if (TU) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007430 if (ASTUnit *Unit = cxtu::getASTUnit(TU)) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007431 LogOS << '<' << Unit->getMainFileName() << '>';
Argyrios Kyrtzidis37f2ab42013-03-05 20:21:14 +00007432 if (Unit->isMainFileAST())
7433 LogOS << " (" << Unit->getASTFileName() << ')';
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007434 return *this;
7435 }
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00007436 } else {
7437 LogOS << "<NULL TU>";
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007438 }
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007439 return *this;
7440}
7441
Argyrios Kyrtzidisba4b5f82013-03-08 02:32:26 +00007442Logger &cxindex::Logger::operator<<(const FileEntry *FE) {
7443 *this << FE->getName();
7444 return *this;
7445}
7446
7447Logger &cxindex::Logger::operator<<(CXCursor cursor) {
7448 CXString cursorName = clang_getCursorDisplayName(cursor);
7449 *this << cursorName << "@" << clang_getCursorLocation(cursor);
7450 clang_disposeString(cursorName);
7451 return *this;
7452}
7453
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007454Logger &cxindex::Logger::operator<<(CXSourceLocation Loc) {
7455 CXFile File;
7456 unsigned Line, Column;
Craig Topper69186e72014-06-08 08:38:04 +00007457 clang_getFileLocation(Loc, &File, &Line, &Column, nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007458 CXString FileName = clang_getFileName(File);
7459 *this << llvm::format("(%s:%d:%d)", clang_getCString(FileName), Line, Column);
7460 clang_disposeString(FileName);
7461 return *this;
7462}
7463
7464Logger &cxindex::Logger::operator<<(CXSourceRange range) {
7465 CXSourceLocation BLoc = clang_getRangeStart(range);
7466 CXSourceLocation ELoc = clang_getRangeEnd(range);
7467
7468 CXFile BFile;
7469 unsigned BLine, BColumn;
Craig Topper69186e72014-06-08 08:38:04 +00007470 clang_getFileLocation(BLoc, &BFile, &BLine, &BColumn, nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007471
7472 CXFile EFile;
7473 unsigned ELine, EColumn;
Craig Topper69186e72014-06-08 08:38:04 +00007474 clang_getFileLocation(ELoc, &EFile, &ELine, &EColumn, nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007475
7476 CXString BFileName = clang_getFileName(BFile);
7477 if (BFile == EFile) {
7478 *this << llvm::format("[%s %d:%d-%d:%d]", clang_getCString(BFileName),
7479 BLine, BColumn, ELine, EColumn);
7480 } else {
7481 CXString EFileName = clang_getFileName(EFile);
7482 *this << llvm::format("[%s:%d:%d - ", clang_getCString(BFileName),
7483 BLine, BColumn)
7484 << llvm::format("%s:%d:%d]", clang_getCString(EFileName),
7485 ELine, EColumn);
7486 clang_disposeString(EFileName);
7487 }
7488 clang_disposeString(BFileName);
7489 return *this;
7490}
7491
7492Logger &cxindex::Logger::operator<<(CXString Str) {
7493 *this << clang_getCString(Str);
7494 return *this;
7495}
7496
7497Logger &cxindex::Logger::operator<<(const llvm::format_object_base &Fmt) {
7498 LogOS << Fmt;
7499 return *this;
7500}
7501
Chandler Carruth37ad2582014-06-27 15:14:39 +00007502static llvm::ManagedStatic<llvm::sys::Mutex> LoggingMutex;
7503
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007504cxindex::Logger::~Logger() {
Chandler Carruth37ad2582014-06-27 15:14:39 +00007505 llvm::sys::ScopedLock L(*LoggingMutex);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007506
7507 static llvm::TimeRecord sBeginTR = llvm::TimeRecord::getCurrentTime();
7508
Dmitri Gribenkof8579502013-01-12 19:30:44 +00007509 raw_ostream &OS = llvm::errs();
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007510 OS << "[libclang:" << Name << ':';
7511
Alp Toker1a86ad22014-07-06 06:24:00 +00007512#ifdef USE_DARWIN_THREADS
7513 // TODO: Portability.
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007514 mach_port_t tid = pthread_mach_thread_np(pthread_self());
7515 OS << tid << ':';
7516#endif
7517
7518 llvm::TimeRecord TR = llvm::TimeRecord::getCurrentTime();
7519 OS << llvm::format("%7.4f] ", TR.getWallTime() - sBeginTR.getWallTime());
Yaron Keren09fb7c62015-03-10 07:33:23 +00007520 OS << Msg << '\n';
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007521
7522 if (Trace) {
Zachary Turner1fe2a8d2015-03-05 19:15:09 +00007523 llvm::sys::PrintStackTrace(OS);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007524 OS << "--------------------------------------------------\n";
7525 }
7526}