blob: 589e39e797da2ed6dc59dcc20dbee2150faa270b [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}
Kelvin Li0bff7af2015-11-23 05:32:03 +00002181void OMPClauseEnqueue::VisitOMPMapClause(const OMPMapClause *C) {
2182 VisitOMPClauseList(C);
2183}
Alexander Kornienkoab9db512015-06-22 23:07:51 +00002184}
Alexey Bataev756c1962013-09-24 03:17:45 +00002185
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002186void EnqueueVisitor::EnqueueChildren(const OMPClause *S) {
2187 unsigned size = WL.size();
2188 OMPClauseEnqueue Visitor(this);
2189 Visitor.Visit(S);
2190 if (size == WL.size())
2191 return;
2192 // Now reverse the entries we just added. This will match the DFS
2193 // ordering performed by the worklist.
2194 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
2195 std::reverse(I, E);
2196}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002197void EnqueueVisitor::VisitAddrLabelExpr(const AddrLabelExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002198 WL.push_back(LabelRefVisit(E->getLabel(), E->getLabelLoc(), Parent));
2199}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002200void EnqueueVisitor::VisitBlockExpr(const BlockExpr *B) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002201 AddDecl(B->getBlockDecl());
2202}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002203void EnqueueVisitor::VisitCompoundLiteralExpr(const CompoundLiteralExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002204 EnqueueChildren(E);
2205 AddTypeLoc(E->getTypeSourceInfo());
2206}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002207void EnqueueVisitor::VisitCompoundStmt(const CompoundStmt *S) {
Pete Cooper57d3f142015-07-30 17:22:52 +00002208 for (auto &I : llvm::reverse(S->body()))
2209 AddStmt(I);
Guy Benyei11169dd2012-12-18 14:30:41 +00002210}
2211void EnqueueVisitor::
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002212VisitMSDependentExistsStmt(const MSDependentExistsStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002213 AddStmt(S->getSubStmt());
2214 AddDeclarationNameInfo(S);
2215 if (NestedNameSpecifierLoc QualifierLoc = S->getQualifierLoc())
2216 AddNestedNameSpecifierLoc(QualifierLoc);
2217}
2218
2219void EnqueueVisitor::
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002220VisitCXXDependentScopeMemberExpr(const CXXDependentScopeMemberExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002221 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
2222 AddDeclarationNameInfo(E);
2223 if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
2224 AddNestedNameSpecifierLoc(QualifierLoc);
2225 if (!E->isImplicitAccess())
2226 AddStmt(E->getBase());
2227}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002228void EnqueueVisitor::VisitCXXNewExpr(const CXXNewExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002229 // Enqueue the initializer , if any.
2230 AddStmt(E->getInitializer());
2231 // Enqueue the array size, if any.
2232 AddStmt(E->getArraySize());
2233 // Enqueue the allocated type.
2234 AddTypeLoc(E->getAllocatedTypeSourceInfo());
2235 // Enqueue the placement arguments.
2236 for (unsigned I = E->getNumPlacementArgs(); I > 0; --I)
2237 AddStmt(E->getPlacementArg(I-1));
2238}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002239void EnqueueVisitor::VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *CE) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002240 for (unsigned I = CE->getNumArgs(); I > 1 /* Yes, this is 1 */; --I)
2241 AddStmt(CE->getArg(I-1));
2242 AddStmt(CE->getCallee());
2243 AddStmt(CE->getArg(0));
2244}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002245void EnqueueVisitor::VisitCXXPseudoDestructorExpr(
2246 const CXXPseudoDestructorExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002247 // Visit the name of the type being destroyed.
2248 AddTypeLoc(E->getDestroyedTypeInfo());
2249 // Visit the scope type that looks disturbingly like the nested-name-specifier
2250 // but isn't.
2251 AddTypeLoc(E->getScopeTypeInfo());
2252 // Visit the nested-name-specifier.
2253 if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
2254 AddNestedNameSpecifierLoc(QualifierLoc);
2255 // Visit base expression.
2256 AddStmt(E->getBase());
2257}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002258void EnqueueVisitor::VisitCXXScalarValueInitExpr(
2259 const CXXScalarValueInitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002260 AddTypeLoc(E->getTypeSourceInfo());
2261}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002262void EnqueueVisitor::VisitCXXTemporaryObjectExpr(
2263 const CXXTemporaryObjectExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002264 EnqueueChildren(E);
2265 AddTypeLoc(E->getTypeSourceInfo());
2266}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002267void EnqueueVisitor::VisitCXXTypeidExpr(const CXXTypeidExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002268 EnqueueChildren(E);
2269 if (E->isTypeOperand())
2270 AddTypeLoc(E->getTypeOperandSourceInfo());
2271}
2272
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002273void EnqueueVisitor::VisitCXXUnresolvedConstructExpr(
2274 const CXXUnresolvedConstructExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002275 EnqueueChildren(E);
2276 AddTypeLoc(E->getTypeSourceInfo());
2277}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002278void EnqueueVisitor::VisitCXXUuidofExpr(const CXXUuidofExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002279 EnqueueChildren(E);
2280 if (E->isTypeOperand())
2281 AddTypeLoc(E->getTypeOperandSourceInfo());
2282}
2283
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002284void EnqueueVisitor::VisitCXXCatchStmt(const CXXCatchStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002285 EnqueueChildren(S);
2286 AddDecl(S->getExceptionDecl());
2287}
2288
Argyrios Kyrtzidis99891242014-11-13 09:03:21 +00002289void EnqueueVisitor::VisitCXXForRangeStmt(const CXXForRangeStmt *S) {
Argyrios Kyrtzidiscde70692014-11-13 09:50:19 +00002290 AddStmt(S->getBody());
Argyrios Kyrtzidis99891242014-11-13 09:03:21 +00002291 AddStmt(S->getRangeInit());
Argyrios Kyrtzidiscde70692014-11-13 09:50:19 +00002292 AddDecl(S->getLoopVariable());
Argyrios Kyrtzidis99891242014-11-13 09:03:21 +00002293}
2294
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002295void EnqueueVisitor::VisitDeclRefExpr(const DeclRefExpr *DR) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002296 if (DR->hasExplicitTemplateArgs()) {
2297 AddExplicitTemplateArgs(&DR->getExplicitTemplateArgs());
2298 }
2299 WL.push_back(DeclRefExprParts(DR, Parent));
2300}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002301void EnqueueVisitor::VisitDependentScopeDeclRefExpr(
2302 const DependentScopeDeclRefExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002303 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
2304 AddDeclarationNameInfo(E);
2305 AddNestedNameSpecifierLoc(E->getQualifierLoc());
2306}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002307void EnqueueVisitor::VisitDeclStmt(const DeclStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002308 unsigned size = WL.size();
2309 bool isFirst = true;
Aaron Ballman535bbcc2014-03-14 17:01:24 +00002310 for (const auto *D : S->decls()) {
2311 AddDecl(D, isFirst);
Guy Benyei11169dd2012-12-18 14:30:41 +00002312 isFirst = false;
2313 }
2314 if (size == WL.size())
2315 return;
2316 // Now reverse the entries we just added. This will match the DFS
2317 // ordering performed by the worklist.
2318 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
2319 std::reverse(I, E);
2320}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002321void EnqueueVisitor::VisitDesignatedInitExpr(const DesignatedInitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002322 AddStmt(E->getInit());
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002323 for (DesignatedInitExpr::const_reverse_designators_iterator
Guy Benyei11169dd2012-12-18 14:30:41 +00002324 D = E->designators_rbegin(), DEnd = E->designators_rend();
2325 D != DEnd; ++D) {
2326 if (D->isFieldDesignator()) {
2327 if (FieldDecl *Field = D->getField())
2328 AddMemberRef(Field, D->getFieldLoc());
2329 continue;
2330 }
2331 if (D->isArrayDesignator()) {
2332 AddStmt(E->getArrayIndex(*D));
2333 continue;
2334 }
2335 assert(D->isArrayRangeDesignator() && "Unknown designator kind");
2336 AddStmt(E->getArrayRangeEnd(*D));
2337 AddStmt(E->getArrayRangeStart(*D));
2338 }
2339}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002340void EnqueueVisitor::VisitExplicitCastExpr(const ExplicitCastExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002341 EnqueueChildren(E);
2342 AddTypeLoc(E->getTypeInfoAsWritten());
2343}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002344void EnqueueVisitor::VisitForStmt(const ForStmt *FS) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002345 AddStmt(FS->getBody());
2346 AddStmt(FS->getInc());
2347 AddStmt(FS->getCond());
2348 AddDecl(FS->getConditionVariable());
2349 AddStmt(FS->getInit());
2350}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002351void EnqueueVisitor::VisitGotoStmt(const GotoStmt *GS) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002352 WL.push_back(LabelRefVisit(GS->getLabel(), GS->getLabelLoc(), Parent));
2353}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002354void EnqueueVisitor::VisitIfStmt(const IfStmt *If) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002355 AddStmt(If->getElse());
2356 AddStmt(If->getThen());
2357 AddStmt(If->getCond());
2358 AddDecl(If->getConditionVariable());
2359}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002360void EnqueueVisitor::VisitInitListExpr(const InitListExpr *IE) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002361 // We care about the syntactic form of the initializer list, only.
2362 if (InitListExpr *Syntactic = IE->getSyntacticForm())
2363 IE = Syntactic;
2364 EnqueueChildren(IE);
2365}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002366void EnqueueVisitor::VisitMemberExpr(const MemberExpr *M) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002367 WL.push_back(MemberExprParts(M, Parent));
2368
2369 // If the base of the member access expression is an implicit 'this', don't
2370 // visit it.
2371 // FIXME: If we ever want to show these implicit accesses, this will be
2372 // unfortunate. However, clang_getCursor() relies on this behavior.
Argyrios Kyrtzidis58d0e7a2015-03-13 04:40:07 +00002373 if (M->isImplicitAccess())
2374 return;
2375
2376 // Ignore base anonymous struct/union fields, otherwise they will shadow the
2377 // real field that that we are interested in.
2378 if (auto *SubME = dyn_cast<MemberExpr>(M->getBase())) {
2379 if (auto *FD = dyn_cast_or_null<FieldDecl>(SubME->getMemberDecl())) {
2380 if (FD->isAnonymousStructOrUnion()) {
2381 AddStmt(SubME->getBase());
2382 return;
2383 }
2384 }
2385 }
2386
2387 AddStmt(M->getBase());
Guy Benyei11169dd2012-12-18 14:30:41 +00002388}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002389void EnqueueVisitor::VisitObjCEncodeExpr(const ObjCEncodeExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002390 AddTypeLoc(E->getEncodedTypeSourceInfo());
2391}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002392void EnqueueVisitor::VisitObjCMessageExpr(const ObjCMessageExpr *M) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002393 EnqueueChildren(M);
2394 AddTypeLoc(M->getClassReceiverTypeInfo());
2395}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002396void EnqueueVisitor::VisitOffsetOfExpr(const OffsetOfExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002397 // Visit the components of the offsetof expression.
2398 for (unsigned N = E->getNumComponents(), I = N; I > 0; --I) {
2399 typedef OffsetOfExpr::OffsetOfNode OffsetOfNode;
2400 const OffsetOfNode &Node = E->getComponent(I-1);
2401 switch (Node.getKind()) {
2402 case OffsetOfNode::Array:
2403 AddStmt(E->getIndexExpr(Node.getArrayExprIndex()));
2404 break;
2405 case OffsetOfNode::Field:
2406 AddMemberRef(Node.getField(), Node.getSourceRange().getEnd());
2407 break;
2408 case OffsetOfNode::Identifier:
2409 case OffsetOfNode::Base:
2410 continue;
2411 }
2412 }
2413 // Visit the type into which we're computing the offset.
2414 AddTypeLoc(E->getTypeSourceInfo());
2415}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002416void EnqueueVisitor::VisitOverloadExpr(const OverloadExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002417 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
2418 WL.push_back(OverloadExprParts(E, Parent));
2419}
2420void EnqueueVisitor::VisitUnaryExprOrTypeTraitExpr(
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002421 const UnaryExprOrTypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002422 EnqueueChildren(E);
2423 if (E->isArgumentType())
2424 AddTypeLoc(E->getArgumentTypeInfo());
2425}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002426void EnqueueVisitor::VisitStmt(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002427 EnqueueChildren(S);
2428}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002429void EnqueueVisitor::VisitSwitchStmt(const SwitchStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002430 AddStmt(S->getBody());
2431 AddStmt(S->getCond());
2432 AddDecl(S->getConditionVariable());
2433}
2434
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002435void EnqueueVisitor::VisitWhileStmt(const WhileStmt *W) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002436 AddStmt(W->getBody());
2437 AddStmt(W->getCond());
2438 AddDecl(W->getConditionVariable());
2439}
2440
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002441void EnqueueVisitor::VisitTypeTraitExpr(const TypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002442 for (unsigned I = E->getNumArgs(); I > 0; --I)
2443 AddTypeLoc(E->getArg(I-1));
2444}
2445
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002446void EnqueueVisitor::VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002447 AddTypeLoc(E->getQueriedTypeSourceInfo());
2448}
2449
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002450void EnqueueVisitor::VisitExpressionTraitExpr(const ExpressionTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002451 EnqueueChildren(E);
2452}
2453
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002454void EnqueueVisitor::VisitUnresolvedMemberExpr(const UnresolvedMemberExpr *U) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002455 VisitOverloadExpr(U);
2456 if (!U->isImplicitAccess())
2457 AddStmt(U->getBase());
2458}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002459void EnqueueVisitor::VisitVAArgExpr(const VAArgExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002460 AddStmt(E->getSubExpr());
2461 AddTypeLoc(E->getWrittenTypeInfo());
2462}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002463void EnqueueVisitor::VisitSizeOfPackExpr(const SizeOfPackExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002464 WL.push_back(SizeOfPackExprParts(E, Parent));
2465}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002466void EnqueueVisitor::VisitOpaqueValueExpr(const OpaqueValueExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002467 // If the opaque value has a source expression, just transparently
2468 // visit that. This is useful for (e.g.) pseudo-object expressions.
2469 if (Expr *SourceExpr = E->getSourceExpr())
2470 return Visit(SourceExpr);
2471}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002472void EnqueueVisitor::VisitLambdaExpr(const LambdaExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002473 AddStmt(E->getBody());
2474 WL.push_back(LambdaExprParts(E, Parent));
2475}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002476void EnqueueVisitor::VisitPseudoObjectExpr(const PseudoObjectExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002477 // Treat the expression like its syntactic form.
2478 Visit(E->getSyntacticForm());
2479}
2480
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002481void EnqueueVisitor::VisitOMPExecutableDirective(
2482 const OMPExecutableDirective *D) {
2483 EnqueueChildren(D);
2484 for (ArrayRef<OMPClause *>::iterator I = D->clauses().begin(),
2485 E = D->clauses().end();
2486 I != E; ++I)
2487 EnqueueChildren(*I);
2488}
2489
Alexander Musman3aaab662014-08-19 11:27:13 +00002490void EnqueueVisitor::VisitOMPLoopDirective(const OMPLoopDirective *D) {
2491 VisitOMPExecutableDirective(D);
2492}
2493
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002494void EnqueueVisitor::VisitOMPParallelDirective(const OMPParallelDirective *D) {
2495 VisitOMPExecutableDirective(D);
2496}
2497
Alexey Bataev1b59ab52014-02-27 08:29:12 +00002498void EnqueueVisitor::VisitOMPSimdDirective(const OMPSimdDirective *D) {
Alexander Musman3aaab662014-08-19 11:27:13 +00002499 VisitOMPLoopDirective(D);
Alexey Bataev1b59ab52014-02-27 08:29:12 +00002500}
2501
Alexey Bataevf29276e2014-06-18 04:14:57 +00002502void EnqueueVisitor::VisitOMPForDirective(const OMPForDirective *D) {
Alexander Musman3aaab662014-08-19 11:27:13 +00002503 VisitOMPLoopDirective(D);
Alexey Bataevf29276e2014-06-18 04:14:57 +00002504}
2505
Alexander Musmanf82886e2014-09-18 05:12:34 +00002506void EnqueueVisitor::VisitOMPForSimdDirective(const OMPForSimdDirective *D) {
2507 VisitOMPLoopDirective(D);
2508}
2509
Alexey Bataevd3f8dd22014-06-25 11:44:49 +00002510void EnqueueVisitor::VisitOMPSectionsDirective(const OMPSectionsDirective *D) {
2511 VisitOMPExecutableDirective(D);
2512}
2513
Alexey Bataev1e0498a2014-06-26 08:21:58 +00002514void EnqueueVisitor::VisitOMPSectionDirective(const OMPSectionDirective *D) {
2515 VisitOMPExecutableDirective(D);
2516}
2517
Alexey Bataevd1e40fb2014-06-26 12:05:45 +00002518void EnqueueVisitor::VisitOMPSingleDirective(const OMPSingleDirective *D) {
2519 VisitOMPExecutableDirective(D);
2520}
2521
Alexander Musman80c22892014-07-17 08:54:58 +00002522void EnqueueVisitor::VisitOMPMasterDirective(const OMPMasterDirective *D) {
2523 VisitOMPExecutableDirective(D);
2524}
2525
Alexander Musmand9ed09f2014-07-21 09:42:05 +00002526void EnqueueVisitor::VisitOMPCriticalDirective(const OMPCriticalDirective *D) {
2527 VisitOMPExecutableDirective(D);
2528 AddDeclarationNameInfo(D);
2529}
2530
Alexey Bataev4acb8592014-07-07 13:01:15 +00002531void
2532EnqueueVisitor::VisitOMPParallelForDirective(const OMPParallelForDirective *D) {
Alexander Musman3aaab662014-08-19 11:27:13 +00002533 VisitOMPLoopDirective(D);
Alexey Bataev4acb8592014-07-07 13:01:15 +00002534}
2535
Alexander Musmane4e893b2014-09-23 09:33:00 +00002536void EnqueueVisitor::VisitOMPParallelForSimdDirective(
2537 const OMPParallelForSimdDirective *D) {
2538 VisitOMPLoopDirective(D);
2539}
2540
Alexey Bataev84d0b3e2014-07-08 08:12:03 +00002541void EnqueueVisitor::VisitOMPParallelSectionsDirective(
2542 const OMPParallelSectionsDirective *D) {
2543 VisitOMPExecutableDirective(D);
2544}
2545
Alexey Bataev9c2e8ee2014-07-11 11:25:16 +00002546void EnqueueVisitor::VisitOMPTaskDirective(const OMPTaskDirective *D) {
2547 VisitOMPExecutableDirective(D);
2548}
2549
Alexey Bataev68446b72014-07-18 07:47:19 +00002550void
2551EnqueueVisitor::VisitOMPTaskyieldDirective(const OMPTaskyieldDirective *D) {
2552 VisitOMPExecutableDirective(D);
2553}
2554
Alexey Bataev4d1dfea2014-07-18 09:11:51 +00002555void EnqueueVisitor::VisitOMPBarrierDirective(const OMPBarrierDirective *D) {
2556 VisitOMPExecutableDirective(D);
2557}
2558
Alexey Bataev2df347a2014-07-18 10:17:07 +00002559void EnqueueVisitor::VisitOMPTaskwaitDirective(const OMPTaskwaitDirective *D) {
2560 VisitOMPExecutableDirective(D);
2561}
2562
Alexey Bataevc30dd2d2015-06-18 12:14:09 +00002563void EnqueueVisitor::VisitOMPTaskgroupDirective(
2564 const OMPTaskgroupDirective *D) {
2565 VisitOMPExecutableDirective(D);
2566}
2567
Alexey Bataev6125da92014-07-21 11:26:11 +00002568void EnqueueVisitor::VisitOMPFlushDirective(const OMPFlushDirective *D) {
2569 VisitOMPExecutableDirective(D);
2570}
2571
Alexey Bataev9fb6e642014-07-22 06:45:04 +00002572void EnqueueVisitor::VisitOMPOrderedDirective(const OMPOrderedDirective *D) {
2573 VisitOMPExecutableDirective(D);
2574}
2575
Alexey Bataev0162e452014-07-22 10:10:35 +00002576void EnqueueVisitor::VisitOMPAtomicDirective(const OMPAtomicDirective *D) {
2577 VisitOMPExecutableDirective(D);
2578}
2579
Alexey Bataev0bd520b2014-09-19 08:19:49 +00002580void EnqueueVisitor::VisitOMPTargetDirective(const OMPTargetDirective *D) {
2581 VisitOMPExecutableDirective(D);
2582}
2583
Michael Wong65f367f2015-07-21 13:44:28 +00002584void EnqueueVisitor::VisitOMPTargetDataDirective(const
2585 OMPTargetDataDirective *D) {
2586 VisitOMPExecutableDirective(D);
2587}
2588
Alexey Bataev13314bf2014-10-09 04:18:56 +00002589void EnqueueVisitor::VisitOMPTeamsDirective(const OMPTeamsDirective *D) {
2590 VisitOMPExecutableDirective(D);
2591}
2592
Alexey Bataev6d4ed052015-07-01 06:57:41 +00002593void EnqueueVisitor::VisitOMPCancellationPointDirective(
2594 const OMPCancellationPointDirective *D) {
2595 VisitOMPExecutableDirective(D);
2596}
2597
Alexey Bataev80909872015-07-02 11:25:17 +00002598void EnqueueVisitor::VisitOMPCancelDirective(const OMPCancelDirective *D) {
2599 VisitOMPExecutableDirective(D);
2600}
2601
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002602void CursorVisitor::EnqueueWorkList(VisitorWorkList &WL, const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002603 EnqueueVisitor(WL, MakeCXCursor(S, StmtParent, TU,RegionOfInterest)).Visit(S);
2604}
2605
2606bool CursorVisitor::IsInRegionOfInterest(CXCursor C) {
2607 if (RegionOfInterest.isValid()) {
2608 SourceRange Range = getRawCursorExtent(C);
2609 if (Range.isInvalid() || CompareRegionOfInterest(Range))
2610 return false;
2611 }
2612 return true;
2613}
2614
2615bool CursorVisitor::RunVisitorWorkList(VisitorWorkList &WL) {
2616 while (!WL.empty()) {
2617 // Dequeue the worklist item.
Robert Wilhelm25284cc2013-08-23 16:11:15 +00002618 VisitorJob LI = WL.pop_back_val();
Guy Benyei11169dd2012-12-18 14:30:41 +00002619
2620 // Set the Parent field, then back to its old value once we're done.
2621 SetParentRAII SetParent(Parent, StmtParent, LI.getParent());
2622
2623 switch (LI.getKind()) {
2624 case VisitorJob::DeclVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002625 const Decl *D = cast<DeclVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002626 if (!D)
2627 continue;
2628
2629 // For now, perform default visitation for Decls.
2630 if (Visit(MakeCXCursor(D, TU, RegionOfInterest,
2631 cast<DeclVisit>(&LI)->isFirst())))
2632 return true;
2633
2634 continue;
2635 }
2636 case VisitorJob::ExplicitTemplateArgsVisitKind: {
2637 const ASTTemplateArgumentListInfo *ArgList =
2638 cast<ExplicitTemplateArgsVisit>(&LI)->get();
2639 for (const TemplateArgumentLoc *Arg = ArgList->getTemplateArgs(),
2640 *ArgEnd = Arg + ArgList->NumTemplateArgs;
2641 Arg != ArgEnd; ++Arg) {
2642 if (VisitTemplateArgumentLoc(*Arg))
2643 return true;
2644 }
2645 continue;
2646 }
2647 case VisitorJob::TypeLocVisitKind: {
2648 // Perform default visitation for TypeLocs.
2649 if (Visit(cast<TypeLocVisit>(&LI)->get()))
2650 return true;
2651 continue;
2652 }
2653 case VisitorJob::LabelRefVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002654 const LabelDecl *LS = cast<LabelRefVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002655 if (LabelStmt *stmt = LS->getStmt()) {
2656 if (Visit(MakeCursorLabelRef(stmt, cast<LabelRefVisit>(&LI)->getLoc(),
2657 TU))) {
2658 return true;
2659 }
2660 }
2661 continue;
2662 }
2663
2664 case VisitorJob::NestedNameSpecifierLocVisitKind: {
2665 NestedNameSpecifierLocVisit *V = cast<NestedNameSpecifierLocVisit>(&LI);
2666 if (VisitNestedNameSpecifierLoc(V->get()))
2667 return true;
2668 continue;
2669 }
2670
2671 case VisitorJob::DeclarationNameInfoVisitKind: {
2672 if (VisitDeclarationNameInfo(cast<DeclarationNameInfoVisit>(&LI)
2673 ->get()))
2674 return true;
2675 continue;
2676 }
2677 case VisitorJob::MemberRefVisitKind: {
2678 MemberRefVisit *V = cast<MemberRefVisit>(&LI);
2679 if (Visit(MakeCursorMemberRef(V->get(), V->getLoc(), TU)))
2680 return true;
2681 continue;
2682 }
2683 case VisitorJob::StmtVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002684 const Stmt *S = cast<StmtVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002685 if (!S)
2686 continue;
2687
2688 // Update the current cursor.
2689 CXCursor Cursor = MakeCXCursor(S, StmtParent, TU, RegionOfInterest);
2690 if (!IsInRegionOfInterest(Cursor))
2691 continue;
2692 switch (Visitor(Cursor, Parent, ClientData)) {
2693 case CXChildVisit_Break: return true;
2694 case CXChildVisit_Continue: break;
2695 case CXChildVisit_Recurse:
2696 if (PostChildrenVisitor)
Craig Topper69186e72014-06-08 08:38:04 +00002697 WL.push_back(PostChildrenVisit(nullptr, Cursor));
Guy Benyei11169dd2012-12-18 14:30:41 +00002698 EnqueueWorkList(WL, S);
2699 break;
2700 }
2701 continue;
2702 }
2703 case VisitorJob::MemberExprPartsKind: {
2704 // Handle the other pieces in the MemberExpr besides the base.
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002705 const MemberExpr *M = cast<MemberExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002706
2707 // Visit the nested-name-specifier
2708 if (NestedNameSpecifierLoc QualifierLoc = M->getQualifierLoc())
2709 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2710 return true;
2711
2712 // Visit the declaration name.
2713 if (VisitDeclarationNameInfo(M->getMemberNameInfo()))
2714 return true;
2715
2716 // Visit the explicitly-specified template arguments, if any.
2717 if (M->hasExplicitTemplateArgs()) {
2718 for (const TemplateArgumentLoc *Arg = M->getTemplateArgs(),
2719 *ArgEnd = Arg + M->getNumTemplateArgs();
2720 Arg != ArgEnd; ++Arg) {
2721 if (VisitTemplateArgumentLoc(*Arg))
2722 return true;
2723 }
2724 }
2725 continue;
2726 }
2727 case VisitorJob::DeclRefExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002728 const DeclRefExpr *DR = cast<DeclRefExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002729 // Visit nested-name-specifier, if present.
2730 if (NestedNameSpecifierLoc QualifierLoc = DR->getQualifierLoc())
2731 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2732 return true;
2733 // Visit declaration name.
2734 if (VisitDeclarationNameInfo(DR->getNameInfo()))
2735 return true;
2736 continue;
2737 }
2738 case VisitorJob::OverloadExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002739 const OverloadExpr *O = cast<OverloadExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002740 // Visit the nested-name-specifier.
2741 if (NestedNameSpecifierLoc QualifierLoc = O->getQualifierLoc())
2742 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2743 return true;
2744 // Visit the declaration name.
2745 if (VisitDeclarationNameInfo(O->getNameInfo()))
2746 return true;
2747 // Visit the overloaded declaration reference.
2748 if (Visit(MakeCursorOverloadedDeclRef(O, TU)))
2749 return true;
2750 continue;
2751 }
2752 case VisitorJob::SizeOfPackExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002753 const SizeOfPackExpr *E = cast<SizeOfPackExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002754 NamedDecl *Pack = E->getPack();
2755 if (isa<TemplateTypeParmDecl>(Pack)) {
2756 if (Visit(MakeCursorTypeRef(cast<TemplateTypeParmDecl>(Pack),
2757 E->getPackLoc(), TU)))
2758 return true;
2759
2760 continue;
2761 }
2762
2763 if (isa<TemplateTemplateParmDecl>(Pack)) {
2764 if (Visit(MakeCursorTemplateRef(cast<TemplateTemplateParmDecl>(Pack),
2765 E->getPackLoc(), TU)))
2766 return true;
2767
2768 continue;
2769 }
2770
2771 // Non-type template parameter packs and function parameter packs are
2772 // treated like DeclRefExpr cursors.
2773 continue;
2774 }
2775
2776 case VisitorJob::LambdaExprPartsKind: {
2777 // Visit captures.
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002778 const LambdaExpr *E = cast<LambdaExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002779 for (LambdaExpr::capture_iterator C = E->explicit_capture_begin(),
2780 CEnd = E->explicit_capture_end();
2781 C != CEnd; ++C) {
Richard Smithba71c082013-05-16 06:20:58 +00002782 // FIXME: Lambda init-captures.
2783 if (!C->capturesVariable())
Guy Benyei11169dd2012-12-18 14:30:41 +00002784 continue;
Richard Smithba71c082013-05-16 06:20:58 +00002785
Guy Benyei11169dd2012-12-18 14:30:41 +00002786 if (Visit(MakeCursorVariableRef(C->getCapturedVar(),
2787 C->getLocation(),
2788 TU)))
2789 return true;
2790 }
2791
2792 // Visit parameters and return type, if present.
2793 if (E->hasExplicitParameters() || E->hasExplicitResultType()) {
2794 TypeLoc TL = E->getCallOperator()->getTypeSourceInfo()->getTypeLoc();
2795 if (E->hasExplicitParameters() && E->hasExplicitResultType()) {
2796 // Visit the whole type.
2797 if (Visit(TL))
2798 return true;
David Blaikie6adc78e2013-02-18 22:06:02 +00002799 } else if (FunctionProtoTypeLoc Proto =
2800 TL.getAs<FunctionProtoTypeLoc>()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002801 if (E->hasExplicitParameters()) {
2802 // Visit parameters.
Alp Tokerb3fd5cf2014-01-21 00:32:38 +00002803 for (unsigned I = 0, N = Proto.getNumParams(); I != N; ++I)
2804 if (Visit(MakeCXCursor(Proto.getParam(I), TU)))
Guy Benyei11169dd2012-12-18 14:30:41 +00002805 return true;
2806 } else {
2807 // Visit result type.
Alp Toker42a16a62014-01-25 23:51:36 +00002808 if (Visit(Proto.getReturnLoc()))
Guy Benyei11169dd2012-12-18 14:30:41 +00002809 return true;
2810 }
2811 }
2812 }
2813 break;
2814 }
2815
2816 case VisitorJob::PostChildrenVisitKind:
2817 if (PostChildrenVisitor(Parent, ClientData))
2818 return true;
2819 break;
2820 }
2821 }
2822 return false;
2823}
2824
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002825bool CursorVisitor::Visit(const Stmt *S) {
Craig Topper69186e72014-06-08 08:38:04 +00002826 VisitorWorkList *WL = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00002827 if (!WorkListFreeList.empty()) {
2828 WL = WorkListFreeList.back();
2829 WL->clear();
2830 WorkListFreeList.pop_back();
2831 }
2832 else {
2833 WL = new VisitorWorkList();
2834 WorkListCache.push_back(WL);
2835 }
2836 EnqueueWorkList(*WL, S);
2837 bool result = RunVisitorWorkList(*WL);
2838 WorkListFreeList.push_back(WL);
2839 return result;
2840}
2841
2842namespace {
Dmitri Gribenkof8579502013-01-12 19:30:44 +00002843typedef SmallVector<SourceRange, 4> RefNamePieces;
Craig Topper69186e72014-06-08 08:38:04 +00002844RefNamePieces
2845buildPieces(unsigned NameFlags, bool IsMemberRefExpr,
Craig Toppere335f252015-10-04 04:53:55 +00002846 const DeclarationNameInfo &NI, SourceRange QLoc,
Craig Topper69186e72014-06-08 08:38:04 +00002847 const ASTTemplateArgumentListInfo *TemplateArgs = nullptr) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002848 const bool WantQualifier = NameFlags & CXNameRange_WantQualifier;
2849 const bool WantTemplateArgs = NameFlags & CXNameRange_WantTemplateArgs;
2850 const bool WantSinglePiece = NameFlags & CXNameRange_WantSinglePiece;
2851
2852 const DeclarationName::NameKind Kind = NI.getName().getNameKind();
2853
2854 RefNamePieces Pieces;
2855
2856 if (WantQualifier && QLoc.isValid())
2857 Pieces.push_back(QLoc);
2858
2859 if (Kind != DeclarationName::CXXOperatorName || IsMemberRefExpr)
2860 Pieces.push_back(NI.getLoc());
2861
2862 if (WantTemplateArgs && TemplateArgs)
2863 Pieces.push_back(SourceRange(TemplateArgs->LAngleLoc,
2864 TemplateArgs->RAngleLoc));
2865
2866 if (Kind == DeclarationName::CXXOperatorName) {
2867 Pieces.push_back(SourceLocation::getFromRawEncoding(
2868 NI.getInfo().CXXOperatorName.BeginOpNameLoc));
2869 Pieces.push_back(SourceLocation::getFromRawEncoding(
2870 NI.getInfo().CXXOperatorName.EndOpNameLoc));
2871 }
2872
2873 if (WantSinglePiece) {
2874 SourceRange R(Pieces.front().getBegin(), Pieces.back().getEnd());
2875 Pieces.clear();
2876 Pieces.push_back(R);
2877 }
2878
2879 return Pieces;
2880}
Alexander Kornienkoab9db512015-06-22 23:07:51 +00002881}
Guy Benyei11169dd2012-12-18 14:30:41 +00002882
2883//===----------------------------------------------------------------------===//
2884// Misc. API hooks.
2885//===----------------------------------------------------------------------===//
2886
Chad Rosier05c71aa2013-03-27 18:28:23 +00002887static void fatal_error_handler(void *user_data, const std::string& reason,
2888 bool gen_crash_diag) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002889 // Write the result out to stderr avoiding errs() because raw_ostreams can
2890 // call report_fatal_error.
2891 fprintf(stderr, "LIBCLANG FATAL ERROR: %s\n", reason.c_str());
2892 ::abort();
2893}
2894
Chandler Carruth66660742014-06-27 16:37:27 +00002895namespace {
2896struct RegisterFatalErrorHandler {
2897 RegisterFatalErrorHandler() {
2898 llvm::install_fatal_error_handler(fatal_error_handler, nullptr);
2899 }
2900};
2901}
2902
2903static llvm::ManagedStatic<RegisterFatalErrorHandler> RegisterFatalErrorHandlerOnce;
2904
Guy Benyei11169dd2012-12-18 14:30:41 +00002905extern "C" {
2906CXIndex clang_createIndex(int excludeDeclarationsFromPCH,
2907 int displayDiagnostics) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002908 // We use crash recovery to make some of our APIs more reliable, implicitly
2909 // enable it.
Argyrios Kyrtzidis3701f542013-11-27 08:58:09 +00002910 if (!getenv("LIBCLANG_DISABLE_CRASH_RECOVERY"))
2911 llvm::CrashRecoveryContext::Enable();
Guy Benyei11169dd2012-12-18 14:30:41 +00002912
Chandler Carruth66660742014-06-27 16:37:27 +00002913 // Look through the managed static to trigger construction of the managed
2914 // static which registers our fatal error handler. This ensures it is only
2915 // registered once.
2916 (void)*RegisterFatalErrorHandlerOnce;
Guy Benyei11169dd2012-12-18 14:30:41 +00002917
Adrian Prantlbc068582015-07-08 01:00:30 +00002918 // Initialize targets for clang module support.
2919 llvm::InitializeAllTargets();
2920 llvm::InitializeAllTargetMCs();
2921 llvm::InitializeAllAsmPrinters();
2922 llvm::InitializeAllAsmParsers();
2923
Adrian Prantlfb2398d2015-07-17 01:19:54 +00002924 CIndexer *CIdxr = new CIndexer();
2925
Guy Benyei11169dd2012-12-18 14:30:41 +00002926 if (excludeDeclarationsFromPCH)
2927 CIdxr->setOnlyLocalDecls();
2928 if (displayDiagnostics)
2929 CIdxr->setDisplayDiagnostics();
2930
2931 if (getenv("LIBCLANG_BGPRIO_INDEX"))
2932 CIdxr->setCXGlobalOptFlags(CIdxr->getCXGlobalOptFlags() |
2933 CXGlobalOpt_ThreadBackgroundPriorityForIndexing);
2934 if (getenv("LIBCLANG_BGPRIO_EDIT"))
2935 CIdxr->setCXGlobalOptFlags(CIdxr->getCXGlobalOptFlags() |
2936 CXGlobalOpt_ThreadBackgroundPriorityForEditing);
2937
2938 return CIdxr;
2939}
2940
2941void clang_disposeIndex(CXIndex CIdx) {
2942 if (CIdx)
2943 delete static_cast<CIndexer *>(CIdx);
2944}
2945
2946void clang_CXIndex_setGlobalOptions(CXIndex CIdx, unsigned options) {
2947 if (CIdx)
2948 static_cast<CIndexer *>(CIdx)->setCXGlobalOptFlags(options);
2949}
2950
2951unsigned clang_CXIndex_getGlobalOptions(CXIndex CIdx) {
2952 if (CIdx)
2953 return static_cast<CIndexer *>(CIdx)->getCXGlobalOptFlags();
2954 return 0;
2955}
2956
2957void clang_toggleCrashRecovery(unsigned isEnabled) {
2958 if (isEnabled)
2959 llvm::CrashRecoveryContext::Enable();
2960 else
2961 llvm::CrashRecoveryContext::Disable();
2962}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002963
Guy Benyei11169dd2012-12-18 14:30:41 +00002964CXTranslationUnit clang_createTranslationUnit(CXIndex CIdx,
2965 const char *ast_filename) {
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00002966 CXTranslationUnit TU;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002967 enum CXErrorCode Result =
2968 clang_createTranslationUnit2(CIdx, ast_filename, &TU);
Reid Klecknerfd48fc62014-02-12 23:56:20 +00002969 (void)Result;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002970 assert((TU && Result == CXError_Success) ||
2971 (!TU && Result != CXError_Success));
2972 return TU;
2973}
2974
2975enum CXErrorCode clang_createTranslationUnit2(CXIndex CIdx,
2976 const char *ast_filename,
2977 CXTranslationUnit *out_TU) {
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00002978 if (out_TU)
Craig Topper69186e72014-06-08 08:38:04 +00002979 *out_TU = nullptr;
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00002980
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002981 if (!CIdx || !ast_filename || !out_TU)
2982 return CXError_InvalidArguments;
Guy Benyei11169dd2012-12-18 14:30:41 +00002983
Argyrios Kyrtzidis27021012013-05-24 22:24:07 +00002984 LOG_FUNC_SECTION {
2985 *Log << ast_filename;
2986 }
2987
Guy Benyei11169dd2012-12-18 14:30:41 +00002988 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
2989 FileSystemOptions FileSystemOpts;
2990
Justin Bognerd512c1e2014-10-15 00:33:06 +00002991 IntrusiveRefCntPtr<DiagnosticsEngine> Diags =
2992 CompilerInstance::createDiagnostics(new DiagnosticOptions());
David Blaikie6f7382d2014-08-10 19:08:04 +00002993 std::unique_ptr<ASTUnit> AU = ASTUnit::LoadFromASTFile(
Adrian Prantlfb2398d2015-07-17 01:19:54 +00002994 ast_filename, CXXIdx->getPCHContainerOperations()->getRawReader(), Diags,
Adrian Prantl6b21ab22015-08-27 19:46:20 +00002995 FileSystemOpts, /*UseDebugInfo=*/false,
2996 CXXIdx->getOnlyLocalDecls(), None,
David Blaikie6f7382d2014-08-10 19:08:04 +00002997 /*CaptureDiagnostics=*/true,
2998 /*AllowPCHWithCompilerErrors=*/true,
2999 /*UserFilesAreVolatile=*/true);
3000 *out_TU = MakeCXTranslationUnit(CXXIdx, AU.release());
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003001 return *out_TU ? CXError_Success : CXError_Failure;
Guy Benyei11169dd2012-12-18 14:30:41 +00003002}
3003
3004unsigned clang_defaultEditingTranslationUnitOptions() {
3005 return CXTranslationUnit_PrecompiledPreamble |
3006 CXTranslationUnit_CacheCompletionResults;
3007}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003008
Guy Benyei11169dd2012-12-18 14:30:41 +00003009CXTranslationUnit
3010clang_createTranslationUnitFromSourceFile(CXIndex CIdx,
3011 const char *source_filename,
3012 int num_command_line_args,
3013 const char * const *command_line_args,
3014 unsigned num_unsaved_files,
3015 struct CXUnsavedFile *unsaved_files) {
3016 unsigned Options = CXTranslationUnit_DetailedPreprocessingRecord;
3017 return clang_parseTranslationUnit(CIdx, source_filename,
3018 command_line_args, num_command_line_args,
3019 unsaved_files, num_unsaved_files,
3020 Options);
3021}
3022
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003023static CXErrorCode
3024clang_parseTranslationUnit_Impl(CXIndex CIdx, const char *source_filename,
3025 const char *const *command_line_args,
3026 int num_command_line_args,
3027 ArrayRef<CXUnsavedFile> unsaved_files,
3028 unsigned options, CXTranslationUnit *out_TU) {
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00003029 // Set up the initial return values.
3030 if (out_TU)
Craig Topper69186e72014-06-08 08:38:04 +00003031 *out_TU = nullptr;
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00003032
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003033 // Check arguments.
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003034 if (!CIdx || !out_TU)
3035 return CXError_InvalidArguments;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003036
Guy Benyei11169dd2012-12-18 14:30:41 +00003037 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
3038
3039 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
3040 setThreadBackgroundPriority();
3041
3042 bool PrecompilePreamble = options & CXTranslationUnit_PrecompiledPreamble;
3043 // FIXME: Add a flag for modules.
3044 TranslationUnitKind TUKind
3045 = (options & CXTranslationUnit_Incomplete)? TU_Prefix : TU_Complete;
Alp Toker8c8a8752013-12-03 06:53:35 +00003046 bool CacheCodeCompletionResults
Guy Benyei11169dd2012-12-18 14:30:41 +00003047 = options & CXTranslationUnit_CacheCompletionResults;
3048 bool IncludeBriefCommentsInCodeCompletion
3049 = options & CXTranslationUnit_IncludeBriefCommentsInCodeCompletion;
3050 bool SkipFunctionBodies = options & CXTranslationUnit_SkipFunctionBodies;
3051 bool ForSerialization = options & CXTranslationUnit_ForSerialization;
3052
3053 // Configure the diagnostics.
3054 IntrusiveRefCntPtr<DiagnosticsEngine>
Sean Silvaf1b49e22013-01-20 01:58:28 +00003055 Diags(CompilerInstance::createDiagnostics(new DiagnosticOptions));
Guy Benyei11169dd2012-12-18 14:30:41 +00003056
3057 // Recover resources if we crash before exiting this function.
3058 llvm::CrashRecoveryContextCleanupRegistrar<DiagnosticsEngine,
3059 llvm::CrashRecoveryContextReleaseRefCleanup<DiagnosticsEngine> >
Alp Tokerf994cef2014-07-05 03:08:06 +00003060 DiagCleanup(Diags.get());
Guy Benyei11169dd2012-12-18 14:30:41 +00003061
Ahmed Charlesb8984322014-03-07 20:03:18 +00003062 std::unique_ptr<std::vector<ASTUnit::RemappedFile>> RemappedFiles(
3063 new std::vector<ASTUnit::RemappedFile>());
Guy Benyei11169dd2012-12-18 14:30:41 +00003064
3065 // Recover resources if we crash before exiting this function.
3066 llvm::CrashRecoveryContextCleanupRegistrar<
3067 std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
3068
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003069 for (auto &UF : unsaved_files) {
Rafael Espindolad87f8d72014-08-27 20:03:29 +00003070 std::unique_ptr<llvm::MemoryBuffer> MB =
Alp Toker9d85b182014-07-07 01:23:14 +00003071 llvm::MemoryBuffer::getMemBufferCopy(getContents(UF), UF.Filename);
Rafael Espindolad87f8d72014-08-27 20:03:29 +00003072 RemappedFiles->push_back(std::make_pair(UF.Filename, MB.release()));
Guy Benyei11169dd2012-12-18 14:30:41 +00003073 }
3074
Ahmed Charlesb8984322014-03-07 20:03:18 +00003075 std::unique_ptr<std::vector<const char *>> Args(
3076 new std::vector<const char *>());
Guy Benyei11169dd2012-12-18 14:30:41 +00003077
3078 // Recover resources if we crash before exiting this method.
3079 llvm::CrashRecoveryContextCleanupRegistrar<std::vector<const char*> >
3080 ArgsCleanup(Args.get());
3081
3082 // Since the Clang C library is primarily used by batch tools dealing with
3083 // (often very broken) source code, where spell-checking can have a
3084 // significant negative impact on performance (particularly when
3085 // precompiled headers are involved), we disable it by default.
3086 // Only do this if we haven't found a spell-checking-related argument.
3087 bool FoundSpellCheckingArgument = false;
3088 for (int I = 0; I != num_command_line_args; ++I) {
3089 if (strcmp(command_line_args[I], "-fno-spell-checking") == 0 ||
3090 strcmp(command_line_args[I], "-fspell-checking") == 0) {
3091 FoundSpellCheckingArgument = true;
3092 break;
3093 }
3094 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003095 Args->insert(Args->end(), command_line_args,
3096 command_line_args + num_command_line_args);
3097
Benjamin Kramerc02670e2015-11-18 16:14:27 +00003098 if (!FoundSpellCheckingArgument)
3099 Args->insert(Args->begin() + 1, "-fno-spell-checking");
3100
Guy Benyei11169dd2012-12-18 14:30:41 +00003101 // The 'source_filename' argument is optional. If the caller does not
3102 // specify it then it is assumed that the source file is specified
3103 // in the actual argument list.
3104 // Put the source file after command_line_args otherwise if '-x' flag is
3105 // present it will be unused.
3106 if (source_filename)
3107 Args->push_back(source_filename);
3108
3109 // Do we need the detailed preprocessing record?
3110 if (options & CXTranslationUnit_DetailedPreprocessingRecord) {
3111 Args->push_back("-Xclang");
3112 Args->push_back("-detailed-preprocessing-record");
3113 }
3114
3115 unsigned NumErrors = Diags->getClient()->getNumErrors();
Ahmed Charlesb8984322014-03-07 20:03:18 +00003116 std::unique_ptr<ASTUnit> ErrUnit;
3117 std::unique_ptr<ASTUnit> Unit(ASTUnit::LoadFromCommandLine(
Adrian Prantlbb165fb2015-06-20 18:53:08 +00003118 Args->data(), Args->data() + Args->size(),
3119 CXXIdx->getPCHContainerOperations(), Diags,
Ahmed Charlesb8984322014-03-07 20:03:18 +00003120 CXXIdx->getClangResourcesPath(), CXXIdx->getOnlyLocalDecls(),
3121 /*CaptureDiagnostics=*/true, *RemappedFiles.get(),
3122 /*RemappedFilesKeepOriginalName=*/true, PrecompilePreamble, TUKind,
3123 CacheCodeCompletionResults, IncludeBriefCommentsInCodeCompletion,
3124 /*AllowPCHWithCompilerErrors=*/true, SkipFunctionBodies,
Argyrios Kyrtzidisa3e2ff12015-11-20 03:36:21 +00003125 /*UserFilesAreVolatile=*/true, ForSerialization,
3126 CXXIdx->getPCHContainerOperations()->getRawReader().getFormat(),
3127 &ErrUnit));
Guy Benyei11169dd2012-12-18 14:30:41 +00003128
Artem Belevich0ff05cd2015-07-13 23:27:56 +00003129 // Early failures in LoadFromCommandLine may return with ErrUnit unset.
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003130 if (!Unit && !ErrUnit)
3131 return CXError_ASTReadError;
Artem Belevich0ff05cd2015-07-13 23:27:56 +00003132
Guy Benyei11169dd2012-12-18 14:30:41 +00003133 if (NumErrors != Diags->getClient()->getNumErrors()) {
3134 // Make sure to check that 'Unit' is non-NULL.
3135 if (CXXIdx->getDisplayDiagnostics())
3136 printDiagsToStderr(Unit ? Unit.get() : ErrUnit.get());
3137 }
3138
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003139 if (isASTReadError(Unit ? Unit.get() : ErrUnit.get()))
3140 return CXError_ASTReadError;
3141
3142 *out_TU = MakeCXTranslationUnit(CXXIdx, Unit.release());
3143 return *out_TU ? CXError_Success : CXError_Failure;
Guy Benyei11169dd2012-12-18 14:30:41 +00003144}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003145
3146CXTranslationUnit
3147clang_parseTranslationUnit(CXIndex CIdx,
3148 const char *source_filename,
3149 const char *const *command_line_args,
3150 int num_command_line_args,
3151 struct CXUnsavedFile *unsaved_files,
3152 unsigned num_unsaved_files,
3153 unsigned options) {
3154 CXTranslationUnit TU;
3155 enum CXErrorCode Result = clang_parseTranslationUnit2(
3156 CIdx, source_filename, command_line_args, num_command_line_args,
3157 unsaved_files, num_unsaved_files, options, &TU);
Reid Kleckner6eaf05a2014-02-13 01:19:59 +00003158 (void)Result;
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00003159 assert((TU && Result == CXError_Success) ||
3160 (!TU && Result != CXError_Success));
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003161 return TU;
3162}
3163
3164enum CXErrorCode clang_parseTranslationUnit2(
Benjamin Kramerc02670e2015-11-18 16:14:27 +00003165 CXIndex CIdx, const char *source_filename,
3166 const char *const *command_line_args, int num_command_line_args,
3167 struct CXUnsavedFile *unsaved_files, unsigned num_unsaved_files,
3168 unsigned options, CXTranslationUnit *out_TU) {
3169 SmallVector<const char *, 4> Args;
3170 Args.push_back("clang");
3171 Args.append(command_line_args, command_line_args + num_command_line_args);
3172 return clang_parseTranslationUnit2FullArgv(
3173 CIdx, source_filename, Args.data(), Args.size(), unsaved_files,
3174 num_unsaved_files, options, out_TU);
3175}
3176
3177enum CXErrorCode clang_parseTranslationUnit2FullArgv(
3178 CXIndex CIdx, const char *source_filename,
3179 const char *const *command_line_args, int num_command_line_args,
3180 struct CXUnsavedFile *unsaved_files, unsigned num_unsaved_files,
3181 unsigned options, CXTranslationUnit *out_TU) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00003182 LOG_FUNC_SECTION {
3183 *Log << source_filename << ": ";
3184 for (int i = 0; i != num_command_line_args; ++i)
3185 *Log << command_line_args[i] << " ";
3186 }
3187
Alp Toker9d85b182014-07-07 01:23:14 +00003188 if (num_unsaved_files && !unsaved_files)
3189 return CXError_InvalidArguments;
3190
Alp Toker5c532982014-07-07 22:42:03 +00003191 CXErrorCode result = CXError_Failure;
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003192 auto ParseTranslationUnitImpl = [=, &result] {
3193 result = clang_parseTranslationUnit_Impl(
3194 CIdx, source_filename, command_line_args, num_command_line_args,
3195 llvm::makeArrayRef(unsaved_files, num_unsaved_files), options, out_TU);
3196 };
Guy Benyei11169dd2012-12-18 14:30:41 +00003197 llvm::CrashRecoveryContext CRC;
3198
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003199 if (!RunSafely(CRC, ParseTranslationUnitImpl)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003200 fprintf(stderr, "libclang: crash detected during parsing: {\n");
3201 fprintf(stderr, " 'source_filename' : '%s'\n", source_filename);
3202 fprintf(stderr, " 'command_line_args' : [");
3203 for (int i = 0; i != num_command_line_args; ++i) {
3204 if (i)
3205 fprintf(stderr, ", ");
3206 fprintf(stderr, "'%s'", command_line_args[i]);
3207 }
3208 fprintf(stderr, "],\n");
3209 fprintf(stderr, " 'unsaved_files' : [");
3210 for (unsigned i = 0; i != num_unsaved_files; ++i) {
3211 if (i)
3212 fprintf(stderr, ", ");
3213 fprintf(stderr, "('%s', '...', %ld)", unsaved_files[i].Filename,
3214 unsaved_files[i].Length);
3215 }
3216 fprintf(stderr, "],\n");
3217 fprintf(stderr, " 'options' : %d,\n", options);
3218 fprintf(stderr, "}\n");
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003219
3220 return CXError_Crashed;
Guy Benyei11169dd2012-12-18 14:30:41 +00003221 } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003222 if (CXTranslationUnit *TU = out_TU)
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003223 PrintLibclangResourceUsage(*TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003224 }
Alp Toker5c532982014-07-07 22:42:03 +00003225
3226 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003227}
3228
3229unsigned clang_defaultSaveOptions(CXTranslationUnit TU) {
3230 return CXSaveTranslationUnit_None;
3231}
3232
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003233static CXSaveError clang_saveTranslationUnit_Impl(CXTranslationUnit TU,
3234 const char *FileName,
3235 unsigned options) {
3236 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00003237 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
3238 setThreadBackgroundPriority();
3239
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003240 bool hadError = cxtu::getASTUnit(TU)->Save(FileName);
3241 return hadError ? CXSaveError_Unknown : CXSaveError_None;
Guy Benyei11169dd2012-12-18 14:30:41 +00003242}
3243
3244int clang_saveTranslationUnit(CXTranslationUnit TU, const char *FileName,
3245 unsigned options) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00003246 LOG_FUNC_SECTION {
3247 *Log << TU << ' ' << FileName;
3248 }
3249
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003250 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003251 LOG_BAD_TU(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003252 return CXSaveError_InvalidTU;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003253 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003254
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003255 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003256 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
3257 if (!CXXUnit->hasSema())
3258 return CXSaveError_InvalidTU;
3259
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003260 CXSaveError result;
3261 auto SaveTranslationUnitImpl = [=, &result]() {
3262 result = clang_saveTranslationUnit_Impl(TU, FileName, options);
3263 };
Guy Benyei11169dd2012-12-18 14:30:41 +00003264
3265 if (!CXXUnit->getDiagnostics().hasUnrecoverableErrorOccurred() ||
3266 getenv("LIBCLANG_NOTHREADS")) {
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003267 SaveTranslationUnitImpl();
Guy Benyei11169dd2012-12-18 14:30:41 +00003268
3269 if (getenv("LIBCLANG_RESOURCE_USAGE"))
3270 PrintLibclangResourceUsage(TU);
3271
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003272 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003273 }
3274
3275 // We have an AST that has invalid nodes due to compiler errors.
3276 // Use a crash recovery thread for protection.
3277
3278 llvm::CrashRecoveryContext CRC;
3279
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003280 if (!RunSafely(CRC, SaveTranslationUnitImpl)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003281 fprintf(stderr, "libclang: crash detected during AST saving: {\n");
3282 fprintf(stderr, " 'filename' : '%s'\n", FileName);
3283 fprintf(stderr, " 'options' : %d,\n", options);
3284 fprintf(stderr, "}\n");
3285
3286 return CXSaveError_Unknown;
3287
3288 } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
3289 PrintLibclangResourceUsage(TU);
3290 }
3291
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003292 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003293}
3294
3295void clang_disposeTranslationUnit(CXTranslationUnit CTUnit) {
3296 if (CTUnit) {
3297 // If the translation unit has been marked as unsafe to free, just discard
3298 // it.
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003299 ASTUnit *Unit = cxtu::getASTUnit(CTUnit);
3300 if (Unit && Unit->isUnsafeToFree())
Guy Benyei11169dd2012-12-18 14:30:41 +00003301 return;
3302
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003303 delete cxtu::getASTUnit(CTUnit);
Dmitri Gribenkob95b3f12013-01-26 22:44:19 +00003304 delete CTUnit->StringPool;
Guy Benyei11169dd2012-12-18 14:30:41 +00003305 delete static_cast<CXDiagnosticSetImpl *>(CTUnit->Diagnostics);
3306 disposeOverridenCXCursorsPool(CTUnit->OverridenCursorsPool);
Dmitri Gribenko9e605112013-11-13 22:16:51 +00003307 delete CTUnit->CommentToXML;
Guy Benyei11169dd2012-12-18 14:30:41 +00003308 delete CTUnit;
3309 }
3310}
3311
3312unsigned clang_defaultReparseOptions(CXTranslationUnit TU) {
3313 return CXReparse_None;
3314}
3315
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003316static CXErrorCode
3317clang_reparseTranslationUnit_Impl(CXTranslationUnit TU,
3318 ArrayRef<CXUnsavedFile> unsaved_files,
3319 unsigned options) {
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003320 // Check arguments.
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003321 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003322 LOG_BAD_TU(TU);
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003323 return CXError_InvalidArguments;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003324 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003325
3326 // Reset the associated diagnostics.
3327 delete static_cast<CXDiagnosticSetImpl*>(TU->Diagnostics);
Craig Topper69186e72014-06-08 08:38:04 +00003328 TU->Diagnostics = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00003329
Dmitri Gribenko183436e2013-01-26 21:49:50 +00003330 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00003331 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
3332 setThreadBackgroundPriority();
3333
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003334 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003335 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
Ahmed Charlesb8984322014-03-07 20:03:18 +00003336
3337 std::unique_ptr<std::vector<ASTUnit::RemappedFile>> RemappedFiles(
3338 new std::vector<ASTUnit::RemappedFile>());
3339
Guy Benyei11169dd2012-12-18 14:30:41 +00003340 // Recover resources if we crash before exiting this function.
3341 llvm::CrashRecoveryContextCleanupRegistrar<
3342 std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
Alp Toker9d85b182014-07-07 01:23:14 +00003343
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003344 for (auto &UF : unsaved_files) {
Rafael Espindolad87f8d72014-08-27 20:03:29 +00003345 std::unique_ptr<llvm::MemoryBuffer> MB =
Alp Toker9d85b182014-07-07 01:23:14 +00003346 llvm::MemoryBuffer::getMemBufferCopy(getContents(UF), UF.Filename);
Rafael Espindolad87f8d72014-08-27 20:03:29 +00003347 RemappedFiles->push_back(std::make_pair(UF.Filename, MB.release()));
Guy Benyei11169dd2012-12-18 14:30:41 +00003348 }
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003349
Adrian Prantlbb165fb2015-06-20 18:53:08 +00003350 if (!CXXUnit->Reparse(CXXIdx->getPCHContainerOperations(),
3351 *RemappedFiles.get()))
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003352 return CXError_Success;
3353 if (isASTReadError(CXXUnit))
3354 return CXError_ASTReadError;
3355 return CXError_Failure;
Guy Benyei11169dd2012-12-18 14:30:41 +00003356}
3357
3358int clang_reparseTranslationUnit(CXTranslationUnit TU,
3359 unsigned num_unsaved_files,
3360 struct CXUnsavedFile *unsaved_files,
3361 unsigned options) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00003362 LOG_FUNC_SECTION {
3363 *Log << TU;
3364 }
3365
Alp Toker9d85b182014-07-07 01:23:14 +00003366 if (num_unsaved_files && !unsaved_files)
3367 return CXError_InvalidArguments;
3368
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003369 CXErrorCode result;
3370 auto ReparseTranslationUnitImpl = [=, &result]() {
3371 result = clang_reparseTranslationUnit_Impl(
3372 TU, llvm::makeArrayRef(unsaved_files, num_unsaved_files), options);
3373 };
Guy Benyei11169dd2012-12-18 14:30:41 +00003374
3375 if (getenv("LIBCLANG_NOTHREADS")) {
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003376 ReparseTranslationUnitImpl();
Alp Toker5c532982014-07-07 22:42:03 +00003377 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003378 }
3379
3380 llvm::CrashRecoveryContext CRC;
3381
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003382 if (!RunSafely(CRC, ReparseTranslationUnitImpl)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003383 fprintf(stderr, "libclang: crash detected during reparsing\n");
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003384 cxtu::getASTUnit(TU)->setUnsafeToFree(true);
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003385 return CXError_Crashed;
Guy Benyei11169dd2012-12-18 14:30:41 +00003386 } else if (getenv("LIBCLANG_RESOURCE_USAGE"))
3387 PrintLibclangResourceUsage(TU);
3388
Alp Toker5c532982014-07-07 22:42:03 +00003389 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003390}
3391
3392
3393CXString clang_getTranslationUnitSpelling(CXTranslationUnit CTUnit) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003394 if (isNotUsableTU(CTUnit)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003395 LOG_BAD_TU(CTUnit);
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003396 return cxstring::createEmpty();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003397 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003398
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003399 ASTUnit *CXXUnit = cxtu::getASTUnit(CTUnit);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003400 return cxstring::createDup(CXXUnit->getOriginalSourceFileName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003401}
3402
3403CXCursor clang_getTranslationUnitCursor(CXTranslationUnit TU) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003404 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003405 LOG_BAD_TU(TU);
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00003406 return clang_getNullCursor();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003407 }
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00003408
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003409 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003410 return MakeCXCursor(CXXUnit->getASTContext().getTranslationUnitDecl(), TU);
3411}
3412
3413} // end: extern "C"
3414
3415//===----------------------------------------------------------------------===//
3416// CXFile Operations.
3417//===----------------------------------------------------------------------===//
3418
3419extern "C" {
3420CXString clang_getFileName(CXFile SFile) {
3421 if (!SFile)
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00003422 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00003423
3424 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003425 return cxstring::createRef(FEnt->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003426}
3427
3428time_t clang_getFileTime(CXFile SFile) {
3429 if (!SFile)
3430 return 0;
3431
3432 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
3433 return FEnt->getModificationTime();
3434}
3435
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003436CXFile clang_getFile(CXTranslationUnit TU, const char *file_name) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003437 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003438 LOG_BAD_TU(TU);
Craig Topper69186e72014-06-08 08:38:04 +00003439 return nullptr;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003440 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003441
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003442 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003443
3444 FileManager &FMgr = CXXUnit->getFileManager();
3445 return const_cast<FileEntry *>(FMgr.getFile(file_name));
3446}
3447
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003448unsigned clang_isFileMultipleIncludeGuarded(CXTranslationUnit TU,
3449 CXFile file) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003450 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003451 LOG_BAD_TU(TU);
3452 return 0;
3453 }
3454
3455 if (!file)
Guy Benyei11169dd2012-12-18 14:30:41 +00003456 return 0;
3457
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003458 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003459 FileEntry *FEnt = static_cast<FileEntry *>(file);
3460 return CXXUnit->getPreprocessor().getHeaderSearchInfo()
3461 .isFileMultipleIncludeGuarded(FEnt);
3462}
3463
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003464int clang_getFileUniqueID(CXFile file, CXFileUniqueID *outID) {
3465 if (!file || !outID)
3466 return 1;
3467
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003468 FileEntry *FEnt = static_cast<FileEntry *>(file);
Rafael Espindolaf8f91b82013-08-01 21:42:11 +00003469 const llvm::sys::fs::UniqueID &ID = FEnt->getUniqueID();
3470 outID->data[0] = ID.getDevice();
3471 outID->data[1] = ID.getFile();
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003472 outID->data[2] = FEnt->getModificationTime();
3473 return 0;
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003474}
3475
Argyrios Kyrtzidisac3997e2014-08-16 00:26:19 +00003476int clang_File_isEqual(CXFile file1, CXFile file2) {
3477 if (file1 == file2)
3478 return true;
3479
3480 if (!file1 || !file2)
3481 return false;
3482
3483 FileEntry *FEnt1 = static_cast<FileEntry *>(file1);
3484 FileEntry *FEnt2 = static_cast<FileEntry *>(file2);
3485 return FEnt1->getUniqueID() == FEnt2->getUniqueID();
3486}
3487
Guy Benyei11169dd2012-12-18 14:30:41 +00003488} // end: extern "C"
3489
3490//===----------------------------------------------------------------------===//
3491// CXCursor Operations.
3492//===----------------------------------------------------------------------===//
3493
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003494static const Decl *getDeclFromExpr(const Stmt *E) {
3495 if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003496 return getDeclFromExpr(CE->getSubExpr());
3497
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003498 if (const DeclRefExpr *RefExpr = dyn_cast<DeclRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003499 return RefExpr->getDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003500 if (const MemberExpr *ME = dyn_cast<MemberExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003501 return ME->getMemberDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003502 if (const ObjCIvarRefExpr *RE = dyn_cast<ObjCIvarRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003503 return RE->getDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003504 if (const ObjCPropertyRefExpr *PRE = dyn_cast<ObjCPropertyRefExpr>(E)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003505 if (PRE->isExplicitProperty())
3506 return PRE->getExplicitProperty();
3507 // It could be messaging both getter and setter as in:
3508 // ++myobj.myprop;
3509 // in which case prefer to associate the setter since it is less obvious
3510 // from inspecting the source that the setter is going to get called.
3511 if (PRE->isMessagingSetter())
3512 return PRE->getImplicitPropertySetter();
3513 return PRE->getImplicitPropertyGetter();
3514 }
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003515 if (const PseudoObjectExpr *POE = dyn_cast<PseudoObjectExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003516 return getDeclFromExpr(POE->getSyntacticForm());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003517 if (const OpaqueValueExpr *OVE = dyn_cast<OpaqueValueExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003518 if (Expr *Src = OVE->getSourceExpr())
3519 return getDeclFromExpr(Src);
3520
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003521 if (const CallExpr *CE = dyn_cast<CallExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003522 return getDeclFromExpr(CE->getCallee());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003523 if (const CXXConstructExpr *CE = dyn_cast<CXXConstructExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003524 if (!CE->isElidable())
3525 return CE->getConstructor();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003526 if (const ObjCMessageExpr *OME = dyn_cast<ObjCMessageExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003527 return OME->getMethodDecl();
3528
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003529 if (const ObjCProtocolExpr *PE = dyn_cast<ObjCProtocolExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003530 return PE->getProtocol();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003531 if (const SubstNonTypeTemplateParmPackExpr *NTTP
Guy Benyei11169dd2012-12-18 14:30:41 +00003532 = dyn_cast<SubstNonTypeTemplateParmPackExpr>(E))
3533 return NTTP->getParameterPack();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003534 if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003535 if (isa<NonTypeTemplateParmDecl>(SizeOfPack->getPack()) ||
3536 isa<ParmVarDecl>(SizeOfPack->getPack()))
3537 return SizeOfPack->getPack();
Craig Topper69186e72014-06-08 08:38:04 +00003538
3539 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00003540}
3541
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003542static SourceLocation getLocationFromExpr(const Expr *E) {
3543 if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003544 return getLocationFromExpr(CE->getSubExpr());
3545
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003546 if (const ObjCMessageExpr *Msg = dyn_cast<ObjCMessageExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003547 return /*FIXME:*/Msg->getLeftLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003548 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003549 return DRE->getLocation();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003550 if (const MemberExpr *Member = dyn_cast<MemberExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003551 return Member->getMemberLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003552 if (const ObjCIvarRefExpr *Ivar = dyn_cast<ObjCIvarRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003553 return Ivar->getLocation();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003554 if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003555 return SizeOfPack->getPackLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003556 if (const ObjCPropertyRefExpr *PropRef = dyn_cast<ObjCPropertyRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003557 return PropRef->getLocation();
3558
3559 return E->getLocStart();
3560}
3561
Aaron Ballmana85d3f82015-11-12 15:25:06 +00003562static std::string getMangledStructor(std::unique_ptr<MangleContext> &M,
3563 std::unique_ptr<llvm::DataLayout> &DL,
3564 const NamedDecl *ND,
3565 unsigned StructorType) {
3566 std::string FrontendBuf;
3567 llvm::raw_string_ostream FOS(FrontendBuf);
3568
3569 if (const auto *CD = dyn_cast_or_null<CXXConstructorDecl>(ND))
3570 M->mangleCXXCtor(CD, static_cast<CXXCtorType>(StructorType), FOS);
3571 else if (const auto *DD = dyn_cast_or_null<CXXDestructorDecl>(ND))
3572 M->mangleCXXDtor(DD, static_cast<CXXDtorType>(StructorType), FOS);
3573
3574 std::string BackendBuf;
3575 llvm::raw_string_ostream BOS(BackendBuf);
3576
3577 llvm::Mangler::getNameWithPrefix(BOS, llvm::Twine(FOS.str()), *DL);
3578
3579 return BOS.str();
3580}
3581
Guy Benyei11169dd2012-12-18 14:30:41 +00003582extern "C" {
3583
3584unsigned clang_visitChildren(CXCursor parent,
3585 CXCursorVisitor visitor,
3586 CXClientData client_data) {
3587 CursorVisitor CursorVis(getCursorTU(parent), visitor, client_data,
3588 /*VisitPreprocessorLast=*/false);
3589 return CursorVis.VisitChildren(parent);
3590}
3591
3592#ifndef __has_feature
3593#define __has_feature(x) 0
3594#endif
3595#if __has_feature(blocks)
3596typedef enum CXChildVisitResult
3597 (^CXCursorVisitorBlock)(CXCursor cursor, CXCursor parent);
3598
3599static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
3600 CXClientData client_data) {
3601 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
3602 return block(cursor, parent);
3603}
3604#else
3605// If we are compiled with a compiler that doesn't have native blocks support,
3606// define and call the block manually, so the
3607typedef struct _CXChildVisitResult
3608{
3609 void *isa;
3610 int flags;
3611 int reserved;
3612 enum CXChildVisitResult(*invoke)(struct _CXChildVisitResult*, CXCursor,
3613 CXCursor);
3614} *CXCursorVisitorBlock;
3615
3616static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
3617 CXClientData client_data) {
3618 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
3619 return block->invoke(block, cursor, parent);
3620}
3621#endif
3622
3623
3624unsigned clang_visitChildrenWithBlock(CXCursor parent,
3625 CXCursorVisitorBlock block) {
3626 return clang_visitChildren(parent, visitWithBlock, block);
3627}
3628
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003629static CXString getDeclSpelling(const Decl *D) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003630 if (!D)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003631 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003632
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003633 const NamedDecl *ND = dyn_cast<NamedDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00003634 if (!ND) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003635 if (const ObjCPropertyImplDecl *PropImpl =
3636 dyn_cast<ObjCPropertyImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00003637 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003638 return cxstring::createDup(Property->getIdentifier()->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003639
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003640 if (const ImportDecl *ImportD = dyn_cast<ImportDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00003641 if (Module *Mod = ImportD->getImportedModule())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003642 return cxstring::createDup(Mod->getFullModuleName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003643
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003644 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003645 }
3646
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003647 if (const ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(ND))
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003648 return cxstring::createDup(OMD->getSelector().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003649
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003650 if (const ObjCCategoryImplDecl *CIMP = dyn_cast<ObjCCategoryImplDecl>(ND))
Guy Benyei11169dd2012-12-18 14:30:41 +00003651 // No, this isn't the same as the code below. getIdentifier() is non-virtual
3652 // and returns different names. NamedDecl returns the class name and
3653 // ObjCCategoryImplDecl returns the category name.
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003654 return cxstring::createRef(CIMP->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003655
3656 if (isa<UsingDirectiveDecl>(D))
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003657 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003658
3659 SmallString<1024> S;
3660 llvm::raw_svector_ostream os(S);
3661 ND->printName(os);
3662
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003663 return cxstring::createDup(os.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003664}
3665
3666CXString clang_getCursorSpelling(CXCursor C) {
3667 if (clang_isTranslationUnit(C.kind))
Dmitri Gribenko2c173b42013-01-11 19:28:44 +00003668 return clang_getTranslationUnitSpelling(getCursorTU(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00003669
3670 if (clang_isReference(C.kind)) {
3671 switch (C.kind) {
3672 case CXCursor_ObjCSuperClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003673 const ObjCInterfaceDecl *Super = getCursorObjCSuperClassRef(C).first;
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003674 return cxstring::createRef(Super->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003675 }
3676 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003677 const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003678 return cxstring::createRef(Class->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003679 }
3680 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003681 const ObjCProtocolDecl *OID = getCursorObjCProtocolRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003682 assert(OID && "getCursorSpelling(): Missing protocol decl");
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003683 return cxstring::createRef(OID->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003684 }
3685 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003686 const CXXBaseSpecifier *B = getCursorCXXBaseSpecifier(C);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003687 return cxstring::createDup(B->getType().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003688 }
3689 case CXCursor_TypeRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003690 const TypeDecl *Type = getCursorTypeRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003691 assert(Type && "Missing type decl");
3692
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003693 return cxstring::createDup(getCursorContext(C).getTypeDeclType(Type).
Guy Benyei11169dd2012-12-18 14:30:41 +00003694 getAsString());
3695 }
3696 case CXCursor_TemplateRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003697 const TemplateDecl *Template = getCursorTemplateRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003698 assert(Template && "Missing template decl");
3699
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003700 return cxstring::createDup(Template->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003701 }
3702
3703 case CXCursor_NamespaceRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003704 const NamedDecl *NS = getCursorNamespaceRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003705 assert(NS && "Missing namespace decl");
3706
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003707 return cxstring::createDup(NS->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003708 }
3709
3710 case CXCursor_MemberRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003711 const FieldDecl *Field = getCursorMemberRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003712 assert(Field && "Missing member decl");
3713
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003714 return cxstring::createDup(Field->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003715 }
3716
3717 case CXCursor_LabelRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003718 const LabelStmt *Label = getCursorLabelRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003719 assert(Label && "Missing label");
3720
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003721 return cxstring::createRef(Label->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003722 }
3723
3724 case CXCursor_OverloadedDeclRef: {
3725 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003726 if (const Decl *D = Storage.dyn_cast<const Decl *>()) {
3727 if (const NamedDecl *ND = dyn_cast<NamedDecl>(D))
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003728 return cxstring::createDup(ND->getNameAsString());
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003729 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003730 }
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003731 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003732 return cxstring::createDup(E->getName().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003733 OverloadedTemplateStorage *Ovl
3734 = Storage.get<OverloadedTemplateStorage*>();
3735 if (Ovl->size() == 0)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003736 return cxstring::createEmpty();
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003737 return cxstring::createDup((*Ovl->begin())->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003738 }
3739
3740 case CXCursor_VariableRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003741 const VarDecl *Var = getCursorVariableRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003742 assert(Var && "Missing variable decl");
3743
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003744 return cxstring::createDup(Var->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003745 }
3746
3747 default:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003748 return cxstring::createRef("<not implemented>");
Guy Benyei11169dd2012-12-18 14:30:41 +00003749 }
3750 }
3751
3752 if (clang_isExpression(C.kind)) {
Argyrios Kyrtzidis3227d862014-03-03 19:40:52 +00003753 const Expr *E = getCursorExpr(C);
3754
3755 if (C.kind == CXCursor_ObjCStringLiteral ||
3756 C.kind == CXCursor_StringLiteral) {
3757 const StringLiteral *SLit;
3758 if (const ObjCStringLiteral *OSL = dyn_cast<ObjCStringLiteral>(E)) {
3759 SLit = OSL->getString();
3760 } else {
3761 SLit = cast<StringLiteral>(E);
3762 }
3763 SmallString<256> Buf;
3764 llvm::raw_svector_ostream OS(Buf);
3765 SLit->outputString(OS);
3766 return cxstring::createDup(OS.str());
3767 }
3768
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003769 const Decl *D = getDeclFromExpr(getCursorExpr(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00003770 if (D)
3771 return getDeclSpelling(D);
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003772 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003773 }
3774
3775 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003776 const Stmt *S = getCursorStmt(C);
3777 if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S))
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003778 return cxstring::createRef(Label->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003779
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003780 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003781 }
3782
3783 if (C.kind == CXCursor_MacroExpansion)
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003784 return cxstring::createRef(getCursorMacroExpansion(C).getName()
Guy Benyei11169dd2012-12-18 14:30:41 +00003785 ->getNameStart());
3786
3787 if (C.kind == CXCursor_MacroDefinition)
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003788 return cxstring::createRef(getCursorMacroDefinition(C)->getName()
Guy Benyei11169dd2012-12-18 14:30:41 +00003789 ->getNameStart());
3790
3791 if (C.kind == CXCursor_InclusionDirective)
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003792 return cxstring::createDup(getCursorInclusionDirective(C)->getFileName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003793
3794 if (clang_isDeclaration(C.kind))
3795 return getDeclSpelling(getCursorDecl(C));
3796
3797 if (C.kind == CXCursor_AnnotateAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00003798 const AnnotateAttr *AA = cast<AnnotateAttr>(cxcursor::getCursorAttr(C));
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003799 return cxstring::createDup(AA->getAnnotation());
Guy Benyei11169dd2012-12-18 14:30:41 +00003800 }
3801
3802 if (C.kind == CXCursor_AsmLabelAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00003803 const AsmLabelAttr *AA = cast<AsmLabelAttr>(cxcursor::getCursorAttr(C));
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003804 return cxstring::createDup(AA->getLabel());
Guy Benyei11169dd2012-12-18 14:30:41 +00003805 }
3806
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00003807 if (C.kind == CXCursor_PackedAttr) {
3808 return cxstring::createRef("packed");
3809 }
3810
Saleem Abdulrasool79c69712015-09-05 18:53:43 +00003811 if (C.kind == CXCursor_VisibilityAttr) {
3812 const VisibilityAttr *AA = cast<VisibilityAttr>(cxcursor::getCursorAttr(C));
3813 switch (AA->getVisibility()) {
3814 case VisibilityAttr::VisibilityType::Default:
3815 return cxstring::createRef("default");
3816 case VisibilityAttr::VisibilityType::Hidden:
3817 return cxstring::createRef("hidden");
3818 case VisibilityAttr::VisibilityType::Protected:
3819 return cxstring::createRef("protected");
3820 }
3821 llvm_unreachable("unknown visibility type");
3822 }
3823
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003824 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003825}
3826
3827CXSourceRange clang_Cursor_getSpellingNameRange(CXCursor C,
3828 unsigned pieceIndex,
3829 unsigned options) {
3830 if (clang_Cursor_isNull(C))
3831 return clang_getNullRange();
3832
3833 ASTContext &Ctx = getCursorContext(C);
3834
3835 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003836 const Stmt *S = getCursorStmt(C);
3837 if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003838 if (pieceIndex > 0)
3839 return clang_getNullRange();
3840 return cxloc::translateSourceRange(Ctx, Label->getIdentLoc());
3841 }
3842
3843 return clang_getNullRange();
3844 }
3845
3846 if (C.kind == CXCursor_ObjCMessageExpr) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003847 if (const ObjCMessageExpr *
Guy Benyei11169dd2012-12-18 14:30:41 +00003848 ME = dyn_cast_or_null<ObjCMessageExpr>(getCursorExpr(C))) {
3849 if (pieceIndex >= ME->getNumSelectorLocs())
3850 return clang_getNullRange();
3851 return cxloc::translateSourceRange(Ctx, ME->getSelectorLoc(pieceIndex));
3852 }
3853 }
3854
3855 if (C.kind == CXCursor_ObjCInstanceMethodDecl ||
3856 C.kind == CXCursor_ObjCClassMethodDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003857 if (const ObjCMethodDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003858 MD = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(C))) {
3859 if (pieceIndex >= MD->getNumSelectorLocs())
3860 return clang_getNullRange();
3861 return cxloc::translateSourceRange(Ctx, MD->getSelectorLoc(pieceIndex));
3862 }
3863 }
3864
3865 if (C.kind == CXCursor_ObjCCategoryDecl ||
3866 C.kind == CXCursor_ObjCCategoryImplDecl) {
3867 if (pieceIndex > 0)
3868 return clang_getNullRange();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003869 if (const ObjCCategoryDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003870 CD = dyn_cast_or_null<ObjCCategoryDecl>(getCursorDecl(C)))
3871 return cxloc::translateSourceRange(Ctx, CD->getCategoryNameLoc());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003872 if (const ObjCCategoryImplDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003873 CID = dyn_cast_or_null<ObjCCategoryImplDecl>(getCursorDecl(C)))
3874 return cxloc::translateSourceRange(Ctx, CID->getCategoryNameLoc());
3875 }
3876
3877 if (C.kind == CXCursor_ModuleImportDecl) {
3878 if (pieceIndex > 0)
3879 return clang_getNullRange();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003880 if (const ImportDecl *ImportD =
3881 dyn_cast_or_null<ImportDecl>(getCursorDecl(C))) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003882 ArrayRef<SourceLocation> Locs = ImportD->getIdentifierLocs();
3883 if (!Locs.empty())
3884 return cxloc::translateSourceRange(Ctx,
3885 SourceRange(Locs.front(), Locs.back()));
3886 }
3887 return clang_getNullRange();
3888 }
3889
Argyrios Kyrtzidisa2a1e532014-08-26 20:23:26 +00003890 if (C.kind == CXCursor_CXXMethod || C.kind == CXCursor_Destructor ||
3891 C.kind == CXCursor_ConversionFunction) {
3892 if (pieceIndex > 0)
3893 return clang_getNullRange();
3894 if (const FunctionDecl *FD =
3895 dyn_cast_or_null<FunctionDecl>(getCursorDecl(C))) {
3896 DeclarationNameInfo FunctionName = FD->getNameInfo();
3897 return cxloc::translateSourceRange(Ctx, FunctionName.getSourceRange());
3898 }
3899 return clang_getNullRange();
3900 }
3901
Guy Benyei11169dd2012-12-18 14:30:41 +00003902 // FIXME: A CXCursor_InclusionDirective should give the location of the
3903 // filename, but we don't keep track of this.
3904
3905 // FIXME: A CXCursor_AnnotateAttr should give the location of the annotation
3906 // but we don't keep track of this.
3907
3908 // FIXME: A CXCursor_AsmLabelAttr should give the location of the label
3909 // but we don't keep track of this.
3910
3911 // Default handling, give the location of the cursor.
3912
3913 if (pieceIndex > 0)
3914 return clang_getNullRange();
3915
3916 CXSourceLocation CXLoc = clang_getCursorLocation(C);
3917 SourceLocation Loc = cxloc::translateSourceLocation(CXLoc);
3918 return cxloc::translateSourceRange(Ctx, Loc);
3919}
3920
Eli Bendersky44a206f2014-07-31 18:04:56 +00003921CXString clang_Cursor_getMangling(CXCursor C) {
3922 if (clang_isInvalid(C.kind) || !clang_isDeclaration(C.kind))
3923 return cxstring::createEmpty();
3924
Eli Bendersky44a206f2014-07-31 18:04:56 +00003925 // Mangling only works for functions and variables.
Eli Bendersky79759592014-08-01 15:01:10 +00003926 const Decl *D = getCursorDecl(C);
Eli Bendersky44a206f2014-07-31 18:04:56 +00003927 if (!D || !(isa<FunctionDecl>(D) || isa<VarDecl>(D)))
3928 return cxstring::createEmpty();
3929
Eli Bendersky79759592014-08-01 15:01:10 +00003930 // First apply frontend mangling.
Eli Bendersky44a206f2014-07-31 18:04:56 +00003931 const NamedDecl *ND = cast<NamedDecl>(D);
Eli Bendersky79759592014-08-01 15:01:10 +00003932 ASTContext &Ctx = ND->getASTContext();
3933 std::unique_ptr<MangleContext> MC(Ctx.createMangleContext());
Eli Bendersky44a206f2014-07-31 18:04:56 +00003934
Eli Bendersky79759592014-08-01 15:01:10 +00003935 std::string FrontendBuf;
3936 llvm::raw_string_ostream FrontendBufOS(FrontendBuf);
Ehsan Akhgarif8d44de2015-10-08 00:01:20 +00003937 if (MC->shouldMangleDeclName(ND)) {
3938 MC->mangleName(ND, FrontendBufOS);
3939 } else {
3940 ND->printName(FrontendBufOS);
3941 }
Eli Bendersky44a206f2014-07-31 18:04:56 +00003942
Eli Bendersky79759592014-08-01 15:01:10 +00003943 // Now apply backend mangling.
3944 std::unique_ptr<llvm::DataLayout> DL(
Eric Christopher964a5f32015-08-05 23:48:05 +00003945 new llvm::DataLayout(Ctx.getTargetInfo().getDataLayoutString()));
Eli Bendersky79759592014-08-01 15:01:10 +00003946
3947 std::string FinalBuf;
3948 llvm::raw_string_ostream FinalBufOS(FinalBuf);
Rafael Espindolab633d202015-06-23 13:59:36 +00003949 llvm::Mangler::getNameWithPrefix(FinalBufOS, llvm::Twine(FrontendBufOS.str()),
3950 *DL);
Eli Bendersky79759592014-08-01 15:01:10 +00003951
3952 return cxstring::createDup(FinalBufOS.str());
Eli Bendersky44a206f2014-07-31 18:04:56 +00003953}
3954
Saleem Abdulrasool60034432015-11-12 03:57:22 +00003955CXStringSet *clang_Cursor_getCXXManglings(CXCursor C) {
3956 if (clang_isInvalid(C.kind) || !clang_isDeclaration(C.kind))
3957 return nullptr;
3958
3959 const Decl *D = getCursorDecl(C);
3960 if (!(isa<CXXRecordDecl>(D) || isa<CXXMethodDecl>(D)))
3961 return nullptr;
3962
3963 const NamedDecl *ND = cast<NamedDecl>(D);
3964
3965 ASTContext &Ctx = ND->getASTContext();
3966 std::unique_ptr<MangleContext> M(Ctx.createMangleContext());
3967 std::unique_ptr<llvm::DataLayout> DL(
3968 new llvm::DataLayout(Ctx.getTargetInfo().getDataLayoutString()));
3969
3970 std::vector<std::string> Manglings;
3971
3972 auto hasDefaultCXXMethodCC = [](ASTContext &C, const CXXMethodDecl *MD) {
3973 auto DefaultCC = C.getDefaultCallingConvention(/*IsVariadic=*/false,
3974 /*IsCSSMethod=*/true);
3975 auto CC = MD->getType()->getAs<FunctionProtoType>()->getCallConv();
3976 return CC == DefaultCC;
3977 };
3978
3979 if (const auto *CD = dyn_cast_or_null<CXXConstructorDecl>(ND)) {
3980 Manglings.emplace_back(getMangledStructor(M, DL, CD, Ctor_Base));
3981
3982 if (Ctx.getTargetInfo().getCXXABI().isItaniumFamily())
3983 if (!CD->getParent()->isAbstract())
3984 Manglings.emplace_back(getMangledStructor(M, DL, CD, Ctor_Complete));
3985
3986 if (Ctx.getTargetInfo().getCXXABI().isMicrosoft())
3987 if (CD->hasAttr<DLLExportAttr>() && CD->isDefaultConstructor())
3988 if (!(hasDefaultCXXMethodCC(Ctx, CD) && CD->getNumParams() == 0))
3989 Manglings.emplace_back(getMangledStructor(M, DL, CD,
3990 Ctor_DefaultClosure));
3991 } else if (const auto *DD = dyn_cast_or_null<CXXDestructorDecl>(ND)) {
3992 Manglings.emplace_back(getMangledStructor(M, DL, DD, Dtor_Base));
3993 if (Ctx.getTargetInfo().getCXXABI().isItaniumFamily()) {
3994 Manglings.emplace_back(getMangledStructor(M, DL, DD, Dtor_Complete));
3995
3996 if (!DD->isVirtual())
3997 Manglings.emplace_back(getMangledStructor(M, DL, DD, Dtor_Deleting));
3998 }
3999 }
4000
4001 return cxstring::createSet(Manglings);
4002}
4003
Guy Benyei11169dd2012-12-18 14:30:41 +00004004CXString clang_getCursorDisplayName(CXCursor C) {
4005 if (!clang_isDeclaration(C.kind))
4006 return clang_getCursorSpelling(C);
4007
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004008 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004009 if (!D)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00004010 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00004011
4012 PrintingPolicy Policy = getCursorContext(C).getPrintingPolicy();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004013 if (const FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004014 D = FunTmpl->getTemplatedDecl();
4015
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004016 if (const FunctionDecl *Function = dyn_cast<FunctionDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004017 SmallString<64> Str;
4018 llvm::raw_svector_ostream OS(Str);
4019 OS << *Function;
4020 if (Function->getPrimaryTemplate())
4021 OS << "<>";
4022 OS << "(";
4023 for (unsigned I = 0, N = Function->getNumParams(); I != N; ++I) {
4024 if (I)
4025 OS << ", ";
4026 OS << Function->getParamDecl(I)->getType().getAsString(Policy);
4027 }
4028
4029 if (Function->isVariadic()) {
4030 if (Function->getNumParams())
4031 OS << ", ";
4032 OS << "...";
4033 }
4034 OS << ")";
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004035 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00004036 }
4037
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004038 if (const ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004039 SmallString<64> Str;
4040 llvm::raw_svector_ostream OS(Str);
4041 OS << *ClassTemplate;
4042 OS << "<";
4043 TemplateParameterList *Params = ClassTemplate->getTemplateParameters();
4044 for (unsigned I = 0, N = Params->size(); I != N; ++I) {
4045 if (I)
4046 OS << ", ";
4047
4048 NamedDecl *Param = Params->getParam(I);
4049 if (Param->getIdentifier()) {
4050 OS << Param->getIdentifier()->getName();
4051 continue;
4052 }
4053
4054 // There is no parameter name, which makes this tricky. Try to come up
4055 // with something useful that isn't too long.
4056 if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(Param))
4057 OS << (TTP->wasDeclaredWithTypename()? "typename" : "class");
4058 else if (NonTypeTemplateParmDecl *NTTP
4059 = dyn_cast<NonTypeTemplateParmDecl>(Param))
4060 OS << NTTP->getType().getAsString(Policy);
4061 else
4062 OS << "template<...> class";
4063 }
4064
4065 OS << ">";
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004066 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00004067 }
4068
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004069 if (const ClassTemplateSpecializationDecl *ClassSpec
Guy Benyei11169dd2012-12-18 14:30:41 +00004070 = dyn_cast<ClassTemplateSpecializationDecl>(D)) {
4071 // If the type was explicitly written, use that.
4072 if (TypeSourceInfo *TSInfo = ClassSpec->getTypeAsWritten())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004073 return cxstring::createDup(TSInfo->getType().getAsString(Policy));
Guy Benyei11169dd2012-12-18 14:30:41 +00004074
Benjamin Kramer9170e912013-02-22 15:46:01 +00004075 SmallString<128> Str;
Guy Benyei11169dd2012-12-18 14:30:41 +00004076 llvm::raw_svector_ostream OS(Str);
4077 OS << *ClassSpec;
Benjamin Kramer9170e912013-02-22 15:46:01 +00004078 TemplateSpecializationType::PrintTemplateArgumentList(OS,
Guy Benyei11169dd2012-12-18 14:30:41 +00004079 ClassSpec->getTemplateArgs().data(),
4080 ClassSpec->getTemplateArgs().size(),
4081 Policy);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004082 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00004083 }
4084
4085 return clang_getCursorSpelling(C);
4086}
4087
4088CXString clang_getCursorKindSpelling(enum CXCursorKind Kind) {
4089 switch (Kind) {
4090 case CXCursor_FunctionDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004091 return cxstring::createRef("FunctionDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004092 case CXCursor_TypedefDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004093 return cxstring::createRef("TypedefDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004094 case CXCursor_EnumDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004095 return cxstring::createRef("EnumDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004096 case CXCursor_EnumConstantDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004097 return cxstring::createRef("EnumConstantDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004098 case CXCursor_StructDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004099 return cxstring::createRef("StructDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004100 case CXCursor_UnionDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004101 return cxstring::createRef("UnionDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004102 case CXCursor_ClassDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004103 return cxstring::createRef("ClassDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004104 case CXCursor_FieldDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004105 return cxstring::createRef("FieldDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004106 case CXCursor_VarDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004107 return cxstring::createRef("VarDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004108 case CXCursor_ParmDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004109 return cxstring::createRef("ParmDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004110 case CXCursor_ObjCInterfaceDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004111 return cxstring::createRef("ObjCInterfaceDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004112 case CXCursor_ObjCCategoryDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004113 return cxstring::createRef("ObjCCategoryDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004114 case CXCursor_ObjCProtocolDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004115 return cxstring::createRef("ObjCProtocolDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004116 case CXCursor_ObjCPropertyDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004117 return cxstring::createRef("ObjCPropertyDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004118 case CXCursor_ObjCIvarDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004119 return cxstring::createRef("ObjCIvarDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004120 case CXCursor_ObjCInstanceMethodDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004121 return cxstring::createRef("ObjCInstanceMethodDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004122 case CXCursor_ObjCClassMethodDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004123 return cxstring::createRef("ObjCClassMethodDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004124 case CXCursor_ObjCImplementationDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004125 return cxstring::createRef("ObjCImplementationDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004126 case CXCursor_ObjCCategoryImplDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004127 return cxstring::createRef("ObjCCategoryImplDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004128 case CXCursor_CXXMethod:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004129 return cxstring::createRef("CXXMethod");
Guy Benyei11169dd2012-12-18 14:30:41 +00004130 case CXCursor_UnexposedDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004131 return cxstring::createRef("UnexposedDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004132 case CXCursor_ObjCSuperClassRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004133 return cxstring::createRef("ObjCSuperClassRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004134 case CXCursor_ObjCProtocolRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004135 return cxstring::createRef("ObjCProtocolRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004136 case CXCursor_ObjCClassRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004137 return cxstring::createRef("ObjCClassRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004138 case CXCursor_TypeRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004139 return cxstring::createRef("TypeRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004140 case CXCursor_TemplateRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004141 return cxstring::createRef("TemplateRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004142 case CXCursor_NamespaceRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004143 return cxstring::createRef("NamespaceRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004144 case CXCursor_MemberRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004145 return cxstring::createRef("MemberRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004146 case CXCursor_LabelRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004147 return cxstring::createRef("LabelRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004148 case CXCursor_OverloadedDeclRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004149 return cxstring::createRef("OverloadedDeclRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004150 case CXCursor_VariableRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004151 return cxstring::createRef("VariableRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004152 case CXCursor_IntegerLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004153 return cxstring::createRef("IntegerLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00004154 case CXCursor_FloatingLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004155 return cxstring::createRef("FloatingLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00004156 case CXCursor_ImaginaryLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004157 return cxstring::createRef("ImaginaryLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00004158 case CXCursor_StringLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004159 return cxstring::createRef("StringLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00004160 case CXCursor_CharacterLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004161 return cxstring::createRef("CharacterLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00004162 case CXCursor_ParenExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004163 return cxstring::createRef("ParenExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004164 case CXCursor_UnaryOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004165 return cxstring::createRef("UnaryOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00004166 case CXCursor_ArraySubscriptExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004167 return cxstring::createRef("ArraySubscriptExpr");
Alexey Bataev1a3320e2015-08-25 14:24:04 +00004168 case CXCursor_OMPArraySectionExpr:
4169 return cxstring::createRef("OMPArraySectionExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004170 case CXCursor_BinaryOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004171 return cxstring::createRef("BinaryOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00004172 case CXCursor_CompoundAssignOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004173 return cxstring::createRef("CompoundAssignOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00004174 case CXCursor_ConditionalOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004175 return cxstring::createRef("ConditionalOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00004176 case CXCursor_CStyleCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004177 return cxstring::createRef("CStyleCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004178 case CXCursor_CompoundLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004179 return cxstring::createRef("CompoundLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004180 case CXCursor_InitListExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004181 return cxstring::createRef("InitListExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004182 case CXCursor_AddrLabelExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004183 return cxstring::createRef("AddrLabelExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004184 case CXCursor_StmtExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004185 return cxstring::createRef("StmtExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004186 case CXCursor_GenericSelectionExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004187 return cxstring::createRef("GenericSelectionExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004188 case CXCursor_GNUNullExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004189 return cxstring::createRef("GNUNullExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004190 case CXCursor_CXXStaticCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004191 return cxstring::createRef("CXXStaticCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004192 case CXCursor_CXXDynamicCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004193 return cxstring::createRef("CXXDynamicCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004194 case CXCursor_CXXReinterpretCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004195 return cxstring::createRef("CXXReinterpretCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004196 case CXCursor_CXXConstCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004197 return cxstring::createRef("CXXConstCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004198 case CXCursor_CXXFunctionalCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004199 return cxstring::createRef("CXXFunctionalCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004200 case CXCursor_CXXTypeidExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004201 return cxstring::createRef("CXXTypeidExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004202 case CXCursor_CXXBoolLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004203 return cxstring::createRef("CXXBoolLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004204 case CXCursor_CXXNullPtrLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004205 return cxstring::createRef("CXXNullPtrLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004206 case CXCursor_CXXThisExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004207 return cxstring::createRef("CXXThisExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004208 case CXCursor_CXXThrowExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004209 return cxstring::createRef("CXXThrowExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004210 case CXCursor_CXXNewExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004211 return cxstring::createRef("CXXNewExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004212 case CXCursor_CXXDeleteExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004213 return cxstring::createRef("CXXDeleteExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004214 case CXCursor_UnaryExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004215 return cxstring::createRef("UnaryExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004216 case CXCursor_ObjCStringLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004217 return cxstring::createRef("ObjCStringLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00004218 case CXCursor_ObjCBoolLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004219 return cxstring::createRef("ObjCBoolLiteralExpr");
Argyrios Kyrtzidisc2233be2013-04-23 17:57:17 +00004220 case CXCursor_ObjCSelfExpr:
4221 return cxstring::createRef("ObjCSelfExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004222 case CXCursor_ObjCEncodeExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004223 return cxstring::createRef("ObjCEncodeExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004224 case CXCursor_ObjCSelectorExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004225 return cxstring::createRef("ObjCSelectorExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004226 case CXCursor_ObjCProtocolExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004227 return cxstring::createRef("ObjCProtocolExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004228 case CXCursor_ObjCBridgedCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004229 return cxstring::createRef("ObjCBridgedCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004230 case CXCursor_BlockExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004231 return cxstring::createRef("BlockExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004232 case CXCursor_PackExpansionExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004233 return cxstring::createRef("PackExpansionExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004234 case CXCursor_SizeOfPackExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004235 return cxstring::createRef("SizeOfPackExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004236 case CXCursor_LambdaExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004237 return cxstring::createRef("LambdaExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004238 case CXCursor_UnexposedExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004239 return cxstring::createRef("UnexposedExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004240 case CXCursor_DeclRefExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004241 return cxstring::createRef("DeclRefExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004242 case CXCursor_MemberRefExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004243 return cxstring::createRef("MemberRefExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004244 case CXCursor_CallExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004245 return cxstring::createRef("CallExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004246 case CXCursor_ObjCMessageExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004247 return cxstring::createRef("ObjCMessageExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004248 case CXCursor_UnexposedStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004249 return cxstring::createRef("UnexposedStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004250 case CXCursor_DeclStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004251 return cxstring::createRef("DeclStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004252 case CXCursor_LabelStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004253 return cxstring::createRef("LabelStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004254 case CXCursor_CompoundStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004255 return cxstring::createRef("CompoundStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004256 case CXCursor_CaseStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004257 return cxstring::createRef("CaseStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004258 case CXCursor_DefaultStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004259 return cxstring::createRef("DefaultStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004260 case CXCursor_IfStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004261 return cxstring::createRef("IfStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004262 case CXCursor_SwitchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004263 return cxstring::createRef("SwitchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004264 case CXCursor_WhileStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004265 return cxstring::createRef("WhileStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004266 case CXCursor_DoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004267 return cxstring::createRef("DoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004268 case CXCursor_ForStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004269 return cxstring::createRef("ForStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004270 case CXCursor_GotoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004271 return cxstring::createRef("GotoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004272 case CXCursor_IndirectGotoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004273 return cxstring::createRef("IndirectGotoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004274 case CXCursor_ContinueStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004275 return cxstring::createRef("ContinueStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004276 case CXCursor_BreakStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004277 return cxstring::createRef("BreakStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004278 case CXCursor_ReturnStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004279 return cxstring::createRef("ReturnStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004280 case CXCursor_GCCAsmStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004281 return cxstring::createRef("GCCAsmStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004282 case CXCursor_MSAsmStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004283 return cxstring::createRef("MSAsmStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004284 case CXCursor_ObjCAtTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004285 return cxstring::createRef("ObjCAtTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004286 case CXCursor_ObjCAtCatchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004287 return cxstring::createRef("ObjCAtCatchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004288 case CXCursor_ObjCAtFinallyStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004289 return cxstring::createRef("ObjCAtFinallyStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004290 case CXCursor_ObjCAtThrowStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004291 return cxstring::createRef("ObjCAtThrowStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004292 case CXCursor_ObjCAtSynchronizedStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004293 return cxstring::createRef("ObjCAtSynchronizedStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004294 case CXCursor_ObjCAutoreleasePoolStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004295 return cxstring::createRef("ObjCAutoreleasePoolStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004296 case CXCursor_ObjCForCollectionStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004297 return cxstring::createRef("ObjCForCollectionStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004298 case CXCursor_CXXCatchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004299 return cxstring::createRef("CXXCatchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004300 case CXCursor_CXXTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004301 return cxstring::createRef("CXXTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004302 case CXCursor_CXXForRangeStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004303 return cxstring::createRef("CXXForRangeStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004304 case CXCursor_SEHTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004305 return cxstring::createRef("SEHTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004306 case CXCursor_SEHExceptStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004307 return cxstring::createRef("SEHExceptStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004308 case CXCursor_SEHFinallyStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004309 return cxstring::createRef("SEHFinallyStmt");
Nico Weber9b982072014-07-07 00:12:30 +00004310 case CXCursor_SEHLeaveStmt:
4311 return cxstring::createRef("SEHLeaveStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004312 case CXCursor_NullStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004313 return cxstring::createRef("NullStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004314 case CXCursor_InvalidFile:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004315 return cxstring::createRef("InvalidFile");
Guy Benyei11169dd2012-12-18 14:30:41 +00004316 case CXCursor_InvalidCode:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004317 return cxstring::createRef("InvalidCode");
Guy Benyei11169dd2012-12-18 14:30:41 +00004318 case CXCursor_NoDeclFound:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004319 return cxstring::createRef("NoDeclFound");
Guy Benyei11169dd2012-12-18 14:30:41 +00004320 case CXCursor_NotImplemented:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004321 return cxstring::createRef("NotImplemented");
Guy Benyei11169dd2012-12-18 14:30:41 +00004322 case CXCursor_TranslationUnit:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004323 return cxstring::createRef("TranslationUnit");
Guy Benyei11169dd2012-12-18 14:30:41 +00004324 case CXCursor_UnexposedAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004325 return cxstring::createRef("UnexposedAttr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004326 case CXCursor_IBActionAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004327 return cxstring::createRef("attribute(ibaction)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004328 case CXCursor_IBOutletAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004329 return cxstring::createRef("attribute(iboutlet)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004330 case CXCursor_IBOutletCollectionAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004331 return cxstring::createRef("attribute(iboutletcollection)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004332 case CXCursor_CXXFinalAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004333 return cxstring::createRef("attribute(final)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004334 case CXCursor_CXXOverrideAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004335 return cxstring::createRef("attribute(override)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004336 case CXCursor_AnnotateAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004337 return cxstring::createRef("attribute(annotate)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004338 case CXCursor_AsmLabelAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004339 return cxstring::createRef("asm label");
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00004340 case CXCursor_PackedAttr:
4341 return cxstring::createRef("attribute(packed)");
Joey Gouly81228382014-05-01 15:41:58 +00004342 case CXCursor_PureAttr:
4343 return cxstring::createRef("attribute(pure)");
4344 case CXCursor_ConstAttr:
4345 return cxstring::createRef("attribute(const)");
4346 case CXCursor_NoDuplicateAttr:
4347 return cxstring::createRef("attribute(noduplicate)");
Eli Bendersky2581e662014-05-28 19:29:58 +00004348 case CXCursor_CUDAConstantAttr:
4349 return cxstring::createRef("attribute(constant)");
4350 case CXCursor_CUDADeviceAttr:
4351 return cxstring::createRef("attribute(device)");
4352 case CXCursor_CUDAGlobalAttr:
4353 return cxstring::createRef("attribute(global)");
4354 case CXCursor_CUDAHostAttr:
4355 return cxstring::createRef("attribute(host)");
Eli Bendersky9b071472014-08-08 14:59:00 +00004356 case CXCursor_CUDASharedAttr:
4357 return cxstring::createRef("attribute(shared)");
Saleem Abdulrasool79c69712015-09-05 18:53:43 +00004358 case CXCursor_VisibilityAttr:
4359 return cxstring::createRef("attribute(visibility)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004360 case CXCursor_PreprocessingDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004361 return cxstring::createRef("preprocessing directive");
Guy Benyei11169dd2012-12-18 14:30:41 +00004362 case CXCursor_MacroDefinition:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004363 return cxstring::createRef("macro definition");
Guy Benyei11169dd2012-12-18 14:30:41 +00004364 case CXCursor_MacroExpansion:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004365 return cxstring::createRef("macro expansion");
Guy Benyei11169dd2012-12-18 14:30:41 +00004366 case CXCursor_InclusionDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004367 return cxstring::createRef("inclusion directive");
Guy Benyei11169dd2012-12-18 14:30:41 +00004368 case CXCursor_Namespace:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004369 return cxstring::createRef("Namespace");
Guy Benyei11169dd2012-12-18 14:30:41 +00004370 case CXCursor_LinkageSpec:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004371 return cxstring::createRef("LinkageSpec");
Guy Benyei11169dd2012-12-18 14:30:41 +00004372 case CXCursor_CXXBaseSpecifier:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004373 return cxstring::createRef("C++ base class specifier");
Guy Benyei11169dd2012-12-18 14:30:41 +00004374 case CXCursor_Constructor:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004375 return cxstring::createRef("CXXConstructor");
Guy Benyei11169dd2012-12-18 14:30:41 +00004376 case CXCursor_Destructor:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004377 return cxstring::createRef("CXXDestructor");
Guy Benyei11169dd2012-12-18 14:30:41 +00004378 case CXCursor_ConversionFunction:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004379 return cxstring::createRef("CXXConversion");
Guy Benyei11169dd2012-12-18 14:30:41 +00004380 case CXCursor_TemplateTypeParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004381 return cxstring::createRef("TemplateTypeParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00004382 case CXCursor_NonTypeTemplateParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004383 return cxstring::createRef("NonTypeTemplateParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00004384 case CXCursor_TemplateTemplateParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004385 return cxstring::createRef("TemplateTemplateParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00004386 case CXCursor_FunctionTemplate:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004387 return cxstring::createRef("FunctionTemplate");
Guy Benyei11169dd2012-12-18 14:30:41 +00004388 case CXCursor_ClassTemplate:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004389 return cxstring::createRef("ClassTemplate");
Guy Benyei11169dd2012-12-18 14:30:41 +00004390 case CXCursor_ClassTemplatePartialSpecialization:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004391 return cxstring::createRef("ClassTemplatePartialSpecialization");
Guy Benyei11169dd2012-12-18 14:30:41 +00004392 case CXCursor_NamespaceAlias:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004393 return cxstring::createRef("NamespaceAlias");
Guy Benyei11169dd2012-12-18 14:30:41 +00004394 case CXCursor_UsingDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004395 return cxstring::createRef("UsingDirective");
Guy Benyei11169dd2012-12-18 14:30:41 +00004396 case CXCursor_UsingDeclaration:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004397 return cxstring::createRef("UsingDeclaration");
Guy Benyei11169dd2012-12-18 14:30:41 +00004398 case CXCursor_TypeAliasDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004399 return cxstring::createRef("TypeAliasDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004400 case CXCursor_ObjCSynthesizeDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004401 return cxstring::createRef("ObjCSynthesizeDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004402 case CXCursor_ObjCDynamicDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004403 return cxstring::createRef("ObjCDynamicDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004404 case CXCursor_CXXAccessSpecifier:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004405 return cxstring::createRef("CXXAccessSpecifier");
Guy Benyei11169dd2012-12-18 14:30:41 +00004406 case CXCursor_ModuleImportDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004407 return cxstring::createRef("ModuleImport");
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00004408 case CXCursor_OMPParallelDirective:
Alexey Bataev1b59ab52014-02-27 08:29:12 +00004409 return cxstring::createRef("OMPParallelDirective");
4410 case CXCursor_OMPSimdDirective:
4411 return cxstring::createRef("OMPSimdDirective");
Alexey Bataevf29276e2014-06-18 04:14:57 +00004412 case CXCursor_OMPForDirective:
4413 return cxstring::createRef("OMPForDirective");
Alexander Musmanf82886e2014-09-18 05:12:34 +00004414 case CXCursor_OMPForSimdDirective:
4415 return cxstring::createRef("OMPForSimdDirective");
Alexey Bataevd3f8dd22014-06-25 11:44:49 +00004416 case CXCursor_OMPSectionsDirective:
4417 return cxstring::createRef("OMPSectionsDirective");
Alexey Bataev1e0498a2014-06-26 08:21:58 +00004418 case CXCursor_OMPSectionDirective:
4419 return cxstring::createRef("OMPSectionDirective");
Alexey Bataevd1e40fb2014-06-26 12:05:45 +00004420 case CXCursor_OMPSingleDirective:
4421 return cxstring::createRef("OMPSingleDirective");
Alexander Musman80c22892014-07-17 08:54:58 +00004422 case CXCursor_OMPMasterDirective:
4423 return cxstring::createRef("OMPMasterDirective");
Alexander Musmand9ed09f2014-07-21 09:42:05 +00004424 case CXCursor_OMPCriticalDirective:
4425 return cxstring::createRef("OMPCriticalDirective");
Alexey Bataev4acb8592014-07-07 13:01:15 +00004426 case CXCursor_OMPParallelForDirective:
4427 return cxstring::createRef("OMPParallelForDirective");
Alexander Musmane4e893b2014-09-23 09:33:00 +00004428 case CXCursor_OMPParallelForSimdDirective:
4429 return cxstring::createRef("OMPParallelForSimdDirective");
Alexey Bataev84d0b3e2014-07-08 08:12:03 +00004430 case CXCursor_OMPParallelSectionsDirective:
4431 return cxstring::createRef("OMPParallelSectionsDirective");
Alexey Bataev9c2e8ee2014-07-11 11:25:16 +00004432 case CXCursor_OMPTaskDirective:
4433 return cxstring::createRef("OMPTaskDirective");
Alexey Bataev68446b72014-07-18 07:47:19 +00004434 case CXCursor_OMPTaskyieldDirective:
4435 return cxstring::createRef("OMPTaskyieldDirective");
Alexey Bataev4d1dfea2014-07-18 09:11:51 +00004436 case CXCursor_OMPBarrierDirective:
4437 return cxstring::createRef("OMPBarrierDirective");
Alexey Bataev2df347a2014-07-18 10:17:07 +00004438 case CXCursor_OMPTaskwaitDirective:
4439 return cxstring::createRef("OMPTaskwaitDirective");
Alexey Bataevc30dd2d2015-06-18 12:14:09 +00004440 case CXCursor_OMPTaskgroupDirective:
4441 return cxstring::createRef("OMPTaskgroupDirective");
Alexey Bataev6125da92014-07-21 11:26:11 +00004442 case CXCursor_OMPFlushDirective:
4443 return cxstring::createRef("OMPFlushDirective");
Alexey Bataev9fb6e642014-07-22 06:45:04 +00004444 case CXCursor_OMPOrderedDirective:
4445 return cxstring::createRef("OMPOrderedDirective");
Alexey Bataev0162e452014-07-22 10:10:35 +00004446 case CXCursor_OMPAtomicDirective:
4447 return cxstring::createRef("OMPAtomicDirective");
Alexey Bataev0bd520b2014-09-19 08:19:49 +00004448 case CXCursor_OMPTargetDirective:
4449 return cxstring::createRef("OMPTargetDirective");
Michael Wong65f367f2015-07-21 13:44:28 +00004450 case CXCursor_OMPTargetDataDirective:
4451 return cxstring::createRef("OMPTargetDataDirective");
Alexey Bataev13314bf2014-10-09 04:18:56 +00004452 case CXCursor_OMPTeamsDirective:
4453 return cxstring::createRef("OMPTeamsDirective");
Alexey Bataev6d4ed052015-07-01 06:57:41 +00004454 case CXCursor_OMPCancellationPointDirective:
4455 return cxstring::createRef("OMPCancellationPointDirective");
Alexey Bataev80909872015-07-02 11:25:17 +00004456 case CXCursor_OMPCancelDirective:
4457 return cxstring::createRef("OMPCancelDirective");
Francisco Lopes da Silva975a9f62015-01-21 16:24:11 +00004458 case CXCursor_OverloadCandidate:
4459 return cxstring::createRef("OverloadCandidate");
Sergey Kalinichev8f3b1872015-11-15 13:48:32 +00004460 case CXCursor_TypeAliasTemplateDecl:
4461 return cxstring::createRef("TypeAliasTemplateDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004462 }
4463
4464 llvm_unreachable("Unhandled CXCursorKind");
4465}
4466
4467struct GetCursorData {
4468 SourceLocation TokenBeginLoc;
4469 bool PointsAtMacroArgExpansion;
4470 bool VisitedObjCPropertyImplDecl;
4471 SourceLocation VisitedDeclaratorDeclStartLoc;
4472 CXCursor &BestCursor;
4473
4474 GetCursorData(SourceManager &SM,
4475 SourceLocation tokenBegin, CXCursor &outputCursor)
4476 : TokenBeginLoc(tokenBegin), BestCursor(outputCursor) {
4477 PointsAtMacroArgExpansion = SM.isMacroArgExpansion(tokenBegin);
4478 VisitedObjCPropertyImplDecl = false;
4479 }
4480};
4481
4482static enum CXChildVisitResult GetCursorVisitor(CXCursor cursor,
4483 CXCursor parent,
4484 CXClientData client_data) {
4485 GetCursorData *Data = static_cast<GetCursorData *>(client_data);
4486 CXCursor *BestCursor = &Data->BestCursor;
4487
4488 // If we point inside a macro argument we should provide info of what the
4489 // token is so use the actual cursor, don't replace it with a macro expansion
4490 // cursor.
4491 if (cursor.kind == CXCursor_MacroExpansion && Data->PointsAtMacroArgExpansion)
4492 return CXChildVisit_Recurse;
4493
4494 if (clang_isDeclaration(cursor.kind)) {
4495 // Avoid having the implicit methods override the property decls.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004496 if (const ObjCMethodDecl *MD
Guy Benyei11169dd2012-12-18 14:30:41 +00004497 = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
4498 if (MD->isImplicit())
4499 return CXChildVisit_Break;
4500
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004501 } else if (const ObjCInterfaceDecl *ID
Guy Benyei11169dd2012-12-18 14:30:41 +00004502 = dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(cursor))) {
4503 // Check that when we have multiple @class references in the same line,
4504 // that later ones do not override the previous ones.
4505 // If we have:
4506 // @class Foo, Bar;
4507 // source ranges for both start at '@', so 'Bar' will end up overriding
4508 // 'Foo' even though the cursor location was at 'Foo'.
4509 if (BestCursor->kind == CXCursor_ObjCInterfaceDecl ||
4510 BestCursor->kind == CXCursor_ObjCClassRef)
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004511 if (const ObjCInterfaceDecl *PrevID
Guy Benyei11169dd2012-12-18 14:30:41 +00004512 = dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(*BestCursor))){
4513 if (PrevID != ID &&
4514 !PrevID->isThisDeclarationADefinition() &&
4515 !ID->isThisDeclarationADefinition())
4516 return CXChildVisit_Break;
4517 }
4518
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004519 } else if (const DeclaratorDecl *DD
Guy Benyei11169dd2012-12-18 14:30:41 +00004520 = dyn_cast_or_null<DeclaratorDecl>(getCursorDecl(cursor))) {
4521 SourceLocation StartLoc = DD->getSourceRange().getBegin();
4522 // Check that when we have multiple declarators in the same line,
4523 // that later ones do not override the previous ones.
4524 // If we have:
4525 // int Foo, Bar;
4526 // source ranges for both start at 'int', so 'Bar' will end up overriding
4527 // 'Foo' even though the cursor location was at 'Foo'.
4528 if (Data->VisitedDeclaratorDeclStartLoc == StartLoc)
4529 return CXChildVisit_Break;
4530 Data->VisitedDeclaratorDeclStartLoc = StartLoc;
4531
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004532 } else if (const ObjCPropertyImplDecl *PropImp
Guy Benyei11169dd2012-12-18 14:30:41 +00004533 = dyn_cast_or_null<ObjCPropertyImplDecl>(getCursorDecl(cursor))) {
4534 (void)PropImp;
4535 // Check that when we have multiple @synthesize in the same line,
4536 // that later ones do not override the previous ones.
4537 // If we have:
4538 // @synthesize Foo, Bar;
4539 // source ranges for both start at '@', so 'Bar' will end up overriding
4540 // 'Foo' even though the cursor location was at 'Foo'.
4541 if (Data->VisitedObjCPropertyImplDecl)
4542 return CXChildVisit_Break;
4543 Data->VisitedObjCPropertyImplDecl = true;
4544 }
4545 }
4546
4547 if (clang_isExpression(cursor.kind) &&
4548 clang_isDeclaration(BestCursor->kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004549 if (const Decl *D = getCursorDecl(*BestCursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004550 // Avoid having the cursor of an expression replace the declaration cursor
4551 // when the expression source range overlaps the declaration range.
4552 // This can happen for C++ constructor expressions whose range generally
4553 // include the variable declaration, e.g.:
4554 // MyCXXClass foo; // Make sure pointing at 'foo' returns a VarDecl cursor.
4555 if (D->getLocation().isValid() && Data->TokenBeginLoc.isValid() &&
4556 D->getLocation() == Data->TokenBeginLoc)
4557 return CXChildVisit_Break;
4558 }
4559 }
4560
4561 // If our current best cursor is the construction of a temporary object,
4562 // don't replace that cursor with a type reference, because we want
4563 // clang_getCursor() to point at the constructor.
4564 if (clang_isExpression(BestCursor->kind) &&
4565 isa<CXXTemporaryObjectExpr>(getCursorExpr(*BestCursor)) &&
4566 cursor.kind == CXCursor_TypeRef) {
4567 // Keep the cursor pointing at CXXTemporaryObjectExpr but also mark it
4568 // as having the actual point on the type reference.
4569 *BestCursor = getTypeRefedCallExprCursor(*BestCursor);
4570 return CXChildVisit_Recurse;
4571 }
Douglas Gregore9d95f12015-07-07 03:57:35 +00004572
4573 // If we already have an Objective-C superclass reference, don't
4574 // update it further.
4575 if (BestCursor->kind == CXCursor_ObjCSuperClassRef)
4576 return CXChildVisit_Break;
4577
Guy Benyei11169dd2012-12-18 14:30:41 +00004578 *BestCursor = cursor;
4579 return CXChildVisit_Recurse;
4580}
4581
4582CXCursor clang_getCursor(CXTranslationUnit TU, CXSourceLocation Loc) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00004583 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004584 LOG_BAD_TU(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004585 return clang_getNullCursor();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004586 }
Guy Benyei11169dd2012-12-18 14:30:41 +00004587
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004588 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004589 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
4590
4591 SourceLocation SLoc = cxloc::translateSourceLocation(Loc);
4592 CXCursor Result = cxcursor::getCursor(TU, SLoc);
4593
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004594 LOG_FUNC_SECTION {
Guy Benyei11169dd2012-12-18 14:30:41 +00004595 CXFile SearchFile;
4596 unsigned SearchLine, SearchColumn;
4597 CXFile ResultFile;
4598 unsigned ResultLine, ResultColumn;
4599 CXString SearchFileName, ResultFileName, KindSpelling, USR;
4600 const char *IsDef = clang_isCursorDefinition(Result)? " (Definition)" : "";
4601 CXSourceLocation ResultLoc = clang_getCursorLocation(Result);
Craig Topper69186e72014-06-08 08:38:04 +00004602
4603 clang_getFileLocation(Loc, &SearchFile, &SearchLine, &SearchColumn,
4604 nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004605 clang_getFileLocation(ResultLoc, &ResultFile, &ResultLine,
Craig Topper69186e72014-06-08 08:38:04 +00004606 &ResultColumn, nullptr);
Guy Benyei11169dd2012-12-18 14:30:41 +00004607 SearchFileName = clang_getFileName(SearchFile);
4608 ResultFileName = clang_getFileName(ResultFile);
4609 KindSpelling = clang_getCursorKindSpelling(Result.kind);
4610 USR = clang_getCursorUSR(Result);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004611 *Log << llvm::format("(%s:%d:%d) = %s",
4612 clang_getCString(SearchFileName), SearchLine, SearchColumn,
4613 clang_getCString(KindSpelling))
4614 << llvm::format("(%s:%d:%d):%s%s",
4615 clang_getCString(ResultFileName), ResultLine, ResultColumn,
4616 clang_getCString(USR), IsDef);
Guy Benyei11169dd2012-12-18 14:30:41 +00004617 clang_disposeString(SearchFileName);
4618 clang_disposeString(ResultFileName);
4619 clang_disposeString(KindSpelling);
4620 clang_disposeString(USR);
4621
4622 CXCursor Definition = clang_getCursorDefinition(Result);
4623 if (!clang_equalCursors(Definition, clang_getNullCursor())) {
4624 CXSourceLocation DefinitionLoc = clang_getCursorLocation(Definition);
4625 CXString DefinitionKindSpelling
4626 = clang_getCursorKindSpelling(Definition.kind);
4627 CXFile DefinitionFile;
4628 unsigned DefinitionLine, DefinitionColumn;
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004629 clang_getFileLocation(DefinitionLoc, &DefinitionFile,
Craig Topper69186e72014-06-08 08:38:04 +00004630 &DefinitionLine, &DefinitionColumn, nullptr);
Guy Benyei11169dd2012-12-18 14:30:41 +00004631 CXString DefinitionFileName = clang_getFileName(DefinitionFile);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004632 *Log << llvm::format(" -> %s(%s:%d:%d)",
4633 clang_getCString(DefinitionKindSpelling),
4634 clang_getCString(DefinitionFileName),
4635 DefinitionLine, DefinitionColumn);
Guy Benyei11169dd2012-12-18 14:30:41 +00004636 clang_disposeString(DefinitionFileName);
4637 clang_disposeString(DefinitionKindSpelling);
4638 }
4639 }
4640
4641 return Result;
4642}
4643
4644CXCursor clang_getNullCursor(void) {
4645 return MakeCXCursorInvalid(CXCursor_InvalidFile);
4646}
4647
4648unsigned clang_equalCursors(CXCursor X, CXCursor Y) {
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00004649 // Clear out the "FirstInDeclGroup" part in a declaration cursor, since we
4650 // can't set consistently. For example, when visiting a DeclStmt we will set
4651 // it but we don't set it on the result of clang_getCursorDefinition for
4652 // a reference of the same declaration.
4653 // FIXME: Setting "FirstInDeclGroup" in CXCursors is a hack that only works
4654 // when visiting a DeclStmt currently, the AST should be enhanced to be able
4655 // to provide that kind of info.
4656 if (clang_isDeclaration(X.kind))
Craig Topper69186e72014-06-08 08:38:04 +00004657 X.data[1] = nullptr;
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00004658 if (clang_isDeclaration(Y.kind))
Craig Topper69186e72014-06-08 08:38:04 +00004659 Y.data[1] = nullptr;
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00004660
Guy Benyei11169dd2012-12-18 14:30:41 +00004661 return X == Y;
4662}
4663
4664unsigned clang_hashCursor(CXCursor C) {
4665 unsigned Index = 0;
4666 if (clang_isExpression(C.kind) || clang_isStatement(C.kind))
4667 Index = 1;
4668
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004669 return llvm::DenseMapInfo<std::pair<unsigned, const void*> >::getHashValue(
Guy Benyei11169dd2012-12-18 14:30:41 +00004670 std::make_pair(C.kind, C.data[Index]));
4671}
4672
4673unsigned clang_isInvalid(enum CXCursorKind K) {
4674 return K >= CXCursor_FirstInvalid && K <= CXCursor_LastInvalid;
4675}
4676
4677unsigned clang_isDeclaration(enum CXCursorKind K) {
4678 return (K >= CXCursor_FirstDecl && K <= CXCursor_LastDecl) ||
4679 (K >= CXCursor_FirstExtraDecl && K <= CXCursor_LastExtraDecl);
4680}
4681
4682unsigned clang_isReference(enum CXCursorKind K) {
4683 return K >= CXCursor_FirstRef && K <= CXCursor_LastRef;
4684}
4685
4686unsigned clang_isExpression(enum CXCursorKind K) {
4687 return K >= CXCursor_FirstExpr && K <= CXCursor_LastExpr;
4688}
4689
4690unsigned clang_isStatement(enum CXCursorKind K) {
4691 return K >= CXCursor_FirstStmt && K <= CXCursor_LastStmt;
4692}
4693
4694unsigned clang_isAttribute(enum CXCursorKind K) {
4695 return K >= CXCursor_FirstAttr && K <= CXCursor_LastAttr;
4696}
4697
4698unsigned clang_isTranslationUnit(enum CXCursorKind K) {
4699 return K == CXCursor_TranslationUnit;
4700}
4701
4702unsigned clang_isPreprocessing(enum CXCursorKind K) {
4703 return K >= CXCursor_FirstPreprocessing && K <= CXCursor_LastPreprocessing;
4704}
4705
4706unsigned clang_isUnexposed(enum CXCursorKind K) {
4707 switch (K) {
4708 case CXCursor_UnexposedDecl:
4709 case CXCursor_UnexposedExpr:
4710 case CXCursor_UnexposedStmt:
4711 case CXCursor_UnexposedAttr:
4712 return true;
4713 default:
4714 return false;
4715 }
4716}
4717
4718CXCursorKind clang_getCursorKind(CXCursor C) {
4719 return C.kind;
4720}
4721
4722CXSourceLocation clang_getCursorLocation(CXCursor C) {
4723 if (clang_isReference(C.kind)) {
4724 switch (C.kind) {
4725 case CXCursor_ObjCSuperClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004726 std::pair<const ObjCInterfaceDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004727 = getCursorObjCSuperClassRef(C);
4728 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4729 }
4730
4731 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004732 std::pair<const ObjCProtocolDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004733 = getCursorObjCProtocolRef(C);
4734 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4735 }
4736
4737 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004738 std::pair<const ObjCInterfaceDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004739 = getCursorObjCClassRef(C);
4740 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4741 }
4742
4743 case CXCursor_TypeRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004744 std::pair<const TypeDecl *, SourceLocation> P = getCursorTypeRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004745 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4746 }
4747
4748 case CXCursor_TemplateRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004749 std::pair<const TemplateDecl *, SourceLocation> P =
4750 getCursorTemplateRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004751 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4752 }
4753
4754 case CXCursor_NamespaceRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004755 std::pair<const NamedDecl *, SourceLocation> P = getCursorNamespaceRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004756 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4757 }
4758
4759 case CXCursor_MemberRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004760 std::pair<const FieldDecl *, SourceLocation> P = getCursorMemberRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004761 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4762 }
4763
4764 case CXCursor_VariableRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004765 std::pair<const VarDecl *, SourceLocation> P = getCursorVariableRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004766 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4767 }
4768
4769 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004770 const CXXBaseSpecifier *BaseSpec = getCursorCXXBaseSpecifier(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004771 if (!BaseSpec)
4772 return clang_getNullLocation();
4773
4774 if (TypeSourceInfo *TSInfo = BaseSpec->getTypeSourceInfo())
4775 return cxloc::translateSourceLocation(getCursorContext(C),
4776 TSInfo->getTypeLoc().getBeginLoc());
4777
4778 return cxloc::translateSourceLocation(getCursorContext(C),
4779 BaseSpec->getLocStart());
4780 }
4781
4782 case CXCursor_LabelRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004783 std::pair<const LabelStmt *, SourceLocation> P = getCursorLabelRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004784 return cxloc::translateSourceLocation(getCursorContext(C), P.second);
4785 }
4786
4787 case CXCursor_OverloadedDeclRef:
4788 return cxloc::translateSourceLocation(getCursorContext(C),
4789 getCursorOverloadedDeclRef(C).second);
4790
4791 default:
4792 // FIXME: Need a way to enumerate all non-reference cases.
4793 llvm_unreachable("Missed a reference kind");
4794 }
4795 }
4796
4797 if (clang_isExpression(C.kind))
4798 return cxloc::translateSourceLocation(getCursorContext(C),
4799 getLocationFromExpr(getCursorExpr(C)));
4800
4801 if (clang_isStatement(C.kind))
4802 return cxloc::translateSourceLocation(getCursorContext(C),
4803 getCursorStmt(C)->getLocStart());
4804
4805 if (C.kind == CXCursor_PreprocessingDirective) {
4806 SourceLocation L = cxcursor::getCursorPreprocessingDirective(C).getBegin();
4807 return cxloc::translateSourceLocation(getCursorContext(C), L);
4808 }
4809
4810 if (C.kind == CXCursor_MacroExpansion) {
4811 SourceLocation L
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00004812 = cxcursor::getCursorMacroExpansion(C).getSourceRange().getBegin();
Guy Benyei11169dd2012-12-18 14:30:41 +00004813 return cxloc::translateSourceLocation(getCursorContext(C), L);
4814 }
4815
4816 if (C.kind == CXCursor_MacroDefinition) {
4817 SourceLocation L = cxcursor::getCursorMacroDefinition(C)->getLocation();
4818 return cxloc::translateSourceLocation(getCursorContext(C), L);
4819 }
4820
4821 if (C.kind == CXCursor_InclusionDirective) {
4822 SourceLocation L
4823 = cxcursor::getCursorInclusionDirective(C)->getSourceRange().getBegin();
4824 return cxloc::translateSourceLocation(getCursorContext(C), L);
4825 }
4826
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00004827 if (clang_isAttribute(C.kind)) {
4828 SourceLocation L
4829 = cxcursor::getCursorAttr(C)->getLocation();
4830 return cxloc::translateSourceLocation(getCursorContext(C), L);
4831 }
4832
Guy Benyei11169dd2012-12-18 14:30:41 +00004833 if (!clang_isDeclaration(C.kind))
4834 return clang_getNullLocation();
4835
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004836 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004837 if (!D)
4838 return clang_getNullLocation();
4839
4840 SourceLocation Loc = D->getLocation();
4841 // FIXME: Multiple variables declared in a single declaration
4842 // currently lack the information needed to correctly determine their
4843 // ranges when accounting for the type-specifier. We use context
4844 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4845 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004846 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004847 if (!cxcursor::isFirstInDeclGroup(C))
4848 Loc = VD->getLocation();
4849 }
4850
4851 // For ObjC methods, give the start location of the method name.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004852 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004853 Loc = MD->getSelectorStartLoc();
4854
4855 return cxloc::translateSourceLocation(getCursorContext(C), Loc);
4856}
4857
4858} // end extern "C"
4859
4860CXCursor cxcursor::getCursor(CXTranslationUnit TU, SourceLocation SLoc) {
4861 assert(TU);
4862
4863 // Guard against an invalid SourceLocation, or we may assert in one
4864 // of the following calls.
4865 if (SLoc.isInvalid())
4866 return clang_getNullCursor();
4867
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004868 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004869
4870 // Translate the given source location to make it point at the beginning of
4871 // the token under the cursor.
4872 SLoc = Lexer::GetBeginningOfToken(SLoc, CXXUnit->getSourceManager(),
4873 CXXUnit->getASTContext().getLangOpts());
4874
4875 CXCursor Result = MakeCXCursorInvalid(CXCursor_NoDeclFound);
4876 if (SLoc.isValid()) {
4877 GetCursorData ResultData(CXXUnit->getSourceManager(), SLoc, Result);
4878 CursorVisitor CursorVis(TU, GetCursorVisitor, &ResultData,
4879 /*VisitPreprocessorLast=*/true,
4880 /*VisitIncludedEntities=*/false,
4881 SourceLocation(SLoc));
4882 CursorVis.visitFileRegion();
4883 }
4884
4885 return Result;
4886}
4887
4888static SourceRange getRawCursorExtent(CXCursor C) {
4889 if (clang_isReference(C.kind)) {
4890 switch (C.kind) {
4891 case CXCursor_ObjCSuperClassRef:
4892 return getCursorObjCSuperClassRef(C).second;
4893
4894 case CXCursor_ObjCProtocolRef:
4895 return getCursorObjCProtocolRef(C).second;
4896
4897 case CXCursor_ObjCClassRef:
4898 return getCursorObjCClassRef(C).second;
4899
4900 case CXCursor_TypeRef:
4901 return getCursorTypeRef(C).second;
4902
4903 case CXCursor_TemplateRef:
4904 return getCursorTemplateRef(C).second;
4905
4906 case CXCursor_NamespaceRef:
4907 return getCursorNamespaceRef(C).second;
4908
4909 case CXCursor_MemberRef:
4910 return getCursorMemberRef(C).second;
4911
4912 case CXCursor_CXXBaseSpecifier:
4913 return getCursorCXXBaseSpecifier(C)->getSourceRange();
4914
4915 case CXCursor_LabelRef:
4916 return getCursorLabelRef(C).second;
4917
4918 case CXCursor_OverloadedDeclRef:
4919 return getCursorOverloadedDeclRef(C).second;
4920
4921 case CXCursor_VariableRef:
4922 return getCursorVariableRef(C).second;
4923
4924 default:
4925 // FIXME: Need a way to enumerate all non-reference cases.
4926 llvm_unreachable("Missed a reference kind");
4927 }
4928 }
4929
4930 if (clang_isExpression(C.kind))
4931 return getCursorExpr(C)->getSourceRange();
4932
4933 if (clang_isStatement(C.kind))
4934 return getCursorStmt(C)->getSourceRange();
4935
4936 if (clang_isAttribute(C.kind))
4937 return getCursorAttr(C)->getRange();
4938
4939 if (C.kind == CXCursor_PreprocessingDirective)
4940 return cxcursor::getCursorPreprocessingDirective(C);
4941
4942 if (C.kind == CXCursor_MacroExpansion) {
4943 ASTUnit *TU = getCursorASTUnit(C);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00004944 SourceRange Range = cxcursor::getCursorMacroExpansion(C).getSourceRange();
Guy Benyei11169dd2012-12-18 14:30:41 +00004945 return TU->mapRangeFromPreamble(Range);
4946 }
4947
4948 if (C.kind == CXCursor_MacroDefinition) {
4949 ASTUnit *TU = getCursorASTUnit(C);
4950 SourceRange Range = cxcursor::getCursorMacroDefinition(C)->getSourceRange();
4951 return TU->mapRangeFromPreamble(Range);
4952 }
4953
4954 if (C.kind == CXCursor_InclusionDirective) {
4955 ASTUnit *TU = getCursorASTUnit(C);
4956 SourceRange Range = cxcursor::getCursorInclusionDirective(C)->getSourceRange();
4957 return TU->mapRangeFromPreamble(Range);
4958 }
4959
4960 if (C.kind == CXCursor_TranslationUnit) {
4961 ASTUnit *TU = getCursorASTUnit(C);
4962 FileID MainID = TU->getSourceManager().getMainFileID();
4963 SourceLocation Start = TU->getSourceManager().getLocForStartOfFile(MainID);
4964 SourceLocation End = TU->getSourceManager().getLocForEndOfFile(MainID);
4965 return SourceRange(Start, End);
4966 }
4967
4968 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004969 const Decl *D = cxcursor::getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004970 if (!D)
4971 return SourceRange();
4972
4973 SourceRange R = D->getSourceRange();
4974 // FIXME: Multiple variables declared in a single declaration
4975 // currently lack the information needed to correctly determine their
4976 // ranges when accounting for the type-specifier. We use context
4977 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4978 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004979 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004980 if (!cxcursor::isFirstInDeclGroup(C))
4981 R.setBegin(VD->getLocation());
4982 }
4983 return R;
4984 }
4985 return SourceRange();
4986}
4987
4988/// \brief Retrieves the "raw" cursor extent, which is then extended to include
4989/// the decl-specifier-seq for declarations.
4990static SourceRange getFullCursorExtent(CXCursor C, SourceManager &SrcMgr) {
4991 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004992 const Decl *D = cxcursor::getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004993 if (!D)
4994 return SourceRange();
4995
4996 SourceRange R = D->getSourceRange();
4997
4998 // Adjust the start of the location for declarations preceded by
4999 // declaration specifiers.
5000 SourceLocation StartLoc;
5001 if (const DeclaratorDecl *DD = dyn_cast<DeclaratorDecl>(D)) {
5002 if (TypeSourceInfo *TI = DD->getTypeSourceInfo())
5003 StartLoc = TI->getTypeLoc().getLocStart();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005004 } else if (const TypedefDecl *Typedef = dyn_cast<TypedefDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005005 if (TypeSourceInfo *TI = Typedef->getTypeSourceInfo())
5006 StartLoc = TI->getTypeLoc().getLocStart();
5007 }
5008
5009 if (StartLoc.isValid() && R.getBegin().isValid() &&
5010 SrcMgr.isBeforeInTranslationUnit(StartLoc, R.getBegin()))
5011 R.setBegin(StartLoc);
5012
5013 // FIXME: Multiple variables declared in a single declaration
5014 // currently lack the information needed to correctly determine their
5015 // ranges when accounting for the type-specifier. We use context
5016 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
5017 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005018 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005019 if (!cxcursor::isFirstInDeclGroup(C))
5020 R.setBegin(VD->getLocation());
5021 }
5022
5023 return R;
5024 }
5025
5026 return getRawCursorExtent(C);
5027}
5028
5029extern "C" {
5030
5031CXSourceRange clang_getCursorExtent(CXCursor C) {
5032 SourceRange R = getRawCursorExtent(C);
5033 if (R.isInvalid())
5034 return clang_getNullRange();
5035
5036 return cxloc::translateSourceRange(getCursorContext(C), R);
5037}
5038
5039CXCursor clang_getCursorReferenced(CXCursor C) {
5040 if (clang_isInvalid(C.kind))
5041 return clang_getNullCursor();
5042
5043 CXTranslationUnit tu = getCursorTU(C);
5044 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005045 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005046 if (!D)
5047 return clang_getNullCursor();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005048 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00005049 return MakeCursorOverloadedDeclRef(Using, D->getLocation(), tu);
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005050 if (const ObjCPropertyImplDecl *PropImpl =
5051 dyn_cast<ObjCPropertyImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00005052 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
5053 return MakeCXCursor(Property, tu);
5054
5055 return C;
5056 }
5057
5058 if (clang_isExpression(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005059 const Expr *E = getCursorExpr(C);
5060 const Decl *D = getDeclFromExpr(E);
Guy Benyei11169dd2012-12-18 14:30:41 +00005061 if (D) {
5062 CXCursor declCursor = MakeCXCursor(D, tu);
5063 declCursor = getSelectorIdentifierCursor(getSelectorIdentifierIndex(C),
5064 declCursor);
5065 return declCursor;
5066 }
5067
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005068 if (const OverloadExpr *Ovl = dyn_cast_or_null<OverloadExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00005069 return MakeCursorOverloadedDeclRef(Ovl, tu);
5070
5071 return clang_getNullCursor();
5072 }
5073
5074 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005075 const Stmt *S = getCursorStmt(C);
5076 if (const GotoStmt *Goto = dyn_cast_or_null<GotoStmt>(S))
Guy Benyei11169dd2012-12-18 14:30:41 +00005077 if (LabelDecl *label = Goto->getLabel())
5078 if (LabelStmt *labelS = label->getStmt())
5079 return MakeCXCursor(labelS, getCursorDecl(C), tu);
5080
5081 return clang_getNullCursor();
5082 }
Richard Smith66a81862015-05-04 02:25:31 +00005083
Guy Benyei11169dd2012-12-18 14:30:41 +00005084 if (C.kind == CXCursor_MacroExpansion) {
Richard Smith66a81862015-05-04 02:25:31 +00005085 if (const MacroDefinitionRecord *Def =
5086 getCursorMacroExpansion(C).getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005087 return MakeMacroDefinitionCursor(Def, tu);
5088 }
5089
5090 if (!clang_isReference(C.kind))
5091 return clang_getNullCursor();
5092
5093 switch (C.kind) {
5094 case CXCursor_ObjCSuperClassRef:
5095 return MakeCXCursor(getCursorObjCSuperClassRef(C).first, tu);
5096
5097 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005098 const ObjCProtocolDecl *Prot = getCursorObjCProtocolRef(C).first;
5099 if (const ObjCProtocolDecl *Def = Prot->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005100 return MakeCXCursor(Def, tu);
5101
5102 return MakeCXCursor(Prot, tu);
5103 }
5104
5105 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005106 const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
5107 if (const ObjCInterfaceDecl *Def = Class->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005108 return MakeCXCursor(Def, tu);
5109
5110 return MakeCXCursor(Class, tu);
5111 }
5112
5113 case CXCursor_TypeRef:
5114 return MakeCXCursor(getCursorTypeRef(C).first, tu );
5115
5116 case CXCursor_TemplateRef:
5117 return MakeCXCursor(getCursorTemplateRef(C).first, tu );
5118
5119 case CXCursor_NamespaceRef:
5120 return MakeCXCursor(getCursorNamespaceRef(C).first, tu );
5121
5122 case CXCursor_MemberRef:
5123 return MakeCXCursor(getCursorMemberRef(C).first, tu );
5124
5125 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005126 const CXXBaseSpecifier *B = cxcursor::getCursorCXXBaseSpecifier(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005127 return clang_getTypeDeclaration(cxtype::MakeCXType(B->getType(),
5128 tu ));
5129 }
5130
5131 case CXCursor_LabelRef:
5132 // FIXME: We end up faking the "parent" declaration here because we
5133 // don't want to make CXCursor larger.
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005134 return MakeCXCursor(getCursorLabelRef(C).first,
5135 cxtu::getASTUnit(tu)->getASTContext()
5136 .getTranslationUnitDecl(),
Guy Benyei11169dd2012-12-18 14:30:41 +00005137 tu);
5138
5139 case CXCursor_OverloadedDeclRef:
5140 return C;
5141
5142 case CXCursor_VariableRef:
5143 return MakeCXCursor(getCursorVariableRef(C).first, tu);
5144
5145 default:
5146 // We would prefer to enumerate all non-reference cursor kinds here.
5147 llvm_unreachable("Unhandled reference cursor kind");
5148 }
5149}
5150
5151CXCursor clang_getCursorDefinition(CXCursor C) {
5152 if (clang_isInvalid(C.kind))
5153 return clang_getNullCursor();
5154
5155 CXTranslationUnit TU = getCursorTU(C);
5156
5157 bool WasReference = false;
5158 if (clang_isReference(C.kind) || clang_isExpression(C.kind)) {
5159 C = clang_getCursorReferenced(C);
5160 WasReference = true;
5161 }
5162
5163 if (C.kind == CXCursor_MacroExpansion)
5164 return clang_getCursorReferenced(C);
5165
5166 if (!clang_isDeclaration(C.kind))
5167 return clang_getNullCursor();
5168
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005169 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005170 if (!D)
5171 return clang_getNullCursor();
5172
5173 switch (D->getKind()) {
5174 // Declaration kinds that don't really separate the notions of
5175 // declaration and definition.
5176 case Decl::Namespace:
5177 case Decl::Typedef:
5178 case Decl::TypeAlias:
5179 case Decl::TypeAliasTemplate:
5180 case Decl::TemplateTypeParm:
5181 case Decl::EnumConstant:
5182 case Decl::Field:
John McCall5e77d762013-04-16 07:28:30 +00005183 case Decl::MSProperty:
Guy Benyei11169dd2012-12-18 14:30:41 +00005184 case Decl::IndirectField:
5185 case Decl::ObjCIvar:
5186 case Decl::ObjCAtDefsField:
5187 case Decl::ImplicitParam:
5188 case Decl::ParmVar:
5189 case Decl::NonTypeTemplateParm:
5190 case Decl::TemplateTemplateParm:
5191 case Decl::ObjCCategoryImpl:
5192 case Decl::ObjCImplementation:
5193 case Decl::AccessSpec:
5194 case Decl::LinkageSpec:
5195 case Decl::ObjCPropertyImpl:
5196 case Decl::FileScopeAsm:
5197 case Decl::StaticAssert:
5198 case Decl::Block:
Tareq A. Siraj6dfa25a2013-04-16 19:37:38 +00005199 case Decl::Captured:
Guy Benyei11169dd2012-12-18 14:30:41 +00005200 case Decl::Label: // FIXME: Is this right??
5201 case Decl::ClassScopeFunctionSpecialization:
5202 case Decl::Import:
Alexey Bataeva769e072013-03-22 06:34:35 +00005203 case Decl::OMPThreadPrivate:
Douglas Gregor85f3f952015-07-07 03:57:15 +00005204 case Decl::ObjCTypeParam:
David Majnemerd9b1a4f2015-11-04 03:40:30 +00005205 case Decl::BuiltinTemplate:
Guy Benyei11169dd2012-12-18 14:30:41 +00005206 return C;
5207
5208 // Declaration kinds that don't make any sense here, but are
5209 // nonetheless harmless.
David Blaikief005d3c2013-02-22 17:44:58 +00005210 case Decl::Empty:
Guy Benyei11169dd2012-12-18 14:30:41 +00005211 case Decl::TranslationUnit:
Richard Smithf19e1272015-03-07 00:04:49 +00005212 case Decl::ExternCContext:
Guy Benyei11169dd2012-12-18 14:30:41 +00005213 break;
5214
5215 // Declaration kinds for which the definition is not resolvable.
5216 case Decl::UnresolvedUsingTypename:
5217 case Decl::UnresolvedUsingValue:
5218 break;
5219
5220 case Decl::UsingDirective:
5221 return MakeCXCursor(cast<UsingDirectiveDecl>(D)->getNominatedNamespace(),
5222 TU);
5223
5224 case Decl::NamespaceAlias:
5225 return MakeCXCursor(cast<NamespaceAliasDecl>(D)->getNamespace(), TU);
5226
5227 case Decl::Enum:
5228 case Decl::Record:
5229 case Decl::CXXRecord:
5230 case Decl::ClassTemplateSpecialization:
5231 case Decl::ClassTemplatePartialSpecialization:
5232 if (TagDecl *Def = cast<TagDecl>(D)->getDefinition())
5233 return MakeCXCursor(Def, TU);
5234 return clang_getNullCursor();
5235
5236 case Decl::Function:
5237 case Decl::CXXMethod:
5238 case Decl::CXXConstructor:
5239 case Decl::CXXDestructor:
5240 case Decl::CXXConversion: {
Craig Topper69186e72014-06-08 08:38:04 +00005241 const FunctionDecl *Def = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005242 if (cast<FunctionDecl>(D)->getBody(Def))
Dmitri Gribenko9c256e32013-01-14 00:46:27 +00005243 return MakeCXCursor(Def, TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005244 return clang_getNullCursor();
5245 }
5246
Larisse Voufo39a1e502013-08-06 01:03:05 +00005247 case Decl::Var:
5248 case Decl::VarTemplateSpecialization:
5249 case Decl::VarTemplatePartialSpecialization: {
Guy Benyei11169dd2012-12-18 14:30:41 +00005250 // Ask the variable if it has a definition.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005251 if (const VarDecl *Def = cast<VarDecl>(D)->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005252 return MakeCXCursor(Def, TU);
5253 return clang_getNullCursor();
5254 }
5255
5256 case Decl::FunctionTemplate: {
Craig Topper69186e72014-06-08 08:38:04 +00005257 const FunctionDecl *Def = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005258 if (cast<FunctionTemplateDecl>(D)->getTemplatedDecl()->getBody(Def))
5259 return MakeCXCursor(Def->getDescribedFunctionTemplate(), TU);
5260 return clang_getNullCursor();
5261 }
5262
5263 case Decl::ClassTemplate: {
5264 if (RecordDecl *Def = cast<ClassTemplateDecl>(D)->getTemplatedDecl()
5265 ->getDefinition())
5266 return MakeCXCursor(cast<CXXRecordDecl>(Def)->getDescribedClassTemplate(),
5267 TU);
5268 return clang_getNullCursor();
5269 }
5270
Larisse Voufo39a1e502013-08-06 01:03:05 +00005271 case Decl::VarTemplate: {
5272 if (VarDecl *Def =
5273 cast<VarTemplateDecl>(D)->getTemplatedDecl()->getDefinition())
5274 return MakeCXCursor(cast<VarDecl>(Def)->getDescribedVarTemplate(), TU);
5275 return clang_getNullCursor();
5276 }
5277
Guy Benyei11169dd2012-12-18 14:30:41 +00005278 case Decl::Using:
5279 return MakeCursorOverloadedDeclRef(cast<UsingDecl>(D),
5280 D->getLocation(), TU);
5281
5282 case Decl::UsingShadow:
5283 return clang_getCursorDefinition(
5284 MakeCXCursor(cast<UsingShadowDecl>(D)->getTargetDecl(),
5285 TU));
5286
5287 case Decl::ObjCMethod: {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005288 const ObjCMethodDecl *Method = cast<ObjCMethodDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00005289 if (Method->isThisDeclarationADefinition())
5290 return C;
5291
5292 // Dig out the method definition in the associated
5293 // @implementation, if we have it.
5294 // FIXME: The ASTs should make finding the definition easier.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005295 if (const ObjCInterfaceDecl *Class
Guy Benyei11169dd2012-12-18 14:30:41 +00005296 = dyn_cast<ObjCInterfaceDecl>(Method->getDeclContext()))
5297 if (ObjCImplementationDecl *ClassImpl = Class->getImplementation())
5298 if (ObjCMethodDecl *Def = ClassImpl->getMethod(Method->getSelector(),
5299 Method->isInstanceMethod()))
5300 if (Def->isThisDeclarationADefinition())
5301 return MakeCXCursor(Def, TU);
5302
5303 return clang_getNullCursor();
5304 }
5305
5306 case Decl::ObjCCategory:
5307 if (ObjCCategoryImplDecl *Impl
5308 = cast<ObjCCategoryDecl>(D)->getImplementation())
5309 return MakeCXCursor(Impl, TU);
5310 return clang_getNullCursor();
5311
5312 case Decl::ObjCProtocol:
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005313 if (const ObjCProtocolDecl *Def = cast<ObjCProtocolDecl>(D)->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005314 return MakeCXCursor(Def, TU);
5315 return clang_getNullCursor();
5316
5317 case Decl::ObjCInterface: {
5318 // There are two notions of a "definition" for an Objective-C
5319 // class: the interface and its implementation. When we resolved a
5320 // reference to an Objective-C class, produce the @interface as
5321 // the definition; when we were provided with the interface,
5322 // produce the @implementation as the definition.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005323 const ObjCInterfaceDecl *IFace = cast<ObjCInterfaceDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00005324 if (WasReference) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005325 if (const ObjCInterfaceDecl *Def = IFace->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005326 return MakeCXCursor(Def, TU);
5327 } else if (ObjCImplementationDecl *Impl = IFace->getImplementation())
5328 return MakeCXCursor(Impl, TU);
5329 return clang_getNullCursor();
5330 }
5331
5332 case Decl::ObjCProperty:
5333 // FIXME: We don't really know where to find the
5334 // ObjCPropertyImplDecls that implement this property.
5335 return clang_getNullCursor();
5336
5337 case Decl::ObjCCompatibleAlias:
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005338 if (const ObjCInterfaceDecl *Class
Guy Benyei11169dd2012-12-18 14:30:41 +00005339 = cast<ObjCCompatibleAliasDecl>(D)->getClassInterface())
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005340 if (const ObjCInterfaceDecl *Def = Class->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005341 return MakeCXCursor(Def, TU);
5342
5343 return clang_getNullCursor();
5344
5345 case Decl::Friend:
5346 if (NamedDecl *Friend = cast<FriendDecl>(D)->getFriendDecl())
5347 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
5348 return clang_getNullCursor();
5349
5350 case Decl::FriendTemplate:
5351 if (NamedDecl *Friend = cast<FriendTemplateDecl>(D)->getFriendDecl())
5352 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
5353 return clang_getNullCursor();
5354 }
5355
5356 return clang_getNullCursor();
5357}
5358
5359unsigned clang_isCursorDefinition(CXCursor C) {
5360 if (!clang_isDeclaration(C.kind))
5361 return 0;
5362
5363 return clang_getCursorDefinition(C) == C;
5364}
5365
5366CXCursor clang_getCanonicalCursor(CXCursor C) {
5367 if (!clang_isDeclaration(C.kind))
5368 return C;
5369
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005370 if (const Decl *D = getCursorDecl(C)) {
5371 if (const ObjCCategoryImplDecl *CatImplD = dyn_cast<ObjCCategoryImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00005372 if (ObjCCategoryDecl *CatD = CatImplD->getCategoryDecl())
5373 return MakeCXCursor(CatD, getCursorTU(C));
5374
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005375 if (const ObjCImplDecl *ImplD = dyn_cast<ObjCImplDecl>(D))
5376 if (const ObjCInterfaceDecl *IFD = ImplD->getClassInterface())
Guy Benyei11169dd2012-12-18 14:30:41 +00005377 return MakeCXCursor(IFD, getCursorTU(C));
5378
5379 return MakeCXCursor(D->getCanonicalDecl(), getCursorTU(C));
5380 }
5381
5382 return C;
5383}
5384
5385int clang_Cursor_getObjCSelectorIndex(CXCursor cursor) {
5386 return cxcursor::getSelectorIdentifierIndexAndLoc(cursor).first;
5387}
5388
5389unsigned clang_getNumOverloadedDecls(CXCursor C) {
5390 if (C.kind != CXCursor_OverloadedDeclRef)
5391 return 0;
5392
5393 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005394 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Guy Benyei11169dd2012-12-18 14:30:41 +00005395 return E->getNumDecls();
5396
5397 if (OverloadedTemplateStorage *S
5398 = Storage.dyn_cast<OverloadedTemplateStorage*>())
5399 return S->size();
5400
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005401 const Decl *D = Storage.get<const Decl *>();
5402 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00005403 return Using->shadow_size();
5404
5405 return 0;
5406}
5407
5408CXCursor clang_getOverloadedDecl(CXCursor cursor, unsigned index) {
5409 if (cursor.kind != CXCursor_OverloadedDeclRef)
5410 return clang_getNullCursor();
5411
5412 if (index >= clang_getNumOverloadedDecls(cursor))
5413 return clang_getNullCursor();
5414
5415 CXTranslationUnit TU = getCursorTU(cursor);
5416 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(cursor).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005417 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Guy Benyei11169dd2012-12-18 14:30:41 +00005418 return MakeCXCursor(E->decls_begin()[index], TU);
5419
5420 if (OverloadedTemplateStorage *S
5421 = Storage.dyn_cast<OverloadedTemplateStorage*>())
5422 return MakeCXCursor(S->begin()[index], TU);
5423
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005424 const Decl *D = Storage.get<const Decl *>();
5425 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005426 // FIXME: This is, unfortunately, linear time.
5427 UsingDecl::shadow_iterator Pos = Using->shadow_begin();
5428 std::advance(Pos, index);
5429 return MakeCXCursor(cast<UsingShadowDecl>(*Pos)->getTargetDecl(), TU);
5430 }
5431
5432 return clang_getNullCursor();
5433}
5434
5435void clang_getDefinitionSpellingAndExtent(CXCursor C,
5436 const char **startBuf,
5437 const char **endBuf,
5438 unsigned *startLine,
5439 unsigned *startColumn,
5440 unsigned *endLine,
5441 unsigned *endColumn) {
5442 assert(getCursorDecl(C) && "CXCursor has null decl");
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005443 const FunctionDecl *FD = dyn_cast<FunctionDecl>(getCursorDecl(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00005444 CompoundStmt *Body = dyn_cast<CompoundStmt>(FD->getBody());
5445
5446 SourceManager &SM = FD->getASTContext().getSourceManager();
5447 *startBuf = SM.getCharacterData(Body->getLBracLoc());
5448 *endBuf = SM.getCharacterData(Body->getRBracLoc());
5449 *startLine = SM.getSpellingLineNumber(Body->getLBracLoc());
5450 *startColumn = SM.getSpellingColumnNumber(Body->getLBracLoc());
5451 *endLine = SM.getSpellingLineNumber(Body->getRBracLoc());
5452 *endColumn = SM.getSpellingColumnNumber(Body->getRBracLoc());
5453}
5454
5455
5456CXSourceRange clang_getCursorReferenceNameRange(CXCursor C, unsigned NameFlags,
5457 unsigned PieceIndex) {
5458 RefNamePieces Pieces;
5459
5460 switch (C.kind) {
5461 case CXCursor_MemberRefExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005462 if (const MemberExpr *E = dyn_cast<MemberExpr>(getCursorExpr(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00005463 Pieces = buildPieces(NameFlags, true, E->getMemberNameInfo(),
5464 E->getQualifierLoc().getSourceRange());
5465 break;
5466
5467 case CXCursor_DeclRefExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005468 if (const DeclRefExpr *E = dyn_cast<DeclRefExpr>(getCursorExpr(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00005469 Pieces = buildPieces(NameFlags, false, E->getNameInfo(),
5470 E->getQualifierLoc().getSourceRange(),
5471 E->getOptionalExplicitTemplateArgs());
5472 break;
5473
5474 case CXCursor_CallExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005475 if (const CXXOperatorCallExpr *OCE =
Guy Benyei11169dd2012-12-18 14:30:41 +00005476 dyn_cast<CXXOperatorCallExpr>(getCursorExpr(C))) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005477 const Expr *Callee = OCE->getCallee();
5478 if (const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Callee))
Guy Benyei11169dd2012-12-18 14:30:41 +00005479 Callee = ICE->getSubExpr();
5480
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005481 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(Callee))
Guy Benyei11169dd2012-12-18 14:30:41 +00005482 Pieces = buildPieces(NameFlags, false, DRE->getNameInfo(),
5483 DRE->getQualifierLoc().getSourceRange());
5484 }
5485 break;
5486
5487 default:
5488 break;
5489 }
5490
5491 if (Pieces.empty()) {
5492 if (PieceIndex == 0)
5493 return clang_getCursorExtent(C);
5494 } else if (PieceIndex < Pieces.size()) {
5495 SourceRange R = Pieces[PieceIndex];
5496 if (R.isValid())
5497 return cxloc::translateSourceRange(getCursorContext(C), R);
5498 }
5499
5500 return clang_getNullRange();
5501}
5502
5503void clang_enableStackTraces(void) {
5504 llvm::sys::PrintStackTraceOnErrorSignal();
5505}
5506
5507void clang_executeOnThread(void (*fn)(void*), void *user_data,
5508 unsigned stack_size) {
5509 llvm::llvm_execute_on_thread(fn, user_data, stack_size);
5510}
5511
5512} // end: extern "C"
5513
5514//===----------------------------------------------------------------------===//
5515// Token-based Operations.
5516//===----------------------------------------------------------------------===//
5517
5518/* CXToken layout:
5519 * int_data[0]: a CXTokenKind
5520 * int_data[1]: starting token location
5521 * int_data[2]: token length
5522 * int_data[3]: reserved
5523 * ptr_data: for identifiers and keywords, an IdentifierInfo*.
5524 * otherwise unused.
5525 */
5526extern "C" {
5527
5528CXTokenKind clang_getTokenKind(CXToken CXTok) {
5529 return static_cast<CXTokenKind>(CXTok.int_data[0]);
5530}
5531
5532CXString clang_getTokenSpelling(CXTranslationUnit TU, CXToken CXTok) {
5533 switch (clang_getTokenKind(CXTok)) {
5534 case CXToken_Identifier:
5535 case CXToken_Keyword:
5536 // We know we have an IdentifierInfo*, so use that.
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005537 return cxstring::createRef(static_cast<IdentifierInfo *>(CXTok.ptr_data)
Guy Benyei11169dd2012-12-18 14:30:41 +00005538 ->getNameStart());
5539
5540 case CXToken_Literal: {
5541 // We have stashed the starting pointer in the ptr_data field. Use it.
5542 const char *Text = static_cast<const char *>(CXTok.ptr_data);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00005543 return cxstring::createDup(StringRef(Text, CXTok.int_data[2]));
Guy Benyei11169dd2012-12-18 14:30:41 +00005544 }
5545
5546 case CXToken_Punctuation:
5547 case CXToken_Comment:
5548 break;
5549 }
5550
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005551 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005552 LOG_BAD_TU(TU);
5553 return cxstring::createEmpty();
5554 }
5555
Guy Benyei11169dd2012-12-18 14:30:41 +00005556 // We have to find the starting buffer pointer the hard way, by
5557 // deconstructing the source location.
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005558 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005559 if (!CXXUnit)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00005560 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00005561
5562 SourceLocation Loc = SourceLocation::getFromRawEncoding(CXTok.int_data[1]);
5563 std::pair<FileID, unsigned> LocInfo
5564 = CXXUnit->getSourceManager().getDecomposedSpellingLoc(Loc);
5565 bool Invalid = false;
5566 StringRef Buffer
5567 = CXXUnit->getSourceManager().getBufferData(LocInfo.first, &Invalid);
5568 if (Invalid)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00005569 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00005570
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00005571 return cxstring::createDup(Buffer.substr(LocInfo.second, CXTok.int_data[2]));
Guy Benyei11169dd2012-12-18 14:30:41 +00005572}
5573
5574CXSourceLocation clang_getTokenLocation(CXTranslationUnit TU, CXToken CXTok) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005575 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005576 LOG_BAD_TU(TU);
5577 return clang_getNullLocation();
5578 }
5579
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005580 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005581 if (!CXXUnit)
5582 return clang_getNullLocation();
5583
5584 return cxloc::translateSourceLocation(CXXUnit->getASTContext(),
5585 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
5586}
5587
5588CXSourceRange clang_getTokenExtent(CXTranslationUnit TU, CXToken CXTok) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005589 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005590 LOG_BAD_TU(TU);
5591 return clang_getNullRange();
5592 }
5593
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005594 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005595 if (!CXXUnit)
5596 return clang_getNullRange();
5597
5598 return cxloc::translateSourceRange(CXXUnit->getASTContext(),
5599 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
5600}
5601
5602static void getTokens(ASTUnit *CXXUnit, SourceRange Range,
5603 SmallVectorImpl<CXToken> &CXTokens) {
5604 SourceManager &SourceMgr = CXXUnit->getSourceManager();
5605 std::pair<FileID, unsigned> BeginLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005606 = SourceMgr.getDecomposedSpellingLoc(Range.getBegin());
Guy Benyei11169dd2012-12-18 14:30:41 +00005607 std::pair<FileID, unsigned> EndLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005608 = SourceMgr.getDecomposedSpellingLoc(Range.getEnd());
Guy Benyei11169dd2012-12-18 14:30:41 +00005609
5610 // Cannot tokenize across files.
5611 if (BeginLocInfo.first != EndLocInfo.first)
5612 return;
5613
5614 // Create a lexer
5615 bool Invalid = false;
5616 StringRef Buffer
5617 = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
5618 if (Invalid)
5619 return;
5620
5621 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
5622 CXXUnit->getASTContext().getLangOpts(),
5623 Buffer.begin(), Buffer.data() + BeginLocInfo.second, Buffer.end());
5624 Lex.SetCommentRetentionState(true);
5625
5626 // Lex tokens until we hit the end of the range.
5627 const char *EffectiveBufferEnd = Buffer.data() + EndLocInfo.second;
5628 Token Tok;
5629 bool previousWasAt = false;
5630 do {
5631 // Lex the next token
5632 Lex.LexFromRawLexer(Tok);
5633 if (Tok.is(tok::eof))
5634 break;
5635
5636 // Initialize the CXToken.
5637 CXToken CXTok;
5638
5639 // - Common fields
5640 CXTok.int_data[1] = Tok.getLocation().getRawEncoding();
5641 CXTok.int_data[2] = Tok.getLength();
5642 CXTok.int_data[3] = 0;
5643
5644 // - Kind-specific fields
5645 if (Tok.isLiteral()) {
5646 CXTok.int_data[0] = CXToken_Literal;
Dmitri Gribenkof9304482013-01-23 15:56:07 +00005647 CXTok.ptr_data = const_cast<char *>(Tok.getLiteralData());
Guy Benyei11169dd2012-12-18 14:30:41 +00005648 } else if (Tok.is(tok::raw_identifier)) {
5649 // Lookup the identifier to determine whether we have a keyword.
5650 IdentifierInfo *II
5651 = CXXUnit->getPreprocessor().LookUpIdentifierInfo(Tok);
5652
5653 if ((II->getObjCKeywordID() != tok::objc_not_keyword) && previousWasAt) {
5654 CXTok.int_data[0] = CXToken_Keyword;
5655 }
5656 else {
5657 CXTok.int_data[0] = Tok.is(tok::identifier)
5658 ? CXToken_Identifier
5659 : CXToken_Keyword;
5660 }
5661 CXTok.ptr_data = II;
5662 } else if (Tok.is(tok::comment)) {
5663 CXTok.int_data[0] = CXToken_Comment;
Craig Topper69186e72014-06-08 08:38:04 +00005664 CXTok.ptr_data = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005665 } else {
5666 CXTok.int_data[0] = CXToken_Punctuation;
Craig Topper69186e72014-06-08 08:38:04 +00005667 CXTok.ptr_data = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005668 }
5669 CXTokens.push_back(CXTok);
5670 previousWasAt = Tok.is(tok::at);
5671 } while (Lex.getBufferLocation() <= EffectiveBufferEnd);
5672}
5673
5674void clang_tokenize(CXTranslationUnit TU, CXSourceRange Range,
5675 CXToken **Tokens, unsigned *NumTokens) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00005676 LOG_FUNC_SECTION {
5677 *Log << TU << ' ' << Range;
5678 }
5679
Guy Benyei11169dd2012-12-18 14:30:41 +00005680 if (Tokens)
Craig Topper69186e72014-06-08 08:38:04 +00005681 *Tokens = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005682 if (NumTokens)
5683 *NumTokens = 0;
5684
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005685 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005686 LOG_BAD_TU(TU);
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00005687 return;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005688 }
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00005689
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005690 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005691 if (!CXXUnit || !Tokens || !NumTokens)
5692 return;
5693
5694 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
5695
5696 SourceRange R = cxloc::translateCXSourceRange(Range);
5697 if (R.isInvalid())
5698 return;
5699
5700 SmallVector<CXToken, 32> CXTokens;
5701 getTokens(CXXUnit, R, CXTokens);
5702
5703 if (CXTokens.empty())
5704 return;
5705
5706 *Tokens = (CXToken *)malloc(sizeof(CXToken) * CXTokens.size());
5707 memmove(*Tokens, CXTokens.data(), sizeof(CXToken) * CXTokens.size());
5708 *NumTokens = CXTokens.size();
5709}
5710
5711void clang_disposeTokens(CXTranslationUnit TU,
5712 CXToken *Tokens, unsigned NumTokens) {
5713 free(Tokens);
5714}
5715
5716} // end: extern "C"
5717
5718//===----------------------------------------------------------------------===//
5719// Token annotation APIs.
5720//===----------------------------------------------------------------------===//
5721
Guy Benyei11169dd2012-12-18 14:30:41 +00005722static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
5723 CXCursor parent,
5724 CXClientData client_data);
5725static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
5726 CXClientData client_data);
5727
5728namespace {
5729class AnnotateTokensWorker {
Guy Benyei11169dd2012-12-18 14:30:41 +00005730 CXToken *Tokens;
5731 CXCursor *Cursors;
5732 unsigned NumTokens;
5733 unsigned TokIdx;
5734 unsigned PreprocessingTokIdx;
5735 CursorVisitor AnnotateVis;
5736 SourceManager &SrcMgr;
5737 bool HasContextSensitiveKeywords;
5738
5739 struct PostChildrenInfo {
5740 CXCursor Cursor;
5741 SourceRange CursorRange;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005742 unsigned BeforeReachingCursorIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00005743 unsigned BeforeChildrenTokenIdx;
5744 };
Dmitri Gribenkof8579502013-01-12 19:30:44 +00005745 SmallVector<PostChildrenInfo, 8> PostChildrenInfos;
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005746
5747 CXToken &getTok(unsigned Idx) {
5748 assert(Idx < NumTokens);
5749 return Tokens[Idx];
5750 }
5751 const CXToken &getTok(unsigned Idx) const {
5752 assert(Idx < NumTokens);
5753 return Tokens[Idx];
5754 }
Guy Benyei11169dd2012-12-18 14:30:41 +00005755 bool MoreTokens() const { return TokIdx < NumTokens; }
5756 unsigned NextToken() const { return TokIdx; }
5757 void AdvanceToken() { ++TokIdx; }
5758 SourceLocation GetTokenLoc(unsigned tokI) {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005759 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[1]);
Guy Benyei11169dd2012-12-18 14:30:41 +00005760 }
5761 bool isFunctionMacroToken(unsigned tokI) const {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005762 return getTok(tokI).int_data[3] != 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00005763 }
5764 SourceLocation getFunctionMacroTokenLoc(unsigned tokI) const {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005765 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[3]);
Guy Benyei11169dd2012-12-18 14:30:41 +00005766 }
5767
5768 void annotateAndAdvanceTokens(CXCursor, RangeComparisonResult, SourceRange);
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005769 bool annotateAndAdvanceFunctionMacroTokens(CXCursor, RangeComparisonResult,
Guy Benyei11169dd2012-12-18 14:30:41 +00005770 SourceRange);
5771
5772public:
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005773 AnnotateTokensWorker(CXToken *tokens, CXCursor *cursors, unsigned numTokens,
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005774 CXTranslationUnit TU, SourceRange RegionOfInterest)
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005775 : Tokens(tokens), Cursors(cursors),
Guy Benyei11169dd2012-12-18 14:30:41 +00005776 NumTokens(numTokens), TokIdx(0), PreprocessingTokIdx(0),
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005777 AnnotateVis(TU,
Guy Benyei11169dd2012-12-18 14:30:41 +00005778 AnnotateTokensVisitor, this,
5779 /*VisitPreprocessorLast=*/true,
5780 /*VisitIncludedEntities=*/false,
5781 RegionOfInterest,
5782 /*VisitDeclsOnly=*/false,
5783 AnnotateTokensPostChildrenVisitor),
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005784 SrcMgr(cxtu::getASTUnit(TU)->getSourceManager()),
Guy Benyei11169dd2012-12-18 14:30:41 +00005785 HasContextSensitiveKeywords(false) { }
5786
5787 void VisitChildren(CXCursor C) { AnnotateVis.VisitChildren(C); }
5788 enum CXChildVisitResult Visit(CXCursor cursor, CXCursor parent);
5789 bool postVisitChildren(CXCursor cursor);
5790 void AnnotateTokens();
5791
5792 /// \brief Determine whether the annotator saw any cursors that have
5793 /// context-sensitive keywords.
5794 bool hasContextSensitiveKeywords() const {
5795 return HasContextSensitiveKeywords;
5796 }
5797
5798 ~AnnotateTokensWorker() {
5799 assert(PostChildrenInfos.empty());
5800 }
5801};
Alexander Kornienkoab9db512015-06-22 23:07:51 +00005802}
Guy Benyei11169dd2012-12-18 14:30:41 +00005803
5804void AnnotateTokensWorker::AnnotateTokens() {
5805 // Walk the AST within the region of interest, annotating tokens
5806 // along the way.
5807 AnnotateVis.visitFileRegion();
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005808}
Guy Benyei11169dd2012-12-18 14:30:41 +00005809
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005810static inline void updateCursorAnnotation(CXCursor &Cursor,
5811 const CXCursor &updateC) {
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005812 if (clang_isInvalid(updateC.kind) || !clang_isInvalid(Cursor.kind))
Guy Benyei11169dd2012-12-18 14:30:41 +00005813 return;
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005814 Cursor = updateC;
Guy Benyei11169dd2012-12-18 14:30:41 +00005815}
5816
5817/// \brief It annotates and advances tokens with a cursor until the comparison
5818//// between the cursor location and the source range is the same as
5819/// \arg compResult.
5820///
5821/// Pass RangeBefore to annotate tokens with a cursor until a range is reached.
5822/// Pass RangeOverlap to annotate tokens inside a range.
5823void AnnotateTokensWorker::annotateAndAdvanceTokens(CXCursor updateC,
5824 RangeComparisonResult compResult,
5825 SourceRange range) {
5826 while (MoreTokens()) {
5827 const unsigned I = NextToken();
5828 if (isFunctionMacroToken(I))
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005829 if (!annotateAndAdvanceFunctionMacroTokens(updateC, compResult, range))
5830 return;
Guy Benyei11169dd2012-12-18 14:30:41 +00005831
5832 SourceLocation TokLoc = GetTokenLoc(I);
5833 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005834 updateCursorAnnotation(Cursors[I], updateC);
Guy Benyei11169dd2012-12-18 14:30:41 +00005835 AdvanceToken();
5836 continue;
5837 }
5838 break;
5839 }
5840}
5841
5842/// \brief Special annotation handling for macro argument tokens.
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005843/// \returns true if it advanced beyond all macro tokens, false otherwise.
5844bool AnnotateTokensWorker::annotateAndAdvanceFunctionMacroTokens(
Guy Benyei11169dd2012-12-18 14:30:41 +00005845 CXCursor updateC,
5846 RangeComparisonResult compResult,
5847 SourceRange range) {
5848 assert(MoreTokens());
5849 assert(isFunctionMacroToken(NextToken()) &&
5850 "Should be called only for macro arg tokens");
5851
5852 // This works differently than annotateAndAdvanceTokens; because expanded
5853 // macro arguments can have arbitrary translation-unit source order, we do not
5854 // advance the token index one by one until a token fails the range test.
5855 // We only advance once past all of the macro arg tokens if all of them
5856 // pass the range test. If one of them fails we keep the token index pointing
5857 // at the start of the macro arg tokens so that the failing token will be
5858 // annotated by a subsequent annotation try.
5859
5860 bool atLeastOneCompFail = false;
5861
5862 unsigned I = NextToken();
5863 for (; I < NumTokens && isFunctionMacroToken(I); ++I) {
5864 SourceLocation TokLoc = getFunctionMacroTokenLoc(I);
5865 if (TokLoc.isFileID())
5866 continue; // not macro arg token, it's parens or comma.
5867 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
5868 if (clang_isInvalid(clang_getCursorKind(Cursors[I])))
5869 Cursors[I] = updateC;
5870 } else
5871 atLeastOneCompFail = true;
5872 }
5873
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005874 if (atLeastOneCompFail)
5875 return false;
5876
5877 TokIdx = I; // All of the tokens were handled, advance beyond all of them.
5878 return true;
Guy Benyei11169dd2012-12-18 14:30:41 +00005879}
5880
5881enum CXChildVisitResult
5882AnnotateTokensWorker::Visit(CXCursor cursor, CXCursor parent) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005883 SourceRange cursorRange = getRawCursorExtent(cursor);
5884 if (cursorRange.isInvalid())
5885 return CXChildVisit_Recurse;
5886
5887 if (!HasContextSensitiveKeywords) {
5888 // Objective-C properties can have context-sensitive keywords.
5889 if (cursor.kind == CXCursor_ObjCPropertyDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005890 if (const ObjCPropertyDecl *Property
Guy Benyei11169dd2012-12-18 14:30:41 +00005891 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(cursor)))
5892 HasContextSensitiveKeywords = Property->getPropertyAttributesAsWritten() != 0;
5893 }
5894 // Objective-C methods can have context-sensitive keywords.
5895 else if (cursor.kind == CXCursor_ObjCInstanceMethodDecl ||
5896 cursor.kind == CXCursor_ObjCClassMethodDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005897 if (const ObjCMethodDecl *Method
Guy Benyei11169dd2012-12-18 14:30:41 +00005898 = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
5899 if (Method->getObjCDeclQualifier())
5900 HasContextSensitiveKeywords = true;
5901 else {
Aaron Ballman43b68be2014-03-07 17:50:17 +00005902 for (const auto *P : Method->params()) {
5903 if (P->getObjCDeclQualifier()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005904 HasContextSensitiveKeywords = true;
5905 break;
5906 }
5907 }
5908 }
5909 }
5910 }
5911 // C++ methods can have context-sensitive keywords.
5912 else if (cursor.kind == CXCursor_CXXMethod) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005913 if (const CXXMethodDecl *Method
Guy Benyei11169dd2012-12-18 14:30:41 +00005914 = dyn_cast_or_null<CXXMethodDecl>(getCursorDecl(cursor))) {
5915 if (Method->hasAttr<FinalAttr>() || Method->hasAttr<OverrideAttr>())
5916 HasContextSensitiveKeywords = true;
5917 }
5918 }
5919 // C++ classes can have context-sensitive keywords.
5920 else if (cursor.kind == CXCursor_StructDecl ||
5921 cursor.kind == CXCursor_ClassDecl ||
5922 cursor.kind == CXCursor_ClassTemplate ||
5923 cursor.kind == CXCursor_ClassTemplatePartialSpecialization) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005924 if (const Decl *D = getCursorDecl(cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +00005925 if (D->hasAttr<FinalAttr>())
5926 HasContextSensitiveKeywords = true;
5927 }
5928 }
Argyrios Kyrtzidis990b3862013-06-04 18:24:30 +00005929
5930 // Don't override a property annotation with its getter/setter method.
5931 if (cursor.kind == CXCursor_ObjCInstanceMethodDecl &&
5932 parent.kind == CXCursor_ObjCPropertyDecl)
5933 return CXChildVisit_Continue;
Guy Benyei11169dd2012-12-18 14:30:41 +00005934
5935 if (clang_isPreprocessing(cursor.kind)) {
5936 // Items in the preprocessing record are kept separate from items in
5937 // declarations, so we keep a separate token index.
5938 unsigned SavedTokIdx = TokIdx;
5939 TokIdx = PreprocessingTokIdx;
5940
5941 // Skip tokens up until we catch up to the beginning of the preprocessing
5942 // entry.
5943 while (MoreTokens()) {
5944 const unsigned I = NextToken();
5945 SourceLocation TokLoc = GetTokenLoc(I);
5946 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
5947 case RangeBefore:
5948 AdvanceToken();
5949 continue;
5950 case RangeAfter:
5951 case RangeOverlap:
5952 break;
5953 }
5954 break;
5955 }
5956
5957 // Look at all of the tokens within this range.
5958 while (MoreTokens()) {
5959 const unsigned I = NextToken();
5960 SourceLocation TokLoc = GetTokenLoc(I);
5961 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
5962 case RangeBefore:
5963 llvm_unreachable("Infeasible");
5964 case RangeAfter:
5965 break;
5966 case RangeOverlap:
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005967 // For macro expansions, just note where the beginning of the macro
5968 // expansion occurs.
5969 if (cursor.kind == CXCursor_MacroExpansion) {
5970 if (TokLoc == cursorRange.getBegin())
5971 Cursors[I] = cursor;
5972 AdvanceToken();
5973 break;
5974 }
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005975 // We may have already annotated macro names inside macro definitions.
5976 if (Cursors[I].kind != CXCursor_MacroExpansion)
5977 Cursors[I] = cursor;
Guy Benyei11169dd2012-12-18 14:30:41 +00005978 AdvanceToken();
Guy Benyei11169dd2012-12-18 14:30:41 +00005979 continue;
5980 }
5981 break;
5982 }
5983
5984 // Save the preprocessing token index; restore the non-preprocessing
5985 // token index.
5986 PreprocessingTokIdx = TokIdx;
5987 TokIdx = SavedTokIdx;
5988 return CXChildVisit_Recurse;
5989 }
5990
5991 if (cursorRange.isInvalid())
5992 return CXChildVisit_Continue;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005993
5994 unsigned BeforeReachingCursorIdx = NextToken();
Guy Benyei11169dd2012-12-18 14:30:41 +00005995 const enum CXCursorKind cursorK = clang_getCursorKind(cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00005996 const enum CXCursorKind K = clang_getCursorKind(parent);
5997 const CXCursor updateC =
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005998 (clang_isInvalid(K) || K == CXCursor_TranslationUnit ||
5999 // Attributes are annotated out-of-order, skip tokens until we reach it.
6000 clang_isAttribute(cursor.kind))
Guy Benyei11169dd2012-12-18 14:30:41 +00006001 ? clang_getNullCursor() : parent;
6002
6003 annotateAndAdvanceTokens(updateC, RangeBefore, cursorRange);
6004
6005 // Avoid having the cursor of an expression "overwrite" the annotation of the
6006 // variable declaration that it belongs to.
6007 // This can happen for C++ constructor expressions whose range generally
6008 // include the variable declaration, e.g.:
6009 // MyCXXClass foo; // Make sure we don't annotate 'foo' as a CallExpr cursor.
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00006010 if (clang_isExpression(cursorK) && MoreTokens()) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00006011 const Expr *E = getCursorExpr(cursor);
Dmitri Gribenkoa1691182013-01-26 18:12:08 +00006012 if (const Decl *D = getCursorParentDecl(cursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00006013 const unsigned I = NextToken();
6014 if (E->getLocStart().isValid() && D->getLocation().isValid() &&
6015 E->getLocStart() == D->getLocation() &&
6016 E->getLocStart() == GetTokenLoc(I)) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006017 updateCursorAnnotation(Cursors[I], updateC);
Guy Benyei11169dd2012-12-18 14:30:41 +00006018 AdvanceToken();
6019 }
6020 }
6021 }
6022
6023 // Before recursing into the children keep some state that we are going
6024 // to use in the AnnotateTokensWorker::postVisitChildren callback to do some
6025 // extra work after the child nodes are visited.
6026 // Note that we don't call VisitChildren here to avoid traversing statements
6027 // code-recursively which can blow the stack.
6028
6029 PostChildrenInfo Info;
6030 Info.Cursor = cursor;
6031 Info.CursorRange = cursorRange;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00006032 Info.BeforeReachingCursorIdx = BeforeReachingCursorIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00006033 Info.BeforeChildrenTokenIdx = NextToken();
6034 PostChildrenInfos.push_back(Info);
6035
6036 return CXChildVisit_Recurse;
6037}
6038
6039bool AnnotateTokensWorker::postVisitChildren(CXCursor cursor) {
6040 if (PostChildrenInfos.empty())
6041 return false;
6042 const PostChildrenInfo &Info = PostChildrenInfos.back();
6043 if (!clang_equalCursors(Info.Cursor, cursor))
6044 return false;
6045
6046 const unsigned BeforeChildren = Info.BeforeChildrenTokenIdx;
6047 const unsigned AfterChildren = NextToken();
6048 SourceRange cursorRange = Info.CursorRange;
6049
6050 // Scan the tokens that are at the end of the cursor, but are not captured
6051 // but the child cursors.
6052 annotateAndAdvanceTokens(cursor, RangeOverlap, cursorRange);
6053
6054 // Scan the tokens that are at the beginning of the cursor, but are not
6055 // capture by the child cursors.
6056 for (unsigned I = BeforeChildren; I != AfterChildren; ++I) {
6057 if (!clang_isInvalid(clang_getCursorKind(Cursors[I])))
6058 break;
6059
6060 Cursors[I] = cursor;
6061 }
6062
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00006063 // Attributes are annotated out-of-order, rewind TokIdx to when we first
6064 // encountered the attribute cursor.
6065 if (clang_isAttribute(cursor.kind))
6066 TokIdx = Info.BeforeReachingCursorIdx;
6067
Guy Benyei11169dd2012-12-18 14:30:41 +00006068 PostChildrenInfos.pop_back();
6069 return false;
6070}
6071
6072static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
6073 CXCursor parent,
6074 CXClientData client_data) {
6075 return static_cast<AnnotateTokensWorker*>(client_data)->Visit(cursor, parent);
6076}
6077
6078static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
6079 CXClientData client_data) {
6080 return static_cast<AnnotateTokensWorker*>(client_data)->
6081 postVisitChildren(cursor);
6082}
6083
6084namespace {
6085
6086/// \brief Uses the macro expansions in the preprocessing record to find
6087/// and mark tokens that are macro arguments. This info is used by the
6088/// AnnotateTokensWorker.
6089class MarkMacroArgTokensVisitor {
6090 SourceManager &SM;
6091 CXToken *Tokens;
6092 unsigned NumTokens;
6093 unsigned CurIdx;
6094
6095public:
6096 MarkMacroArgTokensVisitor(SourceManager &SM,
6097 CXToken *tokens, unsigned numTokens)
6098 : SM(SM), Tokens(tokens), NumTokens(numTokens), CurIdx(0) { }
6099
6100 CXChildVisitResult visit(CXCursor cursor, CXCursor parent) {
6101 if (cursor.kind != CXCursor_MacroExpansion)
6102 return CXChildVisit_Continue;
6103
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006104 SourceRange macroRange = getCursorMacroExpansion(cursor).getSourceRange();
Guy Benyei11169dd2012-12-18 14:30:41 +00006105 if (macroRange.getBegin() == macroRange.getEnd())
6106 return CXChildVisit_Continue; // it's not a function macro.
6107
6108 for (; CurIdx < NumTokens; ++CurIdx) {
6109 if (!SM.isBeforeInTranslationUnit(getTokenLoc(CurIdx),
6110 macroRange.getBegin()))
6111 break;
6112 }
6113
6114 if (CurIdx == NumTokens)
6115 return CXChildVisit_Break;
6116
6117 for (; CurIdx < NumTokens; ++CurIdx) {
6118 SourceLocation tokLoc = getTokenLoc(CurIdx);
6119 if (!SM.isBeforeInTranslationUnit(tokLoc, macroRange.getEnd()))
6120 break;
6121
6122 setFunctionMacroTokenLoc(CurIdx, SM.getMacroArgExpandedLocation(tokLoc));
6123 }
6124
6125 if (CurIdx == NumTokens)
6126 return CXChildVisit_Break;
6127
6128 return CXChildVisit_Continue;
6129 }
6130
6131private:
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00006132 CXToken &getTok(unsigned Idx) {
6133 assert(Idx < NumTokens);
6134 return Tokens[Idx];
6135 }
6136 const CXToken &getTok(unsigned Idx) const {
6137 assert(Idx < NumTokens);
6138 return Tokens[Idx];
6139 }
6140
Guy Benyei11169dd2012-12-18 14:30:41 +00006141 SourceLocation getTokenLoc(unsigned tokI) {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00006142 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[1]);
Guy Benyei11169dd2012-12-18 14:30:41 +00006143 }
6144
6145 void setFunctionMacroTokenLoc(unsigned tokI, SourceLocation loc) {
6146 // The third field is reserved and currently not used. Use it here
6147 // to mark macro arg expanded tokens with their expanded locations.
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00006148 getTok(tokI).int_data[3] = loc.getRawEncoding();
Guy Benyei11169dd2012-12-18 14:30:41 +00006149 }
6150};
6151
6152} // end anonymous namespace
6153
6154static CXChildVisitResult
6155MarkMacroArgTokensVisitorDelegate(CXCursor cursor, CXCursor parent,
6156 CXClientData client_data) {
6157 return static_cast<MarkMacroArgTokensVisitor*>(client_data)->visit(cursor,
6158 parent);
6159}
6160
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006161/// \brief Used by \c annotatePreprocessorTokens.
6162/// \returns true if lexing was finished, false otherwise.
6163static bool lexNext(Lexer &Lex, Token &Tok,
6164 unsigned &NextIdx, unsigned NumTokens) {
6165 if (NextIdx >= NumTokens)
6166 return true;
6167
6168 ++NextIdx;
6169 Lex.LexFromRawLexer(Tok);
6170 if (Tok.is(tok::eof))
6171 return true;
6172
6173 return false;
6174}
6175
Guy Benyei11169dd2012-12-18 14:30:41 +00006176static void annotatePreprocessorTokens(CXTranslationUnit TU,
6177 SourceRange RegionOfInterest,
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006178 CXCursor *Cursors,
6179 CXToken *Tokens,
6180 unsigned NumTokens) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006181 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00006182
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006183 Preprocessor &PP = CXXUnit->getPreprocessor();
Guy Benyei11169dd2012-12-18 14:30:41 +00006184 SourceManager &SourceMgr = CXXUnit->getSourceManager();
6185 std::pair<FileID, unsigned> BeginLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00006186 = SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getBegin());
Guy Benyei11169dd2012-12-18 14:30:41 +00006187 std::pair<FileID, unsigned> EndLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00006188 = SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getEnd());
Guy Benyei11169dd2012-12-18 14:30:41 +00006189
6190 if (BeginLocInfo.first != EndLocInfo.first)
6191 return;
6192
6193 StringRef Buffer;
6194 bool Invalid = false;
6195 Buffer = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
6196 if (Buffer.empty() || Invalid)
6197 return;
6198
6199 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
6200 CXXUnit->getASTContext().getLangOpts(),
6201 Buffer.begin(), Buffer.data() + BeginLocInfo.second,
6202 Buffer.end());
6203 Lex.SetCommentRetentionState(true);
6204
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006205 unsigned NextIdx = 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00006206 // Lex tokens in raw mode until we hit the end of the range, to avoid
6207 // entering #includes or expanding macros.
6208 while (true) {
6209 Token Tok;
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006210 if (lexNext(Lex, Tok, NextIdx, NumTokens))
6211 break;
6212 unsigned TokIdx = NextIdx-1;
6213 assert(Tok.getLocation() ==
6214 SourceLocation::getFromRawEncoding(Tokens[TokIdx].int_data[1]));
Guy Benyei11169dd2012-12-18 14:30:41 +00006215
6216 reprocess:
6217 if (Tok.is(tok::hash) && Tok.isAtStartOfLine()) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006218 // We have found a preprocessing directive. Annotate the tokens
6219 // appropriately.
Guy Benyei11169dd2012-12-18 14:30:41 +00006220 //
6221 // FIXME: Some simple tests here could identify macro definitions and
6222 // #undefs, to provide specific cursor kinds for those.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006223
6224 SourceLocation BeginLoc = Tok.getLocation();
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006225 if (lexNext(Lex, Tok, NextIdx, NumTokens))
6226 break;
6227
Craig Topper69186e72014-06-08 08:38:04 +00006228 MacroInfo *MI = nullptr;
Alp Toker2d57cea2014-05-17 04:53:25 +00006229 if (Tok.is(tok::raw_identifier) && Tok.getRawIdentifier() == "define") {
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006230 if (lexNext(Lex, Tok, NextIdx, NumTokens))
6231 break;
6232
6233 if (Tok.is(tok::raw_identifier)) {
Alp Toker2d57cea2014-05-17 04:53:25 +00006234 IdentifierInfo &II =
6235 PP.getIdentifierTable().get(Tok.getRawIdentifier());
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006236 SourceLocation MappedTokLoc =
6237 CXXUnit->mapLocationToPreamble(Tok.getLocation());
6238 MI = getMacroInfo(II, MappedTokLoc, TU);
6239 }
6240 }
6241
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006242 bool finished = false;
Guy Benyei11169dd2012-12-18 14:30:41 +00006243 do {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006244 if (lexNext(Lex, Tok, NextIdx, NumTokens)) {
6245 finished = true;
6246 break;
6247 }
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006248 // If we are in a macro definition, check if the token was ever a
6249 // macro name and annotate it if that's the case.
6250 if (MI) {
6251 SourceLocation SaveLoc = Tok.getLocation();
6252 Tok.setLocation(CXXUnit->mapLocationToPreamble(SaveLoc));
Richard Smith66a81862015-05-04 02:25:31 +00006253 MacroDefinitionRecord *MacroDef =
6254 checkForMacroInMacroDefinition(MI, Tok, TU);
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006255 Tok.setLocation(SaveLoc);
6256 if (MacroDef)
Richard Smith66a81862015-05-04 02:25:31 +00006257 Cursors[NextIdx - 1] =
6258 MakeMacroExpansionCursor(MacroDef, Tok.getLocation(), TU);
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006259 }
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006260 } while (!Tok.isAtStartOfLine());
6261
6262 unsigned LastIdx = finished ? NextIdx-1 : NextIdx-2;
6263 assert(TokIdx <= LastIdx);
6264 SourceLocation EndLoc =
6265 SourceLocation::getFromRawEncoding(Tokens[LastIdx].int_data[1]);
6266 CXCursor Cursor =
6267 MakePreprocessingDirectiveCursor(SourceRange(BeginLoc, EndLoc), TU);
6268
6269 for (; TokIdx <= LastIdx; ++TokIdx)
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006270 updateCursorAnnotation(Cursors[TokIdx], Cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00006271
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006272 if (finished)
6273 break;
6274 goto reprocess;
Guy Benyei11169dd2012-12-18 14:30:41 +00006275 }
Guy Benyei11169dd2012-12-18 14:30:41 +00006276 }
6277}
6278
6279// This gets run a separate thread to avoid stack blowout.
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00006280static void clang_annotateTokensImpl(CXTranslationUnit TU, ASTUnit *CXXUnit,
6281 CXToken *Tokens, unsigned NumTokens,
6282 CXCursor *Cursors) {
Dmitri Gribenko183436e2013-01-26 21:49:50 +00006283 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00006284 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
6285 setThreadBackgroundPriority();
6286
6287 // Determine the region of interest, which contains all of the tokens.
6288 SourceRange RegionOfInterest;
6289 RegionOfInterest.setBegin(
6290 cxloc::translateSourceLocation(clang_getTokenLocation(TU, Tokens[0])));
6291 RegionOfInterest.setEnd(
6292 cxloc::translateSourceLocation(clang_getTokenLocation(TU,
6293 Tokens[NumTokens-1])));
6294
Guy Benyei11169dd2012-12-18 14:30:41 +00006295 // Relex the tokens within the source range to look for preprocessing
6296 // directives.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006297 annotatePreprocessorTokens(TU, RegionOfInterest, Cursors, Tokens, NumTokens);
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00006298
6299 // If begin location points inside a macro argument, set it to the expansion
6300 // location so we can have the full context when annotating semantically.
6301 {
6302 SourceManager &SM = CXXUnit->getSourceManager();
6303 SourceLocation Loc =
6304 SM.getMacroArgExpandedLocation(RegionOfInterest.getBegin());
6305 if (Loc.isMacroID())
6306 RegionOfInterest.setBegin(SM.getExpansionLoc(Loc));
6307 }
6308
Guy Benyei11169dd2012-12-18 14:30:41 +00006309 if (CXXUnit->getPreprocessor().getPreprocessingRecord()) {
6310 // Search and mark tokens that are macro argument expansions.
6311 MarkMacroArgTokensVisitor Visitor(CXXUnit->getSourceManager(),
6312 Tokens, NumTokens);
6313 CursorVisitor MacroArgMarker(TU,
6314 MarkMacroArgTokensVisitorDelegate, &Visitor,
6315 /*VisitPreprocessorLast=*/true,
6316 /*VisitIncludedEntities=*/false,
6317 RegionOfInterest);
6318 MacroArgMarker.visitPreprocessedEntitiesInRegion();
6319 }
6320
6321 // Annotate all of the source locations in the region of interest that map to
6322 // a specific cursor.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006323 AnnotateTokensWorker W(Tokens, Cursors, NumTokens, TU, RegionOfInterest);
Guy Benyei11169dd2012-12-18 14:30:41 +00006324
6325 // FIXME: We use a ridiculous stack size here because the data-recursion
6326 // algorithm uses a large stack frame than the non-data recursive version,
6327 // and AnnotationTokensWorker currently transforms the data-recursion
6328 // algorithm back into a traditional recursion by explicitly calling
6329 // VisitChildren(). We will need to remove this explicit recursive call.
6330 W.AnnotateTokens();
6331
6332 // If we ran into any entities that involve context-sensitive keywords,
6333 // take another pass through the tokens to mark them as such.
6334 if (W.hasContextSensitiveKeywords()) {
6335 for (unsigned I = 0; I != NumTokens; ++I) {
6336 if (clang_getTokenKind(Tokens[I]) != CXToken_Identifier)
6337 continue;
6338
6339 if (Cursors[I].kind == CXCursor_ObjCPropertyDecl) {
6340 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006341 if (const ObjCPropertyDecl *Property
Guy Benyei11169dd2012-12-18 14:30:41 +00006342 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(Cursors[I]))) {
6343 if (Property->getPropertyAttributesAsWritten() != 0 &&
6344 llvm::StringSwitch<bool>(II->getName())
6345 .Case("readonly", true)
6346 .Case("assign", true)
6347 .Case("unsafe_unretained", true)
6348 .Case("readwrite", true)
6349 .Case("retain", true)
6350 .Case("copy", true)
6351 .Case("nonatomic", true)
6352 .Case("atomic", true)
6353 .Case("getter", true)
6354 .Case("setter", true)
6355 .Case("strong", true)
6356 .Case("weak", true)
6357 .Default(false))
6358 Tokens[I].int_data[0] = CXToken_Keyword;
6359 }
6360 continue;
6361 }
6362
6363 if (Cursors[I].kind == CXCursor_ObjCInstanceMethodDecl ||
6364 Cursors[I].kind == CXCursor_ObjCClassMethodDecl) {
6365 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
6366 if (llvm::StringSwitch<bool>(II->getName())
6367 .Case("in", true)
6368 .Case("out", true)
6369 .Case("inout", true)
6370 .Case("oneway", true)
6371 .Case("bycopy", true)
6372 .Case("byref", true)
6373 .Default(false))
6374 Tokens[I].int_data[0] = CXToken_Keyword;
6375 continue;
6376 }
6377
6378 if (Cursors[I].kind == CXCursor_CXXFinalAttr ||
6379 Cursors[I].kind == CXCursor_CXXOverrideAttr) {
6380 Tokens[I].int_data[0] = CXToken_Keyword;
6381 continue;
6382 }
6383 }
6384 }
6385}
6386
6387extern "C" {
6388
6389void clang_annotateTokens(CXTranslationUnit TU,
6390 CXToken *Tokens, unsigned NumTokens,
6391 CXCursor *Cursors) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006392 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006393 LOG_BAD_TU(TU);
6394 return;
6395 }
6396 if (NumTokens == 0 || !Tokens || !Cursors) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006397 LOG_FUNC_SECTION { *Log << "<null input>"; }
Guy Benyei11169dd2012-12-18 14:30:41 +00006398 return;
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006399 }
6400
6401 LOG_FUNC_SECTION {
6402 *Log << TU << ' ';
6403 CXSourceLocation bloc = clang_getTokenLocation(TU, Tokens[0]);
6404 CXSourceLocation eloc = clang_getTokenLocation(TU, Tokens[NumTokens-1]);
6405 *Log << clang_getRange(bloc, eloc);
6406 }
Guy Benyei11169dd2012-12-18 14:30:41 +00006407
6408 // Any token we don't specifically annotate will have a NULL cursor.
6409 CXCursor C = clang_getNullCursor();
6410 for (unsigned I = 0; I != NumTokens; ++I)
6411 Cursors[I] = C;
6412
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006413 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00006414 if (!CXXUnit)
6415 return;
6416
6417 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00006418
6419 auto AnnotateTokensImpl = [=]() {
6420 clang_annotateTokensImpl(TU, CXXUnit, Tokens, NumTokens, Cursors);
6421 };
Guy Benyei11169dd2012-12-18 14:30:41 +00006422 llvm::CrashRecoveryContext CRC;
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00006423 if (!RunSafely(CRC, AnnotateTokensImpl, GetSafetyThreadStackSize() * 2)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00006424 fprintf(stderr, "libclang: crash detected while annotating tokens\n");
6425 }
6426}
6427
6428} // end: extern "C"
6429
6430//===----------------------------------------------------------------------===//
6431// Operations for querying linkage of a cursor.
6432//===----------------------------------------------------------------------===//
6433
6434extern "C" {
6435CXLinkageKind clang_getCursorLinkage(CXCursor cursor) {
6436 if (!clang_isDeclaration(cursor.kind))
6437 return CXLinkage_Invalid;
6438
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006439 const Decl *D = cxcursor::getCursorDecl(cursor);
6440 if (const NamedDecl *ND = dyn_cast_or_null<NamedDecl>(D))
Rafael Espindola3ae00052013-05-13 00:12:11 +00006441 switch (ND->getLinkageInternal()) {
Rafael Espindola50df3a02013-05-25 17:16:20 +00006442 case NoLinkage:
6443 case VisibleNoLinkage: return CXLinkage_NoLinkage;
Guy Benyei11169dd2012-12-18 14:30:41 +00006444 case InternalLinkage: return CXLinkage_Internal;
6445 case UniqueExternalLinkage: return CXLinkage_UniqueExternal;
6446 case ExternalLinkage: return CXLinkage_External;
6447 };
6448
6449 return CXLinkage_Invalid;
6450}
6451} // end: extern "C"
6452
6453//===----------------------------------------------------------------------===//
Ehsan Akhgari93697fa2015-11-23 19:56:46 +00006454// Operations for querying visibility of a cursor.
6455//===----------------------------------------------------------------------===//
6456
6457extern "C" {
6458CXVisibilityKind clang_getCursorVisibility(CXCursor cursor) {
6459 if (!clang_isDeclaration(cursor.kind))
6460 return CXVisibility_Invalid;
6461
6462 const Decl *D = cxcursor::getCursorDecl(cursor);
6463 if (const NamedDecl *ND = dyn_cast_or_null<NamedDecl>(D))
6464 switch (ND->getVisibility()) {
6465 case HiddenVisibility: return CXVisibility_Hidden;
6466 case ProtectedVisibility: return CXVisibility_Protected;
6467 case DefaultVisibility: return CXVisibility_Default;
6468 };
6469
6470 return CXVisibility_Invalid;
6471}
6472} // end: extern "C"
6473
6474//===----------------------------------------------------------------------===//
Guy Benyei11169dd2012-12-18 14:30:41 +00006475// Operations for querying language of a cursor.
6476//===----------------------------------------------------------------------===//
6477
6478static CXLanguageKind getDeclLanguage(const Decl *D) {
6479 if (!D)
6480 return CXLanguage_C;
6481
6482 switch (D->getKind()) {
6483 default:
6484 break;
6485 case Decl::ImplicitParam:
6486 case Decl::ObjCAtDefsField:
6487 case Decl::ObjCCategory:
6488 case Decl::ObjCCategoryImpl:
6489 case Decl::ObjCCompatibleAlias:
6490 case Decl::ObjCImplementation:
6491 case Decl::ObjCInterface:
6492 case Decl::ObjCIvar:
6493 case Decl::ObjCMethod:
6494 case Decl::ObjCProperty:
6495 case Decl::ObjCPropertyImpl:
6496 case Decl::ObjCProtocol:
Douglas Gregor85f3f952015-07-07 03:57:15 +00006497 case Decl::ObjCTypeParam:
Guy Benyei11169dd2012-12-18 14:30:41 +00006498 return CXLanguage_ObjC;
6499 case Decl::CXXConstructor:
6500 case Decl::CXXConversion:
6501 case Decl::CXXDestructor:
6502 case Decl::CXXMethod:
6503 case Decl::CXXRecord:
6504 case Decl::ClassTemplate:
6505 case Decl::ClassTemplatePartialSpecialization:
6506 case Decl::ClassTemplateSpecialization:
6507 case Decl::Friend:
6508 case Decl::FriendTemplate:
6509 case Decl::FunctionTemplate:
6510 case Decl::LinkageSpec:
6511 case Decl::Namespace:
6512 case Decl::NamespaceAlias:
6513 case Decl::NonTypeTemplateParm:
6514 case Decl::StaticAssert:
6515 case Decl::TemplateTemplateParm:
6516 case Decl::TemplateTypeParm:
6517 case Decl::UnresolvedUsingTypename:
6518 case Decl::UnresolvedUsingValue:
6519 case Decl::Using:
6520 case Decl::UsingDirective:
6521 case Decl::UsingShadow:
6522 return CXLanguage_CPlusPlus;
6523 }
6524
6525 return CXLanguage_C;
6526}
6527
6528extern "C" {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006529
6530static CXAvailabilityKind getCursorAvailabilityForDecl(const Decl *D) {
6531 if (isa<FunctionDecl>(D) && cast<FunctionDecl>(D)->isDeleted())
Manuel Klimek8e3a7ed2015-09-25 17:53:16 +00006532 return CXAvailability_NotAvailable;
Guy Benyei11169dd2012-12-18 14:30:41 +00006533
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006534 switch (D->getAvailability()) {
6535 case AR_Available:
6536 case AR_NotYetIntroduced:
6537 if (const EnumConstantDecl *EnumConst = dyn_cast<EnumConstantDecl>(D))
Benjamin Kramer656363d2013-10-15 18:53:18 +00006538 return getCursorAvailabilityForDecl(
6539 cast<Decl>(EnumConst->getDeclContext()));
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006540 return CXAvailability_Available;
6541
6542 case AR_Deprecated:
6543 return CXAvailability_Deprecated;
6544
6545 case AR_Unavailable:
6546 return CXAvailability_NotAvailable;
6547 }
Benjamin Kramer656363d2013-10-15 18:53:18 +00006548
6549 llvm_unreachable("Unknown availability kind!");
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006550}
6551
Guy Benyei11169dd2012-12-18 14:30:41 +00006552enum CXAvailabilityKind clang_getCursorAvailability(CXCursor cursor) {
6553 if (clang_isDeclaration(cursor.kind))
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006554 if (const Decl *D = cxcursor::getCursorDecl(cursor))
6555 return getCursorAvailabilityForDecl(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00006556
6557 return CXAvailability_Available;
6558}
6559
6560static CXVersion convertVersion(VersionTuple In) {
6561 CXVersion Out = { -1, -1, -1 };
6562 if (In.empty())
6563 return Out;
6564
6565 Out.Major = In.getMajor();
6566
NAKAMURA Takumic2b5d1f2013-02-21 02:32:34 +00006567 Optional<unsigned> Minor = In.getMinor();
6568 if (Minor.hasValue())
Guy Benyei11169dd2012-12-18 14:30:41 +00006569 Out.Minor = *Minor;
6570 else
6571 return Out;
6572
NAKAMURA Takumic2b5d1f2013-02-21 02:32:34 +00006573 Optional<unsigned> Subminor = In.getSubminor();
6574 if (Subminor.hasValue())
Guy Benyei11169dd2012-12-18 14:30:41 +00006575 Out.Subminor = *Subminor;
6576
6577 return Out;
6578}
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006579
6580static int getCursorPlatformAvailabilityForDecl(const Decl *D,
6581 int *always_deprecated,
6582 CXString *deprecated_message,
6583 int *always_unavailable,
6584 CXString *unavailable_message,
6585 CXPlatformAvailability *availability,
6586 int availability_size) {
6587 bool HadAvailAttr = false;
6588 int N = 0;
Aaron Ballmanb97112e2014-03-08 22:19:01 +00006589 for (auto A : D->attrs()) {
6590 if (DeprecatedAttr *Deprecated = dyn_cast<DeprecatedAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006591 HadAvailAttr = true;
6592 if (always_deprecated)
6593 *always_deprecated = 1;
Nico Weberaacf0312014-04-24 05:16:45 +00006594 if (deprecated_message) {
Argyrios Kyrtzidisedfe07f2014-04-24 06:05:40 +00006595 clang_disposeString(*deprecated_message);
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006596 *deprecated_message = cxstring::createDup(Deprecated->getMessage());
Nico Weberaacf0312014-04-24 05:16:45 +00006597 }
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006598 continue;
6599 }
6600
Aaron Ballmanb97112e2014-03-08 22:19:01 +00006601 if (UnavailableAttr *Unavailable = dyn_cast<UnavailableAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006602 HadAvailAttr = true;
6603 if (always_unavailable)
6604 *always_unavailable = 1;
6605 if (unavailable_message) {
Argyrios Kyrtzidisedfe07f2014-04-24 06:05:40 +00006606 clang_disposeString(*unavailable_message);
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006607 *unavailable_message = cxstring::createDup(Unavailable->getMessage());
6608 }
6609 continue;
6610 }
6611
Aaron Ballmanb97112e2014-03-08 22:19:01 +00006612 if (AvailabilityAttr *Avail = dyn_cast<AvailabilityAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006613 HadAvailAttr = true;
6614 if (N < availability_size) {
6615 availability[N].Platform
6616 = cxstring::createDup(Avail->getPlatform()->getName());
6617 availability[N].Introduced = convertVersion(Avail->getIntroduced());
6618 availability[N].Deprecated = convertVersion(Avail->getDeprecated());
6619 availability[N].Obsoleted = convertVersion(Avail->getObsoleted());
6620 availability[N].Unavailable = Avail->getUnavailable();
6621 availability[N].Message = cxstring::createDup(Avail->getMessage());
6622 }
6623 ++N;
6624 }
6625 }
6626
6627 if (!HadAvailAttr)
6628 if (const EnumConstantDecl *EnumConst = dyn_cast<EnumConstantDecl>(D))
6629 return getCursorPlatformAvailabilityForDecl(
6630 cast<Decl>(EnumConst->getDeclContext()),
6631 always_deprecated,
6632 deprecated_message,
6633 always_unavailable,
6634 unavailable_message,
6635 availability,
6636 availability_size);
Guy Benyei11169dd2012-12-18 14:30:41 +00006637
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006638 return N;
6639}
6640
Guy Benyei11169dd2012-12-18 14:30:41 +00006641int clang_getCursorPlatformAvailability(CXCursor cursor,
6642 int *always_deprecated,
6643 CXString *deprecated_message,
6644 int *always_unavailable,
6645 CXString *unavailable_message,
6646 CXPlatformAvailability *availability,
6647 int availability_size) {
6648 if (always_deprecated)
6649 *always_deprecated = 0;
6650 if (deprecated_message)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006651 *deprecated_message = cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006652 if (always_unavailable)
6653 *always_unavailable = 0;
6654 if (unavailable_message)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006655 *unavailable_message = cxstring::createEmpty();
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006656
Guy Benyei11169dd2012-12-18 14:30:41 +00006657 if (!clang_isDeclaration(cursor.kind))
6658 return 0;
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006659
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006660 const Decl *D = cxcursor::getCursorDecl(cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00006661 if (!D)
6662 return 0;
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006663
6664 return getCursorPlatformAvailabilityForDecl(D, always_deprecated,
6665 deprecated_message,
6666 always_unavailable,
6667 unavailable_message,
6668 availability,
6669 availability_size);
Guy Benyei11169dd2012-12-18 14:30:41 +00006670}
6671
6672void clang_disposeCXPlatformAvailability(CXPlatformAvailability *availability) {
6673 clang_disposeString(availability->Platform);
6674 clang_disposeString(availability->Message);
6675}
6676
6677CXLanguageKind clang_getCursorLanguage(CXCursor cursor) {
6678 if (clang_isDeclaration(cursor.kind))
6679 return getDeclLanguage(cxcursor::getCursorDecl(cursor));
6680
6681 return CXLanguage_Invalid;
6682}
6683
6684 /// \brief If the given cursor is the "templated" declaration
6685 /// descibing a class or function template, return the class or
6686 /// function template.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006687static const Decl *maybeGetTemplateCursor(const Decl *D) {
Guy Benyei11169dd2012-12-18 14:30:41 +00006688 if (!D)
Craig Topper69186e72014-06-08 08:38:04 +00006689 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006690
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006691 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00006692 if (FunctionTemplateDecl *FunTmpl = FD->getDescribedFunctionTemplate())
6693 return FunTmpl;
6694
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006695 if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00006696 if (ClassTemplateDecl *ClassTmpl = RD->getDescribedClassTemplate())
6697 return ClassTmpl;
6698
6699 return D;
6700}
6701
Argyrios Kyrtzidis4e0854f2014-10-15 17:05:31 +00006702
6703enum CX_StorageClass clang_Cursor_getStorageClass(CXCursor C) {
6704 StorageClass sc = SC_None;
6705 const Decl *D = getCursorDecl(C);
6706 if (D) {
6707 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
6708 sc = FD->getStorageClass();
6709 } else if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
6710 sc = VD->getStorageClass();
6711 } else {
6712 return CX_SC_Invalid;
6713 }
6714 } else {
6715 return CX_SC_Invalid;
6716 }
6717 switch (sc) {
6718 case SC_None:
6719 return CX_SC_None;
6720 case SC_Extern:
6721 return CX_SC_Extern;
6722 case SC_Static:
6723 return CX_SC_Static;
6724 case SC_PrivateExtern:
6725 return CX_SC_PrivateExtern;
Argyrios Kyrtzidis4e0854f2014-10-15 17:05:31 +00006726 case SC_Auto:
6727 return CX_SC_Auto;
6728 case SC_Register:
6729 return CX_SC_Register;
Argyrios Kyrtzidis4e0854f2014-10-15 17:05:31 +00006730 }
Kaelyn Takataab61e702014-10-15 18:03:26 +00006731 llvm_unreachable("Unhandled storage class!");
Argyrios Kyrtzidis4e0854f2014-10-15 17:05:31 +00006732}
6733
Guy Benyei11169dd2012-12-18 14:30:41 +00006734CXCursor clang_getCursorSemanticParent(CXCursor cursor) {
6735 if (clang_isDeclaration(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006736 if (const Decl *D = getCursorDecl(cursor)) {
6737 const DeclContext *DC = D->getDeclContext();
Guy Benyei11169dd2012-12-18 14:30:41 +00006738 if (!DC)
6739 return clang_getNullCursor();
6740
6741 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
6742 getCursorTU(cursor));
6743 }
6744 }
6745
6746 if (clang_isStatement(cursor.kind) || clang_isExpression(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006747 if (const Decl *D = getCursorDecl(cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +00006748 return MakeCXCursor(D, getCursorTU(cursor));
6749 }
6750
6751 return clang_getNullCursor();
6752}
6753
6754CXCursor clang_getCursorLexicalParent(CXCursor cursor) {
6755 if (clang_isDeclaration(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006756 if (const Decl *D = getCursorDecl(cursor)) {
6757 const DeclContext *DC = D->getLexicalDeclContext();
Guy Benyei11169dd2012-12-18 14:30:41 +00006758 if (!DC)
6759 return clang_getNullCursor();
6760
6761 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
6762 getCursorTU(cursor));
6763 }
6764 }
6765
6766 // FIXME: Note that we can't easily compute the lexical context of a
6767 // statement or expression, so we return nothing.
6768 return clang_getNullCursor();
6769}
6770
6771CXFile clang_getIncludedFile(CXCursor cursor) {
6772 if (cursor.kind != CXCursor_InclusionDirective)
Craig Topper69186e72014-06-08 08:38:04 +00006773 return nullptr;
6774
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00006775 const InclusionDirective *ID = getCursorInclusionDirective(cursor);
Dmitri Gribenkof9304482013-01-23 15:56:07 +00006776 return const_cast<FileEntry *>(ID->getFile());
Guy Benyei11169dd2012-12-18 14:30:41 +00006777}
6778
Argyrios Kyrtzidis9adfd8a2013-04-18 22:15:49 +00006779unsigned clang_Cursor_getObjCPropertyAttributes(CXCursor C, unsigned reserved) {
6780 if (C.kind != CXCursor_ObjCPropertyDecl)
6781 return CXObjCPropertyAttr_noattr;
6782
6783 unsigned Result = CXObjCPropertyAttr_noattr;
6784 const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(getCursorDecl(C));
6785 ObjCPropertyDecl::PropertyAttributeKind Attr =
6786 PD->getPropertyAttributesAsWritten();
6787
6788#define SET_CXOBJCPROP_ATTR(A) \
6789 if (Attr & ObjCPropertyDecl::OBJC_PR_##A) \
6790 Result |= CXObjCPropertyAttr_##A
6791 SET_CXOBJCPROP_ATTR(readonly);
6792 SET_CXOBJCPROP_ATTR(getter);
6793 SET_CXOBJCPROP_ATTR(assign);
6794 SET_CXOBJCPROP_ATTR(readwrite);
6795 SET_CXOBJCPROP_ATTR(retain);
6796 SET_CXOBJCPROP_ATTR(copy);
6797 SET_CXOBJCPROP_ATTR(nonatomic);
6798 SET_CXOBJCPROP_ATTR(setter);
6799 SET_CXOBJCPROP_ATTR(atomic);
6800 SET_CXOBJCPROP_ATTR(weak);
6801 SET_CXOBJCPROP_ATTR(strong);
6802 SET_CXOBJCPROP_ATTR(unsafe_unretained);
6803#undef SET_CXOBJCPROP_ATTR
6804
6805 return Result;
6806}
6807
Argyrios Kyrtzidis9d9bc012013-04-18 23:29:12 +00006808unsigned clang_Cursor_getObjCDeclQualifiers(CXCursor C) {
6809 if (!clang_isDeclaration(C.kind))
6810 return CXObjCDeclQualifier_None;
6811
6812 Decl::ObjCDeclQualifier QT = Decl::OBJC_TQ_None;
6813 const Decl *D = getCursorDecl(C);
6814 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6815 QT = MD->getObjCDeclQualifier();
6816 else if (const ParmVarDecl *PD = dyn_cast<ParmVarDecl>(D))
6817 QT = PD->getObjCDeclQualifier();
6818 if (QT == Decl::OBJC_TQ_None)
6819 return CXObjCDeclQualifier_None;
6820
6821 unsigned Result = CXObjCDeclQualifier_None;
6822 if (QT & Decl::OBJC_TQ_In) Result |= CXObjCDeclQualifier_In;
6823 if (QT & Decl::OBJC_TQ_Inout) Result |= CXObjCDeclQualifier_Inout;
6824 if (QT & Decl::OBJC_TQ_Out) Result |= CXObjCDeclQualifier_Out;
6825 if (QT & Decl::OBJC_TQ_Bycopy) Result |= CXObjCDeclQualifier_Bycopy;
6826 if (QT & Decl::OBJC_TQ_Byref) Result |= CXObjCDeclQualifier_Byref;
6827 if (QT & Decl::OBJC_TQ_Oneway) Result |= CXObjCDeclQualifier_Oneway;
6828
6829 return Result;
6830}
6831
Argyrios Kyrtzidis7b50fc52013-07-05 20:44:37 +00006832unsigned clang_Cursor_isObjCOptional(CXCursor C) {
6833 if (!clang_isDeclaration(C.kind))
6834 return 0;
6835
6836 const Decl *D = getCursorDecl(C);
6837 if (const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(D))
6838 return PD->getPropertyImplementation() == ObjCPropertyDecl::Optional;
6839 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6840 return MD->getImplementationControl() == ObjCMethodDecl::Optional;
6841
6842 return 0;
6843}
6844
Argyrios Kyrtzidis23814e42013-04-18 23:53:05 +00006845unsigned clang_Cursor_isVariadic(CXCursor C) {
6846 if (!clang_isDeclaration(C.kind))
6847 return 0;
6848
6849 const Decl *D = getCursorDecl(C);
6850 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
6851 return FD->isVariadic();
6852 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6853 return MD->isVariadic();
6854
6855 return 0;
6856}
6857
Guy Benyei11169dd2012-12-18 14:30:41 +00006858CXSourceRange clang_Cursor_getCommentRange(CXCursor C) {
6859 if (!clang_isDeclaration(C.kind))
6860 return clang_getNullRange();
6861
6862 const Decl *D = getCursorDecl(C);
6863 ASTContext &Context = getCursorContext(C);
6864 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6865 if (!RC)
6866 return clang_getNullRange();
6867
6868 return cxloc::translateSourceRange(Context, RC->getSourceRange());
6869}
6870
6871CXString clang_Cursor_getRawCommentText(CXCursor C) {
6872 if (!clang_isDeclaration(C.kind))
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006873 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006874
6875 const Decl *D = getCursorDecl(C);
6876 ASTContext &Context = getCursorContext(C);
6877 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6878 StringRef RawText = RC ? RC->getRawText(Context.getSourceManager()) :
6879 StringRef();
6880
6881 // Don't duplicate the string because RawText points directly into source
6882 // code.
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006883 return cxstring::createRef(RawText);
Guy Benyei11169dd2012-12-18 14:30:41 +00006884}
6885
6886CXString clang_Cursor_getBriefCommentText(CXCursor C) {
6887 if (!clang_isDeclaration(C.kind))
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006888 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006889
6890 const Decl *D = getCursorDecl(C);
6891 const ASTContext &Context = getCursorContext(C);
6892 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6893
6894 if (RC) {
6895 StringRef BriefText = RC->getBriefText(Context);
6896
6897 // Don't duplicate the string because RawComment ensures that this memory
6898 // will not go away.
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006899 return cxstring::createRef(BriefText);
Guy Benyei11169dd2012-12-18 14:30:41 +00006900 }
6901
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006902 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006903}
6904
Guy Benyei11169dd2012-12-18 14:30:41 +00006905CXModule clang_Cursor_getModule(CXCursor C) {
6906 if (C.kind == CXCursor_ModuleImportDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006907 if (const ImportDecl *ImportD =
6908 dyn_cast_or_null<ImportDecl>(getCursorDecl(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00006909 return ImportD->getImportedModule();
6910 }
6911
Craig Topper69186e72014-06-08 08:38:04 +00006912 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006913}
6914
Argyrios Kyrtzidisf6d49c32014-05-14 23:14:37 +00006915CXModule clang_getModuleForFile(CXTranslationUnit TU, CXFile File) {
6916 if (isNotUsableTU(TU)) {
6917 LOG_BAD_TU(TU);
6918 return nullptr;
6919 }
6920 if (!File)
6921 return nullptr;
6922 FileEntry *FE = static_cast<FileEntry *>(File);
6923
6924 ASTUnit &Unit = *cxtu::getASTUnit(TU);
6925 HeaderSearch &HS = Unit.getPreprocessor().getHeaderSearchInfo();
6926 ModuleMap::KnownHeader Header = HS.findModuleForHeader(FE);
6927
Richard Smithfeb54b62014-10-23 02:01:19 +00006928 return Header.getModule();
Argyrios Kyrtzidisf6d49c32014-05-14 23:14:37 +00006929}
6930
Argyrios Kyrtzidis12fdb9e2013-04-26 22:47:49 +00006931CXFile clang_Module_getASTFile(CXModule CXMod) {
6932 if (!CXMod)
Craig Topper69186e72014-06-08 08:38:04 +00006933 return nullptr;
Argyrios Kyrtzidis12fdb9e2013-04-26 22:47:49 +00006934 Module *Mod = static_cast<Module*>(CXMod);
6935 return const_cast<FileEntry *>(Mod->getASTFile());
6936}
6937
Guy Benyei11169dd2012-12-18 14:30:41 +00006938CXModule clang_Module_getParent(CXModule CXMod) {
6939 if (!CXMod)
Craig Topper69186e72014-06-08 08:38:04 +00006940 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006941 Module *Mod = static_cast<Module*>(CXMod);
6942 return Mod->Parent;
6943}
6944
6945CXString clang_Module_getName(CXModule CXMod) {
6946 if (!CXMod)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006947 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006948 Module *Mod = static_cast<Module*>(CXMod);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006949 return cxstring::createDup(Mod->Name);
Guy Benyei11169dd2012-12-18 14:30:41 +00006950}
6951
6952CXString clang_Module_getFullName(CXModule CXMod) {
6953 if (!CXMod)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006954 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006955 Module *Mod = static_cast<Module*>(CXMod);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006956 return cxstring::createDup(Mod->getFullModuleName());
Guy Benyei11169dd2012-12-18 14:30:41 +00006957}
6958
Argyrios Kyrtzidis884337f2014-05-15 04:44:25 +00006959int clang_Module_isSystem(CXModule CXMod) {
6960 if (!CXMod)
6961 return 0;
6962 Module *Mod = static_cast<Module*>(CXMod);
6963 return Mod->IsSystem;
6964}
6965
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006966unsigned clang_Module_getNumTopLevelHeaders(CXTranslationUnit TU,
6967 CXModule CXMod) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006968 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006969 LOG_BAD_TU(TU);
6970 return 0;
6971 }
6972 if (!CXMod)
Guy Benyei11169dd2012-12-18 14:30:41 +00006973 return 0;
6974 Module *Mod = static_cast<Module*>(CXMod);
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006975 FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
6976 ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
6977 return TopHeaders.size();
Guy Benyei11169dd2012-12-18 14:30:41 +00006978}
6979
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006980CXFile clang_Module_getTopLevelHeader(CXTranslationUnit TU,
6981 CXModule CXMod, unsigned Index) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006982 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006983 LOG_BAD_TU(TU);
Craig Topper69186e72014-06-08 08:38:04 +00006984 return nullptr;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006985 }
6986 if (!CXMod)
Craig Topper69186e72014-06-08 08:38:04 +00006987 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006988 Module *Mod = static_cast<Module*>(CXMod);
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006989 FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
Guy Benyei11169dd2012-12-18 14:30:41 +00006990
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006991 ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
6992 if (Index < TopHeaders.size())
6993 return const_cast<FileEntry *>(TopHeaders[Index]);
Guy Benyei11169dd2012-12-18 14:30:41 +00006994
Craig Topper69186e72014-06-08 08:38:04 +00006995 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006996}
6997
6998} // end: extern "C"
6999
7000//===----------------------------------------------------------------------===//
7001// C++ AST instrospection.
7002//===----------------------------------------------------------------------===//
7003
7004extern "C" {
Saleem Abdulrasool6ea75db2015-10-27 15:50:22 +00007005unsigned clang_CXXField_isMutable(CXCursor C) {
7006 if (!clang_isDeclaration(C.kind))
7007 return 0;
7008
7009 if (const auto D = cxcursor::getCursorDecl(C))
7010 if (const auto FD = dyn_cast_or_null<FieldDecl>(D))
7011 return FD->isMutable() ? 1 : 0;
7012 return 0;
7013}
7014
Dmitri Gribenko62770be2013-05-17 18:38:35 +00007015unsigned clang_CXXMethod_isPureVirtual(CXCursor C) {
7016 if (!clang_isDeclaration(C.kind))
7017 return 0;
7018
Dmitri Gribenko62770be2013-05-17 18:38:35 +00007019 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00007020 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00007021 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Dmitri Gribenko62770be2013-05-17 18:38:35 +00007022 return (Method && Method->isVirtual() && Method->isPure()) ? 1 : 0;
7023}
7024
Dmitri Gribenkoe570ede2014-04-07 14:59:13 +00007025unsigned clang_CXXMethod_isConst(CXCursor C) {
7026 if (!clang_isDeclaration(C.kind))
7027 return 0;
7028
7029 const Decl *D = cxcursor::getCursorDecl(C);
7030 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00007031 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Dmitri Gribenkoe570ede2014-04-07 14:59:13 +00007032 return (Method && (Method->getTypeQualifiers() & Qualifiers::Const)) ? 1 : 0;
7033}
7034
Guy Benyei11169dd2012-12-18 14:30:41 +00007035unsigned clang_CXXMethod_isStatic(CXCursor C) {
7036 if (!clang_isDeclaration(C.kind))
7037 return 0;
7038
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00007039 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00007040 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00007041 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00007042 return (Method && Method->isStatic()) ? 1 : 0;
7043}
7044
7045unsigned clang_CXXMethod_isVirtual(CXCursor C) {
7046 if (!clang_isDeclaration(C.kind))
7047 return 0;
7048
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00007049 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00007050 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00007051 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00007052 return (Method && Method->isVirtual()) ? 1 : 0;
7053}
7054} // end: extern "C"
7055
7056//===----------------------------------------------------------------------===//
7057// Attribute introspection.
7058//===----------------------------------------------------------------------===//
7059
7060extern "C" {
7061CXType clang_getIBOutletCollectionType(CXCursor C) {
7062 if (C.kind != CXCursor_IBOutletCollectionAttr)
7063 return cxtype::MakeCXType(QualType(), cxcursor::getCursorTU(C));
7064
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00007065 const IBOutletCollectionAttr *A =
Guy Benyei11169dd2012-12-18 14:30:41 +00007066 cast<IBOutletCollectionAttr>(cxcursor::getCursorAttr(C));
7067
7068 return cxtype::MakeCXType(A->getInterface(), cxcursor::getCursorTU(C));
7069}
7070} // end: extern "C"
7071
7072//===----------------------------------------------------------------------===//
7073// Inspecting memory usage.
7074//===----------------------------------------------------------------------===//
7075
7076typedef std::vector<CXTUResourceUsageEntry> MemUsageEntries;
7077
7078static inline void createCXTUResourceUsageEntry(MemUsageEntries &entries,
7079 enum CXTUResourceUsageKind k,
7080 unsigned long amount) {
7081 CXTUResourceUsageEntry entry = { k, amount };
7082 entries.push_back(entry);
7083}
7084
7085extern "C" {
7086
7087const char *clang_getTUResourceUsageName(CXTUResourceUsageKind kind) {
7088 const char *str = "";
7089 switch (kind) {
7090 case CXTUResourceUsage_AST:
7091 str = "ASTContext: expressions, declarations, and types";
7092 break;
7093 case CXTUResourceUsage_Identifiers:
7094 str = "ASTContext: identifiers";
7095 break;
7096 case CXTUResourceUsage_Selectors:
7097 str = "ASTContext: selectors";
7098 break;
7099 case CXTUResourceUsage_GlobalCompletionResults:
7100 str = "Code completion: cached global results";
7101 break;
7102 case CXTUResourceUsage_SourceManagerContentCache:
7103 str = "SourceManager: content cache allocator";
7104 break;
7105 case CXTUResourceUsage_AST_SideTables:
7106 str = "ASTContext: side tables";
7107 break;
7108 case CXTUResourceUsage_SourceManager_Membuffer_Malloc:
7109 str = "SourceManager: malloc'ed memory buffers";
7110 break;
7111 case CXTUResourceUsage_SourceManager_Membuffer_MMap:
7112 str = "SourceManager: mmap'ed memory buffers";
7113 break;
7114 case CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc:
7115 str = "ExternalASTSource: malloc'ed memory buffers";
7116 break;
7117 case CXTUResourceUsage_ExternalASTSource_Membuffer_MMap:
7118 str = "ExternalASTSource: mmap'ed memory buffers";
7119 break;
7120 case CXTUResourceUsage_Preprocessor:
7121 str = "Preprocessor: malloc'ed memory";
7122 break;
7123 case CXTUResourceUsage_PreprocessingRecord:
7124 str = "Preprocessor: PreprocessingRecord";
7125 break;
7126 case CXTUResourceUsage_SourceManager_DataStructures:
7127 str = "SourceManager: data structures and tables";
7128 break;
7129 case CXTUResourceUsage_Preprocessor_HeaderSearch:
7130 str = "Preprocessor: header search tables";
7131 break;
7132 }
7133 return str;
7134}
7135
7136CXTUResourceUsage clang_getCXTUResourceUsage(CXTranslationUnit TU) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00007137 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00007138 LOG_BAD_TU(TU);
Craig Topper69186e72014-06-08 08:38:04 +00007139 CXTUResourceUsage usage = { (void*) nullptr, 0, nullptr };
Guy Benyei11169dd2012-12-18 14:30:41 +00007140 return usage;
7141 }
7142
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007143 ASTUnit *astUnit = cxtu::getASTUnit(TU);
Ahmed Charlesb8984322014-03-07 20:03:18 +00007144 std::unique_ptr<MemUsageEntries> entries(new MemUsageEntries());
Guy Benyei11169dd2012-12-18 14:30:41 +00007145 ASTContext &astContext = astUnit->getASTContext();
7146
7147 // How much memory is used by AST nodes and types?
7148 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST,
7149 (unsigned long) astContext.getASTAllocatedMemory());
7150
7151 // How much memory is used by identifiers?
7152 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Identifiers,
7153 (unsigned long) astContext.Idents.getAllocator().getTotalMemory());
7154
7155 // How much memory is used for selectors?
7156 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Selectors,
7157 (unsigned long) astContext.Selectors.getTotalMemory());
7158
7159 // How much memory is used by ASTContext's side tables?
7160 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST_SideTables,
7161 (unsigned long) astContext.getSideTableAllocatedMemory());
7162
7163 // How much memory is used for caching global code completion results?
7164 unsigned long completionBytes = 0;
7165 if (GlobalCodeCompletionAllocator *completionAllocator =
Alp Tokerf994cef2014-07-05 03:08:06 +00007166 astUnit->getCachedCompletionAllocator().get()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00007167 completionBytes = completionAllocator->getTotalMemory();
7168 }
7169 createCXTUResourceUsageEntry(*entries,
7170 CXTUResourceUsage_GlobalCompletionResults,
7171 completionBytes);
7172
7173 // How much memory is being used by SourceManager's content cache?
7174 createCXTUResourceUsageEntry(*entries,
7175 CXTUResourceUsage_SourceManagerContentCache,
7176 (unsigned long) astContext.getSourceManager().getContentCacheSize());
7177
7178 // How much memory is being used by the MemoryBuffer's in SourceManager?
7179 const SourceManager::MemoryBufferSizes &srcBufs =
7180 astUnit->getSourceManager().getMemoryBufferSizes();
7181
7182 createCXTUResourceUsageEntry(*entries,
7183 CXTUResourceUsage_SourceManager_Membuffer_Malloc,
7184 (unsigned long) srcBufs.malloc_bytes);
7185 createCXTUResourceUsageEntry(*entries,
7186 CXTUResourceUsage_SourceManager_Membuffer_MMap,
7187 (unsigned long) srcBufs.mmap_bytes);
7188 createCXTUResourceUsageEntry(*entries,
7189 CXTUResourceUsage_SourceManager_DataStructures,
7190 (unsigned long) astContext.getSourceManager()
7191 .getDataStructureSizes());
7192
7193 // How much memory is being used by the ExternalASTSource?
7194 if (ExternalASTSource *esrc = astContext.getExternalSource()) {
7195 const ExternalASTSource::MemoryBufferSizes &sizes =
7196 esrc->getMemoryBufferSizes();
7197
7198 createCXTUResourceUsageEntry(*entries,
7199 CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc,
7200 (unsigned long) sizes.malloc_bytes);
7201 createCXTUResourceUsageEntry(*entries,
7202 CXTUResourceUsage_ExternalASTSource_Membuffer_MMap,
7203 (unsigned long) sizes.mmap_bytes);
7204 }
7205
7206 // How much memory is being used by the Preprocessor?
7207 Preprocessor &pp = astUnit->getPreprocessor();
7208 createCXTUResourceUsageEntry(*entries,
7209 CXTUResourceUsage_Preprocessor,
7210 pp.getTotalMemory());
7211
7212 if (PreprocessingRecord *pRec = pp.getPreprocessingRecord()) {
7213 createCXTUResourceUsageEntry(*entries,
7214 CXTUResourceUsage_PreprocessingRecord,
7215 pRec->getTotalMemory());
7216 }
7217
7218 createCXTUResourceUsageEntry(*entries,
7219 CXTUResourceUsage_Preprocessor_HeaderSearch,
7220 pp.getHeaderSearchInfo().getTotalMemory());
Craig Topper69186e72014-06-08 08:38:04 +00007221
Guy Benyei11169dd2012-12-18 14:30:41 +00007222 CXTUResourceUsage usage = { (void*) entries.get(),
7223 (unsigned) entries->size(),
Alexander Kornienko6ee521c2015-01-23 15:36:10 +00007224 !entries->empty() ? &(*entries)[0] : nullptr };
Ahmed Charles9a16beb2014-03-07 19:33:25 +00007225 entries.release();
Guy Benyei11169dd2012-12-18 14:30:41 +00007226 return usage;
7227}
7228
7229void clang_disposeCXTUResourceUsage(CXTUResourceUsage usage) {
7230 if (usage.data)
7231 delete (MemUsageEntries*) usage.data;
7232}
7233
Argyrios Kyrtzidis0e282ef2013-12-06 18:55:45 +00007234CXSourceRangeList *clang_getSkippedRanges(CXTranslationUnit TU, CXFile file) {
7235 CXSourceRangeList *skipped = new CXSourceRangeList;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00007236 skipped->count = 0;
Craig Topper69186e72014-06-08 08:38:04 +00007237 skipped->ranges = nullptr;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00007238
Dmitri Gribenko852d6222014-02-11 15:02:48 +00007239 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00007240 LOG_BAD_TU(TU);
7241 return skipped;
7242 }
7243
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00007244 if (!file)
7245 return skipped;
7246
7247 ASTUnit *astUnit = cxtu::getASTUnit(TU);
7248 PreprocessingRecord *ppRec = astUnit->getPreprocessor().getPreprocessingRecord();
7249 if (!ppRec)
7250 return skipped;
7251
7252 ASTContext &Ctx = astUnit->getASTContext();
7253 SourceManager &sm = Ctx.getSourceManager();
7254 FileEntry *fileEntry = static_cast<FileEntry *>(file);
7255 FileID wantedFileID = sm.translateFile(fileEntry);
7256
7257 const std::vector<SourceRange> &SkippedRanges = ppRec->getSkippedRanges();
7258 std::vector<SourceRange> wantedRanges;
7259 for (std::vector<SourceRange>::const_iterator i = SkippedRanges.begin(), ei = SkippedRanges.end();
7260 i != ei; ++i) {
7261 if (sm.getFileID(i->getBegin()) == wantedFileID || sm.getFileID(i->getEnd()) == wantedFileID)
7262 wantedRanges.push_back(*i);
7263 }
7264
7265 skipped->count = wantedRanges.size();
7266 skipped->ranges = new CXSourceRange[skipped->count];
7267 for (unsigned i = 0, ei = skipped->count; i != ei; ++i)
7268 skipped->ranges[i] = cxloc::translateSourceRange(Ctx, wantedRanges[i]);
7269
7270 return skipped;
7271}
7272
Argyrios Kyrtzidis0e282ef2013-12-06 18:55:45 +00007273void clang_disposeSourceRangeList(CXSourceRangeList *ranges) {
7274 if (ranges) {
7275 delete[] ranges->ranges;
7276 delete ranges;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00007277 }
7278}
7279
Guy Benyei11169dd2012-12-18 14:30:41 +00007280} // end extern "C"
7281
7282void clang::PrintLibclangResourceUsage(CXTranslationUnit TU) {
7283 CXTUResourceUsage Usage = clang_getCXTUResourceUsage(TU);
7284 for (unsigned I = 0; I != Usage.numEntries; ++I)
7285 fprintf(stderr, " %s: %lu\n",
7286 clang_getTUResourceUsageName(Usage.entries[I].kind),
7287 Usage.entries[I].amount);
7288
7289 clang_disposeCXTUResourceUsage(Usage);
7290}
7291
7292//===----------------------------------------------------------------------===//
7293// Misc. utility functions.
7294//===----------------------------------------------------------------------===//
7295
7296/// Default to using an 8 MB stack size on "safety" threads.
7297static unsigned SafetyStackThreadSize = 8 << 20;
7298
7299namespace clang {
7300
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00007301bool RunSafely(llvm::CrashRecoveryContext &CRC, llvm::function_ref<void()> Fn,
Guy Benyei11169dd2012-12-18 14:30:41 +00007302 unsigned Size) {
7303 if (!Size)
7304 Size = GetSafetyThreadStackSize();
7305 if (Size)
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00007306 return CRC.RunSafelyOnThread(Fn, Size);
7307 return CRC.RunSafely(Fn);
Guy Benyei11169dd2012-12-18 14:30:41 +00007308}
7309
7310unsigned GetSafetyThreadStackSize() {
7311 return SafetyStackThreadSize;
7312}
7313
7314void SetSafetyThreadStackSize(unsigned Value) {
7315 SafetyStackThreadSize = Value;
7316}
7317
Alexander Kornienkoab9db512015-06-22 23:07:51 +00007318}
Guy Benyei11169dd2012-12-18 14:30:41 +00007319
7320void clang::setThreadBackgroundPriority() {
7321 if (getenv("LIBCLANG_BGPRIO_DISABLE"))
7322 return;
7323
Alp Toker1a86ad22014-07-06 06:24:00 +00007324#ifdef USE_DARWIN_THREADS
Guy Benyei11169dd2012-12-18 14:30:41 +00007325 setpriority(PRIO_DARWIN_THREAD, 0, PRIO_DARWIN_BG);
7326#endif
7327}
7328
7329void cxindex::printDiagsToStderr(ASTUnit *Unit) {
7330 if (!Unit)
7331 return;
7332
7333 for (ASTUnit::stored_diag_iterator D = Unit->stored_diag_begin(),
7334 DEnd = Unit->stored_diag_end();
7335 D != DEnd; ++D) {
Ben Langmuir749323f2014-04-22 17:40:12 +00007336 CXStoredDiagnostic Diag(*D, Unit->getLangOpts());
Guy Benyei11169dd2012-12-18 14:30:41 +00007337 CXString Msg = clang_formatDiagnostic(&Diag,
7338 clang_defaultDiagnosticDisplayOptions());
7339 fprintf(stderr, "%s\n", clang_getCString(Msg));
7340 clang_disposeString(Msg);
7341 }
7342#ifdef LLVM_ON_WIN32
7343 // On Windows, force a flush, since there may be multiple copies of
7344 // stderr and stdout in the file system, all with different buffers
7345 // but writing to the same device.
7346 fflush(stderr);
7347#endif
7348}
7349
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007350MacroInfo *cxindex::getMacroInfo(const IdentifierInfo &II,
7351 SourceLocation MacroDefLoc,
7352 CXTranslationUnit TU){
7353 if (MacroDefLoc.isInvalid() || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00007354 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007355 if (!II.hadMacroDefinition())
Craig Topper69186e72014-06-08 08:38:04 +00007356 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007357
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007358 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00007359 Preprocessor &PP = Unit->getPreprocessor();
Richard Smith20e883e2015-04-29 23:20:19 +00007360 MacroDirective *MD = PP.getLocalMacroDirectiveHistory(&II);
Argyrios Kyrtzidisb6210df2013-03-26 17:17:01 +00007361 if (MD) {
7362 for (MacroDirective::DefInfo
7363 Def = MD->getDefinition(); Def; Def = Def.getPreviousDefinition()) {
7364 if (MacroDefLoc == Def.getMacroInfo()->getDefinitionLoc())
7365 return Def.getMacroInfo();
7366 }
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007367 }
7368
Craig Topper69186e72014-06-08 08:38:04 +00007369 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007370}
7371
Richard Smith66a81862015-05-04 02:25:31 +00007372const MacroInfo *cxindex::getMacroInfo(const MacroDefinitionRecord *MacroDef,
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00007373 CXTranslationUnit TU) {
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007374 if (!MacroDef || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00007375 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007376 const IdentifierInfo *II = MacroDef->getName();
7377 if (!II)
Craig Topper69186e72014-06-08 08:38:04 +00007378 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007379
7380 return getMacroInfo(*II, MacroDef->getLocation(), TU);
7381}
7382
Richard Smith66a81862015-05-04 02:25:31 +00007383MacroDefinitionRecord *
7384cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI, const Token &Tok,
7385 CXTranslationUnit TU) {
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007386 if (!MI || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00007387 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007388 if (Tok.isNot(tok::raw_identifier))
Craig Topper69186e72014-06-08 08:38:04 +00007389 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007390
7391 if (MI->getNumTokens() == 0)
Craig Topper69186e72014-06-08 08:38:04 +00007392 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007393 SourceRange DefRange(MI->getReplacementToken(0).getLocation(),
7394 MI->getDefinitionEndLoc());
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007395 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007396
7397 // Check that the token is inside the definition and not its argument list.
7398 SourceManager &SM = Unit->getSourceManager();
7399 if (SM.isBeforeInTranslationUnit(Tok.getLocation(), DefRange.getBegin()))
Craig Topper69186e72014-06-08 08:38:04 +00007400 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007401 if (SM.isBeforeInTranslationUnit(DefRange.getEnd(), Tok.getLocation()))
Craig Topper69186e72014-06-08 08:38:04 +00007402 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007403
7404 Preprocessor &PP = Unit->getPreprocessor();
7405 PreprocessingRecord *PPRec = PP.getPreprocessingRecord();
7406 if (!PPRec)
Craig Topper69186e72014-06-08 08:38:04 +00007407 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007408
Alp Toker2d57cea2014-05-17 04:53:25 +00007409 IdentifierInfo &II = PP.getIdentifierTable().get(Tok.getRawIdentifier());
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007410 if (!II.hadMacroDefinition())
Craig Topper69186e72014-06-08 08:38:04 +00007411 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007412
7413 // Check that the identifier is not one of the macro arguments.
7414 if (std::find(MI->arg_begin(), MI->arg_end(), &II) != MI->arg_end())
Craig Topper69186e72014-06-08 08:38:04 +00007415 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007416
Richard Smith20e883e2015-04-29 23:20:19 +00007417 MacroDirective *InnerMD = PP.getLocalMacroDirectiveHistory(&II);
Argyrios Kyrtzidis09c9e812013-02-20 00:54:57 +00007418 if (!InnerMD)
Craig Topper69186e72014-06-08 08:38:04 +00007419 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007420
Argyrios Kyrtzidisb6210df2013-03-26 17:17:01 +00007421 return PPRec->findMacroDefinition(InnerMD->getMacroInfo());
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007422}
7423
Richard Smith66a81862015-05-04 02:25:31 +00007424MacroDefinitionRecord *
7425cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI, SourceLocation Loc,
7426 CXTranslationUnit TU) {
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007427 if (Loc.isInvalid() || !MI || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00007428 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007429
7430 if (MI->getNumTokens() == 0)
Craig Topper69186e72014-06-08 08:38:04 +00007431 return nullptr;
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007432 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007433 Preprocessor &PP = Unit->getPreprocessor();
7434 if (!PP.getPreprocessingRecord())
Craig Topper69186e72014-06-08 08:38:04 +00007435 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007436 Loc = Unit->getSourceManager().getSpellingLoc(Loc);
7437 Token Tok;
7438 if (PP.getRawToken(Loc, Tok))
Craig Topper69186e72014-06-08 08:38:04 +00007439 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007440
7441 return checkForMacroInMacroDefinition(MI, Tok, TU);
7442}
7443
Guy Benyei11169dd2012-12-18 14:30:41 +00007444extern "C" {
7445
7446CXString clang_getClangVersion() {
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00007447 return cxstring::createDup(getClangFullVersion());
Guy Benyei11169dd2012-12-18 14:30:41 +00007448}
7449
7450} // end: extern "C"
7451
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007452Logger &cxindex::Logger::operator<<(CXTranslationUnit TU) {
7453 if (TU) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007454 if (ASTUnit *Unit = cxtu::getASTUnit(TU)) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007455 LogOS << '<' << Unit->getMainFileName() << '>';
Argyrios Kyrtzidis37f2ab42013-03-05 20:21:14 +00007456 if (Unit->isMainFileAST())
7457 LogOS << " (" << Unit->getASTFileName() << ')';
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007458 return *this;
7459 }
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00007460 } else {
7461 LogOS << "<NULL TU>";
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007462 }
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007463 return *this;
7464}
7465
Argyrios Kyrtzidisba4b5f82013-03-08 02:32:26 +00007466Logger &cxindex::Logger::operator<<(const FileEntry *FE) {
7467 *this << FE->getName();
7468 return *this;
7469}
7470
7471Logger &cxindex::Logger::operator<<(CXCursor cursor) {
7472 CXString cursorName = clang_getCursorDisplayName(cursor);
7473 *this << cursorName << "@" << clang_getCursorLocation(cursor);
7474 clang_disposeString(cursorName);
7475 return *this;
7476}
7477
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007478Logger &cxindex::Logger::operator<<(CXSourceLocation Loc) {
7479 CXFile File;
7480 unsigned Line, Column;
Craig Topper69186e72014-06-08 08:38:04 +00007481 clang_getFileLocation(Loc, &File, &Line, &Column, nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007482 CXString FileName = clang_getFileName(File);
7483 *this << llvm::format("(%s:%d:%d)", clang_getCString(FileName), Line, Column);
7484 clang_disposeString(FileName);
7485 return *this;
7486}
7487
7488Logger &cxindex::Logger::operator<<(CXSourceRange range) {
7489 CXSourceLocation BLoc = clang_getRangeStart(range);
7490 CXSourceLocation ELoc = clang_getRangeEnd(range);
7491
7492 CXFile BFile;
7493 unsigned BLine, BColumn;
Craig Topper69186e72014-06-08 08:38:04 +00007494 clang_getFileLocation(BLoc, &BFile, &BLine, &BColumn, nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007495
7496 CXFile EFile;
7497 unsigned ELine, EColumn;
Craig Topper69186e72014-06-08 08:38:04 +00007498 clang_getFileLocation(ELoc, &EFile, &ELine, &EColumn, nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007499
7500 CXString BFileName = clang_getFileName(BFile);
7501 if (BFile == EFile) {
7502 *this << llvm::format("[%s %d:%d-%d:%d]", clang_getCString(BFileName),
7503 BLine, BColumn, ELine, EColumn);
7504 } else {
7505 CXString EFileName = clang_getFileName(EFile);
7506 *this << llvm::format("[%s:%d:%d - ", clang_getCString(BFileName),
7507 BLine, BColumn)
7508 << llvm::format("%s:%d:%d]", clang_getCString(EFileName),
7509 ELine, EColumn);
7510 clang_disposeString(EFileName);
7511 }
7512 clang_disposeString(BFileName);
7513 return *this;
7514}
7515
7516Logger &cxindex::Logger::operator<<(CXString Str) {
7517 *this << clang_getCString(Str);
7518 return *this;
7519}
7520
7521Logger &cxindex::Logger::operator<<(const llvm::format_object_base &Fmt) {
7522 LogOS << Fmt;
7523 return *this;
7524}
7525
Chandler Carruth37ad2582014-06-27 15:14:39 +00007526static llvm::ManagedStatic<llvm::sys::Mutex> LoggingMutex;
7527
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007528cxindex::Logger::~Logger() {
Chandler Carruth37ad2582014-06-27 15:14:39 +00007529 llvm::sys::ScopedLock L(*LoggingMutex);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007530
7531 static llvm::TimeRecord sBeginTR = llvm::TimeRecord::getCurrentTime();
7532
Dmitri Gribenkof8579502013-01-12 19:30:44 +00007533 raw_ostream &OS = llvm::errs();
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007534 OS << "[libclang:" << Name << ':';
7535
Alp Toker1a86ad22014-07-06 06:24:00 +00007536#ifdef USE_DARWIN_THREADS
7537 // TODO: Portability.
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007538 mach_port_t tid = pthread_mach_thread_np(pthread_self());
7539 OS << tid << ':';
7540#endif
7541
7542 llvm::TimeRecord TR = llvm::TimeRecord::getCurrentTime();
7543 OS << llvm::format("%7.4f] ", TR.getWallTime() - sBeginTR.getWallTime());
Yaron Keren09fb7c62015-03-10 07:33:23 +00007544 OS << Msg << '\n';
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007545
7546 if (Trace) {
Zachary Turner1fe2a8d2015-03-05 19:15:09 +00007547 llvm::sys::PrintStackTrace(OS);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007548 OS << "--------------------------------------------------\n";
7549 }
7550}