blob: 1141f92881e5c1403298297ff5c8b8966dcd01b5 [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
Kelvin Li099bb8c2015-11-24 20:50:12 +00002078void OMPClauseEnqueue::VisitOMPNumTeamsClause(const OMPNumTeamsClause *C) {
2079 Visitor->AddStmt(C->getNumTeams());
2080}
2081
Kelvin Lia15fb1a2015-11-27 18:47:36 +00002082void OMPClauseEnqueue::VisitOMPThreadLimitClause(const OMPThreadLimitClause *C) {
2083 Visitor->AddStmt(C->getThreadLimit());
2084}
2085
Alexey Bataev756c1962013-09-24 03:17:45 +00002086template<typename T>
2087void OMPClauseEnqueue::VisitOMPClauseList(T *Node) {
Alexey Bataev03b340a2014-10-21 03:16:40 +00002088 for (const auto *I : Node->varlists()) {
Aaron Ballman2205d2a2014-03-14 15:55:35 +00002089 Visitor->AddStmt(I);
Alexey Bataev03b340a2014-10-21 03:16:40 +00002090 }
Alexey Bataev756c1962013-09-24 03:17:45 +00002091}
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002092
2093void OMPClauseEnqueue::VisitOMPPrivateClause(const OMPPrivateClause *C) {
Alexey Bataev756c1962013-09-24 03:17:45 +00002094 VisitOMPClauseList(C);
Alexey Bataev03b340a2014-10-21 03:16:40 +00002095 for (const auto *E : C->private_copies()) {
2096 Visitor->AddStmt(E);
2097 }
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002098}
Alexey Bataevd5af8e42013-10-01 05:32:34 +00002099void OMPClauseEnqueue::VisitOMPFirstprivateClause(
2100 const OMPFirstprivateClause *C) {
2101 VisitOMPClauseList(C);
2102}
Alexander Musman1bb328c2014-06-04 13:06:39 +00002103void OMPClauseEnqueue::VisitOMPLastprivateClause(
2104 const OMPLastprivateClause *C) {
2105 VisitOMPClauseList(C);
Alexey Bataev38e89532015-04-16 04:54:05 +00002106 for (auto *E : C->private_copies()) {
2107 Visitor->AddStmt(E);
2108 }
2109 for (auto *E : C->source_exprs()) {
2110 Visitor->AddStmt(E);
2111 }
2112 for (auto *E : C->destination_exprs()) {
2113 Visitor->AddStmt(E);
2114 }
2115 for (auto *E : C->assignment_ops()) {
2116 Visitor->AddStmt(E);
2117 }
Alexander Musman1bb328c2014-06-04 13:06:39 +00002118}
Alexey Bataev758e55e2013-09-06 18:03:48 +00002119void OMPClauseEnqueue::VisitOMPSharedClause(const OMPSharedClause *C) {
Alexey Bataev756c1962013-09-24 03:17:45 +00002120 VisitOMPClauseList(C);
Alexey Bataev758e55e2013-09-06 18:03:48 +00002121}
Alexey Bataevc5e02582014-06-16 07:08:35 +00002122void OMPClauseEnqueue::VisitOMPReductionClause(const OMPReductionClause *C) {
2123 VisitOMPClauseList(C);
Alexey Bataevf24e7b12015-10-08 09:10:53 +00002124 for (auto *E : C->privates()) {
2125 Visitor->AddStmt(E);
2126 }
Alexey Bataev794ba0d2015-04-10 10:43:45 +00002127 for (auto *E : C->lhs_exprs()) {
2128 Visitor->AddStmt(E);
2129 }
2130 for (auto *E : C->rhs_exprs()) {
2131 Visitor->AddStmt(E);
2132 }
2133 for (auto *E : C->reduction_ops()) {
2134 Visitor->AddStmt(E);
2135 }
Alexey Bataevc5e02582014-06-16 07:08:35 +00002136}
Alexander Musman8dba6642014-04-22 13:09:42 +00002137void OMPClauseEnqueue::VisitOMPLinearClause(const OMPLinearClause *C) {
2138 VisitOMPClauseList(C);
Alexey Bataevbd9fec12015-08-18 06:47:21 +00002139 for (const auto *E : C->privates()) {
2140 Visitor->AddStmt(E);
2141 }
Alexander Musman3276a272015-03-21 10:12:56 +00002142 for (const auto *E : C->inits()) {
2143 Visitor->AddStmt(E);
2144 }
2145 for (const auto *E : C->updates()) {
2146 Visitor->AddStmt(E);
2147 }
2148 for (const auto *E : C->finals()) {
2149 Visitor->AddStmt(E);
2150 }
Alexander Musman8dba6642014-04-22 13:09:42 +00002151 Visitor->AddStmt(C->getStep());
Alexander Musman3276a272015-03-21 10:12:56 +00002152 Visitor->AddStmt(C->getCalcStep());
Alexander Musman8dba6642014-04-22 13:09:42 +00002153}
Alexander Musmanf0d76e72014-05-29 14:36:25 +00002154void OMPClauseEnqueue::VisitOMPAlignedClause(const OMPAlignedClause *C) {
2155 VisitOMPClauseList(C);
2156 Visitor->AddStmt(C->getAlignment());
2157}
Alexey Bataevd48bcd82014-03-31 03:36:38 +00002158void OMPClauseEnqueue::VisitOMPCopyinClause(const OMPCopyinClause *C) {
2159 VisitOMPClauseList(C);
Alexey Bataevf56f98c2015-04-16 05:39:01 +00002160 for (auto *E : C->source_exprs()) {
2161 Visitor->AddStmt(E);
2162 }
2163 for (auto *E : C->destination_exprs()) {
2164 Visitor->AddStmt(E);
2165 }
2166 for (auto *E : C->assignment_ops()) {
2167 Visitor->AddStmt(E);
2168 }
Alexey Bataevd48bcd82014-03-31 03:36:38 +00002169}
Alexey Bataevbae9a792014-06-27 10:37:06 +00002170void
2171OMPClauseEnqueue::VisitOMPCopyprivateClause(const OMPCopyprivateClause *C) {
2172 VisitOMPClauseList(C);
Alexey Bataeva63048e2015-03-23 06:18:07 +00002173 for (auto *E : C->source_exprs()) {
2174 Visitor->AddStmt(E);
2175 }
2176 for (auto *E : C->destination_exprs()) {
2177 Visitor->AddStmt(E);
2178 }
2179 for (auto *E : C->assignment_ops()) {
2180 Visitor->AddStmt(E);
2181 }
Alexey Bataevbae9a792014-06-27 10:37:06 +00002182}
Alexey Bataev6125da92014-07-21 11:26:11 +00002183void OMPClauseEnqueue::VisitOMPFlushClause(const OMPFlushClause *C) {
2184 VisitOMPClauseList(C);
2185}
Alexey Bataev1c2cfbc2015-06-23 14:25:19 +00002186void OMPClauseEnqueue::VisitOMPDependClause(const OMPDependClause *C) {
2187 VisitOMPClauseList(C);
2188}
Kelvin Li0bff7af2015-11-23 05:32:03 +00002189void OMPClauseEnqueue::VisitOMPMapClause(const OMPMapClause *C) {
2190 VisitOMPClauseList(C);
2191}
Alexander Kornienkoab9db512015-06-22 23:07:51 +00002192}
Alexey Bataev756c1962013-09-24 03:17:45 +00002193
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002194void EnqueueVisitor::EnqueueChildren(const OMPClause *S) {
2195 unsigned size = WL.size();
2196 OMPClauseEnqueue Visitor(this);
2197 Visitor.Visit(S);
2198 if (size == WL.size())
2199 return;
2200 // Now reverse the entries we just added. This will match the DFS
2201 // ordering performed by the worklist.
2202 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
2203 std::reverse(I, E);
2204}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002205void EnqueueVisitor::VisitAddrLabelExpr(const AddrLabelExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002206 WL.push_back(LabelRefVisit(E->getLabel(), E->getLabelLoc(), Parent));
2207}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002208void EnqueueVisitor::VisitBlockExpr(const BlockExpr *B) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002209 AddDecl(B->getBlockDecl());
2210}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002211void EnqueueVisitor::VisitCompoundLiteralExpr(const CompoundLiteralExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002212 EnqueueChildren(E);
2213 AddTypeLoc(E->getTypeSourceInfo());
2214}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002215void EnqueueVisitor::VisitCompoundStmt(const CompoundStmt *S) {
Pete Cooper57d3f142015-07-30 17:22:52 +00002216 for (auto &I : llvm::reverse(S->body()))
2217 AddStmt(I);
Guy Benyei11169dd2012-12-18 14:30:41 +00002218}
2219void EnqueueVisitor::
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002220VisitMSDependentExistsStmt(const MSDependentExistsStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002221 AddStmt(S->getSubStmt());
2222 AddDeclarationNameInfo(S);
2223 if (NestedNameSpecifierLoc QualifierLoc = S->getQualifierLoc())
2224 AddNestedNameSpecifierLoc(QualifierLoc);
2225}
2226
2227void EnqueueVisitor::
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002228VisitCXXDependentScopeMemberExpr(const CXXDependentScopeMemberExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002229 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
2230 AddDeclarationNameInfo(E);
2231 if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
2232 AddNestedNameSpecifierLoc(QualifierLoc);
2233 if (!E->isImplicitAccess())
2234 AddStmt(E->getBase());
2235}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002236void EnqueueVisitor::VisitCXXNewExpr(const CXXNewExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002237 // Enqueue the initializer , if any.
2238 AddStmt(E->getInitializer());
2239 // Enqueue the array size, if any.
2240 AddStmt(E->getArraySize());
2241 // Enqueue the allocated type.
2242 AddTypeLoc(E->getAllocatedTypeSourceInfo());
2243 // Enqueue the placement arguments.
2244 for (unsigned I = E->getNumPlacementArgs(); I > 0; --I)
2245 AddStmt(E->getPlacementArg(I-1));
2246}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002247void EnqueueVisitor::VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *CE) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002248 for (unsigned I = CE->getNumArgs(); I > 1 /* Yes, this is 1 */; --I)
2249 AddStmt(CE->getArg(I-1));
2250 AddStmt(CE->getCallee());
2251 AddStmt(CE->getArg(0));
2252}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002253void EnqueueVisitor::VisitCXXPseudoDestructorExpr(
2254 const CXXPseudoDestructorExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002255 // Visit the name of the type being destroyed.
2256 AddTypeLoc(E->getDestroyedTypeInfo());
2257 // Visit the scope type that looks disturbingly like the nested-name-specifier
2258 // but isn't.
2259 AddTypeLoc(E->getScopeTypeInfo());
2260 // Visit the nested-name-specifier.
2261 if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
2262 AddNestedNameSpecifierLoc(QualifierLoc);
2263 // Visit base expression.
2264 AddStmt(E->getBase());
2265}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002266void EnqueueVisitor::VisitCXXScalarValueInitExpr(
2267 const CXXScalarValueInitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002268 AddTypeLoc(E->getTypeSourceInfo());
2269}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002270void EnqueueVisitor::VisitCXXTemporaryObjectExpr(
2271 const CXXTemporaryObjectExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002272 EnqueueChildren(E);
2273 AddTypeLoc(E->getTypeSourceInfo());
2274}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002275void EnqueueVisitor::VisitCXXTypeidExpr(const CXXTypeidExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002276 EnqueueChildren(E);
2277 if (E->isTypeOperand())
2278 AddTypeLoc(E->getTypeOperandSourceInfo());
2279}
2280
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002281void EnqueueVisitor::VisitCXXUnresolvedConstructExpr(
2282 const CXXUnresolvedConstructExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002283 EnqueueChildren(E);
2284 AddTypeLoc(E->getTypeSourceInfo());
2285}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002286void EnqueueVisitor::VisitCXXUuidofExpr(const CXXUuidofExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002287 EnqueueChildren(E);
2288 if (E->isTypeOperand())
2289 AddTypeLoc(E->getTypeOperandSourceInfo());
2290}
2291
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002292void EnqueueVisitor::VisitCXXCatchStmt(const CXXCatchStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002293 EnqueueChildren(S);
2294 AddDecl(S->getExceptionDecl());
2295}
2296
Argyrios Kyrtzidis99891242014-11-13 09:03:21 +00002297void EnqueueVisitor::VisitCXXForRangeStmt(const CXXForRangeStmt *S) {
Argyrios Kyrtzidiscde70692014-11-13 09:50:19 +00002298 AddStmt(S->getBody());
Argyrios Kyrtzidis99891242014-11-13 09:03:21 +00002299 AddStmt(S->getRangeInit());
Argyrios Kyrtzidiscde70692014-11-13 09:50:19 +00002300 AddDecl(S->getLoopVariable());
Argyrios Kyrtzidis99891242014-11-13 09:03:21 +00002301}
2302
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002303void EnqueueVisitor::VisitDeclRefExpr(const DeclRefExpr *DR) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002304 if (DR->hasExplicitTemplateArgs()) {
2305 AddExplicitTemplateArgs(&DR->getExplicitTemplateArgs());
2306 }
2307 WL.push_back(DeclRefExprParts(DR, Parent));
2308}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002309void EnqueueVisitor::VisitDependentScopeDeclRefExpr(
2310 const DependentScopeDeclRefExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002311 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
2312 AddDeclarationNameInfo(E);
2313 AddNestedNameSpecifierLoc(E->getQualifierLoc());
2314}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002315void EnqueueVisitor::VisitDeclStmt(const DeclStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002316 unsigned size = WL.size();
2317 bool isFirst = true;
Aaron Ballman535bbcc2014-03-14 17:01:24 +00002318 for (const auto *D : S->decls()) {
2319 AddDecl(D, isFirst);
Guy Benyei11169dd2012-12-18 14:30:41 +00002320 isFirst = false;
2321 }
2322 if (size == WL.size())
2323 return;
2324 // Now reverse the entries we just added. This will match the DFS
2325 // ordering performed by the worklist.
2326 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
2327 std::reverse(I, E);
2328}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002329void EnqueueVisitor::VisitDesignatedInitExpr(const DesignatedInitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002330 AddStmt(E->getInit());
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002331 for (DesignatedInitExpr::const_reverse_designators_iterator
Guy Benyei11169dd2012-12-18 14:30:41 +00002332 D = E->designators_rbegin(), DEnd = E->designators_rend();
2333 D != DEnd; ++D) {
2334 if (D->isFieldDesignator()) {
2335 if (FieldDecl *Field = D->getField())
2336 AddMemberRef(Field, D->getFieldLoc());
2337 continue;
2338 }
2339 if (D->isArrayDesignator()) {
2340 AddStmt(E->getArrayIndex(*D));
2341 continue;
2342 }
2343 assert(D->isArrayRangeDesignator() && "Unknown designator kind");
2344 AddStmt(E->getArrayRangeEnd(*D));
2345 AddStmt(E->getArrayRangeStart(*D));
2346 }
2347}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002348void EnqueueVisitor::VisitExplicitCastExpr(const ExplicitCastExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002349 EnqueueChildren(E);
2350 AddTypeLoc(E->getTypeInfoAsWritten());
2351}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002352void EnqueueVisitor::VisitForStmt(const ForStmt *FS) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002353 AddStmt(FS->getBody());
2354 AddStmt(FS->getInc());
2355 AddStmt(FS->getCond());
2356 AddDecl(FS->getConditionVariable());
2357 AddStmt(FS->getInit());
2358}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002359void EnqueueVisitor::VisitGotoStmt(const GotoStmt *GS) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002360 WL.push_back(LabelRefVisit(GS->getLabel(), GS->getLabelLoc(), Parent));
2361}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002362void EnqueueVisitor::VisitIfStmt(const IfStmt *If) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002363 AddStmt(If->getElse());
2364 AddStmt(If->getThen());
2365 AddStmt(If->getCond());
2366 AddDecl(If->getConditionVariable());
2367}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002368void EnqueueVisitor::VisitInitListExpr(const InitListExpr *IE) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002369 // We care about the syntactic form of the initializer list, only.
2370 if (InitListExpr *Syntactic = IE->getSyntacticForm())
2371 IE = Syntactic;
2372 EnqueueChildren(IE);
2373}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002374void EnqueueVisitor::VisitMemberExpr(const MemberExpr *M) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002375 WL.push_back(MemberExprParts(M, Parent));
2376
2377 // If the base of the member access expression is an implicit 'this', don't
2378 // visit it.
2379 // FIXME: If we ever want to show these implicit accesses, this will be
2380 // unfortunate. However, clang_getCursor() relies on this behavior.
Argyrios Kyrtzidis58d0e7a2015-03-13 04:40:07 +00002381 if (M->isImplicitAccess())
2382 return;
2383
2384 // Ignore base anonymous struct/union fields, otherwise they will shadow the
2385 // real field that that we are interested in.
2386 if (auto *SubME = dyn_cast<MemberExpr>(M->getBase())) {
2387 if (auto *FD = dyn_cast_or_null<FieldDecl>(SubME->getMemberDecl())) {
2388 if (FD->isAnonymousStructOrUnion()) {
2389 AddStmt(SubME->getBase());
2390 return;
2391 }
2392 }
2393 }
2394
2395 AddStmt(M->getBase());
Guy Benyei11169dd2012-12-18 14:30:41 +00002396}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002397void EnqueueVisitor::VisitObjCEncodeExpr(const ObjCEncodeExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002398 AddTypeLoc(E->getEncodedTypeSourceInfo());
2399}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002400void EnqueueVisitor::VisitObjCMessageExpr(const ObjCMessageExpr *M) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002401 EnqueueChildren(M);
2402 AddTypeLoc(M->getClassReceiverTypeInfo());
2403}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002404void EnqueueVisitor::VisitOffsetOfExpr(const OffsetOfExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002405 // Visit the components of the offsetof expression.
2406 for (unsigned N = E->getNumComponents(), I = N; I > 0; --I) {
2407 typedef OffsetOfExpr::OffsetOfNode OffsetOfNode;
2408 const OffsetOfNode &Node = E->getComponent(I-1);
2409 switch (Node.getKind()) {
2410 case OffsetOfNode::Array:
2411 AddStmt(E->getIndexExpr(Node.getArrayExprIndex()));
2412 break;
2413 case OffsetOfNode::Field:
2414 AddMemberRef(Node.getField(), Node.getSourceRange().getEnd());
2415 break;
2416 case OffsetOfNode::Identifier:
2417 case OffsetOfNode::Base:
2418 continue;
2419 }
2420 }
2421 // Visit the type into which we're computing the offset.
2422 AddTypeLoc(E->getTypeSourceInfo());
2423}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002424void EnqueueVisitor::VisitOverloadExpr(const OverloadExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002425 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
2426 WL.push_back(OverloadExprParts(E, Parent));
2427}
2428void EnqueueVisitor::VisitUnaryExprOrTypeTraitExpr(
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002429 const UnaryExprOrTypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002430 EnqueueChildren(E);
2431 if (E->isArgumentType())
2432 AddTypeLoc(E->getArgumentTypeInfo());
2433}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002434void EnqueueVisitor::VisitStmt(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002435 EnqueueChildren(S);
2436}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002437void EnqueueVisitor::VisitSwitchStmt(const SwitchStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002438 AddStmt(S->getBody());
2439 AddStmt(S->getCond());
2440 AddDecl(S->getConditionVariable());
2441}
2442
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002443void EnqueueVisitor::VisitWhileStmt(const WhileStmt *W) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002444 AddStmt(W->getBody());
2445 AddStmt(W->getCond());
2446 AddDecl(W->getConditionVariable());
2447}
2448
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002449void EnqueueVisitor::VisitTypeTraitExpr(const TypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002450 for (unsigned I = E->getNumArgs(); I > 0; --I)
2451 AddTypeLoc(E->getArg(I-1));
2452}
2453
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002454void EnqueueVisitor::VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002455 AddTypeLoc(E->getQueriedTypeSourceInfo());
2456}
2457
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002458void EnqueueVisitor::VisitExpressionTraitExpr(const ExpressionTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002459 EnqueueChildren(E);
2460}
2461
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002462void EnqueueVisitor::VisitUnresolvedMemberExpr(const UnresolvedMemberExpr *U) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002463 VisitOverloadExpr(U);
2464 if (!U->isImplicitAccess())
2465 AddStmt(U->getBase());
2466}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002467void EnqueueVisitor::VisitVAArgExpr(const VAArgExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002468 AddStmt(E->getSubExpr());
2469 AddTypeLoc(E->getWrittenTypeInfo());
2470}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002471void EnqueueVisitor::VisitSizeOfPackExpr(const SizeOfPackExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002472 WL.push_back(SizeOfPackExprParts(E, Parent));
2473}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002474void EnqueueVisitor::VisitOpaqueValueExpr(const OpaqueValueExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002475 // If the opaque value has a source expression, just transparently
2476 // visit that. This is useful for (e.g.) pseudo-object expressions.
2477 if (Expr *SourceExpr = E->getSourceExpr())
2478 return Visit(SourceExpr);
2479}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002480void EnqueueVisitor::VisitLambdaExpr(const LambdaExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002481 AddStmt(E->getBody());
2482 WL.push_back(LambdaExprParts(E, Parent));
2483}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002484void EnqueueVisitor::VisitPseudoObjectExpr(const PseudoObjectExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002485 // Treat the expression like its syntactic form.
2486 Visit(E->getSyntacticForm());
2487}
2488
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002489void EnqueueVisitor::VisitOMPExecutableDirective(
2490 const OMPExecutableDirective *D) {
2491 EnqueueChildren(D);
2492 for (ArrayRef<OMPClause *>::iterator I = D->clauses().begin(),
2493 E = D->clauses().end();
2494 I != E; ++I)
2495 EnqueueChildren(*I);
2496}
2497
Alexander Musman3aaab662014-08-19 11:27:13 +00002498void EnqueueVisitor::VisitOMPLoopDirective(const OMPLoopDirective *D) {
2499 VisitOMPExecutableDirective(D);
2500}
2501
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002502void EnqueueVisitor::VisitOMPParallelDirective(const OMPParallelDirective *D) {
2503 VisitOMPExecutableDirective(D);
2504}
2505
Alexey Bataev1b59ab52014-02-27 08:29:12 +00002506void EnqueueVisitor::VisitOMPSimdDirective(const OMPSimdDirective *D) {
Alexander Musman3aaab662014-08-19 11:27:13 +00002507 VisitOMPLoopDirective(D);
Alexey Bataev1b59ab52014-02-27 08:29:12 +00002508}
2509
Alexey Bataevf29276e2014-06-18 04:14:57 +00002510void EnqueueVisitor::VisitOMPForDirective(const OMPForDirective *D) {
Alexander Musman3aaab662014-08-19 11:27:13 +00002511 VisitOMPLoopDirective(D);
Alexey Bataevf29276e2014-06-18 04:14:57 +00002512}
2513
Alexander Musmanf82886e2014-09-18 05:12:34 +00002514void EnqueueVisitor::VisitOMPForSimdDirective(const OMPForSimdDirective *D) {
2515 VisitOMPLoopDirective(D);
2516}
2517
Alexey Bataevd3f8dd22014-06-25 11:44:49 +00002518void EnqueueVisitor::VisitOMPSectionsDirective(const OMPSectionsDirective *D) {
2519 VisitOMPExecutableDirective(D);
2520}
2521
Alexey Bataev1e0498a2014-06-26 08:21:58 +00002522void EnqueueVisitor::VisitOMPSectionDirective(const OMPSectionDirective *D) {
2523 VisitOMPExecutableDirective(D);
2524}
2525
Alexey Bataevd1e40fb2014-06-26 12:05:45 +00002526void EnqueueVisitor::VisitOMPSingleDirective(const OMPSingleDirective *D) {
2527 VisitOMPExecutableDirective(D);
2528}
2529
Alexander Musman80c22892014-07-17 08:54:58 +00002530void EnqueueVisitor::VisitOMPMasterDirective(const OMPMasterDirective *D) {
2531 VisitOMPExecutableDirective(D);
2532}
2533
Alexander Musmand9ed09f2014-07-21 09:42:05 +00002534void EnqueueVisitor::VisitOMPCriticalDirective(const OMPCriticalDirective *D) {
2535 VisitOMPExecutableDirective(D);
2536 AddDeclarationNameInfo(D);
2537}
2538
Alexey Bataev4acb8592014-07-07 13:01:15 +00002539void
2540EnqueueVisitor::VisitOMPParallelForDirective(const OMPParallelForDirective *D) {
Alexander Musman3aaab662014-08-19 11:27:13 +00002541 VisitOMPLoopDirective(D);
Alexey Bataev4acb8592014-07-07 13:01:15 +00002542}
2543
Alexander Musmane4e893b2014-09-23 09:33:00 +00002544void EnqueueVisitor::VisitOMPParallelForSimdDirective(
2545 const OMPParallelForSimdDirective *D) {
2546 VisitOMPLoopDirective(D);
2547}
2548
Alexey Bataev84d0b3e2014-07-08 08:12:03 +00002549void EnqueueVisitor::VisitOMPParallelSectionsDirective(
2550 const OMPParallelSectionsDirective *D) {
2551 VisitOMPExecutableDirective(D);
2552}
2553
Alexey Bataev9c2e8ee2014-07-11 11:25:16 +00002554void EnqueueVisitor::VisitOMPTaskDirective(const OMPTaskDirective *D) {
2555 VisitOMPExecutableDirective(D);
2556}
2557
Alexey Bataev68446b72014-07-18 07:47:19 +00002558void
2559EnqueueVisitor::VisitOMPTaskyieldDirective(const OMPTaskyieldDirective *D) {
2560 VisitOMPExecutableDirective(D);
2561}
2562
Alexey Bataev4d1dfea2014-07-18 09:11:51 +00002563void EnqueueVisitor::VisitOMPBarrierDirective(const OMPBarrierDirective *D) {
2564 VisitOMPExecutableDirective(D);
2565}
2566
Alexey Bataev2df347a2014-07-18 10:17:07 +00002567void EnqueueVisitor::VisitOMPTaskwaitDirective(const OMPTaskwaitDirective *D) {
2568 VisitOMPExecutableDirective(D);
2569}
2570
Alexey Bataevc30dd2d2015-06-18 12:14:09 +00002571void EnqueueVisitor::VisitOMPTaskgroupDirective(
2572 const OMPTaskgroupDirective *D) {
2573 VisitOMPExecutableDirective(D);
2574}
2575
Alexey Bataev6125da92014-07-21 11:26:11 +00002576void EnqueueVisitor::VisitOMPFlushDirective(const OMPFlushDirective *D) {
2577 VisitOMPExecutableDirective(D);
2578}
2579
Alexey Bataev9fb6e642014-07-22 06:45:04 +00002580void EnqueueVisitor::VisitOMPOrderedDirective(const OMPOrderedDirective *D) {
2581 VisitOMPExecutableDirective(D);
2582}
2583
Alexey Bataev0162e452014-07-22 10:10:35 +00002584void EnqueueVisitor::VisitOMPAtomicDirective(const OMPAtomicDirective *D) {
2585 VisitOMPExecutableDirective(D);
2586}
2587
Alexey Bataev0bd520b2014-09-19 08:19:49 +00002588void EnqueueVisitor::VisitOMPTargetDirective(const OMPTargetDirective *D) {
2589 VisitOMPExecutableDirective(D);
2590}
2591
Michael Wong65f367f2015-07-21 13:44:28 +00002592void EnqueueVisitor::VisitOMPTargetDataDirective(const
2593 OMPTargetDataDirective *D) {
2594 VisitOMPExecutableDirective(D);
2595}
2596
Alexey Bataev13314bf2014-10-09 04:18:56 +00002597void EnqueueVisitor::VisitOMPTeamsDirective(const OMPTeamsDirective *D) {
2598 VisitOMPExecutableDirective(D);
2599}
2600
Alexey Bataev6d4ed052015-07-01 06:57:41 +00002601void EnqueueVisitor::VisitOMPCancellationPointDirective(
2602 const OMPCancellationPointDirective *D) {
2603 VisitOMPExecutableDirective(D);
2604}
2605
Alexey Bataev80909872015-07-02 11:25:17 +00002606void EnqueueVisitor::VisitOMPCancelDirective(const OMPCancelDirective *D) {
2607 VisitOMPExecutableDirective(D);
2608}
2609
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002610void CursorVisitor::EnqueueWorkList(VisitorWorkList &WL, const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002611 EnqueueVisitor(WL, MakeCXCursor(S, StmtParent, TU,RegionOfInterest)).Visit(S);
2612}
2613
2614bool CursorVisitor::IsInRegionOfInterest(CXCursor C) {
2615 if (RegionOfInterest.isValid()) {
2616 SourceRange Range = getRawCursorExtent(C);
2617 if (Range.isInvalid() || CompareRegionOfInterest(Range))
2618 return false;
2619 }
2620 return true;
2621}
2622
2623bool CursorVisitor::RunVisitorWorkList(VisitorWorkList &WL) {
2624 while (!WL.empty()) {
2625 // Dequeue the worklist item.
Robert Wilhelm25284cc2013-08-23 16:11:15 +00002626 VisitorJob LI = WL.pop_back_val();
Guy Benyei11169dd2012-12-18 14:30:41 +00002627
2628 // Set the Parent field, then back to its old value once we're done.
2629 SetParentRAII SetParent(Parent, StmtParent, LI.getParent());
2630
2631 switch (LI.getKind()) {
2632 case VisitorJob::DeclVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002633 const Decl *D = cast<DeclVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002634 if (!D)
2635 continue;
2636
2637 // For now, perform default visitation for Decls.
2638 if (Visit(MakeCXCursor(D, TU, RegionOfInterest,
2639 cast<DeclVisit>(&LI)->isFirst())))
2640 return true;
2641
2642 continue;
2643 }
2644 case VisitorJob::ExplicitTemplateArgsVisitKind: {
2645 const ASTTemplateArgumentListInfo *ArgList =
2646 cast<ExplicitTemplateArgsVisit>(&LI)->get();
2647 for (const TemplateArgumentLoc *Arg = ArgList->getTemplateArgs(),
2648 *ArgEnd = Arg + ArgList->NumTemplateArgs;
2649 Arg != ArgEnd; ++Arg) {
2650 if (VisitTemplateArgumentLoc(*Arg))
2651 return true;
2652 }
2653 continue;
2654 }
2655 case VisitorJob::TypeLocVisitKind: {
2656 // Perform default visitation for TypeLocs.
2657 if (Visit(cast<TypeLocVisit>(&LI)->get()))
2658 return true;
2659 continue;
2660 }
2661 case VisitorJob::LabelRefVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002662 const LabelDecl *LS = cast<LabelRefVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002663 if (LabelStmt *stmt = LS->getStmt()) {
2664 if (Visit(MakeCursorLabelRef(stmt, cast<LabelRefVisit>(&LI)->getLoc(),
2665 TU))) {
2666 return true;
2667 }
2668 }
2669 continue;
2670 }
2671
2672 case VisitorJob::NestedNameSpecifierLocVisitKind: {
2673 NestedNameSpecifierLocVisit *V = cast<NestedNameSpecifierLocVisit>(&LI);
2674 if (VisitNestedNameSpecifierLoc(V->get()))
2675 return true;
2676 continue;
2677 }
2678
2679 case VisitorJob::DeclarationNameInfoVisitKind: {
2680 if (VisitDeclarationNameInfo(cast<DeclarationNameInfoVisit>(&LI)
2681 ->get()))
2682 return true;
2683 continue;
2684 }
2685 case VisitorJob::MemberRefVisitKind: {
2686 MemberRefVisit *V = cast<MemberRefVisit>(&LI);
2687 if (Visit(MakeCursorMemberRef(V->get(), V->getLoc(), TU)))
2688 return true;
2689 continue;
2690 }
2691 case VisitorJob::StmtVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002692 const Stmt *S = cast<StmtVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002693 if (!S)
2694 continue;
2695
2696 // Update the current cursor.
2697 CXCursor Cursor = MakeCXCursor(S, StmtParent, TU, RegionOfInterest);
2698 if (!IsInRegionOfInterest(Cursor))
2699 continue;
2700 switch (Visitor(Cursor, Parent, ClientData)) {
2701 case CXChildVisit_Break: return true;
2702 case CXChildVisit_Continue: break;
2703 case CXChildVisit_Recurse:
2704 if (PostChildrenVisitor)
Craig Topper69186e72014-06-08 08:38:04 +00002705 WL.push_back(PostChildrenVisit(nullptr, Cursor));
Guy Benyei11169dd2012-12-18 14:30:41 +00002706 EnqueueWorkList(WL, S);
2707 break;
2708 }
2709 continue;
2710 }
2711 case VisitorJob::MemberExprPartsKind: {
2712 // Handle the other pieces in the MemberExpr besides the base.
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002713 const MemberExpr *M = cast<MemberExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002714
2715 // Visit the nested-name-specifier
2716 if (NestedNameSpecifierLoc QualifierLoc = M->getQualifierLoc())
2717 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2718 return true;
2719
2720 // Visit the declaration name.
2721 if (VisitDeclarationNameInfo(M->getMemberNameInfo()))
2722 return true;
2723
2724 // Visit the explicitly-specified template arguments, if any.
2725 if (M->hasExplicitTemplateArgs()) {
2726 for (const TemplateArgumentLoc *Arg = M->getTemplateArgs(),
2727 *ArgEnd = Arg + M->getNumTemplateArgs();
2728 Arg != ArgEnd; ++Arg) {
2729 if (VisitTemplateArgumentLoc(*Arg))
2730 return true;
2731 }
2732 }
2733 continue;
2734 }
2735 case VisitorJob::DeclRefExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002736 const DeclRefExpr *DR = cast<DeclRefExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002737 // Visit nested-name-specifier, if present.
2738 if (NestedNameSpecifierLoc QualifierLoc = DR->getQualifierLoc())
2739 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2740 return true;
2741 // Visit declaration name.
2742 if (VisitDeclarationNameInfo(DR->getNameInfo()))
2743 return true;
2744 continue;
2745 }
2746 case VisitorJob::OverloadExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002747 const OverloadExpr *O = cast<OverloadExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002748 // Visit the nested-name-specifier.
2749 if (NestedNameSpecifierLoc QualifierLoc = O->getQualifierLoc())
2750 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2751 return true;
2752 // Visit the declaration name.
2753 if (VisitDeclarationNameInfo(O->getNameInfo()))
2754 return true;
2755 // Visit the overloaded declaration reference.
2756 if (Visit(MakeCursorOverloadedDeclRef(O, TU)))
2757 return true;
2758 continue;
2759 }
2760 case VisitorJob::SizeOfPackExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002761 const SizeOfPackExpr *E = cast<SizeOfPackExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002762 NamedDecl *Pack = E->getPack();
2763 if (isa<TemplateTypeParmDecl>(Pack)) {
2764 if (Visit(MakeCursorTypeRef(cast<TemplateTypeParmDecl>(Pack),
2765 E->getPackLoc(), TU)))
2766 return true;
2767
2768 continue;
2769 }
2770
2771 if (isa<TemplateTemplateParmDecl>(Pack)) {
2772 if (Visit(MakeCursorTemplateRef(cast<TemplateTemplateParmDecl>(Pack),
2773 E->getPackLoc(), TU)))
2774 return true;
2775
2776 continue;
2777 }
2778
2779 // Non-type template parameter packs and function parameter packs are
2780 // treated like DeclRefExpr cursors.
2781 continue;
2782 }
2783
2784 case VisitorJob::LambdaExprPartsKind: {
2785 // Visit captures.
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002786 const LambdaExpr *E = cast<LambdaExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002787 for (LambdaExpr::capture_iterator C = E->explicit_capture_begin(),
2788 CEnd = E->explicit_capture_end();
2789 C != CEnd; ++C) {
Richard Smithba71c082013-05-16 06:20:58 +00002790 // FIXME: Lambda init-captures.
2791 if (!C->capturesVariable())
Guy Benyei11169dd2012-12-18 14:30:41 +00002792 continue;
Richard Smithba71c082013-05-16 06:20:58 +00002793
Guy Benyei11169dd2012-12-18 14:30:41 +00002794 if (Visit(MakeCursorVariableRef(C->getCapturedVar(),
2795 C->getLocation(),
2796 TU)))
2797 return true;
2798 }
2799
2800 // Visit parameters and return type, if present.
2801 if (E->hasExplicitParameters() || E->hasExplicitResultType()) {
2802 TypeLoc TL = E->getCallOperator()->getTypeSourceInfo()->getTypeLoc();
2803 if (E->hasExplicitParameters() && E->hasExplicitResultType()) {
2804 // Visit the whole type.
2805 if (Visit(TL))
2806 return true;
David Blaikie6adc78e2013-02-18 22:06:02 +00002807 } else if (FunctionProtoTypeLoc Proto =
2808 TL.getAs<FunctionProtoTypeLoc>()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002809 if (E->hasExplicitParameters()) {
2810 // Visit parameters.
Alp Tokerb3fd5cf2014-01-21 00:32:38 +00002811 for (unsigned I = 0, N = Proto.getNumParams(); I != N; ++I)
2812 if (Visit(MakeCXCursor(Proto.getParam(I), TU)))
Guy Benyei11169dd2012-12-18 14:30:41 +00002813 return true;
2814 } else {
2815 // Visit result type.
Alp Toker42a16a62014-01-25 23:51:36 +00002816 if (Visit(Proto.getReturnLoc()))
Guy Benyei11169dd2012-12-18 14:30:41 +00002817 return true;
2818 }
2819 }
2820 }
2821 break;
2822 }
2823
2824 case VisitorJob::PostChildrenVisitKind:
2825 if (PostChildrenVisitor(Parent, ClientData))
2826 return true;
2827 break;
2828 }
2829 }
2830 return false;
2831}
2832
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002833bool CursorVisitor::Visit(const Stmt *S) {
Craig Topper69186e72014-06-08 08:38:04 +00002834 VisitorWorkList *WL = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00002835 if (!WorkListFreeList.empty()) {
2836 WL = WorkListFreeList.back();
2837 WL->clear();
2838 WorkListFreeList.pop_back();
2839 }
2840 else {
2841 WL = new VisitorWorkList();
2842 WorkListCache.push_back(WL);
2843 }
2844 EnqueueWorkList(*WL, S);
2845 bool result = RunVisitorWorkList(*WL);
2846 WorkListFreeList.push_back(WL);
2847 return result;
2848}
2849
2850namespace {
Dmitri Gribenkof8579502013-01-12 19:30:44 +00002851typedef SmallVector<SourceRange, 4> RefNamePieces;
Craig Topper69186e72014-06-08 08:38:04 +00002852RefNamePieces
2853buildPieces(unsigned NameFlags, bool IsMemberRefExpr,
Craig Toppere335f252015-10-04 04:53:55 +00002854 const DeclarationNameInfo &NI, SourceRange QLoc,
Craig Topper69186e72014-06-08 08:38:04 +00002855 const ASTTemplateArgumentListInfo *TemplateArgs = nullptr) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002856 const bool WantQualifier = NameFlags & CXNameRange_WantQualifier;
2857 const bool WantTemplateArgs = NameFlags & CXNameRange_WantTemplateArgs;
2858 const bool WantSinglePiece = NameFlags & CXNameRange_WantSinglePiece;
2859
2860 const DeclarationName::NameKind Kind = NI.getName().getNameKind();
2861
2862 RefNamePieces Pieces;
2863
2864 if (WantQualifier && QLoc.isValid())
2865 Pieces.push_back(QLoc);
2866
2867 if (Kind != DeclarationName::CXXOperatorName || IsMemberRefExpr)
2868 Pieces.push_back(NI.getLoc());
2869
2870 if (WantTemplateArgs && TemplateArgs)
2871 Pieces.push_back(SourceRange(TemplateArgs->LAngleLoc,
2872 TemplateArgs->RAngleLoc));
2873
2874 if (Kind == DeclarationName::CXXOperatorName) {
2875 Pieces.push_back(SourceLocation::getFromRawEncoding(
2876 NI.getInfo().CXXOperatorName.BeginOpNameLoc));
2877 Pieces.push_back(SourceLocation::getFromRawEncoding(
2878 NI.getInfo().CXXOperatorName.EndOpNameLoc));
2879 }
2880
2881 if (WantSinglePiece) {
2882 SourceRange R(Pieces.front().getBegin(), Pieces.back().getEnd());
2883 Pieces.clear();
2884 Pieces.push_back(R);
2885 }
2886
2887 return Pieces;
2888}
Alexander Kornienkoab9db512015-06-22 23:07:51 +00002889}
Guy Benyei11169dd2012-12-18 14:30:41 +00002890
2891//===----------------------------------------------------------------------===//
2892// Misc. API hooks.
2893//===----------------------------------------------------------------------===//
2894
Chad Rosier05c71aa2013-03-27 18:28:23 +00002895static void fatal_error_handler(void *user_data, const std::string& reason,
2896 bool gen_crash_diag) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002897 // Write the result out to stderr avoiding errs() because raw_ostreams can
2898 // call report_fatal_error.
2899 fprintf(stderr, "LIBCLANG FATAL ERROR: %s\n", reason.c_str());
2900 ::abort();
2901}
2902
Chandler Carruth66660742014-06-27 16:37:27 +00002903namespace {
2904struct RegisterFatalErrorHandler {
2905 RegisterFatalErrorHandler() {
2906 llvm::install_fatal_error_handler(fatal_error_handler, nullptr);
2907 }
2908};
2909}
2910
2911static llvm::ManagedStatic<RegisterFatalErrorHandler> RegisterFatalErrorHandlerOnce;
2912
Guy Benyei11169dd2012-12-18 14:30:41 +00002913extern "C" {
2914CXIndex clang_createIndex(int excludeDeclarationsFromPCH,
2915 int displayDiagnostics) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002916 // We use crash recovery to make some of our APIs more reliable, implicitly
2917 // enable it.
Argyrios Kyrtzidis3701f542013-11-27 08:58:09 +00002918 if (!getenv("LIBCLANG_DISABLE_CRASH_RECOVERY"))
2919 llvm::CrashRecoveryContext::Enable();
Guy Benyei11169dd2012-12-18 14:30:41 +00002920
Chandler Carruth66660742014-06-27 16:37:27 +00002921 // Look through the managed static to trigger construction of the managed
2922 // static which registers our fatal error handler. This ensures it is only
2923 // registered once.
2924 (void)*RegisterFatalErrorHandlerOnce;
Guy Benyei11169dd2012-12-18 14:30:41 +00002925
Adrian Prantlbc068582015-07-08 01:00:30 +00002926 // Initialize targets for clang module support.
2927 llvm::InitializeAllTargets();
2928 llvm::InitializeAllTargetMCs();
2929 llvm::InitializeAllAsmPrinters();
2930 llvm::InitializeAllAsmParsers();
2931
Adrian Prantlfb2398d2015-07-17 01:19:54 +00002932 CIndexer *CIdxr = new CIndexer();
2933
Guy Benyei11169dd2012-12-18 14:30:41 +00002934 if (excludeDeclarationsFromPCH)
2935 CIdxr->setOnlyLocalDecls();
2936 if (displayDiagnostics)
2937 CIdxr->setDisplayDiagnostics();
2938
2939 if (getenv("LIBCLANG_BGPRIO_INDEX"))
2940 CIdxr->setCXGlobalOptFlags(CIdxr->getCXGlobalOptFlags() |
2941 CXGlobalOpt_ThreadBackgroundPriorityForIndexing);
2942 if (getenv("LIBCLANG_BGPRIO_EDIT"))
2943 CIdxr->setCXGlobalOptFlags(CIdxr->getCXGlobalOptFlags() |
2944 CXGlobalOpt_ThreadBackgroundPriorityForEditing);
2945
2946 return CIdxr;
2947}
2948
2949void clang_disposeIndex(CXIndex CIdx) {
2950 if (CIdx)
2951 delete static_cast<CIndexer *>(CIdx);
2952}
2953
2954void clang_CXIndex_setGlobalOptions(CXIndex CIdx, unsigned options) {
2955 if (CIdx)
2956 static_cast<CIndexer *>(CIdx)->setCXGlobalOptFlags(options);
2957}
2958
2959unsigned clang_CXIndex_getGlobalOptions(CXIndex CIdx) {
2960 if (CIdx)
2961 return static_cast<CIndexer *>(CIdx)->getCXGlobalOptFlags();
2962 return 0;
2963}
2964
2965void clang_toggleCrashRecovery(unsigned isEnabled) {
2966 if (isEnabled)
2967 llvm::CrashRecoveryContext::Enable();
2968 else
2969 llvm::CrashRecoveryContext::Disable();
2970}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002971
Guy Benyei11169dd2012-12-18 14:30:41 +00002972CXTranslationUnit clang_createTranslationUnit(CXIndex CIdx,
2973 const char *ast_filename) {
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00002974 CXTranslationUnit TU;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002975 enum CXErrorCode Result =
2976 clang_createTranslationUnit2(CIdx, ast_filename, &TU);
Reid Klecknerfd48fc62014-02-12 23:56:20 +00002977 (void)Result;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002978 assert((TU && Result == CXError_Success) ||
2979 (!TU && Result != CXError_Success));
2980 return TU;
2981}
2982
2983enum CXErrorCode clang_createTranslationUnit2(CXIndex CIdx,
2984 const char *ast_filename,
2985 CXTranslationUnit *out_TU) {
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00002986 if (out_TU)
Craig Topper69186e72014-06-08 08:38:04 +00002987 *out_TU = nullptr;
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00002988
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002989 if (!CIdx || !ast_filename || !out_TU)
2990 return CXError_InvalidArguments;
Guy Benyei11169dd2012-12-18 14:30:41 +00002991
Argyrios Kyrtzidis27021012013-05-24 22:24:07 +00002992 LOG_FUNC_SECTION {
2993 *Log << ast_filename;
2994 }
2995
Guy Benyei11169dd2012-12-18 14:30:41 +00002996 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
2997 FileSystemOptions FileSystemOpts;
2998
Justin Bognerd512c1e2014-10-15 00:33:06 +00002999 IntrusiveRefCntPtr<DiagnosticsEngine> Diags =
3000 CompilerInstance::createDiagnostics(new DiagnosticOptions());
David Blaikie6f7382d2014-08-10 19:08:04 +00003001 std::unique_ptr<ASTUnit> AU = ASTUnit::LoadFromASTFile(
Adrian Prantlfb2398d2015-07-17 01:19:54 +00003002 ast_filename, CXXIdx->getPCHContainerOperations()->getRawReader(), Diags,
Adrian Prantl6b21ab22015-08-27 19:46:20 +00003003 FileSystemOpts, /*UseDebugInfo=*/false,
3004 CXXIdx->getOnlyLocalDecls(), None,
David Blaikie6f7382d2014-08-10 19:08:04 +00003005 /*CaptureDiagnostics=*/true,
3006 /*AllowPCHWithCompilerErrors=*/true,
3007 /*UserFilesAreVolatile=*/true);
3008 *out_TU = MakeCXTranslationUnit(CXXIdx, AU.release());
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003009 return *out_TU ? CXError_Success : CXError_Failure;
Guy Benyei11169dd2012-12-18 14:30:41 +00003010}
3011
3012unsigned clang_defaultEditingTranslationUnitOptions() {
3013 return CXTranslationUnit_PrecompiledPreamble |
3014 CXTranslationUnit_CacheCompletionResults;
3015}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003016
Guy Benyei11169dd2012-12-18 14:30:41 +00003017CXTranslationUnit
3018clang_createTranslationUnitFromSourceFile(CXIndex CIdx,
3019 const char *source_filename,
3020 int num_command_line_args,
3021 const char * const *command_line_args,
3022 unsigned num_unsaved_files,
3023 struct CXUnsavedFile *unsaved_files) {
3024 unsigned Options = CXTranslationUnit_DetailedPreprocessingRecord;
3025 return clang_parseTranslationUnit(CIdx, source_filename,
3026 command_line_args, num_command_line_args,
3027 unsaved_files, num_unsaved_files,
3028 Options);
3029}
3030
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003031static CXErrorCode
3032clang_parseTranslationUnit_Impl(CXIndex CIdx, const char *source_filename,
3033 const char *const *command_line_args,
3034 int num_command_line_args,
3035 ArrayRef<CXUnsavedFile> unsaved_files,
3036 unsigned options, CXTranslationUnit *out_TU) {
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00003037 // Set up the initial return values.
3038 if (out_TU)
Craig Topper69186e72014-06-08 08:38:04 +00003039 *out_TU = nullptr;
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00003040
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003041 // Check arguments.
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003042 if (!CIdx || !out_TU)
3043 return CXError_InvalidArguments;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003044
Guy Benyei11169dd2012-12-18 14:30:41 +00003045 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
3046
3047 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
3048 setThreadBackgroundPriority();
3049
3050 bool PrecompilePreamble = options & CXTranslationUnit_PrecompiledPreamble;
3051 // FIXME: Add a flag for modules.
3052 TranslationUnitKind TUKind
3053 = (options & CXTranslationUnit_Incomplete)? TU_Prefix : TU_Complete;
Alp Toker8c8a8752013-12-03 06:53:35 +00003054 bool CacheCodeCompletionResults
Guy Benyei11169dd2012-12-18 14:30:41 +00003055 = options & CXTranslationUnit_CacheCompletionResults;
3056 bool IncludeBriefCommentsInCodeCompletion
3057 = options & CXTranslationUnit_IncludeBriefCommentsInCodeCompletion;
3058 bool SkipFunctionBodies = options & CXTranslationUnit_SkipFunctionBodies;
3059 bool ForSerialization = options & CXTranslationUnit_ForSerialization;
3060
3061 // Configure the diagnostics.
3062 IntrusiveRefCntPtr<DiagnosticsEngine>
Sean Silvaf1b49e22013-01-20 01:58:28 +00003063 Diags(CompilerInstance::createDiagnostics(new DiagnosticOptions));
Guy Benyei11169dd2012-12-18 14:30:41 +00003064
3065 // Recover resources if we crash before exiting this function.
3066 llvm::CrashRecoveryContextCleanupRegistrar<DiagnosticsEngine,
3067 llvm::CrashRecoveryContextReleaseRefCleanup<DiagnosticsEngine> >
Alp Tokerf994cef2014-07-05 03:08:06 +00003068 DiagCleanup(Diags.get());
Guy Benyei11169dd2012-12-18 14:30:41 +00003069
Ahmed Charlesb8984322014-03-07 20:03:18 +00003070 std::unique_ptr<std::vector<ASTUnit::RemappedFile>> RemappedFiles(
3071 new std::vector<ASTUnit::RemappedFile>());
Guy Benyei11169dd2012-12-18 14:30:41 +00003072
3073 // Recover resources if we crash before exiting this function.
3074 llvm::CrashRecoveryContextCleanupRegistrar<
3075 std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
3076
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003077 for (auto &UF : unsaved_files) {
Rafael Espindolad87f8d72014-08-27 20:03:29 +00003078 std::unique_ptr<llvm::MemoryBuffer> MB =
Alp Toker9d85b182014-07-07 01:23:14 +00003079 llvm::MemoryBuffer::getMemBufferCopy(getContents(UF), UF.Filename);
Rafael Espindolad87f8d72014-08-27 20:03:29 +00003080 RemappedFiles->push_back(std::make_pair(UF.Filename, MB.release()));
Guy Benyei11169dd2012-12-18 14:30:41 +00003081 }
3082
Ahmed Charlesb8984322014-03-07 20:03:18 +00003083 std::unique_ptr<std::vector<const char *>> Args(
3084 new std::vector<const char *>());
Guy Benyei11169dd2012-12-18 14:30:41 +00003085
3086 // Recover resources if we crash before exiting this method.
3087 llvm::CrashRecoveryContextCleanupRegistrar<std::vector<const char*> >
3088 ArgsCleanup(Args.get());
3089
3090 // Since the Clang C library is primarily used by batch tools dealing with
3091 // (often very broken) source code, where spell-checking can have a
3092 // significant negative impact on performance (particularly when
3093 // precompiled headers are involved), we disable it by default.
3094 // Only do this if we haven't found a spell-checking-related argument.
3095 bool FoundSpellCheckingArgument = false;
3096 for (int I = 0; I != num_command_line_args; ++I) {
3097 if (strcmp(command_line_args[I], "-fno-spell-checking") == 0 ||
3098 strcmp(command_line_args[I], "-fspell-checking") == 0) {
3099 FoundSpellCheckingArgument = true;
3100 break;
3101 }
3102 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003103 Args->insert(Args->end(), command_line_args,
3104 command_line_args + num_command_line_args);
3105
Benjamin Kramerc02670e2015-11-18 16:14:27 +00003106 if (!FoundSpellCheckingArgument)
3107 Args->insert(Args->begin() + 1, "-fno-spell-checking");
3108
Guy Benyei11169dd2012-12-18 14:30:41 +00003109 // The 'source_filename' argument is optional. If the caller does not
3110 // specify it then it is assumed that the source file is specified
3111 // in the actual argument list.
3112 // Put the source file after command_line_args otherwise if '-x' flag is
3113 // present it will be unused.
3114 if (source_filename)
3115 Args->push_back(source_filename);
3116
3117 // Do we need the detailed preprocessing record?
3118 if (options & CXTranslationUnit_DetailedPreprocessingRecord) {
3119 Args->push_back("-Xclang");
3120 Args->push_back("-detailed-preprocessing-record");
3121 }
3122
3123 unsigned NumErrors = Diags->getClient()->getNumErrors();
Ahmed Charlesb8984322014-03-07 20:03:18 +00003124 std::unique_ptr<ASTUnit> ErrUnit;
3125 std::unique_ptr<ASTUnit> Unit(ASTUnit::LoadFromCommandLine(
Adrian Prantlbb165fb2015-06-20 18:53:08 +00003126 Args->data(), Args->data() + Args->size(),
3127 CXXIdx->getPCHContainerOperations(), Diags,
Ahmed Charlesb8984322014-03-07 20:03:18 +00003128 CXXIdx->getClangResourcesPath(), CXXIdx->getOnlyLocalDecls(),
3129 /*CaptureDiagnostics=*/true, *RemappedFiles.get(),
3130 /*RemappedFilesKeepOriginalName=*/true, PrecompilePreamble, TUKind,
3131 CacheCodeCompletionResults, IncludeBriefCommentsInCodeCompletion,
3132 /*AllowPCHWithCompilerErrors=*/true, SkipFunctionBodies,
Argyrios Kyrtzidisa3e2ff12015-11-20 03:36:21 +00003133 /*UserFilesAreVolatile=*/true, ForSerialization,
3134 CXXIdx->getPCHContainerOperations()->getRawReader().getFormat(),
3135 &ErrUnit));
Guy Benyei11169dd2012-12-18 14:30:41 +00003136
Artem Belevich0ff05cd2015-07-13 23:27:56 +00003137 // Early failures in LoadFromCommandLine may return with ErrUnit unset.
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003138 if (!Unit && !ErrUnit)
3139 return CXError_ASTReadError;
Artem Belevich0ff05cd2015-07-13 23:27:56 +00003140
Guy Benyei11169dd2012-12-18 14:30:41 +00003141 if (NumErrors != Diags->getClient()->getNumErrors()) {
3142 // Make sure to check that 'Unit' is non-NULL.
3143 if (CXXIdx->getDisplayDiagnostics())
3144 printDiagsToStderr(Unit ? Unit.get() : ErrUnit.get());
3145 }
3146
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003147 if (isASTReadError(Unit ? Unit.get() : ErrUnit.get()))
3148 return CXError_ASTReadError;
3149
3150 *out_TU = MakeCXTranslationUnit(CXXIdx, Unit.release());
3151 return *out_TU ? CXError_Success : CXError_Failure;
Guy Benyei11169dd2012-12-18 14:30:41 +00003152}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003153
3154CXTranslationUnit
3155clang_parseTranslationUnit(CXIndex CIdx,
3156 const char *source_filename,
3157 const char *const *command_line_args,
3158 int num_command_line_args,
3159 struct CXUnsavedFile *unsaved_files,
3160 unsigned num_unsaved_files,
3161 unsigned options) {
3162 CXTranslationUnit TU;
3163 enum CXErrorCode Result = clang_parseTranslationUnit2(
3164 CIdx, source_filename, command_line_args, num_command_line_args,
3165 unsaved_files, num_unsaved_files, options, &TU);
Reid Kleckner6eaf05a2014-02-13 01:19:59 +00003166 (void)Result;
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00003167 assert((TU && Result == CXError_Success) ||
3168 (!TU && Result != CXError_Success));
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003169 return TU;
3170}
3171
3172enum CXErrorCode clang_parseTranslationUnit2(
Benjamin Kramerc02670e2015-11-18 16:14:27 +00003173 CXIndex CIdx, const char *source_filename,
3174 const char *const *command_line_args, int num_command_line_args,
3175 struct CXUnsavedFile *unsaved_files, unsigned num_unsaved_files,
3176 unsigned options, CXTranslationUnit *out_TU) {
3177 SmallVector<const char *, 4> Args;
3178 Args.push_back("clang");
3179 Args.append(command_line_args, command_line_args + num_command_line_args);
3180 return clang_parseTranslationUnit2FullArgv(
3181 CIdx, source_filename, Args.data(), Args.size(), unsaved_files,
3182 num_unsaved_files, options, out_TU);
3183}
3184
3185enum CXErrorCode clang_parseTranslationUnit2FullArgv(
3186 CXIndex CIdx, const char *source_filename,
3187 const char *const *command_line_args, int num_command_line_args,
3188 struct CXUnsavedFile *unsaved_files, unsigned num_unsaved_files,
3189 unsigned options, CXTranslationUnit *out_TU) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00003190 LOG_FUNC_SECTION {
3191 *Log << source_filename << ": ";
3192 for (int i = 0; i != num_command_line_args; ++i)
3193 *Log << command_line_args[i] << " ";
3194 }
3195
Alp Toker9d85b182014-07-07 01:23:14 +00003196 if (num_unsaved_files && !unsaved_files)
3197 return CXError_InvalidArguments;
3198
Alp Toker5c532982014-07-07 22:42:03 +00003199 CXErrorCode result = CXError_Failure;
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003200 auto ParseTranslationUnitImpl = [=, &result] {
3201 result = clang_parseTranslationUnit_Impl(
3202 CIdx, source_filename, command_line_args, num_command_line_args,
3203 llvm::makeArrayRef(unsaved_files, num_unsaved_files), options, out_TU);
3204 };
Guy Benyei11169dd2012-12-18 14:30:41 +00003205 llvm::CrashRecoveryContext CRC;
3206
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003207 if (!RunSafely(CRC, ParseTranslationUnitImpl)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003208 fprintf(stderr, "libclang: crash detected during parsing: {\n");
3209 fprintf(stderr, " 'source_filename' : '%s'\n", source_filename);
3210 fprintf(stderr, " 'command_line_args' : [");
3211 for (int i = 0; i != num_command_line_args; ++i) {
3212 if (i)
3213 fprintf(stderr, ", ");
3214 fprintf(stderr, "'%s'", command_line_args[i]);
3215 }
3216 fprintf(stderr, "],\n");
3217 fprintf(stderr, " 'unsaved_files' : [");
3218 for (unsigned i = 0; i != num_unsaved_files; ++i) {
3219 if (i)
3220 fprintf(stderr, ", ");
3221 fprintf(stderr, "('%s', '...', %ld)", unsaved_files[i].Filename,
3222 unsaved_files[i].Length);
3223 }
3224 fprintf(stderr, "],\n");
3225 fprintf(stderr, " 'options' : %d,\n", options);
3226 fprintf(stderr, "}\n");
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003227
3228 return CXError_Crashed;
Guy Benyei11169dd2012-12-18 14:30:41 +00003229 } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003230 if (CXTranslationUnit *TU = out_TU)
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003231 PrintLibclangResourceUsage(*TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003232 }
Alp Toker5c532982014-07-07 22:42:03 +00003233
3234 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003235}
3236
3237unsigned clang_defaultSaveOptions(CXTranslationUnit TU) {
3238 return CXSaveTranslationUnit_None;
3239}
3240
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003241static CXSaveError clang_saveTranslationUnit_Impl(CXTranslationUnit TU,
3242 const char *FileName,
3243 unsigned options) {
3244 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00003245 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
3246 setThreadBackgroundPriority();
3247
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003248 bool hadError = cxtu::getASTUnit(TU)->Save(FileName);
3249 return hadError ? CXSaveError_Unknown : CXSaveError_None;
Guy Benyei11169dd2012-12-18 14:30:41 +00003250}
3251
3252int clang_saveTranslationUnit(CXTranslationUnit TU, const char *FileName,
3253 unsigned options) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00003254 LOG_FUNC_SECTION {
3255 *Log << TU << ' ' << FileName;
3256 }
3257
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003258 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003259 LOG_BAD_TU(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003260 return CXSaveError_InvalidTU;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003261 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003262
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003263 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003264 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
3265 if (!CXXUnit->hasSema())
3266 return CXSaveError_InvalidTU;
3267
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003268 CXSaveError result;
3269 auto SaveTranslationUnitImpl = [=, &result]() {
3270 result = clang_saveTranslationUnit_Impl(TU, FileName, options);
3271 };
Guy Benyei11169dd2012-12-18 14:30:41 +00003272
3273 if (!CXXUnit->getDiagnostics().hasUnrecoverableErrorOccurred() ||
3274 getenv("LIBCLANG_NOTHREADS")) {
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003275 SaveTranslationUnitImpl();
Guy Benyei11169dd2012-12-18 14:30:41 +00003276
3277 if (getenv("LIBCLANG_RESOURCE_USAGE"))
3278 PrintLibclangResourceUsage(TU);
3279
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003280 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003281 }
3282
3283 // We have an AST that has invalid nodes due to compiler errors.
3284 // Use a crash recovery thread for protection.
3285
3286 llvm::CrashRecoveryContext CRC;
3287
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003288 if (!RunSafely(CRC, SaveTranslationUnitImpl)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003289 fprintf(stderr, "libclang: crash detected during AST saving: {\n");
3290 fprintf(stderr, " 'filename' : '%s'\n", FileName);
3291 fprintf(stderr, " 'options' : %d,\n", options);
3292 fprintf(stderr, "}\n");
3293
3294 return CXSaveError_Unknown;
3295
3296 } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
3297 PrintLibclangResourceUsage(TU);
3298 }
3299
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003300 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003301}
3302
3303void clang_disposeTranslationUnit(CXTranslationUnit CTUnit) {
3304 if (CTUnit) {
3305 // If the translation unit has been marked as unsafe to free, just discard
3306 // it.
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003307 ASTUnit *Unit = cxtu::getASTUnit(CTUnit);
3308 if (Unit && Unit->isUnsafeToFree())
Guy Benyei11169dd2012-12-18 14:30:41 +00003309 return;
3310
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003311 delete cxtu::getASTUnit(CTUnit);
Dmitri Gribenkob95b3f12013-01-26 22:44:19 +00003312 delete CTUnit->StringPool;
Guy Benyei11169dd2012-12-18 14:30:41 +00003313 delete static_cast<CXDiagnosticSetImpl *>(CTUnit->Diagnostics);
3314 disposeOverridenCXCursorsPool(CTUnit->OverridenCursorsPool);
Dmitri Gribenko9e605112013-11-13 22:16:51 +00003315 delete CTUnit->CommentToXML;
Guy Benyei11169dd2012-12-18 14:30:41 +00003316 delete CTUnit;
3317 }
3318}
3319
3320unsigned clang_defaultReparseOptions(CXTranslationUnit TU) {
3321 return CXReparse_None;
3322}
3323
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003324static CXErrorCode
3325clang_reparseTranslationUnit_Impl(CXTranslationUnit TU,
3326 ArrayRef<CXUnsavedFile> unsaved_files,
3327 unsigned options) {
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003328 // Check arguments.
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003329 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003330 LOG_BAD_TU(TU);
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003331 return CXError_InvalidArguments;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003332 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003333
3334 // Reset the associated diagnostics.
3335 delete static_cast<CXDiagnosticSetImpl*>(TU->Diagnostics);
Craig Topper69186e72014-06-08 08:38:04 +00003336 TU->Diagnostics = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00003337
Dmitri Gribenko183436e2013-01-26 21:49:50 +00003338 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00003339 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
3340 setThreadBackgroundPriority();
3341
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003342 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003343 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
Ahmed Charlesb8984322014-03-07 20:03:18 +00003344
3345 std::unique_ptr<std::vector<ASTUnit::RemappedFile>> RemappedFiles(
3346 new std::vector<ASTUnit::RemappedFile>());
3347
Guy Benyei11169dd2012-12-18 14:30:41 +00003348 // Recover resources if we crash before exiting this function.
3349 llvm::CrashRecoveryContextCleanupRegistrar<
3350 std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
Alp Toker9d85b182014-07-07 01:23:14 +00003351
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003352 for (auto &UF : unsaved_files) {
Rafael Espindolad87f8d72014-08-27 20:03:29 +00003353 std::unique_ptr<llvm::MemoryBuffer> MB =
Alp Toker9d85b182014-07-07 01:23:14 +00003354 llvm::MemoryBuffer::getMemBufferCopy(getContents(UF), UF.Filename);
Rafael Espindolad87f8d72014-08-27 20:03:29 +00003355 RemappedFiles->push_back(std::make_pair(UF.Filename, MB.release()));
Guy Benyei11169dd2012-12-18 14:30:41 +00003356 }
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003357
Adrian Prantlbb165fb2015-06-20 18:53:08 +00003358 if (!CXXUnit->Reparse(CXXIdx->getPCHContainerOperations(),
3359 *RemappedFiles.get()))
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003360 return CXError_Success;
3361 if (isASTReadError(CXXUnit))
3362 return CXError_ASTReadError;
3363 return CXError_Failure;
Guy Benyei11169dd2012-12-18 14:30:41 +00003364}
3365
3366int clang_reparseTranslationUnit(CXTranslationUnit TU,
3367 unsigned num_unsaved_files,
3368 struct CXUnsavedFile *unsaved_files,
3369 unsigned options) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00003370 LOG_FUNC_SECTION {
3371 *Log << TU;
3372 }
3373
Alp Toker9d85b182014-07-07 01:23:14 +00003374 if (num_unsaved_files && !unsaved_files)
3375 return CXError_InvalidArguments;
3376
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003377 CXErrorCode result;
3378 auto ReparseTranslationUnitImpl = [=, &result]() {
3379 result = clang_reparseTranslationUnit_Impl(
3380 TU, llvm::makeArrayRef(unsaved_files, num_unsaved_files), options);
3381 };
Guy Benyei11169dd2012-12-18 14:30:41 +00003382
3383 if (getenv("LIBCLANG_NOTHREADS")) {
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003384 ReparseTranslationUnitImpl();
Alp Toker5c532982014-07-07 22:42:03 +00003385 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003386 }
3387
3388 llvm::CrashRecoveryContext CRC;
3389
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003390 if (!RunSafely(CRC, ReparseTranslationUnitImpl)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003391 fprintf(stderr, "libclang: crash detected during reparsing\n");
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003392 cxtu::getASTUnit(TU)->setUnsafeToFree(true);
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003393 return CXError_Crashed;
Guy Benyei11169dd2012-12-18 14:30:41 +00003394 } else if (getenv("LIBCLANG_RESOURCE_USAGE"))
3395 PrintLibclangResourceUsage(TU);
3396
Alp Toker5c532982014-07-07 22:42:03 +00003397 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003398}
3399
3400
3401CXString clang_getTranslationUnitSpelling(CXTranslationUnit CTUnit) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003402 if (isNotUsableTU(CTUnit)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003403 LOG_BAD_TU(CTUnit);
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003404 return cxstring::createEmpty();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003405 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003406
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003407 ASTUnit *CXXUnit = cxtu::getASTUnit(CTUnit);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003408 return cxstring::createDup(CXXUnit->getOriginalSourceFileName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003409}
3410
3411CXCursor clang_getTranslationUnitCursor(CXTranslationUnit TU) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003412 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003413 LOG_BAD_TU(TU);
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00003414 return clang_getNullCursor();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003415 }
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00003416
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003417 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003418 return MakeCXCursor(CXXUnit->getASTContext().getTranslationUnitDecl(), TU);
3419}
3420
3421} // end: extern "C"
3422
3423//===----------------------------------------------------------------------===//
3424// CXFile Operations.
3425//===----------------------------------------------------------------------===//
3426
3427extern "C" {
3428CXString clang_getFileName(CXFile SFile) {
3429 if (!SFile)
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00003430 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00003431
3432 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003433 return cxstring::createRef(FEnt->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003434}
3435
3436time_t clang_getFileTime(CXFile SFile) {
3437 if (!SFile)
3438 return 0;
3439
3440 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
3441 return FEnt->getModificationTime();
3442}
3443
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003444CXFile clang_getFile(CXTranslationUnit TU, const char *file_name) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003445 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003446 LOG_BAD_TU(TU);
Craig Topper69186e72014-06-08 08:38:04 +00003447 return nullptr;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003448 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003449
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003450 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003451
3452 FileManager &FMgr = CXXUnit->getFileManager();
3453 return const_cast<FileEntry *>(FMgr.getFile(file_name));
3454}
3455
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003456unsigned clang_isFileMultipleIncludeGuarded(CXTranslationUnit TU,
3457 CXFile file) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003458 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003459 LOG_BAD_TU(TU);
3460 return 0;
3461 }
3462
3463 if (!file)
Guy Benyei11169dd2012-12-18 14:30:41 +00003464 return 0;
3465
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003466 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003467 FileEntry *FEnt = static_cast<FileEntry *>(file);
3468 return CXXUnit->getPreprocessor().getHeaderSearchInfo()
3469 .isFileMultipleIncludeGuarded(FEnt);
3470}
3471
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003472int clang_getFileUniqueID(CXFile file, CXFileUniqueID *outID) {
3473 if (!file || !outID)
3474 return 1;
3475
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003476 FileEntry *FEnt = static_cast<FileEntry *>(file);
Rafael Espindolaf8f91b82013-08-01 21:42:11 +00003477 const llvm::sys::fs::UniqueID &ID = FEnt->getUniqueID();
3478 outID->data[0] = ID.getDevice();
3479 outID->data[1] = ID.getFile();
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003480 outID->data[2] = FEnt->getModificationTime();
3481 return 0;
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003482}
3483
Argyrios Kyrtzidisac3997e2014-08-16 00:26:19 +00003484int clang_File_isEqual(CXFile file1, CXFile file2) {
3485 if (file1 == file2)
3486 return true;
3487
3488 if (!file1 || !file2)
3489 return false;
3490
3491 FileEntry *FEnt1 = static_cast<FileEntry *>(file1);
3492 FileEntry *FEnt2 = static_cast<FileEntry *>(file2);
3493 return FEnt1->getUniqueID() == FEnt2->getUniqueID();
3494}
3495
Guy Benyei11169dd2012-12-18 14:30:41 +00003496} // end: extern "C"
3497
3498//===----------------------------------------------------------------------===//
3499// CXCursor Operations.
3500//===----------------------------------------------------------------------===//
3501
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003502static const Decl *getDeclFromExpr(const Stmt *E) {
3503 if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003504 return getDeclFromExpr(CE->getSubExpr());
3505
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003506 if (const DeclRefExpr *RefExpr = dyn_cast<DeclRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003507 return RefExpr->getDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003508 if (const MemberExpr *ME = dyn_cast<MemberExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003509 return ME->getMemberDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003510 if (const ObjCIvarRefExpr *RE = dyn_cast<ObjCIvarRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003511 return RE->getDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003512 if (const ObjCPropertyRefExpr *PRE = dyn_cast<ObjCPropertyRefExpr>(E)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003513 if (PRE->isExplicitProperty())
3514 return PRE->getExplicitProperty();
3515 // It could be messaging both getter and setter as in:
3516 // ++myobj.myprop;
3517 // in which case prefer to associate the setter since it is less obvious
3518 // from inspecting the source that the setter is going to get called.
3519 if (PRE->isMessagingSetter())
3520 return PRE->getImplicitPropertySetter();
3521 return PRE->getImplicitPropertyGetter();
3522 }
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003523 if (const PseudoObjectExpr *POE = dyn_cast<PseudoObjectExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003524 return getDeclFromExpr(POE->getSyntacticForm());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003525 if (const OpaqueValueExpr *OVE = dyn_cast<OpaqueValueExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003526 if (Expr *Src = OVE->getSourceExpr())
3527 return getDeclFromExpr(Src);
3528
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003529 if (const CallExpr *CE = dyn_cast<CallExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003530 return getDeclFromExpr(CE->getCallee());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003531 if (const CXXConstructExpr *CE = dyn_cast<CXXConstructExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003532 if (!CE->isElidable())
3533 return CE->getConstructor();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003534 if (const ObjCMessageExpr *OME = dyn_cast<ObjCMessageExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003535 return OME->getMethodDecl();
3536
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003537 if (const ObjCProtocolExpr *PE = dyn_cast<ObjCProtocolExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003538 return PE->getProtocol();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003539 if (const SubstNonTypeTemplateParmPackExpr *NTTP
Guy Benyei11169dd2012-12-18 14:30:41 +00003540 = dyn_cast<SubstNonTypeTemplateParmPackExpr>(E))
3541 return NTTP->getParameterPack();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003542 if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003543 if (isa<NonTypeTemplateParmDecl>(SizeOfPack->getPack()) ||
3544 isa<ParmVarDecl>(SizeOfPack->getPack()))
3545 return SizeOfPack->getPack();
Craig Topper69186e72014-06-08 08:38:04 +00003546
3547 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00003548}
3549
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003550static SourceLocation getLocationFromExpr(const Expr *E) {
3551 if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003552 return getLocationFromExpr(CE->getSubExpr());
3553
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003554 if (const ObjCMessageExpr *Msg = dyn_cast<ObjCMessageExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003555 return /*FIXME:*/Msg->getLeftLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003556 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003557 return DRE->getLocation();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003558 if (const MemberExpr *Member = dyn_cast<MemberExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003559 return Member->getMemberLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003560 if (const ObjCIvarRefExpr *Ivar = dyn_cast<ObjCIvarRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003561 return Ivar->getLocation();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003562 if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003563 return SizeOfPack->getPackLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003564 if (const ObjCPropertyRefExpr *PropRef = dyn_cast<ObjCPropertyRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003565 return PropRef->getLocation();
3566
3567 return E->getLocStart();
3568}
3569
Aaron Ballmana85d3f82015-11-12 15:25:06 +00003570static std::string getMangledStructor(std::unique_ptr<MangleContext> &M,
3571 std::unique_ptr<llvm::DataLayout> &DL,
3572 const NamedDecl *ND,
3573 unsigned StructorType) {
3574 std::string FrontendBuf;
3575 llvm::raw_string_ostream FOS(FrontendBuf);
3576
3577 if (const auto *CD = dyn_cast_or_null<CXXConstructorDecl>(ND))
3578 M->mangleCXXCtor(CD, static_cast<CXXCtorType>(StructorType), FOS);
3579 else if (const auto *DD = dyn_cast_or_null<CXXDestructorDecl>(ND))
3580 M->mangleCXXDtor(DD, static_cast<CXXDtorType>(StructorType), FOS);
3581
3582 std::string BackendBuf;
3583 llvm::raw_string_ostream BOS(BackendBuf);
3584
3585 llvm::Mangler::getNameWithPrefix(BOS, llvm::Twine(FOS.str()), *DL);
3586
3587 return BOS.str();
3588}
3589
Guy Benyei11169dd2012-12-18 14:30:41 +00003590extern "C" {
3591
3592unsigned clang_visitChildren(CXCursor parent,
3593 CXCursorVisitor visitor,
3594 CXClientData client_data) {
3595 CursorVisitor CursorVis(getCursorTU(parent), visitor, client_data,
3596 /*VisitPreprocessorLast=*/false);
3597 return CursorVis.VisitChildren(parent);
3598}
3599
3600#ifndef __has_feature
3601#define __has_feature(x) 0
3602#endif
3603#if __has_feature(blocks)
3604typedef enum CXChildVisitResult
3605 (^CXCursorVisitorBlock)(CXCursor cursor, CXCursor parent);
3606
3607static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
3608 CXClientData client_data) {
3609 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
3610 return block(cursor, parent);
3611}
3612#else
3613// If we are compiled with a compiler that doesn't have native blocks support,
3614// define and call the block manually, so the
3615typedef struct _CXChildVisitResult
3616{
3617 void *isa;
3618 int flags;
3619 int reserved;
3620 enum CXChildVisitResult(*invoke)(struct _CXChildVisitResult*, CXCursor,
3621 CXCursor);
3622} *CXCursorVisitorBlock;
3623
3624static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
3625 CXClientData client_data) {
3626 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
3627 return block->invoke(block, cursor, parent);
3628}
3629#endif
3630
3631
3632unsigned clang_visitChildrenWithBlock(CXCursor parent,
3633 CXCursorVisitorBlock block) {
3634 return clang_visitChildren(parent, visitWithBlock, block);
3635}
3636
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003637static CXString getDeclSpelling(const Decl *D) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003638 if (!D)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003639 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003640
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003641 const NamedDecl *ND = dyn_cast<NamedDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00003642 if (!ND) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003643 if (const ObjCPropertyImplDecl *PropImpl =
3644 dyn_cast<ObjCPropertyImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00003645 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003646 return cxstring::createDup(Property->getIdentifier()->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003647
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003648 if (const ImportDecl *ImportD = dyn_cast<ImportDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00003649 if (Module *Mod = ImportD->getImportedModule())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003650 return cxstring::createDup(Mod->getFullModuleName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003651
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003652 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003653 }
3654
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003655 if (const ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(ND))
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003656 return cxstring::createDup(OMD->getSelector().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003657
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003658 if (const ObjCCategoryImplDecl *CIMP = dyn_cast<ObjCCategoryImplDecl>(ND))
Guy Benyei11169dd2012-12-18 14:30:41 +00003659 // No, this isn't the same as the code below. getIdentifier() is non-virtual
3660 // and returns different names. NamedDecl returns the class name and
3661 // ObjCCategoryImplDecl returns the category name.
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003662 return cxstring::createRef(CIMP->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003663
3664 if (isa<UsingDirectiveDecl>(D))
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003665 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003666
3667 SmallString<1024> S;
3668 llvm::raw_svector_ostream os(S);
3669 ND->printName(os);
3670
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003671 return cxstring::createDup(os.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003672}
3673
3674CXString clang_getCursorSpelling(CXCursor C) {
3675 if (clang_isTranslationUnit(C.kind))
Dmitri Gribenko2c173b42013-01-11 19:28:44 +00003676 return clang_getTranslationUnitSpelling(getCursorTU(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00003677
3678 if (clang_isReference(C.kind)) {
3679 switch (C.kind) {
3680 case CXCursor_ObjCSuperClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003681 const ObjCInterfaceDecl *Super = getCursorObjCSuperClassRef(C).first;
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003682 return cxstring::createRef(Super->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003683 }
3684 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003685 const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003686 return cxstring::createRef(Class->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003687 }
3688 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003689 const ObjCProtocolDecl *OID = getCursorObjCProtocolRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003690 assert(OID && "getCursorSpelling(): Missing protocol decl");
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003691 return cxstring::createRef(OID->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003692 }
3693 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003694 const CXXBaseSpecifier *B = getCursorCXXBaseSpecifier(C);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003695 return cxstring::createDup(B->getType().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003696 }
3697 case CXCursor_TypeRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003698 const TypeDecl *Type = getCursorTypeRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003699 assert(Type && "Missing type decl");
3700
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003701 return cxstring::createDup(getCursorContext(C).getTypeDeclType(Type).
Guy Benyei11169dd2012-12-18 14:30:41 +00003702 getAsString());
3703 }
3704 case CXCursor_TemplateRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003705 const TemplateDecl *Template = getCursorTemplateRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003706 assert(Template && "Missing template decl");
3707
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003708 return cxstring::createDup(Template->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003709 }
3710
3711 case CXCursor_NamespaceRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003712 const NamedDecl *NS = getCursorNamespaceRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003713 assert(NS && "Missing namespace decl");
3714
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003715 return cxstring::createDup(NS->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003716 }
3717
3718 case CXCursor_MemberRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003719 const FieldDecl *Field = getCursorMemberRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003720 assert(Field && "Missing member decl");
3721
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003722 return cxstring::createDup(Field->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003723 }
3724
3725 case CXCursor_LabelRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003726 const LabelStmt *Label = getCursorLabelRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003727 assert(Label && "Missing label");
3728
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003729 return cxstring::createRef(Label->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003730 }
3731
3732 case CXCursor_OverloadedDeclRef: {
3733 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003734 if (const Decl *D = Storage.dyn_cast<const Decl *>()) {
3735 if (const NamedDecl *ND = dyn_cast<NamedDecl>(D))
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003736 return cxstring::createDup(ND->getNameAsString());
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003737 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003738 }
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003739 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003740 return cxstring::createDup(E->getName().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003741 OverloadedTemplateStorage *Ovl
3742 = Storage.get<OverloadedTemplateStorage*>();
3743 if (Ovl->size() == 0)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003744 return cxstring::createEmpty();
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003745 return cxstring::createDup((*Ovl->begin())->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003746 }
3747
3748 case CXCursor_VariableRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003749 const VarDecl *Var = getCursorVariableRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003750 assert(Var && "Missing variable decl");
3751
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003752 return cxstring::createDup(Var->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003753 }
3754
3755 default:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003756 return cxstring::createRef("<not implemented>");
Guy Benyei11169dd2012-12-18 14:30:41 +00003757 }
3758 }
3759
3760 if (clang_isExpression(C.kind)) {
Argyrios Kyrtzidis3227d862014-03-03 19:40:52 +00003761 const Expr *E = getCursorExpr(C);
3762
3763 if (C.kind == CXCursor_ObjCStringLiteral ||
3764 C.kind == CXCursor_StringLiteral) {
3765 const StringLiteral *SLit;
3766 if (const ObjCStringLiteral *OSL = dyn_cast<ObjCStringLiteral>(E)) {
3767 SLit = OSL->getString();
3768 } else {
3769 SLit = cast<StringLiteral>(E);
3770 }
3771 SmallString<256> Buf;
3772 llvm::raw_svector_ostream OS(Buf);
3773 SLit->outputString(OS);
3774 return cxstring::createDup(OS.str());
3775 }
3776
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003777 const Decl *D = getDeclFromExpr(getCursorExpr(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00003778 if (D)
3779 return getDeclSpelling(D);
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003780 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003781 }
3782
3783 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003784 const Stmt *S = getCursorStmt(C);
3785 if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S))
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003786 return cxstring::createRef(Label->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003787
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003788 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003789 }
3790
3791 if (C.kind == CXCursor_MacroExpansion)
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003792 return cxstring::createRef(getCursorMacroExpansion(C).getName()
Guy Benyei11169dd2012-12-18 14:30:41 +00003793 ->getNameStart());
3794
3795 if (C.kind == CXCursor_MacroDefinition)
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003796 return cxstring::createRef(getCursorMacroDefinition(C)->getName()
Guy Benyei11169dd2012-12-18 14:30:41 +00003797 ->getNameStart());
3798
3799 if (C.kind == CXCursor_InclusionDirective)
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003800 return cxstring::createDup(getCursorInclusionDirective(C)->getFileName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003801
3802 if (clang_isDeclaration(C.kind))
3803 return getDeclSpelling(getCursorDecl(C));
3804
3805 if (C.kind == CXCursor_AnnotateAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00003806 const AnnotateAttr *AA = cast<AnnotateAttr>(cxcursor::getCursorAttr(C));
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003807 return cxstring::createDup(AA->getAnnotation());
Guy Benyei11169dd2012-12-18 14:30:41 +00003808 }
3809
3810 if (C.kind == CXCursor_AsmLabelAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00003811 const AsmLabelAttr *AA = cast<AsmLabelAttr>(cxcursor::getCursorAttr(C));
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003812 return cxstring::createDup(AA->getLabel());
Guy Benyei11169dd2012-12-18 14:30:41 +00003813 }
3814
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00003815 if (C.kind == CXCursor_PackedAttr) {
3816 return cxstring::createRef("packed");
3817 }
3818
Saleem Abdulrasool79c69712015-09-05 18:53:43 +00003819 if (C.kind == CXCursor_VisibilityAttr) {
3820 const VisibilityAttr *AA = cast<VisibilityAttr>(cxcursor::getCursorAttr(C));
3821 switch (AA->getVisibility()) {
3822 case VisibilityAttr::VisibilityType::Default:
3823 return cxstring::createRef("default");
3824 case VisibilityAttr::VisibilityType::Hidden:
3825 return cxstring::createRef("hidden");
3826 case VisibilityAttr::VisibilityType::Protected:
3827 return cxstring::createRef("protected");
3828 }
3829 llvm_unreachable("unknown visibility type");
3830 }
3831
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003832 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003833}
3834
3835CXSourceRange clang_Cursor_getSpellingNameRange(CXCursor C,
3836 unsigned pieceIndex,
3837 unsigned options) {
3838 if (clang_Cursor_isNull(C))
3839 return clang_getNullRange();
3840
3841 ASTContext &Ctx = getCursorContext(C);
3842
3843 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003844 const Stmt *S = getCursorStmt(C);
3845 if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003846 if (pieceIndex > 0)
3847 return clang_getNullRange();
3848 return cxloc::translateSourceRange(Ctx, Label->getIdentLoc());
3849 }
3850
3851 return clang_getNullRange();
3852 }
3853
3854 if (C.kind == CXCursor_ObjCMessageExpr) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003855 if (const ObjCMessageExpr *
Guy Benyei11169dd2012-12-18 14:30:41 +00003856 ME = dyn_cast_or_null<ObjCMessageExpr>(getCursorExpr(C))) {
3857 if (pieceIndex >= ME->getNumSelectorLocs())
3858 return clang_getNullRange();
3859 return cxloc::translateSourceRange(Ctx, ME->getSelectorLoc(pieceIndex));
3860 }
3861 }
3862
3863 if (C.kind == CXCursor_ObjCInstanceMethodDecl ||
3864 C.kind == CXCursor_ObjCClassMethodDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003865 if (const ObjCMethodDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003866 MD = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(C))) {
3867 if (pieceIndex >= MD->getNumSelectorLocs())
3868 return clang_getNullRange();
3869 return cxloc::translateSourceRange(Ctx, MD->getSelectorLoc(pieceIndex));
3870 }
3871 }
3872
3873 if (C.kind == CXCursor_ObjCCategoryDecl ||
3874 C.kind == CXCursor_ObjCCategoryImplDecl) {
3875 if (pieceIndex > 0)
3876 return clang_getNullRange();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003877 if (const ObjCCategoryDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003878 CD = dyn_cast_or_null<ObjCCategoryDecl>(getCursorDecl(C)))
3879 return cxloc::translateSourceRange(Ctx, CD->getCategoryNameLoc());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003880 if (const ObjCCategoryImplDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003881 CID = dyn_cast_or_null<ObjCCategoryImplDecl>(getCursorDecl(C)))
3882 return cxloc::translateSourceRange(Ctx, CID->getCategoryNameLoc());
3883 }
3884
3885 if (C.kind == CXCursor_ModuleImportDecl) {
3886 if (pieceIndex > 0)
3887 return clang_getNullRange();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003888 if (const ImportDecl *ImportD =
3889 dyn_cast_or_null<ImportDecl>(getCursorDecl(C))) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003890 ArrayRef<SourceLocation> Locs = ImportD->getIdentifierLocs();
3891 if (!Locs.empty())
3892 return cxloc::translateSourceRange(Ctx,
3893 SourceRange(Locs.front(), Locs.back()));
3894 }
3895 return clang_getNullRange();
3896 }
3897
Argyrios Kyrtzidisa2a1e532014-08-26 20:23:26 +00003898 if (C.kind == CXCursor_CXXMethod || C.kind == CXCursor_Destructor ||
3899 C.kind == CXCursor_ConversionFunction) {
3900 if (pieceIndex > 0)
3901 return clang_getNullRange();
3902 if (const FunctionDecl *FD =
3903 dyn_cast_or_null<FunctionDecl>(getCursorDecl(C))) {
3904 DeclarationNameInfo FunctionName = FD->getNameInfo();
3905 return cxloc::translateSourceRange(Ctx, FunctionName.getSourceRange());
3906 }
3907 return clang_getNullRange();
3908 }
3909
Guy Benyei11169dd2012-12-18 14:30:41 +00003910 // FIXME: A CXCursor_InclusionDirective should give the location of the
3911 // filename, but we don't keep track of this.
3912
3913 // FIXME: A CXCursor_AnnotateAttr should give the location of the annotation
3914 // but we don't keep track of this.
3915
3916 // FIXME: A CXCursor_AsmLabelAttr should give the location of the label
3917 // but we don't keep track of this.
3918
3919 // Default handling, give the location of the cursor.
3920
3921 if (pieceIndex > 0)
3922 return clang_getNullRange();
3923
3924 CXSourceLocation CXLoc = clang_getCursorLocation(C);
3925 SourceLocation Loc = cxloc::translateSourceLocation(CXLoc);
3926 return cxloc::translateSourceRange(Ctx, Loc);
3927}
3928
Eli Bendersky44a206f2014-07-31 18:04:56 +00003929CXString clang_Cursor_getMangling(CXCursor C) {
3930 if (clang_isInvalid(C.kind) || !clang_isDeclaration(C.kind))
3931 return cxstring::createEmpty();
3932
Eli Bendersky44a206f2014-07-31 18:04:56 +00003933 // Mangling only works for functions and variables.
Eli Bendersky79759592014-08-01 15:01:10 +00003934 const Decl *D = getCursorDecl(C);
Eli Bendersky44a206f2014-07-31 18:04:56 +00003935 if (!D || !(isa<FunctionDecl>(D) || isa<VarDecl>(D)))
3936 return cxstring::createEmpty();
3937
Eli Bendersky79759592014-08-01 15:01:10 +00003938 // First apply frontend mangling.
Eli Bendersky44a206f2014-07-31 18:04:56 +00003939 const NamedDecl *ND = cast<NamedDecl>(D);
Eli Bendersky79759592014-08-01 15:01:10 +00003940 ASTContext &Ctx = ND->getASTContext();
3941 std::unique_ptr<MangleContext> MC(Ctx.createMangleContext());
Eli Bendersky44a206f2014-07-31 18:04:56 +00003942
Eli Bendersky79759592014-08-01 15:01:10 +00003943 std::string FrontendBuf;
3944 llvm::raw_string_ostream FrontendBufOS(FrontendBuf);
Ehsan Akhgarif8d44de2015-10-08 00:01:20 +00003945 if (MC->shouldMangleDeclName(ND)) {
3946 MC->mangleName(ND, FrontendBufOS);
3947 } else {
3948 ND->printName(FrontendBufOS);
3949 }
Eli Bendersky44a206f2014-07-31 18:04:56 +00003950
Eli Bendersky79759592014-08-01 15:01:10 +00003951 // Now apply backend mangling.
3952 std::unique_ptr<llvm::DataLayout> DL(
Eric Christopher964a5f32015-08-05 23:48:05 +00003953 new llvm::DataLayout(Ctx.getTargetInfo().getDataLayoutString()));
Eli Bendersky79759592014-08-01 15:01:10 +00003954
3955 std::string FinalBuf;
3956 llvm::raw_string_ostream FinalBufOS(FinalBuf);
Rafael Espindolab633d202015-06-23 13:59:36 +00003957 llvm::Mangler::getNameWithPrefix(FinalBufOS, llvm::Twine(FrontendBufOS.str()),
3958 *DL);
Eli Bendersky79759592014-08-01 15:01:10 +00003959
3960 return cxstring::createDup(FinalBufOS.str());
Eli Bendersky44a206f2014-07-31 18:04:56 +00003961}
3962
Saleem Abdulrasool60034432015-11-12 03:57:22 +00003963CXStringSet *clang_Cursor_getCXXManglings(CXCursor C) {
3964 if (clang_isInvalid(C.kind) || !clang_isDeclaration(C.kind))
3965 return nullptr;
3966
3967 const Decl *D = getCursorDecl(C);
3968 if (!(isa<CXXRecordDecl>(D) || isa<CXXMethodDecl>(D)))
3969 return nullptr;
3970
3971 const NamedDecl *ND = cast<NamedDecl>(D);
3972
3973 ASTContext &Ctx = ND->getASTContext();
3974 std::unique_ptr<MangleContext> M(Ctx.createMangleContext());
3975 std::unique_ptr<llvm::DataLayout> DL(
3976 new llvm::DataLayout(Ctx.getTargetInfo().getDataLayoutString()));
3977
3978 std::vector<std::string> Manglings;
3979
3980 auto hasDefaultCXXMethodCC = [](ASTContext &C, const CXXMethodDecl *MD) {
3981 auto DefaultCC = C.getDefaultCallingConvention(/*IsVariadic=*/false,
3982 /*IsCSSMethod=*/true);
3983 auto CC = MD->getType()->getAs<FunctionProtoType>()->getCallConv();
3984 return CC == DefaultCC;
3985 };
3986
3987 if (const auto *CD = dyn_cast_or_null<CXXConstructorDecl>(ND)) {
3988 Manglings.emplace_back(getMangledStructor(M, DL, CD, Ctor_Base));
3989
3990 if (Ctx.getTargetInfo().getCXXABI().isItaniumFamily())
3991 if (!CD->getParent()->isAbstract())
3992 Manglings.emplace_back(getMangledStructor(M, DL, CD, Ctor_Complete));
3993
3994 if (Ctx.getTargetInfo().getCXXABI().isMicrosoft())
3995 if (CD->hasAttr<DLLExportAttr>() && CD->isDefaultConstructor())
3996 if (!(hasDefaultCXXMethodCC(Ctx, CD) && CD->getNumParams() == 0))
3997 Manglings.emplace_back(getMangledStructor(M, DL, CD,
3998 Ctor_DefaultClosure));
3999 } else if (const auto *DD = dyn_cast_or_null<CXXDestructorDecl>(ND)) {
4000 Manglings.emplace_back(getMangledStructor(M, DL, DD, Dtor_Base));
4001 if (Ctx.getTargetInfo().getCXXABI().isItaniumFamily()) {
4002 Manglings.emplace_back(getMangledStructor(M, DL, DD, Dtor_Complete));
4003
4004 if (!DD->isVirtual())
4005 Manglings.emplace_back(getMangledStructor(M, DL, DD, Dtor_Deleting));
4006 }
4007 }
4008
4009 return cxstring::createSet(Manglings);
4010}
4011
Guy Benyei11169dd2012-12-18 14:30:41 +00004012CXString clang_getCursorDisplayName(CXCursor C) {
4013 if (!clang_isDeclaration(C.kind))
4014 return clang_getCursorSpelling(C);
4015
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004016 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004017 if (!D)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00004018 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00004019
4020 PrintingPolicy Policy = getCursorContext(C).getPrintingPolicy();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004021 if (const FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004022 D = FunTmpl->getTemplatedDecl();
4023
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004024 if (const FunctionDecl *Function = dyn_cast<FunctionDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004025 SmallString<64> Str;
4026 llvm::raw_svector_ostream OS(Str);
4027 OS << *Function;
4028 if (Function->getPrimaryTemplate())
4029 OS << "<>";
4030 OS << "(";
4031 for (unsigned I = 0, N = Function->getNumParams(); I != N; ++I) {
4032 if (I)
4033 OS << ", ";
4034 OS << Function->getParamDecl(I)->getType().getAsString(Policy);
4035 }
4036
4037 if (Function->isVariadic()) {
4038 if (Function->getNumParams())
4039 OS << ", ";
4040 OS << "...";
4041 }
4042 OS << ")";
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004043 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00004044 }
4045
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004046 if (const ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004047 SmallString<64> Str;
4048 llvm::raw_svector_ostream OS(Str);
4049 OS << *ClassTemplate;
4050 OS << "<";
4051 TemplateParameterList *Params = ClassTemplate->getTemplateParameters();
4052 for (unsigned I = 0, N = Params->size(); I != N; ++I) {
4053 if (I)
4054 OS << ", ";
4055
4056 NamedDecl *Param = Params->getParam(I);
4057 if (Param->getIdentifier()) {
4058 OS << Param->getIdentifier()->getName();
4059 continue;
4060 }
4061
4062 // There is no parameter name, which makes this tricky. Try to come up
4063 // with something useful that isn't too long.
4064 if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(Param))
4065 OS << (TTP->wasDeclaredWithTypename()? "typename" : "class");
4066 else if (NonTypeTemplateParmDecl *NTTP
4067 = dyn_cast<NonTypeTemplateParmDecl>(Param))
4068 OS << NTTP->getType().getAsString(Policy);
4069 else
4070 OS << "template<...> class";
4071 }
4072
4073 OS << ">";
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004074 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00004075 }
4076
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004077 if (const ClassTemplateSpecializationDecl *ClassSpec
Guy Benyei11169dd2012-12-18 14:30:41 +00004078 = dyn_cast<ClassTemplateSpecializationDecl>(D)) {
4079 // If the type was explicitly written, use that.
4080 if (TypeSourceInfo *TSInfo = ClassSpec->getTypeAsWritten())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004081 return cxstring::createDup(TSInfo->getType().getAsString(Policy));
Guy Benyei11169dd2012-12-18 14:30:41 +00004082
Benjamin Kramer9170e912013-02-22 15:46:01 +00004083 SmallString<128> Str;
Guy Benyei11169dd2012-12-18 14:30:41 +00004084 llvm::raw_svector_ostream OS(Str);
4085 OS << *ClassSpec;
Benjamin Kramer9170e912013-02-22 15:46:01 +00004086 TemplateSpecializationType::PrintTemplateArgumentList(OS,
Guy Benyei11169dd2012-12-18 14:30:41 +00004087 ClassSpec->getTemplateArgs().data(),
4088 ClassSpec->getTemplateArgs().size(),
4089 Policy);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004090 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00004091 }
4092
4093 return clang_getCursorSpelling(C);
4094}
4095
4096CXString clang_getCursorKindSpelling(enum CXCursorKind Kind) {
4097 switch (Kind) {
4098 case CXCursor_FunctionDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004099 return cxstring::createRef("FunctionDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004100 case CXCursor_TypedefDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004101 return cxstring::createRef("TypedefDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004102 case CXCursor_EnumDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004103 return cxstring::createRef("EnumDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004104 case CXCursor_EnumConstantDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004105 return cxstring::createRef("EnumConstantDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004106 case CXCursor_StructDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004107 return cxstring::createRef("StructDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004108 case CXCursor_UnionDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004109 return cxstring::createRef("UnionDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004110 case CXCursor_ClassDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004111 return cxstring::createRef("ClassDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004112 case CXCursor_FieldDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004113 return cxstring::createRef("FieldDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004114 case CXCursor_VarDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004115 return cxstring::createRef("VarDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004116 case CXCursor_ParmDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004117 return cxstring::createRef("ParmDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004118 case CXCursor_ObjCInterfaceDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004119 return cxstring::createRef("ObjCInterfaceDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004120 case CXCursor_ObjCCategoryDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004121 return cxstring::createRef("ObjCCategoryDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004122 case CXCursor_ObjCProtocolDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004123 return cxstring::createRef("ObjCProtocolDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004124 case CXCursor_ObjCPropertyDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004125 return cxstring::createRef("ObjCPropertyDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004126 case CXCursor_ObjCIvarDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004127 return cxstring::createRef("ObjCIvarDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004128 case CXCursor_ObjCInstanceMethodDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004129 return cxstring::createRef("ObjCInstanceMethodDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004130 case CXCursor_ObjCClassMethodDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004131 return cxstring::createRef("ObjCClassMethodDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004132 case CXCursor_ObjCImplementationDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004133 return cxstring::createRef("ObjCImplementationDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004134 case CXCursor_ObjCCategoryImplDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004135 return cxstring::createRef("ObjCCategoryImplDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004136 case CXCursor_CXXMethod:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004137 return cxstring::createRef("CXXMethod");
Guy Benyei11169dd2012-12-18 14:30:41 +00004138 case CXCursor_UnexposedDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004139 return cxstring::createRef("UnexposedDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004140 case CXCursor_ObjCSuperClassRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004141 return cxstring::createRef("ObjCSuperClassRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004142 case CXCursor_ObjCProtocolRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004143 return cxstring::createRef("ObjCProtocolRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004144 case CXCursor_ObjCClassRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004145 return cxstring::createRef("ObjCClassRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004146 case CXCursor_TypeRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004147 return cxstring::createRef("TypeRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004148 case CXCursor_TemplateRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004149 return cxstring::createRef("TemplateRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004150 case CXCursor_NamespaceRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004151 return cxstring::createRef("NamespaceRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004152 case CXCursor_MemberRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004153 return cxstring::createRef("MemberRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004154 case CXCursor_LabelRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004155 return cxstring::createRef("LabelRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004156 case CXCursor_OverloadedDeclRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004157 return cxstring::createRef("OverloadedDeclRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004158 case CXCursor_VariableRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004159 return cxstring::createRef("VariableRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004160 case CXCursor_IntegerLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004161 return cxstring::createRef("IntegerLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00004162 case CXCursor_FloatingLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004163 return cxstring::createRef("FloatingLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00004164 case CXCursor_ImaginaryLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004165 return cxstring::createRef("ImaginaryLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00004166 case CXCursor_StringLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004167 return cxstring::createRef("StringLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00004168 case CXCursor_CharacterLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004169 return cxstring::createRef("CharacterLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00004170 case CXCursor_ParenExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004171 return cxstring::createRef("ParenExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004172 case CXCursor_UnaryOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004173 return cxstring::createRef("UnaryOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00004174 case CXCursor_ArraySubscriptExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004175 return cxstring::createRef("ArraySubscriptExpr");
Alexey Bataev1a3320e2015-08-25 14:24:04 +00004176 case CXCursor_OMPArraySectionExpr:
4177 return cxstring::createRef("OMPArraySectionExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004178 case CXCursor_BinaryOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004179 return cxstring::createRef("BinaryOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00004180 case CXCursor_CompoundAssignOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004181 return cxstring::createRef("CompoundAssignOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00004182 case CXCursor_ConditionalOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004183 return cxstring::createRef("ConditionalOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00004184 case CXCursor_CStyleCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004185 return cxstring::createRef("CStyleCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004186 case CXCursor_CompoundLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004187 return cxstring::createRef("CompoundLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004188 case CXCursor_InitListExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004189 return cxstring::createRef("InitListExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004190 case CXCursor_AddrLabelExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004191 return cxstring::createRef("AddrLabelExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004192 case CXCursor_StmtExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004193 return cxstring::createRef("StmtExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004194 case CXCursor_GenericSelectionExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004195 return cxstring::createRef("GenericSelectionExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004196 case CXCursor_GNUNullExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004197 return cxstring::createRef("GNUNullExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004198 case CXCursor_CXXStaticCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004199 return cxstring::createRef("CXXStaticCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004200 case CXCursor_CXXDynamicCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004201 return cxstring::createRef("CXXDynamicCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004202 case CXCursor_CXXReinterpretCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004203 return cxstring::createRef("CXXReinterpretCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004204 case CXCursor_CXXConstCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004205 return cxstring::createRef("CXXConstCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004206 case CXCursor_CXXFunctionalCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004207 return cxstring::createRef("CXXFunctionalCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004208 case CXCursor_CXXTypeidExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004209 return cxstring::createRef("CXXTypeidExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004210 case CXCursor_CXXBoolLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004211 return cxstring::createRef("CXXBoolLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004212 case CXCursor_CXXNullPtrLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004213 return cxstring::createRef("CXXNullPtrLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004214 case CXCursor_CXXThisExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004215 return cxstring::createRef("CXXThisExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004216 case CXCursor_CXXThrowExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004217 return cxstring::createRef("CXXThrowExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004218 case CXCursor_CXXNewExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004219 return cxstring::createRef("CXXNewExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004220 case CXCursor_CXXDeleteExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004221 return cxstring::createRef("CXXDeleteExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004222 case CXCursor_UnaryExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004223 return cxstring::createRef("UnaryExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004224 case CXCursor_ObjCStringLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004225 return cxstring::createRef("ObjCStringLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00004226 case CXCursor_ObjCBoolLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004227 return cxstring::createRef("ObjCBoolLiteralExpr");
Argyrios Kyrtzidisc2233be2013-04-23 17:57:17 +00004228 case CXCursor_ObjCSelfExpr:
4229 return cxstring::createRef("ObjCSelfExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004230 case CXCursor_ObjCEncodeExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004231 return cxstring::createRef("ObjCEncodeExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004232 case CXCursor_ObjCSelectorExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004233 return cxstring::createRef("ObjCSelectorExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004234 case CXCursor_ObjCProtocolExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004235 return cxstring::createRef("ObjCProtocolExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004236 case CXCursor_ObjCBridgedCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004237 return cxstring::createRef("ObjCBridgedCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004238 case CXCursor_BlockExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004239 return cxstring::createRef("BlockExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004240 case CXCursor_PackExpansionExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004241 return cxstring::createRef("PackExpansionExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004242 case CXCursor_SizeOfPackExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004243 return cxstring::createRef("SizeOfPackExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004244 case CXCursor_LambdaExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004245 return cxstring::createRef("LambdaExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004246 case CXCursor_UnexposedExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004247 return cxstring::createRef("UnexposedExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004248 case CXCursor_DeclRefExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004249 return cxstring::createRef("DeclRefExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004250 case CXCursor_MemberRefExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004251 return cxstring::createRef("MemberRefExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004252 case CXCursor_CallExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004253 return cxstring::createRef("CallExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004254 case CXCursor_ObjCMessageExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004255 return cxstring::createRef("ObjCMessageExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004256 case CXCursor_UnexposedStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004257 return cxstring::createRef("UnexposedStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004258 case CXCursor_DeclStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004259 return cxstring::createRef("DeclStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004260 case CXCursor_LabelStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004261 return cxstring::createRef("LabelStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004262 case CXCursor_CompoundStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004263 return cxstring::createRef("CompoundStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004264 case CXCursor_CaseStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004265 return cxstring::createRef("CaseStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004266 case CXCursor_DefaultStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004267 return cxstring::createRef("DefaultStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004268 case CXCursor_IfStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004269 return cxstring::createRef("IfStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004270 case CXCursor_SwitchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004271 return cxstring::createRef("SwitchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004272 case CXCursor_WhileStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004273 return cxstring::createRef("WhileStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004274 case CXCursor_DoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004275 return cxstring::createRef("DoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004276 case CXCursor_ForStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004277 return cxstring::createRef("ForStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004278 case CXCursor_GotoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004279 return cxstring::createRef("GotoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004280 case CXCursor_IndirectGotoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004281 return cxstring::createRef("IndirectGotoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004282 case CXCursor_ContinueStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004283 return cxstring::createRef("ContinueStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004284 case CXCursor_BreakStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004285 return cxstring::createRef("BreakStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004286 case CXCursor_ReturnStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004287 return cxstring::createRef("ReturnStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004288 case CXCursor_GCCAsmStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004289 return cxstring::createRef("GCCAsmStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004290 case CXCursor_MSAsmStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004291 return cxstring::createRef("MSAsmStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004292 case CXCursor_ObjCAtTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004293 return cxstring::createRef("ObjCAtTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004294 case CXCursor_ObjCAtCatchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004295 return cxstring::createRef("ObjCAtCatchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004296 case CXCursor_ObjCAtFinallyStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004297 return cxstring::createRef("ObjCAtFinallyStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004298 case CXCursor_ObjCAtThrowStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004299 return cxstring::createRef("ObjCAtThrowStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004300 case CXCursor_ObjCAtSynchronizedStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004301 return cxstring::createRef("ObjCAtSynchronizedStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004302 case CXCursor_ObjCAutoreleasePoolStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004303 return cxstring::createRef("ObjCAutoreleasePoolStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004304 case CXCursor_ObjCForCollectionStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004305 return cxstring::createRef("ObjCForCollectionStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004306 case CXCursor_CXXCatchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004307 return cxstring::createRef("CXXCatchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004308 case CXCursor_CXXTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004309 return cxstring::createRef("CXXTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004310 case CXCursor_CXXForRangeStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004311 return cxstring::createRef("CXXForRangeStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004312 case CXCursor_SEHTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004313 return cxstring::createRef("SEHTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004314 case CXCursor_SEHExceptStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004315 return cxstring::createRef("SEHExceptStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004316 case CXCursor_SEHFinallyStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004317 return cxstring::createRef("SEHFinallyStmt");
Nico Weber9b982072014-07-07 00:12:30 +00004318 case CXCursor_SEHLeaveStmt:
4319 return cxstring::createRef("SEHLeaveStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004320 case CXCursor_NullStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004321 return cxstring::createRef("NullStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004322 case CXCursor_InvalidFile:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004323 return cxstring::createRef("InvalidFile");
Guy Benyei11169dd2012-12-18 14:30:41 +00004324 case CXCursor_InvalidCode:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004325 return cxstring::createRef("InvalidCode");
Guy Benyei11169dd2012-12-18 14:30:41 +00004326 case CXCursor_NoDeclFound:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004327 return cxstring::createRef("NoDeclFound");
Guy Benyei11169dd2012-12-18 14:30:41 +00004328 case CXCursor_NotImplemented:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004329 return cxstring::createRef("NotImplemented");
Guy Benyei11169dd2012-12-18 14:30:41 +00004330 case CXCursor_TranslationUnit:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004331 return cxstring::createRef("TranslationUnit");
Guy Benyei11169dd2012-12-18 14:30:41 +00004332 case CXCursor_UnexposedAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004333 return cxstring::createRef("UnexposedAttr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004334 case CXCursor_IBActionAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004335 return cxstring::createRef("attribute(ibaction)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004336 case CXCursor_IBOutletAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004337 return cxstring::createRef("attribute(iboutlet)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004338 case CXCursor_IBOutletCollectionAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004339 return cxstring::createRef("attribute(iboutletcollection)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004340 case CXCursor_CXXFinalAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004341 return cxstring::createRef("attribute(final)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004342 case CXCursor_CXXOverrideAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004343 return cxstring::createRef("attribute(override)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004344 case CXCursor_AnnotateAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004345 return cxstring::createRef("attribute(annotate)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004346 case CXCursor_AsmLabelAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004347 return cxstring::createRef("asm label");
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00004348 case CXCursor_PackedAttr:
4349 return cxstring::createRef("attribute(packed)");
Joey Gouly81228382014-05-01 15:41:58 +00004350 case CXCursor_PureAttr:
4351 return cxstring::createRef("attribute(pure)");
4352 case CXCursor_ConstAttr:
4353 return cxstring::createRef("attribute(const)");
4354 case CXCursor_NoDuplicateAttr:
4355 return cxstring::createRef("attribute(noduplicate)");
Eli Bendersky2581e662014-05-28 19:29:58 +00004356 case CXCursor_CUDAConstantAttr:
4357 return cxstring::createRef("attribute(constant)");
4358 case CXCursor_CUDADeviceAttr:
4359 return cxstring::createRef("attribute(device)");
4360 case CXCursor_CUDAGlobalAttr:
4361 return cxstring::createRef("attribute(global)");
4362 case CXCursor_CUDAHostAttr:
4363 return cxstring::createRef("attribute(host)");
Eli Bendersky9b071472014-08-08 14:59:00 +00004364 case CXCursor_CUDASharedAttr:
4365 return cxstring::createRef("attribute(shared)");
Saleem Abdulrasool79c69712015-09-05 18:53:43 +00004366 case CXCursor_VisibilityAttr:
4367 return cxstring::createRef("attribute(visibility)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004368 case CXCursor_PreprocessingDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004369 return cxstring::createRef("preprocessing directive");
Guy Benyei11169dd2012-12-18 14:30:41 +00004370 case CXCursor_MacroDefinition:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004371 return cxstring::createRef("macro definition");
Guy Benyei11169dd2012-12-18 14:30:41 +00004372 case CXCursor_MacroExpansion:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004373 return cxstring::createRef("macro expansion");
Guy Benyei11169dd2012-12-18 14:30:41 +00004374 case CXCursor_InclusionDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004375 return cxstring::createRef("inclusion directive");
Guy Benyei11169dd2012-12-18 14:30:41 +00004376 case CXCursor_Namespace:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004377 return cxstring::createRef("Namespace");
Guy Benyei11169dd2012-12-18 14:30:41 +00004378 case CXCursor_LinkageSpec:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004379 return cxstring::createRef("LinkageSpec");
Guy Benyei11169dd2012-12-18 14:30:41 +00004380 case CXCursor_CXXBaseSpecifier:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004381 return cxstring::createRef("C++ base class specifier");
Guy Benyei11169dd2012-12-18 14:30:41 +00004382 case CXCursor_Constructor:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004383 return cxstring::createRef("CXXConstructor");
Guy Benyei11169dd2012-12-18 14:30:41 +00004384 case CXCursor_Destructor:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004385 return cxstring::createRef("CXXDestructor");
Guy Benyei11169dd2012-12-18 14:30:41 +00004386 case CXCursor_ConversionFunction:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004387 return cxstring::createRef("CXXConversion");
Guy Benyei11169dd2012-12-18 14:30:41 +00004388 case CXCursor_TemplateTypeParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004389 return cxstring::createRef("TemplateTypeParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00004390 case CXCursor_NonTypeTemplateParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004391 return cxstring::createRef("NonTypeTemplateParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00004392 case CXCursor_TemplateTemplateParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004393 return cxstring::createRef("TemplateTemplateParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00004394 case CXCursor_FunctionTemplate:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004395 return cxstring::createRef("FunctionTemplate");
Guy Benyei11169dd2012-12-18 14:30:41 +00004396 case CXCursor_ClassTemplate:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004397 return cxstring::createRef("ClassTemplate");
Guy Benyei11169dd2012-12-18 14:30:41 +00004398 case CXCursor_ClassTemplatePartialSpecialization:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004399 return cxstring::createRef("ClassTemplatePartialSpecialization");
Guy Benyei11169dd2012-12-18 14:30:41 +00004400 case CXCursor_NamespaceAlias:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004401 return cxstring::createRef("NamespaceAlias");
Guy Benyei11169dd2012-12-18 14:30:41 +00004402 case CXCursor_UsingDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004403 return cxstring::createRef("UsingDirective");
Guy Benyei11169dd2012-12-18 14:30:41 +00004404 case CXCursor_UsingDeclaration:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004405 return cxstring::createRef("UsingDeclaration");
Guy Benyei11169dd2012-12-18 14:30:41 +00004406 case CXCursor_TypeAliasDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004407 return cxstring::createRef("TypeAliasDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004408 case CXCursor_ObjCSynthesizeDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004409 return cxstring::createRef("ObjCSynthesizeDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004410 case CXCursor_ObjCDynamicDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004411 return cxstring::createRef("ObjCDynamicDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004412 case CXCursor_CXXAccessSpecifier:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004413 return cxstring::createRef("CXXAccessSpecifier");
Guy Benyei11169dd2012-12-18 14:30:41 +00004414 case CXCursor_ModuleImportDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004415 return cxstring::createRef("ModuleImport");
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00004416 case CXCursor_OMPParallelDirective:
Alexey Bataev1b59ab52014-02-27 08:29:12 +00004417 return cxstring::createRef("OMPParallelDirective");
4418 case CXCursor_OMPSimdDirective:
4419 return cxstring::createRef("OMPSimdDirective");
Alexey Bataevf29276e2014-06-18 04:14:57 +00004420 case CXCursor_OMPForDirective:
4421 return cxstring::createRef("OMPForDirective");
Alexander Musmanf82886e2014-09-18 05:12:34 +00004422 case CXCursor_OMPForSimdDirective:
4423 return cxstring::createRef("OMPForSimdDirective");
Alexey Bataevd3f8dd22014-06-25 11:44:49 +00004424 case CXCursor_OMPSectionsDirective:
4425 return cxstring::createRef("OMPSectionsDirective");
Alexey Bataev1e0498a2014-06-26 08:21:58 +00004426 case CXCursor_OMPSectionDirective:
4427 return cxstring::createRef("OMPSectionDirective");
Alexey Bataevd1e40fb2014-06-26 12:05:45 +00004428 case CXCursor_OMPSingleDirective:
4429 return cxstring::createRef("OMPSingleDirective");
Alexander Musman80c22892014-07-17 08:54:58 +00004430 case CXCursor_OMPMasterDirective:
4431 return cxstring::createRef("OMPMasterDirective");
Alexander Musmand9ed09f2014-07-21 09:42:05 +00004432 case CXCursor_OMPCriticalDirective:
4433 return cxstring::createRef("OMPCriticalDirective");
Alexey Bataev4acb8592014-07-07 13:01:15 +00004434 case CXCursor_OMPParallelForDirective:
4435 return cxstring::createRef("OMPParallelForDirective");
Alexander Musmane4e893b2014-09-23 09:33:00 +00004436 case CXCursor_OMPParallelForSimdDirective:
4437 return cxstring::createRef("OMPParallelForSimdDirective");
Alexey Bataev84d0b3e2014-07-08 08:12:03 +00004438 case CXCursor_OMPParallelSectionsDirective:
4439 return cxstring::createRef("OMPParallelSectionsDirective");
Alexey Bataev9c2e8ee2014-07-11 11:25:16 +00004440 case CXCursor_OMPTaskDirective:
4441 return cxstring::createRef("OMPTaskDirective");
Alexey Bataev68446b72014-07-18 07:47:19 +00004442 case CXCursor_OMPTaskyieldDirective:
4443 return cxstring::createRef("OMPTaskyieldDirective");
Alexey Bataev4d1dfea2014-07-18 09:11:51 +00004444 case CXCursor_OMPBarrierDirective:
4445 return cxstring::createRef("OMPBarrierDirective");
Alexey Bataev2df347a2014-07-18 10:17:07 +00004446 case CXCursor_OMPTaskwaitDirective:
4447 return cxstring::createRef("OMPTaskwaitDirective");
Alexey Bataevc30dd2d2015-06-18 12:14:09 +00004448 case CXCursor_OMPTaskgroupDirective:
4449 return cxstring::createRef("OMPTaskgroupDirective");
Alexey Bataev6125da92014-07-21 11:26:11 +00004450 case CXCursor_OMPFlushDirective:
4451 return cxstring::createRef("OMPFlushDirective");
Alexey Bataev9fb6e642014-07-22 06:45:04 +00004452 case CXCursor_OMPOrderedDirective:
4453 return cxstring::createRef("OMPOrderedDirective");
Alexey Bataev0162e452014-07-22 10:10:35 +00004454 case CXCursor_OMPAtomicDirective:
4455 return cxstring::createRef("OMPAtomicDirective");
Alexey Bataev0bd520b2014-09-19 08:19:49 +00004456 case CXCursor_OMPTargetDirective:
4457 return cxstring::createRef("OMPTargetDirective");
Michael Wong65f367f2015-07-21 13:44:28 +00004458 case CXCursor_OMPTargetDataDirective:
4459 return cxstring::createRef("OMPTargetDataDirective");
Alexey Bataev13314bf2014-10-09 04:18:56 +00004460 case CXCursor_OMPTeamsDirective:
4461 return cxstring::createRef("OMPTeamsDirective");
Alexey Bataev6d4ed052015-07-01 06:57:41 +00004462 case CXCursor_OMPCancellationPointDirective:
4463 return cxstring::createRef("OMPCancellationPointDirective");
Alexey Bataev80909872015-07-02 11:25:17 +00004464 case CXCursor_OMPCancelDirective:
4465 return cxstring::createRef("OMPCancelDirective");
Francisco Lopes da Silva975a9f62015-01-21 16:24:11 +00004466 case CXCursor_OverloadCandidate:
4467 return cxstring::createRef("OverloadCandidate");
Sergey Kalinichev8f3b1872015-11-15 13:48:32 +00004468 case CXCursor_TypeAliasTemplateDecl:
4469 return cxstring::createRef("TypeAliasTemplateDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004470 }
4471
4472 llvm_unreachable("Unhandled CXCursorKind");
4473}
4474
4475struct GetCursorData {
4476 SourceLocation TokenBeginLoc;
4477 bool PointsAtMacroArgExpansion;
4478 bool VisitedObjCPropertyImplDecl;
4479 SourceLocation VisitedDeclaratorDeclStartLoc;
4480 CXCursor &BestCursor;
4481
4482 GetCursorData(SourceManager &SM,
4483 SourceLocation tokenBegin, CXCursor &outputCursor)
4484 : TokenBeginLoc(tokenBegin), BestCursor(outputCursor) {
4485 PointsAtMacroArgExpansion = SM.isMacroArgExpansion(tokenBegin);
4486 VisitedObjCPropertyImplDecl = false;
4487 }
4488};
4489
4490static enum CXChildVisitResult GetCursorVisitor(CXCursor cursor,
4491 CXCursor parent,
4492 CXClientData client_data) {
4493 GetCursorData *Data = static_cast<GetCursorData *>(client_data);
4494 CXCursor *BestCursor = &Data->BestCursor;
4495
4496 // If we point inside a macro argument we should provide info of what the
4497 // token is so use the actual cursor, don't replace it with a macro expansion
4498 // cursor.
4499 if (cursor.kind == CXCursor_MacroExpansion && Data->PointsAtMacroArgExpansion)
4500 return CXChildVisit_Recurse;
4501
4502 if (clang_isDeclaration(cursor.kind)) {
4503 // Avoid having the implicit methods override the property decls.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004504 if (const ObjCMethodDecl *MD
Guy Benyei11169dd2012-12-18 14:30:41 +00004505 = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
4506 if (MD->isImplicit())
4507 return CXChildVisit_Break;
4508
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004509 } else if (const ObjCInterfaceDecl *ID
Guy Benyei11169dd2012-12-18 14:30:41 +00004510 = dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(cursor))) {
4511 // Check that when we have multiple @class references in the same line,
4512 // that later ones do not override the previous ones.
4513 // If we have:
4514 // @class Foo, Bar;
4515 // source ranges for both start at '@', so 'Bar' will end up overriding
4516 // 'Foo' even though the cursor location was at 'Foo'.
4517 if (BestCursor->kind == CXCursor_ObjCInterfaceDecl ||
4518 BestCursor->kind == CXCursor_ObjCClassRef)
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004519 if (const ObjCInterfaceDecl *PrevID
Guy Benyei11169dd2012-12-18 14:30:41 +00004520 = dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(*BestCursor))){
4521 if (PrevID != ID &&
4522 !PrevID->isThisDeclarationADefinition() &&
4523 !ID->isThisDeclarationADefinition())
4524 return CXChildVisit_Break;
4525 }
4526
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004527 } else if (const DeclaratorDecl *DD
Guy Benyei11169dd2012-12-18 14:30:41 +00004528 = dyn_cast_or_null<DeclaratorDecl>(getCursorDecl(cursor))) {
4529 SourceLocation StartLoc = DD->getSourceRange().getBegin();
4530 // Check that when we have multiple declarators in the same line,
4531 // that later ones do not override the previous ones.
4532 // If we have:
4533 // int Foo, Bar;
4534 // source ranges for both start at 'int', so 'Bar' will end up overriding
4535 // 'Foo' even though the cursor location was at 'Foo'.
4536 if (Data->VisitedDeclaratorDeclStartLoc == StartLoc)
4537 return CXChildVisit_Break;
4538 Data->VisitedDeclaratorDeclStartLoc = StartLoc;
4539
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004540 } else if (const ObjCPropertyImplDecl *PropImp
Guy Benyei11169dd2012-12-18 14:30:41 +00004541 = dyn_cast_or_null<ObjCPropertyImplDecl>(getCursorDecl(cursor))) {
4542 (void)PropImp;
4543 // Check that when we have multiple @synthesize in the same line,
4544 // that later ones do not override the previous ones.
4545 // If we have:
4546 // @synthesize Foo, Bar;
4547 // source ranges for both start at '@', so 'Bar' will end up overriding
4548 // 'Foo' even though the cursor location was at 'Foo'.
4549 if (Data->VisitedObjCPropertyImplDecl)
4550 return CXChildVisit_Break;
4551 Data->VisitedObjCPropertyImplDecl = true;
4552 }
4553 }
4554
4555 if (clang_isExpression(cursor.kind) &&
4556 clang_isDeclaration(BestCursor->kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004557 if (const Decl *D = getCursorDecl(*BestCursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004558 // Avoid having the cursor of an expression replace the declaration cursor
4559 // when the expression source range overlaps the declaration range.
4560 // This can happen for C++ constructor expressions whose range generally
4561 // include the variable declaration, e.g.:
4562 // MyCXXClass foo; // Make sure pointing at 'foo' returns a VarDecl cursor.
4563 if (D->getLocation().isValid() && Data->TokenBeginLoc.isValid() &&
4564 D->getLocation() == Data->TokenBeginLoc)
4565 return CXChildVisit_Break;
4566 }
4567 }
4568
4569 // If our current best cursor is the construction of a temporary object,
4570 // don't replace that cursor with a type reference, because we want
4571 // clang_getCursor() to point at the constructor.
4572 if (clang_isExpression(BestCursor->kind) &&
4573 isa<CXXTemporaryObjectExpr>(getCursorExpr(*BestCursor)) &&
4574 cursor.kind == CXCursor_TypeRef) {
4575 // Keep the cursor pointing at CXXTemporaryObjectExpr but also mark it
4576 // as having the actual point on the type reference.
4577 *BestCursor = getTypeRefedCallExprCursor(*BestCursor);
4578 return CXChildVisit_Recurse;
4579 }
Douglas Gregore9d95f12015-07-07 03:57:35 +00004580
4581 // If we already have an Objective-C superclass reference, don't
4582 // update it further.
4583 if (BestCursor->kind == CXCursor_ObjCSuperClassRef)
4584 return CXChildVisit_Break;
4585
Guy Benyei11169dd2012-12-18 14:30:41 +00004586 *BestCursor = cursor;
4587 return CXChildVisit_Recurse;
4588}
4589
4590CXCursor clang_getCursor(CXTranslationUnit TU, CXSourceLocation Loc) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00004591 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004592 LOG_BAD_TU(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004593 return clang_getNullCursor();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004594 }
Guy Benyei11169dd2012-12-18 14:30:41 +00004595
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004596 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004597 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
4598
4599 SourceLocation SLoc = cxloc::translateSourceLocation(Loc);
4600 CXCursor Result = cxcursor::getCursor(TU, SLoc);
4601
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004602 LOG_FUNC_SECTION {
Guy Benyei11169dd2012-12-18 14:30:41 +00004603 CXFile SearchFile;
4604 unsigned SearchLine, SearchColumn;
4605 CXFile ResultFile;
4606 unsigned ResultLine, ResultColumn;
4607 CXString SearchFileName, ResultFileName, KindSpelling, USR;
4608 const char *IsDef = clang_isCursorDefinition(Result)? " (Definition)" : "";
4609 CXSourceLocation ResultLoc = clang_getCursorLocation(Result);
Craig Topper69186e72014-06-08 08:38:04 +00004610
4611 clang_getFileLocation(Loc, &SearchFile, &SearchLine, &SearchColumn,
4612 nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004613 clang_getFileLocation(ResultLoc, &ResultFile, &ResultLine,
Craig Topper69186e72014-06-08 08:38:04 +00004614 &ResultColumn, nullptr);
Guy Benyei11169dd2012-12-18 14:30:41 +00004615 SearchFileName = clang_getFileName(SearchFile);
4616 ResultFileName = clang_getFileName(ResultFile);
4617 KindSpelling = clang_getCursorKindSpelling(Result.kind);
4618 USR = clang_getCursorUSR(Result);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004619 *Log << llvm::format("(%s:%d:%d) = %s",
4620 clang_getCString(SearchFileName), SearchLine, SearchColumn,
4621 clang_getCString(KindSpelling))
4622 << llvm::format("(%s:%d:%d):%s%s",
4623 clang_getCString(ResultFileName), ResultLine, ResultColumn,
4624 clang_getCString(USR), IsDef);
Guy Benyei11169dd2012-12-18 14:30:41 +00004625 clang_disposeString(SearchFileName);
4626 clang_disposeString(ResultFileName);
4627 clang_disposeString(KindSpelling);
4628 clang_disposeString(USR);
4629
4630 CXCursor Definition = clang_getCursorDefinition(Result);
4631 if (!clang_equalCursors(Definition, clang_getNullCursor())) {
4632 CXSourceLocation DefinitionLoc = clang_getCursorLocation(Definition);
4633 CXString DefinitionKindSpelling
4634 = clang_getCursorKindSpelling(Definition.kind);
4635 CXFile DefinitionFile;
4636 unsigned DefinitionLine, DefinitionColumn;
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004637 clang_getFileLocation(DefinitionLoc, &DefinitionFile,
Craig Topper69186e72014-06-08 08:38:04 +00004638 &DefinitionLine, &DefinitionColumn, nullptr);
Guy Benyei11169dd2012-12-18 14:30:41 +00004639 CXString DefinitionFileName = clang_getFileName(DefinitionFile);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004640 *Log << llvm::format(" -> %s(%s:%d:%d)",
4641 clang_getCString(DefinitionKindSpelling),
4642 clang_getCString(DefinitionFileName),
4643 DefinitionLine, DefinitionColumn);
Guy Benyei11169dd2012-12-18 14:30:41 +00004644 clang_disposeString(DefinitionFileName);
4645 clang_disposeString(DefinitionKindSpelling);
4646 }
4647 }
4648
4649 return Result;
4650}
4651
4652CXCursor clang_getNullCursor(void) {
4653 return MakeCXCursorInvalid(CXCursor_InvalidFile);
4654}
4655
4656unsigned clang_equalCursors(CXCursor X, CXCursor Y) {
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00004657 // Clear out the "FirstInDeclGroup" part in a declaration cursor, since we
4658 // can't set consistently. For example, when visiting a DeclStmt we will set
4659 // it but we don't set it on the result of clang_getCursorDefinition for
4660 // a reference of the same declaration.
4661 // FIXME: Setting "FirstInDeclGroup" in CXCursors is a hack that only works
4662 // when visiting a DeclStmt currently, the AST should be enhanced to be able
4663 // to provide that kind of info.
4664 if (clang_isDeclaration(X.kind))
Craig Topper69186e72014-06-08 08:38:04 +00004665 X.data[1] = nullptr;
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00004666 if (clang_isDeclaration(Y.kind))
Craig Topper69186e72014-06-08 08:38:04 +00004667 Y.data[1] = nullptr;
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00004668
Guy Benyei11169dd2012-12-18 14:30:41 +00004669 return X == Y;
4670}
4671
4672unsigned clang_hashCursor(CXCursor C) {
4673 unsigned Index = 0;
4674 if (clang_isExpression(C.kind) || clang_isStatement(C.kind))
4675 Index = 1;
4676
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004677 return llvm::DenseMapInfo<std::pair<unsigned, const void*> >::getHashValue(
Guy Benyei11169dd2012-12-18 14:30:41 +00004678 std::make_pair(C.kind, C.data[Index]));
4679}
4680
4681unsigned clang_isInvalid(enum CXCursorKind K) {
4682 return K >= CXCursor_FirstInvalid && K <= CXCursor_LastInvalid;
4683}
4684
4685unsigned clang_isDeclaration(enum CXCursorKind K) {
4686 return (K >= CXCursor_FirstDecl && K <= CXCursor_LastDecl) ||
4687 (K >= CXCursor_FirstExtraDecl && K <= CXCursor_LastExtraDecl);
4688}
4689
4690unsigned clang_isReference(enum CXCursorKind K) {
4691 return K >= CXCursor_FirstRef && K <= CXCursor_LastRef;
4692}
4693
4694unsigned clang_isExpression(enum CXCursorKind K) {
4695 return K >= CXCursor_FirstExpr && K <= CXCursor_LastExpr;
4696}
4697
4698unsigned clang_isStatement(enum CXCursorKind K) {
4699 return K >= CXCursor_FirstStmt && K <= CXCursor_LastStmt;
4700}
4701
4702unsigned clang_isAttribute(enum CXCursorKind K) {
4703 return K >= CXCursor_FirstAttr && K <= CXCursor_LastAttr;
4704}
4705
4706unsigned clang_isTranslationUnit(enum CXCursorKind K) {
4707 return K == CXCursor_TranslationUnit;
4708}
4709
4710unsigned clang_isPreprocessing(enum CXCursorKind K) {
4711 return K >= CXCursor_FirstPreprocessing && K <= CXCursor_LastPreprocessing;
4712}
4713
4714unsigned clang_isUnexposed(enum CXCursorKind K) {
4715 switch (K) {
4716 case CXCursor_UnexposedDecl:
4717 case CXCursor_UnexposedExpr:
4718 case CXCursor_UnexposedStmt:
4719 case CXCursor_UnexposedAttr:
4720 return true;
4721 default:
4722 return false;
4723 }
4724}
4725
4726CXCursorKind clang_getCursorKind(CXCursor C) {
4727 return C.kind;
4728}
4729
4730CXSourceLocation clang_getCursorLocation(CXCursor C) {
4731 if (clang_isReference(C.kind)) {
4732 switch (C.kind) {
4733 case CXCursor_ObjCSuperClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004734 std::pair<const ObjCInterfaceDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004735 = getCursorObjCSuperClassRef(C);
4736 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4737 }
4738
4739 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004740 std::pair<const ObjCProtocolDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004741 = getCursorObjCProtocolRef(C);
4742 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4743 }
4744
4745 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004746 std::pair<const ObjCInterfaceDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004747 = getCursorObjCClassRef(C);
4748 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4749 }
4750
4751 case CXCursor_TypeRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004752 std::pair<const TypeDecl *, SourceLocation> P = getCursorTypeRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004753 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4754 }
4755
4756 case CXCursor_TemplateRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004757 std::pair<const TemplateDecl *, SourceLocation> P =
4758 getCursorTemplateRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004759 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4760 }
4761
4762 case CXCursor_NamespaceRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004763 std::pair<const NamedDecl *, SourceLocation> P = getCursorNamespaceRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004764 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4765 }
4766
4767 case CXCursor_MemberRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004768 std::pair<const FieldDecl *, SourceLocation> P = getCursorMemberRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004769 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4770 }
4771
4772 case CXCursor_VariableRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004773 std::pair<const VarDecl *, SourceLocation> P = getCursorVariableRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004774 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4775 }
4776
4777 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004778 const CXXBaseSpecifier *BaseSpec = getCursorCXXBaseSpecifier(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004779 if (!BaseSpec)
4780 return clang_getNullLocation();
4781
4782 if (TypeSourceInfo *TSInfo = BaseSpec->getTypeSourceInfo())
4783 return cxloc::translateSourceLocation(getCursorContext(C),
4784 TSInfo->getTypeLoc().getBeginLoc());
4785
4786 return cxloc::translateSourceLocation(getCursorContext(C),
4787 BaseSpec->getLocStart());
4788 }
4789
4790 case CXCursor_LabelRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004791 std::pair<const LabelStmt *, SourceLocation> P = getCursorLabelRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004792 return cxloc::translateSourceLocation(getCursorContext(C), P.second);
4793 }
4794
4795 case CXCursor_OverloadedDeclRef:
4796 return cxloc::translateSourceLocation(getCursorContext(C),
4797 getCursorOverloadedDeclRef(C).second);
4798
4799 default:
4800 // FIXME: Need a way to enumerate all non-reference cases.
4801 llvm_unreachable("Missed a reference kind");
4802 }
4803 }
4804
4805 if (clang_isExpression(C.kind))
4806 return cxloc::translateSourceLocation(getCursorContext(C),
4807 getLocationFromExpr(getCursorExpr(C)));
4808
4809 if (clang_isStatement(C.kind))
4810 return cxloc::translateSourceLocation(getCursorContext(C),
4811 getCursorStmt(C)->getLocStart());
4812
4813 if (C.kind == CXCursor_PreprocessingDirective) {
4814 SourceLocation L = cxcursor::getCursorPreprocessingDirective(C).getBegin();
4815 return cxloc::translateSourceLocation(getCursorContext(C), L);
4816 }
4817
4818 if (C.kind == CXCursor_MacroExpansion) {
4819 SourceLocation L
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00004820 = cxcursor::getCursorMacroExpansion(C).getSourceRange().getBegin();
Guy Benyei11169dd2012-12-18 14:30:41 +00004821 return cxloc::translateSourceLocation(getCursorContext(C), L);
4822 }
4823
4824 if (C.kind == CXCursor_MacroDefinition) {
4825 SourceLocation L = cxcursor::getCursorMacroDefinition(C)->getLocation();
4826 return cxloc::translateSourceLocation(getCursorContext(C), L);
4827 }
4828
4829 if (C.kind == CXCursor_InclusionDirective) {
4830 SourceLocation L
4831 = cxcursor::getCursorInclusionDirective(C)->getSourceRange().getBegin();
4832 return cxloc::translateSourceLocation(getCursorContext(C), L);
4833 }
4834
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00004835 if (clang_isAttribute(C.kind)) {
4836 SourceLocation L
4837 = cxcursor::getCursorAttr(C)->getLocation();
4838 return cxloc::translateSourceLocation(getCursorContext(C), L);
4839 }
4840
Guy Benyei11169dd2012-12-18 14:30:41 +00004841 if (!clang_isDeclaration(C.kind))
4842 return clang_getNullLocation();
4843
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004844 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004845 if (!D)
4846 return clang_getNullLocation();
4847
4848 SourceLocation Loc = D->getLocation();
4849 // FIXME: Multiple variables declared in a single declaration
4850 // currently lack the information needed to correctly determine their
4851 // ranges when accounting for the type-specifier. We use context
4852 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4853 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004854 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004855 if (!cxcursor::isFirstInDeclGroup(C))
4856 Loc = VD->getLocation();
4857 }
4858
4859 // For ObjC methods, give the start location of the method name.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004860 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004861 Loc = MD->getSelectorStartLoc();
4862
4863 return cxloc::translateSourceLocation(getCursorContext(C), Loc);
4864}
4865
4866} // end extern "C"
4867
4868CXCursor cxcursor::getCursor(CXTranslationUnit TU, SourceLocation SLoc) {
4869 assert(TU);
4870
4871 // Guard against an invalid SourceLocation, or we may assert in one
4872 // of the following calls.
4873 if (SLoc.isInvalid())
4874 return clang_getNullCursor();
4875
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004876 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004877
4878 // Translate the given source location to make it point at the beginning of
4879 // the token under the cursor.
4880 SLoc = Lexer::GetBeginningOfToken(SLoc, CXXUnit->getSourceManager(),
4881 CXXUnit->getASTContext().getLangOpts());
4882
4883 CXCursor Result = MakeCXCursorInvalid(CXCursor_NoDeclFound);
4884 if (SLoc.isValid()) {
4885 GetCursorData ResultData(CXXUnit->getSourceManager(), SLoc, Result);
4886 CursorVisitor CursorVis(TU, GetCursorVisitor, &ResultData,
4887 /*VisitPreprocessorLast=*/true,
4888 /*VisitIncludedEntities=*/false,
4889 SourceLocation(SLoc));
4890 CursorVis.visitFileRegion();
4891 }
4892
4893 return Result;
4894}
4895
4896static SourceRange getRawCursorExtent(CXCursor C) {
4897 if (clang_isReference(C.kind)) {
4898 switch (C.kind) {
4899 case CXCursor_ObjCSuperClassRef:
4900 return getCursorObjCSuperClassRef(C).second;
4901
4902 case CXCursor_ObjCProtocolRef:
4903 return getCursorObjCProtocolRef(C).second;
4904
4905 case CXCursor_ObjCClassRef:
4906 return getCursorObjCClassRef(C).second;
4907
4908 case CXCursor_TypeRef:
4909 return getCursorTypeRef(C).second;
4910
4911 case CXCursor_TemplateRef:
4912 return getCursorTemplateRef(C).second;
4913
4914 case CXCursor_NamespaceRef:
4915 return getCursorNamespaceRef(C).second;
4916
4917 case CXCursor_MemberRef:
4918 return getCursorMemberRef(C).second;
4919
4920 case CXCursor_CXXBaseSpecifier:
4921 return getCursorCXXBaseSpecifier(C)->getSourceRange();
4922
4923 case CXCursor_LabelRef:
4924 return getCursorLabelRef(C).second;
4925
4926 case CXCursor_OverloadedDeclRef:
4927 return getCursorOverloadedDeclRef(C).second;
4928
4929 case CXCursor_VariableRef:
4930 return getCursorVariableRef(C).second;
4931
4932 default:
4933 // FIXME: Need a way to enumerate all non-reference cases.
4934 llvm_unreachable("Missed a reference kind");
4935 }
4936 }
4937
4938 if (clang_isExpression(C.kind))
4939 return getCursorExpr(C)->getSourceRange();
4940
4941 if (clang_isStatement(C.kind))
4942 return getCursorStmt(C)->getSourceRange();
4943
4944 if (clang_isAttribute(C.kind))
4945 return getCursorAttr(C)->getRange();
4946
4947 if (C.kind == CXCursor_PreprocessingDirective)
4948 return cxcursor::getCursorPreprocessingDirective(C);
4949
4950 if (C.kind == CXCursor_MacroExpansion) {
4951 ASTUnit *TU = getCursorASTUnit(C);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00004952 SourceRange Range = cxcursor::getCursorMacroExpansion(C).getSourceRange();
Guy Benyei11169dd2012-12-18 14:30:41 +00004953 return TU->mapRangeFromPreamble(Range);
4954 }
4955
4956 if (C.kind == CXCursor_MacroDefinition) {
4957 ASTUnit *TU = getCursorASTUnit(C);
4958 SourceRange Range = cxcursor::getCursorMacroDefinition(C)->getSourceRange();
4959 return TU->mapRangeFromPreamble(Range);
4960 }
4961
4962 if (C.kind == CXCursor_InclusionDirective) {
4963 ASTUnit *TU = getCursorASTUnit(C);
4964 SourceRange Range = cxcursor::getCursorInclusionDirective(C)->getSourceRange();
4965 return TU->mapRangeFromPreamble(Range);
4966 }
4967
4968 if (C.kind == CXCursor_TranslationUnit) {
4969 ASTUnit *TU = getCursorASTUnit(C);
4970 FileID MainID = TU->getSourceManager().getMainFileID();
4971 SourceLocation Start = TU->getSourceManager().getLocForStartOfFile(MainID);
4972 SourceLocation End = TU->getSourceManager().getLocForEndOfFile(MainID);
4973 return SourceRange(Start, End);
4974 }
4975
4976 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004977 const Decl *D = cxcursor::getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004978 if (!D)
4979 return SourceRange();
4980
4981 SourceRange R = D->getSourceRange();
4982 // FIXME: Multiple variables declared in a single declaration
4983 // currently lack the information needed to correctly determine their
4984 // ranges when accounting for the type-specifier. We use context
4985 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4986 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004987 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004988 if (!cxcursor::isFirstInDeclGroup(C))
4989 R.setBegin(VD->getLocation());
4990 }
4991 return R;
4992 }
4993 return SourceRange();
4994}
4995
4996/// \brief Retrieves the "raw" cursor extent, which is then extended to include
4997/// the decl-specifier-seq for declarations.
4998static SourceRange getFullCursorExtent(CXCursor C, SourceManager &SrcMgr) {
4999 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005000 const Decl *D = cxcursor::getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005001 if (!D)
5002 return SourceRange();
5003
5004 SourceRange R = D->getSourceRange();
5005
5006 // Adjust the start of the location for declarations preceded by
5007 // declaration specifiers.
5008 SourceLocation StartLoc;
5009 if (const DeclaratorDecl *DD = dyn_cast<DeclaratorDecl>(D)) {
5010 if (TypeSourceInfo *TI = DD->getTypeSourceInfo())
5011 StartLoc = TI->getTypeLoc().getLocStart();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005012 } else if (const TypedefDecl *Typedef = dyn_cast<TypedefDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005013 if (TypeSourceInfo *TI = Typedef->getTypeSourceInfo())
5014 StartLoc = TI->getTypeLoc().getLocStart();
5015 }
5016
5017 if (StartLoc.isValid() && R.getBegin().isValid() &&
5018 SrcMgr.isBeforeInTranslationUnit(StartLoc, R.getBegin()))
5019 R.setBegin(StartLoc);
5020
5021 // FIXME: Multiple variables declared in a single declaration
5022 // currently lack the information needed to correctly determine their
5023 // ranges when accounting for the type-specifier. We use context
5024 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
5025 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005026 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005027 if (!cxcursor::isFirstInDeclGroup(C))
5028 R.setBegin(VD->getLocation());
5029 }
5030
5031 return R;
5032 }
5033
5034 return getRawCursorExtent(C);
5035}
5036
5037extern "C" {
5038
5039CXSourceRange clang_getCursorExtent(CXCursor C) {
5040 SourceRange R = getRawCursorExtent(C);
5041 if (R.isInvalid())
5042 return clang_getNullRange();
5043
5044 return cxloc::translateSourceRange(getCursorContext(C), R);
5045}
5046
5047CXCursor clang_getCursorReferenced(CXCursor C) {
5048 if (clang_isInvalid(C.kind))
5049 return clang_getNullCursor();
5050
5051 CXTranslationUnit tu = getCursorTU(C);
5052 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005053 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005054 if (!D)
5055 return clang_getNullCursor();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005056 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00005057 return MakeCursorOverloadedDeclRef(Using, D->getLocation(), tu);
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005058 if (const ObjCPropertyImplDecl *PropImpl =
5059 dyn_cast<ObjCPropertyImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00005060 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
5061 return MakeCXCursor(Property, tu);
5062
5063 return C;
5064 }
5065
5066 if (clang_isExpression(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005067 const Expr *E = getCursorExpr(C);
5068 const Decl *D = getDeclFromExpr(E);
Guy Benyei11169dd2012-12-18 14:30:41 +00005069 if (D) {
5070 CXCursor declCursor = MakeCXCursor(D, tu);
5071 declCursor = getSelectorIdentifierCursor(getSelectorIdentifierIndex(C),
5072 declCursor);
5073 return declCursor;
5074 }
5075
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005076 if (const OverloadExpr *Ovl = dyn_cast_or_null<OverloadExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00005077 return MakeCursorOverloadedDeclRef(Ovl, tu);
5078
5079 return clang_getNullCursor();
5080 }
5081
5082 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005083 const Stmt *S = getCursorStmt(C);
5084 if (const GotoStmt *Goto = dyn_cast_or_null<GotoStmt>(S))
Guy Benyei11169dd2012-12-18 14:30:41 +00005085 if (LabelDecl *label = Goto->getLabel())
5086 if (LabelStmt *labelS = label->getStmt())
5087 return MakeCXCursor(labelS, getCursorDecl(C), tu);
5088
5089 return clang_getNullCursor();
5090 }
Richard Smith66a81862015-05-04 02:25:31 +00005091
Guy Benyei11169dd2012-12-18 14:30:41 +00005092 if (C.kind == CXCursor_MacroExpansion) {
Richard Smith66a81862015-05-04 02:25:31 +00005093 if (const MacroDefinitionRecord *Def =
5094 getCursorMacroExpansion(C).getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005095 return MakeMacroDefinitionCursor(Def, tu);
5096 }
5097
5098 if (!clang_isReference(C.kind))
5099 return clang_getNullCursor();
5100
5101 switch (C.kind) {
5102 case CXCursor_ObjCSuperClassRef:
5103 return MakeCXCursor(getCursorObjCSuperClassRef(C).first, tu);
5104
5105 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005106 const ObjCProtocolDecl *Prot = getCursorObjCProtocolRef(C).first;
5107 if (const ObjCProtocolDecl *Def = Prot->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005108 return MakeCXCursor(Def, tu);
5109
5110 return MakeCXCursor(Prot, tu);
5111 }
5112
5113 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005114 const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
5115 if (const ObjCInterfaceDecl *Def = Class->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005116 return MakeCXCursor(Def, tu);
5117
5118 return MakeCXCursor(Class, tu);
5119 }
5120
5121 case CXCursor_TypeRef:
5122 return MakeCXCursor(getCursorTypeRef(C).first, tu );
5123
5124 case CXCursor_TemplateRef:
5125 return MakeCXCursor(getCursorTemplateRef(C).first, tu );
5126
5127 case CXCursor_NamespaceRef:
5128 return MakeCXCursor(getCursorNamespaceRef(C).first, tu );
5129
5130 case CXCursor_MemberRef:
5131 return MakeCXCursor(getCursorMemberRef(C).first, tu );
5132
5133 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005134 const CXXBaseSpecifier *B = cxcursor::getCursorCXXBaseSpecifier(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005135 return clang_getTypeDeclaration(cxtype::MakeCXType(B->getType(),
5136 tu ));
5137 }
5138
5139 case CXCursor_LabelRef:
5140 // FIXME: We end up faking the "parent" declaration here because we
5141 // don't want to make CXCursor larger.
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005142 return MakeCXCursor(getCursorLabelRef(C).first,
5143 cxtu::getASTUnit(tu)->getASTContext()
5144 .getTranslationUnitDecl(),
Guy Benyei11169dd2012-12-18 14:30:41 +00005145 tu);
5146
5147 case CXCursor_OverloadedDeclRef:
5148 return C;
5149
5150 case CXCursor_VariableRef:
5151 return MakeCXCursor(getCursorVariableRef(C).first, tu);
5152
5153 default:
5154 // We would prefer to enumerate all non-reference cursor kinds here.
5155 llvm_unreachable("Unhandled reference cursor kind");
5156 }
5157}
5158
5159CXCursor clang_getCursorDefinition(CXCursor C) {
5160 if (clang_isInvalid(C.kind))
5161 return clang_getNullCursor();
5162
5163 CXTranslationUnit TU = getCursorTU(C);
5164
5165 bool WasReference = false;
5166 if (clang_isReference(C.kind) || clang_isExpression(C.kind)) {
5167 C = clang_getCursorReferenced(C);
5168 WasReference = true;
5169 }
5170
5171 if (C.kind == CXCursor_MacroExpansion)
5172 return clang_getCursorReferenced(C);
5173
5174 if (!clang_isDeclaration(C.kind))
5175 return clang_getNullCursor();
5176
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005177 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005178 if (!D)
5179 return clang_getNullCursor();
5180
5181 switch (D->getKind()) {
5182 // Declaration kinds that don't really separate the notions of
5183 // declaration and definition.
5184 case Decl::Namespace:
5185 case Decl::Typedef:
5186 case Decl::TypeAlias:
5187 case Decl::TypeAliasTemplate:
5188 case Decl::TemplateTypeParm:
5189 case Decl::EnumConstant:
5190 case Decl::Field:
John McCall5e77d762013-04-16 07:28:30 +00005191 case Decl::MSProperty:
Guy Benyei11169dd2012-12-18 14:30:41 +00005192 case Decl::IndirectField:
5193 case Decl::ObjCIvar:
5194 case Decl::ObjCAtDefsField:
5195 case Decl::ImplicitParam:
5196 case Decl::ParmVar:
5197 case Decl::NonTypeTemplateParm:
5198 case Decl::TemplateTemplateParm:
5199 case Decl::ObjCCategoryImpl:
5200 case Decl::ObjCImplementation:
5201 case Decl::AccessSpec:
5202 case Decl::LinkageSpec:
5203 case Decl::ObjCPropertyImpl:
5204 case Decl::FileScopeAsm:
5205 case Decl::StaticAssert:
5206 case Decl::Block:
Tareq A. Siraj6dfa25a2013-04-16 19:37:38 +00005207 case Decl::Captured:
Guy Benyei11169dd2012-12-18 14:30:41 +00005208 case Decl::Label: // FIXME: Is this right??
5209 case Decl::ClassScopeFunctionSpecialization:
5210 case Decl::Import:
Alexey Bataeva769e072013-03-22 06:34:35 +00005211 case Decl::OMPThreadPrivate:
Douglas Gregor85f3f952015-07-07 03:57:15 +00005212 case Decl::ObjCTypeParam:
David Majnemerd9b1a4f2015-11-04 03:40:30 +00005213 case Decl::BuiltinTemplate:
Guy Benyei11169dd2012-12-18 14:30:41 +00005214 return C;
5215
5216 // Declaration kinds that don't make any sense here, but are
5217 // nonetheless harmless.
David Blaikief005d3c2013-02-22 17:44:58 +00005218 case Decl::Empty:
Guy Benyei11169dd2012-12-18 14:30:41 +00005219 case Decl::TranslationUnit:
Richard Smithf19e1272015-03-07 00:04:49 +00005220 case Decl::ExternCContext:
Guy Benyei11169dd2012-12-18 14:30:41 +00005221 break;
5222
5223 // Declaration kinds for which the definition is not resolvable.
5224 case Decl::UnresolvedUsingTypename:
5225 case Decl::UnresolvedUsingValue:
5226 break;
5227
5228 case Decl::UsingDirective:
5229 return MakeCXCursor(cast<UsingDirectiveDecl>(D)->getNominatedNamespace(),
5230 TU);
5231
5232 case Decl::NamespaceAlias:
5233 return MakeCXCursor(cast<NamespaceAliasDecl>(D)->getNamespace(), TU);
5234
5235 case Decl::Enum:
5236 case Decl::Record:
5237 case Decl::CXXRecord:
5238 case Decl::ClassTemplateSpecialization:
5239 case Decl::ClassTemplatePartialSpecialization:
5240 if (TagDecl *Def = cast<TagDecl>(D)->getDefinition())
5241 return MakeCXCursor(Def, TU);
5242 return clang_getNullCursor();
5243
5244 case Decl::Function:
5245 case Decl::CXXMethod:
5246 case Decl::CXXConstructor:
5247 case Decl::CXXDestructor:
5248 case Decl::CXXConversion: {
Craig Topper69186e72014-06-08 08:38:04 +00005249 const FunctionDecl *Def = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005250 if (cast<FunctionDecl>(D)->getBody(Def))
Dmitri Gribenko9c256e32013-01-14 00:46:27 +00005251 return MakeCXCursor(Def, TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005252 return clang_getNullCursor();
5253 }
5254
Larisse Voufo39a1e502013-08-06 01:03:05 +00005255 case Decl::Var:
5256 case Decl::VarTemplateSpecialization:
5257 case Decl::VarTemplatePartialSpecialization: {
Guy Benyei11169dd2012-12-18 14:30:41 +00005258 // Ask the variable if it has a definition.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005259 if (const VarDecl *Def = cast<VarDecl>(D)->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005260 return MakeCXCursor(Def, TU);
5261 return clang_getNullCursor();
5262 }
5263
5264 case Decl::FunctionTemplate: {
Craig Topper69186e72014-06-08 08:38:04 +00005265 const FunctionDecl *Def = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005266 if (cast<FunctionTemplateDecl>(D)->getTemplatedDecl()->getBody(Def))
5267 return MakeCXCursor(Def->getDescribedFunctionTemplate(), TU);
5268 return clang_getNullCursor();
5269 }
5270
5271 case Decl::ClassTemplate: {
5272 if (RecordDecl *Def = cast<ClassTemplateDecl>(D)->getTemplatedDecl()
5273 ->getDefinition())
5274 return MakeCXCursor(cast<CXXRecordDecl>(Def)->getDescribedClassTemplate(),
5275 TU);
5276 return clang_getNullCursor();
5277 }
5278
Larisse Voufo39a1e502013-08-06 01:03:05 +00005279 case Decl::VarTemplate: {
5280 if (VarDecl *Def =
5281 cast<VarTemplateDecl>(D)->getTemplatedDecl()->getDefinition())
5282 return MakeCXCursor(cast<VarDecl>(Def)->getDescribedVarTemplate(), TU);
5283 return clang_getNullCursor();
5284 }
5285
Guy Benyei11169dd2012-12-18 14:30:41 +00005286 case Decl::Using:
5287 return MakeCursorOverloadedDeclRef(cast<UsingDecl>(D),
5288 D->getLocation(), TU);
5289
5290 case Decl::UsingShadow:
5291 return clang_getCursorDefinition(
5292 MakeCXCursor(cast<UsingShadowDecl>(D)->getTargetDecl(),
5293 TU));
5294
5295 case Decl::ObjCMethod: {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005296 const ObjCMethodDecl *Method = cast<ObjCMethodDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00005297 if (Method->isThisDeclarationADefinition())
5298 return C;
5299
5300 // Dig out the method definition in the associated
5301 // @implementation, if we have it.
5302 // FIXME: The ASTs should make finding the definition easier.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005303 if (const ObjCInterfaceDecl *Class
Guy Benyei11169dd2012-12-18 14:30:41 +00005304 = dyn_cast<ObjCInterfaceDecl>(Method->getDeclContext()))
5305 if (ObjCImplementationDecl *ClassImpl = Class->getImplementation())
5306 if (ObjCMethodDecl *Def = ClassImpl->getMethod(Method->getSelector(),
5307 Method->isInstanceMethod()))
5308 if (Def->isThisDeclarationADefinition())
5309 return MakeCXCursor(Def, TU);
5310
5311 return clang_getNullCursor();
5312 }
5313
5314 case Decl::ObjCCategory:
5315 if (ObjCCategoryImplDecl *Impl
5316 = cast<ObjCCategoryDecl>(D)->getImplementation())
5317 return MakeCXCursor(Impl, TU);
5318 return clang_getNullCursor();
5319
5320 case Decl::ObjCProtocol:
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005321 if (const ObjCProtocolDecl *Def = cast<ObjCProtocolDecl>(D)->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005322 return MakeCXCursor(Def, TU);
5323 return clang_getNullCursor();
5324
5325 case Decl::ObjCInterface: {
5326 // There are two notions of a "definition" for an Objective-C
5327 // class: the interface and its implementation. When we resolved a
5328 // reference to an Objective-C class, produce the @interface as
5329 // the definition; when we were provided with the interface,
5330 // produce the @implementation as the definition.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005331 const ObjCInterfaceDecl *IFace = cast<ObjCInterfaceDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00005332 if (WasReference) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005333 if (const ObjCInterfaceDecl *Def = IFace->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005334 return MakeCXCursor(Def, TU);
5335 } else if (ObjCImplementationDecl *Impl = IFace->getImplementation())
5336 return MakeCXCursor(Impl, TU);
5337 return clang_getNullCursor();
5338 }
5339
5340 case Decl::ObjCProperty:
5341 // FIXME: We don't really know where to find the
5342 // ObjCPropertyImplDecls that implement this property.
5343 return clang_getNullCursor();
5344
5345 case Decl::ObjCCompatibleAlias:
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005346 if (const ObjCInterfaceDecl *Class
Guy Benyei11169dd2012-12-18 14:30:41 +00005347 = cast<ObjCCompatibleAliasDecl>(D)->getClassInterface())
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005348 if (const ObjCInterfaceDecl *Def = Class->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005349 return MakeCXCursor(Def, TU);
5350
5351 return clang_getNullCursor();
5352
5353 case Decl::Friend:
5354 if (NamedDecl *Friend = cast<FriendDecl>(D)->getFriendDecl())
5355 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
5356 return clang_getNullCursor();
5357
5358 case Decl::FriendTemplate:
5359 if (NamedDecl *Friend = cast<FriendTemplateDecl>(D)->getFriendDecl())
5360 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
5361 return clang_getNullCursor();
5362 }
5363
5364 return clang_getNullCursor();
5365}
5366
5367unsigned clang_isCursorDefinition(CXCursor C) {
5368 if (!clang_isDeclaration(C.kind))
5369 return 0;
5370
5371 return clang_getCursorDefinition(C) == C;
5372}
5373
5374CXCursor clang_getCanonicalCursor(CXCursor C) {
5375 if (!clang_isDeclaration(C.kind))
5376 return C;
5377
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005378 if (const Decl *D = getCursorDecl(C)) {
5379 if (const ObjCCategoryImplDecl *CatImplD = dyn_cast<ObjCCategoryImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00005380 if (ObjCCategoryDecl *CatD = CatImplD->getCategoryDecl())
5381 return MakeCXCursor(CatD, getCursorTU(C));
5382
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005383 if (const ObjCImplDecl *ImplD = dyn_cast<ObjCImplDecl>(D))
5384 if (const ObjCInterfaceDecl *IFD = ImplD->getClassInterface())
Guy Benyei11169dd2012-12-18 14:30:41 +00005385 return MakeCXCursor(IFD, getCursorTU(C));
5386
5387 return MakeCXCursor(D->getCanonicalDecl(), getCursorTU(C));
5388 }
5389
5390 return C;
5391}
5392
5393int clang_Cursor_getObjCSelectorIndex(CXCursor cursor) {
5394 return cxcursor::getSelectorIdentifierIndexAndLoc(cursor).first;
5395}
5396
5397unsigned clang_getNumOverloadedDecls(CXCursor C) {
5398 if (C.kind != CXCursor_OverloadedDeclRef)
5399 return 0;
5400
5401 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005402 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Guy Benyei11169dd2012-12-18 14:30:41 +00005403 return E->getNumDecls();
5404
5405 if (OverloadedTemplateStorage *S
5406 = Storage.dyn_cast<OverloadedTemplateStorage*>())
5407 return S->size();
5408
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005409 const Decl *D = Storage.get<const Decl *>();
5410 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00005411 return Using->shadow_size();
5412
5413 return 0;
5414}
5415
5416CXCursor clang_getOverloadedDecl(CXCursor cursor, unsigned index) {
5417 if (cursor.kind != CXCursor_OverloadedDeclRef)
5418 return clang_getNullCursor();
5419
5420 if (index >= clang_getNumOverloadedDecls(cursor))
5421 return clang_getNullCursor();
5422
5423 CXTranslationUnit TU = getCursorTU(cursor);
5424 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(cursor).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005425 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Guy Benyei11169dd2012-12-18 14:30:41 +00005426 return MakeCXCursor(E->decls_begin()[index], TU);
5427
5428 if (OverloadedTemplateStorage *S
5429 = Storage.dyn_cast<OverloadedTemplateStorage*>())
5430 return MakeCXCursor(S->begin()[index], TU);
5431
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005432 const Decl *D = Storage.get<const Decl *>();
5433 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005434 // FIXME: This is, unfortunately, linear time.
5435 UsingDecl::shadow_iterator Pos = Using->shadow_begin();
5436 std::advance(Pos, index);
5437 return MakeCXCursor(cast<UsingShadowDecl>(*Pos)->getTargetDecl(), TU);
5438 }
5439
5440 return clang_getNullCursor();
5441}
5442
5443void clang_getDefinitionSpellingAndExtent(CXCursor C,
5444 const char **startBuf,
5445 const char **endBuf,
5446 unsigned *startLine,
5447 unsigned *startColumn,
5448 unsigned *endLine,
5449 unsigned *endColumn) {
5450 assert(getCursorDecl(C) && "CXCursor has null decl");
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005451 const FunctionDecl *FD = dyn_cast<FunctionDecl>(getCursorDecl(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00005452 CompoundStmt *Body = dyn_cast<CompoundStmt>(FD->getBody());
5453
5454 SourceManager &SM = FD->getASTContext().getSourceManager();
5455 *startBuf = SM.getCharacterData(Body->getLBracLoc());
5456 *endBuf = SM.getCharacterData(Body->getRBracLoc());
5457 *startLine = SM.getSpellingLineNumber(Body->getLBracLoc());
5458 *startColumn = SM.getSpellingColumnNumber(Body->getLBracLoc());
5459 *endLine = SM.getSpellingLineNumber(Body->getRBracLoc());
5460 *endColumn = SM.getSpellingColumnNumber(Body->getRBracLoc());
5461}
5462
5463
5464CXSourceRange clang_getCursorReferenceNameRange(CXCursor C, unsigned NameFlags,
5465 unsigned PieceIndex) {
5466 RefNamePieces Pieces;
5467
5468 switch (C.kind) {
5469 case CXCursor_MemberRefExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005470 if (const MemberExpr *E = dyn_cast<MemberExpr>(getCursorExpr(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00005471 Pieces = buildPieces(NameFlags, true, E->getMemberNameInfo(),
5472 E->getQualifierLoc().getSourceRange());
5473 break;
5474
5475 case CXCursor_DeclRefExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005476 if (const DeclRefExpr *E = dyn_cast<DeclRefExpr>(getCursorExpr(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00005477 Pieces = buildPieces(NameFlags, false, E->getNameInfo(),
5478 E->getQualifierLoc().getSourceRange(),
5479 E->getOptionalExplicitTemplateArgs());
5480 break;
5481
5482 case CXCursor_CallExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005483 if (const CXXOperatorCallExpr *OCE =
Guy Benyei11169dd2012-12-18 14:30:41 +00005484 dyn_cast<CXXOperatorCallExpr>(getCursorExpr(C))) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005485 const Expr *Callee = OCE->getCallee();
5486 if (const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Callee))
Guy Benyei11169dd2012-12-18 14:30:41 +00005487 Callee = ICE->getSubExpr();
5488
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005489 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(Callee))
Guy Benyei11169dd2012-12-18 14:30:41 +00005490 Pieces = buildPieces(NameFlags, false, DRE->getNameInfo(),
5491 DRE->getQualifierLoc().getSourceRange());
5492 }
5493 break;
5494
5495 default:
5496 break;
5497 }
5498
5499 if (Pieces.empty()) {
5500 if (PieceIndex == 0)
5501 return clang_getCursorExtent(C);
5502 } else if (PieceIndex < Pieces.size()) {
5503 SourceRange R = Pieces[PieceIndex];
5504 if (R.isValid())
5505 return cxloc::translateSourceRange(getCursorContext(C), R);
5506 }
5507
5508 return clang_getNullRange();
5509}
5510
5511void clang_enableStackTraces(void) {
5512 llvm::sys::PrintStackTraceOnErrorSignal();
5513}
5514
5515void clang_executeOnThread(void (*fn)(void*), void *user_data,
5516 unsigned stack_size) {
5517 llvm::llvm_execute_on_thread(fn, user_data, stack_size);
5518}
5519
5520} // end: extern "C"
5521
5522//===----------------------------------------------------------------------===//
5523// Token-based Operations.
5524//===----------------------------------------------------------------------===//
5525
5526/* CXToken layout:
5527 * int_data[0]: a CXTokenKind
5528 * int_data[1]: starting token location
5529 * int_data[2]: token length
5530 * int_data[3]: reserved
5531 * ptr_data: for identifiers and keywords, an IdentifierInfo*.
5532 * otherwise unused.
5533 */
5534extern "C" {
5535
5536CXTokenKind clang_getTokenKind(CXToken CXTok) {
5537 return static_cast<CXTokenKind>(CXTok.int_data[0]);
5538}
5539
5540CXString clang_getTokenSpelling(CXTranslationUnit TU, CXToken CXTok) {
5541 switch (clang_getTokenKind(CXTok)) {
5542 case CXToken_Identifier:
5543 case CXToken_Keyword:
5544 // We know we have an IdentifierInfo*, so use that.
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005545 return cxstring::createRef(static_cast<IdentifierInfo *>(CXTok.ptr_data)
Guy Benyei11169dd2012-12-18 14:30:41 +00005546 ->getNameStart());
5547
5548 case CXToken_Literal: {
5549 // We have stashed the starting pointer in the ptr_data field. Use it.
5550 const char *Text = static_cast<const char *>(CXTok.ptr_data);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00005551 return cxstring::createDup(StringRef(Text, CXTok.int_data[2]));
Guy Benyei11169dd2012-12-18 14:30:41 +00005552 }
5553
5554 case CXToken_Punctuation:
5555 case CXToken_Comment:
5556 break;
5557 }
5558
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005559 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005560 LOG_BAD_TU(TU);
5561 return cxstring::createEmpty();
5562 }
5563
Guy Benyei11169dd2012-12-18 14:30:41 +00005564 // We have to find the starting buffer pointer the hard way, by
5565 // deconstructing the source location.
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005566 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005567 if (!CXXUnit)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00005568 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00005569
5570 SourceLocation Loc = SourceLocation::getFromRawEncoding(CXTok.int_data[1]);
5571 std::pair<FileID, unsigned> LocInfo
5572 = CXXUnit->getSourceManager().getDecomposedSpellingLoc(Loc);
5573 bool Invalid = false;
5574 StringRef Buffer
5575 = CXXUnit->getSourceManager().getBufferData(LocInfo.first, &Invalid);
5576 if (Invalid)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00005577 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00005578
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00005579 return cxstring::createDup(Buffer.substr(LocInfo.second, CXTok.int_data[2]));
Guy Benyei11169dd2012-12-18 14:30:41 +00005580}
5581
5582CXSourceLocation clang_getTokenLocation(CXTranslationUnit TU, CXToken CXTok) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005583 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005584 LOG_BAD_TU(TU);
5585 return clang_getNullLocation();
5586 }
5587
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005588 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005589 if (!CXXUnit)
5590 return clang_getNullLocation();
5591
5592 return cxloc::translateSourceLocation(CXXUnit->getASTContext(),
5593 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
5594}
5595
5596CXSourceRange clang_getTokenExtent(CXTranslationUnit TU, CXToken CXTok) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005597 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005598 LOG_BAD_TU(TU);
5599 return clang_getNullRange();
5600 }
5601
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005602 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005603 if (!CXXUnit)
5604 return clang_getNullRange();
5605
5606 return cxloc::translateSourceRange(CXXUnit->getASTContext(),
5607 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
5608}
5609
5610static void getTokens(ASTUnit *CXXUnit, SourceRange Range,
5611 SmallVectorImpl<CXToken> &CXTokens) {
5612 SourceManager &SourceMgr = CXXUnit->getSourceManager();
5613 std::pair<FileID, unsigned> BeginLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005614 = SourceMgr.getDecomposedSpellingLoc(Range.getBegin());
Guy Benyei11169dd2012-12-18 14:30:41 +00005615 std::pair<FileID, unsigned> EndLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005616 = SourceMgr.getDecomposedSpellingLoc(Range.getEnd());
Guy Benyei11169dd2012-12-18 14:30:41 +00005617
5618 // Cannot tokenize across files.
5619 if (BeginLocInfo.first != EndLocInfo.first)
5620 return;
5621
5622 // Create a lexer
5623 bool Invalid = false;
5624 StringRef Buffer
5625 = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
5626 if (Invalid)
5627 return;
5628
5629 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
5630 CXXUnit->getASTContext().getLangOpts(),
5631 Buffer.begin(), Buffer.data() + BeginLocInfo.second, Buffer.end());
5632 Lex.SetCommentRetentionState(true);
5633
5634 // Lex tokens until we hit the end of the range.
5635 const char *EffectiveBufferEnd = Buffer.data() + EndLocInfo.second;
5636 Token Tok;
5637 bool previousWasAt = false;
5638 do {
5639 // Lex the next token
5640 Lex.LexFromRawLexer(Tok);
5641 if (Tok.is(tok::eof))
5642 break;
5643
5644 // Initialize the CXToken.
5645 CXToken CXTok;
5646
5647 // - Common fields
5648 CXTok.int_data[1] = Tok.getLocation().getRawEncoding();
5649 CXTok.int_data[2] = Tok.getLength();
5650 CXTok.int_data[3] = 0;
5651
5652 // - Kind-specific fields
5653 if (Tok.isLiteral()) {
5654 CXTok.int_data[0] = CXToken_Literal;
Dmitri Gribenkof9304482013-01-23 15:56:07 +00005655 CXTok.ptr_data = const_cast<char *>(Tok.getLiteralData());
Guy Benyei11169dd2012-12-18 14:30:41 +00005656 } else if (Tok.is(tok::raw_identifier)) {
5657 // Lookup the identifier to determine whether we have a keyword.
5658 IdentifierInfo *II
5659 = CXXUnit->getPreprocessor().LookUpIdentifierInfo(Tok);
5660
5661 if ((II->getObjCKeywordID() != tok::objc_not_keyword) && previousWasAt) {
5662 CXTok.int_data[0] = CXToken_Keyword;
5663 }
5664 else {
5665 CXTok.int_data[0] = Tok.is(tok::identifier)
5666 ? CXToken_Identifier
5667 : CXToken_Keyword;
5668 }
5669 CXTok.ptr_data = II;
5670 } else if (Tok.is(tok::comment)) {
5671 CXTok.int_data[0] = CXToken_Comment;
Craig Topper69186e72014-06-08 08:38:04 +00005672 CXTok.ptr_data = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005673 } else {
5674 CXTok.int_data[0] = CXToken_Punctuation;
Craig Topper69186e72014-06-08 08:38:04 +00005675 CXTok.ptr_data = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005676 }
5677 CXTokens.push_back(CXTok);
5678 previousWasAt = Tok.is(tok::at);
5679 } while (Lex.getBufferLocation() <= EffectiveBufferEnd);
5680}
5681
5682void clang_tokenize(CXTranslationUnit TU, CXSourceRange Range,
5683 CXToken **Tokens, unsigned *NumTokens) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00005684 LOG_FUNC_SECTION {
5685 *Log << TU << ' ' << Range;
5686 }
5687
Guy Benyei11169dd2012-12-18 14:30:41 +00005688 if (Tokens)
Craig Topper69186e72014-06-08 08:38:04 +00005689 *Tokens = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005690 if (NumTokens)
5691 *NumTokens = 0;
5692
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005693 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005694 LOG_BAD_TU(TU);
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00005695 return;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005696 }
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00005697
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005698 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005699 if (!CXXUnit || !Tokens || !NumTokens)
5700 return;
5701
5702 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
5703
5704 SourceRange R = cxloc::translateCXSourceRange(Range);
5705 if (R.isInvalid())
5706 return;
5707
5708 SmallVector<CXToken, 32> CXTokens;
5709 getTokens(CXXUnit, R, CXTokens);
5710
5711 if (CXTokens.empty())
5712 return;
5713
5714 *Tokens = (CXToken *)malloc(sizeof(CXToken) * CXTokens.size());
5715 memmove(*Tokens, CXTokens.data(), sizeof(CXToken) * CXTokens.size());
5716 *NumTokens = CXTokens.size();
5717}
5718
5719void clang_disposeTokens(CXTranslationUnit TU,
5720 CXToken *Tokens, unsigned NumTokens) {
5721 free(Tokens);
5722}
5723
5724} // end: extern "C"
5725
5726//===----------------------------------------------------------------------===//
5727// Token annotation APIs.
5728//===----------------------------------------------------------------------===//
5729
Guy Benyei11169dd2012-12-18 14:30:41 +00005730static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
5731 CXCursor parent,
5732 CXClientData client_data);
5733static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
5734 CXClientData client_data);
5735
5736namespace {
5737class AnnotateTokensWorker {
Guy Benyei11169dd2012-12-18 14:30:41 +00005738 CXToken *Tokens;
5739 CXCursor *Cursors;
5740 unsigned NumTokens;
5741 unsigned TokIdx;
5742 unsigned PreprocessingTokIdx;
5743 CursorVisitor AnnotateVis;
5744 SourceManager &SrcMgr;
5745 bool HasContextSensitiveKeywords;
5746
5747 struct PostChildrenInfo {
5748 CXCursor Cursor;
5749 SourceRange CursorRange;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005750 unsigned BeforeReachingCursorIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00005751 unsigned BeforeChildrenTokenIdx;
5752 };
Dmitri Gribenkof8579502013-01-12 19:30:44 +00005753 SmallVector<PostChildrenInfo, 8> PostChildrenInfos;
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005754
5755 CXToken &getTok(unsigned Idx) {
5756 assert(Idx < NumTokens);
5757 return Tokens[Idx];
5758 }
5759 const CXToken &getTok(unsigned Idx) const {
5760 assert(Idx < NumTokens);
5761 return Tokens[Idx];
5762 }
Guy Benyei11169dd2012-12-18 14:30:41 +00005763 bool MoreTokens() const { return TokIdx < NumTokens; }
5764 unsigned NextToken() const { return TokIdx; }
5765 void AdvanceToken() { ++TokIdx; }
5766 SourceLocation GetTokenLoc(unsigned tokI) {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005767 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[1]);
Guy Benyei11169dd2012-12-18 14:30:41 +00005768 }
5769 bool isFunctionMacroToken(unsigned tokI) const {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005770 return getTok(tokI).int_data[3] != 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00005771 }
5772 SourceLocation getFunctionMacroTokenLoc(unsigned tokI) const {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005773 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[3]);
Guy Benyei11169dd2012-12-18 14:30:41 +00005774 }
5775
5776 void annotateAndAdvanceTokens(CXCursor, RangeComparisonResult, SourceRange);
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005777 bool annotateAndAdvanceFunctionMacroTokens(CXCursor, RangeComparisonResult,
Guy Benyei11169dd2012-12-18 14:30:41 +00005778 SourceRange);
5779
5780public:
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005781 AnnotateTokensWorker(CXToken *tokens, CXCursor *cursors, unsigned numTokens,
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005782 CXTranslationUnit TU, SourceRange RegionOfInterest)
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005783 : Tokens(tokens), Cursors(cursors),
Guy Benyei11169dd2012-12-18 14:30:41 +00005784 NumTokens(numTokens), TokIdx(0), PreprocessingTokIdx(0),
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005785 AnnotateVis(TU,
Guy Benyei11169dd2012-12-18 14:30:41 +00005786 AnnotateTokensVisitor, this,
5787 /*VisitPreprocessorLast=*/true,
5788 /*VisitIncludedEntities=*/false,
5789 RegionOfInterest,
5790 /*VisitDeclsOnly=*/false,
5791 AnnotateTokensPostChildrenVisitor),
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005792 SrcMgr(cxtu::getASTUnit(TU)->getSourceManager()),
Guy Benyei11169dd2012-12-18 14:30:41 +00005793 HasContextSensitiveKeywords(false) { }
5794
5795 void VisitChildren(CXCursor C) { AnnotateVis.VisitChildren(C); }
5796 enum CXChildVisitResult Visit(CXCursor cursor, CXCursor parent);
5797 bool postVisitChildren(CXCursor cursor);
5798 void AnnotateTokens();
5799
5800 /// \brief Determine whether the annotator saw any cursors that have
5801 /// context-sensitive keywords.
5802 bool hasContextSensitiveKeywords() const {
5803 return HasContextSensitiveKeywords;
5804 }
5805
5806 ~AnnotateTokensWorker() {
5807 assert(PostChildrenInfos.empty());
5808 }
5809};
Alexander Kornienkoab9db512015-06-22 23:07:51 +00005810}
Guy Benyei11169dd2012-12-18 14:30:41 +00005811
5812void AnnotateTokensWorker::AnnotateTokens() {
5813 // Walk the AST within the region of interest, annotating tokens
5814 // along the way.
5815 AnnotateVis.visitFileRegion();
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005816}
Guy Benyei11169dd2012-12-18 14:30:41 +00005817
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005818static inline void updateCursorAnnotation(CXCursor &Cursor,
5819 const CXCursor &updateC) {
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005820 if (clang_isInvalid(updateC.kind) || !clang_isInvalid(Cursor.kind))
Guy Benyei11169dd2012-12-18 14:30:41 +00005821 return;
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005822 Cursor = updateC;
Guy Benyei11169dd2012-12-18 14:30:41 +00005823}
5824
5825/// \brief It annotates and advances tokens with a cursor until the comparison
5826//// between the cursor location and the source range is the same as
5827/// \arg compResult.
5828///
5829/// Pass RangeBefore to annotate tokens with a cursor until a range is reached.
5830/// Pass RangeOverlap to annotate tokens inside a range.
5831void AnnotateTokensWorker::annotateAndAdvanceTokens(CXCursor updateC,
5832 RangeComparisonResult compResult,
5833 SourceRange range) {
5834 while (MoreTokens()) {
5835 const unsigned I = NextToken();
5836 if (isFunctionMacroToken(I))
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005837 if (!annotateAndAdvanceFunctionMacroTokens(updateC, compResult, range))
5838 return;
Guy Benyei11169dd2012-12-18 14:30:41 +00005839
5840 SourceLocation TokLoc = GetTokenLoc(I);
5841 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005842 updateCursorAnnotation(Cursors[I], updateC);
Guy Benyei11169dd2012-12-18 14:30:41 +00005843 AdvanceToken();
5844 continue;
5845 }
5846 break;
5847 }
5848}
5849
5850/// \brief Special annotation handling for macro argument tokens.
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005851/// \returns true if it advanced beyond all macro tokens, false otherwise.
5852bool AnnotateTokensWorker::annotateAndAdvanceFunctionMacroTokens(
Guy Benyei11169dd2012-12-18 14:30:41 +00005853 CXCursor updateC,
5854 RangeComparisonResult compResult,
5855 SourceRange range) {
5856 assert(MoreTokens());
5857 assert(isFunctionMacroToken(NextToken()) &&
5858 "Should be called only for macro arg tokens");
5859
5860 // This works differently than annotateAndAdvanceTokens; because expanded
5861 // macro arguments can have arbitrary translation-unit source order, we do not
5862 // advance the token index one by one until a token fails the range test.
5863 // We only advance once past all of the macro arg tokens if all of them
5864 // pass the range test. If one of them fails we keep the token index pointing
5865 // at the start of the macro arg tokens so that the failing token will be
5866 // annotated by a subsequent annotation try.
5867
5868 bool atLeastOneCompFail = false;
5869
5870 unsigned I = NextToken();
5871 for (; I < NumTokens && isFunctionMacroToken(I); ++I) {
5872 SourceLocation TokLoc = getFunctionMacroTokenLoc(I);
5873 if (TokLoc.isFileID())
5874 continue; // not macro arg token, it's parens or comma.
5875 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
5876 if (clang_isInvalid(clang_getCursorKind(Cursors[I])))
5877 Cursors[I] = updateC;
5878 } else
5879 atLeastOneCompFail = true;
5880 }
5881
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005882 if (atLeastOneCompFail)
5883 return false;
5884
5885 TokIdx = I; // All of the tokens were handled, advance beyond all of them.
5886 return true;
Guy Benyei11169dd2012-12-18 14:30:41 +00005887}
5888
5889enum CXChildVisitResult
5890AnnotateTokensWorker::Visit(CXCursor cursor, CXCursor parent) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005891 SourceRange cursorRange = getRawCursorExtent(cursor);
5892 if (cursorRange.isInvalid())
5893 return CXChildVisit_Recurse;
5894
5895 if (!HasContextSensitiveKeywords) {
5896 // Objective-C properties can have context-sensitive keywords.
5897 if (cursor.kind == CXCursor_ObjCPropertyDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005898 if (const ObjCPropertyDecl *Property
Guy Benyei11169dd2012-12-18 14:30:41 +00005899 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(cursor)))
5900 HasContextSensitiveKeywords = Property->getPropertyAttributesAsWritten() != 0;
5901 }
5902 // Objective-C methods can have context-sensitive keywords.
5903 else if (cursor.kind == CXCursor_ObjCInstanceMethodDecl ||
5904 cursor.kind == CXCursor_ObjCClassMethodDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005905 if (const ObjCMethodDecl *Method
Guy Benyei11169dd2012-12-18 14:30:41 +00005906 = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
5907 if (Method->getObjCDeclQualifier())
5908 HasContextSensitiveKeywords = true;
5909 else {
Aaron Ballman43b68be2014-03-07 17:50:17 +00005910 for (const auto *P : Method->params()) {
5911 if (P->getObjCDeclQualifier()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005912 HasContextSensitiveKeywords = true;
5913 break;
5914 }
5915 }
5916 }
5917 }
5918 }
5919 // C++ methods can have context-sensitive keywords.
5920 else if (cursor.kind == CXCursor_CXXMethod) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005921 if (const CXXMethodDecl *Method
Guy Benyei11169dd2012-12-18 14:30:41 +00005922 = dyn_cast_or_null<CXXMethodDecl>(getCursorDecl(cursor))) {
5923 if (Method->hasAttr<FinalAttr>() || Method->hasAttr<OverrideAttr>())
5924 HasContextSensitiveKeywords = true;
5925 }
5926 }
5927 // C++ classes can have context-sensitive keywords.
5928 else if (cursor.kind == CXCursor_StructDecl ||
5929 cursor.kind == CXCursor_ClassDecl ||
5930 cursor.kind == CXCursor_ClassTemplate ||
5931 cursor.kind == CXCursor_ClassTemplatePartialSpecialization) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005932 if (const Decl *D = getCursorDecl(cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +00005933 if (D->hasAttr<FinalAttr>())
5934 HasContextSensitiveKeywords = true;
5935 }
5936 }
Argyrios Kyrtzidis990b3862013-06-04 18:24:30 +00005937
5938 // Don't override a property annotation with its getter/setter method.
5939 if (cursor.kind == CXCursor_ObjCInstanceMethodDecl &&
5940 parent.kind == CXCursor_ObjCPropertyDecl)
5941 return CXChildVisit_Continue;
Guy Benyei11169dd2012-12-18 14:30:41 +00005942
5943 if (clang_isPreprocessing(cursor.kind)) {
5944 // Items in the preprocessing record are kept separate from items in
5945 // declarations, so we keep a separate token index.
5946 unsigned SavedTokIdx = TokIdx;
5947 TokIdx = PreprocessingTokIdx;
5948
5949 // Skip tokens up until we catch up to the beginning of the preprocessing
5950 // entry.
5951 while (MoreTokens()) {
5952 const unsigned I = NextToken();
5953 SourceLocation TokLoc = GetTokenLoc(I);
5954 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
5955 case RangeBefore:
5956 AdvanceToken();
5957 continue;
5958 case RangeAfter:
5959 case RangeOverlap:
5960 break;
5961 }
5962 break;
5963 }
5964
5965 // Look at all of the tokens within this range.
5966 while (MoreTokens()) {
5967 const unsigned I = NextToken();
5968 SourceLocation TokLoc = GetTokenLoc(I);
5969 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
5970 case RangeBefore:
5971 llvm_unreachable("Infeasible");
5972 case RangeAfter:
5973 break;
5974 case RangeOverlap:
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005975 // For macro expansions, just note where the beginning of the macro
5976 // expansion occurs.
5977 if (cursor.kind == CXCursor_MacroExpansion) {
5978 if (TokLoc == cursorRange.getBegin())
5979 Cursors[I] = cursor;
5980 AdvanceToken();
5981 break;
5982 }
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005983 // We may have already annotated macro names inside macro definitions.
5984 if (Cursors[I].kind != CXCursor_MacroExpansion)
5985 Cursors[I] = cursor;
Guy Benyei11169dd2012-12-18 14:30:41 +00005986 AdvanceToken();
Guy Benyei11169dd2012-12-18 14:30:41 +00005987 continue;
5988 }
5989 break;
5990 }
5991
5992 // Save the preprocessing token index; restore the non-preprocessing
5993 // token index.
5994 PreprocessingTokIdx = TokIdx;
5995 TokIdx = SavedTokIdx;
5996 return CXChildVisit_Recurse;
5997 }
5998
5999 if (cursorRange.isInvalid())
6000 return CXChildVisit_Continue;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00006001
6002 unsigned BeforeReachingCursorIdx = NextToken();
Guy Benyei11169dd2012-12-18 14:30:41 +00006003 const enum CXCursorKind cursorK = clang_getCursorKind(cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00006004 const enum CXCursorKind K = clang_getCursorKind(parent);
6005 const CXCursor updateC =
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00006006 (clang_isInvalid(K) || K == CXCursor_TranslationUnit ||
6007 // Attributes are annotated out-of-order, skip tokens until we reach it.
6008 clang_isAttribute(cursor.kind))
Guy Benyei11169dd2012-12-18 14:30:41 +00006009 ? clang_getNullCursor() : parent;
6010
6011 annotateAndAdvanceTokens(updateC, RangeBefore, cursorRange);
6012
6013 // Avoid having the cursor of an expression "overwrite" the annotation of the
6014 // variable declaration that it belongs to.
6015 // This can happen for C++ constructor expressions whose range generally
6016 // include the variable declaration, e.g.:
6017 // MyCXXClass foo; // Make sure we don't annotate 'foo' as a CallExpr cursor.
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00006018 if (clang_isExpression(cursorK) && MoreTokens()) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00006019 const Expr *E = getCursorExpr(cursor);
Dmitri Gribenkoa1691182013-01-26 18:12:08 +00006020 if (const Decl *D = getCursorParentDecl(cursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00006021 const unsigned I = NextToken();
6022 if (E->getLocStart().isValid() && D->getLocation().isValid() &&
6023 E->getLocStart() == D->getLocation() &&
6024 E->getLocStart() == GetTokenLoc(I)) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006025 updateCursorAnnotation(Cursors[I], updateC);
Guy Benyei11169dd2012-12-18 14:30:41 +00006026 AdvanceToken();
6027 }
6028 }
6029 }
6030
6031 // Before recursing into the children keep some state that we are going
6032 // to use in the AnnotateTokensWorker::postVisitChildren callback to do some
6033 // extra work after the child nodes are visited.
6034 // Note that we don't call VisitChildren here to avoid traversing statements
6035 // code-recursively which can blow the stack.
6036
6037 PostChildrenInfo Info;
6038 Info.Cursor = cursor;
6039 Info.CursorRange = cursorRange;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00006040 Info.BeforeReachingCursorIdx = BeforeReachingCursorIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00006041 Info.BeforeChildrenTokenIdx = NextToken();
6042 PostChildrenInfos.push_back(Info);
6043
6044 return CXChildVisit_Recurse;
6045}
6046
6047bool AnnotateTokensWorker::postVisitChildren(CXCursor cursor) {
6048 if (PostChildrenInfos.empty())
6049 return false;
6050 const PostChildrenInfo &Info = PostChildrenInfos.back();
6051 if (!clang_equalCursors(Info.Cursor, cursor))
6052 return false;
6053
6054 const unsigned BeforeChildren = Info.BeforeChildrenTokenIdx;
6055 const unsigned AfterChildren = NextToken();
6056 SourceRange cursorRange = Info.CursorRange;
6057
6058 // Scan the tokens that are at the end of the cursor, but are not captured
6059 // but the child cursors.
6060 annotateAndAdvanceTokens(cursor, RangeOverlap, cursorRange);
6061
6062 // Scan the tokens that are at the beginning of the cursor, but are not
6063 // capture by the child cursors.
6064 for (unsigned I = BeforeChildren; I != AfterChildren; ++I) {
6065 if (!clang_isInvalid(clang_getCursorKind(Cursors[I])))
6066 break;
6067
6068 Cursors[I] = cursor;
6069 }
6070
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00006071 // Attributes are annotated out-of-order, rewind TokIdx to when we first
6072 // encountered the attribute cursor.
6073 if (clang_isAttribute(cursor.kind))
6074 TokIdx = Info.BeforeReachingCursorIdx;
6075
Guy Benyei11169dd2012-12-18 14:30:41 +00006076 PostChildrenInfos.pop_back();
6077 return false;
6078}
6079
6080static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
6081 CXCursor parent,
6082 CXClientData client_data) {
6083 return static_cast<AnnotateTokensWorker*>(client_data)->Visit(cursor, parent);
6084}
6085
6086static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
6087 CXClientData client_data) {
6088 return static_cast<AnnotateTokensWorker*>(client_data)->
6089 postVisitChildren(cursor);
6090}
6091
6092namespace {
6093
6094/// \brief Uses the macro expansions in the preprocessing record to find
6095/// and mark tokens that are macro arguments. This info is used by the
6096/// AnnotateTokensWorker.
6097class MarkMacroArgTokensVisitor {
6098 SourceManager &SM;
6099 CXToken *Tokens;
6100 unsigned NumTokens;
6101 unsigned CurIdx;
6102
6103public:
6104 MarkMacroArgTokensVisitor(SourceManager &SM,
6105 CXToken *tokens, unsigned numTokens)
6106 : SM(SM), Tokens(tokens), NumTokens(numTokens), CurIdx(0) { }
6107
6108 CXChildVisitResult visit(CXCursor cursor, CXCursor parent) {
6109 if (cursor.kind != CXCursor_MacroExpansion)
6110 return CXChildVisit_Continue;
6111
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006112 SourceRange macroRange = getCursorMacroExpansion(cursor).getSourceRange();
Guy Benyei11169dd2012-12-18 14:30:41 +00006113 if (macroRange.getBegin() == macroRange.getEnd())
6114 return CXChildVisit_Continue; // it's not a function macro.
6115
6116 for (; CurIdx < NumTokens; ++CurIdx) {
6117 if (!SM.isBeforeInTranslationUnit(getTokenLoc(CurIdx),
6118 macroRange.getBegin()))
6119 break;
6120 }
6121
6122 if (CurIdx == NumTokens)
6123 return CXChildVisit_Break;
6124
6125 for (; CurIdx < NumTokens; ++CurIdx) {
6126 SourceLocation tokLoc = getTokenLoc(CurIdx);
6127 if (!SM.isBeforeInTranslationUnit(tokLoc, macroRange.getEnd()))
6128 break;
6129
6130 setFunctionMacroTokenLoc(CurIdx, SM.getMacroArgExpandedLocation(tokLoc));
6131 }
6132
6133 if (CurIdx == NumTokens)
6134 return CXChildVisit_Break;
6135
6136 return CXChildVisit_Continue;
6137 }
6138
6139private:
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00006140 CXToken &getTok(unsigned Idx) {
6141 assert(Idx < NumTokens);
6142 return Tokens[Idx];
6143 }
6144 const CXToken &getTok(unsigned Idx) const {
6145 assert(Idx < NumTokens);
6146 return Tokens[Idx];
6147 }
6148
Guy Benyei11169dd2012-12-18 14:30:41 +00006149 SourceLocation getTokenLoc(unsigned tokI) {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00006150 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[1]);
Guy Benyei11169dd2012-12-18 14:30:41 +00006151 }
6152
6153 void setFunctionMacroTokenLoc(unsigned tokI, SourceLocation loc) {
6154 // The third field is reserved and currently not used. Use it here
6155 // to mark macro arg expanded tokens with their expanded locations.
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00006156 getTok(tokI).int_data[3] = loc.getRawEncoding();
Guy Benyei11169dd2012-12-18 14:30:41 +00006157 }
6158};
6159
6160} // end anonymous namespace
6161
6162static CXChildVisitResult
6163MarkMacroArgTokensVisitorDelegate(CXCursor cursor, CXCursor parent,
6164 CXClientData client_data) {
6165 return static_cast<MarkMacroArgTokensVisitor*>(client_data)->visit(cursor,
6166 parent);
6167}
6168
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006169/// \brief Used by \c annotatePreprocessorTokens.
6170/// \returns true if lexing was finished, false otherwise.
6171static bool lexNext(Lexer &Lex, Token &Tok,
6172 unsigned &NextIdx, unsigned NumTokens) {
6173 if (NextIdx >= NumTokens)
6174 return true;
6175
6176 ++NextIdx;
6177 Lex.LexFromRawLexer(Tok);
6178 if (Tok.is(tok::eof))
6179 return true;
6180
6181 return false;
6182}
6183
Guy Benyei11169dd2012-12-18 14:30:41 +00006184static void annotatePreprocessorTokens(CXTranslationUnit TU,
6185 SourceRange RegionOfInterest,
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006186 CXCursor *Cursors,
6187 CXToken *Tokens,
6188 unsigned NumTokens) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006189 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00006190
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006191 Preprocessor &PP = CXXUnit->getPreprocessor();
Guy Benyei11169dd2012-12-18 14:30:41 +00006192 SourceManager &SourceMgr = CXXUnit->getSourceManager();
6193 std::pair<FileID, unsigned> BeginLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00006194 = SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getBegin());
Guy Benyei11169dd2012-12-18 14:30:41 +00006195 std::pair<FileID, unsigned> EndLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00006196 = SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getEnd());
Guy Benyei11169dd2012-12-18 14:30:41 +00006197
6198 if (BeginLocInfo.first != EndLocInfo.first)
6199 return;
6200
6201 StringRef Buffer;
6202 bool Invalid = false;
6203 Buffer = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
6204 if (Buffer.empty() || Invalid)
6205 return;
6206
6207 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
6208 CXXUnit->getASTContext().getLangOpts(),
6209 Buffer.begin(), Buffer.data() + BeginLocInfo.second,
6210 Buffer.end());
6211 Lex.SetCommentRetentionState(true);
6212
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006213 unsigned NextIdx = 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00006214 // Lex tokens in raw mode until we hit the end of the range, to avoid
6215 // entering #includes or expanding macros.
6216 while (true) {
6217 Token Tok;
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006218 if (lexNext(Lex, Tok, NextIdx, NumTokens))
6219 break;
6220 unsigned TokIdx = NextIdx-1;
6221 assert(Tok.getLocation() ==
6222 SourceLocation::getFromRawEncoding(Tokens[TokIdx].int_data[1]));
Guy Benyei11169dd2012-12-18 14:30:41 +00006223
6224 reprocess:
6225 if (Tok.is(tok::hash) && Tok.isAtStartOfLine()) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006226 // We have found a preprocessing directive. Annotate the tokens
6227 // appropriately.
Guy Benyei11169dd2012-12-18 14:30:41 +00006228 //
6229 // FIXME: Some simple tests here could identify macro definitions and
6230 // #undefs, to provide specific cursor kinds for those.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006231
6232 SourceLocation BeginLoc = Tok.getLocation();
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006233 if (lexNext(Lex, Tok, NextIdx, NumTokens))
6234 break;
6235
Craig Topper69186e72014-06-08 08:38:04 +00006236 MacroInfo *MI = nullptr;
Alp Toker2d57cea2014-05-17 04:53:25 +00006237 if (Tok.is(tok::raw_identifier) && Tok.getRawIdentifier() == "define") {
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006238 if (lexNext(Lex, Tok, NextIdx, NumTokens))
6239 break;
6240
6241 if (Tok.is(tok::raw_identifier)) {
Alp Toker2d57cea2014-05-17 04:53:25 +00006242 IdentifierInfo &II =
6243 PP.getIdentifierTable().get(Tok.getRawIdentifier());
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006244 SourceLocation MappedTokLoc =
6245 CXXUnit->mapLocationToPreamble(Tok.getLocation());
6246 MI = getMacroInfo(II, MappedTokLoc, TU);
6247 }
6248 }
6249
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006250 bool finished = false;
Guy Benyei11169dd2012-12-18 14:30:41 +00006251 do {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006252 if (lexNext(Lex, Tok, NextIdx, NumTokens)) {
6253 finished = true;
6254 break;
6255 }
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006256 // If we are in a macro definition, check if the token was ever a
6257 // macro name and annotate it if that's the case.
6258 if (MI) {
6259 SourceLocation SaveLoc = Tok.getLocation();
6260 Tok.setLocation(CXXUnit->mapLocationToPreamble(SaveLoc));
Richard Smith66a81862015-05-04 02:25:31 +00006261 MacroDefinitionRecord *MacroDef =
6262 checkForMacroInMacroDefinition(MI, Tok, TU);
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006263 Tok.setLocation(SaveLoc);
6264 if (MacroDef)
Richard Smith66a81862015-05-04 02:25:31 +00006265 Cursors[NextIdx - 1] =
6266 MakeMacroExpansionCursor(MacroDef, Tok.getLocation(), TU);
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006267 }
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006268 } while (!Tok.isAtStartOfLine());
6269
6270 unsigned LastIdx = finished ? NextIdx-1 : NextIdx-2;
6271 assert(TokIdx <= LastIdx);
6272 SourceLocation EndLoc =
6273 SourceLocation::getFromRawEncoding(Tokens[LastIdx].int_data[1]);
6274 CXCursor Cursor =
6275 MakePreprocessingDirectiveCursor(SourceRange(BeginLoc, EndLoc), TU);
6276
6277 for (; TokIdx <= LastIdx; ++TokIdx)
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006278 updateCursorAnnotation(Cursors[TokIdx], Cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00006279
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006280 if (finished)
6281 break;
6282 goto reprocess;
Guy Benyei11169dd2012-12-18 14:30:41 +00006283 }
Guy Benyei11169dd2012-12-18 14:30:41 +00006284 }
6285}
6286
6287// This gets run a separate thread to avoid stack blowout.
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00006288static void clang_annotateTokensImpl(CXTranslationUnit TU, ASTUnit *CXXUnit,
6289 CXToken *Tokens, unsigned NumTokens,
6290 CXCursor *Cursors) {
Dmitri Gribenko183436e2013-01-26 21:49:50 +00006291 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00006292 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
6293 setThreadBackgroundPriority();
6294
6295 // Determine the region of interest, which contains all of the tokens.
6296 SourceRange RegionOfInterest;
6297 RegionOfInterest.setBegin(
6298 cxloc::translateSourceLocation(clang_getTokenLocation(TU, Tokens[0])));
6299 RegionOfInterest.setEnd(
6300 cxloc::translateSourceLocation(clang_getTokenLocation(TU,
6301 Tokens[NumTokens-1])));
6302
Guy Benyei11169dd2012-12-18 14:30:41 +00006303 // Relex the tokens within the source range to look for preprocessing
6304 // directives.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006305 annotatePreprocessorTokens(TU, RegionOfInterest, Cursors, Tokens, NumTokens);
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00006306
6307 // If begin location points inside a macro argument, set it to the expansion
6308 // location so we can have the full context when annotating semantically.
6309 {
6310 SourceManager &SM = CXXUnit->getSourceManager();
6311 SourceLocation Loc =
6312 SM.getMacroArgExpandedLocation(RegionOfInterest.getBegin());
6313 if (Loc.isMacroID())
6314 RegionOfInterest.setBegin(SM.getExpansionLoc(Loc));
6315 }
6316
Guy Benyei11169dd2012-12-18 14:30:41 +00006317 if (CXXUnit->getPreprocessor().getPreprocessingRecord()) {
6318 // Search and mark tokens that are macro argument expansions.
6319 MarkMacroArgTokensVisitor Visitor(CXXUnit->getSourceManager(),
6320 Tokens, NumTokens);
6321 CursorVisitor MacroArgMarker(TU,
6322 MarkMacroArgTokensVisitorDelegate, &Visitor,
6323 /*VisitPreprocessorLast=*/true,
6324 /*VisitIncludedEntities=*/false,
6325 RegionOfInterest);
6326 MacroArgMarker.visitPreprocessedEntitiesInRegion();
6327 }
6328
6329 // Annotate all of the source locations in the region of interest that map to
6330 // a specific cursor.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006331 AnnotateTokensWorker W(Tokens, Cursors, NumTokens, TU, RegionOfInterest);
Guy Benyei11169dd2012-12-18 14:30:41 +00006332
6333 // FIXME: We use a ridiculous stack size here because the data-recursion
6334 // algorithm uses a large stack frame than the non-data recursive version,
6335 // and AnnotationTokensWorker currently transforms the data-recursion
6336 // algorithm back into a traditional recursion by explicitly calling
6337 // VisitChildren(). We will need to remove this explicit recursive call.
6338 W.AnnotateTokens();
6339
6340 // If we ran into any entities that involve context-sensitive keywords,
6341 // take another pass through the tokens to mark them as such.
6342 if (W.hasContextSensitiveKeywords()) {
6343 for (unsigned I = 0; I != NumTokens; ++I) {
6344 if (clang_getTokenKind(Tokens[I]) != CXToken_Identifier)
6345 continue;
6346
6347 if (Cursors[I].kind == CXCursor_ObjCPropertyDecl) {
6348 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006349 if (const ObjCPropertyDecl *Property
Guy Benyei11169dd2012-12-18 14:30:41 +00006350 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(Cursors[I]))) {
6351 if (Property->getPropertyAttributesAsWritten() != 0 &&
6352 llvm::StringSwitch<bool>(II->getName())
6353 .Case("readonly", true)
6354 .Case("assign", true)
6355 .Case("unsafe_unretained", true)
6356 .Case("readwrite", true)
6357 .Case("retain", true)
6358 .Case("copy", true)
6359 .Case("nonatomic", true)
6360 .Case("atomic", true)
6361 .Case("getter", true)
6362 .Case("setter", true)
6363 .Case("strong", true)
6364 .Case("weak", true)
6365 .Default(false))
6366 Tokens[I].int_data[0] = CXToken_Keyword;
6367 }
6368 continue;
6369 }
6370
6371 if (Cursors[I].kind == CXCursor_ObjCInstanceMethodDecl ||
6372 Cursors[I].kind == CXCursor_ObjCClassMethodDecl) {
6373 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
6374 if (llvm::StringSwitch<bool>(II->getName())
6375 .Case("in", true)
6376 .Case("out", true)
6377 .Case("inout", true)
6378 .Case("oneway", true)
6379 .Case("bycopy", true)
6380 .Case("byref", true)
6381 .Default(false))
6382 Tokens[I].int_data[0] = CXToken_Keyword;
6383 continue;
6384 }
6385
6386 if (Cursors[I].kind == CXCursor_CXXFinalAttr ||
6387 Cursors[I].kind == CXCursor_CXXOverrideAttr) {
6388 Tokens[I].int_data[0] = CXToken_Keyword;
6389 continue;
6390 }
6391 }
6392 }
6393}
6394
6395extern "C" {
6396
6397void clang_annotateTokens(CXTranslationUnit TU,
6398 CXToken *Tokens, unsigned NumTokens,
6399 CXCursor *Cursors) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006400 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006401 LOG_BAD_TU(TU);
6402 return;
6403 }
6404 if (NumTokens == 0 || !Tokens || !Cursors) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006405 LOG_FUNC_SECTION { *Log << "<null input>"; }
Guy Benyei11169dd2012-12-18 14:30:41 +00006406 return;
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006407 }
6408
6409 LOG_FUNC_SECTION {
6410 *Log << TU << ' ';
6411 CXSourceLocation bloc = clang_getTokenLocation(TU, Tokens[0]);
6412 CXSourceLocation eloc = clang_getTokenLocation(TU, Tokens[NumTokens-1]);
6413 *Log << clang_getRange(bloc, eloc);
6414 }
Guy Benyei11169dd2012-12-18 14:30:41 +00006415
6416 // Any token we don't specifically annotate will have a NULL cursor.
6417 CXCursor C = clang_getNullCursor();
6418 for (unsigned I = 0; I != NumTokens; ++I)
6419 Cursors[I] = C;
6420
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006421 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00006422 if (!CXXUnit)
6423 return;
6424
6425 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00006426
6427 auto AnnotateTokensImpl = [=]() {
6428 clang_annotateTokensImpl(TU, CXXUnit, Tokens, NumTokens, Cursors);
6429 };
Guy Benyei11169dd2012-12-18 14:30:41 +00006430 llvm::CrashRecoveryContext CRC;
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00006431 if (!RunSafely(CRC, AnnotateTokensImpl, GetSafetyThreadStackSize() * 2)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00006432 fprintf(stderr, "libclang: crash detected while annotating tokens\n");
6433 }
6434}
6435
6436} // end: extern "C"
6437
6438//===----------------------------------------------------------------------===//
6439// Operations for querying linkage of a cursor.
6440//===----------------------------------------------------------------------===//
6441
6442extern "C" {
6443CXLinkageKind clang_getCursorLinkage(CXCursor cursor) {
6444 if (!clang_isDeclaration(cursor.kind))
6445 return CXLinkage_Invalid;
6446
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006447 const Decl *D = cxcursor::getCursorDecl(cursor);
6448 if (const NamedDecl *ND = dyn_cast_or_null<NamedDecl>(D))
Rafael Espindola3ae00052013-05-13 00:12:11 +00006449 switch (ND->getLinkageInternal()) {
Rafael Espindola50df3a02013-05-25 17:16:20 +00006450 case NoLinkage:
6451 case VisibleNoLinkage: return CXLinkage_NoLinkage;
Guy Benyei11169dd2012-12-18 14:30:41 +00006452 case InternalLinkage: return CXLinkage_Internal;
6453 case UniqueExternalLinkage: return CXLinkage_UniqueExternal;
6454 case ExternalLinkage: return CXLinkage_External;
6455 };
6456
6457 return CXLinkage_Invalid;
6458}
6459} // end: extern "C"
6460
6461//===----------------------------------------------------------------------===//
Ehsan Akhgari93697fa2015-11-23 19:56:46 +00006462// Operations for querying visibility of a cursor.
6463//===----------------------------------------------------------------------===//
6464
6465extern "C" {
6466CXVisibilityKind clang_getCursorVisibility(CXCursor cursor) {
6467 if (!clang_isDeclaration(cursor.kind))
6468 return CXVisibility_Invalid;
6469
6470 const Decl *D = cxcursor::getCursorDecl(cursor);
6471 if (const NamedDecl *ND = dyn_cast_or_null<NamedDecl>(D))
6472 switch (ND->getVisibility()) {
6473 case HiddenVisibility: return CXVisibility_Hidden;
6474 case ProtectedVisibility: return CXVisibility_Protected;
6475 case DefaultVisibility: return CXVisibility_Default;
6476 };
6477
6478 return CXVisibility_Invalid;
6479}
6480} // end: extern "C"
6481
6482//===----------------------------------------------------------------------===//
Guy Benyei11169dd2012-12-18 14:30:41 +00006483// Operations for querying language of a cursor.
6484//===----------------------------------------------------------------------===//
6485
6486static CXLanguageKind getDeclLanguage(const Decl *D) {
6487 if (!D)
6488 return CXLanguage_C;
6489
6490 switch (D->getKind()) {
6491 default:
6492 break;
6493 case Decl::ImplicitParam:
6494 case Decl::ObjCAtDefsField:
6495 case Decl::ObjCCategory:
6496 case Decl::ObjCCategoryImpl:
6497 case Decl::ObjCCompatibleAlias:
6498 case Decl::ObjCImplementation:
6499 case Decl::ObjCInterface:
6500 case Decl::ObjCIvar:
6501 case Decl::ObjCMethod:
6502 case Decl::ObjCProperty:
6503 case Decl::ObjCPropertyImpl:
6504 case Decl::ObjCProtocol:
Douglas Gregor85f3f952015-07-07 03:57:15 +00006505 case Decl::ObjCTypeParam:
Guy Benyei11169dd2012-12-18 14:30:41 +00006506 return CXLanguage_ObjC;
6507 case Decl::CXXConstructor:
6508 case Decl::CXXConversion:
6509 case Decl::CXXDestructor:
6510 case Decl::CXXMethod:
6511 case Decl::CXXRecord:
6512 case Decl::ClassTemplate:
6513 case Decl::ClassTemplatePartialSpecialization:
6514 case Decl::ClassTemplateSpecialization:
6515 case Decl::Friend:
6516 case Decl::FriendTemplate:
6517 case Decl::FunctionTemplate:
6518 case Decl::LinkageSpec:
6519 case Decl::Namespace:
6520 case Decl::NamespaceAlias:
6521 case Decl::NonTypeTemplateParm:
6522 case Decl::StaticAssert:
6523 case Decl::TemplateTemplateParm:
6524 case Decl::TemplateTypeParm:
6525 case Decl::UnresolvedUsingTypename:
6526 case Decl::UnresolvedUsingValue:
6527 case Decl::Using:
6528 case Decl::UsingDirective:
6529 case Decl::UsingShadow:
6530 return CXLanguage_CPlusPlus;
6531 }
6532
6533 return CXLanguage_C;
6534}
6535
6536extern "C" {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006537
6538static CXAvailabilityKind getCursorAvailabilityForDecl(const Decl *D) {
6539 if (isa<FunctionDecl>(D) && cast<FunctionDecl>(D)->isDeleted())
Manuel Klimek8e3a7ed2015-09-25 17:53:16 +00006540 return CXAvailability_NotAvailable;
Guy Benyei11169dd2012-12-18 14:30:41 +00006541
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006542 switch (D->getAvailability()) {
6543 case AR_Available:
6544 case AR_NotYetIntroduced:
6545 if (const EnumConstantDecl *EnumConst = dyn_cast<EnumConstantDecl>(D))
Benjamin Kramer656363d2013-10-15 18:53:18 +00006546 return getCursorAvailabilityForDecl(
6547 cast<Decl>(EnumConst->getDeclContext()));
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006548 return CXAvailability_Available;
6549
6550 case AR_Deprecated:
6551 return CXAvailability_Deprecated;
6552
6553 case AR_Unavailable:
6554 return CXAvailability_NotAvailable;
6555 }
Benjamin Kramer656363d2013-10-15 18:53:18 +00006556
6557 llvm_unreachable("Unknown availability kind!");
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006558}
6559
Guy Benyei11169dd2012-12-18 14:30:41 +00006560enum CXAvailabilityKind clang_getCursorAvailability(CXCursor cursor) {
6561 if (clang_isDeclaration(cursor.kind))
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006562 if (const Decl *D = cxcursor::getCursorDecl(cursor))
6563 return getCursorAvailabilityForDecl(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00006564
6565 return CXAvailability_Available;
6566}
6567
6568static CXVersion convertVersion(VersionTuple In) {
6569 CXVersion Out = { -1, -1, -1 };
6570 if (In.empty())
6571 return Out;
6572
6573 Out.Major = In.getMajor();
6574
NAKAMURA Takumic2b5d1f2013-02-21 02:32:34 +00006575 Optional<unsigned> Minor = In.getMinor();
6576 if (Minor.hasValue())
Guy Benyei11169dd2012-12-18 14:30:41 +00006577 Out.Minor = *Minor;
6578 else
6579 return Out;
6580
NAKAMURA Takumic2b5d1f2013-02-21 02:32:34 +00006581 Optional<unsigned> Subminor = In.getSubminor();
6582 if (Subminor.hasValue())
Guy Benyei11169dd2012-12-18 14:30:41 +00006583 Out.Subminor = *Subminor;
6584
6585 return Out;
6586}
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006587
6588static int getCursorPlatformAvailabilityForDecl(const Decl *D,
6589 int *always_deprecated,
6590 CXString *deprecated_message,
6591 int *always_unavailable,
6592 CXString *unavailable_message,
6593 CXPlatformAvailability *availability,
6594 int availability_size) {
6595 bool HadAvailAttr = false;
6596 int N = 0;
Aaron Ballmanb97112e2014-03-08 22:19:01 +00006597 for (auto A : D->attrs()) {
6598 if (DeprecatedAttr *Deprecated = dyn_cast<DeprecatedAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006599 HadAvailAttr = true;
6600 if (always_deprecated)
6601 *always_deprecated = 1;
Nico Weberaacf0312014-04-24 05:16:45 +00006602 if (deprecated_message) {
Argyrios Kyrtzidisedfe07f2014-04-24 06:05:40 +00006603 clang_disposeString(*deprecated_message);
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006604 *deprecated_message = cxstring::createDup(Deprecated->getMessage());
Nico Weberaacf0312014-04-24 05:16:45 +00006605 }
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006606 continue;
6607 }
6608
Aaron Ballmanb97112e2014-03-08 22:19:01 +00006609 if (UnavailableAttr *Unavailable = dyn_cast<UnavailableAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006610 HadAvailAttr = true;
6611 if (always_unavailable)
6612 *always_unavailable = 1;
6613 if (unavailable_message) {
Argyrios Kyrtzidisedfe07f2014-04-24 06:05:40 +00006614 clang_disposeString(*unavailable_message);
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006615 *unavailable_message = cxstring::createDup(Unavailable->getMessage());
6616 }
6617 continue;
6618 }
6619
Aaron Ballmanb97112e2014-03-08 22:19:01 +00006620 if (AvailabilityAttr *Avail = dyn_cast<AvailabilityAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006621 HadAvailAttr = true;
6622 if (N < availability_size) {
6623 availability[N].Platform
6624 = cxstring::createDup(Avail->getPlatform()->getName());
6625 availability[N].Introduced = convertVersion(Avail->getIntroduced());
6626 availability[N].Deprecated = convertVersion(Avail->getDeprecated());
6627 availability[N].Obsoleted = convertVersion(Avail->getObsoleted());
6628 availability[N].Unavailable = Avail->getUnavailable();
6629 availability[N].Message = cxstring::createDup(Avail->getMessage());
6630 }
6631 ++N;
6632 }
6633 }
6634
6635 if (!HadAvailAttr)
6636 if (const EnumConstantDecl *EnumConst = dyn_cast<EnumConstantDecl>(D))
6637 return getCursorPlatformAvailabilityForDecl(
6638 cast<Decl>(EnumConst->getDeclContext()),
6639 always_deprecated,
6640 deprecated_message,
6641 always_unavailable,
6642 unavailable_message,
6643 availability,
6644 availability_size);
Guy Benyei11169dd2012-12-18 14:30:41 +00006645
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006646 return N;
6647}
6648
Guy Benyei11169dd2012-12-18 14:30:41 +00006649int clang_getCursorPlatformAvailability(CXCursor cursor,
6650 int *always_deprecated,
6651 CXString *deprecated_message,
6652 int *always_unavailable,
6653 CXString *unavailable_message,
6654 CXPlatformAvailability *availability,
6655 int availability_size) {
6656 if (always_deprecated)
6657 *always_deprecated = 0;
6658 if (deprecated_message)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006659 *deprecated_message = cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006660 if (always_unavailable)
6661 *always_unavailable = 0;
6662 if (unavailable_message)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006663 *unavailable_message = cxstring::createEmpty();
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006664
Guy Benyei11169dd2012-12-18 14:30:41 +00006665 if (!clang_isDeclaration(cursor.kind))
6666 return 0;
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006667
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006668 const Decl *D = cxcursor::getCursorDecl(cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00006669 if (!D)
6670 return 0;
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006671
6672 return getCursorPlatformAvailabilityForDecl(D, always_deprecated,
6673 deprecated_message,
6674 always_unavailable,
6675 unavailable_message,
6676 availability,
6677 availability_size);
Guy Benyei11169dd2012-12-18 14:30:41 +00006678}
6679
6680void clang_disposeCXPlatformAvailability(CXPlatformAvailability *availability) {
6681 clang_disposeString(availability->Platform);
6682 clang_disposeString(availability->Message);
6683}
6684
6685CXLanguageKind clang_getCursorLanguage(CXCursor cursor) {
6686 if (clang_isDeclaration(cursor.kind))
6687 return getDeclLanguage(cxcursor::getCursorDecl(cursor));
6688
6689 return CXLanguage_Invalid;
6690}
6691
6692 /// \brief If the given cursor is the "templated" declaration
6693 /// descibing a class or function template, return the class or
6694 /// function template.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006695static const Decl *maybeGetTemplateCursor(const Decl *D) {
Guy Benyei11169dd2012-12-18 14:30:41 +00006696 if (!D)
Craig Topper69186e72014-06-08 08:38:04 +00006697 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006698
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006699 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00006700 if (FunctionTemplateDecl *FunTmpl = FD->getDescribedFunctionTemplate())
6701 return FunTmpl;
6702
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006703 if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00006704 if (ClassTemplateDecl *ClassTmpl = RD->getDescribedClassTemplate())
6705 return ClassTmpl;
6706
6707 return D;
6708}
6709
Argyrios Kyrtzidis4e0854f2014-10-15 17:05:31 +00006710
6711enum CX_StorageClass clang_Cursor_getStorageClass(CXCursor C) {
6712 StorageClass sc = SC_None;
6713 const Decl *D = getCursorDecl(C);
6714 if (D) {
6715 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
6716 sc = FD->getStorageClass();
6717 } else if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
6718 sc = VD->getStorageClass();
6719 } else {
6720 return CX_SC_Invalid;
6721 }
6722 } else {
6723 return CX_SC_Invalid;
6724 }
6725 switch (sc) {
6726 case SC_None:
6727 return CX_SC_None;
6728 case SC_Extern:
6729 return CX_SC_Extern;
6730 case SC_Static:
6731 return CX_SC_Static;
6732 case SC_PrivateExtern:
6733 return CX_SC_PrivateExtern;
Argyrios Kyrtzidis4e0854f2014-10-15 17:05:31 +00006734 case SC_Auto:
6735 return CX_SC_Auto;
6736 case SC_Register:
6737 return CX_SC_Register;
Argyrios Kyrtzidis4e0854f2014-10-15 17:05:31 +00006738 }
Kaelyn Takataab61e702014-10-15 18:03:26 +00006739 llvm_unreachable("Unhandled storage class!");
Argyrios Kyrtzidis4e0854f2014-10-15 17:05:31 +00006740}
6741
Guy Benyei11169dd2012-12-18 14:30:41 +00006742CXCursor clang_getCursorSemanticParent(CXCursor cursor) {
6743 if (clang_isDeclaration(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006744 if (const Decl *D = getCursorDecl(cursor)) {
6745 const DeclContext *DC = D->getDeclContext();
Guy Benyei11169dd2012-12-18 14:30:41 +00006746 if (!DC)
6747 return clang_getNullCursor();
6748
6749 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
6750 getCursorTU(cursor));
6751 }
6752 }
6753
6754 if (clang_isStatement(cursor.kind) || clang_isExpression(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006755 if (const Decl *D = getCursorDecl(cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +00006756 return MakeCXCursor(D, getCursorTU(cursor));
6757 }
6758
6759 return clang_getNullCursor();
6760}
6761
6762CXCursor clang_getCursorLexicalParent(CXCursor cursor) {
6763 if (clang_isDeclaration(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006764 if (const Decl *D = getCursorDecl(cursor)) {
6765 const DeclContext *DC = D->getLexicalDeclContext();
Guy Benyei11169dd2012-12-18 14:30:41 +00006766 if (!DC)
6767 return clang_getNullCursor();
6768
6769 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
6770 getCursorTU(cursor));
6771 }
6772 }
6773
6774 // FIXME: Note that we can't easily compute the lexical context of a
6775 // statement or expression, so we return nothing.
6776 return clang_getNullCursor();
6777}
6778
6779CXFile clang_getIncludedFile(CXCursor cursor) {
6780 if (cursor.kind != CXCursor_InclusionDirective)
Craig Topper69186e72014-06-08 08:38:04 +00006781 return nullptr;
6782
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00006783 const InclusionDirective *ID = getCursorInclusionDirective(cursor);
Dmitri Gribenkof9304482013-01-23 15:56:07 +00006784 return const_cast<FileEntry *>(ID->getFile());
Guy Benyei11169dd2012-12-18 14:30:41 +00006785}
6786
Argyrios Kyrtzidis9adfd8a2013-04-18 22:15:49 +00006787unsigned clang_Cursor_getObjCPropertyAttributes(CXCursor C, unsigned reserved) {
6788 if (C.kind != CXCursor_ObjCPropertyDecl)
6789 return CXObjCPropertyAttr_noattr;
6790
6791 unsigned Result = CXObjCPropertyAttr_noattr;
6792 const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(getCursorDecl(C));
6793 ObjCPropertyDecl::PropertyAttributeKind Attr =
6794 PD->getPropertyAttributesAsWritten();
6795
6796#define SET_CXOBJCPROP_ATTR(A) \
6797 if (Attr & ObjCPropertyDecl::OBJC_PR_##A) \
6798 Result |= CXObjCPropertyAttr_##A
6799 SET_CXOBJCPROP_ATTR(readonly);
6800 SET_CXOBJCPROP_ATTR(getter);
6801 SET_CXOBJCPROP_ATTR(assign);
6802 SET_CXOBJCPROP_ATTR(readwrite);
6803 SET_CXOBJCPROP_ATTR(retain);
6804 SET_CXOBJCPROP_ATTR(copy);
6805 SET_CXOBJCPROP_ATTR(nonatomic);
6806 SET_CXOBJCPROP_ATTR(setter);
6807 SET_CXOBJCPROP_ATTR(atomic);
6808 SET_CXOBJCPROP_ATTR(weak);
6809 SET_CXOBJCPROP_ATTR(strong);
6810 SET_CXOBJCPROP_ATTR(unsafe_unretained);
6811#undef SET_CXOBJCPROP_ATTR
6812
6813 return Result;
6814}
6815
Argyrios Kyrtzidis9d9bc012013-04-18 23:29:12 +00006816unsigned clang_Cursor_getObjCDeclQualifiers(CXCursor C) {
6817 if (!clang_isDeclaration(C.kind))
6818 return CXObjCDeclQualifier_None;
6819
6820 Decl::ObjCDeclQualifier QT = Decl::OBJC_TQ_None;
6821 const Decl *D = getCursorDecl(C);
6822 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6823 QT = MD->getObjCDeclQualifier();
6824 else if (const ParmVarDecl *PD = dyn_cast<ParmVarDecl>(D))
6825 QT = PD->getObjCDeclQualifier();
6826 if (QT == Decl::OBJC_TQ_None)
6827 return CXObjCDeclQualifier_None;
6828
6829 unsigned Result = CXObjCDeclQualifier_None;
6830 if (QT & Decl::OBJC_TQ_In) Result |= CXObjCDeclQualifier_In;
6831 if (QT & Decl::OBJC_TQ_Inout) Result |= CXObjCDeclQualifier_Inout;
6832 if (QT & Decl::OBJC_TQ_Out) Result |= CXObjCDeclQualifier_Out;
6833 if (QT & Decl::OBJC_TQ_Bycopy) Result |= CXObjCDeclQualifier_Bycopy;
6834 if (QT & Decl::OBJC_TQ_Byref) Result |= CXObjCDeclQualifier_Byref;
6835 if (QT & Decl::OBJC_TQ_Oneway) Result |= CXObjCDeclQualifier_Oneway;
6836
6837 return Result;
6838}
6839
Argyrios Kyrtzidis7b50fc52013-07-05 20:44:37 +00006840unsigned clang_Cursor_isObjCOptional(CXCursor C) {
6841 if (!clang_isDeclaration(C.kind))
6842 return 0;
6843
6844 const Decl *D = getCursorDecl(C);
6845 if (const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(D))
6846 return PD->getPropertyImplementation() == ObjCPropertyDecl::Optional;
6847 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6848 return MD->getImplementationControl() == ObjCMethodDecl::Optional;
6849
6850 return 0;
6851}
6852
Argyrios Kyrtzidis23814e42013-04-18 23:53:05 +00006853unsigned clang_Cursor_isVariadic(CXCursor C) {
6854 if (!clang_isDeclaration(C.kind))
6855 return 0;
6856
6857 const Decl *D = getCursorDecl(C);
6858 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
6859 return FD->isVariadic();
6860 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6861 return MD->isVariadic();
6862
6863 return 0;
6864}
6865
Guy Benyei11169dd2012-12-18 14:30:41 +00006866CXSourceRange clang_Cursor_getCommentRange(CXCursor C) {
6867 if (!clang_isDeclaration(C.kind))
6868 return clang_getNullRange();
6869
6870 const Decl *D = getCursorDecl(C);
6871 ASTContext &Context = getCursorContext(C);
6872 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6873 if (!RC)
6874 return clang_getNullRange();
6875
6876 return cxloc::translateSourceRange(Context, RC->getSourceRange());
6877}
6878
6879CXString clang_Cursor_getRawCommentText(CXCursor C) {
6880 if (!clang_isDeclaration(C.kind))
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006881 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006882
6883 const Decl *D = getCursorDecl(C);
6884 ASTContext &Context = getCursorContext(C);
6885 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6886 StringRef RawText = RC ? RC->getRawText(Context.getSourceManager()) :
6887 StringRef();
6888
6889 // Don't duplicate the string because RawText points directly into source
6890 // code.
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006891 return cxstring::createRef(RawText);
Guy Benyei11169dd2012-12-18 14:30:41 +00006892}
6893
6894CXString clang_Cursor_getBriefCommentText(CXCursor C) {
6895 if (!clang_isDeclaration(C.kind))
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006896 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006897
6898 const Decl *D = getCursorDecl(C);
6899 const ASTContext &Context = getCursorContext(C);
6900 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6901
6902 if (RC) {
6903 StringRef BriefText = RC->getBriefText(Context);
6904
6905 // Don't duplicate the string because RawComment ensures that this memory
6906 // will not go away.
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006907 return cxstring::createRef(BriefText);
Guy Benyei11169dd2012-12-18 14:30:41 +00006908 }
6909
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006910 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006911}
6912
Guy Benyei11169dd2012-12-18 14:30:41 +00006913CXModule clang_Cursor_getModule(CXCursor C) {
6914 if (C.kind == CXCursor_ModuleImportDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006915 if (const ImportDecl *ImportD =
6916 dyn_cast_or_null<ImportDecl>(getCursorDecl(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00006917 return ImportD->getImportedModule();
6918 }
6919
Craig Topper69186e72014-06-08 08:38:04 +00006920 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006921}
6922
Argyrios Kyrtzidisf6d49c32014-05-14 23:14:37 +00006923CXModule clang_getModuleForFile(CXTranslationUnit TU, CXFile File) {
6924 if (isNotUsableTU(TU)) {
6925 LOG_BAD_TU(TU);
6926 return nullptr;
6927 }
6928 if (!File)
6929 return nullptr;
6930 FileEntry *FE = static_cast<FileEntry *>(File);
6931
6932 ASTUnit &Unit = *cxtu::getASTUnit(TU);
6933 HeaderSearch &HS = Unit.getPreprocessor().getHeaderSearchInfo();
6934 ModuleMap::KnownHeader Header = HS.findModuleForHeader(FE);
6935
Richard Smithfeb54b62014-10-23 02:01:19 +00006936 return Header.getModule();
Argyrios Kyrtzidisf6d49c32014-05-14 23:14:37 +00006937}
6938
Argyrios Kyrtzidis12fdb9e2013-04-26 22:47:49 +00006939CXFile clang_Module_getASTFile(CXModule CXMod) {
6940 if (!CXMod)
Craig Topper69186e72014-06-08 08:38:04 +00006941 return nullptr;
Argyrios Kyrtzidis12fdb9e2013-04-26 22:47:49 +00006942 Module *Mod = static_cast<Module*>(CXMod);
6943 return const_cast<FileEntry *>(Mod->getASTFile());
6944}
6945
Guy Benyei11169dd2012-12-18 14:30:41 +00006946CXModule clang_Module_getParent(CXModule CXMod) {
6947 if (!CXMod)
Craig Topper69186e72014-06-08 08:38:04 +00006948 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006949 Module *Mod = static_cast<Module*>(CXMod);
6950 return Mod->Parent;
6951}
6952
6953CXString clang_Module_getName(CXModule CXMod) {
6954 if (!CXMod)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006955 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006956 Module *Mod = static_cast<Module*>(CXMod);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006957 return cxstring::createDup(Mod->Name);
Guy Benyei11169dd2012-12-18 14:30:41 +00006958}
6959
6960CXString clang_Module_getFullName(CXModule CXMod) {
6961 if (!CXMod)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006962 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006963 Module *Mod = static_cast<Module*>(CXMod);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006964 return cxstring::createDup(Mod->getFullModuleName());
Guy Benyei11169dd2012-12-18 14:30:41 +00006965}
6966
Argyrios Kyrtzidis884337f2014-05-15 04:44:25 +00006967int clang_Module_isSystem(CXModule CXMod) {
6968 if (!CXMod)
6969 return 0;
6970 Module *Mod = static_cast<Module*>(CXMod);
6971 return Mod->IsSystem;
6972}
6973
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006974unsigned clang_Module_getNumTopLevelHeaders(CXTranslationUnit TU,
6975 CXModule CXMod) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006976 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006977 LOG_BAD_TU(TU);
6978 return 0;
6979 }
6980 if (!CXMod)
Guy Benyei11169dd2012-12-18 14:30:41 +00006981 return 0;
6982 Module *Mod = static_cast<Module*>(CXMod);
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006983 FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
6984 ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
6985 return TopHeaders.size();
Guy Benyei11169dd2012-12-18 14:30:41 +00006986}
6987
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006988CXFile clang_Module_getTopLevelHeader(CXTranslationUnit TU,
6989 CXModule CXMod, unsigned Index) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006990 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006991 LOG_BAD_TU(TU);
Craig Topper69186e72014-06-08 08:38:04 +00006992 return nullptr;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006993 }
6994 if (!CXMod)
Craig Topper69186e72014-06-08 08:38:04 +00006995 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006996 Module *Mod = static_cast<Module*>(CXMod);
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006997 FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
Guy Benyei11169dd2012-12-18 14:30:41 +00006998
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006999 ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
7000 if (Index < TopHeaders.size())
7001 return const_cast<FileEntry *>(TopHeaders[Index]);
Guy Benyei11169dd2012-12-18 14:30:41 +00007002
Craig Topper69186e72014-06-08 08:38:04 +00007003 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00007004}
7005
7006} // end: extern "C"
7007
7008//===----------------------------------------------------------------------===//
7009// C++ AST instrospection.
7010//===----------------------------------------------------------------------===//
7011
7012extern "C" {
Saleem Abdulrasool6ea75db2015-10-27 15:50:22 +00007013unsigned clang_CXXField_isMutable(CXCursor C) {
7014 if (!clang_isDeclaration(C.kind))
7015 return 0;
7016
7017 if (const auto D = cxcursor::getCursorDecl(C))
7018 if (const auto FD = dyn_cast_or_null<FieldDecl>(D))
7019 return FD->isMutable() ? 1 : 0;
7020 return 0;
7021}
7022
Dmitri Gribenko62770be2013-05-17 18:38:35 +00007023unsigned clang_CXXMethod_isPureVirtual(CXCursor C) {
7024 if (!clang_isDeclaration(C.kind))
7025 return 0;
7026
Dmitri Gribenko62770be2013-05-17 18:38:35 +00007027 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00007028 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00007029 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Dmitri Gribenko62770be2013-05-17 18:38:35 +00007030 return (Method && Method->isVirtual() && Method->isPure()) ? 1 : 0;
7031}
7032
Dmitri Gribenkoe570ede2014-04-07 14:59:13 +00007033unsigned clang_CXXMethod_isConst(CXCursor C) {
7034 if (!clang_isDeclaration(C.kind))
7035 return 0;
7036
7037 const Decl *D = cxcursor::getCursorDecl(C);
7038 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00007039 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Dmitri Gribenkoe570ede2014-04-07 14:59:13 +00007040 return (Method && (Method->getTypeQualifiers() & Qualifiers::Const)) ? 1 : 0;
7041}
7042
Guy Benyei11169dd2012-12-18 14:30:41 +00007043unsigned clang_CXXMethod_isStatic(CXCursor C) {
7044 if (!clang_isDeclaration(C.kind))
7045 return 0;
7046
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00007047 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00007048 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00007049 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00007050 return (Method && Method->isStatic()) ? 1 : 0;
7051}
7052
7053unsigned clang_CXXMethod_isVirtual(CXCursor C) {
7054 if (!clang_isDeclaration(C.kind))
7055 return 0;
7056
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00007057 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00007058 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00007059 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00007060 return (Method && Method->isVirtual()) ? 1 : 0;
7061}
7062} // end: extern "C"
7063
7064//===----------------------------------------------------------------------===//
7065// Attribute introspection.
7066//===----------------------------------------------------------------------===//
7067
7068extern "C" {
7069CXType clang_getIBOutletCollectionType(CXCursor C) {
7070 if (C.kind != CXCursor_IBOutletCollectionAttr)
7071 return cxtype::MakeCXType(QualType(), cxcursor::getCursorTU(C));
7072
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00007073 const IBOutletCollectionAttr *A =
Guy Benyei11169dd2012-12-18 14:30:41 +00007074 cast<IBOutletCollectionAttr>(cxcursor::getCursorAttr(C));
7075
7076 return cxtype::MakeCXType(A->getInterface(), cxcursor::getCursorTU(C));
7077}
7078} // end: extern "C"
7079
7080//===----------------------------------------------------------------------===//
7081// Inspecting memory usage.
7082//===----------------------------------------------------------------------===//
7083
7084typedef std::vector<CXTUResourceUsageEntry> MemUsageEntries;
7085
7086static inline void createCXTUResourceUsageEntry(MemUsageEntries &entries,
7087 enum CXTUResourceUsageKind k,
7088 unsigned long amount) {
7089 CXTUResourceUsageEntry entry = { k, amount };
7090 entries.push_back(entry);
7091}
7092
7093extern "C" {
7094
7095const char *clang_getTUResourceUsageName(CXTUResourceUsageKind kind) {
7096 const char *str = "";
7097 switch (kind) {
7098 case CXTUResourceUsage_AST:
7099 str = "ASTContext: expressions, declarations, and types";
7100 break;
7101 case CXTUResourceUsage_Identifiers:
7102 str = "ASTContext: identifiers";
7103 break;
7104 case CXTUResourceUsage_Selectors:
7105 str = "ASTContext: selectors";
7106 break;
7107 case CXTUResourceUsage_GlobalCompletionResults:
7108 str = "Code completion: cached global results";
7109 break;
7110 case CXTUResourceUsage_SourceManagerContentCache:
7111 str = "SourceManager: content cache allocator";
7112 break;
7113 case CXTUResourceUsage_AST_SideTables:
7114 str = "ASTContext: side tables";
7115 break;
7116 case CXTUResourceUsage_SourceManager_Membuffer_Malloc:
7117 str = "SourceManager: malloc'ed memory buffers";
7118 break;
7119 case CXTUResourceUsage_SourceManager_Membuffer_MMap:
7120 str = "SourceManager: mmap'ed memory buffers";
7121 break;
7122 case CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc:
7123 str = "ExternalASTSource: malloc'ed memory buffers";
7124 break;
7125 case CXTUResourceUsage_ExternalASTSource_Membuffer_MMap:
7126 str = "ExternalASTSource: mmap'ed memory buffers";
7127 break;
7128 case CXTUResourceUsage_Preprocessor:
7129 str = "Preprocessor: malloc'ed memory";
7130 break;
7131 case CXTUResourceUsage_PreprocessingRecord:
7132 str = "Preprocessor: PreprocessingRecord";
7133 break;
7134 case CXTUResourceUsage_SourceManager_DataStructures:
7135 str = "SourceManager: data structures and tables";
7136 break;
7137 case CXTUResourceUsage_Preprocessor_HeaderSearch:
7138 str = "Preprocessor: header search tables";
7139 break;
7140 }
7141 return str;
7142}
7143
7144CXTUResourceUsage clang_getCXTUResourceUsage(CXTranslationUnit TU) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00007145 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00007146 LOG_BAD_TU(TU);
Craig Topper69186e72014-06-08 08:38:04 +00007147 CXTUResourceUsage usage = { (void*) nullptr, 0, nullptr };
Guy Benyei11169dd2012-12-18 14:30:41 +00007148 return usage;
7149 }
7150
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007151 ASTUnit *astUnit = cxtu::getASTUnit(TU);
Ahmed Charlesb8984322014-03-07 20:03:18 +00007152 std::unique_ptr<MemUsageEntries> entries(new MemUsageEntries());
Guy Benyei11169dd2012-12-18 14:30:41 +00007153 ASTContext &astContext = astUnit->getASTContext();
7154
7155 // How much memory is used by AST nodes and types?
7156 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST,
7157 (unsigned long) astContext.getASTAllocatedMemory());
7158
7159 // How much memory is used by identifiers?
7160 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Identifiers,
7161 (unsigned long) astContext.Idents.getAllocator().getTotalMemory());
7162
7163 // How much memory is used for selectors?
7164 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Selectors,
7165 (unsigned long) astContext.Selectors.getTotalMemory());
7166
7167 // How much memory is used by ASTContext's side tables?
7168 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST_SideTables,
7169 (unsigned long) astContext.getSideTableAllocatedMemory());
7170
7171 // How much memory is used for caching global code completion results?
7172 unsigned long completionBytes = 0;
7173 if (GlobalCodeCompletionAllocator *completionAllocator =
Alp Tokerf994cef2014-07-05 03:08:06 +00007174 astUnit->getCachedCompletionAllocator().get()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00007175 completionBytes = completionAllocator->getTotalMemory();
7176 }
7177 createCXTUResourceUsageEntry(*entries,
7178 CXTUResourceUsage_GlobalCompletionResults,
7179 completionBytes);
7180
7181 // How much memory is being used by SourceManager's content cache?
7182 createCXTUResourceUsageEntry(*entries,
7183 CXTUResourceUsage_SourceManagerContentCache,
7184 (unsigned long) astContext.getSourceManager().getContentCacheSize());
7185
7186 // How much memory is being used by the MemoryBuffer's in SourceManager?
7187 const SourceManager::MemoryBufferSizes &srcBufs =
7188 astUnit->getSourceManager().getMemoryBufferSizes();
7189
7190 createCXTUResourceUsageEntry(*entries,
7191 CXTUResourceUsage_SourceManager_Membuffer_Malloc,
7192 (unsigned long) srcBufs.malloc_bytes);
7193 createCXTUResourceUsageEntry(*entries,
7194 CXTUResourceUsage_SourceManager_Membuffer_MMap,
7195 (unsigned long) srcBufs.mmap_bytes);
7196 createCXTUResourceUsageEntry(*entries,
7197 CXTUResourceUsage_SourceManager_DataStructures,
7198 (unsigned long) astContext.getSourceManager()
7199 .getDataStructureSizes());
7200
7201 // How much memory is being used by the ExternalASTSource?
7202 if (ExternalASTSource *esrc = astContext.getExternalSource()) {
7203 const ExternalASTSource::MemoryBufferSizes &sizes =
7204 esrc->getMemoryBufferSizes();
7205
7206 createCXTUResourceUsageEntry(*entries,
7207 CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc,
7208 (unsigned long) sizes.malloc_bytes);
7209 createCXTUResourceUsageEntry(*entries,
7210 CXTUResourceUsage_ExternalASTSource_Membuffer_MMap,
7211 (unsigned long) sizes.mmap_bytes);
7212 }
7213
7214 // How much memory is being used by the Preprocessor?
7215 Preprocessor &pp = astUnit->getPreprocessor();
7216 createCXTUResourceUsageEntry(*entries,
7217 CXTUResourceUsage_Preprocessor,
7218 pp.getTotalMemory());
7219
7220 if (PreprocessingRecord *pRec = pp.getPreprocessingRecord()) {
7221 createCXTUResourceUsageEntry(*entries,
7222 CXTUResourceUsage_PreprocessingRecord,
7223 pRec->getTotalMemory());
7224 }
7225
7226 createCXTUResourceUsageEntry(*entries,
7227 CXTUResourceUsage_Preprocessor_HeaderSearch,
7228 pp.getHeaderSearchInfo().getTotalMemory());
Craig Topper69186e72014-06-08 08:38:04 +00007229
Guy Benyei11169dd2012-12-18 14:30:41 +00007230 CXTUResourceUsage usage = { (void*) entries.get(),
7231 (unsigned) entries->size(),
Alexander Kornienko6ee521c2015-01-23 15:36:10 +00007232 !entries->empty() ? &(*entries)[0] : nullptr };
Ahmed Charles9a16beb2014-03-07 19:33:25 +00007233 entries.release();
Guy Benyei11169dd2012-12-18 14:30:41 +00007234 return usage;
7235}
7236
7237void clang_disposeCXTUResourceUsage(CXTUResourceUsage usage) {
7238 if (usage.data)
7239 delete (MemUsageEntries*) usage.data;
7240}
7241
Argyrios Kyrtzidis0e282ef2013-12-06 18:55:45 +00007242CXSourceRangeList *clang_getSkippedRanges(CXTranslationUnit TU, CXFile file) {
7243 CXSourceRangeList *skipped = new CXSourceRangeList;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00007244 skipped->count = 0;
Craig Topper69186e72014-06-08 08:38:04 +00007245 skipped->ranges = nullptr;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00007246
Dmitri Gribenko852d6222014-02-11 15:02:48 +00007247 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00007248 LOG_BAD_TU(TU);
7249 return skipped;
7250 }
7251
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00007252 if (!file)
7253 return skipped;
7254
7255 ASTUnit *astUnit = cxtu::getASTUnit(TU);
7256 PreprocessingRecord *ppRec = astUnit->getPreprocessor().getPreprocessingRecord();
7257 if (!ppRec)
7258 return skipped;
7259
7260 ASTContext &Ctx = astUnit->getASTContext();
7261 SourceManager &sm = Ctx.getSourceManager();
7262 FileEntry *fileEntry = static_cast<FileEntry *>(file);
7263 FileID wantedFileID = sm.translateFile(fileEntry);
7264
7265 const std::vector<SourceRange> &SkippedRanges = ppRec->getSkippedRanges();
7266 std::vector<SourceRange> wantedRanges;
7267 for (std::vector<SourceRange>::const_iterator i = SkippedRanges.begin(), ei = SkippedRanges.end();
7268 i != ei; ++i) {
7269 if (sm.getFileID(i->getBegin()) == wantedFileID || sm.getFileID(i->getEnd()) == wantedFileID)
7270 wantedRanges.push_back(*i);
7271 }
7272
7273 skipped->count = wantedRanges.size();
7274 skipped->ranges = new CXSourceRange[skipped->count];
7275 for (unsigned i = 0, ei = skipped->count; i != ei; ++i)
7276 skipped->ranges[i] = cxloc::translateSourceRange(Ctx, wantedRanges[i]);
7277
7278 return skipped;
7279}
7280
Argyrios Kyrtzidis0e282ef2013-12-06 18:55:45 +00007281void clang_disposeSourceRangeList(CXSourceRangeList *ranges) {
7282 if (ranges) {
7283 delete[] ranges->ranges;
7284 delete ranges;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00007285 }
7286}
7287
Guy Benyei11169dd2012-12-18 14:30:41 +00007288} // end extern "C"
7289
7290void clang::PrintLibclangResourceUsage(CXTranslationUnit TU) {
7291 CXTUResourceUsage Usage = clang_getCXTUResourceUsage(TU);
7292 for (unsigned I = 0; I != Usage.numEntries; ++I)
7293 fprintf(stderr, " %s: %lu\n",
7294 clang_getTUResourceUsageName(Usage.entries[I].kind),
7295 Usage.entries[I].amount);
7296
7297 clang_disposeCXTUResourceUsage(Usage);
7298}
7299
7300//===----------------------------------------------------------------------===//
7301// Misc. utility functions.
7302//===----------------------------------------------------------------------===//
7303
7304/// Default to using an 8 MB stack size on "safety" threads.
7305static unsigned SafetyStackThreadSize = 8 << 20;
7306
7307namespace clang {
7308
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00007309bool RunSafely(llvm::CrashRecoveryContext &CRC, llvm::function_ref<void()> Fn,
Guy Benyei11169dd2012-12-18 14:30:41 +00007310 unsigned Size) {
7311 if (!Size)
7312 Size = GetSafetyThreadStackSize();
7313 if (Size)
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00007314 return CRC.RunSafelyOnThread(Fn, Size);
7315 return CRC.RunSafely(Fn);
Guy Benyei11169dd2012-12-18 14:30:41 +00007316}
7317
7318unsigned GetSafetyThreadStackSize() {
7319 return SafetyStackThreadSize;
7320}
7321
7322void SetSafetyThreadStackSize(unsigned Value) {
7323 SafetyStackThreadSize = Value;
7324}
7325
Alexander Kornienkoab9db512015-06-22 23:07:51 +00007326}
Guy Benyei11169dd2012-12-18 14:30:41 +00007327
7328void clang::setThreadBackgroundPriority() {
7329 if (getenv("LIBCLANG_BGPRIO_DISABLE"))
7330 return;
7331
Alp Toker1a86ad22014-07-06 06:24:00 +00007332#ifdef USE_DARWIN_THREADS
Guy Benyei11169dd2012-12-18 14:30:41 +00007333 setpriority(PRIO_DARWIN_THREAD, 0, PRIO_DARWIN_BG);
7334#endif
7335}
7336
7337void cxindex::printDiagsToStderr(ASTUnit *Unit) {
7338 if (!Unit)
7339 return;
7340
7341 for (ASTUnit::stored_diag_iterator D = Unit->stored_diag_begin(),
7342 DEnd = Unit->stored_diag_end();
7343 D != DEnd; ++D) {
Ben Langmuir749323f2014-04-22 17:40:12 +00007344 CXStoredDiagnostic Diag(*D, Unit->getLangOpts());
Guy Benyei11169dd2012-12-18 14:30:41 +00007345 CXString Msg = clang_formatDiagnostic(&Diag,
7346 clang_defaultDiagnosticDisplayOptions());
7347 fprintf(stderr, "%s\n", clang_getCString(Msg));
7348 clang_disposeString(Msg);
7349 }
7350#ifdef LLVM_ON_WIN32
7351 // On Windows, force a flush, since there may be multiple copies of
7352 // stderr and stdout in the file system, all with different buffers
7353 // but writing to the same device.
7354 fflush(stderr);
7355#endif
7356}
7357
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007358MacroInfo *cxindex::getMacroInfo(const IdentifierInfo &II,
7359 SourceLocation MacroDefLoc,
7360 CXTranslationUnit TU){
7361 if (MacroDefLoc.isInvalid() || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00007362 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007363 if (!II.hadMacroDefinition())
Craig Topper69186e72014-06-08 08:38:04 +00007364 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007365
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007366 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00007367 Preprocessor &PP = Unit->getPreprocessor();
Richard Smith20e883e2015-04-29 23:20:19 +00007368 MacroDirective *MD = PP.getLocalMacroDirectiveHistory(&II);
Argyrios Kyrtzidisb6210df2013-03-26 17:17:01 +00007369 if (MD) {
7370 for (MacroDirective::DefInfo
7371 Def = MD->getDefinition(); Def; Def = Def.getPreviousDefinition()) {
7372 if (MacroDefLoc == Def.getMacroInfo()->getDefinitionLoc())
7373 return Def.getMacroInfo();
7374 }
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007375 }
7376
Craig Topper69186e72014-06-08 08:38:04 +00007377 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007378}
7379
Richard Smith66a81862015-05-04 02:25:31 +00007380const MacroInfo *cxindex::getMacroInfo(const MacroDefinitionRecord *MacroDef,
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00007381 CXTranslationUnit TU) {
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007382 if (!MacroDef || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00007383 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007384 const IdentifierInfo *II = MacroDef->getName();
7385 if (!II)
Craig Topper69186e72014-06-08 08:38:04 +00007386 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007387
7388 return getMacroInfo(*II, MacroDef->getLocation(), TU);
7389}
7390
Richard Smith66a81862015-05-04 02:25:31 +00007391MacroDefinitionRecord *
7392cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI, const Token &Tok,
7393 CXTranslationUnit TU) {
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007394 if (!MI || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00007395 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007396 if (Tok.isNot(tok::raw_identifier))
Craig Topper69186e72014-06-08 08:38:04 +00007397 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007398
7399 if (MI->getNumTokens() == 0)
Craig Topper69186e72014-06-08 08:38:04 +00007400 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007401 SourceRange DefRange(MI->getReplacementToken(0).getLocation(),
7402 MI->getDefinitionEndLoc());
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007403 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007404
7405 // Check that the token is inside the definition and not its argument list.
7406 SourceManager &SM = Unit->getSourceManager();
7407 if (SM.isBeforeInTranslationUnit(Tok.getLocation(), DefRange.getBegin()))
Craig Topper69186e72014-06-08 08:38:04 +00007408 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007409 if (SM.isBeforeInTranslationUnit(DefRange.getEnd(), Tok.getLocation()))
Craig Topper69186e72014-06-08 08:38:04 +00007410 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007411
7412 Preprocessor &PP = Unit->getPreprocessor();
7413 PreprocessingRecord *PPRec = PP.getPreprocessingRecord();
7414 if (!PPRec)
Craig Topper69186e72014-06-08 08:38:04 +00007415 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007416
Alp Toker2d57cea2014-05-17 04:53:25 +00007417 IdentifierInfo &II = PP.getIdentifierTable().get(Tok.getRawIdentifier());
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007418 if (!II.hadMacroDefinition())
Craig Topper69186e72014-06-08 08:38:04 +00007419 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007420
7421 // Check that the identifier is not one of the macro arguments.
7422 if (std::find(MI->arg_begin(), MI->arg_end(), &II) != MI->arg_end())
Craig Topper69186e72014-06-08 08:38:04 +00007423 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007424
Richard Smith20e883e2015-04-29 23:20:19 +00007425 MacroDirective *InnerMD = PP.getLocalMacroDirectiveHistory(&II);
Argyrios Kyrtzidis09c9e812013-02-20 00:54:57 +00007426 if (!InnerMD)
Craig Topper69186e72014-06-08 08:38:04 +00007427 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007428
Argyrios Kyrtzidisb6210df2013-03-26 17:17:01 +00007429 return PPRec->findMacroDefinition(InnerMD->getMacroInfo());
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007430}
7431
Richard Smith66a81862015-05-04 02:25:31 +00007432MacroDefinitionRecord *
7433cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI, SourceLocation Loc,
7434 CXTranslationUnit TU) {
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007435 if (Loc.isInvalid() || !MI || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00007436 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007437
7438 if (MI->getNumTokens() == 0)
Craig Topper69186e72014-06-08 08:38:04 +00007439 return nullptr;
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007440 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007441 Preprocessor &PP = Unit->getPreprocessor();
7442 if (!PP.getPreprocessingRecord())
Craig Topper69186e72014-06-08 08:38:04 +00007443 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007444 Loc = Unit->getSourceManager().getSpellingLoc(Loc);
7445 Token Tok;
7446 if (PP.getRawToken(Loc, Tok))
Craig Topper69186e72014-06-08 08:38:04 +00007447 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007448
7449 return checkForMacroInMacroDefinition(MI, Tok, TU);
7450}
7451
Guy Benyei11169dd2012-12-18 14:30:41 +00007452extern "C" {
7453
7454CXString clang_getClangVersion() {
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00007455 return cxstring::createDup(getClangFullVersion());
Guy Benyei11169dd2012-12-18 14:30:41 +00007456}
7457
7458} // end: extern "C"
7459
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007460Logger &cxindex::Logger::operator<<(CXTranslationUnit TU) {
7461 if (TU) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007462 if (ASTUnit *Unit = cxtu::getASTUnit(TU)) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007463 LogOS << '<' << Unit->getMainFileName() << '>';
Argyrios Kyrtzidis37f2ab42013-03-05 20:21:14 +00007464 if (Unit->isMainFileAST())
7465 LogOS << " (" << Unit->getASTFileName() << ')';
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007466 return *this;
7467 }
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00007468 } else {
7469 LogOS << "<NULL TU>";
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007470 }
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007471 return *this;
7472}
7473
Argyrios Kyrtzidisba4b5f82013-03-08 02:32:26 +00007474Logger &cxindex::Logger::operator<<(const FileEntry *FE) {
7475 *this << FE->getName();
7476 return *this;
7477}
7478
7479Logger &cxindex::Logger::operator<<(CXCursor cursor) {
7480 CXString cursorName = clang_getCursorDisplayName(cursor);
7481 *this << cursorName << "@" << clang_getCursorLocation(cursor);
7482 clang_disposeString(cursorName);
7483 return *this;
7484}
7485
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007486Logger &cxindex::Logger::operator<<(CXSourceLocation Loc) {
7487 CXFile File;
7488 unsigned Line, Column;
Craig Topper69186e72014-06-08 08:38:04 +00007489 clang_getFileLocation(Loc, &File, &Line, &Column, nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007490 CXString FileName = clang_getFileName(File);
7491 *this << llvm::format("(%s:%d:%d)", clang_getCString(FileName), Line, Column);
7492 clang_disposeString(FileName);
7493 return *this;
7494}
7495
7496Logger &cxindex::Logger::operator<<(CXSourceRange range) {
7497 CXSourceLocation BLoc = clang_getRangeStart(range);
7498 CXSourceLocation ELoc = clang_getRangeEnd(range);
7499
7500 CXFile BFile;
7501 unsigned BLine, BColumn;
Craig Topper69186e72014-06-08 08:38:04 +00007502 clang_getFileLocation(BLoc, &BFile, &BLine, &BColumn, nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007503
7504 CXFile EFile;
7505 unsigned ELine, EColumn;
Craig Topper69186e72014-06-08 08:38:04 +00007506 clang_getFileLocation(ELoc, &EFile, &ELine, &EColumn, nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007507
7508 CXString BFileName = clang_getFileName(BFile);
7509 if (BFile == EFile) {
7510 *this << llvm::format("[%s %d:%d-%d:%d]", clang_getCString(BFileName),
7511 BLine, BColumn, ELine, EColumn);
7512 } else {
7513 CXString EFileName = clang_getFileName(EFile);
7514 *this << llvm::format("[%s:%d:%d - ", clang_getCString(BFileName),
7515 BLine, BColumn)
7516 << llvm::format("%s:%d:%d]", clang_getCString(EFileName),
7517 ELine, EColumn);
7518 clang_disposeString(EFileName);
7519 }
7520 clang_disposeString(BFileName);
7521 return *this;
7522}
7523
7524Logger &cxindex::Logger::operator<<(CXString Str) {
7525 *this << clang_getCString(Str);
7526 return *this;
7527}
7528
7529Logger &cxindex::Logger::operator<<(const llvm::format_object_base &Fmt) {
7530 LogOS << Fmt;
7531 return *this;
7532}
7533
Chandler Carruth37ad2582014-06-27 15:14:39 +00007534static llvm::ManagedStatic<llvm::sys::Mutex> LoggingMutex;
7535
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007536cxindex::Logger::~Logger() {
Chandler Carruth37ad2582014-06-27 15:14:39 +00007537 llvm::sys::ScopedLock L(*LoggingMutex);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007538
7539 static llvm::TimeRecord sBeginTR = llvm::TimeRecord::getCurrentTime();
7540
Dmitri Gribenkof8579502013-01-12 19:30:44 +00007541 raw_ostream &OS = llvm::errs();
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007542 OS << "[libclang:" << Name << ':';
7543
Alp Toker1a86ad22014-07-06 06:24:00 +00007544#ifdef USE_DARWIN_THREADS
7545 // TODO: Portability.
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007546 mach_port_t tid = pthread_mach_thread_np(pthread_self());
7547 OS << tid << ':';
7548#endif
7549
7550 llvm::TimeRecord TR = llvm::TimeRecord::getCurrentTime();
7551 OS << llvm::format("%7.4f] ", TR.getWallTime() - sBeginTR.getWallTime());
Yaron Keren09fb7c62015-03-10 07:33:23 +00007552 OS << Msg << '\n';
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007553
7554 if (Trace) {
Zachary Turner1fe2a8d2015-03-05 19:15:09 +00007555 llvm::sys::PrintStackTrace(OS);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007556 OS << "--------------------------------------------------\n";
7557 }
7558}