blob: 7fbe6471ff9adca5da0ef0add767010f3ae24235 [file] [log] [blame]
Guy Benyei11169dd2012-12-18 14:30:41 +00001//===- CIndex.cpp - Clang-C Source Indexing Library -----------------------===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file implements the main API hooks in the Clang-C Source Indexing
11// library.
12//
13//===----------------------------------------------------------------------===//
14
15#include "CIndexer.h"
16#include "CIndexDiagnostic.h"
Chandler Carruth4b417452013-01-19 08:09:44 +000017#include "CLog.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000018#include "CXCursor.h"
19#include "CXSourceLocation.h"
20#include "CXString.h"
21#include "CXTranslationUnit.h"
22#include "CXType.h"
23#include "CursorVisitor.h"
David Blaikie0a4e61f2013-09-13 18:32:52 +000024#include "clang/AST/Attr.h"
Eli Bendersky44a206f2014-07-31 18:04:56 +000025#include "clang/AST/Mangle.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000026#include "clang/AST/StmtVisitor.h"
27#include "clang/Basic/Diagnostic.h"
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +000028#include "clang/Basic/DiagnosticCategories.h"
29#include "clang/Basic/DiagnosticIDs.h"
Eli Bendersky79759592014-08-01 15:01:10 +000030#include "clang/Basic/TargetInfo.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000031#include "clang/Basic/Version.h"
32#include "clang/Frontend/ASTUnit.h"
33#include "clang/Frontend/CompilerInstance.h"
34#include "clang/Frontend/FrontendDiagnostic.h"
Dmitri Gribenko9e605112013-11-13 22:16:51 +000035#include "clang/Index/CommentToXML.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000036#include "clang/Lex/HeaderSearch.h"
37#include "clang/Lex/Lexer.h"
38#include "clang/Lex/PreprocessingRecord.h"
39#include "clang/Lex/Preprocessor.h"
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +000040#include "clang/Serialization/SerializationDiagnostic.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000041#include "llvm/ADT/Optional.h"
42#include "llvm/ADT/STLExtras.h"
43#include "llvm/ADT/StringSwitch.h"
Alp Toker1d257e12014-06-04 03:28:55 +000044#include "llvm/Config/llvm-config.h"
Eli Bendersky79759592014-08-01 15:01:10 +000045#include "llvm/IR/DataLayout.h"
46#include "llvm/IR/Mangler.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000047#include "llvm/Support/Compiler.h"
48#include "llvm/Support/CrashRecoveryContext.h"
Chandler Carruth4b417452013-01-19 08:09:44 +000049#include "llvm/Support/Format.h"
Chandler Carruth37ad2582014-06-27 15:14:39 +000050#include "llvm/Support/ManagedStatic.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000051#include "llvm/Support/MemoryBuffer.h"
52#include "llvm/Support/Mutex.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000053#include "llvm/Support/Program.h"
54#include "llvm/Support/SaveAndRestore.h"
55#include "llvm/Support/Signals.h"
Adrian Prantlbc068582015-07-08 01:00:30 +000056#include "llvm/Support/TargetSelect.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000057#include "llvm/Support/Threading.h"
58#include "llvm/Support/Timer.h"
59#include "llvm/Support/raw_ostream.h"
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +000060
Alp Toker1a86ad22014-07-06 06:24:00 +000061#if LLVM_ENABLE_THREADS != 0 && defined(__APPLE__)
62#define USE_DARWIN_THREADS
63#endif
64
65#ifdef USE_DARWIN_THREADS
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +000066#include <pthread.h>
67#endif
Guy Benyei11169dd2012-12-18 14:30:41 +000068
69using namespace clang;
70using namespace clang::cxcursor;
Guy Benyei11169dd2012-12-18 14:30:41 +000071using namespace clang::cxtu;
72using namespace clang::cxindex;
73
Dmitri Gribenkod36209e2013-01-26 21:32:42 +000074CXTranslationUnit cxtu::MakeCXTranslationUnit(CIndexer *CIdx, ASTUnit *AU) {
75 if (!AU)
Craig Topper69186e72014-06-08 08:38:04 +000076 return nullptr;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +000077 assert(CIdx);
Guy Benyei11169dd2012-12-18 14:30:41 +000078 CXTranslationUnit D = new CXTranslationUnitImpl();
79 D->CIdx = CIdx;
Dmitri Gribenkod36209e2013-01-26 21:32:42 +000080 D->TheASTUnit = AU;
Dmitri Gribenko74895212013-02-03 13:52:47 +000081 D->StringPool = new cxstring::CXStringPool();
Craig Topper69186e72014-06-08 08:38:04 +000082 D->Diagnostics = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +000083 D->OverridenCursorsPool = createOverridenCXCursorsPool();
Craig Topper69186e72014-06-08 08:38:04 +000084 D->CommentToXML = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +000085 return D;
86}
87
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +000088bool cxtu::isASTReadError(ASTUnit *AU) {
89 for (ASTUnit::stored_diag_iterator D = AU->stored_diag_begin(),
90 DEnd = AU->stored_diag_end();
91 D != DEnd; ++D) {
92 if (D->getLevel() >= DiagnosticsEngine::Error &&
93 DiagnosticIDs::getCategoryNumberForDiag(D->getID()) ==
94 diag::DiagCat_AST_Deserialization_Issue)
95 return true;
96 }
97 return false;
98}
99
Guy Benyei11169dd2012-12-18 14:30:41 +0000100cxtu::CXTUOwner::~CXTUOwner() {
101 if (TU)
102 clang_disposeTranslationUnit(TU);
103}
104
105/// \brief Compare two source ranges to determine their relative position in
106/// the translation unit.
107static RangeComparisonResult RangeCompare(SourceManager &SM,
108 SourceRange R1,
109 SourceRange R2) {
110 assert(R1.isValid() && "First range is invalid?");
111 assert(R2.isValid() && "Second range is invalid?");
112 if (R1.getEnd() != R2.getBegin() &&
113 SM.isBeforeInTranslationUnit(R1.getEnd(), R2.getBegin()))
114 return RangeBefore;
115 if (R2.getEnd() != R1.getBegin() &&
116 SM.isBeforeInTranslationUnit(R2.getEnd(), R1.getBegin()))
117 return RangeAfter;
118 return RangeOverlap;
119}
120
121/// \brief Determine if a source location falls within, before, or after a
122/// a given source range.
123static RangeComparisonResult LocationCompare(SourceManager &SM,
124 SourceLocation L, SourceRange R) {
125 assert(R.isValid() && "First range is invalid?");
126 assert(L.isValid() && "Second range is invalid?");
127 if (L == R.getBegin() || L == R.getEnd())
128 return RangeOverlap;
129 if (SM.isBeforeInTranslationUnit(L, R.getBegin()))
130 return RangeBefore;
131 if (SM.isBeforeInTranslationUnit(R.getEnd(), L))
132 return RangeAfter;
133 return RangeOverlap;
134}
135
136/// \brief Translate a Clang source range into a CIndex source range.
137///
138/// Clang internally represents ranges where the end location points to the
139/// start of the token at the end. However, for external clients it is more
140/// useful to have a CXSourceRange be a proper half-open interval. This routine
141/// does the appropriate translation.
142CXSourceRange cxloc::translateSourceRange(const SourceManager &SM,
143 const LangOptions &LangOpts,
144 const CharSourceRange &R) {
145 // We want the last character in this location, so we will adjust the
146 // location accordingly.
147 SourceLocation EndLoc = R.getEnd();
148 if (EndLoc.isValid() && EndLoc.isMacroID() && !SM.isMacroArgExpansion(EndLoc))
149 EndLoc = SM.getExpansionRange(EndLoc).second;
Yaron Keren8b563662015-10-03 10:46:20 +0000150 if (R.isTokenRange() && EndLoc.isValid()) {
Guy Benyei11169dd2012-12-18 14:30:41 +0000151 unsigned Length = Lexer::MeasureTokenLength(SM.getSpellingLoc(EndLoc),
152 SM, LangOpts);
153 EndLoc = EndLoc.getLocWithOffset(Length);
154 }
155
Bill Wendlingeade3622013-01-23 08:25:41 +0000156 CXSourceRange Result = {
Dmitri Gribenkof9304482013-01-23 15:56:07 +0000157 { &SM, &LangOpts },
Bill Wendlingeade3622013-01-23 08:25:41 +0000158 R.getBegin().getRawEncoding(),
159 EndLoc.getRawEncoding()
160 };
Guy Benyei11169dd2012-12-18 14:30:41 +0000161 return Result;
162}
163
164//===----------------------------------------------------------------------===//
165// Cursor visitor.
166//===----------------------------------------------------------------------===//
167
168static SourceRange getRawCursorExtent(CXCursor C);
169static SourceRange getFullCursorExtent(CXCursor C, SourceManager &SrcMgr);
170
171
172RangeComparisonResult CursorVisitor::CompareRegionOfInterest(SourceRange R) {
173 return RangeCompare(AU->getSourceManager(), R, RegionOfInterest);
174}
175
176/// \brief Visit the given cursor and, if requested by the visitor,
177/// its children.
178///
179/// \param Cursor the cursor to visit.
180///
181/// \param CheckedRegionOfInterest if true, then the caller already checked
182/// that this cursor is within the region of interest.
183///
184/// \returns true if the visitation should be aborted, false if it
185/// should continue.
186bool CursorVisitor::Visit(CXCursor Cursor, bool CheckedRegionOfInterest) {
187 if (clang_isInvalid(Cursor.kind))
188 return false;
189
190 if (clang_isDeclaration(Cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +0000191 const Decl *D = getCursorDecl(Cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +0000192 if (!D) {
193 assert(0 && "Invalid declaration cursor");
194 return true; // abort.
195 }
196
197 // Ignore implicit declarations, unless it's an objc method because
198 // currently we should report implicit methods for properties when indexing.
199 if (D->isImplicit() && !isa<ObjCMethodDecl>(D))
200 return false;
201 }
202
203 // If we have a range of interest, and this cursor doesn't intersect with it,
204 // we're done.
205 if (RegionOfInterest.isValid() && !CheckedRegionOfInterest) {
206 SourceRange Range = getRawCursorExtent(Cursor);
207 if (Range.isInvalid() || CompareRegionOfInterest(Range))
208 return false;
209 }
210
211 switch (Visitor(Cursor, Parent, ClientData)) {
212 case CXChildVisit_Break:
213 return true;
214
215 case CXChildVisit_Continue:
216 return false;
217
218 case CXChildVisit_Recurse: {
219 bool ret = VisitChildren(Cursor);
220 if (PostChildrenVisitor)
221 if (PostChildrenVisitor(Cursor, ClientData))
222 return true;
223 return ret;
224 }
225 }
226
227 llvm_unreachable("Invalid CXChildVisitResult!");
228}
229
230static bool visitPreprocessedEntitiesInRange(SourceRange R,
231 PreprocessingRecord &PPRec,
232 CursorVisitor &Visitor) {
233 SourceManager &SM = Visitor.getASTUnit()->getSourceManager();
234 FileID FID;
235
236 if (!Visitor.shouldVisitIncludedEntities()) {
237 // If the begin/end of the range lie in the same FileID, do the optimization
238 // where we skip preprocessed entities that do not come from the same FileID.
239 FID = SM.getFileID(SM.getFileLoc(R.getBegin()));
240 if (FID != SM.getFileID(SM.getFileLoc(R.getEnd())))
241 FID = FileID();
242 }
243
Benjamin Kramerb4ef6682015-02-06 17:25:10 +0000244 const auto &Entities = PPRec.getPreprocessedEntitiesInRange(R);
245 return Visitor.visitPreprocessedEntities(Entities.begin(), Entities.end(),
Guy Benyei11169dd2012-12-18 14:30:41 +0000246 PPRec, FID);
247}
248
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000249bool CursorVisitor::visitFileRegion() {
Guy Benyei11169dd2012-12-18 14:30:41 +0000250 if (RegionOfInterest.isInvalid())
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000251 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000252
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +0000253 ASTUnit *Unit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +0000254 SourceManager &SM = Unit->getSourceManager();
255
256 std::pair<FileID, unsigned>
257 Begin = SM.getDecomposedLoc(SM.getFileLoc(RegionOfInterest.getBegin())),
258 End = SM.getDecomposedLoc(SM.getFileLoc(RegionOfInterest.getEnd()));
259
260 if (End.first != Begin.first) {
261 // If the end does not reside in the same file, try to recover by
262 // picking the end of the file of begin location.
263 End.first = Begin.first;
264 End.second = SM.getFileIDSize(Begin.first);
265 }
266
267 assert(Begin.first == End.first);
268 if (Begin.second > End.second)
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000269 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000270
271 FileID File = Begin.first;
272 unsigned Offset = Begin.second;
273 unsigned Length = End.second - Begin.second;
274
275 if (!VisitDeclsOnly && !VisitPreprocessorLast)
276 if (visitPreprocessedEntitiesInRegion())
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000277 return true; // visitation break.
Guy Benyei11169dd2012-12-18 14:30:41 +0000278
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000279 if (visitDeclsFromFileRegion(File, Offset, Length))
280 return true; // visitation break.
Guy Benyei11169dd2012-12-18 14:30:41 +0000281
282 if (!VisitDeclsOnly && VisitPreprocessorLast)
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000283 return visitPreprocessedEntitiesInRegion();
284
285 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000286}
287
288static bool isInLexicalContext(Decl *D, DeclContext *DC) {
289 if (!DC)
290 return false;
291
292 for (DeclContext *DeclDC = D->getLexicalDeclContext();
293 DeclDC; DeclDC = DeclDC->getLexicalParent()) {
294 if (DeclDC == DC)
295 return true;
296 }
297 return false;
298}
299
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000300bool CursorVisitor::visitDeclsFromFileRegion(FileID File,
Guy Benyei11169dd2012-12-18 14:30:41 +0000301 unsigned Offset, unsigned Length) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +0000302 ASTUnit *Unit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +0000303 SourceManager &SM = Unit->getSourceManager();
304 SourceRange Range = RegionOfInterest;
305
306 SmallVector<Decl *, 16> Decls;
307 Unit->findFileRegionDecls(File, Offset, Length, Decls);
308
309 // If we didn't find any file level decls for the file, try looking at the
310 // file that it was included from.
311 while (Decls.empty() || Decls.front()->isTopLevelDeclInObjCContainer()) {
312 bool Invalid = false;
313 const SrcMgr::SLocEntry &SLEntry = SM.getSLocEntry(File, &Invalid);
314 if (Invalid)
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000315 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000316
317 SourceLocation Outer;
318 if (SLEntry.isFile())
319 Outer = SLEntry.getFile().getIncludeLoc();
320 else
321 Outer = SLEntry.getExpansion().getExpansionLocStart();
322 if (Outer.isInvalid())
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000323 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000324
Benjamin Kramer867ea1d2014-03-02 13:01:17 +0000325 std::tie(File, Offset) = SM.getDecomposedExpansionLoc(Outer);
Guy Benyei11169dd2012-12-18 14:30:41 +0000326 Length = 0;
327 Unit->findFileRegionDecls(File, Offset, Length, Decls);
328 }
329
330 assert(!Decls.empty());
331
332 bool VisitedAtLeastOnce = false;
Craig Topper69186e72014-06-08 08:38:04 +0000333 DeclContext *CurDC = nullptr;
Craig Topper2341c0d2013-07-04 03:08:24 +0000334 SmallVectorImpl<Decl *>::iterator DIt = Decls.begin();
335 for (SmallVectorImpl<Decl *>::iterator DE = Decls.end(); DIt != DE; ++DIt) {
Guy Benyei11169dd2012-12-18 14:30:41 +0000336 Decl *D = *DIt;
337 if (D->getSourceRange().isInvalid())
338 continue;
339
340 if (isInLexicalContext(D, CurDC))
341 continue;
342
343 CurDC = dyn_cast<DeclContext>(D);
344
345 if (TagDecl *TD = dyn_cast<TagDecl>(D))
346 if (!TD->isFreeStanding())
347 continue;
348
349 RangeComparisonResult CompRes = RangeCompare(SM, D->getSourceRange(),Range);
350 if (CompRes == RangeBefore)
351 continue;
352 if (CompRes == RangeAfter)
353 break;
354
355 assert(CompRes == RangeOverlap);
356 VisitedAtLeastOnce = true;
357
358 if (isa<ObjCContainerDecl>(D)) {
359 FileDI_current = &DIt;
360 FileDE_current = DE;
361 } else {
Craig Topper69186e72014-06-08 08:38:04 +0000362 FileDI_current = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +0000363 }
364
365 if (Visit(MakeCXCursor(D, TU, Range), /*CheckedRegionOfInterest=*/true))
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000366 return true; // visitation break.
Guy Benyei11169dd2012-12-18 14:30:41 +0000367 }
368
369 if (VisitedAtLeastOnce)
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000370 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000371
372 // No Decls overlapped with the range. Move up the lexical context until there
373 // is a context that contains the range or we reach the translation unit
374 // level.
375 DeclContext *DC = DIt == Decls.begin() ? (*DIt)->getLexicalDeclContext()
376 : (*(DIt-1))->getLexicalDeclContext();
377
378 while (DC && !DC->isTranslationUnit()) {
379 Decl *D = cast<Decl>(DC);
380 SourceRange CurDeclRange = D->getSourceRange();
381 if (CurDeclRange.isInvalid())
382 break;
383
384 if (RangeCompare(SM, CurDeclRange, Range) == RangeOverlap) {
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000385 if (Visit(MakeCXCursor(D, TU, Range), /*CheckedRegionOfInterest=*/true))
386 return true; // visitation break.
Guy Benyei11169dd2012-12-18 14:30:41 +0000387 }
388
389 DC = D->getLexicalDeclContext();
390 }
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000391
392 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000393}
394
395bool CursorVisitor::visitPreprocessedEntitiesInRegion() {
396 if (!AU->getPreprocessor().getPreprocessingRecord())
397 return false;
398
399 PreprocessingRecord &PPRec
400 = *AU->getPreprocessor().getPreprocessingRecord();
401 SourceManager &SM = AU->getSourceManager();
402
403 if (RegionOfInterest.isValid()) {
404 SourceRange MappedRange = AU->mapRangeToPreamble(RegionOfInterest);
405 SourceLocation B = MappedRange.getBegin();
406 SourceLocation E = MappedRange.getEnd();
407
408 if (AU->isInPreambleFileID(B)) {
409 if (SM.isLoadedSourceLocation(E))
410 return visitPreprocessedEntitiesInRange(SourceRange(B, E),
411 PPRec, *this);
412
413 // Beginning of range lies in the preamble but it also extends beyond
414 // it into the main file. Split the range into 2 parts, one covering
415 // the preamble and another covering the main file. This allows subsequent
416 // calls to visitPreprocessedEntitiesInRange to accept a source range that
417 // lies in the same FileID, allowing it to skip preprocessed entities that
418 // do not come from the same FileID.
419 bool breaked =
420 visitPreprocessedEntitiesInRange(
421 SourceRange(B, AU->getEndOfPreambleFileID()),
422 PPRec, *this);
423 if (breaked) return true;
424 return visitPreprocessedEntitiesInRange(
425 SourceRange(AU->getStartOfMainFileID(), E),
426 PPRec, *this);
427 }
428
429 return visitPreprocessedEntitiesInRange(SourceRange(B, E), PPRec, *this);
430 }
431
432 bool OnlyLocalDecls
433 = !AU->isMainFileAST() && AU->getOnlyLocalDecls();
434
435 if (OnlyLocalDecls)
436 return visitPreprocessedEntities(PPRec.local_begin(), PPRec.local_end(),
437 PPRec);
438
439 return visitPreprocessedEntities(PPRec.begin(), PPRec.end(), PPRec);
440}
441
442template<typename InputIterator>
443bool CursorVisitor::visitPreprocessedEntities(InputIterator First,
444 InputIterator Last,
445 PreprocessingRecord &PPRec,
446 FileID FID) {
447 for (; First != Last; ++First) {
448 if (!FID.isInvalid() && !PPRec.isEntityInFileID(First, FID))
449 continue;
450
451 PreprocessedEntity *PPE = *First;
Argyrios Kyrtzidis1030f262013-05-07 20:37:17 +0000452 if (!PPE)
453 continue;
454
Guy Benyei11169dd2012-12-18 14:30:41 +0000455 if (MacroExpansion *ME = dyn_cast<MacroExpansion>(PPE)) {
456 if (Visit(MakeMacroExpansionCursor(ME, TU)))
457 return true;
Richard Smith66a81862015-05-04 02:25:31 +0000458
Guy Benyei11169dd2012-12-18 14:30:41 +0000459 continue;
460 }
Richard Smith66a81862015-05-04 02:25:31 +0000461
462 if (MacroDefinitionRecord *MD = dyn_cast<MacroDefinitionRecord>(PPE)) {
Guy Benyei11169dd2012-12-18 14:30:41 +0000463 if (Visit(MakeMacroDefinitionCursor(MD, TU)))
464 return true;
Richard Smith66a81862015-05-04 02:25:31 +0000465
Guy Benyei11169dd2012-12-18 14:30:41 +0000466 continue;
467 }
468
469 if (InclusionDirective *ID = dyn_cast<InclusionDirective>(PPE)) {
470 if (Visit(MakeInclusionDirectiveCursor(ID, TU)))
471 return true;
472
473 continue;
474 }
475 }
476
477 return false;
478}
479
480/// \brief Visit the children of the given cursor.
481///
482/// \returns true if the visitation should be aborted, false if it
483/// should continue.
484bool CursorVisitor::VisitChildren(CXCursor Cursor) {
485 if (clang_isReference(Cursor.kind) &&
486 Cursor.kind != CXCursor_CXXBaseSpecifier) {
487 // By definition, references have no children.
488 return false;
489 }
490
491 // Set the Parent field to Cursor, then back to its old value once we're
492 // done.
493 SetParentRAII SetParent(Parent, StmtParent, Cursor);
494
495 if (clang_isDeclaration(Cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +0000496 Decl *D = const_cast<Decl *>(getCursorDecl(Cursor));
Guy Benyei11169dd2012-12-18 14:30:41 +0000497 if (!D)
498 return false;
499
500 return VisitAttributes(D) || Visit(D);
501 }
502
503 if (clang_isStatement(Cursor.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +0000504 if (const Stmt *S = getCursorStmt(Cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +0000505 return Visit(S);
506
507 return false;
508 }
509
510 if (clang_isExpression(Cursor.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +0000511 if (const Expr *E = getCursorExpr(Cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +0000512 return Visit(E);
513
514 return false;
515 }
516
517 if (clang_isTranslationUnit(Cursor.kind)) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +0000518 CXTranslationUnit TU = getCursorTU(Cursor);
519 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +0000520
521 int VisitOrder[2] = { VisitPreprocessorLast, !VisitPreprocessorLast };
522 for (unsigned I = 0; I != 2; ++I) {
523 if (VisitOrder[I]) {
524 if (!CXXUnit->isMainFileAST() && CXXUnit->getOnlyLocalDecls() &&
525 RegionOfInterest.isInvalid()) {
526 for (ASTUnit::top_level_iterator TL = CXXUnit->top_level_begin(),
527 TLEnd = CXXUnit->top_level_end();
528 TL != TLEnd; ++TL) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +0000529 if (Visit(MakeCXCursor(*TL, TU, RegionOfInterest), true))
Guy Benyei11169dd2012-12-18 14:30:41 +0000530 return true;
531 }
532 } else if (VisitDeclContext(
533 CXXUnit->getASTContext().getTranslationUnitDecl()))
534 return true;
535 continue;
536 }
537
538 // Walk the preprocessing record.
539 if (CXXUnit->getPreprocessor().getPreprocessingRecord())
540 visitPreprocessedEntitiesInRegion();
541 }
542
543 return false;
544 }
545
546 if (Cursor.kind == CXCursor_CXXBaseSpecifier) {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +0000547 if (const CXXBaseSpecifier *Base = getCursorCXXBaseSpecifier(Cursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +0000548 if (TypeSourceInfo *BaseTSInfo = Base->getTypeSourceInfo()) {
549 return Visit(BaseTSInfo->getTypeLoc());
550 }
551 }
552 }
553
554 if (Cursor.kind == CXCursor_IBOutletCollectionAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +0000555 const IBOutletCollectionAttr *A =
Guy Benyei11169dd2012-12-18 14:30:41 +0000556 cast<IBOutletCollectionAttr>(cxcursor::getCursorAttr(Cursor));
Richard Smithb1f9a282013-10-31 01:56:18 +0000557 if (const ObjCObjectType *ObjT = A->getInterface()->getAs<ObjCObjectType>())
Richard Smithb87c4652013-10-31 21:23:20 +0000558 return Visit(cxcursor::MakeCursorObjCClassRef(
559 ObjT->getInterface(),
560 A->getInterfaceLoc()->getTypeLoc().getLocStart(), TU));
Guy Benyei11169dd2012-12-18 14:30:41 +0000561 }
562
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +0000563 // If pointing inside a macro definition, check if the token is an identifier
564 // that was ever defined as a macro. In such a case, create a "pseudo" macro
565 // expansion cursor for that token.
566 SourceLocation BeginLoc = RegionOfInterest.getBegin();
567 if (Cursor.kind == CXCursor_MacroDefinition &&
568 BeginLoc == RegionOfInterest.getEnd()) {
569 SourceLocation Loc = AU->mapLocationToPreamble(BeginLoc);
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +0000570 const MacroInfo *MI =
571 getMacroInfo(cxcursor::getCursorMacroDefinition(Cursor), TU);
Richard Smith66a81862015-05-04 02:25:31 +0000572 if (MacroDefinitionRecord *MacroDef =
573 checkForMacroInMacroDefinition(MI, Loc, TU))
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +0000574 return Visit(cxcursor::MakeMacroExpansionCursor(MacroDef, BeginLoc, TU));
575 }
576
Guy Benyei11169dd2012-12-18 14:30:41 +0000577 // Nothing to visit at the moment.
578 return false;
579}
580
581bool CursorVisitor::VisitBlockDecl(BlockDecl *B) {
582 if (TypeSourceInfo *TSInfo = B->getSignatureAsWritten())
583 if (Visit(TSInfo->getTypeLoc()))
584 return true;
585
586 if (Stmt *Body = B->getBody())
587 return Visit(MakeCXCursor(Body, StmtParent, TU, RegionOfInterest));
588
589 return false;
590}
591
Ted Kremenek03325582013-02-21 01:29:01 +0000592Optional<bool> CursorVisitor::shouldVisitCursor(CXCursor Cursor) {
Guy Benyei11169dd2012-12-18 14:30:41 +0000593 if (RegionOfInterest.isValid()) {
594 SourceRange Range = getFullCursorExtent(Cursor, AU->getSourceManager());
595 if (Range.isInvalid())
David Blaikie7a30dc52013-02-21 01:47:18 +0000596 return None;
Guy Benyei11169dd2012-12-18 14:30:41 +0000597
598 switch (CompareRegionOfInterest(Range)) {
599 case RangeBefore:
600 // This declaration comes before the region of interest; skip it.
David Blaikie7a30dc52013-02-21 01:47:18 +0000601 return None;
Guy Benyei11169dd2012-12-18 14:30:41 +0000602
603 case RangeAfter:
604 // This declaration comes after the region of interest; we're done.
605 return false;
606
607 case RangeOverlap:
608 // This declaration overlaps the region of interest; visit it.
609 break;
610 }
611 }
612 return true;
613}
614
615bool CursorVisitor::VisitDeclContext(DeclContext *DC) {
616 DeclContext::decl_iterator I = DC->decls_begin(), E = DC->decls_end();
617
618 // FIXME: Eventually remove. This part of a hack to support proper
619 // iteration over all Decls contained lexically within an ObjC container.
620 SaveAndRestore<DeclContext::decl_iterator*> DI_saved(DI_current, &I);
621 SaveAndRestore<DeclContext::decl_iterator> DE_saved(DE_current, E);
622
623 for ( ; I != E; ++I) {
624 Decl *D = *I;
625 if (D->getLexicalDeclContext() != DC)
626 continue;
627 CXCursor Cursor = MakeCXCursor(D, TU, RegionOfInterest);
628
629 // Ignore synthesized ivars here, otherwise if we have something like:
630 // @synthesize prop = _prop;
631 // and '_prop' is not declared, we will encounter a '_prop' ivar before
632 // encountering the 'prop' synthesize declaration and we will think that
633 // we passed the region-of-interest.
634 if (ObjCIvarDecl *ivarD = dyn_cast<ObjCIvarDecl>(D)) {
635 if (ivarD->getSynthesize())
636 continue;
637 }
638
639 // FIXME: ObjCClassRef/ObjCProtocolRef for forward class/protocol
640 // declarations is a mismatch with the compiler semantics.
641 if (Cursor.kind == CXCursor_ObjCInterfaceDecl) {
642 ObjCInterfaceDecl *ID = cast<ObjCInterfaceDecl>(D);
643 if (!ID->isThisDeclarationADefinition())
644 Cursor = MakeCursorObjCClassRef(ID, ID->getLocation(), TU);
645
646 } else if (Cursor.kind == CXCursor_ObjCProtocolDecl) {
647 ObjCProtocolDecl *PD = cast<ObjCProtocolDecl>(D);
648 if (!PD->isThisDeclarationADefinition())
649 Cursor = MakeCursorObjCProtocolRef(PD, PD->getLocation(), TU);
650 }
651
Ted Kremenek03325582013-02-21 01:29:01 +0000652 const Optional<bool> &V = shouldVisitCursor(Cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +0000653 if (!V.hasValue())
654 continue;
655 if (!V.getValue())
656 return false;
657 if (Visit(Cursor, true))
658 return true;
659 }
660 return false;
661}
662
663bool CursorVisitor::VisitTranslationUnitDecl(TranslationUnitDecl *D) {
664 llvm_unreachable("Translation units are visited directly by Visit()");
665}
666
Sergey Kalinichev8f3b1872015-11-15 13:48:32 +0000667bool CursorVisitor::VisitTypeAliasTemplateDecl(TypeAliasTemplateDecl *D) {
668 if (VisitTemplateParameters(D->getTemplateParameters()))
669 return true;
670
671 return Visit(MakeCXCursor(D->getTemplatedDecl(), TU, RegionOfInterest));
672}
673
Guy Benyei11169dd2012-12-18 14:30:41 +0000674bool CursorVisitor::VisitTypeAliasDecl(TypeAliasDecl *D) {
675 if (TypeSourceInfo *TSInfo = D->getTypeSourceInfo())
676 return Visit(TSInfo->getTypeLoc());
677
678 return false;
679}
680
681bool CursorVisitor::VisitTypedefDecl(TypedefDecl *D) {
682 if (TypeSourceInfo *TSInfo = D->getTypeSourceInfo())
683 return Visit(TSInfo->getTypeLoc());
684
685 return false;
686}
687
688bool CursorVisitor::VisitTagDecl(TagDecl *D) {
689 return VisitDeclContext(D);
690}
691
692bool CursorVisitor::VisitClassTemplateSpecializationDecl(
693 ClassTemplateSpecializationDecl *D) {
694 bool ShouldVisitBody = false;
695 switch (D->getSpecializationKind()) {
696 case TSK_Undeclared:
697 case TSK_ImplicitInstantiation:
698 // Nothing to visit
699 return false;
700
701 case TSK_ExplicitInstantiationDeclaration:
702 case TSK_ExplicitInstantiationDefinition:
703 break;
704
705 case TSK_ExplicitSpecialization:
706 ShouldVisitBody = true;
707 break;
708 }
709
710 // Visit the template arguments used in the specialization.
711 if (TypeSourceInfo *SpecType = D->getTypeAsWritten()) {
712 TypeLoc TL = SpecType->getTypeLoc();
David Blaikie6adc78e2013-02-18 22:06:02 +0000713 if (TemplateSpecializationTypeLoc TSTLoc =
714 TL.getAs<TemplateSpecializationTypeLoc>()) {
715 for (unsigned I = 0, N = TSTLoc.getNumArgs(); I != N; ++I)
716 if (VisitTemplateArgumentLoc(TSTLoc.getArgLoc(I)))
Guy Benyei11169dd2012-12-18 14:30:41 +0000717 return true;
718 }
719 }
720
721 if (ShouldVisitBody && VisitCXXRecordDecl(D))
722 return true;
723
724 return false;
725}
726
727bool CursorVisitor::VisitClassTemplatePartialSpecializationDecl(
728 ClassTemplatePartialSpecializationDecl *D) {
729 // FIXME: Visit the "outer" template parameter lists on the TagDecl
730 // before visiting these template parameters.
731 if (VisitTemplateParameters(D->getTemplateParameters()))
732 return true;
733
734 // Visit the partial specialization arguments.
Enea Zaffanella6dbe1872013-08-10 07:24:53 +0000735 const ASTTemplateArgumentListInfo *Info = D->getTemplateArgsAsWritten();
736 const TemplateArgumentLoc *TemplateArgs = Info->getTemplateArgs();
737 for (unsigned I = 0, N = Info->NumTemplateArgs; I != N; ++I)
Guy Benyei11169dd2012-12-18 14:30:41 +0000738 if (VisitTemplateArgumentLoc(TemplateArgs[I]))
739 return true;
740
741 return VisitCXXRecordDecl(D);
742}
743
744bool CursorVisitor::VisitTemplateTypeParmDecl(TemplateTypeParmDecl *D) {
745 // Visit the default argument.
746 if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited())
747 if (TypeSourceInfo *DefArg = D->getDefaultArgumentInfo())
748 if (Visit(DefArg->getTypeLoc()))
749 return true;
750
751 return false;
752}
753
754bool CursorVisitor::VisitEnumConstantDecl(EnumConstantDecl *D) {
755 if (Expr *Init = D->getInitExpr())
756 return Visit(MakeCXCursor(Init, StmtParent, TU, RegionOfInterest));
757 return false;
758}
759
760bool CursorVisitor::VisitDeclaratorDecl(DeclaratorDecl *DD) {
Argyrios Kyrtzidis2ec76742013-04-05 21:04:10 +0000761 unsigned NumParamList = DD->getNumTemplateParameterLists();
762 for (unsigned i = 0; i < NumParamList; i++) {
763 TemplateParameterList* Params = DD->getTemplateParameterList(i);
764 if (VisitTemplateParameters(Params))
765 return true;
766 }
767
Guy Benyei11169dd2012-12-18 14:30:41 +0000768 if (TypeSourceInfo *TSInfo = DD->getTypeSourceInfo())
769 if (Visit(TSInfo->getTypeLoc()))
770 return true;
771
772 // Visit the nested-name-specifier, if present.
773 if (NestedNameSpecifierLoc QualifierLoc = DD->getQualifierLoc())
774 if (VisitNestedNameSpecifierLoc(QualifierLoc))
775 return true;
776
777 return false;
778}
779
Benjamin Kramer4cadf292014-03-07 21:51:58 +0000780/// \brief Compare two base or member initializers based on their source order.
781static int CompareCXXCtorInitializers(CXXCtorInitializer *const *X,
782 CXXCtorInitializer *const *Y) {
783 return (*X)->getSourceOrder() - (*Y)->getSourceOrder();
784}
785
Guy Benyei11169dd2012-12-18 14:30:41 +0000786bool CursorVisitor::VisitFunctionDecl(FunctionDecl *ND) {
Argyrios Kyrtzidis2ec76742013-04-05 21:04:10 +0000787 unsigned NumParamList = ND->getNumTemplateParameterLists();
788 for (unsigned i = 0; i < NumParamList; i++) {
789 TemplateParameterList* Params = ND->getTemplateParameterList(i);
790 if (VisitTemplateParameters(Params))
791 return true;
792 }
793
Guy Benyei11169dd2012-12-18 14:30:41 +0000794 if (TypeSourceInfo *TSInfo = ND->getTypeSourceInfo()) {
795 // Visit the function declaration's syntactic components in the order
796 // written. This requires a bit of work.
797 TypeLoc TL = TSInfo->getTypeLoc().IgnoreParens();
David Blaikie6adc78e2013-02-18 22:06:02 +0000798 FunctionTypeLoc FTL = TL.getAs<FunctionTypeLoc>();
Guy Benyei11169dd2012-12-18 14:30:41 +0000799
800 // If we have a function declared directly (without the use of a typedef),
801 // visit just the return type. Otherwise, just visit the function's type
802 // now.
Alp Toker42a16a62014-01-25 23:51:36 +0000803 if ((FTL && !isa<CXXConversionDecl>(ND) && Visit(FTL.getReturnLoc())) ||
Guy Benyei11169dd2012-12-18 14:30:41 +0000804 (!FTL && Visit(TL)))
805 return true;
806
807 // Visit the nested-name-specifier, if present.
808 if (NestedNameSpecifierLoc QualifierLoc = ND->getQualifierLoc())
809 if (VisitNestedNameSpecifierLoc(QualifierLoc))
810 return true;
811
812 // Visit the declaration name.
Argyrios Kyrtzidis4a4d2b42014-02-09 08:13:47 +0000813 if (!isa<CXXDestructorDecl>(ND))
814 if (VisitDeclarationNameInfo(ND->getNameInfo()))
815 return true;
Guy Benyei11169dd2012-12-18 14:30:41 +0000816
817 // FIXME: Visit explicitly-specified template arguments!
818
819 // Visit the function parameters, if we have a function type.
David Blaikie6adc78e2013-02-18 22:06:02 +0000820 if (FTL && VisitFunctionTypeLoc(FTL, true))
Guy Benyei11169dd2012-12-18 14:30:41 +0000821 return true;
822
Bill Wendling44426052012-12-20 19:22:21 +0000823 // FIXME: Attributes?
Guy Benyei11169dd2012-12-18 14:30:41 +0000824 }
825
826 if (ND->doesThisDeclarationHaveABody() && !ND->isLateTemplateParsed()) {
827 if (CXXConstructorDecl *Constructor = dyn_cast<CXXConstructorDecl>(ND)) {
828 // Find the initializers that were written in the source.
829 SmallVector<CXXCtorInitializer *, 4> WrittenInits;
Aaron Ballman0ad78302014-03-13 17:34:31 +0000830 for (auto *I : Constructor->inits()) {
831 if (!I->isWritten())
Guy Benyei11169dd2012-12-18 14:30:41 +0000832 continue;
833
Aaron Ballman0ad78302014-03-13 17:34:31 +0000834 WrittenInits.push_back(I);
Guy Benyei11169dd2012-12-18 14:30:41 +0000835 }
836
837 // Sort the initializers in source order
Benjamin Kramer4cadf292014-03-07 21:51:58 +0000838 llvm::array_pod_sort(WrittenInits.begin(), WrittenInits.end(),
839 &CompareCXXCtorInitializers);
840
Guy Benyei11169dd2012-12-18 14:30:41 +0000841 // Visit the initializers in source order
842 for (unsigned I = 0, N = WrittenInits.size(); I != N; ++I) {
843 CXXCtorInitializer *Init = WrittenInits[I];
844 if (Init->isAnyMemberInitializer()) {
845 if (Visit(MakeCursorMemberRef(Init->getAnyMember(),
846 Init->getMemberLocation(), TU)))
847 return true;
848 } else if (TypeSourceInfo *TInfo = Init->getTypeSourceInfo()) {
849 if (Visit(TInfo->getTypeLoc()))
850 return true;
851 }
852
853 // Visit the initializer value.
854 if (Expr *Initializer = Init->getInit())
855 if (Visit(MakeCXCursor(Initializer, ND, TU, RegionOfInterest)))
856 return true;
857 }
858 }
859
860 if (Visit(MakeCXCursor(ND->getBody(), StmtParent, TU, RegionOfInterest)))
861 return true;
862 }
863
864 return false;
865}
866
867bool CursorVisitor::VisitFieldDecl(FieldDecl *D) {
868 if (VisitDeclaratorDecl(D))
869 return true;
870
871 if (Expr *BitWidth = D->getBitWidth())
872 return Visit(MakeCXCursor(BitWidth, StmtParent, TU, RegionOfInterest));
873
874 return false;
875}
876
877bool CursorVisitor::VisitVarDecl(VarDecl *D) {
878 if (VisitDeclaratorDecl(D))
879 return true;
880
881 if (Expr *Init = D->getInit())
882 return Visit(MakeCXCursor(Init, StmtParent, TU, RegionOfInterest));
883
884 return false;
885}
886
887bool CursorVisitor::VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl *D) {
888 if (VisitDeclaratorDecl(D))
889 return true;
890
891 if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited())
892 if (Expr *DefArg = D->getDefaultArgument())
893 return Visit(MakeCXCursor(DefArg, StmtParent, TU, RegionOfInterest));
894
895 return false;
896}
897
898bool CursorVisitor::VisitFunctionTemplateDecl(FunctionTemplateDecl *D) {
899 // FIXME: Visit the "outer" template parameter lists on the FunctionDecl
900 // before visiting these template parameters.
901 if (VisitTemplateParameters(D->getTemplateParameters()))
902 return true;
903
904 return VisitFunctionDecl(D->getTemplatedDecl());
905}
906
907bool CursorVisitor::VisitClassTemplateDecl(ClassTemplateDecl *D) {
908 // FIXME: Visit the "outer" template parameter lists on the TagDecl
909 // before visiting these template parameters.
910 if (VisitTemplateParameters(D->getTemplateParameters()))
911 return true;
912
913 return VisitCXXRecordDecl(D->getTemplatedDecl());
914}
915
916bool CursorVisitor::VisitTemplateTemplateParmDecl(TemplateTemplateParmDecl *D) {
917 if (VisitTemplateParameters(D->getTemplateParameters()))
918 return true;
919
920 if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited() &&
921 VisitTemplateArgumentLoc(D->getDefaultArgument()))
922 return true;
923
924 return false;
925}
926
Douglas Gregor9bda6cf2015-07-07 03:58:14 +0000927bool CursorVisitor::VisitObjCTypeParamDecl(ObjCTypeParamDecl *D) {
928 // Visit the bound, if it's explicit.
929 if (D->hasExplicitBound()) {
930 if (auto TInfo = D->getTypeSourceInfo()) {
931 if (Visit(TInfo->getTypeLoc()))
932 return true;
933 }
934 }
935
936 return false;
937}
938
Guy Benyei11169dd2012-12-18 14:30:41 +0000939bool CursorVisitor::VisitObjCMethodDecl(ObjCMethodDecl *ND) {
Alp Toker314cc812014-01-25 16:55:45 +0000940 if (TypeSourceInfo *TSInfo = ND->getReturnTypeSourceInfo())
Guy Benyei11169dd2012-12-18 14:30:41 +0000941 if (Visit(TSInfo->getTypeLoc()))
942 return true;
943
Aaron Ballman43b68be2014-03-07 17:50:17 +0000944 for (const auto *P : ND->params()) {
945 if (Visit(MakeCXCursor(P, TU, RegionOfInterest)))
Guy Benyei11169dd2012-12-18 14:30:41 +0000946 return true;
947 }
948
949 if (ND->isThisDeclarationADefinition() &&
950 Visit(MakeCXCursor(ND->getBody(), StmtParent, TU, RegionOfInterest)))
951 return true;
952
953 return false;
954}
955
956template <typename DeclIt>
957static void addRangedDeclsInContainer(DeclIt *DI_current, DeclIt DE_current,
958 SourceManager &SM, SourceLocation EndLoc,
959 SmallVectorImpl<Decl *> &Decls) {
960 DeclIt next = *DI_current;
961 while (++next != DE_current) {
962 Decl *D_next = *next;
963 if (!D_next)
964 break;
965 SourceLocation L = D_next->getLocStart();
966 if (!L.isValid())
967 break;
968 if (SM.isBeforeInTranslationUnit(L, EndLoc)) {
969 *DI_current = next;
970 Decls.push_back(D_next);
971 continue;
972 }
973 break;
974 }
975}
976
Guy Benyei11169dd2012-12-18 14:30:41 +0000977bool CursorVisitor::VisitObjCContainerDecl(ObjCContainerDecl *D) {
978 // FIXME: Eventually convert back to just 'VisitDeclContext()'. Essentially
979 // an @implementation can lexically contain Decls that are not properly
980 // nested in the AST. When we identify such cases, we need to retrofit
981 // this nesting here.
982 if (!DI_current && !FileDI_current)
983 return VisitDeclContext(D);
984
985 // Scan the Decls that immediately come after the container
986 // in the current DeclContext. If any fall within the
987 // container's lexical region, stash them into a vector
988 // for later processing.
989 SmallVector<Decl *, 24> DeclsInContainer;
990 SourceLocation EndLoc = D->getSourceRange().getEnd();
991 SourceManager &SM = AU->getSourceManager();
992 if (EndLoc.isValid()) {
993 if (DI_current) {
994 addRangedDeclsInContainer(DI_current, DE_current, SM, EndLoc,
995 DeclsInContainer);
996 } else {
997 addRangedDeclsInContainer(FileDI_current, FileDE_current, SM, EndLoc,
998 DeclsInContainer);
999 }
1000 }
1001
1002 // The common case.
1003 if (DeclsInContainer.empty())
1004 return VisitDeclContext(D);
1005
1006 // Get all the Decls in the DeclContext, and sort them with the
1007 // additional ones we've collected. Then visit them.
Aaron Ballman629afae2014-03-07 19:56:05 +00001008 for (auto *SubDecl : D->decls()) {
1009 if (!SubDecl || SubDecl->getLexicalDeclContext() != D ||
1010 SubDecl->getLocStart().isInvalid())
Guy Benyei11169dd2012-12-18 14:30:41 +00001011 continue;
Aaron Ballman629afae2014-03-07 19:56:05 +00001012 DeclsInContainer.push_back(SubDecl);
Guy Benyei11169dd2012-12-18 14:30:41 +00001013 }
1014
1015 // Now sort the Decls so that they appear in lexical order.
1016 std::sort(DeclsInContainer.begin(), DeclsInContainer.end(),
Benjamin Kramerbbdd7642014-03-01 14:48:57 +00001017 [&SM](Decl *A, Decl *B) {
1018 SourceLocation L_A = A->getLocStart();
1019 SourceLocation L_B = B->getLocStart();
1020 assert(L_A.isValid() && L_B.isValid());
1021 return SM.isBeforeInTranslationUnit(L_A, L_B);
1022 });
Guy Benyei11169dd2012-12-18 14:30:41 +00001023
1024 // Now visit the decls.
1025 for (SmallVectorImpl<Decl*>::iterator I = DeclsInContainer.begin(),
1026 E = DeclsInContainer.end(); I != E; ++I) {
1027 CXCursor Cursor = MakeCXCursor(*I, TU, RegionOfInterest);
Ted Kremenek03325582013-02-21 01:29:01 +00001028 const Optional<bool> &V = shouldVisitCursor(Cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00001029 if (!V.hasValue())
1030 continue;
1031 if (!V.getValue())
1032 return false;
1033 if (Visit(Cursor, true))
1034 return true;
1035 }
1036 return false;
1037}
1038
1039bool CursorVisitor::VisitObjCCategoryDecl(ObjCCategoryDecl *ND) {
1040 if (Visit(MakeCursorObjCClassRef(ND->getClassInterface(), ND->getLocation(),
1041 TU)))
1042 return true;
1043
Douglas Gregore9d95f12015-07-07 03:57:35 +00001044 if (VisitObjCTypeParamList(ND->getTypeParamList()))
1045 return true;
1046
Guy Benyei11169dd2012-12-18 14:30:41 +00001047 ObjCCategoryDecl::protocol_loc_iterator PL = ND->protocol_loc_begin();
1048 for (ObjCCategoryDecl::protocol_iterator I = ND->protocol_begin(),
1049 E = ND->protocol_end(); I != E; ++I, ++PL)
1050 if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
1051 return true;
1052
1053 return VisitObjCContainerDecl(ND);
1054}
1055
1056bool CursorVisitor::VisitObjCProtocolDecl(ObjCProtocolDecl *PID) {
1057 if (!PID->isThisDeclarationADefinition())
1058 return Visit(MakeCursorObjCProtocolRef(PID, PID->getLocation(), TU));
1059
1060 ObjCProtocolDecl::protocol_loc_iterator PL = PID->protocol_loc_begin();
1061 for (ObjCProtocolDecl::protocol_iterator I = PID->protocol_begin(),
1062 E = PID->protocol_end(); I != E; ++I, ++PL)
1063 if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
1064 return true;
1065
1066 return VisitObjCContainerDecl(PID);
1067}
1068
1069bool CursorVisitor::VisitObjCPropertyDecl(ObjCPropertyDecl *PD) {
1070 if (PD->getTypeSourceInfo() && Visit(PD->getTypeSourceInfo()->getTypeLoc()))
1071 return true;
1072
1073 // FIXME: This implements a workaround with @property declarations also being
1074 // installed in the DeclContext for the @interface. Eventually this code
1075 // should be removed.
1076 ObjCCategoryDecl *CDecl = dyn_cast<ObjCCategoryDecl>(PD->getDeclContext());
1077 if (!CDecl || !CDecl->IsClassExtension())
1078 return false;
1079
1080 ObjCInterfaceDecl *ID = CDecl->getClassInterface();
1081 if (!ID)
1082 return false;
1083
1084 IdentifierInfo *PropertyId = PD->getIdentifier();
1085 ObjCPropertyDecl *prevDecl =
1086 ObjCPropertyDecl::findPropertyDecl(cast<DeclContext>(ID), PropertyId);
1087
1088 if (!prevDecl)
1089 return false;
1090
1091 // Visit synthesized methods since they will be skipped when visiting
1092 // the @interface.
1093 if (ObjCMethodDecl *MD = prevDecl->getGetterMethodDecl())
1094 if (MD->isPropertyAccessor() && MD->getLexicalDeclContext() == CDecl)
1095 if (Visit(MakeCXCursor(MD, TU, RegionOfInterest)))
1096 return true;
1097
1098 if (ObjCMethodDecl *MD = prevDecl->getSetterMethodDecl())
1099 if (MD->isPropertyAccessor() && MD->getLexicalDeclContext() == CDecl)
1100 if (Visit(MakeCXCursor(MD, TU, RegionOfInterest)))
1101 return true;
1102
1103 return false;
1104}
1105
Douglas Gregore9d95f12015-07-07 03:57:35 +00001106bool CursorVisitor::VisitObjCTypeParamList(ObjCTypeParamList *typeParamList) {
1107 if (!typeParamList)
1108 return false;
1109
1110 for (auto *typeParam : *typeParamList) {
1111 // Visit the type parameter.
1112 if (Visit(MakeCXCursor(typeParam, TU, RegionOfInterest)))
1113 return true;
Douglas Gregore9d95f12015-07-07 03:57:35 +00001114 }
1115
1116 return false;
1117}
1118
Guy Benyei11169dd2012-12-18 14:30:41 +00001119bool CursorVisitor::VisitObjCInterfaceDecl(ObjCInterfaceDecl *D) {
1120 if (!D->isThisDeclarationADefinition()) {
1121 // Forward declaration is treated like a reference.
1122 return Visit(MakeCursorObjCClassRef(D, D->getLocation(), TU));
1123 }
1124
Douglas Gregore9d95f12015-07-07 03:57:35 +00001125 // Objective-C type parameters.
1126 if (VisitObjCTypeParamList(D->getTypeParamListAsWritten()))
1127 return true;
1128
Guy Benyei11169dd2012-12-18 14:30:41 +00001129 // Issue callbacks for super class.
1130 if (D->getSuperClass() &&
1131 Visit(MakeCursorObjCSuperClassRef(D->getSuperClass(),
1132 D->getSuperClassLoc(),
1133 TU)))
1134 return true;
1135
Douglas Gregore9d95f12015-07-07 03:57:35 +00001136 if (TypeSourceInfo *SuperClassTInfo = D->getSuperClassTInfo())
1137 if (Visit(SuperClassTInfo->getTypeLoc()))
1138 return true;
1139
Guy Benyei11169dd2012-12-18 14:30:41 +00001140 ObjCInterfaceDecl::protocol_loc_iterator PL = D->protocol_loc_begin();
1141 for (ObjCInterfaceDecl::protocol_iterator I = D->protocol_begin(),
1142 E = D->protocol_end(); I != E; ++I, ++PL)
1143 if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
1144 return true;
1145
1146 return VisitObjCContainerDecl(D);
1147}
1148
1149bool CursorVisitor::VisitObjCImplDecl(ObjCImplDecl *D) {
1150 return VisitObjCContainerDecl(D);
1151}
1152
1153bool CursorVisitor::VisitObjCCategoryImplDecl(ObjCCategoryImplDecl *D) {
1154 // 'ID' could be null when dealing with invalid code.
1155 if (ObjCInterfaceDecl *ID = D->getClassInterface())
1156 if (Visit(MakeCursorObjCClassRef(ID, D->getLocation(), TU)))
1157 return true;
1158
1159 return VisitObjCImplDecl(D);
1160}
1161
1162bool CursorVisitor::VisitObjCImplementationDecl(ObjCImplementationDecl *D) {
1163#if 0
1164 // Issue callbacks for super class.
1165 // FIXME: No source location information!
1166 if (D->getSuperClass() &&
1167 Visit(MakeCursorObjCSuperClassRef(D->getSuperClass(),
1168 D->getSuperClassLoc(),
1169 TU)))
1170 return true;
1171#endif
1172
1173 return VisitObjCImplDecl(D);
1174}
1175
1176bool CursorVisitor::VisitObjCPropertyImplDecl(ObjCPropertyImplDecl *PD) {
1177 if (ObjCIvarDecl *Ivar = PD->getPropertyIvarDecl())
1178 if (PD->isIvarNameSpecified())
1179 return Visit(MakeCursorMemberRef(Ivar, PD->getPropertyIvarDeclLoc(), TU));
1180
1181 return false;
1182}
1183
1184bool CursorVisitor::VisitNamespaceDecl(NamespaceDecl *D) {
1185 return VisitDeclContext(D);
1186}
1187
1188bool CursorVisitor::VisitNamespaceAliasDecl(NamespaceAliasDecl *D) {
1189 // Visit nested-name-specifier.
1190 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1191 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1192 return true;
1193
1194 return Visit(MakeCursorNamespaceRef(D->getAliasedNamespace(),
1195 D->getTargetNameLoc(), TU));
1196}
1197
1198bool CursorVisitor::VisitUsingDecl(UsingDecl *D) {
1199 // Visit nested-name-specifier.
1200 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc()) {
1201 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1202 return true;
1203 }
1204
1205 if (Visit(MakeCursorOverloadedDeclRef(D, D->getLocation(), TU)))
1206 return true;
1207
1208 return VisitDeclarationNameInfo(D->getNameInfo());
1209}
1210
1211bool CursorVisitor::VisitUsingDirectiveDecl(UsingDirectiveDecl *D) {
1212 // Visit nested-name-specifier.
1213 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1214 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1215 return true;
1216
1217 return Visit(MakeCursorNamespaceRef(D->getNominatedNamespaceAsWritten(),
1218 D->getIdentLocation(), TU));
1219}
1220
1221bool CursorVisitor::VisitUnresolvedUsingValueDecl(UnresolvedUsingValueDecl *D) {
1222 // Visit nested-name-specifier.
1223 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc()) {
1224 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1225 return true;
1226 }
1227
1228 return VisitDeclarationNameInfo(D->getNameInfo());
1229}
1230
1231bool CursorVisitor::VisitUnresolvedUsingTypenameDecl(
1232 UnresolvedUsingTypenameDecl *D) {
1233 // Visit nested-name-specifier.
1234 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1235 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1236 return true;
1237
1238 return false;
1239}
1240
1241bool CursorVisitor::VisitDeclarationNameInfo(DeclarationNameInfo Name) {
1242 switch (Name.getName().getNameKind()) {
1243 case clang::DeclarationName::Identifier:
1244 case clang::DeclarationName::CXXLiteralOperatorName:
1245 case clang::DeclarationName::CXXOperatorName:
1246 case clang::DeclarationName::CXXUsingDirective:
1247 return false;
1248
1249 case clang::DeclarationName::CXXConstructorName:
1250 case clang::DeclarationName::CXXDestructorName:
1251 case clang::DeclarationName::CXXConversionFunctionName:
1252 if (TypeSourceInfo *TSInfo = Name.getNamedTypeInfo())
1253 return Visit(TSInfo->getTypeLoc());
1254 return false;
1255
1256 case clang::DeclarationName::ObjCZeroArgSelector:
1257 case clang::DeclarationName::ObjCOneArgSelector:
1258 case clang::DeclarationName::ObjCMultiArgSelector:
1259 // FIXME: Per-identifier location info?
1260 return false;
1261 }
1262
1263 llvm_unreachable("Invalid DeclarationName::Kind!");
1264}
1265
1266bool CursorVisitor::VisitNestedNameSpecifier(NestedNameSpecifier *NNS,
1267 SourceRange Range) {
1268 // FIXME: This whole routine is a hack to work around the lack of proper
1269 // source information in nested-name-specifiers (PR5791). Since we do have
1270 // a beginning source location, we can visit the first component of the
1271 // nested-name-specifier, if it's a single-token component.
1272 if (!NNS)
1273 return false;
1274
1275 // Get the first component in the nested-name-specifier.
1276 while (NestedNameSpecifier *Prefix = NNS->getPrefix())
1277 NNS = Prefix;
1278
1279 switch (NNS->getKind()) {
1280 case NestedNameSpecifier::Namespace:
1281 return Visit(MakeCursorNamespaceRef(NNS->getAsNamespace(), Range.getBegin(),
1282 TU));
1283
1284 case NestedNameSpecifier::NamespaceAlias:
1285 return Visit(MakeCursorNamespaceRef(NNS->getAsNamespaceAlias(),
1286 Range.getBegin(), TU));
1287
1288 case NestedNameSpecifier::TypeSpec: {
1289 // If the type has a form where we know that the beginning of the source
1290 // range matches up with a reference cursor. Visit the appropriate reference
1291 // cursor.
1292 const Type *T = NNS->getAsType();
1293 if (const TypedefType *Typedef = dyn_cast<TypedefType>(T))
1294 return Visit(MakeCursorTypeRef(Typedef->getDecl(), Range.getBegin(), TU));
1295 if (const TagType *Tag = dyn_cast<TagType>(T))
1296 return Visit(MakeCursorTypeRef(Tag->getDecl(), Range.getBegin(), TU));
1297 if (const TemplateSpecializationType *TST
1298 = dyn_cast<TemplateSpecializationType>(T))
1299 return VisitTemplateName(TST->getTemplateName(), Range.getBegin());
1300 break;
1301 }
1302
1303 case NestedNameSpecifier::TypeSpecWithTemplate:
1304 case NestedNameSpecifier::Global:
1305 case NestedNameSpecifier::Identifier:
Nikola Smiljanic67860242014-09-26 00:28:20 +00001306 case NestedNameSpecifier::Super:
Guy Benyei11169dd2012-12-18 14:30:41 +00001307 break;
1308 }
1309
1310 return false;
1311}
1312
1313bool
1314CursorVisitor::VisitNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier) {
1315 SmallVector<NestedNameSpecifierLoc, 4> Qualifiers;
1316 for (; Qualifier; Qualifier = Qualifier.getPrefix())
1317 Qualifiers.push_back(Qualifier);
1318
1319 while (!Qualifiers.empty()) {
1320 NestedNameSpecifierLoc Q = Qualifiers.pop_back_val();
1321 NestedNameSpecifier *NNS = Q.getNestedNameSpecifier();
1322 switch (NNS->getKind()) {
1323 case NestedNameSpecifier::Namespace:
1324 if (Visit(MakeCursorNamespaceRef(NNS->getAsNamespace(),
1325 Q.getLocalBeginLoc(),
1326 TU)))
1327 return true;
1328
1329 break;
1330
1331 case NestedNameSpecifier::NamespaceAlias:
1332 if (Visit(MakeCursorNamespaceRef(NNS->getAsNamespaceAlias(),
1333 Q.getLocalBeginLoc(),
1334 TU)))
1335 return true;
1336
1337 break;
1338
1339 case NestedNameSpecifier::TypeSpec:
1340 case NestedNameSpecifier::TypeSpecWithTemplate:
1341 if (Visit(Q.getTypeLoc()))
1342 return true;
1343
1344 break;
1345
1346 case NestedNameSpecifier::Global:
1347 case NestedNameSpecifier::Identifier:
Nikola Smiljanic67860242014-09-26 00:28:20 +00001348 case NestedNameSpecifier::Super:
Guy Benyei11169dd2012-12-18 14:30:41 +00001349 break;
1350 }
1351 }
1352
1353 return false;
1354}
1355
1356bool CursorVisitor::VisitTemplateParameters(
1357 const TemplateParameterList *Params) {
1358 if (!Params)
1359 return false;
1360
1361 for (TemplateParameterList::const_iterator P = Params->begin(),
1362 PEnd = Params->end();
1363 P != PEnd; ++P) {
1364 if (Visit(MakeCXCursor(*P, TU, RegionOfInterest)))
1365 return true;
1366 }
1367
1368 return false;
1369}
1370
1371bool CursorVisitor::VisitTemplateName(TemplateName Name, SourceLocation Loc) {
1372 switch (Name.getKind()) {
1373 case TemplateName::Template:
1374 return Visit(MakeCursorTemplateRef(Name.getAsTemplateDecl(), Loc, TU));
1375
1376 case TemplateName::OverloadedTemplate:
1377 // Visit the overloaded template set.
1378 if (Visit(MakeCursorOverloadedDeclRef(Name, Loc, TU)))
1379 return true;
1380
1381 return false;
1382
1383 case TemplateName::DependentTemplate:
1384 // FIXME: Visit nested-name-specifier.
1385 return false;
1386
1387 case TemplateName::QualifiedTemplate:
1388 // FIXME: Visit nested-name-specifier.
1389 return Visit(MakeCursorTemplateRef(
1390 Name.getAsQualifiedTemplateName()->getDecl(),
1391 Loc, TU));
1392
1393 case TemplateName::SubstTemplateTemplateParm:
1394 return Visit(MakeCursorTemplateRef(
1395 Name.getAsSubstTemplateTemplateParm()->getParameter(),
1396 Loc, TU));
1397
1398 case TemplateName::SubstTemplateTemplateParmPack:
1399 return Visit(MakeCursorTemplateRef(
1400 Name.getAsSubstTemplateTemplateParmPack()->getParameterPack(),
1401 Loc, TU));
1402 }
1403
1404 llvm_unreachable("Invalid TemplateName::Kind!");
1405}
1406
1407bool CursorVisitor::VisitTemplateArgumentLoc(const TemplateArgumentLoc &TAL) {
1408 switch (TAL.getArgument().getKind()) {
1409 case TemplateArgument::Null:
1410 case TemplateArgument::Integral:
1411 case TemplateArgument::Pack:
1412 return false;
1413
1414 case TemplateArgument::Type:
1415 if (TypeSourceInfo *TSInfo = TAL.getTypeSourceInfo())
1416 return Visit(TSInfo->getTypeLoc());
1417 return false;
1418
1419 case TemplateArgument::Declaration:
1420 if (Expr *E = TAL.getSourceDeclExpression())
1421 return Visit(MakeCXCursor(E, StmtParent, TU, RegionOfInterest));
1422 return false;
1423
1424 case TemplateArgument::NullPtr:
1425 if (Expr *E = TAL.getSourceNullPtrExpression())
1426 return Visit(MakeCXCursor(E, StmtParent, TU, RegionOfInterest));
1427 return false;
1428
1429 case TemplateArgument::Expression:
1430 if (Expr *E = TAL.getSourceExpression())
1431 return Visit(MakeCXCursor(E, StmtParent, TU, RegionOfInterest));
1432 return false;
1433
1434 case TemplateArgument::Template:
1435 case TemplateArgument::TemplateExpansion:
1436 if (VisitNestedNameSpecifierLoc(TAL.getTemplateQualifierLoc()))
1437 return true;
1438
1439 return VisitTemplateName(TAL.getArgument().getAsTemplateOrTemplatePattern(),
1440 TAL.getTemplateNameLoc());
1441 }
1442
1443 llvm_unreachable("Invalid TemplateArgument::Kind!");
1444}
1445
1446bool CursorVisitor::VisitLinkageSpecDecl(LinkageSpecDecl *D) {
1447 return VisitDeclContext(D);
1448}
1449
1450bool CursorVisitor::VisitQualifiedTypeLoc(QualifiedTypeLoc TL) {
1451 return Visit(TL.getUnqualifiedLoc());
1452}
1453
1454bool CursorVisitor::VisitBuiltinTypeLoc(BuiltinTypeLoc TL) {
1455 ASTContext &Context = AU->getASTContext();
1456
1457 // Some builtin types (such as Objective-C's "id", "sel", and
1458 // "Class") have associated declarations. Create cursors for those.
1459 QualType VisitType;
1460 switch (TL.getTypePtr()->getKind()) {
1461
1462 case BuiltinType::Void:
1463 case BuiltinType::NullPtr:
1464 case BuiltinType::Dependent:
Guy Benyeid8a08ea2012-12-18 14:38:23 +00001465 case BuiltinType::OCLImage1d:
1466 case BuiltinType::OCLImage1dArray:
1467 case BuiltinType::OCLImage1dBuffer:
1468 case BuiltinType::OCLImage2d:
1469 case BuiltinType::OCLImage2dArray:
Alexey Bader9c8453f2015-09-15 11:18:52 +00001470 case BuiltinType::OCLImage2dDepth:
1471 case BuiltinType::OCLImage2dArrayDepth:
1472 case BuiltinType::OCLImage2dMSAA:
1473 case BuiltinType::OCLImage2dArrayMSAA:
1474 case BuiltinType::OCLImage2dMSAADepth:
1475 case BuiltinType::OCLImage2dArrayMSAADepth:
Guy Benyeid8a08ea2012-12-18 14:38:23 +00001476 case BuiltinType::OCLImage3d:
NAKAMURA Takumi288c42e2013-02-07 12:47:42 +00001477 case BuiltinType::OCLSampler:
Guy Benyei1b4fb3e2013-01-20 12:31:11 +00001478 case BuiltinType::OCLEvent:
Alexey Bader9c8453f2015-09-15 11:18:52 +00001479 case BuiltinType::OCLClkEvent:
1480 case BuiltinType::OCLQueue:
1481 case BuiltinType::OCLNDRange:
1482 case BuiltinType::OCLReserveID:
Guy Benyei11169dd2012-12-18 14:30:41 +00001483#define BUILTIN_TYPE(Id, SingletonId)
1484#define SIGNED_TYPE(Id, SingletonId) case BuiltinType::Id:
1485#define UNSIGNED_TYPE(Id, SingletonId) case BuiltinType::Id:
1486#define FLOATING_TYPE(Id, SingletonId) case BuiltinType::Id:
1487#define PLACEHOLDER_TYPE(Id, SingletonId) case BuiltinType::Id:
1488#include "clang/AST/BuiltinTypes.def"
1489 break;
1490
1491 case BuiltinType::ObjCId:
1492 VisitType = Context.getObjCIdType();
1493 break;
1494
1495 case BuiltinType::ObjCClass:
1496 VisitType = Context.getObjCClassType();
1497 break;
1498
1499 case BuiltinType::ObjCSel:
1500 VisitType = Context.getObjCSelType();
1501 break;
1502 }
1503
1504 if (!VisitType.isNull()) {
1505 if (const TypedefType *Typedef = VisitType->getAs<TypedefType>())
1506 return Visit(MakeCursorTypeRef(Typedef->getDecl(), TL.getBuiltinLoc(),
1507 TU));
1508 }
1509
1510 return false;
1511}
1512
1513bool CursorVisitor::VisitTypedefTypeLoc(TypedefTypeLoc TL) {
1514 return Visit(MakeCursorTypeRef(TL.getTypedefNameDecl(), TL.getNameLoc(), TU));
1515}
1516
1517bool CursorVisitor::VisitUnresolvedUsingTypeLoc(UnresolvedUsingTypeLoc TL) {
1518 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1519}
1520
1521bool CursorVisitor::VisitTagTypeLoc(TagTypeLoc TL) {
1522 if (TL.isDefinition())
1523 return Visit(MakeCXCursor(TL.getDecl(), TU, RegionOfInterest));
1524
1525 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1526}
1527
1528bool CursorVisitor::VisitTemplateTypeParmTypeLoc(TemplateTypeParmTypeLoc TL) {
1529 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1530}
1531
1532bool CursorVisitor::VisitObjCInterfaceTypeLoc(ObjCInterfaceTypeLoc TL) {
Hans Wennborg59dbe862015-09-29 20:56:43 +00001533 return Visit(MakeCursorObjCClassRef(TL.getIFaceDecl(), TL.getNameLoc(), TU));
Guy Benyei11169dd2012-12-18 14:30:41 +00001534}
1535
1536bool CursorVisitor::VisitObjCObjectTypeLoc(ObjCObjectTypeLoc TL) {
1537 if (TL.hasBaseTypeAsWritten() && Visit(TL.getBaseLoc()))
1538 return true;
1539
Douglas Gregore9d95f12015-07-07 03:57:35 +00001540 for (unsigned I = 0, N = TL.getNumTypeArgs(); I != N; ++I) {
1541 if (Visit(TL.getTypeArgTInfo(I)->getTypeLoc()))
1542 return true;
1543 }
1544
Guy Benyei11169dd2012-12-18 14:30:41 +00001545 for (unsigned I = 0, N = TL.getNumProtocols(); I != N; ++I) {
1546 if (Visit(MakeCursorObjCProtocolRef(TL.getProtocol(I), TL.getProtocolLoc(I),
1547 TU)))
1548 return true;
1549 }
1550
1551 return false;
1552}
1553
1554bool CursorVisitor::VisitObjCObjectPointerTypeLoc(ObjCObjectPointerTypeLoc TL) {
1555 return Visit(TL.getPointeeLoc());
1556}
1557
1558bool CursorVisitor::VisitParenTypeLoc(ParenTypeLoc TL) {
1559 return Visit(TL.getInnerLoc());
1560}
1561
1562bool CursorVisitor::VisitPointerTypeLoc(PointerTypeLoc TL) {
1563 return Visit(TL.getPointeeLoc());
1564}
1565
1566bool CursorVisitor::VisitBlockPointerTypeLoc(BlockPointerTypeLoc TL) {
1567 return Visit(TL.getPointeeLoc());
1568}
1569
1570bool CursorVisitor::VisitMemberPointerTypeLoc(MemberPointerTypeLoc TL) {
1571 return Visit(TL.getPointeeLoc());
1572}
1573
1574bool CursorVisitor::VisitLValueReferenceTypeLoc(LValueReferenceTypeLoc TL) {
1575 return Visit(TL.getPointeeLoc());
1576}
1577
1578bool CursorVisitor::VisitRValueReferenceTypeLoc(RValueReferenceTypeLoc TL) {
1579 return Visit(TL.getPointeeLoc());
1580}
1581
1582bool CursorVisitor::VisitAttributedTypeLoc(AttributedTypeLoc TL) {
1583 return Visit(TL.getModifiedLoc());
1584}
1585
1586bool CursorVisitor::VisitFunctionTypeLoc(FunctionTypeLoc TL,
1587 bool SkipResultType) {
Alp Toker42a16a62014-01-25 23:51:36 +00001588 if (!SkipResultType && Visit(TL.getReturnLoc()))
Guy Benyei11169dd2012-12-18 14:30:41 +00001589 return true;
1590
Alp Tokerb3fd5cf2014-01-21 00:32:38 +00001591 for (unsigned I = 0, N = TL.getNumParams(); I != N; ++I)
1592 if (Decl *D = TL.getParam(I))
Guy Benyei11169dd2012-12-18 14:30:41 +00001593 if (Visit(MakeCXCursor(D, TU, RegionOfInterest)))
1594 return true;
1595
1596 return false;
1597}
1598
1599bool CursorVisitor::VisitArrayTypeLoc(ArrayTypeLoc TL) {
1600 if (Visit(TL.getElementLoc()))
1601 return true;
1602
1603 if (Expr *Size = TL.getSizeExpr())
1604 return Visit(MakeCXCursor(Size, StmtParent, TU, RegionOfInterest));
1605
1606 return false;
1607}
1608
Reid Kleckner8a365022013-06-24 17:51:48 +00001609bool CursorVisitor::VisitDecayedTypeLoc(DecayedTypeLoc TL) {
1610 return Visit(TL.getOriginalLoc());
1611}
1612
Reid Kleckner0503a872013-12-05 01:23:43 +00001613bool CursorVisitor::VisitAdjustedTypeLoc(AdjustedTypeLoc TL) {
1614 return Visit(TL.getOriginalLoc());
1615}
1616
Guy Benyei11169dd2012-12-18 14:30:41 +00001617bool CursorVisitor::VisitTemplateSpecializationTypeLoc(
1618 TemplateSpecializationTypeLoc TL) {
1619 // Visit the template name.
1620 if (VisitTemplateName(TL.getTypePtr()->getTemplateName(),
1621 TL.getTemplateNameLoc()))
1622 return true;
1623
1624 // Visit the template arguments.
1625 for (unsigned I = 0, N = TL.getNumArgs(); I != N; ++I)
1626 if (VisitTemplateArgumentLoc(TL.getArgLoc(I)))
1627 return true;
1628
1629 return false;
1630}
1631
1632bool CursorVisitor::VisitTypeOfExprTypeLoc(TypeOfExprTypeLoc TL) {
1633 return Visit(MakeCXCursor(TL.getUnderlyingExpr(), StmtParent, TU));
1634}
1635
1636bool CursorVisitor::VisitTypeOfTypeLoc(TypeOfTypeLoc TL) {
1637 if (TypeSourceInfo *TSInfo = TL.getUnderlyingTInfo())
1638 return Visit(TSInfo->getTypeLoc());
1639
1640 return false;
1641}
1642
1643bool CursorVisitor::VisitUnaryTransformTypeLoc(UnaryTransformTypeLoc TL) {
1644 if (TypeSourceInfo *TSInfo = TL.getUnderlyingTInfo())
1645 return Visit(TSInfo->getTypeLoc());
1646
1647 return false;
1648}
1649
1650bool CursorVisitor::VisitDependentNameTypeLoc(DependentNameTypeLoc TL) {
Hans Wennborg59dbe862015-09-29 20:56:43 +00001651 return VisitNestedNameSpecifierLoc(TL.getQualifierLoc());
Guy Benyei11169dd2012-12-18 14:30:41 +00001652}
1653
1654bool CursorVisitor::VisitDependentTemplateSpecializationTypeLoc(
1655 DependentTemplateSpecializationTypeLoc TL) {
1656 // Visit the nested-name-specifier, if there is one.
1657 if (TL.getQualifierLoc() &&
1658 VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
1659 return true;
1660
1661 // Visit the template arguments.
1662 for (unsigned I = 0, N = TL.getNumArgs(); I != N; ++I)
1663 if (VisitTemplateArgumentLoc(TL.getArgLoc(I)))
1664 return true;
1665
1666 return false;
1667}
1668
1669bool CursorVisitor::VisitElaboratedTypeLoc(ElaboratedTypeLoc TL) {
1670 if (VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
1671 return true;
1672
1673 return Visit(TL.getNamedTypeLoc());
1674}
1675
1676bool CursorVisitor::VisitPackExpansionTypeLoc(PackExpansionTypeLoc TL) {
1677 return Visit(TL.getPatternLoc());
1678}
1679
1680bool CursorVisitor::VisitDecltypeTypeLoc(DecltypeTypeLoc TL) {
1681 if (Expr *E = TL.getUnderlyingExpr())
1682 return Visit(MakeCXCursor(E, StmtParent, TU));
1683
1684 return false;
1685}
1686
1687bool CursorVisitor::VisitInjectedClassNameTypeLoc(InjectedClassNameTypeLoc TL) {
1688 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1689}
1690
1691bool CursorVisitor::VisitAtomicTypeLoc(AtomicTypeLoc TL) {
1692 return Visit(TL.getValueLoc());
1693}
1694
1695#define DEFAULT_TYPELOC_IMPL(CLASS, PARENT) \
1696bool CursorVisitor::Visit##CLASS##TypeLoc(CLASS##TypeLoc TL) { \
1697 return Visit##PARENT##Loc(TL); \
1698}
1699
1700DEFAULT_TYPELOC_IMPL(Complex, Type)
1701DEFAULT_TYPELOC_IMPL(ConstantArray, ArrayType)
1702DEFAULT_TYPELOC_IMPL(IncompleteArray, ArrayType)
1703DEFAULT_TYPELOC_IMPL(VariableArray, ArrayType)
1704DEFAULT_TYPELOC_IMPL(DependentSizedArray, ArrayType)
1705DEFAULT_TYPELOC_IMPL(DependentSizedExtVector, Type)
1706DEFAULT_TYPELOC_IMPL(Vector, Type)
1707DEFAULT_TYPELOC_IMPL(ExtVector, VectorType)
1708DEFAULT_TYPELOC_IMPL(FunctionProto, FunctionType)
1709DEFAULT_TYPELOC_IMPL(FunctionNoProto, FunctionType)
1710DEFAULT_TYPELOC_IMPL(Record, TagType)
1711DEFAULT_TYPELOC_IMPL(Enum, TagType)
1712DEFAULT_TYPELOC_IMPL(SubstTemplateTypeParm, Type)
1713DEFAULT_TYPELOC_IMPL(SubstTemplateTypeParmPack, Type)
1714DEFAULT_TYPELOC_IMPL(Auto, Type)
1715
1716bool CursorVisitor::VisitCXXRecordDecl(CXXRecordDecl *D) {
1717 // Visit the nested-name-specifier, if present.
1718 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1719 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1720 return true;
1721
1722 if (D->isCompleteDefinition()) {
Aaron Ballman574705e2014-03-13 15:41:46 +00001723 for (const auto &I : D->bases()) {
1724 if (Visit(cxcursor::MakeCursorCXXBaseSpecifier(&I, TU)))
Guy Benyei11169dd2012-12-18 14:30:41 +00001725 return true;
1726 }
1727 }
1728
1729 return VisitTagDecl(D);
1730}
1731
1732bool CursorVisitor::VisitAttributes(Decl *D) {
Aaron Ballmanb97112e2014-03-08 22:19:01 +00001733 for (const auto *I : D->attrs())
1734 if (Visit(MakeCXCursor(I, D, TU)))
Guy Benyei11169dd2012-12-18 14:30:41 +00001735 return true;
1736
1737 return false;
1738}
1739
1740//===----------------------------------------------------------------------===//
1741// Data-recursive visitor methods.
1742//===----------------------------------------------------------------------===//
1743
1744namespace {
1745#define DEF_JOB(NAME, DATA, KIND)\
1746class NAME : public VisitorJob {\
1747public:\
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001748 NAME(const DATA *d, CXCursor parent) : \
1749 VisitorJob(parent, VisitorJob::KIND, d) {} \
Guy Benyei11169dd2012-12-18 14:30:41 +00001750 static bool classof(const VisitorJob *VJ) { return VJ->getKind() == KIND; }\
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001751 const DATA *get() const { return static_cast<const DATA*>(data[0]); }\
Guy Benyei11169dd2012-12-18 14:30:41 +00001752};
1753
1754DEF_JOB(StmtVisit, Stmt, StmtVisitKind)
1755DEF_JOB(MemberExprParts, MemberExpr, MemberExprPartsKind)
1756DEF_JOB(DeclRefExprParts, DeclRefExpr, DeclRefExprPartsKind)
1757DEF_JOB(OverloadExprParts, OverloadExpr, OverloadExprPartsKind)
1758DEF_JOB(ExplicitTemplateArgsVisit, ASTTemplateArgumentListInfo,
1759 ExplicitTemplateArgsVisitKind)
1760DEF_JOB(SizeOfPackExprParts, SizeOfPackExpr, SizeOfPackExprPartsKind)
1761DEF_JOB(LambdaExprParts, LambdaExpr, LambdaExprPartsKind)
1762DEF_JOB(PostChildrenVisit, void, PostChildrenVisitKind)
1763#undef DEF_JOB
1764
1765class DeclVisit : public VisitorJob {
1766public:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001767 DeclVisit(const Decl *D, CXCursor parent, bool isFirst) :
Guy Benyei11169dd2012-12-18 14:30:41 +00001768 VisitorJob(parent, VisitorJob::DeclVisitKind,
Craig Topper69186e72014-06-08 08:38:04 +00001769 D, isFirst ? (void*) 1 : (void*) nullptr) {}
Guy Benyei11169dd2012-12-18 14:30:41 +00001770 static bool classof(const VisitorJob *VJ) {
1771 return VJ->getKind() == DeclVisitKind;
1772 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001773 const Decl *get() const { return static_cast<const Decl *>(data[0]); }
Dmitri Gribenkoe5423a72015-03-23 19:23:50 +00001774 bool isFirst() const { return data[1] != nullptr; }
Guy Benyei11169dd2012-12-18 14:30:41 +00001775};
1776class TypeLocVisit : public VisitorJob {
1777public:
1778 TypeLocVisit(TypeLoc tl, CXCursor parent) :
1779 VisitorJob(parent, VisitorJob::TypeLocVisitKind,
1780 tl.getType().getAsOpaquePtr(), tl.getOpaqueData()) {}
1781
1782 static bool classof(const VisitorJob *VJ) {
1783 return VJ->getKind() == TypeLocVisitKind;
1784 }
1785
1786 TypeLoc get() const {
1787 QualType T = QualType::getFromOpaquePtr(data[0]);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001788 return TypeLoc(T, const_cast<void *>(data[1]));
Guy Benyei11169dd2012-12-18 14:30:41 +00001789 }
1790};
1791
1792class LabelRefVisit : public VisitorJob {
1793public:
1794 LabelRefVisit(LabelDecl *LD, SourceLocation labelLoc, CXCursor parent)
1795 : VisitorJob(parent, VisitorJob::LabelRefVisitKind, LD,
1796 labelLoc.getPtrEncoding()) {}
1797
1798 static bool classof(const VisitorJob *VJ) {
1799 return VJ->getKind() == VisitorJob::LabelRefVisitKind;
1800 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001801 const LabelDecl *get() const {
1802 return static_cast<const LabelDecl *>(data[0]);
1803 }
Guy Benyei11169dd2012-12-18 14:30:41 +00001804 SourceLocation getLoc() const {
1805 return SourceLocation::getFromPtrEncoding(data[1]); }
1806};
1807
1808class NestedNameSpecifierLocVisit : public VisitorJob {
1809public:
1810 NestedNameSpecifierLocVisit(NestedNameSpecifierLoc Qualifier, CXCursor parent)
1811 : VisitorJob(parent, VisitorJob::NestedNameSpecifierLocVisitKind,
1812 Qualifier.getNestedNameSpecifier(),
1813 Qualifier.getOpaqueData()) { }
1814
1815 static bool classof(const VisitorJob *VJ) {
1816 return VJ->getKind() == VisitorJob::NestedNameSpecifierLocVisitKind;
1817 }
1818
1819 NestedNameSpecifierLoc get() const {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001820 return NestedNameSpecifierLoc(
1821 const_cast<NestedNameSpecifier *>(
1822 static_cast<const NestedNameSpecifier *>(data[0])),
1823 const_cast<void *>(data[1]));
Guy Benyei11169dd2012-12-18 14:30:41 +00001824 }
1825};
1826
1827class DeclarationNameInfoVisit : public VisitorJob {
1828public:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001829 DeclarationNameInfoVisit(const Stmt *S, CXCursor parent)
Dmitri Gribenkodd7dacf2013-02-03 13:19:54 +00001830 : VisitorJob(parent, VisitorJob::DeclarationNameInfoVisitKind, S) {}
Guy Benyei11169dd2012-12-18 14:30:41 +00001831 static bool classof(const VisitorJob *VJ) {
1832 return VJ->getKind() == VisitorJob::DeclarationNameInfoVisitKind;
1833 }
1834 DeclarationNameInfo get() const {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001835 const Stmt *S = static_cast<const Stmt *>(data[0]);
Guy Benyei11169dd2012-12-18 14:30:41 +00001836 switch (S->getStmtClass()) {
1837 default:
1838 llvm_unreachable("Unhandled Stmt");
1839 case clang::Stmt::MSDependentExistsStmtClass:
1840 return cast<MSDependentExistsStmt>(S)->getNameInfo();
1841 case Stmt::CXXDependentScopeMemberExprClass:
1842 return cast<CXXDependentScopeMemberExpr>(S)->getMemberNameInfo();
1843 case Stmt::DependentScopeDeclRefExprClass:
1844 return cast<DependentScopeDeclRefExpr>(S)->getNameInfo();
Alexander Musmand9ed09f2014-07-21 09:42:05 +00001845 case Stmt::OMPCriticalDirectiveClass:
1846 return cast<OMPCriticalDirective>(S)->getDirectiveName();
Guy Benyei11169dd2012-12-18 14:30:41 +00001847 }
1848 }
1849};
1850class MemberRefVisit : public VisitorJob {
1851public:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001852 MemberRefVisit(const FieldDecl *D, SourceLocation L, CXCursor parent)
Guy Benyei11169dd2012-12-18 14:30:41 +00001853 : VisitorJob(parent, VisitorJob::MemberRefVisitKind, D,
1854 L.getPtrEncoding()) {}
1855 static bool classof(const VisitorJob *VJ) {
1856 return VJ->getKind() == VisitorJob::MemberRefVisitKind;
1857 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001858 const FieldDecl *get() const {
1859 return static_cast<const FieldDecl *>(data[0]);
Guy Benyei11169dd2012-12-18 14:30:41 +00001860 }
1861 SourceLocation getLoc() const {
1862 return SourceLocation::getFromRawEncoding((unsigned)(uintptr_t) data[1]);
1863 }
1864};
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001865class EnqueueVisitor : public ConstStmtVisitor<EnqueueVisitor, void> {
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001866 friend class OMPClauseEnqueue;
Guy Benyei11169dd2012-12-18 14:30:41 +00001867 VisitorWorkList &WL;
1868 CXCursor Parent;
1869public:
1870 EnqueueVisitor(VisitorWorkList &wl, CXCursor parent)
1871 : WL(wl), Parent(parent) {}
1872
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001873 void VisitAddrLabelExpr(const AddrLabelExpr *E);
1874 void VisitBlockExpr(const BlockExpr *B);
1875 void VisitCompoundLiteralExpr(const CompoundLiteralExpr *E);
1876 void VisitCompoundStmt(const CompoundStmt *S);
1877 void VisitCXXDefaultArgExpr(const CXXDefaultArgExpr *E) { /* Do nothing. */ }
1878 void VisitMSDependentExistsStmt(const MSDependentExistsStmt *S);
1879 void VisitCXXDependentScopeMemberExpr(const CXXDependentScopeMemberExpr *E);
1880 void VisitCXXNewExpr(const CXXNewExpr *E);
1881 void VisitCXXScalarValueInitExpr(const CXXScalarValueInitExpr *E);
1882 void VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *E);
1883 void VisitCXXPseudoDestructorExpr(const CXXPseudoDestructorExpr *E);
1884 void VisitCXXTemporaryObjectExpr(const CXXTemporaryObjectExpr *E);
1885 void VisitCXXTypeidExpr(const CXXTypeidExpr *E);
1886 void VisitCXXUnresolvedConstructExpr(const CXXUnresolvedConstructExpr *E);
1887 void VisitCXXUuidofExpr(const CXXUuidofExpr *E);
1888 void VisitCXXCatchStmt(const CXXCatchStmt *S);
Argyrios Kyrtzidis99891242014-11-13 09:03:21 +00001889 void VisitCXXForRangeStmt(const CXXForRangeStmt *S);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001890 void VisitDeclRefExpr(const DeclRefExpr *D);
1891 void VisitDeclStmt(const DeclStmt *S);
1892 void VisitDependentScopeDeclRefExpr(const DependentScopeDeclRefExpr *E);
1893 void VisitDesignatedInitExpr(const DesignatedInitExpr *E);
1894 void VisitExplicitCastExpr(const ExplicitCastExpr *E);
1895 void VisitForStmt(const ForStmt *FS);
1896 void VisitGotoStmt(const GotoStmt *GS);
1897 void VisitIfStmt(const IfStmt *If);
1898 void VisitInitListExpr(const InitListExpr *IE);
1899 void VisitMemberExpr(const MemberExpr *M);
1900 void VisitOffsetOfExpr(const OffsetOfExpr *E);
1901 void VisitObjCEncodeExpr(const ObjCEncodeExpr *E);
1902 void VisitObjCMessageExpr(const ObjCMessageExpr *M);
1903 void VisitOverloadExpr(const OverloadExpr *E);
1904 void VisitUnaryExprOrTypeTraitExpr(const UnaryExprOrTypeTraitExpr *E);
1905 void VisitStmt(const Stmt *S);
1906 void VisitSwitchStmt(const SwitchStmt *S);
1907 void VisitWhileStmt(const WhileStmt *W);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001908 void VisitTypeTraitExpr(const TypeTraitExpr *E);
1909 void VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *E);
1910 void VisitExpressionTraitExpr(const ExpressionTraitExpr *E);
1911 void VisitUnresolvedMemberExpr(const UnresolvedMemberExpr *U);
1912 void VisitVAArgExpr(const VAArgExpr *E);
1913 void VisitSizeOfPackExpr(const SizeOfPackExpr *E);
1914 void VisitPseudoObjectExpr(const PseudoObjectExpr *E);
1915 void VisitOpaqueValueExpr(const OpaqueValueExpr *E);
1916 void VisitLambdaExpr(const LambdaExpr *E);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001917 void VisitOMPExecutableDirective(const OMPExecutableDirective *D);
Alexander Musman3aaab662014-08-19 11:27:13 +00001918 void VisitOMPLoopDirective(const OMPLoopDirective *D);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001919 void VisitOMPParallelDirective(const OMPParallelDirective *D);
Alexey Bataev1b59ab52014-02-27 08:29:12 +00001920 void VisitOMPSimdDirective(const OMPSimdDirective *D);
Alexey Bataevf29276e2014-06-18 04:14:57 +00001921 void VisitOMPForDirective(const OMPForDirective *D);
Alexander Musmanf82886e2014-09-18 05:12:34 +00001922 void VisitOMPForSimdDirective(const OMPForSimdDirective *D);
Alexey Bataevd3f8dd22014-06-25 11:44:49 +00001923 void VisitOMPSectionsDirective(const OMPSectionsDirective *D);
Alexey Bataev1e0498a2014-06-26 08:21:58 +00001924 void VisitOMPSectionDirective(const OMPSectionDirective *D);
Alexey Bataevd1e40fb2014-06-26 12:05:45 +00001925 void VisitOMPSingleDirective(const OMPSingleDirective *D);
Alexander Musman80c22892014-07-17 08:54:58 +00001926 void VisitOMPMasterDirective(const OMPMasterDirective *D);
Alexander Musmand9ed09f2014-07-21 09:42:05 +00001927 void VisitOMPCriticalDirective(const OMPCriticalDirective *D);
Alexey Bataev4acb8592014-07-07 13:01:15 +00001928 void VisitOMPParallelForDirective(const OMPParallelForDirective *D);
Alexander Musmane4e893b2014-09-23 09:33:00 +00001929 void VisitOMPParallelForSimdDirective(const OMPParallelForSimdDirective *D);
Alexey Bataev84d0b3e2014-07-08 08:12:03 +00001930 void VisitOMPParallelSectionsDirective(const OMPParallelSectionsDirective *D);
Alexey Bataev9c2e8ee2014-07-11 11:25:16 +00001931 void VisitOMPTaskDirective(const OMPTaskDirective *D);
Alexey Bataev68446b72014-07-18 07:47:19 +00001932 void VisitOMPTaskyieldDirective(const OMPTaskyieldDirective *D);
Alexey Bataev4d1dfea2014-07-18 09:11:51 +00001933 void VisitOMPBarrierDirective(const OMPBarrierDirective *D);
Alexey Bataev2df347a2014-07-18 10:17:07 +00001934 void VisitOMPTaskwaitDirective(const OMPTaskwaitDirective *D);
Alexey Bataevc30dd2d2015-06-18 12:14:09 +00001935 void VisitOMPTaskgroupDirective(const OMPTaskgroupDirective *D);
Alexey Bataev6d4ed052015-07-01 06:57:41 +00001936 void
1937 VisitOMPCancellationPointDirective(const OMPCancellationPointDirective *D);
Alexey Bataev80909872015-07-02 11:25:17 +00001938 void VisitOMPCancelDirective(const OMPCancelDirective *D);
Alexey Bataev6125da92014-07-21 11:26:11 +00001939 void VisitOMPFlushDirective(const OMPFlushDirective *D);
Alexey Bataev9fb6e642014-07-22 06:45:04 +00001940 void VisitOMPOrderedDirective(const OMPOrderedDirective *D);
Alexey Bataev0162e452014-07-22 10:10:35 +00001941 void VisitOMPAtomicDirective(const OMPAtomicDirective *D);
Alexey Bataev0bd520b2014-09-19 08:19:49 +00001942 void VisitOMPTargetDirective(const OMPTargetDirective *D);
Michael Wong65f367f2015-07-21 13:44:28 +00001943 void VisitOMPTargetDataDirective(const OMPTargetDataDirective *D);
Alexey Bataev13314bf2014-10-09 04:18:56 +00001944 void VisitOMPTeamsDirective(const OMPTeamsDirective *D);
Alexey Bataev49f6e782015-12-01 04:18:41 +00001945 void VisitOMPTaskLoopDirective(const OMPTaskLoopDirective *D);
Alexey Bataev0a6ed842015-12-03 09:40:15 +00001946 void VisitOMPTaskLoopSimdDirective(const OMPTaskLoopSimdDirective *D);
Carlo Bertolli6200a3d2015-12-14 14:51:25 +00001947 void VisitOMPDistributeDirective(const OMPDistributeDirective *D);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001948
Guy Benyei11169dd2012-12-18 14:30:41 +00001949private:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001950 void AddDeclarationNameInfo(const Stmt *S);
Guy Benyei11169dd2012-12-18 14:30:41 +00001951 void AddNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier);
1952 void AddExplicitTemplateArgs(const ASTTemplateArgumentListInfo *A);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001953 void AddMemberRef(const FieldDecl *D, SourceLocation L);
1954 void AddStmt(const Stmt *S);
1955 void AddDecl(const Decl *D, bool isFirst = true);
Guy Benyei11169dd2012-12-18 14:30:41 +00001956 void AddTypeLoc(TypeSourceInfo *TI);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001957 void EnqueueChildren(const Stmt *S);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001958 void EnqueueChildren(const OMPClause *S);
Guy Benyei11169dd2012-12-18 14:30:41 +00001959};
Alexander Kornienkoab9db512015-06-22 23:07:51 +00001960} // end anonyous namespace
Guy Benyei11169dd2012-12-18 14:30:41 +00001961
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001962void EnqueueVisitor::AddDeclarationNameInfo(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001963 // 'S' should always be non-null, since it comes from the
1964 // statement we are visiting.
1965 WL.push_back(DeclarationNameInfoVisit(S, Parent));
1966}
1967
1968void
1969EnqueueVisitor::AddNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier) {
1970 if (Qualifier)
1971 WL.push_back(NestedNameSpecifierLocVisit(Qualifier, Parent));
1972}
1973
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001974void EnqueueVisitor::AddStmt(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001975 if (S)
1976 WL.push_back(StmtVisit(S, Parent));
1977}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001978void EnqueueVisitor::AddDecl(const Decl *D, bool isFirst) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001979 if (D)
1980 WL.push_back(DeclVisit(D, Parent, isFirst));
1981}
1982void EnqueueVisitor::
1983 AddExplicitTemplateArgs(const ASTTemplateArgumentListInfo *A) {
1984 if (A)
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001985 WL.push_back(ExplicitTemplateArgsVisit(A, Parent));
Guy Benyei11169dd2012-12-18 14:30:41 +00001986}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001987void EnqueueVisitor::AddMemberRef(const FieldDecl *D, SourceLocation L) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001988 if (D)
1989 WL.push_back(MemberRefVisit(D, L, Parent));
1990}
1991void EnqueueVisitor::AddTypeLoc(TypeSourceInfo *TI) {
1992 if (TI)
1993 WL.push_back(TypeLocVisit(TI->getTypeLoc(), Parent));
1994 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001995void EnqueueVisitor::EnqueueChildren(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001996 unsigned size = WL.size();
Benjamin Kramer642f1732015-07-02 21:03:14 +00001997 for (const Stmt *SubStmt : S->children()) {
1998 AddStmt(SubStmt);
Guy Benyei11169dd2012-12-18 14:30:41 +00001999 }
2000 if (size == WL.size())
2001 return;
2002 // Now reverse the entries we just added. This will match the DFS
2003 // ordering performed by the worklist.
2004 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
2005 std::reverse(I, E);
2006}
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002007namespace {
2008class OMPClauseEnqueue : public ConstOMPClauseVisitor<OMPClauseEnqueue> {
2009 EnqueueVisitor *Visitor;
Alexey Bataev756c1962013-09-24 03:17:45 +00002010 /// \brief Process clauses with list of variables.
2011 template <typename T>
2012 void VisitOMPClauseList(T *Node);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002013public:
2014 OMPClauseEnqueue(EnqueueVisitor *Visitor) : Visitor(Visitor) { }
2015#define OPENMP_CLAUSE(Name, Class) \
2016 void Visit##Class(const Class *C);
2017#include "clang/Basic/OpenMPKinds.def"
2018};
2019
Alexey Bataevaadd52e2014-02-13 05:29:23 +00002020void OMPClauseEnqueue::VisitOMPIfClause(const OMPIfClause *C) {
2021 Visitor->AddStmt(C->getCondition());
2022}
2023
Alexey Bataev3778b602014-07-17 07:32:53 +00002024void OMPClauseEnqueue::VisitOMPFinalClause(const OMPFinalClause *C) {
2025 Visitor->AddStmt(C->getCondition());
2026}
2027
Alexey Bataev568a8332014-03-06 06:15:19 +00002028void OMPClauseEnqueue::VisitOMPNumThreadsClause(const OMPNumThreadsClause *C) {
2029 Visitor->AddStmt(C->getNumThreads());
2030}
2031
Alexey Bataev62c87d22014-03-21 04:51:18 +00002032void OMPClauseEnqueue::VisitOMPSafelenClause(const OMPSafelenClause *C) {
2033 Visitor->AddStmt(C->getSafelen());
2034}
2035
Alexey Bataev66b15b52015-08-21 11:14:16 +00002036void OMPClauseEnqueue::VisitOMPSimdlenClause(const OMPSimdlenClause *C) {
2037 Visitor->AddStmt(C->getSimdlen());
2038}
2039
Alexander Musman8bd31e62014-05-27 15:12:19 +00002040void OMPClauseEnqueue::VisitOMPCollapseClause(const OMPCollapseClause *C) {
2041 Visitor->AddStmt(C->getNumForLoops());
2042}
2043
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002044void OMPClauseEnqueue::VisitOMPDefaultClause(const OMPDefaultClause *C) { }
Alexey Bataev756c1962013-09-24 03:17:45 +00002045
Alexey Bataevbcbadb62014-05-06 06:04:14 +00002046void OMPClauseEnqueue::VisitOMPProcBindClause(const OMPProcBindClause *C) { }
2047
Alexey Bataev56dafe82014-06-20 07:16:17 +00002048void OMPClauseEnqueue::VisitOMPScheduleClause(const OMPScheduleClause *C) {
2049 Visitor->AddStmt(C->getChunkSize());
Alexey Bataev040d5402015-05-12 08:35:28 +00002050 Visitor->AddStmt(C->getHelperChunkSize());
Alexey Bataev56dafe82014-06-20 07:16:17 +00002051}
2052
Alexey Bataev10e775f2015-07-30 11:36:16 +00002053void OMPClauseEnqueue::VisitOMPOrderedClause(const OMPOrderedClause *C) {
2054 Visitor->AddStmt(C->getNumForLoops());
2055}
Alexey Bataev142e1fc2014-06-20 09:44:06 +00002056
Alexey Bataev236070f2014-06-20 11:19:47 +00002057void OMPClauseEnqueue::VisitOMPNowaitClause(const OMPNowaitClause *) {}
2058
Alexey Bataev7aea99a2014-07-17 12:19:31 +00002059void OMPClauseEnqueue::VisitOMPUntiedClause(const OMPUntiedClause *) {}
2060
Alexey Bataev74ba3a52014-07-17 12:47:03 +00002061void OMPClauseEnqueue::VisitOMPMergeableClause(const OMPMergeableClause *) {}
2062
Alexey Bataevf98b00c2014-07-23 02:27:21 +00002063void OMPClauseEnqueue::VisitOMPReadClause(const OMPReadClause *) {}
2064
Alexey Bataevdea47612014-07-23 07:46:59 +00002065void OMPClauseEnqueue::VisitOMPWriteClause(const OMPWriteClause *) {}
2066
Alexey Bataev67a4f222014-07-23 10:25:33 +00002067void OMPClauseEnqueue::VisitOMPUpdateClause(const OMPUpdateClause *) {}
2068
Alexey Bataev459dec02014-07-24 06:46:57 +00002069void OMPClauseEnqueue::VisitOMPCaptureClause(const OMPCaptureClause *) {}
2070
Alexey Bataev82bad8b2014-07-24 08:55:34 +00002071void OMPClauseEnqueue::VisitOMPSeqCstClause(const OMPSeqCstClause *) {}
2072
Alexey Bataev346265e2015-09-25 10:37:12 +00002073void OMPClauseEnqueue::VisitOMPThreadsClause(const OMPThreadsClause *) {}
2074
Alexey Bataevd14d1e62015-09-28 06:39:35 +00002075void OMPClauseEnqueue::VisitOMPSIMDClause(const OMPSIMDClause *) {}
2076
Alexey Bataevb825de12015-12-07 10:51:44 +00002077void OMPClauseEnqueue::VisitOMPNogroupClause(const OMPNogroupClause *) {}
2078
Michael Wonge710d542015-08-07 16:16:36 +00002079void OMPClauseEnqueue::VisitOMPDeviceClause(const OMPDeviceClause *C) {
2080 Visitor->AddStmt(C->getDevice());
2081}
2082
Kelvin Li099bb8c2015-11-24 20:50:12 +00002083void OMPClauseEnqueue::VisitOMPNumTeamsClause(const OMPNumTeamsClause *C) {
2084 Visitor->AddStmt(C->getNumTeams());
2085}
2086
Kelvin Lia15fb1a2015-11-27 18:47:36 +00002087void OMPClauseEnqueue::VisitOMPThreadLimitClause(const OMPThreadLimitClause *C) {
2088 Visitor->AddStmt(C->getThreadLimit());
2089}
2090
Alexey Bataeva0569352015-12-01 10:17:31 +00002091void OMPClauseEnqueue::VisitOMPPriorityClause(const OMPPriorityClause *C) {
2092 Visitor->AddStmt(C->getPriority());
2093}
2094
Alexey Bataev1fd4aed2015-12-07 12:52:51 +00002095void OMPClauseEnqueue::VisitOMPGrainsizeClause(const OMPGrainsizeClause *C) {
2096 Visitor->AddStmt(C->getGrainsize());
2097}
2098
Alexey Bataev382967a2015-12-08 12:06:20 +00002099void OMPClauseEnqueue::VisitOMPNumTasksClause(const OMPNumTasksClause *C) {
2100 Visitor->AddStmt(C->getNumTasks());
2101}
2102
Alexey Bataev756c1962013-09-24 03:17:45 +00002103template<typename T>
2104void OMPClauseEnqueue::VisitOMPClauseList(T *Node) {
Alexey Bataev03b340a2014-10-21 03:16:40 +00002105 for (const auto *I : Node->varlists()) {
Aaron Ballman2205d2a2014-03-14 15:55:35 +00002106 Visitor->AddStmt(I);
Alexey Bataev03b340a2014-10-21 03:16:40 +00002107 }
Alexey Bataev756c1962013-09-24 03:17:45 +00002108}
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002109
2110void OMPClauseEnqueue::VisitOMPPrivateClause(const OMPPrivateClause *C) {
Alexey Bataev756c1962013-09-24 03:17:45 +00002111 VisitOMPClauseList(C);
Alexey Bataev03b340a2014-10-21 03:16:40 +00002112 for (const auto *E : C->private_copies()) {
2113 Visitor->AddStmt(E);
2114 }
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002115}
Alexey Bataevd5af8e42013-10-01 05:32:34 +00002116void OMPClauseEnqueue::VisitOMPFirstprivateClause(
2117 const OMPFirstprivateClause *C) {
2118 VisitOMPClauseList(C);
2119}
Alexander Musman1bb328c2014-06-04 13:06:39 +00002120void OMPClauseEnqueue::VisitOMPLastprivateClause(
2121 const OMPLastprivateClause *C) {
2122 VisitOMPClauseList(C);
Alexey Bataev38e89532015-04-16 04:54:05 +00002123 for (auto *E : C->private_copies()) {
2124 Visitor->AddStmt(E);
2125 }
2126 for (auto *E : C->source_exprs()) {
2127 Visitor->AddStmt(E);
2128 }
2129 for (auto *E : C->destination_exprs()) {
2130 Visitor->AddStmt(E);
2131 }
2132 for (auto *E : C->assignment_ops()) {
2133 Visitor->AddStmt(E);
2134 }
Alexander Musman1bb328c2014-06-04 13:06:39 +00002135}
Alexey Bataev758e55e2013-09-06 18:03:48 +00002136void OMPClauseEnqueue::VisitOMPSharedClause(const OMPSharedClause *C) {
Alexey Bataev756c1962013-09-24 03:17:45 +00002137 VisitOMPClauseList(C);
Alexey Bataev758e55e2013-09-06 18:03:48 +00002138}
Alexey Bataevc5e02582014-06-16 07:08:35 +00002139void OMPClauseEnqueue::VisitOMPReductionClause(const OMPReductionClause *C) {
2140 VisitOMPClauseList(C);
Alexey Bataevf24e7b12015-10-08 09:10:53 +00002141 for (auto *E : C->privates()) {
2142 Visitor->AddStmt(E);
2143 }
Alexey Bataev794ba0d2015-04-10 10:43:45 +00002144 for (auto *E : C->lhs_exprs()) {
2145 Visitor->AddStmt(E);
2146 }
2147 for (auto *E : C->rhs_exprs()) {
2148 Visitor->AddStmt(E);
2149 }
2150 for (auto *E : C->reduction_ops()) {
2151 Visitor->AddStmt(E);
2152 }
Alexey Bataevc5e02582014-06-16 07:08:35 +00002153}
Alexander Musman8dba6642014-04-22 13:09:42 +00002154void OMPClauseEnqueue::VisitOMPLinearClause(const OMPLinearClause *C) {
2155 VisitOMPClauseList(C);
Alexey Bataevbd9fec12015-08-18 06:47:21 +00002156 for (const auto *E : C->privates()) {
2157 Visitor->AddStmt(E);
2158 }
Alexander Musman3276a272015-03-21 10:12:56 +00002159 for (const auto *E : C->inits()) {
2160 Visitor->AddStmt(E);
2161 }
2162 for (const auto *E : C->updates()) {
2163 Visitor->AddStmt(E);
2164 }
2165 for (const auto *E : C->finals()) {
2166 Visitor->AddStmt(E);
2167 }
Alexander Musman8dba6642014-04-22 13:09:42 +00002168 Visitor->AddStmt(C->getStep());
Alexander Musman3276a272015-03-21 10:12:56 +00002169 Visitor->AddStmt(C->getCalcStep());
Alexander Musman8dba6642014-04-22 13:09:42 +00002170}
Alexander Musmanf0d76e72014-05-29 14:36:25 +00002171void OMPClauseEnqueue::VisitOMPAlignedClause(const OMPAlignedClause *C) {
2172 VisitOMPClauseList(C);
2173 Visitor->AddStmt(C->getAlignment());
2174}
Alexey Bataevd48bcd82014-03-31 03:36:38 +00002175void OMPClauseEnqueue::VisitOMPCopyinClause(const OMPCopyinClause *C) {
2176 VisitOMPClauseList(C);
Alexey Bataevf56f98c2015-04-16 05:39:01 +00002177 for (auto *E : C->source_exprs()) {
2178 Visitor->AddStmt(E);
2179 }
2180 for (auto *E : C->destination_exprs()) {
2181 Visitor->AddStmt(E);
2182 }
2183 for (auto *E : C->assignment_ops()) {
2184 Visitor->AddStmt(E);
2185 }
Alexey Bataevd48bcd82014-03-31 03:36:38 +00002186}
Alexey Bataevbae9a792014-06-27 10:37:06 +00002187void
2188OMPClauseEnqueue::VisitOMPCopyprivateClause(const OMPCopyprivateClause *C) {
2189 VisitOMPClauseList(C);
Alexey Bataeva63048e2015-03-23 06:18:07 +00002190 for (auto *E : C->source_exprs()) {
2191 Visitor->AddStmt(E);
2192 }
2193 for (auto *E : C->destination_exprs()) {
2194 Visitor->AddStmt(E);
2195 }
2196 for (auto *E : C->assignment_ops()) {
2197 Visitor->AddStmt(E);
2198 }
Alexey Bataevbae9a792014-06-27 10:37:06 +00002199}
Alexey Bataev6125da92014-07-21 11:26:11 +00002200void OMPClauseEnqueue::VisitOMPFlushClause(const OMPFlushClause *C) {
2201 VisitOMPClauseList(C);
2202}
Alexey Bataev1c2cfbc2015-06-23 14:25:19 +00002203void OMPClauseEnqueue::VisitOMPDependClause(const OMPDependClause *C) {
2204 VisitOMPClauseList(C);
2205}
Kelvin Li0bff7af2015-11-23 05:32:03 +00002206void OMPClauseEnqueue::VisitOMPMapClause(const OMPMapClause *C) {
2207 VisitOMPClauseList(C);
2208}
Alexander Kornienkoab9db512015-06-22 23:07:51 +00002209}
Alexey Bataev756c1962013-09-24 03:17:45 +00002210
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002211void EnqueueVisitor::EnqueueChildren(const OMPClause *S) {
2212 unsigned size = WL.size();
2213 OMPClauseEnqueue Visitor(this);
2214 Visitor.Visit(S);
2215 if (size == WL.size())
2216 return;
2217 // Now reverse the entries we just added. This will match the DFS
2218 // ordering performed by the worklist.
2219 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
2220 std::reverse(I, E);
2221}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002222void EnqueueVisitor::VisitAddrLabelExpr(const AddrLabelExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002223 WL.push_back(LabelRefVisit(E->getLabel(), E->getLabelLoc(), Parent));
2224}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002225void EnqueueVisitor::VisitBlockExpr(const BlockExpr *B) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002226 AddDecl(B->getBlockDecl());
2227}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002228void EnqueueVisitor::VisitCompoundLiteralExpr(const CompoundLiteralExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002229 EnqueueChildren(E);
2230 AddTypeLoc(E->getTypeSourceInfo());
2231}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002232void EnqueueVisitor::VisitCompoundStmt(const CompoundStmt *S) {
Pete Cooper57d3f142015-07-30 17:22:52 +00002233 for (auto &I : llvm::reverse(S->body()))
2234 AddStmt(I);
Guy Benyei11169dd2012-12-18 14:30:41 +00002235}
2236void EnqueueVisitor::
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002237VisitMSDependentExistsStmt(const MSDependentExistsStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002238 AddStmt(S->getSubStmt());
2239 AddDeclarationNameInfo(S);
2240 if (NestedNameSpecifierLoc QualifierLoc = S->getQualifierLoc())
2241 AddNestedNameSpecifierLoc(QualifierLoc);
2242}
2243
2244void EnqueueVisitor::
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002245VisitCXXDependentScopeMemberExpr(const CXXDependentScopeMemberExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002246 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
2247 AddDeclarationNameInfo(E);
2248 if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
2249 AddNestedNameSpecifierLoc(QualifierLoc);
2250 if (!E->isImplicitAccess())
2251 AddStmt(E->getBase());
2252}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002253void EnqueueVisitor::VisitCXXNewExpr(const CXXNewExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002254 // Enqueue the initializer , if any.
2255 AddStmt(E->getInitializer());
2256 // Enqueue the array size, if any.
2257 AddStmt(E->getArraySize());
2258 // Enqueue the allocated type.
2259 AddTypeLoc(E->getAllocatedTypeSourceInfo());
2260 // Enqueue the placement arguments.
2261 for (unsigned I = E->getNumPlacementArgs(); I > 0; --I)
2262 AddStmt(E->getPlacementArg(I-1));
2263}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002264void EnqueueVisitor::VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *CE) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002265 for (unsigned I = CE->getNumArgs(); I > 1 /* Yes, this is 1 */; --I)
2266 AddStmt(CE->getArg(I-1));
2267 AddStmt(CE->getCallee());
2268 AddStmt(CE->getArg(0));
2269}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002270void EnqueueVisitor::VisitCXXPseudoDestructorExpr(
2271 const CXXPseudoDestructorExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002272 // Visit the name of the type being destroyed.
2273 AddTypeLoc(E->getDestroyedTypeInfo());
2274 // Visit the scope type that looks disturbingly like the nested-name-specifier
2275 // but isn't.
2276 AddTypeLoc(E->getScopeTypeInfo());
2277 // Visit the nested-name-specifier.
2278 if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
2279 AddNestedNameSpecifierLoc(QualifierLoc);
2280 // Visit base expression.
2281 AddStmt(E->getBase());
2282}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002283void EnqueueVisitor::VisitCXXScalarValueInitExpr(
2284 const CXXScalarValueInitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002285 AddTypeLoc(E->getTypeSourceInfo());
2286}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002287void EnqueueVisitor::VisitCXXTemporaryObjectExpr(
2288 const CXXTemporaryObjectExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002289 EnqueueChildren(E);
2290 AddTypeLoc(E->getTypeSourceInfo());
2291}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002292void EnqueueVisitor::VisitCXXTypeidExpr(const CXXTypeidExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002293 EnqueueChildren(E);
2294 if (E->isTypeOperand())
2295 AddTypeLoc(E->getTypeOperandSourceInfo());
2296}
2297
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002298void EnqueueVisitor::VisitCXXUnresolvedConstructExpr(
2299 const CXXUnresolvedConstructExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002300 EnqueueChildren(E);
2301 AddTypeLoc(E->getTypeSourceInfo());
2302}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002303void EnqueueVisitor::VisitCXXUuidofExpr(const CXXUuidofExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002304 EnqueueChildren(E);
2305 if (E->isTypeOperand())
2306 AddTypeLoc(E->getTypeOperandSourceInfo());
2307}
2308
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002309void EnqueueVisitor::VisitCXXCatchStmt(const CXXCatchStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002310 EnqueueChildren(S);
2311 AddDecl(S->getExceptionDecl());
2312}
2313
Argyrios Kyrtzidis99891242014-11-13 09:03:21 +00002314void EnqueueVisitor::VisitCXXForRangeStmt(const CXXForRangeStmt *S) {
Argyrios Kyrtzidiscde70692014-11-13 09:50:19 +00002315 AddStmt(S->getBody());
Argyrios Kyrtzidis99891242014-11-13 09:03:21 +00002316 AddStmt(S->getRangeInit());
Argyrios Kyrtzidiscde70692014-11-13 09:50:19 +00002317 AddDecl(S->getLoopVariable());
Argyrios Kyrtzidis99891242014-11-13 09:03:21 +00002318}
2319
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002320void EnqueueVisitor::VisitDeclRefExpr(const DeclRefExpr *DR) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002321 if (DR->hasExplicitTemplateArgs()) {
2322 AddExplicitTemplateArgs(&DR->getExplicitTemplateArgs());
2323 }
2324 WL.push_back(DeclRefExprParts(DR, Parent));
2325}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002326void EnqueueVisitor::VisitDependentScopeDeclRefExpr(
2327 const DependentScopeDeclRefExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002328 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
2329 AddDeclarationNameInfo(E);
2330 AddNestedNameSpecifierLoc(E->getQualifierLoc());
2331}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002332void EnqueueVisitor::VisitDeclStmt(const DeclStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002333 unsigned size = WL.size();
2334 bool isFirst = true;
Aaron Ballman535bbcc2014-03-14 17:01:24 +00002335 for (const auto *D : S->decls()) {
2336 AddDecl(D, isFirst);
Guy Benyei11169dd2012-12-18 14:30:41 +00002337 isFirst = false;
2338 }
2339 if (size == WL.size())
2340 return;
2341 // Now reverse the entries we just added. This will match the DFS
2342 // ordering performed by the worklist.
2343 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
2344 std::reverse(I, E);
2345}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002346void EnqueueVisitor::VisitDesignatedInitExpr(const DesignatedInitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002347 AddStmt(E->getInit());
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002348 for (DesignatedInitExpr::const_reverse_designators_iterator
Guy Benyei11169dd2012-12-18 14:30:41 +00002349 D = E->designators_rbegin(), DEnd = E->designators_rend();
2350 D != DEnd; ++D) {
2351 if (D->isFieldDesignator()) {
2352 if (FieldDecl *Field = D->getField())
2353 AddMemberRef(Field, D->getFieldLoc());
2354 continue;
2355 }
2356 if (D->isArrayDesignator()) {
2357 AddStmt(E->getArrayIndex(*D));
2358 continue;
2359 }
2360 assert(D->isArrayRangeDesignator() && "Unknown designator kind");
2361 AddStmt(E->getArrayRangeEnd(*D));
2362 AddStmt(E->getArrayRangeStart(*D));
2363 }
2364}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002365void EnqueueVisitor::VisitExplicitCastExpr(const ExplicitCastExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002366 EnqueueChildren(E);
2367 AddTypeLoc(E->getTypeInfoAsWritten());
2368}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002369void EnqueueVisitor::VisitForStmt(const ForStmt *FS) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002370 AddStmt(FS->getBody());
2371 AddStmt(FS->getInc());
2372 AddStmt(FS->getCond());
2373 AddDecl(FS->getConditionVariable());
2374 AddStmt(FS->getInit());
2375}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002376void EnqueueVisitor::VisitGotoStmt(const GotoStmt *GS) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002377 WL.push_back(LabelRefVisit(GS->getLabel(), GS->getLabelLoc(), Parent));
2378}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002379void EnqueueVisitor::VisitIfStmt(const IfStmt *If) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002380 AddStmt(If->getElse());
2381 AddStmt(If->getThen());
2382 AddStmt(If->getCond());
2383 AddDecl(If->getConditionVariable());
2384}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002385void EnqueueVisitor::VisitInitListExpr(const InitListExpr *IE) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002386 // We care about the syntactic form of the initializer list, only.
2387 if (InitListExpr *Syntactic = IE->getSyntacticForm())
2388 IE = Syntactic;
2389 EnqueueChildren(IE);
2390}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002391void EnqueueVisitor::VisitMemberExpr(const MemberExpr *M) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002392 WL.push_back(MemberExprParts(M, Parent));
2393
2394 // If the base of the member access expression is an implicit 'this', don't
2395 // visit it.
2396 // FIXME: If we ever want to show these implicit accesses, this will be
2397 // unfortunate. However, clang_getCursor() relies on this behavior.
Argyrios Kyrtzidis58d0e7a2015-03-13 04:40:07 +00002398 if (M->isImplicitAccess())
2399 return;
2400
2401 // Ignore base anonymous struct/union fields, otherwise they will shadow the
2402 // real field that that we are interested in.
2403 if (auto *SubME = dyn_cast<MemberExpr>(M->getBase())) {
2404 if (auto *FD = dyn_cast_or_null<FieldDecl>(SubME->getMemberDecl())) {
2405 if (FD->isAnonymousStructOrUnion()) {
2406 AddStmt(SubME->getBase());
2407 return;
2408 }
2409 }
2410 }
2411
2412 AddStmt(M->getBase());
Guy Benyei11169dd2012-12-18 14:30:41 +00002413}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002414void EnqueueVisitor::VisitObjCEncodeExpr(const ObjCEncodeExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002415 AddTypeLoc(E->getEncodedTypeSourceInfo());
2416}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002417void EnqueueVisitor::VisitObjCMessageExpr(const ObjCMessageExpr *M) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002418 EnqueueChildren(M);
2419 AddTypeLoc(M->getClassReceiverTypeInfo());
2420}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002421void EnqueueVisitor::VisitOffsetOfExpr(const OffsetOfExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002422 // Visit the components of the offsetof expression.
2423 for (unsigned N = E->getNumComponents(), I = N; I > 0; --I) {
2424 typedef OffsetOfExpr::OffsetOfNode OffsetOfNode;
2425 const OffsetOfNode &Node = E->getComponent(I-1);
2426 switch (Node.getKind()) {
2427 case OffsetOfNode::Array:
2428 AddStmt(E->getIndexExpr(Node.getArrayExprIndex()));
2429 break;
2430 case OffsetOfNode::Field:
2431 AddMemberRef(Node.getField(), Node.getSourceRange().getEnd());
2432 break;
2433 case OffsetOfNode::Identifier:
2434 case OffsetOfNode::Base:
2435 continue;
2436 }
2437 }
2438 // Visit the type into which we're computing the offset.
2439 AddTypeLoc(E->getTypeSourceInfo());
2440}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002441void EnqueueVisitor::VisitOverloadExpr(const OverloadExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002442 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
2443 WL.push_back(OverloadExprParts(E, Parent));
2444}
2445void EnqueueVisitor::VisitUnaryExprOrTypeTraitExpr(
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002446 const UnaryExprOrTypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002447 EnqueueChildren(E);
2448 if (E->isArgumentType())
2449 AddTypeLoc(E->getArgumentTypeInfo());
2450}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002451void EnqueueVisitor::VisitStmt(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002452 EnqueueChildren(S);
2453}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002454void EnqueueVisitor::VisitSwitchStmt(const SwitchStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002455 AddStmt(S->getBody());
2456 AddStmt(S->getCond());
2457 AddDecl(S->getConditionVariable());
2458}
2459
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002460void EnqueueVisitor::VisitWhileStmt(const WhileStmt *W) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002461 AddStmt(W->getBody());
2462 AddStmt(W->getCond());
2463 AddDecl(W->getConditionVariable());
2464}
2465
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002466void EnqueueVisitor::VisitTypeTraitExpr(const TypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002467 for (unsigned I = E->getNumArgs(); I > 0; --I)
2468 AddTypeLoc(E->getArg(I-1));
2469}
2470
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002471void EnqueueVisitor::VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002472 AddTypeLoc(E->getQueriedTypeSourceInfo());
2473}
2474
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002475void EnqueueVisitor::VisitExpressionTraitExpr(const ExpressionTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002476 EnqueueChildren(E);
2477}
2478
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002479void EnqueueVisitor::VisitUnresolvedMemberExpr(const UnresolvedMemberExpr *U) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002480 VisitOverloadExpr(U);
2481 if (!U->isImplicitAccess())
2482 AddStmt(U->getBase());
2483}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002484void EnqueueVisitor::VisitVAArgExpr(const VAArgExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002485 AddStmt(E->getSubExpr());
2486 AddTypeLoc(E->getWrittenTypeInfo());
2487}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002488void EnqueueVisitor::VisitSizeOfPackExpr(const SizeOfPackExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002489 WL.push_back(SizeOfPackExprParts(E, Parent));
2490}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002491void EnqueueVisitor::VisitOpaqueValueExpr(const OpaqueValueExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002492 // If the opaque value has a source expression, just transparently
2493 // visit that. This is useful for (e.g.) pseudo-object expressions.
2494 if (Expr *SourceExpr = E->getSourceExpr())
2495 return Visit(SourceExpr);
2496}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002497void EnqueueVisitor::VisitLambdaExpr(const LambdaExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002498 AddStmt(E->getBody());
2499 WL.push_back(LambdaExprParts(E, Parent));
2500}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002501void EnqueueVisitor::VisitPseudoObjectExpr(const PseudoObjectExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002502 // Treat the expression like its syntactic form.
2503 Visit(E->getSyntacticForm());
2504}
2505
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002506void EnqueueVisitor::VisitOMPExecutableDirective(
2507 const OMPExecutableDirective *D) {
2508 EnqueueChildren(D);
2509 for (ArrayRef<OMPClause *>::iterator I = D->clauses().begin(),
2510 E = D->clauses().end();
2511 I != E; ++I)
2512 EnqueueChildren(*I);
2513}
2514
Alexander Musman3aaab662014-08-19 11:27:13 +00002515void EnqueueVisitor::VisitOMPLoopDirective(const OMPLoopDirective *D) {
2516 VisitOMPExecutableDirective(D);
2517}
2518
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002519void EnqueueVisitor::VisitOMPParallelDirective(const OMPParallelDirective *D) {
2520 VisitOMPExecutableDirective(D);
2521}
2522
Alexey Bataev1b59ab52014-02-27 08:29:12 +00002523void EnqueueVisitor::VisitOMPSimdDirective(const OMPSimdDirective *D) {
Alexander Musman3aaab662014-08-19 11:27:13 +00002524 VisitOMPLoopDirective(D);
Alexey Bataev1b59ab52014-02-27 08:29:12 +00002525}
2526
Alexey Bataevf29276e2014-06-18 04:14:57 +00002527void EnqueueVisitor::VisitOMPForDirective(const OMPForDirective *D) {
Alexander Musman3aaab662014-08-19 11:27:13 +00002528 VisitOMPLoopDirective(D);
Alexey Bataevf29276e2014-06-18 04:14:57 +00002529}
2530
Alexander Musmanf82886e2014-09-18 05:12:34 +00002531void EnqueueVisitor::VisitOMPForSimdDirective(const OMPForSimdDirective *D) {
2532 VisitOMPLoopDirective(D);
2533}
2534
Alexey Bataevd3f8dd22014-06-25 11:44:49 +00002535void EnqueueVisitor::VisitOMPSectionsDirective(const OMPSectionsDirective *D) {
2536 VisitOMPExecutableDirective(D);
2537}
2538
Alexey Bataev1e0498a2014-06-26 08:21:58 +00002539void EnqueueVisitor::VisitOMPSectionDirective(const OMPSectionDirective *D) {
2540 VisitOMPExecutableDirective(D);
2541}
2542
Alexey Bataevd1e40fb2014-06-26 12:05:45 +00002543void EnqueueVisitor::VisitOMPSingleDirective(const OMPSingleDirective *D) {
2544 VisitOMPExecutableDirective(D);
2545}
2546
Alexander Musman80c22892014-07-17 08:54:58 +00002547void EnqueueVisitor::VisitOMPMasterDirective(const OMPMasterDirective *D) {
2548 VisitOMPExecutableDirective(D);
2549}
2550
Alexander Musmand9ed09f2014-07-21 09:42:05 +00002551void EnqueueVisitor::VisitOMPCriticalDirective(const OMPCriticalDirective *D) {
2552 VisitOMPExecutableDirective(D);
2553 AddDeclarationNameInfo(D);
2554}
2555
Alexey Bataev4acb8592014-07-07 13:01:15 +00002556void
2557EnqueueVisitor::VisitOMPParallelForDirective(const OMPParallelForDirective *D) {
Alexander Musman3aaab662014-08-19 11:27:13 +00002558 VisitOMPLoopDirective(D);
Alexey Bataev4acb8592014-07-07 13:01:15 +00002559}
2560
Alexander Musmane4e893b2014-09-23 09:33:00 +00002561void EnqueueVisitor::VisitOMPParallelForSimdDirective(
2562 const OMPParallelForSimdDirective *D) {
2563 VisitOMPLoopDirective(D);
2564}
2565
Alexey Bataev84d0b3e2014-07-08 08:12:03 +00002566void EnqueueVisitor::VisitOMPParallelSectionsDirective(
2567 const OMPParallelSectionsDirective *D) {
2568 VisitOMPExecutableDirective(D);
2569}
2570
Alexey Bataev9c2e8ee2014-07-11 11:25:16 +00002571void EnqueueVisitor::VisitOMPTaskDirective(const OMPTaskDirective *D) {
2572 VisitOMPExecutableDirective(D);
2573}
2574
Alexey Bataev68446b72014-07-18 07:47:19 +00002575void
2576EnqueueVisitor::VisitOMPTaskyieldDirective(const OMPTaskyieldDirective *D) {
2577 VisitOMPExecutableDirective(D);
2578}
2579
Alexey Bataev4d1dfea2014-07-18 09:11:51 +00002580void EnqueueVisitor::VisitOMPBarrierDirective(const OMPBarrierDirective *D) {
2581 VisitOMPExecutableDirective(D);
2582}
2583
Alexey Bataev2df347a2014-07-18 10:17:07 +00002584void EnqueueVisitor::VisitOMPTaskwaitDirective(const OMPTaskwaitDirective *D) {
2585 VisitOMPExecutableDirective(D);
2586}
2587
Alexey Bataevc30dd2d2015-06-18 12:14:09 +00002588void EnqueueVisitor::VisitOMPTaskgroupDirective(
2589 const OMPTaskgroupDirective *D) {
2590 VisitOMPExecutableDirective(D);
2591}
2592
Alexey Bataev6125da92014-07-21 11:26:11 +00002593void EnqueueVisitor::VisitOMPFlushDirective(const OMPFlushDirective *D) {
2594 VisitOMPExecutableDirective(D);
2595}
2596
Alexey Bataev9fb6e642014-07-22 06:45:04 +00002597void EnqueueVisitor::VisitOMPOrderedDirective(const OMPOrderedDirective *D) {
2598 VisitOMPExecutableDirective(D);
2599}
2600
Alexey Bataev0162e452014-07-22 10:10:35 +00002601void EnqueueVisitor::VisitOMPAtomicDirective(const OMPAtomicDirective *D) {
2602 VisitOMPExecutableDirective(D);
2603}
2604
Alexey Bataev0bd520b2014-09-19 08:19:49 +00002605void EnqueueVisitor::VisitOMPTargetDirective(const OMPTargetDirective *D) {
2606 VisitOMPExecutableDirective(D);
2607}
2608
Michael Wong65f367f2015-07-21 13:44:28 +00002609void EnqueueVisitor::VisitOMPTargetDataDirective(const
2610 OMPTargetDataDirective *D) {
2611 VisitOMPExecutableDirective(D);
2612}
2613
Alexey Bataev13314bf2014-10-09 04:18:56 +00002614void EnqueueVisitor::VisitOMPTeamsDirective(const OMPTeamsDirective *D) {
2615 VisitOMPExecutableDirective(D);
2616}
2617
Alexey Bataev6d4ed052015-07-01 06:57:41 +00002618void EnqueueVisitor::VisitOMPCancellationPointDirective(
2619 const OMPCancellationPointDirective *D) {
2620 VisitOMPExecutableDirective(D);
2621}
2622
Alexey Bataev80909872015-07-02 11:25:17 +00002623void EnqueueVisitor::VisitOMPCancelDirective(const OMPCancelDirective *D) {
2624 VisitOMPExecutableDirective(D);
2625}
2626
Alexey Bataev49f6e782015-12-01 04:18:41 +00002627void EnqueueVisitor::VisitOMPTaskLoopDirective(const OMPTaskLoopDirective *D) {
2628 VisitOMPLoopDirective(D);
2629}
2630
Alexey Bataev0a6ed842015-12-03 09:40:15 +00002631void EnqueueVisitor::VisitOMPTaskLoopSimdDirective(
2632 const OMPTaskLoopSimdDirective *D) {
2633 VisitOMPLoopDirective(D);
2634}
2635
Carlo Bertolli6200a3d2015-12-14 14:51:25 +00002636void EnqueueVisitor::VisitOMPDistributeDirective(
2637 const OMPDistributeDirective *D) {
2638 VisitOMPLoopDirective(D);
2639}
2640
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002641void CursorVisitor::EnqueueWorkList(VisitorWorkList &WL, const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002642 EnqueueVisitor(WL, MakeCXCursor(S, StmtParent, TU,RegionOfInterest)).Visit(S);
2643}
2644
2645bool CursorVisitor::IsInRegionOfInterest(CXCursor C) {
2646 if (RegionOfInterest.isValid()) {
2647 SourceRange Range = getRawCursorExtent(C);
2648 if (Range.isInvalid() || CompareRegionOfInterest(Range))
2649 return false;
2650 }
2651 return true;
2652}
2653
2654bool CursorVisitor::RunVisitorWorkList(VisitorWorkList &WL) {
2655 while (!WL.empty()) {
2656 // Dequeue the worklist item.
Robert Wilhelm25284cc2013-08-23 16:11:15 +00002657 VisitorJob LI = WL.pop_back_val();
Guy Benyei11169dd2012-12-18 14:30:41 +00002658
2659 // Set the Parent field, then back to its old value once we're done.
2660 SetParentRAII SetParent(Parent, StmtParent, LI.getParent());
2661
2662 switch (LI.getKind()) {
2663 case VisitorJob::DeclVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002664 const Decl *D = cast<DeclVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002665 if (!D)
2666 continue;
2667
2668 // For now, perform default visitation for Decls.
2669 if (Visit(MakeCXCursor(D, TU, RegionOfInterest,
2670 cast<DeclVisit>(&LI)->isFirst())))
2671 return true;
2672
2673 continue;
2674 }
2675 case VisitorJob::ExplicitTemplateArgsVisitKind: {
2676 const ASTTemplateArgumentListInfo *ArgList =
2677 cast<ExplicitTemplateArgsVisit>(&LI)->get();
2678 for (const TemplateArgumentLoc *Arg = ArgList->getTemplateArgs(),
2679 *ArgEnd = Arg + ArgList->NumTemplateArgs;
2680 Arg != ArgEnd; ++Arg) {
2681 if (VisitTemplateArgumentLoc(*Arg))
2682 return true;
2683 }
2684 continue;
2685 }
2686 case VisitorJob::TypeLocVisitKind: {
2687 // Perform default visitation for TypeLocs.
2688 if (Visit(cast<TypeLocVisit>(&LI)->get()))
2689 return true;
2690 continue;
2691 }
2692 case VisitorJob::LabelRefVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002693 const LabelDecl *LS = cast<LabelRefVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002694 if (LabelStmt *stmt = LS->getStmt()) {
2695 if (Visit(MakeCursorLabelRef(stmt, cast<LabelRefVisit>(&LI)->getLoc(),
2696 TU))) {
2697 return true;
2698 }
2699 }
2700 continue;
2701 }
2702
2703 case VisitorJob::NestedNameSpecifierLocVisitKind: {
2704 NestedNameSpecifierLocVisit *V = cast<NestedNameSpecifierLocVisit>(&LI);
2705 if (VisitNestedNameSpecifierLoc(V->get()))
2706 return true;
2707 continue;
2708 }
2709
2710 case VisitorJob::DeclarationNameInfoVisitKind: {
2711 if (VisitDeclarationNameInfo(cast<DeclarationNameInfoVisit>(&LI)
2712 ->get()))
2713 return true;
2714 continue;
2715 }
2716 case VisitorJob::MemberRefVisitKind: {
2717 MemberRefVisit *V = cast<MemberRefVisit>(&LI);
2718 if (Visit(MakeCursorMemberRef(V->get(), V->getLoc(), TU)))
2719 return true;
2720 continue;
2721 }
2722 case VisitorJob::StmtVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002723 const Stmt *S = cast<StmtVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002724 if (!S)
2725 continue;
2726
2727 // Update the current cursor.
2728 CXCursor Cursor = MakeCXCursor(S, StmtParent, TU, RegionOfInterest);
2729 if (!IsInRegionOfInterest(Cursor))
2730 continue;
2731 switch (Visitor(Cursor, Parent, ClientData)) {
2732 case CXChildVisit_Break: return true;
2733 case CXChildVisit_Continue: break;
2734 case CXChildVisit_Recurse:
2735 if (PostChildrenVisitor)
Craig Topper69186e72014-06-08 08:38:04 +00002736 WL.push_back(PostChildrenVisit(nullptr, Cursor));
Guy Benyei11169dd2012-12-18 14:30:41 +00002737 EnqueueWorkList(WL, S);
2738 break;
2739 }
2740 continue;
2741 }
2742 case VisitorJob::MemberExprPartsKind: {
2743 // Handle the other pieces in the MemberExpr besides the base.
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002744 const MemberExpr *M = cast<MemberExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002745
2746 // Visit the nested-name-specifier
2747 if (NestedNameSpecifierLoc QualifierLoc = M->getQualifierLoc())
2748 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2749 return true;
2750
2751 // Visit the declaration name.
2752 if (VisitDeclarationNameInfo(M->getMemberNameInfo()))
2753 return true;
2754
2755 // Visit the explicitly-specified template arguments, if any.
2756 if (M->hasExplicitTemplateArgs()) {
2757 for (const TemplateArgumentLoc *Arg = M->getTemplateArgs(),
2758 *ArgEnd = Arg + M->getNumTemplateArgs();
2759 Arg != ArgEnd; ++Arg) {
2760 if (VisitTemplateArgumentLoc(*Arg))
2761 return true;
2762 }
2763 }
2764 continue;
2765 }
2766 case VisitorJob::DeclRefExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002767 const DeclRefExpr *DR = cast<DeclRefExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002768 // Visit nested-name-specifier, if present.
2769 if (NestedNameSpecifierLoc QualifierLoc = DR->getQualifierLoc())
2770 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2771 return true;
2772 // Visit declaration name.
2773 if (VisitDeclarationNameInfo(DR->getNameInfo()))
2774 return true;
2775 continue;
2776 }
2777 case VisitorJob::OverloadExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002778 const OverloadExpr *O = cast<OverloadExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002779 // Visit the nested-name-specifier.
2780 if (NestedNameSpecifierLoc QualifierLoc = O->getQualifierLoc())
2781 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2782 return true;
2783 // Visit the declaration name.
2784 if (VisitDeclarationNameInfo(O->getNameInfo()))
2785 return true;
2786 // Visit the overloaded declaration reference.
2787 if (Visit(MakeCursorOverloadedDeclRef(O, TU)))
2788 return true;
2789 continue;
2790 }
2791 case VisitorJob::SizeOfPackExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002792 const SizeOfPackExpr *E = cast<SizeOfPackExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002793 NamedDecl *Pack = E->getPack();
2794 if (isa<TemplateTypeParmDecl>(Pack)) {
2795 if (Visit(MakeCursorTypeRef(cast<TemplateTypeParmDecl>(Pack),
2796 E->getPackLoc(), TU)))
2797 return true;
2798
2799 continue;
2800 }
2801
2802 if (isa<TemplateTemplateParmDecl>(Pack)) {
2803 if (Visit(MakeCursorTemplateRef(cast<TemplateTemplateParmDecl>(Pack),
2804 E->getPackLoc(), TU)))
2805 return true;
2806
2807 continue;
2808 }
2809
2810 // Non-type template parameter packs and function parameter packs are
2811 // treated like DeclRefExpr cursors.
2812 continue;
2813 }
2814
2815 case VisitorJob::LambdaExprPartsKind: {
2816 // Visit captures.
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002817 const LambdaExpr *E = cast<LambdaExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002818 for (LambdaExpr::capture_iterator C = E->explicit_capture_begin(),
2819 CEnd = E->explicit_capture_end();
2820 C != CEnd; ++C) {
Richard Smithba71c082013-05-16 06:20:58 +00002821 // FIXME: Lambda init-captures.
2822 if (!C->capturesVariable())
Guy Benyei11169dd2012-12-18 14:30:41 +00002823 continue;
Richard Smithba71c082013-05-16 06:20:58 +00002824
Guy Benyei11169dd2012-12-18 14:30:41 +00002825 if (Visit(MakeCursorVariableRef(C->getCapturedVar(),
2826 C->getLocation(),
2827 TU)))
2828 return true;
2829 }
2830
2831 // Visit parameters and return type, if present.
2832 if (E->hasExplicitParameters() || E->hasExplicitResultType()) {
2833 TypeLoc TL = E->getCallOperator()->getTypeSourceInfo()->getTypeLoc();
2834 if (E->hasExplicitParameters() && E->hasExplicitResultType()) {
2835 // Visit the whole type.
2836 if (Visit(TL))
2837 return true;
David Blaikie6adc78e2013-02-18 22:06:02 +00002838 } else if (FunctionProtoTypeLoc Proto =
2839 TL.getAs<FunctionProtoTypeLoc>()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002840 if (E->hasExplicitParameters()) {
2841 // Visit parameters.
Alp Tokerb3fd5cf2014-01-21 00:32:38 +00002842 for (unsigned I = 0, N = Proto.getNumParams(); I != N; ++I)
2843 if (Visit(MakeCXCursor(Proto.getParam(I), TU)))
Guy Benyei11169dd2012-12-18 14:30:41 +00002844 return true;
2845 } else {
2846 // Visit result type.
Alp Toker42a16a62014-01-25 23:51:36 +00002847 if (Visit(Proto.getReturnLoc()))
Guy Benyei11169dd2012-12-18 14:30:41 +00002848 return true;
2849 }
2850 }
2851 }
2852 break;
2853 }
2854
2855 case VisitorJob::PostChildrenVisitKind:
2856 if (PostChildrenVisitor(Parent, ClientData))
2857 return true;
2858 break;
2859 }
2860 }
2861 return false;
2862}
2863
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002864bool CursorVisitor::Visit(const Stmt *S) {
Craig Topper69186e72014-06-08 08:38:04 +00002865 VisitorWorkList *WL = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00002866 if (!WorkListFreeList.empty()) {
2867 WL = WorkListFreeList.back();
2868 WL->clear();
2869 WorkListFreeList.pop_back();
2870 }
2871 else {
2872 WL = new VisitorWorkList();
2873 WorkListCache.push_back(WL);
2874 }
2875 EnqueueWorkList(*WL, S);
2876 bool result = RunVisitorWorkList(*WL);
2877 WorkListFreeList.push_back(WL);
2878 return result;
2879}
2880
2881namespace {
Dmitri Gribenkof8579502013-01-12 19:30:44 +00002882typedef SmallVector<SourceRange, 4> RefNamePieces;
Craig Topper69186e72014-06-08 08:38:04 +00002883RefNamePieces
2884buildPieces(unsigned NameFlags, bool IsMemberRefExpr,
Craig Toppere335f252015-10-04 04:53:55 +00002885 const DeclarationNameInfo &NI, SourceRange QLoc,
Craig Topper69186e72014-06-08 08:38:04 +00002886 const ASTTemplateArgumentListInfo *TemplateArgs = nullptr) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002887 const bool WantQualifier = NameFlags & CXNameRange_WantQualifier;
2888 const bool WantTemplateArgs = NameFlags & CXNameRange_WantTemplateArgs;
2889 const bool WantSinglePiece = NameFlags & CXNameRange_WantSinglePiece;
2890
2891 const DeclarationName::NameKind Kind = NI.getName().getNameKind();
2892
2893 RefNamePieces Pieces;
2894
2895 if (WantQualifier && QLoc.isValid())
2896 Pieces.push_back(QLoc);
2897
2898 if (Kind != DeclarationName::CXXOperatorName || IsMemberRefExpr)
2899 Pieces.push_back(NI.getLoc());
2900
2901 if (WantTemplateArgs && TemplateArgs)
2902 Pieces.push_back(SourceRange(TemplateArgs->LAngleLoc,
2903 TemplateArgs->RAngleLoc));
2904
2905 if (Kind == DeclarationName::CXXOperatorName) {
2906 Pieces.push_back(SourceLocation::getFromRawEncoding(
2907 NI.getInfo().CXXOperatorName.BeginOpNameLoc));
2908 Pieces.push_back(SourceLocation::getFromRawEncoding(
2909 NI.getInfo().CXXOperatorName.EndOpNameLoc));
2910 }
2911
2912 if (WantSinglePiece) {
2913 SourceRange R(Pieces.front().getBegin(), Pieces.back().getEnd());
2914 Pieces.clear();
2915 Pieces.push_back(R);
2916 }
2917
2918 return Pieces;
2919}
Alexander Kornienkoab9db512015-06-22 23:07:51 +00002920}
Guy Benyei11169dd2012-12-18 14:30:41 +00002921
2922//===----------------------------------------------------------------------===//
2923// Misc. API hooks.
2924//===----------------------------------------------------------------------===//
2925
Chad Rosier05c71aa2013-03-27 18:28:23 +00002926static void fatal_error_handler(void *user_data, const std::string& reason,
2927 bool gen_crash_diag) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002928 // Write the result out to stderr avoiding errs() because raw_ostreams can
2929 // call report_fatal_error.
2930 fprintf(stderr, "LIBCLANG FATAL ERROR: %s\n", reason.c_str());
2931 ::abort();
2932}
2933
Chandler Carruth66660742014-06-27 16:37:27 +00002934namespace {
2935struct RegisterFatalErrorHandler {
2936 RegisterFatalErrorHandler() {
2937 llvm::install_fatal_error_handler(fatal_error_handler, nullptr);
2938 }
2939};
2940}
2941
2942static llvm::ManagedStatic<RegisterFatalErrorHandler> RegisterFatalErrorHandlerOnce;
2943
Guy Benyei11169dd2012-12-18 14:30:41 +00002944extern "C" {
2945CXIndex clang_createIndex(int excludeDeclarationsFromPCH,
2946 int displayDiagnostics) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002947 // We use crash recovery to make some of our APIs more reliable, implicitly
2948 // enable it.
Argyrios Kyrtzidis3701f542013-11-27 08:58:09 +00002949 if (!getenv("LIBCLANG_DISABLE_CRASH_RECOVERY"))
2950 llvm::CrashRecoveryContext::Enable();
Guy Benyei11169dd2012-12-18 14:30:41 +00002951
Chandler Carruth66660742014-06-27 16:37:27 +00002952 // Look through the managed static to trigger construction of the managed
2953 // static which registers our fatal error handler. This ensures it is only
2954 // registered once.
2955 (void)*RegisterFatalErrorHandlerOnce;
Guy Benyei11169dd2012-12-18 14:30:41 +00002956
Adrian Prantlbc068582015-07-08 01:00:30 +00002957 // Initialize targets for clang module support.
2958 llvm::InitializeAllTargets();
2959 llvm::InitializeAllTargetMCs();
2960 llvm::InitializeAllAsmPrinters();
2961 llvm::InitializeAllAsmParsers();
2962
Adrian Prantlfb2398d2015-07-17 01:19:54 +00002963 CIndexer *CIdxr = new CIndexer();
2964
Guy Benyei11169dd2012-12-18 14:30:41 +00002965 if (excludeDeclarationsFromPCH)
2966 CIdxr->setOnlyLocalDecls();
2967 if (displayDiagnostics)
2968 CIdxr->setDisplayDiagnostics();
2969
2970 if (getenv("LIBCLANG_BGPRIO_INDEX"))
2971 CIdxr->setCXGlobalOptFlags(CIdxr->getCXGlobalOptFlags() |
2972 CXGlobalOpt_ThreadBackgroundPriorityForIndexing);
2973 if (getenv("LIBCLANG_BGPRIO_EDIT"))
2974 CIdxr->setCXGlobalOptFlags(CIdxr->getCXGlobalOptFlags() |
2975 CXGlobalOpt_ThreadBackgroundPriorityForEditing);
2976
2977 return CIdxr;
2978}
2979
2980void clang_disposeIndex(CXIndex CIdx) {
2981 if (CIdx)
2982 delete static_cast<CIndexer *>(CIdx);
2983}
2984
2985void clang_CXIndex_setGlobalOptions(CXIndex CIdx, unsigned options) {
2986 if (CIdx)
2987 static_cast<CIndexer *>(CIdx)->setCXGlobalOptFlags(options);
2988}
2989
2990unsigned clang_CXIndex_getGlobalOptions(CXIndex CIdx) {
2991 if (CIdx)
2992 return static_cast<CIndexer *>(CIdx)->getCXGlobalOptFlags();
2993 return 0;
2994}
2995
2996void clang_toggleCrashRecovery(unsigned isEnabled) {
2997 if (isEnabled)
2998 llvm::CrashRecoveryContext::Enable();
2999 else
3000 llvm::CrashRecoveryContext::Disable();
3001}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003002
Guy Benyei11169dd2012-12-18 14:30:41 +00003003CXTranslationUnit clang_createTranslationUnit(CXIndex CIdx,
3004 const char *ast_filename) {
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00003005 CXTranslationUnit TU;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003006 enum CXErrorCode Result =
3007 clang_createTranslationUnit2(CIdx, ast_filename, &TU);
Reid Klecknerfd48fc62014-02-12 23:56:20 +00003008 (void)Result;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003009 assert((TU && Result == CXError_Success) ||
3010 (!TU && Result != CXError_Success));
3011 return TU;
3012}
3013
3014enum CXErrorCode clang_createTranslationUnit2(CXIndex CIdx,
3015 const char *ast_filename,
3016 CXTranslationUnit *out_TU) {
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00003017 if (out_TU)
Craig Topper69186e72014-06-08 08:38:04 +00003018 *out_TU = nullptr;
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00003019
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003020 if (!CIdx || !ast_filename || !out_TU)
3021 return CXError_InvalidArguments;
Guy Benyei11169dd2012-12-18 14:30:41 +00003022
Argyrios Kyrtzidis27021012013-05-24 22:24:07 +00003023 LOG_FUNC_SECTION {
3024 *Log << ast_filename;
3025 }
3026
Guy Benyei11169dd2012-12-18 14:30:41 +00003027 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
3028 FileSystemOptions FileSystemOpts;
3029
Justin Bognerd512c1e2014-10-15 00:33:06 +00003030 IntrusiveRefCntPtr<DiagnosticsEngine> Diags =
3031 CompilerInstance::createDiagnostics(new DiagnosticOptions());
David Blaikie6f7382d2014-08-10 19:08:04 +00003032 std::unique_ptr<ASTUnit> AU = ASTUnit::LoadFromASTFile(
Adrian Prantlfb2398d2015-07-17 01:19:54 +00003033 ast_filename, CXXIdx->getPCHContainerOperations()->getRawReader(), Diags,
Adrian Prantl6b21ab22015-08-27 19:46:20 +00003034 FileSystemOpts, /*UseDebugInfo=*/false,
3035 CXXIdx->getOnlyLocalDecls(), None,
David Blaikie6f7382d2014-08-10 19:08:04 +00003036 /*CaptureDiagnostics=*/true,
3037 /*AllowPCHWithCompilerErrors=*/true,
3038 /*UserFilesAreVolatile=*/true);
3039 *out_TU = MakeCXTranslationUnit(CXXIdx, AU.release());
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003040 return *out_TU ? CXError_Success : CXError_Failure;
Guy Benyei11169dd2012-12-18 14:30:41 +00003041}
3042
3043unsigned clang_defaultEditingTranslationUnitOptions() {
3044 return CXTranslationUnit_PrecompiledPreamble |
3045 CXTranslationUnit_CacheCompletionResults;
3046}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003047
Guy Benyei11169dd2012-12-18 14:30:41 +00003048CXTranslationUnit
3049clang_createTranslationUnitFromSourceFile(CXIndex CIdx,
3050 const char *source_filename,
3051 int num_command_line_args,
3052 const char * const *command_line_args,
3053 unsigned num_unsaved_files,
3054 struct CXUnsavedFile *unsaved_files) {
3055 unsigned Options = CXTranslationUnit_DetailedPreprocessingRecord;
3056 return clang_parseTranslationUnit(CIdx, source_filename,
3057 command_line_args, num_command_line_args,
3058 unsaved_files, num_unsaved_files,
3059 Options);
3060}
3061
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003062static CXErrorCode
3063clang_parseTranslationUnit_Impl(CXIndex CIdx, const char *source_filename,
3064 const char *const *command_line_args,
3065 int num_command_line_args,
3066 ArrayRef<CXUnsavedFile> unsaved_files,
3067 unsigned options, CXTranslationUnit *out_TU) {
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00003068 // Set up the initial return values.
3069 if (out_TU)
Craig Topper69186e72014-06-08 08:38:04 +00003070 *out_TU = nullptr;
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00003071
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003072 // Check arguments.
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003073 if (!CIdx || !out_TU)
3074 return CXError_InvalidArguments;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003075
Guy Benyei11169dd2012-12-18 14:30:41 +00003076 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
3077
3078 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
3079 setThreadBackgroundPriority();
3080
3081 bool PrecompilePreamble = options & CXTranslationUnit_PrecompiledPreamble;
3082 // FIXME: Add a flag for modules.
3083 TranslationUnitKind TUKind
3084 = (options & CXTranslationUnit_Incomplete)? TU_Prefix : TU_Complete;
Alp Toker8c8a8752013-12-03 06:53:35 +00003085 bool CacheCodeCompletionResults
Guy Benyei11169dd2012-12-18 14:30:41 +00003086 = options & CXTranslationUnit_CacheCompletionResults;
3087 bool IncludeBriefCommentsInCodeCompletion
3088 = options & CXTranslationUnit_IncludeBriefCommentsInCodeCompletion;
3089 bool SkipFunctionBodies = options & CXTranslationUnit_SkipFunctionBodies;
3090 bool ForSerialization = options & CXTranslationUnit_ForSerialization;
3091
3092 // Configure the diagnostics.
3093 IntrusiveRefCntPtr<DiagnosticsEngine>
Sean Silvaf1b49e22013-01-20 01:58:28 +00003094 Diags(CompilerInstance::createDiagnostics(new DiagnosticOptions));
Guy Benyei11169dd2012-12-18 14:30:41 +00003095
3096 // Recover resources if we crash before exiting this function.
3097 llvm::CrashRecoveryContextCleanupRegistrar<DiagnosticsEngine,
3098 llvm::CrashRecoveryContextReleaseRefCleanup<DiagnosticsEngine> >
Alp Tokerf994cef2014-07-05 03:08:06 +00003099 DiagCleanup(Diags.get());
Guy Benyei11169dd2012-12-18 14:30:41 +00003100
Ahmed Charlesb8984322014-03-07 20:03:18 +00003101 std::unique_ptr<std::vector<ASTUnit::RemappedFile>> RemappedFiles(
3102 new std::vector<ASTUnit::RemappedFile>());
Guy Benyei11169dd2012-12-18 14:30:41 +00003103
3104 // Recover resources if we crash before exiting this function.
3105 llvm::CrashRecoveryContextCleanupRegistrar<
3106 std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
3107
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003108 for (auto &UF : unsaved_files) {
Rafael Espindolad87f8d72014-08-27 20:03:29 +00003109 std::unique_ptr<llvm::MemoryBuffer> MB =
Alp Toker9d85b182014-07-07 01:23:14 +00003110 llvm::MemoryBuffer::getMemBufferCopy(getContents(UF), UF.Filename);
Rafael Espindolad87f8d72014-08-27 20:03:29 +00003111 RemappedFiles->push_back(std::make_pair(UF.Filename, MB.release()));
Guy Benyei11169dd2012-12-18 14:30:41 +00003112 }
3113
Ahmed Charlesb8984322014-03-07 20:03:18 +00003114 std::unique_ptr<std::vector<const char *>> Args(
3115 new std::vector<const char *>());
Guy Benyei11169dd2012-12-18 14:30:41 +00003116
3117 // Recover resources if we crash before exiting this method.
3118 llvm::CrashRecoveryContextCleanupRegistrar<std::vector<const char*> >
3119 ArgsCleanup(Args.get());
3120
3121 // Since the Clang C library is primarily used by batch tools dealing with
3122 // (often very broken) source code, where spell-checking can have a
3123 // significant negative impact on performance (particularly when
3124 // precompiled headers are involved), we disable it by default.
3125 // Only do this if we haven't found a spell-checking-related argument.
3126 bool FoundSpellCheckingArgument = false;
3127 for (int I = 0; I != num_command_line_args; ++I) {
3128 if (strcmp(command_line_args[I], "-fno-spell-checking") == 0 ||
3129 strcmp(command_line_args[I], "-fspell-checking") == 0) {
3130 FoundSpellCheckingArgument = true;
3131 break;
3132 }
3133 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003134 Args->insert(Args->end(), command_line_args,
3135 command_line_args + num_command_line_args);
3136
Benjamin Kramerc02670e2015-11-18 16:14:27 +00003137 if (!FoundSpellCheckingArgument)
3138 Args->insert(Args->begin() + 1, "-fno-spell-checking");
3139
Guy Benyei11169dd2012-12-18 14:30:41 +00003140 // The 'source_filename' argument is optional. If the caller does not
3141 // specify it then it is assumed that the source file is specified
3142 // in the actual argument list.
3143 // Put the source file after command_line_args otherwise if '-x' flag is
3144 // present it will be unused.
3145 if (source_filename)
3146 Args->push_back(source_filename);
3147
3148 // Do we need the detailed preprocessing record?
3149 if (options & CXTranslationUnit_DetailedPreprocessingRecord) {
3150 Args->push_back("-Xclang");
3151 Args->push_back("-detailed-preprocessing-record");
3152 }
3153
3154 unsigned NumErrors = Diags->getClient()->getNumErrors();
Ahmed Charlesb8984322014-03-07 20:03:18 +00003155 std::unique_ptr<ASTUnit> ErrUnit;
3156 std::unique_ptr<ASTUnit> Unit(ASTUnit::LoadFromCommandLine(
Adrian Prantlbb165fb2015-06-20 18:53:08 +00003157 Args->data(), Args->data() + Args->size(),
3158 CXXIdx->getPCHContainerOperations(), Diags,
Ahmed Charlesb8984322014-03-07 20:03:18 +00003159 CXXIdx->getClangResourcesPath(), CXXIdx->getOnlyLocalDecls(),
3160 /*CaptureDiagnostics=*/true, *RemappedFiles.get(),
3161 /*RemappedFilesKeepOriginalName=*/true, PrecompilePreamble, TUKind,
3162 CacheCodeCompletionResults, IncludeBriefCommentsInCodeCompletion,
3163 /*AllowPCHWithCompilerErrors=*/true, SkipFunctionBodies,
Argyrios Kyrtzidisa3e2ff12015-11-20 03:36:21 +00003164 /*UserFilesAreVolatile=*/true, ForSerialization,
3165 CXXIdx->getPCHContainerOperations()->getRawReader().getFormat(),
3166 &ErrUnit));
Guy Benyei11169dd2012-12-18 14:30:41 +00003167
Artem Belevich0ff05cd2015-07-13 23:27:56 +00003168 // Early failures in LoadFromCommandLine may return with ErrUnit unset.
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003169 if (!Unit && !ErrUnit)
3170 return CXError_ASTReadError;
Artem Belevich0ff05cd2015-07-13 23:27:56 +00003171
Guy Benyei11169dd2012-12-18 14:30:41 +00003172 if (NumErrors != Diags->getClient()->getNumErrors()) {
3173 // Make sure to check that 'Unit' is non-NULL.
3174 if (CXXIdx->getDisplayDiagnostics())
3175 printDiagsToStderr(Unit ? Unit.get() : ErrUnit.get());
3176 }
3177
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003178 if (isASTReadError(Unit ? Unit.get() : ErrUnit.get()))
3179 return CXError_ASTReadError;
3180
3181 *out_TU = MakeCXTranslationUnit(CXXIdx, Unit.release());
3182 return *out_TU ? CXError_Success : CXError_Failure;
Guy Benyei11169dd2012-12-18 14:30:41 +00003183}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003184
3185CXTranslationUnit
3186clang_parseTranslationUnit(CXIndex CIdx,
3187 const char *source_filename,
3188 const char *const *command_line_args,
3189 int num_command_line_args,
3190 struct CXUnsavedFile *unsaved_files,
3191 unsigned num_unsaved_files,
3192 unsigned options) {
3193 CXTranslationUnit TU;
3194 enum CXErrorCode Result = clang_parseTranslationUnit2(
3195 CIdx, source_filename, command_line_args, num_command_line_args,
3196 unsaved_files, num_unsaved_files, options, &TU);
Reid Kleckner6eaf05a2014-02-13 01:19:59 +00003197 (void)Result;
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00003198 assert((TU && Result == CXError_Success) ||
3199 (!TU && Result != CXError_Success));
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003200 return TU;
3201}
3202
3203enum CXErrorCode clang_parseTranslationUnit2(
Benjamin Kramerc02670e2015-11-18 16:14:27 +00003204 CXIndex CIdx, const char *source_filename,
3205 const char *const *command_line_args, int num_command_line_args,
3206 struct CXUnsavedFile *unsaved_files, unsigned num_unsaved_files,
3207 unsigned options, CXTranslationUnit *out_TU) {
3208 SmallVector<const char *, 4> Args;
3209 Args.push_back("clang");
3210 Args.append(command_line_args, command_line_args + num_command_line_args);
3211 return clang_parseTranslationUnit2FullArgv(
3212 CIdx, source_filename, Args.data(), Args.size(), unsaved_files,
3213 num_unsaved_files, options, out_TU);
3214}
3215
3216enum CXErrorCode clang_parseTranslationUnit2FullArgv(
3217 CXIndex CIdx, const char *source_filename,
3218 const char *const *command_line_args, int num_command_line_args,
3219 struct CXUnsavedFile *unsaved_files, unsigned num_unsaved_files,
3220 unsigned options, CXTranslationUnit *out_TU) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00003221 LOG_FUNC_SECTION {
3222 *Log << source_filename << ": ";
3223 for (int i = 0; i != num_command_line_args; ++i)
3224 *Log << command_line_args[i] << " ";
3225 }
3226
Alp Toker9d85b182014-07-07 01:23:14 +00003227 if (num_unsaved_files && !unsaved_files)
3228 return CXError_InvalidArguments;
3229
Alp Toker5c532982014-07-07 22:42:03 +00003230 CXErrorCode result = CXError_Failure;
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003231 auto ParseTranslationUnitImpl = [=, &result] {
3232 result = clang_parseTranslationUnit_Impl(
3233 CIdx, source_filename, command_line_args, num_command_line_args,
3234 llvm::makeArrayRef(unsaved_files, num_unsaved_files), options, out_TU);
3235 };
Guy Benyei11169dd2012-12-18 14:30:41 +00003236 llvm::CrashRecoveryContext CRC;
3237
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003238 if (!RunSafely(CRC, ParseTranslationUnitImpl)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003239 fprintf(stderr, "libclang: crash detected during parsing: {\n");
3240 fprintf(stderr, " 'source_filename' : '%s'\n", source_filename);
3241 fprintf(stderr, " 'command_line_args' : [");
3242 for (int i = 0; i != num_command_line_args; ++i) {
3243 if (i)
3244 fprintf(stderr, ", ");
3245 fprintf(stderr, "'%s'", command_line_args[i]);
3246 }
3247 fprintf(stderr, "],\n");
3248 fprintf(stderr, " 'unsaved_files' : [");
3249 for (unsigned i = 0; i != num_unsaved_files; ++i) {
3250 if (i)
3251 fprintf(stderr, ", ");
3252 fprintf(stderr, "('%s', '...', %ld)", unsaved_files[i].Filename,
3253 unsaved_files[i].Length);
3254 }
3255 fprintf(stderr, "],\n");
3256 fprintf(stderr, " 'options' : %d,\n", options);
3257 fprintf(stderr, "}\n");
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003258
3259 return CXError_Crashed;
Guy Benyei11169dd2012-12-18 14:30:41 +00003260 } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003261 if (CXTranslationUnit *TU = out_TU)
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003262 PrintLibclangResourceUsage(*TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003263 }
Alp Toker5c532982014-07-07 22:42:03 +00003264
3265 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003266}
3267
3268unsigned clang_defaultSaveOptions(CXTranslationUnit TU) {
3269 return CXSaveTranslationUnit_None;
3270}
3271
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003272static CXSaveError clang_saveTranslationUnit_Impl(CXTranslationUnit TU,
3273 const char *FileName,
3274 unsigned options) {
3275 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00003276 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
3277 setThreadBackgroundPriority();
3278
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003279 bool hadError = cxtu::getASTUnit(TU)->Save(FileName);
3280 return hadError ? CXSaveError_Unknown : CXSaveError_None;
Guy Benyei11169dd2012-12-18 14:30:41 +00003281}
3282
3283int clang_saveTranslationUnit(CXTranslationUnit TU, const char *FileName,
3284 unsigned options) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00003285 LOG_FUNC_SECTION {
3286 *Log << TU << ' ' << FileName;
3287 }
3288
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003289 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003290 LOG_BAD_TU(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003291 return CXSaveError_InvalidTU;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003292 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003293
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003294 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003295 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
3296 if (!CXXUnit->hasSema())
3297 return CXSaveError_InvalidTU;
3298
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003299 CXSaveError result;
3300 auto SaveTranslationUnitImpl = [=, &result]() {
3301 result = clang_saveTranslationUnit_Impl(TU, FileName, options);
3302 };
Guy Benyei11169dd2012-12-18 14:30:41 +00003303
3304 if (!CXXUnit->getDiagnostics().hasUnrecoverableErrorOccurred() ||
3305 getenv("LIBCLANG_NOTHREADS")) {
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003306 SaveTranslationUnitImpl();
Guy Benyei11169dd2012-12-18 14:30:41 +00003307
3308 if (getenv("LIBCLANG_RESOURCE_USAGE"))
3309 PrintLibclangResourceUsage(TU);
3310
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003311 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003312 }
3313
3314 // We have an AST that has invalid nodes due to compiler errors.
3315 // Use a crash recovery thread for protection.
3316
3317 llvm::CrashRecoveryContext CRC;
3318
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003319 if (!RunSafely(CRC, SaveTranslationUnitImpl)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003320 fprintf(stderr, "libclang: crash detected during AST saving: {\n");
3321 fprintf(stderr, " 'filename' : '%s'\n", FileName);
3322 fprintf(stderr, " 'options' : %d,\n", options);
3323 fprintf(stderr, "}\n");
3324
3325 return CXSaveError_Unknown;
3326
3327 } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
3328 PrintLibclangResourceUsage(TU);
3329 }
3330
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003331 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003332}
3333
3334void clang_disposeTranslationUnit(CXTranslationUnit CTUnit) {
3335 if (CTUnit) {
3336 // If the translation unit has been marked as unsafe to free, just discard
3337 // it.
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003338 ASTUnit *Unit = cxtu::getASTUnit(CTUnit);
3339 if (Unit && Unit->isUnsafeToFree())
Guy Benyei11169dd2012-12-18 14:30:41 +00003340 return;
3341
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003342 delete cxtu::getASTUnit(CTUnit);
Dmitri Gribenkob95b3f12013-01-26 22:44:19 +00003343 delete CTUnit->StringPool;
Guy Benyei11169dd2012-12-18 14:30:41 +00003344 delete static_cast<CXDiagnosticSetImpl *>(CTUnit->Diagnostics);
3345 disposeOverridenCXCursorsPool(CTUnit->OverridenCursorsPool);
Dmitri Gribenko9e605112013-11-13 22:16:51 +00003346 delete CTUnit->CommentToXML;
Guy Benyei11169dd2012-12-18 14:30:41 +00003347 delete CTUnit;
3348 }
3349}
3350
3351unsigned clang_defaultReparseOptions(CXTranslationUnit TU) {
3352 return CXReparse_None;
3353}
3354
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003355static CXErrorCode
3356clang_reparseTranslationUnit_Impl(CXTranslationUnit TU,
3357 ArrayRef<CXUnsavedFile> unsaved_files,
3358 unsigned options) {
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003359 // Check arguments.
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003360 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003361 LOG_BAD_TU(TU);
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003362 return CXError_InvalidArguments;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003363 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003364
3365 // Reset the associated diagnostics.
3366 delete static_cast<CXDiagnosticSetImpl*>(TU->Diagnostics);
Craig Topper69186e72014-06-08 08:38:04 +00003367 TU->Diagnostics = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00003368
Dmitri Gribenko183436e2013-01-26 21:49:50 +00003369 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00003370 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
3371 setThreadBackgroundPriority();
3372
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003373 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003374 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
Ahmed Charlesb8984322014-03-07 20:03:18 +00003375
3376 std::unique_ptr<std::vector<ASTUnit::RemappedFile>> RemappedFiles(
3377 new std::vector<ASTUnit::RemappedFile>());
3378
Guy Benyei11169dd2012-12-18 14:30:41 +00003379 // Recover resources if we crash before exiting this function.
3380 llvm::CrashRecoveryContextCleanupRegistrar<
3381 std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
Alp Toker9d85b182014-07-07 01:23:14 +00003382
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003383 for (auto &UF : unsaved_files) {
Rafael Espindolad87f8d72014-08-27 20:03:29 +00003384 std::unique_ptr<llvm::MemoryBuffer> MB =
Alp Toker9d85b182014-07-07 01:23:14 +00003385 llvm::MemoryBuffer::getMemBufferCopy(getContents(UF), UF.Filename);
Rafael Espindolad87f8d72014-08-27 20:03:29 +00003386 RemappedFiles->push_back(std::make_pair(UF.Filename, MB.release()));
Guy Benyei11169dd2012-12-18 14:30:41 +00003387 }
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003388
Adrian Prantlbb165fb2015-06-20 18:53:08 +00003389 if (!CXXUnit->Reparse(CXXIdx->getPCHContainerOperations(),
3390 *RemappedFiles.get()))
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003391 return CXError_Success;
3392 if (isASTReadError(CXXUnit))
3393 return CXError_ASTReadError;
3394 return CXError_Failure;
Guy Benyei11169dd2012-12-18 14:30:41 +00003395}
3396
3397int clang_reparseTranslationUnit(CXTranslationUnit TU,
3398 unsigned num_unsaved_files,
3399 struct CXUnsavedFile *unsaved_files,
3400 unsigned options) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00003401 LOG_FUNC_SECTION {
3402 *Log << TU;
3403 }
3404
Alp Toker9d85b182014-07-07 01:23:14 +00003405 if (num_unsaved_files && !unsaved_files)
3406 return CXError_InvalidArguments;
3407
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003408 CXErrorCode result;
3409 auto ReparseTranslationUnitImpl = [=, &result]() {
3410 result = clang_reparseTranslationUnit_Impl(
3411 TU, llvm::makeArrayRef(unsaved_files, num_unsaved_files), options);
3412 };
Guy Benyei11169dd2012-12-18 14:30:41 +00003413
3414 if (getenv("LIBCLANG_NOTHREADS")) {
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003415 ReparseTranslationUnitImpl();
Alp Toker5c532982014-07-07 22:42:03 +00003416 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003417 }
3418
3419 llvm::CrashRecoveryContext CRC;
3420
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003421 if (!RunSafely(CRC, ReparseTranslationUnitImpl)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003422 fprintf(stderr, "libclang: crash detected during reparsing\n");
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003423 cxtu::getASTUnit(TU)->setUnsafeToFree(true);
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003424 return CXError_Crashed;
Guy Benyei11169dd2012-12-18 14:30:41 +00003425 } else if (getenv("LIBCLANG_RESOURCE_USAGE"))
3426 PrintLibclangResourceUsage(TU);
3427
Alp Toker5c532982014-07-07 22:42:03 +00003428 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003429}
3430
3431
3432CXString clang_getTranslationUnitSpelling(CXTranslationUnit CTUnit) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003433 if (isNotUsableTU(CTUnit)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003434 LOG_BAD_TU(CTUnit);
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003435 return cxstring::createEmpty();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003436 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003437
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003438 ASTUnit *CXXUnit = cxtu::getASTUnit(CTUnit);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003439 return cxstring::createDup(CXXUnit->getOriginalSourceFileName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003440}
3441
3442CXCursor clang_getTranslationUnitCursor(CXTranslationUnit TU) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003443 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003444 LOG_BAD_TU(TU);
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00003445 return clang_getNullCursor();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003446 }
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00003447
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003448 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003449 return MakeCXCursor(CXXUnit->getASTContext().getTranslationUnitDecl(), TU);
3450}
3451
3452} // end: extern "C"
3453
3454//===----------------------------------------------------------------------===//
3455// CXFile Operations.
3456//===----------------------------------------------------------------------===//
3457
3458extern "C" {
3459CXString clang_getFileName(CXFile SFile) {
3460 if (!SFile)
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00003461 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00003462
3463 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003464 return cxstring::createRef(FEnt->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003465}
3466
3467time_t clang_getFileTime(CXFile SFile) {
3468 if (!SFile)
3469 return 0;
3470
3471 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
3472 return FEnt->getModificationTime();
3473}
3474
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003475CXFile clang_getFile(CXTranslationUnit TU, const char *file_name) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003476 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003477 LOG_BAD_TU(TU);
Craig Topper69186e72014-06-08 08:38:04 +00003478 return nullptr;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003479 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003480
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003481 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003482
3483 FileManager &FMgr = CXXUnit->getFileManager();
3484 return const_cast<FileEntry *>(FMgr.getFile(file_name));
3485}
3486
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003487unsigned clang_isFileMultipleIncludeGuarded(CXTranslationUnit TU,
3488 CXFile file) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003489 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003490 LOG_BAD_TU(TU);
3491 return 0;
3492 }
3493
3494 if (!file)
Guy Benyei11169dd2012-12-18 14:30:41 +00003495 return 0;
3496
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003497 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003498 FileEntry *FEnt = static_cast<FileEntry *>(file);
3499 return CXXUnit->getPreprocessor().getHeaderSearchInfo()
3500 .isFileMultipleIncludeGuarded(FEnt);
3501}
3502
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003503int clang_getFileUniqueID(CXFile file, CXFileUniqueID *outID) {
3504 if (!file || !outID)
3505 return 1;
3506
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003507 FileEntry *FEnt = static_cast<FileEntry *>(file);
Rafael Espindolaf8f91b82013-08-01 21:42:11 +00003508 const llvm::sys::fs::UniqueID &ID = FEnt->getUniqueID();
3509 outID->data[0] = ID.getDevice();
3510 outID->data[1] = ID.getFile();
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003511 outID->data[2] = FEnt->getModificationTime();
3512 return 0;
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003513}
3514
Argyrios Kyrtzidisac3997e2014-08-16 00:26:19 +00003515int clang_File_isEqual(CXFile file1, CXFile file2) {
3516 if (file1 == file2)
3517 return true;
3518
3519 if (!file1 || !file2)
3520 return false;
3521
3522 FileEntry *FEnt1 = static_cast<FileEntry *>(file1);
3523 FileEntry *FEnt2 = static_cast<FileEntry *>(file2);
3524 return FEnt1->getUniqueID() == FEnt2->getUniqueID();
3525}
3526
Guy Benyei11169dd2012-12-18 14:30:41 +00003527} // end: extern "C"
3528
3529//===----------------------------------------------------------------------===//
3530// CXCursor Operations.
3531//===----------------------------------------------------------------------===//
3532
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003533static const Decl *getDeclFromExpr(const Stmt *E) {
3534 if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003535 return getDeclFromExpr(CE->getSubExpr());
3536
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003537 if (const DeclRefExpr *RefExpr = dyn_cast<DeclRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003538 return RefExpr->getDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003539 if (const MemberExpr *ME = dyn_cast<MemberExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003540 return ME->getMemberDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003541 if (const ObjCIvarRefExpr *RE = dyn_cast<ObjCIvarRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003542 return RE->getDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003543 if (const ObjCPropertyRefExpr *PRE = dyn_cast<ObjCPropertyRefExpr>(E)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003544 if (PRE->isExplicitProperty())
3545 return PRE->getExplicitProperty();
3546 // It could be messaging both getter and setter as in:
3547 // ++myobj.myprop;
3548 // in which case prefer to associate the setter since it is less obvious
3549 // from inspecting the source that the setter is going to get called.
3550 if (PRE->isMessagingSetter())
3551 return PRE->getImplicitPropertySetter();
3552 return PRE->getImplicitPropertyGetter();
3553 }
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003554 if (const PseudoObjectExpr *POE = dyn_cast<PseudoObjectExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003555 return getDeclFromExpr(POE->getSyntacticForm());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003556 if (const OpaqueValueExpr *OVE = dyn_cast<OpaqueValueExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003557 if (Expr *Src = OVE->getSourceExpr())
3558 return getDeclFromExpr(Src);
3559
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003560 if (const CallExpr *CE = dyn_cast<CallExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003561 return getDeclFromExpr(CE->getCallee());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003562 if (const CXXConstructExpr *CE = dyn_cast<CXXConstructExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003563 if (!CE->isElidable())
3564 return CE->getConstructor();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003565 if (const ObjCMessageExpr *OME = dyn_cast<ObjCMessageExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003566 return OME->getMethodDecl();
3567
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003568 if (const ObjCProtocolExpr *PE = dyn_cast<ObjCProtocolExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003569 return PE->getProtocol();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003570 if (const SubstNonTypeTemplateParmPackExpr *NTTP
Guy Benyei11169dd2012-12-18 14:30:41 +00003571 = dyn_cast<SubstNonTypeTemplateParmPackExpr>(E))
3572 return NTTP->getParameterPack();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003573 if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003574 if (isa<NonTypeTemplateParmDecl>(SizeOfPack->getPack()) ||
3575 isa<ParmVarDecl>(SizeOfPack->getPack()))
3576 return SizeOfPack->getPack();
Craig Topper69186e72014-06-08 08:38:04 +00003577
3578 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00003579}
3580
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003581static SourceLocation getLocationFromExpr(const Expr *E) {
3582 if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003583 return getLocationFromExpr(CE->getSubExpr());
3584
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003585 if (const ObjCMessageExpr *Msg = dyn_cast<ObjCMessageExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003586 return /*FIXME:*/Msg->getLeftLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003587 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003588 return DRE->getLocation();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003589 if (const MemberExpr *Member = dyn_cast<MemberExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003590 return Member->getMemberLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003591 if (const ObjCIvarRefExpr *Ivar = dyn_cast<ObjCIvarRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003592 return Ivar->getLocation();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003593 if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003594 return SizeOfPack->getPackLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003595 if (const ObjCPropertyRefExpr *PropRef = dyn_cast<ObjCPropertyRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003596 return PropRef->getLocation();
3597
3598 return E->getLocStart();
3599}
3600
Aaron Ballmana85d3f82015-11-12 15:25:06 +00003601static std::string getMangledStructor(std::unique_ptr<MangleContext> &M,
3602 std::unique_ptr<llvm::DataLayout> &DL,
3603 const NamedDecl *ND,
3604 unsigned StructorType) {
3605 std::string FrontendBuf;
3606 llvm::raw_string_ostream FOS(FrontendBuf);
3607
3608 if (const auto *CD = dyn_cast_or_null<CXXConstructorDecl>(ND))
3609 M->mangleCXXCtor(CD, static_cast<CXXCtorType>(StructorType), FOS);
3610 else if (const auto *DD = dyn_cast_or_null<CXXDestructorDecl>(ND))
3611 M->mangleCXXDtor(DD, static_cast<CXXDtorType>(StructorType), FOS);
3612
3613 std::string BackendBuf;
3614 llvm::raw_string_ostream BOS(BackendBuf);
3615
3616 llvm::Mangler::getNameWithPrefix(BOS, llvm::Twine(FOS.str()), *DL);
3617
3618 return BOS.str();
3619}
3620
Guy Benyei11169dd2012-12-18 14:30:41 +00003621extern "C" {
3622
3623unsigned clang_visitChildren(CXCursor parent,
3624 CXCursorVisitor visitor,
3625 CXClientData client_data) {
3626 CursorVisitor CursorVis(getCursorTU(parent), visitor, client_data,
3627 /*VisitPreprocessorLast=*/false);
3628 return CursorVis.VisitChildren(parent);
3629}
3630
3631#ifndef __has_feature
3632#define __has_feature(x) 0
3633#endif
3634#if __has_feature(blocks)
3635typedef enum CXChildVisitResult
3636 (^CXCursorVisitorBlock)(CXCursor cursor, CXCursor parent);
3637
3638static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
3639 CXClientData client_data) {
3640 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
3641 return block(cursor, parent);
3642}
3643#else
3644// If we are compiled with a compiler that doesn't have native blocks support,
3645// define and call the block manually, so the
3646typedef struct _CXChildVisitResult
3647{
3648 void *isa;
3649 int flags;
3650 int reserved;
3651 enum CXChildVisitResult(*invoke)(struct _CXChildVisitResult*, CXCursor,
3652 CXCursor);
3653} *CXCursorVisitorBlock;
3654
3655static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
3656 CXClientData client_data) {
3657 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
3658 return block->invoke(block, cursor, parent);
3659}
3660#endif
3661
3662
3663unsigned clang_visitChildrenWithBlock(CXCursor parent,
3664 CXCursorVisitorBlock block) {
3665 return clang_visitChildren(parent, visitWithBlock, block);
3666}
3667
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003668static CXString getDeclSpelling(const Decl *D) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003669 if (!D)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003670 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003671
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003672 const NamedDecl *ND = dyn_cast<NamedDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00003673 if (!ND) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003674 if (const ObjCPropertyImplDecl *PropImpl =
3675 dyn_cast<ObjCPropertyImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00003676 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003677 return cxstring::createDup(Property->getIdentifier()->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003678
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003679 if (const ImportDecl *ImportD = dyn_cast<ImportDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00003680 if (Module *Mod = ImportD->getImportedModule())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003681 return cxstring::createDup(Mod->getFullModuleName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003682
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003683 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003684 }
3685
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003686 if (const ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(ND))
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003687 return cxstring::createDup(OMD->getSelector().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003688
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003689 if (const ObjCCategoryImplDecl *CIMP = dyn_cast<ObjCCategoryImplDecl>(ND))
Guy Benyei11169dd2012-12-18 14:30:41 +00003690 // No, this isn't the same as the code below. getIdentifier() is non-virtual
3691 // and returns different names. NamedDecl returns the class name and
3692 // ObjCCategoryImplDecl returns the category name.
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003693 return cxstring::createRef(CIMP->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003694
3695 if (isa<UsingDirectiveDecl>(D))
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003696 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003697
3698 SmallString<1024> S;
3699 llvm::raw_svector_ostream os(S);
3700 ND->printName(os);
3701
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003702 return cxstring::createDup(os.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003703}
3704
3705CXString clang_getCursorSpelling(CXCursor C) {
3706 if (clang_isTranslationUnit(C.kind))
Dmitri Gribenko2c173b42013-01-11 19:28:44 +00003707 return clang_getTranslationUnitSpelling(getCursorTU(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00003708
3709 if (clang_isReference(C.kind)) {
3710 switch (C.kind) {
3711 case CXCursor_ObjCSuperClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003712 const ObjCInterfaceDecl *Super = getCursorObjCSuperClassRef(C).first;
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003713 return cxstring::createRef(Super->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003714 }
3715 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003716 const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003717 return cxstring::createRef(Class->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003718 }
3719 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003720 const ObjCProtocolDecl *OID = getCursorObjCProtocolRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003721 assert(OID && "getCursorSpelling(): Missing protocol decl");
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003722 return cxstring::createRef(OID->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003723 }
3724 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003725 const CXXBaseSpecifier *B = getCursorCXXBaseSpecifier(C);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003726 return cxstring::createDup(B->getType().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003727 }
3728 case CXCursor_TypeRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003729 const TypeDecl *Type = getCursorTypeRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003730 assert(Type && "Missing type decl");
3731
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003732 return cxstring::createDup(getCursorContext(C).getTypeDeclType(Type).
Guy Benyei11169dd2012-12-18 14:30:41 +00003733 getAsString());
3734 }
3735 case CXCursor_TemplateRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003736 const TemplateDecl *Template = getCursorTemplateRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003737 assert(Template && "Missing template decl");
3738
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003739 return cxstring::createDup(Template->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003740 }
3741
3742 case CXCursor_NamespaceRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003743 const NamedDecl *NS = getCursorNamespaceRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003744 assert(NS && "Missing namespace decl");
3745
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003746 return cxstring::createDup(NS->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003747 }
3748
3749 case CXCursor_MemberRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003750 const FieldDecl *Field = getCursorMemberRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003751 assert(Field && "Missing member decl");
3752
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003753 return cxstring::createDup(Field->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003754 }
3755
3756 case CXCursor_LabelRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003757 const LabelStmt *Label = getCursorLabelRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003758 assert(Label && "Missing label");
3759
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003760 return cxstring::createRef(Label->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003761 }
3762
3763 case CXCursor_OverloadedDeclRef: {
3764 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003765 if (const Decl *D = Storage.dyn_cast<const Decl *>()) {
3766 if (const NamedDecl *ND = dyn_cast<NamedDecl>(D))
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003767 return cxstring::createDup(ND->getNameAsString());
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003768 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003769 }
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003770 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003771 return cxstring::createDup(E->getName().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003772 OverloadedTemplateStorage *Ovl
3773 = Storage.get<OverloadedTemplateStorage*>();
3774 if (Ovl->size() == 0)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003775 return cxstring::createEmpty();
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003776 return cxstring::createDup((*Ovl->begin())->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003777 }
3778
3779 case CXCursor_VariableRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003780 const VarDecl *Var = getCursorVariableRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003781 assert(Var && "Missing variable decl");
3782
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003783 return cxstring::createDup(Var->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003784 }
3785
3786 default:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003787 return cxstring::createRef("<not implemented>");
Guy Benyei11169dd2012-12-18 14:30:41 +00003788 }
3789 }
3790
3791 if (clang_isExpression(C.kind)) {
Argyrios Kyrtzidis3227d862014-03-03 19:40:52 +00003792 const Expr *E = getCursorExpr(C);
3793
3794 if (C.kind == CXCursor_ObjCStringLiteral ||
3795 C.kind == CXCursor_StringLiteral) {
3796 const StringLiteral *SLit;
3797 if (const ObjCStringLiteral *OSL = dyn_cast<ObjCStringLiteral>(E)) {
3798 SLit = OSL->getString();
3799 } else {
3800 SLit = cast<StringLiteral>(E);
3801 }
3802 SmallString<256> Buf;
3803 llvm::raw_svector_ostream OS(Buf);
3804 SLit->outputString(OS);
3805 return cxstring::createDup(OS.str());
3806 }
3807
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003808 const Decl *D = getDeclFromExpr(getCursorExpr(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00003809 if (D)
3810 return getDeclSpelling(D);
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003811 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003812 }
3813
3814 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003815 const Stmt *S = getCursorStmt(C);
3816 if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S))
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003817 return cxstring::createRef(Label->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003818
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003819 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003820 }
3821
3822 if (C.kind == CXCursor_MacroExpansion)
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003823 return cxstring::createRef(getCursorMacroExpansion(C).getName()
Guy Benyei11169dd2012-12-18 14:30:41 +00003824 ->getNameStart());
3825
3826 if (C.kind == CXCursor_MacroDefinition)
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003827 return cxstring::createRef(getCursorMacroDefinition(C)->getName()
Guy Benyei11169dd2012-12-18 14:30:41 +00003828 ->getNameStart());
3829
3830 if (C.kind == CXCursor_InclusionDirective)
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003831 return cxstring::createDup(getCursorInclusionDirective(C)->getFileName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003832
3833 if (clang_isDeclaration(C.kind))
3834 return getDeclSpelling(getCursorDecl(C));
3835
3836 if (C.kind == CXCursor_AnnotateAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00003837 const AnnotateAttr *AA = cast<AnnotateAttr>(cxcursor::getCursorAttr(C));
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003838 return cxstring::createDup(AA->getAnnotation());
Guy Benyei11169dd2012-12-18 14:30:41 +00003839 }
3840
3841 if (C.kind == CXCursor_AsmLabelAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00003842 const AsmLabelAttr *AA = cast<AsmLabelAttr>(cxcursor::getCursorAttr(C));
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003843 return cxstring::createDup(AA->getLabel());
Guy Benyei11169dd2012-12-18 14:30:41 +00003844 }
3845
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00003846 if (C.kind == CXCursor_PackedAttr) {
3847 return cxstring::createRef("packed");
3848 }
3849
Saleem Abdulrasool79c69712015-09-05 18:53:43 +00003850 if (C.kind == CXCursor_VisibilityAttr) {
3851 const VisibilityAttr *AA = cast<VisibilityAttr>(cxcursor::getCursorAttr(C));
3852 switch (AA->getVisibility()) {
3853 case VisibilityAttr::VisibilityType::Default:
3854 return cxstring::createRef("default");
3855 case VisibilityAttr::VisibilityType::Hidden:
3856 return cxstring::createRef("hidden");
3857 case VisibilityAttr::VisibilityType::Protected:
3858 return cxstring::createRef("protected");
3859 }
3860 llvm_unreachable("unknown visibility type");
3861 }
3862
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003863 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003864}
3865
3866CXSourceRange clang_Cursor_getSpellingNameRange(CXCursor C,
3867 unsigned pieceIndex,
3868 unsigned options) {
3869 if (clang_Cursor_isNull(C))
3870 return clang_getNullRange();
3871
3872 ASTContext &Ctx = getCursorContext(C);
3873
3874 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003875 const Stmt *S = getCursorStmt(C);
3876 if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003877 if (pieceIndex > 0)
3878 return clang_getNullRange();
3879 return cxloc::translateSourceRange(Ctx, Label->getIdentLoc());
3880 }
3881
3882 return clang_getNullRange();
3883 }
3884
3885 if (C.kind == CXCursor_ObjCMessageExpr) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003886 if (const ObjCMessageExpr *
Guy Benyei11169dd2012-12-18 14:30:41 +00003887 ME = dyn_cast_or_null<ObjCMessageExpr>(getCursorExpr(C))) {
3888 if (pieceIndex >= ME->getNumSelectorLocs())
3889 return clang_getNullRange();
3890 return cxloc::translateSourceRange(Ctx, ME->getSelectorLoc(pieceIndex));
3891 }
3892 }
3893
3894 if (C.kind == CXCursor_ObjCInstanceMethodDecl ||
3895 C.kind == CXCursor_ObjCClassMethodDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003896 if (const ObjCMethodDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003897 MD = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(C))) {
3898 if (pieceIndex >= MD->getNumSelectorLocs())
3899 return clang_getNullRange();
3900 return cxloc::translateSourceRange(Ctx, MD->getSelectorLoc(pieceIndex));
3901 }
3902 }
3903
3904 if (C.kind == CXCursor_ObjCCategoryDecl ||
3905 C.kind == CXCursor_ObjCCategoryImplDecl) {
3906 if (pieceIndex > 0)
3907 return clang_getNullRange();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003908 if (const ObjCCategoryDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003909 CD = dyn_cast_or_null<ObjCCategoryDecl>(getCursorDecl(C)))
3910 return cxloc::translateSourceRange(Ctx, CD->getCategoryNameLoc());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003911 if (const ObjCCategoryImplDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003912 CID = dyn_cast_or_null<ObjCCategoryImplDecl>(getCursorDecl(C)))
3913 return cxloc::translateSourceRange(Ctx, CID->getCategoryNameLoc());
3914 }
3915
3916 if (C.kind == CXCursor_ModuleImportDecl) {
3917 if (pieceIndex > 0)
3918 return clang_getNullRange();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003919 if (const ImportDecl *ImportD =
3920 dyn_cast_or_null<ImportDecl>(getCursorDecl(C))) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003921 ArrayRef<SourceLocation> Locs = ImportD->getIdentifierLocs();
3922 if (!Locs.empty())
3923 return cxloc::translateSourceRange(Ctx,
3924 SourceRange(Locs.front(), Locs.back()));
3925 }
3926 return clang_getNullRange();
3927 }
3928
Argyrios Kyrtzidisa2a1e532014-08-26 20:23:26 +00003929 if (C.kind == CXCursor_CXXMethod || C.kind == CXCursor_Destructor ||
3930 C.kind == CXCursor_ConversionFunction) {
3931 if (pieceIndex > 0)
3932 return clang_getNullRange();
3933 if (const FunctionDecl *FD =
3934 dyn_cast_or_null<FunctionDecl>(getCursorDecl(C))) {
3935 DeclarationNameInfo FunctionName = FD->getNameInfo();
3936 return cxloc::translateSourceRange(Ctx, FunctionName.getSourceRange());
3937 }
3938 return clang_getNullRange();
3939 }
3940
Guy Benyei11169dd2012-12-18 14:30:41 +00003941 // FIXME: A CXCursor_InclusionDirective should give the location of the
3942 // filename, but we don't keep track of this.
3943
3944 // FIXME: A CXCursor_AnnotateAttr should give the location of the annotation
3945 // but we don't keep track of this.
3946
3947 // FIXME: A CXCursor_AsmLabelAttr should give the location of the label
3948 // but we don't keep track of this.
3949
3950 // Default handling, give the location of the cursor.
3951
3952 if (pieceIndex > 0)
3953 return clang_getNullRange();
3954
3955 CXSourceLocation CXLoc = clang_getCursorLocation(C);
3956 SourceLocation Loc = cxloc::translateSourceLocation(CXLoc);
3957 return cxloc::translateSourceRange(Ctx, Loc);
3958}
3959
Eli Bendersky44a206f2014-07-31 18:04:56 +00003960CXString clang_Cursor_getMangling(CXCursor C) {
3961 if (clang_isInvalid(C.kind) || !clang_isDeclaration(C.kind))
3962 return cxstring::createEmpty();
3963
Eli Bendersky44a206f2014-07-31 18:04:56 +00003964 // Mangling only works for functions and variables.
Eli Bendersky79759592014-08-01 15:01:10 +00003965 const Decl *D = getCursorDecl(C);
Eli Bendersky44a206f2014-07-31 18:04:56 +00003966 if (!D || !(isa<FunctionDecl>(D) || isa<VarDecl>(D)))
3967 return cxstring::createEmpty();
3968
Eli Bendersky79759592014-08-01 15:01:10 +00003969 // First apply frontend mangling.
Eli Bendersky44a206f2014-07-31 18:04:56 +00003970 const NamedDecl *ND = cast<NamedDecl>(D);
Eli Bendersky79759592014-08-01 15:01:10 +00003971 ASTContext &Ctx = ND->getASTContext();
3972 std::unique_ptr<MangleContext> MC(Ctx.createMangleContext());
Eli Bendersky44a206f2014-07-31 18:04:56 +00003973
Eli Bendersky79759592014-08-01 15:01:10 +00003974 std::string FrontendBuf;
3975 llvm::raw_string_ostream FrontendBufOS(FrontendBuf);
Ehsan Akhgarif8d44de2015-10-08 00:01:20 +00003976 if (MC->shouldMangleDeclName(ND)) {
3977 MC->mangleName(ND, FrontendBufOS);
3978 } else {
3979 ND->printName(FrontendBufOS);
3980 }
Eli Bendersky44a206f2014-07-31 18:04:56 +00003981
Eli Bendersky79759592014-08-01 15:01:10 +00003982 // Now apply backend mangling.
3983 std::unique_ptr<llvm::DataLayout> DL(
Eric Christopher964a5f32015-08-05 23:48:05 +00003984 new llvm::DataLayout(Ctx.getTargetInfo().getDataLayoutString()));
Eli Bendersky79759592014-08-01 15:01:10 +00003985
3986 std::string FinalBuf;
3987 llvm::raw_string_ostream FinalBufOS(FinalBuf);
Rafael Espindolab633d202015-06-23 13:59:36 +00003988 llvm::Mangler::getNameWithPrefix(FinalBufOS, llvm::Twine(FrontendBufOS.str()),
3989 *DL);
Eli Bendersky79759592014-08-01 15:01:10 +00003990
3991 return cxstring::createDup(FinalBufOS.str());
Eli Bendersky44a206f2014-07-31 18:04:56 +00003992}
3993
Saleem Abdulrasool60034432015-11-12 03:57:22 +00003994CXStringSet *clang_Cursor_getCXXManglings(CXCursor C) {
3995 if (clang_isInvalid(C.kind) || !clang_isDeclaration(C.kind))
3996 return nullptr;
3997
3998 const Decl *D = getCursorDecl(C);
3999 if (!(isa<CXXRecordDecl>(D) || isa<CXXMethodDecl>(D)))
4000 return nullptr;
4001
4002 const NamedDecl *ND = cast<NamedDecl>(D);
4003
4004 ASTContext &Ctx = ND->getASTContext();
4005 std::unique_ptr<MangleContext> M(Ctx.createMangleContext());
4006 std::unique_ptr<llvm::DataLayout> DL(
4007 new llvm::DataLayout(Ctx.getTargetInfo().getDataLayoutString()));
4008
4009 std::vector<std::string> Manglings;
4010
4011 auto hasDefaultCXXMethodCC = [](ASTContext &C, const CXXMethodDecl *MD) {
4012 auto DefaultCC = C.getDefaultCallingConvention(/*IsVariadic=*/false,
4013 /*IsCSSMethod=*/true);
4014 auto CC = MD->getType()->getAs<FunctionProtoType>()->getCallConv();
4015 return CC == DefaultCC;
4016 };
4017
4018 if (const auto *CD = dyn_cast_or_null<CXXConstructorDecl>(ND)) {
4019 Manglings.emplace_back(getMangledStructor(M, DL, CD, Ctor_Base));
4020
4021 if (Ctx.getTargetInfo().getCXXABI().isItaniumFamily())
4022 if (!CD->getParent()->isAbstract())
4023 Manglings.emplace_back(getMangledStructor(M, DL, CD, Ctor_Complete));
4024
4025 if (Ctx.getTargetInfo().getCXXABI().isMicrosoft())
4026 if (CD->hasAttr<DLLExportAttr>() && CD->isDefaultConstructor())
4027 if (!(hasDefaultCXXMethodCC(Ctx, CD) && CD->getNumParams() == 0))
4028 Manglings.emplace_back(getMangledStructor(M, DL, CD,
4029 Ctor_DefaultClosure));
4030 } else if (const auto *DD = dyn_cast_or_null<CXXDestructorDecl>(ND)) {
4031 Manglings.emplace_back(getMangledStructor(M, DL, DD, Dtor_Base));
4032 if (Ctx.getTargetInfo().getCXXABI().isItaniumFamily()) {
4033 Manglings.emplace_back(getMangledStructor(M, DL, DD, Dtor_Complete));
Saleem Abdulrasoold5af8ae2015-12-10 06:30:23 +00004034 if (DD->isVirtual())
Saleem Abdulrasool60034432015-11-12 03:57:22 +00004035 Manglings.emplace_back(getMangledStructor(M, DL, DD, Dtor_Deleting));
4036 }
4037 }
4038
4039 return cxstring::createSet(Manglings);
4040}
4041
Guy Benyei11169dd2012-12-18 14:30:41 +00004042CXString clang_getCursorDisplayName(CXCursor C) {
4043 if (!clang_isDeclaration(C.kind))
4044 return clang_getCursorSpelling(C);
4045
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004046 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004047 if (!D)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00004048 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00004049
4050 PrintingPolicy Policy = getCursorContext(C).getPrintingPolicy();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004051 if (const FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004052 D = FunTmpl->getTemplatedDecl();
4053
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004054 if (const FunctionDecl *Function = dyn_cast<FunctionDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004055 SmallString<64> Str;
4056 llvm::raw_svector_ostream OS(Str);
4057 OS << *Function;
4058 if (Function->getPrimaryTemplate())
4059 OS << "<>";
4060 OS << "(";
4061 for (unsigned I = 0, N = Function->getNumParams(); I != N; ++I) {
4062 if (I)
4063 OS << ", ";
4064 OS << Function->getParamDecl(I)->getType().getAsString(Policy);
4065 }
4066
4067 if (Function->isVariadic()) {
4068 if (Function->getNumParams())
4069 OS << ", ";
4070 OS << "...";
4071 }
4072 OS << ")";
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004073 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00004074 }
4075
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004076 if (const ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004077 SmallString<64> Str;
4078 llvm::raw_svector_ostream OS(Str);
4079 OS << *ClassTemplate;
4080 OS << "<";
4081 TemplateParameterList *Params = ClassTemplate->getTemplateParameters();
4082 for (unsigned I = 0, N = Params->size(); I != N; ++I) {
4083 if (I)
4084 OS << ", ";
4085
4086 NamedDecl *Param = Params->getParam(I);
4087 if (Param->getIdentifier()) {
4088 OS << Param->getIdentifier()->getName();
4089 continue;
4090 }
4091
4092 // There is no parameter name, which makes this tricky. Try to come up
4093 // with something useful that isn't too long.
4094 if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(Param))
4095 OS << (TTP->wasDeclaredWithTypename()? "typename" : "class");
4096 else if (NonTypeTemplateParmDecl *NTTP
4097 = dyn_cast<NonTypeTemplateParmDecl>(Param))
4098 OS << NTTP->getType().getAsString(Policy);
4099 else
4100 OS << "template<...> class";
4101 }
4102
4103 OS << ">";
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004104 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00004105 }
4106
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004107 if (const ClassTemplateSpecializationDecl *ClassSpec
Guy Benyei11169dd2012-12-18 14:30:41 +00004108 = dyn_cast<ClassTemplateSpecializationDecl>(D)) {
4109 // If the type was explicitly written, use that.
4110 if (TypeSourceInfo *TSInfo = ClassSpec->getTypeAsWritten())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004111 return cxstring::createDup(TSInfo->getType().getAsString(Policy));
Guy Benyei11169dd2012-12-18 14:30:41 +00004112
Benjamin Kramer9170e912013-02-22 15:46:01 +00004113 SmallString<128> Str;
Guy Benyei11169dd2012-12-18 14:30:41 +00004114 llvm::raw_svector_ostream OS(Str);
4115 OS << *ClassSpec;
Benjamin Kramer9170e912013-02-22 15:46:01 +00004116 TemplateSpecializationType::PrintTemplateArgumentList(OS,
Guy Benyei11169dd2012-12-18 14:30:41 +00004117 ClassSpec->getTemplateArgs().data(),
4118 ClassSpec->getTemplateArgs().size(),
4119 Policy);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004120 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00004121 }
4122
4123 return clang_getCursorSpelling(C);
4124}
4125
4126CXString clang_getCursorKindSpelling(enum CXCursorKind Kind) {
4127 switch (Kind) {
4128 case CXCursor_FunctionDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004129 return cxstring::createRef("FunctionDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004130 case CXCursor_TypedefDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004131 return cxstring::createRef("TypedefDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004132 case CXCursor_EnumDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004133 return cxstring::createRef("EnumDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004134 case CXCursor_EnumConstantDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004135 return cxstring::createRef("EnumConstantDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004136 case CXCursor_StructDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004137 return cxstring::createRef("StructDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004138 case CXCursor_UnionDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004139 return cxstring::createRef("UnionDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004140 case CXCursor_ClassDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004141 return cxstring::createRef("ClassDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004142 case CXCursor_FieldDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004143 return cxstring::createRef("FieldDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004144 case CXCursor_VarDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004145 return cxstring::createRef("VarDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004146 case CXCursor_ParmDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004147 return cxstring::createRef("ParmDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004148 case CXCursor_ObjCInterfaceDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004149 return cxstring::createRef("ObjCInterfaceDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004150 case CXCursor_ObjCCategoryDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004151 return cxstring::createRef("ObjCCategoryDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004152 case CXCursor_ObjCProtocolDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004153 return cxstring::createRef("ObjCProtocolDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004154 case CXCursor_ObjCPropertyDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004155 return cxstring::createRef("ObjCPropertyDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004156 case CXCursor_ObjCIvarDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004157 return cxstring::createRef("ObjCIvarDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004158 case CXCursor_ObjCInstanceMethodDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004159 return cxstring::createRef("ObjCInstanceMethodDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004160 case CXCursor_ObjCClassMethodDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004161 return cxstring::createRef("ObjCClassMethodDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004162 case CXCursor_ObjCImplementationDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004163 return cxstring::createRef("ObjCImplementationDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004164 case CXCursor_ObjCCategoryImplDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004165 return cxstring::createRef("ObjCCategoryImplDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004166 case CXCursor_CXXMethod:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004167 return cxstring::createRef("CXXMethod");
Guy Benyei11169dd2012-12-18 14:30:41 +00004168 case CXCursor_UnexposedDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004169 return cxstring::createRef("UnexposedDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004170 case CXCursor_ObjCSuperClassRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004171 return cxstring::createRef("ObjCSuperClassRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004172 case CXCursor_ObjCProtocolRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004173 return cxstring::createRef("ObjCProtocolRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004174 case CXCursor_ObjCClassRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004175 return cxstring::createRef("ObjCClassRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004176 case CXCursor_TypeRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004177 return cxstring::createRef("TypeRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004178 case CXCursor_TemplateRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004179 return cxstring::createRef("TemplateRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004180 case CXCursor_NamespaceRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004181 return cxstring::createRef("NamespaceRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004182 case CXCursor_MemberRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004183 return cxstring::createRef("MemberRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004184 case CXCursor_LabelRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004185 return cxstring::createRef("LabelRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004186 case CXCursor_OverloadedDeclRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004187 return cxstring::createRef("OverloadedDeclRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004188 case CXCursor_VariableRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004189 return cxstring::createRef("VariableRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004190 case CXCursor_IntegerLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004191 return cxstring::createRef("IntegerLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00004192 case CXCursor_FloatingLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004193 return cxstring::createRef("FloatingLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00004194 case CXCursor_ImaginaryLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004195 return cxstring::createRef("ImaginaryLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00004196 case CXCursor_StringLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004197 return cxstring::createRef("StringLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00004198 case CXCursor_CharacterLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004199 return cxstring::createRef("CharacterLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00004200 case CXCursor_ParenExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004201 return cxstring::createRef("ParenExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004202 case CXCursor_UnaryOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004203 return cxstring::createRef("UnaryOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00004204 case CXCursor_ArraySubscriptExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004205 return cxstring::createRef("ArraySubscriptExpr");
Alexey Bataev1a3320e2015-08-25 14:24:04 +00004206 case CXCursor_OMPArraySectionExpr:
4207 return cxstring::createRef("OMPArraySectionExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004208 case CXCursor_BinaryOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004209 return cxstring::createRef("BinaryOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00004210 case CXCursor_CompoundAssignOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004211 return cxstring::createRef("CompoundAssignOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00004212 case CXCursor_ConditionalOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004213 return cxstring::createRef("ConditionalOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00004214 case CXCursor_CStyleCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004215 return cxstring::createRef("CStyleCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004216 case CXCursor_CompoundLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004217 return cxstring::createRef("CompoundLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004218 case CXCursor_InitListExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004219 return cxstring::createRef("InitListExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004220 case CXCursor_AddrLabelExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004221 return cxstring::createRef("AddrLabelExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004222 case CXCursor_StmtExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004223 return cxstring::createRef("StmtExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004224 case CXCursor_GenericSelectionExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004225 return cxstring::createRef("GenericSelectionExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004226 case CXCursor_GNUNullExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004227 return cxstring::createRef("GNUNullExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004228 case CXCursor_CXXStaticCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004229 return cxstring::createRef("CXXStaticCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004230 case CXCursor_CXXDynamicCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004231 return cxstring::createRef("CXXDynamicCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004232 case CXCursor_CXXReinterpretCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004233 return cxstring::createRef("CXXReinterpretCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004234 case CXCursor_CXXConstCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004235 return cxstring::createRef("CXXConstCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004236 case CXCursor_CXXFunctionalCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004237 return cxstring::createRef("CXXFunctionalCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004238 case CXCursor_CXXTypeidExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004239 return cxstring::createRef("CXXTypeidExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004240 case CXCursor_CXXBoolLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004241 return cxstring::createRef("CXXBoolLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004242 case CXCursor_CXXNullPtrLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004243 return cxstring::createRef("CXXNullPtrLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004244 case CXCursor_CXXThisExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004245 return cxstring::createRef("CXXThisExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004246 case CXCursor_CXXThrowExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004247 return cxstring::createRef("CXXThrowExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004248 case CXCursor_CXXNewExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004249 return cxstring::createRef("CXXNewExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004250 case CXCursor_CXXDeleteExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004251 return cxstring::createRef("CXXDeleteExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004252 case CXCursor_UnaryExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004253 return cxstring::createRef("UnaryExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004254 case CXCursor_ObjCStringLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004255 return cxstring::createRef("ObjCStringLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00004256 case CXCursor_ObjCBoolLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004257 return cxstring::createRef("ObjCBoolLiteralExpr");
Argyrios Kyrtzidisc2233be2013-04-23 17:57:17 +00004258 case CXCursor_ObjCSelfExpr:
4259 return cxstring::createRef("ObjCSelfExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004260 case CXCursor_ObjCEncodeExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004261 return cxstring::createRef("ObjCEncodeExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004262 case CXCursor_ObjCSelectorExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004263 return cxstring::createRef("ObjCSelectorExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004264 case CXCursor_ObjCProtocolExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004265 return cxstring::createRef("ObjCProtocolExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004266 case CXCursor_ObjCBridgedCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004267 return cxstring::createRef("ObjCBridgedCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004268 case CXCursor_BlockExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004269 return cxstring::createRef("BlockExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004270 case CXCursor_PackExpansionExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004271 return cxstring::createRef("PackExpansionExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004272 case CXCursor_SizeOfPackExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004273 return cxstring::createRef("SizeOfPackExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004274 case CXCursor_LambdaExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004275 return cxstring::createRef("LambdaExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004276 case CXCursor_UnexposedExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004277 return cxstring::createRef("UnexposedExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004278 case CXCursor_DeclRefExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004279 return cxstring::createRef("DeclRefExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004280 case CXCursor_MemberRefExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004281 return cxstring::createRef("MemberRefExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004282 case CXCursor_CallExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004283 return cxstring::createRef("CallExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004284 case CXCursor_ObjCMessageExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004285 return cxstring::createRef("ObjCMessageExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004286 case CXCursor_UnexposedStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004287 return cxstring::createRef("UnexposedStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004288 case CXCursor_DeclStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004289 return cxstring::createRef("DeclStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004290 case CXCursor_LabelStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004291 return cxstring::createRef("LabelStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004292 case CXCursor_CompoundStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004293 return cxstring::createRef("CompoundStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004294 case CXCursor_CaseStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004295 return cxstring::createRef("CaseStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004296 case CXCursor_DefaultStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004297 return cxstring::createRef("DefaultStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004298 case CXCursor_IfStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004299 return cxstring::createRef("IfStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004300 case CXCursor_SwitchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004301 return cxstring::createRef("SwitchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004302 case CXCursor_WhileStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004303 return cxstring::createRef("WhileStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004304 case CXCursor_DoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004305 return cxstring::createRef("DoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004306 case CXCursor_ForStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004307 return cxstring::createRef("ForStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004308 case CXCursor_GotoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004309 return cxstring::createRef("GotoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004310 case CXCursor_IndirectGotoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004311 return cxstring::createRef("IndirectGotoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004312 case CXCursor_ContinueStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004313 return cxstring::createRef("ContinueStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004314 case CXCursor_BreakStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004315 return cxstring::createRef("BreakStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004316 case CXCursor_ReturnStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004317 return cxstring::createRef("ReturnStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004318 case CXCursor_GCCAsmStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004319 return cxstring::createRef("GCCAsmStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004320 case CXCursor_MSAsmStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004321 return cxstring::createRef("MSAsmStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004322 case CXCursor_ObjCAtTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004323 return cxstring::createRef("ObjCAtTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004324 case CXCursor_ObjCAtCatchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004325 return cxstring::createRef("ObjCAtCatchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004326 case CXCursor_ObjCAtFinallyStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004327 return cxstring::createRef("ObjCAtFinallyStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004328 case CXCursor_ObjCAtThrowStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004329 return cxstring::createRef("ObjCAtThrowStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004330 case CXCursor_ObjCAtSynchronizedStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004331 return cxstring::createRef("ObjCAtSynchronizedStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004332 case CXCursor_ObjCAutoreleasePoolStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004333 return cxstring::createRef("ObjCAutoreleasePoolStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004334 case CXCursor_ObjCForCollectionStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004335 return cxstring::createRef("ObjCForCollectionStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004336 case CXCursor_CXXCatchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004337 return cxstring::createRef("CXXCatchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004338 case CXCursor_CXXTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004339 return cxstring::createRef("CXXTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004340 case CXCursor_CXXForRangeStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004341 return cxstring::createRef("CXXForRangeStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004342 case CXCursor_SEHTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004343 return cxstring::createRef("SEHTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004344 case CXCursor_SEHExceptStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004345 return cxstring::createRef("SEHExceptStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004346 case CXCursor_SEHFinallyStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004347 return cxstring::createRef("SEHFinallyStmt");
Nico Weber9b982072014-07-07 00:12:30 +00004348 case CXCursor_SEHLeaveStmt:
4349 return cxstring::createRef("SEHLeaveStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004350 case CXCursor_NullStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004351 return cxstring::createRef("NullStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004352 case CXCursor_InvalidFile:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004353 return cxstring::createRef("InvalidFile");
Guy Benyei11169dd2012-12-18 14:30:41 +00004354 case CXCursor_InvalidCode:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004355 return cxstring::createRef("InvalidCode");
Guy Benyei11169dd2012-12-18 14:30:41 +00004356 case CXCursor_NoDeclFound:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004357 return cxstring::createRef("NoDeclFound");
Guy Benyei11169dd2012-12-18 14:30:41 +00004358 case CXCursor_NotImplemented:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004359 return cxstring::createRef("NotImplemented");
Guy Benyei11169dd2012-12-18 14:30:41 +00004360 case CXCursor_TranslationUnit:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004361 return cxstring::createRef("TranslationUnit");
Guy Benyei11169dd2012-12-18 14:30:41 +00004362 case CXCursor_UnexposedAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004363 return cxstring::createRef("UnexposedAttr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004364 case CXCursor_IBActionAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004365 return cxstring::createRef("attribute(ibaction)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004366 case CXCursor_IBOutletAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004367 return cxstring::createRef("attribute(iboutlet)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004368 case CXCursor_IBOutletCollectionAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004369 return cxstring::createRef("attribute(iboutletcollection)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004370 case CXCursor_CXXFinalAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004371 return cxstring::createRef("attribute(final)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004372 case CXCursor_CXXOverrideAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004373 return cxstring::createRef("attribute(override)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004374 case CXCursor_AnnotateAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004375 return cxstring::createRef("attribute(annotate)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004376 case CXCursor_AsmLabelAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004377 return cxstring::createRef("asm label");
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00004378 case CXCursor_PackedAttr:
4379 return cxstring::createRef("attribute(packed)");
Joey Gouly81228382014-05-01 15:41:58 +00004380 case CXCursor_PureAttr:
4381 return cxstring::createRef("attribute(pure)");
4382 case CXCursor_ConstAttr:
4383 return cxstring::createRef("attribute(const)");
4384 case CXCursor_NoDuplicateAttr:
4385 return cxstring::createRef("attribute(noduplicate)");
Eli Bendersky2581e662014-05-28 19:29:58 +00004386 case CXCursor_CUDAConstantAttr:
4387 return cxstring::createRef("attribute(constant)");
4388 case CXCursor_CUDADeviceAttr:
4389 return cxstring::createRef("attribute(device)");
4390 case CXCursor_CUDAGlobalAttr:
4391 return cxstring::createRef("attribute(global)");
4392 case CXCursor_CUDAHostAttr:
4393 return cxstring::createRef("attribute(host)");
Eli Bendersky9b071472014-08-08 14:59:00 +00004394 case CXCursor_CUDASharedAttr:
4395 return cxstring::createRef("attribute(shared)");
Saleem Abdulrasool79c69712015-09-05 18:53:43 +00004396 case CXCursor_VisibilityAttr:
4397 return cxstring::createRef("attribute(visibility)");
Saleem Abdulrasool8aa0b802015-12-10 18:45:18 +00004398 case CXCursor_DLLExport:
4399 return cxstring::createRef("attribute(dllexport)");
4400 case CXCursor_DLLImport:
4401 return cxstring::createRef("attribute(dllimport)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004402 case CXCursor_PreprocessingDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004403 return cxstring::createRef("preprocessing directive");
Guy Benyei11169dd2012-12-18 14:30:41 +00004404 case CXCursor_MacroDefinition:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004405 return cxstring::createRef("macro definition");
Guy Benyei11169dd2012-12-18 14:30:41 +00004406 case CXCursor_MacroExpansion:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004407 return cxstring::createRef("macro expansion");
Guy Benyei11169dd2012-12-18 14:30:41 +00004408 case CXCursor_InclusionDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004409 return cxstring::createRef("inclusion directive");
Guy Benyei11169dd2012-12-18 14:30:41 +00004410 case CXCursor_Namespace:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004411 return cxstring::createRef("Namespace");
Guy Benyei11169dd2012-12-18 14:30:41 +00004412 case CXCursor_LinkageSpec:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004413 return cxstring::createRef("LinkageSpec");
Guy Benyei11169dd2012-12-18 14:30:41 +00004414 case CXCursor_CXXBaseSpecifier:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004415 return cxstring::createRef("C++ base class specifier");
Guy Benyei11169dd2012-12-18 14:30:41 +00004416 case CXCursor_Constructor:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004417 return cxstring::createRef("CXXConstructor");
Guy Benyei11169dd2012-12-18 14:30:41 +00004418 case CXCursor_Destructor:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004419 return cxstring::createRef("CXXDestructor");
Guy Benyei11169dd2012-12-18 14:30:41 +00004420 case CXCursor_ConversionFunction:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004421 return cxstring::createRef("CXXConversion");
Guy Benyei11169dd2012-12-18 14:30:41 +00004422 case CXCursor_TemplateTypeParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004423 return cxstring::createRef("TemplateTypeParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00004424 case CXCursor_NonTypeTemplateParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004425 return cxstring::createRef("NonTypeTemplateParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00004426 case CXCursor_TemplateTemplateParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004427 return cxstring::createRef("TemplateTemplateParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00004428 case CXCursor_FunctionTemplate:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004429 return cxstring::createRef("FunctionTemplate");
Guy Benyei11169dd2012-12-18 14:30:41 +00004430 case CXCursor_ClassTemplate:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004431 return cxstring::createRef("ClassTemplate");
Guy Benyei11169dd2012-12-18 14:30:41 +00004432 case CXCursor_ClassTemplatePartialSpecialization:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004433 return cxstring::createRef("ClassTemplatePartialSpecialization");
Guy Benyei11169dd2012-12-18 14:30:41 +00004434 case CXCursor_NamespaceAlias:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004435 return cxstring::createRef("NamespaceAlias");
Guy Benyei11169dd2012-12-18 14:30:41 +00004436 case CXCursor_UsingDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004437 return cxstring::createRef("UsingDirective");
Guy Benyei11169dd2012-12-18 14:30:41 +00004438 case CXCursor_UsingDeclaration:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004439 return cxstring::createRef("UsingDeclaration");
Guy Benyei11169dd2012-12-18 14:30:41 +00004440 case CXCursor_TypeAliasDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004441 return cxstring::createRef("TypeAliasDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004442 case CXCursor_ObjCSynthesizeDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004443 return cxstring::createRef("ObjCSynthesizeDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004444 case CXCursor_ObjCDynamicDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004445 return cxstring::createRef("ObjCDynamicDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004446 case CXCursor_CXXAccessSpecifier:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004447 return cxstring::createRef("CXXAccessSpecifier");
Guy Benyei11169dd2012-12-18 14:30:41 +00004448 case CXCursor_ModuleImportDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004449 return cxstring::createRef("ModuleImport");
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00004450 case CXCursor_OMPParallelDirective:
Alexey Bataev1b59ab52014-02-27 08:29:12 +00004451 return cxstring::createRef("OMPParallelDirective");
4452 case CXCursor_OMPSimdDirective:
4453 return cxstring::createRef("OMPSimdDirective");
Alexey Bataevf29276e2014-06-18 04:14:57 +00004454 case CXCursor_OMPForDirective:
4455 return cxstring::createRef("OMPForDirective");
Alexander Musmanf82886e2014-09-18 05:12:34 +00004456 case CXCursor_OMPForSimdDirective:
4457 return cxstring::createRef("OMPForSimdDirective");
Alexey Bataevd3f8dd22014-06-25 11:44:49 +00004458 case CXCursor_OMPSectionsDirective:
4459 return cxstring::createRef("OMPSectionsDirective");
Alexey Bataev1e0498a2014-06-26 08:21:58 +00004460 case CXCursor_OMPSectionDirective:
4461 return cxstring::createRef("OMPSectionDirective");
Alexey Bataevd1e40fb2014-06-26 12:05:45 +00004462 case CXCursor_OMPSingleDirective:
4463 return cxstring::createRef("OMPSingleDirective");
Alexander Musman80c22892014-07-17 08:54:58 +00004464 case CXCursor_OMPMasterDirective:
4465 return cxstring::createRef("OMPMasterDirective");
Alexander Musmand9ed09f2014-07-21 09:42:05 +00004466 case CXCursor_OMPCriticalDirective:
4467 return cxstring::createRef("OMPCriticalDirective");
Alexey Bataev4acb8592014-07-07 13:01:15 +00004468 case CXCursor_OMPParallelForDirective:
4469 return cxstring::createRef("OMPParallelForDirective");
Alexander Musmane4e893b2014-09-23 09:33:00 +00004470 case CXCursor_OMPParallelForSimdDirective:
4471 return cxstring::createRef("OMPParallelForSimdDirective");
Alexey Bataev84d0b3e2014-07-08 08:12:03 +00004472 case CXCursor_OMPParallelSectionsDirective:
4473 return cxstring::createRef("OMPParallelSectionsDirective");
Alexey Bataev9c2e8ee2014-07-11 11:25:16 +00004474 case CXCursor_OMPTaskDirective:
4475 return cxstring::createRef("OMPTaskDirective");
Alexey Bataev68446b72014-07-18 07:47:19 +00004476 case CXCursor_OMPTaskyieldDirective:
4477 return cxstring::createRef("OMPTaskyieldDirective");
Alexey Bataev4d1dfea2014-07-18 09:11:51 +00004478 case CXCursor_OMPBarrierDirective:
4479 return cxstring::createRef("OMPBarrierDirective");
Alexey Bataev2df347a2014-07-18 10:17:07 +00004480 case CXCursor_OMPTaskwaitDirective:
4481 return cxstring::createRef("OMPTaskwaitDirective");
Alexey Bataevc30dd2d2015-06-18 12:14:09 +00004482 case CXCursor_OMPTaskgroupDirective:
4483 return cxstring::createRef("OMPTaskgroupDirective");
Alexey Bataev6125da92014-07-21 11:26:11 +00004484 case CXCursor_OMPFlushDirective:
4485 return cxstring::createRef("OMPFlushDirective");
Alexey Bataev9fb6e642014-07-22 06:45:04 +00004486 case CXCursor_OMPOrderedDirective:
4487 return cxstring::createRef("OMPOrderedDirective");
Alexey Bataev0162e452014-07-22 10:10:35 +00004488 case CXCursor_OMPAtomicDirective:
4489 return cxstring::createRef("OMPAtomicDirective");
Alexey Bataev0bd520b2014-09-19 08:19:49 +00004490 case CXCursor_OMPTargetDirective:
4491 return cxstring::createRef("OMPTargetDirective");
Michael Wong65f367f2015-07-21 13:44:28 +00004492 case CXCursor_OMPTargetDataDirective:
4493 return cxstring::createRef("OMPTargetDataDirective");
Alexey Bataev13314bf2014-10-09 04:18:56 +00004494 case CXCursor_OMPTeamsDirective:
4495 return cxstring::createRef("OMPTeamsDirective");
Alexey Bataev6d4ed052015-07-01 06:57:41 +00004496 case CXCursor_OMPCancellationPointDirective:
4497 return cxstring::createRef("OMPCancellationPointDirective");
Alexey Bataev80909872015-07-02 11:25:17 +00004498 case CXCursor_OMPCancelDirective:
4499 return cxstring::createRef("OMPCancelDirective");
Alexey Bataev49f6e782015-12-01 04:18:41 +00004500 case CXCursor_OMPTaskLoopDirective:
4501 return cxstring::createRef("OMPTaskLoopDirective");
Alexey Bataev0a6ed842015-12-03 09:40:15 +00004502 case CXCursor_OMPTaskLoopSimdDirective:
4503 return cxstring::createRef("OMPTaskLoopSimdDirective");
Carlo Bertolli6200a3d2015-12-14 14:51:25 +00004504 case CXCursor_OMPDistributeDirective:
4505 return cxstring::createRef("OMPDistributeDirective");
Francisco Lopes da Silva975a9f62015-01-21 16:24:11 +00004506 case CXCursor_OverloadCandidate:
4507 return cxstring::createRef("OverloadCandidate");
Sergey Kalinichev8f3b1872015-11-15 13:48:32 +00004508 case CXCursor_TypeAliasTemplateDecl:
4509 return cxstring::createRef("TypeAliasTemplateDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004510 }
4511
4512 llvm_unreachable("Unhandled CXCursorKind");
4513}
4514
4515struct GetCursorData {
4516 SourceLocation TokenBeginLoc;
4517 bool PointsAtMacroArgExpansion;
4518 bool VisitedObjCPropertyImplDecl;
4519 SourceLocation VisitedDeclaratorDeclStartLoc;
4520 CXCursor &BestCursor;
4521
4522 GetCursorData(SourceManager &SM,
4523 SourceLocation tokenBegin, CXCursor &outputCursor)
4524 : TokenBeginLoc(tokenBegin), BestCursor(outputCursor) {
4525 PointsAtMacroArgExpansion = SM.isMacroArgExpansion(tokenBegin);
4526 VisitedObjCPropertyImplDecl = false;
4527 }
4528};
4529
4530static enum CXChildVisitResult GetCursorVisitor(CXCursor cursor,
4531 CXCursor parent,
4532 CXClientData client_data) {
4533 GetCursorData *Data = static_cast<GetCursorData *>(client_data);
4534 CXCursor *BestCursor = &Data->BestCursor;
4535
4536 // If we point inside a macro argument we should provide info of what the
4537 // token is so use the actual cursor, don't replace it with a macro expansion
4538 // cursor.
4539 if (cursor.kind == CXCursor_MacroExpansion && Data->PointsAtMacroArgExpansion)
4540 return CXChildVisit_Recurse;
4541
4542 if (clang_isDeclaration(cursor.kind)) {
4543 // Avoid having the implicit methods override the property decls.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004544 if (const ObjCMethodDecl *MD
Guy Benyei11169dd2012-12-18 14:30:41 +00004545 = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
4546 if (MD->isImplicit())
4547 return CXChildVisit_Break;
4548
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004549 } else if (const ObjCInterfaceDecl *ID
Guy Benyei11169dd2012-12-18 14:30:41 +00004550 = dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(cursor))) {
4551 // Check that when we have multiple @class references in the same line,
4552 // that later ones do not override the previous ones.
4553 // If we have:
4554 // @class Foo, Bar;
4555 // source ranges for both start at '@', so 'Bar' will end up overriding
4556 // 'Foo' even though the cursor location was at 'Foo'.
4557 if (BestCursor->kind == CXCursor_ObjCInterfaceDecl ||
4558 BestCursor->kind == CXCursor_ObjCClassRef)
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004559 if (const ObjCInterfaceDecl *PrevID
Guy Benyei11169dd2012-12-18 14:30:41 +00004560 = dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(*BestCursor))){
4561 if (PrevID != ID &&
4562 !PrevID->isThisDeclarationADefinition() &&
4563 !ID->isThisDeclarationADefinition())
4564 return CXChildVisit_Break;
4565 }
4566
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004567 } else if (const DeclaratorDecl *DD
Guy Benyei11169dd2012-12-18 14:30:41 +00004568 = dyn_cast_or_null<DeclaratorDecl>(getCursorDecl(cursor))) {
4569 SourceLocation StartLoc = DD->getSourceRange().getBegin();
4570 // Check that when we have multiple declarators in the same line,
4571 // that later ones do not override the previous ones.
4572 // If we have:
4573 // int Foo, Bar;
4574 // source ranges for both start at 'int', so 'Bar' will end up overriding
4575 // 'Foo' even though the cursor location was at 'Foo'.
4576 if (Data->VisitedDeclaratorDeclStartLoc == StartLoc)
4577 return CXChildVisit_Break;
4578 Data->VisitedDeclaratorDeclStartLoc = StartLoc;
4579
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004580 } else if (const ObjCPropertyImplDecl *PropImp
Guy Benyei11169dd2012-12-18 14:30:41 +00004581 = dyn_cast_or_null<ObjCPropertyImplDecl>(getCursorDecl(cursor))) {
4582 (void)PropImp;
4583 // Check that when we have multiple @synthesize in the same line,
4584 // that later ones do not override the previous ones.
4585 // If we have:
4586 // @synthesize Foo, Bar;
4587 // source ranges for both start at '@', so 'Bar' will end up overriding
4588 // 'Foo' even though the cursor location was at 'Foo'.
4589 if (Data->VisitedObjCPropertyImplDecl)
4590 return CXChildVisit_Break;
4591 Data->VisitedObjCPropertyImplDecl = true;
4592 }
4593 }
4594
4595 if (clang_isExpression(cursor.kind) &&
4596 clang_isDeclaration(BestCursor->kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004597 if (const Decl *D = getCursorDecl(*BestCursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004598 // Avoid having the cursor of an expression replace the declaration cursor
4599 // when the expression source range overlaps the declaration range.
4600 // This can happen for C++ constructor expressions whose range generally
4601 // include the variable declaration, e.g.:
4602 // MyCXXClass foo; // Make sure pointing at 'foo' returns a VarDecl cursor.
4603 if (D->getLocation().isValid() && Data->TokenBeginLoc.isValid() &&
4604 D->getLocation() == Data->TokenBeginLoc)
4605 return CXChildVisit_Break;
4606 }
4607 }
4608
4609 // If our current best cursor is the construction of a temporary object,
4610 // don't replace that cursor with a type reference, because we want
4611 // clang_getCursor() to point at the constructor.
4612 if (clang_isExpression(BestCursor->kind) &&
4613 isa<CXXTemporaryObjectExpr>(getCursorExpr(*BestCursor)) &&
4614 cursor.kind == CXCursor_TypeRef) {
4615 // Keep the cursor pointing at CXXTemporaryObjectExpr but also mark it
4616 // as having the actual point on the type reference.
4617 *BestCursor = getTypeRefedCallExprCursor(*BestCursor);
4618 return CXChildVisit_Recurse;
4619 }
Douglas Gregore9d95f12015-07-07 03:57:35 +00004620
4621 // If we already have an Objective-C superclass reference, don't
4622 // update it further.
4623 if (BestCursor->kind == CXCursor_ObjCSuperClassRef)
4624 return CXChildVisit_Break;
4625
Guy Benyei11169dd2012-12-18 14:30:41 +00004626 *BestCursor = cursor;
4627 return CXChildVisit_Recurse;
4628}
4629
4630CXCursor clang_getCursor(CXTranslationUnit TU, CXSourceLocation Loc) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00004631 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004632 LOG_BAD_TU(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004633 return clang_getNullCursor();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004634 }
Guy Benyei11169dd2012-12-18 14:30:41 +00004635
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004636 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004637 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
4638
4639 SourceLocation SLoc = cxloc::translateSourceLocation(Loc);
4640 CXCursor Result = cxcursor::getCursor(TU, SLoc);
4641
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004642 LOG_FUNC_SECTION {
Guy Benyei11169dd2012-12-18 14:30:41 +00004643 CXFile SearchFile;
4644 unsigned SearchLine, SearchColumn;
4645 CXFile ResultFile;
4646 unsigned ResultLine, ResultColumn;
4647 CXString SearchFileName, ResultFileName, KindSpelling, USR;
4648 const char *IsDef = clang_isCursorDefinition(Result)? " (Definition)" : "";
4649 CXSourceLocation ResultLoc = clang_getCursorLocation(Result);
Craig Topper69186e72014-06-08 08:38:04 +00004650
4651 clang_getFileLocation(Loc, &SearchFile, &SearchLine, &SearchColumn,
4652 nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004653 clang_getFileLocation(ResultLoc, &ResultFile, &ResultLine,
Craig Topper69186e72014-06-08 08:38:04 +00004654 &ResultColumn, nullptr);
Guy Benyei11169dd2012-12-18 14:30:41 +00004655 SearchFileName = clang_getFileName(SearchFile);
4656 ResultFileName = clang_getFileName(ResultFile);
4657 KindSpelling = clang_getCursorKindSpelling(Result.kind);
4658 USR = clang_getCursorUSR(Result);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004659 *Log << llvm::format("(%s:%d:%d) = %s",
4660 clang_getCString(SearchFileName), SearchLine, SearchColumn,
4661 clang_getCString(KindSpelling))
4662 << llvm::format("(%s:%d:%d):%s%s",
4663 clang_getCString(ResultFileName), ResultLine, ResultColumn,
4664 clang_getCString(USR), IsDef);
Guy Benyei11169dd2012-12-18 14:30:41 +00004665 clang_disposeString(SearchFileName);
4666 clang_disposeString(ResultFileName);
4667 clang_disposeString(KindSpelling);
4668 clang_disposeString(USR);
4669
4670 CXCursor Definition = clang_getCursorDefinition(Result);
4671 if (!clang_equalCursors(Definition, clang_getNullCursor())) {
4672 CXSourceLocation DefinitionLoc = clang_getCursorLocation(Definition);
4673 CXString DefinitionKindSpelling
4674 = clang_getCursorKindSpelling(Definition.kind);
4675 CXFile DefinitionFile;
4676 unsigned DefinitionLine, DefinitionColumn;
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004677 clang_getFileLocation(DefinitionLoc, &DefinitionFile,
Craig Topper69186e72014-06-08 08:38:04 +00004678 &DefinitionLine, &DefinitionColumn, nullptr);
Guy Benyei11169dd2012-12-18 14:30:41 +00004679 CXString DefinitionFileName = clang_getFileName(DefinitionFile);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004680 *Log << llvm::format(" -> %s(%s:%d:%d)",
4681 clang_getCString(DefinitionKindSpelling),
4682 clang_getCString(DefinitionFileName),
4683 DefinitionLine, DefinitionColumn);
Guy Benyei11169dd2012-12-18 14:30:41 +00004684 clang_disposeString(DefinitionFileName);
4685 clang_disposeString(DefinitionKindSpelling);
4686 }
4687 }
4688
4689 return Result;
4690}
4691
4692CXCursor clang_getNullCursor(void) {
4693 return MakeCXCursorInvalid(CXCursor_InvalidFile);
4694}
4695
4696unsigned clang_equalCursors(CXCursor X, CXCursor Y) {
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00004697 // Clear out the "FirstInDeclGroup" part in a declaration cursor, since we
4698 // can't set consistently. For example, when visiting a DeclStmt we will set
4699 // it but we don't set it on the result of clang_getCursorDefinition for
4700 // a reference of the same declaration.
4701 // FIXME: Setting "FirstInDeclGroup" in CXCursors is a hack that only works
4702 // when visiting a DeclStmt currently, the AST should be enhanced to be able
4703 // to provide that kind of info.
4704 if (clang_isDeclaration(X.kind))
Craig Topper69186e72014-06-08 08:38:04 +00004705 X.data[1] = nullptr;
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00004706 if (clang_isDeclaration(Y.kind))
Craig Topper69186e72014-06-08 08:38:04 +00004707 Y.data[1] = nullptr;
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00004708
Guy Benyei11169dd2012-12-18 14:30:41 +00004709 return X == Y;
4710}
4711
4712unsigned clang_hashCursor(CXCursor C) {
4713 unsigned Index = 0;
4714 if (clang_isExpression(C.kind) || clang_isStatement(C.kind))
4715 Index = 1;
4716
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004717 return llvm::DenseMapInfo<std::pair<unsigned, const void*> >::getHashValue(
Guy Benyei11169dd2012-12-18 14:30:41 +00004718 std::make_pair(C.kind, C.data[Index]));
4719}
4720
4721unsigned clang_isInvalid(enum CXCursorKind K) {
4722 return K >= CXCursor_FirstInvalid && K <= CXCursor_LastInvalid;
4723}
4724
4725unsigned clang_isDeclaration(enum CXCursorKind K) {
4726 return (K >= CXCursor_FirstDecl && K <= CXCursor_LastDecl) ||
4727 (K >= CXCursor_FirstExtraDecl && K <= CXCursor_LastExtraDecl);
4728}
4729
4730unsigned clang_isReference(enum CXCursorKind K) {
4731 return K >= CXCursor_FirstRef && K <= CXCursor_LastRef;
4732}
4733
4734unsigned clang_isExpression(enum CXCursorKind K) {
4735 return K >= CXCursor_FirstExpr && K <= CXCursor_LastExpr;
4736}
4737
4738unsigned clang_isStatement(enum CXCursorKind K) {
4739 return K >= CXCursor_FirstStmt && K <= CXCursor_LastStmt;
4740}
4741
4742unsigned clang_isAttribute(enum CXCursorKind K) {
4743 return K >= CXCursor_FirstAttr && K <= CXCursor_LastAttr;
4744}
4745
4746unsigned clang_isTranslationUnit(enum CXCursorKind K) {
4747 return K == CXCursor_TranslationUnit;
4748}
4749
4750unsigned clang_isPreprocessing(enum CXCursorKind K) {
4751 return K >= CXCursor_FirstPreprocessing && K <= CXCursor_LastPreprocessing;
4752}
4753
4754unsigned clang_isUnexposed(enum CXCursorKind K) {
4755 switch (K) {
4756 case CXCursor_UnexposedDecl:
4757 case CXCursor_UnexposedExpr:
4758 case CXCursor_UnexposedStmt:
4759 case CXCursor_UnexposedAttr:
4760 return true;
4761 default:
4762 return false;
4763 }
4764}
4765
4766CXCursorKind clang_getCursorKind(CXCursor C) {
4767 return C.kind;
4768}
4769
4770CXSourceLocation clang_getCursorLocation(CXCursor C) {
4771 if (clang_isReference(C.kind)) {
4772 switch (C.kind) {
4773 case CXCursor_ObjCSuperClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004774 std::pair<const ObjCInterfaceDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004775 = getCursorObjCSuperClassRef(C);
4776 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4777 }
4778
4779 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004780 std::pair<const ObjCProtocolDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004781 = getCursorObjCProtocolRef(C);
4782 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4783 }
4784
4785 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004786 std::pair<const ObjCInterfaceDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004787 = getCursorObjCClassRef(C);
4788 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4789 }
4790
4791 case CXCursor_TypeRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004792 std::pair<const TypeDecl *, SourceLocation> P = getCursorTypeRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004793 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4794 }
4795
4796 case CXCursor_TemplateRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004797 std::pair<const TemplateDecl *, SourceLocation> P =
4798 getCursorTemplateRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004799 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4800 }
4801
4802 case CXCursor_NamespaceRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004803 std::pair<const NamedDecl *, SourceLocation> P = getCursorNamespaceRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004804 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4805 }
4806
4807 case CXCursor_MemberRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004808 std::pair<const FieldDecl *, SourceLocation> P = getCursorMemberRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004809 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4810 }
4811
4812 case CXCursor_VariableRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004813 std::pair<const VarDecl *, SourceLocation> P = getCursorVariableRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004814 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4815 }
4816
4817 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004818 const CXXBaseSpecifier *BaseSpec = getCursorCXXBaseSpecifier(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004819 if (!BaseSpec)
4820 return clang_getNullLocation();
4821
4822 if (TypeSourceInfo *TSInfo = BaseSpec->getTypeSourceInfo())
4823 return cxloc::translateSourceLocation(getCursorContext(C),
4824 TSInfo->getTypeLoc().getBeginLoc());
4825
4826 return cxloc::translateSourceLocation(getCursorContext(C),
4827 BaseSpec->getLocStart());
4828 }
4829
4830 case CXCursor_LabelRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004831 std::pair<const LabelStmt *, SourceLocation> P = getCursorLabelRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004832 return cxloc::translateSourceLocation(getCursorContext(C), P.second);
4833 }
4834
4835 case CXCursor_OverloadedDeclRef:
4836 return cxloc::translateSourceLocation(getCursorContext(C),
4837 getCursorOverloadedDeclRef(C).second);
4838
4839 default:
4840 // FIXME: Need a way to enumerate all non-reference cases.
4841 llvm_unreachable("Missed a reference kind");
4842 }
4843 }
4844
4845 if (clang_isExpression(C.kind))
4846 return cxloc::translateSourceLocation(getCursorContext(C),
4847 getLocationFromExpr(getCursorExpr(C)));
4848
4849 if (clang_isStatement(C.kind))
4850 return cxloc::translateSourceLocation(getCursorContext(C),
4851 getCursorStmt(C)->getLocStart());
4852
4853 if (C.kind == CXCursor_PreprocessingDirective) {
4854 SourceLocation L = cxcursor::getCursorPreprocessingDirective(C).getBegin();
4855 return cxloc::translateSourceLocation(getCursorContext(C), L);
4856 }
4857
4858 if (C.kind == CXCursor_MacroExpansion) {
4859 SourceLocation L
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00004860 = cxcursor::getCursorMacroExpansion(C).getSourceRange().getBegin();
Guy Benyei11169dd2012-12-18 14:30:41 +00004861 return cxloc::translateSourceLocation(getCursorContext(C), L);
4862 }
4863
4864 if (C.kind == CXCursor_MacroDefinition) {
4865 SourceLocation L = cxcursor::getCursorMacroDefinition(C)->getLocation();
4866 return cxloc::translateSourceLocation(getCursorContext(C), L);
4867 }
4868
4869 if (C.kind == CXCursor_InclusionDirective) {
4870 SourceLocation L
4871 = cxcursor::getCursorInclusionDirective(C)->getSourceRange().getBegin();
4872 return cxloc::translateSourceLocation(getCursorContext(C), L);
4873 }
4874
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00004875 if (clang_isAttribute(C.kind)) {
4876 SourceLocation L
4877 = cxcursor::getCursorAttr(C)->getLocation();
4878 return cxloc::translateSourceLocation(getCursorContext(C), L);
4879 }
4880
Guy Benyei11169dd2012-12-18 14:30:41 +00004881 if (!clang_isDeclaration(C.kind))
4882 return clang_getNullLocation();
4883
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004884 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004885 if (!D)
4886 return clang_getNullLocation();
4887
4888 SourceLocation Loc = D->getLocation();
4889 // FIXME: Multiple variables declared in a single declaration
4890 // currently lack the information needed to correctly determine their
4891 // ranges when accounting for the type-specifier. We use context
4892 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4893 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004894 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004895 if (!cxcursor::isFirstInDeclGroup(C))
4896 Loc = VD->getLocation();
4897 }
4898
4899 // For ObjC methods, give the start location of the method name.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004900 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004901 Loc = MD->getSelectorStartLoc();
4902
4903 return cxloc::translateSourceLocation(getCursorContext(C), Loc);
4904}
4905
4906} // end extern "C"
4907
4908CXCursor cxcursor::getCursor(CXTranslationUnit TU, SourceLocation SLoc) {
4909 assert(TU);
4910
4911 // Guard against an invalid SourceLocation, or we may assert in one
4912 // of the following calls.
4913 if (SLoc.isInvalid())
4914 return clang_getNullCursor();
4915
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004916 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004917
4918 // Translate the given source location to make it point at the beginning of
4919 // the token under the cursor.
4920 SLoc = Lexer::GetBeginningOfToken(SLoc, CXXUnit->getSourceManager(),
4921 CXXUnit->getASTContext().getLangOpts());
4922
4923 CXCursor Result = MakeCXCursorInvalid(CXCursor_NoDeclFound);
4924 if (SLoc.isValid()) {
4925 GetCursorData ResultData(CXXUnit->getSourceManager(), SLoc, Result);
4926 CursorVisitor CursorVis(TU, GetCursorVisitor, &ResultData,
4927 /*VisitPreprocessorLast=*/true,
4928 /*VisitIncludedEntities=*/false,
4929 SourceLocation(SLoc));
4930 CursorVis.visitFileRegion();
4931 }
4932
4933 return Result;
4934}
4935
4936static SourceRange getRawCursorExtent(CXCursor C) {
4937 if (clang_isReference(C.kind)) {
4938 switch (C.kind) {
4939 case CXCursor_ObjCSuperClassRef:
4940 return getCursorObjCSuperClassRef(C).second;
4941
4942 case CXCursor_ObjCProtocolRef:
4943 return getCursorObjCProtocolRef(C).second;
4944
4945 case CXCursor_ObjCClassRef:
4946 return getCursorObjCClassRef(C).second;
4947
4948 case CXCursor_TypeRef:
4949 return getCursorTypeRef(C).second;
4950
4951 case CXCursor_TemplateRef:
4952 return getCursorTemplateRef(C).second;
4953
4954 case CXCursor_NamespaceRef:
4955 return getCursorNamespaceRef(C).second;
4956
4957 case CXCursor_MemberRef:
4958 return getCursorMemberRef(C).second;
4959
4960 case CXCursor_CXXBaseSpecifier:
4961 return getCursorCXXBaseSpecifier(C)->getSourceRange();
4962
4963 case CXCursor_LabelRef:
4964 return getCursorLabelRef(C).second;
4965
4966 case CXCursor_OverloadedDeclRef:
4967 return getCursorOverloadedDeclRef(C).second;
4968
4969 case CXCursor_VariableRef:
4970 return getCursorVariableRef(C).second;
4971
4972 default:
4973 // FIXME: Need a way to enumerate all non-reference cases.
4974 llvm_unreachable("Missed a reference kind");
4975 }
4976 }
4977
4978 if (clang_isExpression(C.kind))
4979 return getCursorExpr(C)->getSourceRange();
4980
4981 if (clang_isStatement(C.kind))
4982 return getCursorStmt(C)->getSourceRange();
4983
4984 if (clang_isAttribute(C.kind))
4985 return getCursorAttr(C)->getRange();
4986
4987 if (C.kind == CXCursor_PreprocessingDirective)
4988 return cxcursor::getCursorPreprocessingDirective(C);
4989
4990 if (C.kind == CXCursor_MacroExpansion) {
4991 ASTUnit *TU = getCursorASTUnit(C);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00004992 SourceRange Range = cxcursor::getCursorMacroExpansion(C).getSourceRange();
Guy Benyei11169dd2012-12-18 14:30:41 +00004993 return TU->mapRangeFromPreamble(Range);
4994 }
4995
4996 if (C.kind == CXCursor_MacroDefinition) {
4997 ASTUnit *TU = getCursorASTUnit(C);
4998 SourceRange Range = cxcursor::getCursorMacroDefinition(C)->getSourceRange();
4999 return TU->mapRangeFromPreamble(Range);
5000 }
5001
5002 if (C.kind == CXCursor_InclusionDirective) {
5003 ASTUnit *TU = getCursorASTUnit(C);
5004 SourceRange Range = cxcursor::getCursorInclusionDirective(C)->getSourceRange();
5005 return TU->mapRangeFromPreamble(Range);
5006 }
5007
5008 if (C.kind == CXCursor_TranslationUnit) {
5009 ASTUnit *TU = getCursorASTUnit(C);
5010 FileID MainID = TU->getSourceManager().getMainFileID();
5011 SourceLocation Start = TU->getSourceManager().getLocForStartOfFile(MainID);
5012 SourceLocation End = TU->getSourceManager().getLocForEndOfFile(MainID);
5013 return SourceRange(Start, End);
5014 }
5015
5016 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005017 const Decl *D = cxcursor::getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005018 if (!D)
5019 return SourceRange();
5020
5021 SourceRange R = D->getSourceRange();
5022 // FIXME: Multiple variables declared in a single declaration
5023 // currently lack the information needed to correctly determine their
5024 // ranges when accounting for the type-specifier. We use context
5025 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
5026 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005027 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005028 if (!cxcursor::isFirstInDeclGroup(C))
5029 R.setBegin(VD->getLocation());
5030 }
5031 return R;
5032 }
5033 return SourceRange();
5034}
5035
5036/// \brief Retrieves the "raw" cursor extent, which is then extended to include
5037/// the decl-specifier-seq for declarations.
5038static SourceRange getFullCursorExtent(CXCursor C, SourceManager &SrcMgr) {
5039 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005040 const Decl *D = cxcursor::getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005041 if (!D)
5042 return SourceRange();
5043
5044 SourceRange R = D->getSourceRange();
5045
5046 // Adjust the start of the location for declarations preceded by
5047 // declaration specifiers.
5048 SourceLocation StartLoc;
5049 if (const DeclaratorDecl *DD = dyn_cast<DeclaratorDecl>(D)) {
5050 if (TypeSourceInfo *TI = DD->getTypeSourceInfo())
5051 StartLoc = TI->getTypeLoc().getLocStart();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005052 } else if (const TypedefDecl *Typedef = dyn_cast<TypedefDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005053 if (TypeSourceInfo *TI = Typedef->getTypeSourceInfo())
5054 StartLoc = TI->getTypeLoc().getLocStart();
5055 }
5056
5057 if (StartLoc.isValid() && R.getBegin().isValid() &&
5058 SrcMgr.isBeforeInTranslationUnit(StartLoc, R.getBegin()))
5059 R.setBegin(StartLoc);
5060
5061 // FIXME: Multiple variables declared in a single declaration
5062 // currently lack the information needed to correctly determine their
5063 // ranges when accounting for the type-specifier. We use context
5064 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
5065 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005066 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005067 if (!cxcursor::isFirstInDeclGroup(C))
5068 R.setBegin(VD->getLocation());
5069 }
5070
5071 return R;
5072 }
5073
5074 return getRawCursorExtent(C);
5075}
5076
5077extern "C" {
5078
5079CXSourceRange clang_getCursorExtent(CXCursor C) {
5080 SourceRange R = getRawCursorExtent(C);
5081 if (R.isInvalid())
5082 return clang_getNullRange();
5083
5084 return cxloc::translateSourceRange(getCursorContext(C), R);
5085}
5086
5087CXCursor clang_getCursorReferenced(CXCursor C) {
5088 if (clang_isInvalid(C.kind))
5089 return clang_getNullCursor();
5090
5091 CXTranslationUnit tu = getCursorTU(C);
5092 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005093 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005094 if (!D)
5095 return clang_getNullCursor();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005096 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00005097 return MakeCursorOverloadedDeclRef(Using, D->getLocation(), tu);
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005098 if (const ObjCPropertyImplDecl *PropImpl =
5099 dyn_cast<ObjCPropertyImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00005100 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
5101 return MakeCXCursor(Property, tu);
5102
5103 return C;
5104 }
5105
5106 if (clang_isExpression(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005107 const Expr *E = getCursorExpr(C);
5108 const Decl *D = getDeclFromExpr(E);
Guy Benyei11169dd2012-12-18 14:30:41 +00005109 if (D) {
5110 CXCursor declCursor = MakeCXCursor(D, tu);
5111 declCursor = getSelectorIdentifierCursor(getSelectorIdentifierIndex(C),
5112 declCursor);
5113 return declCursor;
5114 }
5115
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005116 if (const OverloadExpr *Ovl = dyn_cast_or_null<OverloadExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00005117 return MakeCursorOverloadedDeclRef(Ovl, tu);
5118
5119 return clang_getNullCursor();
5120 }
5121
5122 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005123 const Stmt *S = getCursorStmt(C);
5124 if (const GotoStmt *Goto = dyn_cast_or_null<GotoStmt>(S))
Guy Benyei11169dd2012-12-18 14:30:41 +00005125 if (LabelDecl *label = Goto->getLabel())
5126 if (LabelStmt *labelS = label->getStmt())
5127 return MakeCXCursor(labelS, getCursorDecl(C), tu);
5128
5129 return clang_getNullCursor();
5130 }
Richard Smith66a81862015-05-04 02:25:31 +00005131
Guy Benyei11169dd2012-12-18 14:30:41 +00005132 if (C.kind == CXCursor_MacroExpansion) {
Richard Smith66a81862015-05-04 02:25:31 +00005133 if (const MacroDefinitionRecord *Def =
5134 getCursorMacroExpansion(C).getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005135 return MakeMacroDefinitionCursor(Def, tu);
5136 }
5137
5138 if (!clang_isReference(C.kind))
5139 return clang_getNullCursor();
5140
5141 switch (C.kind) {
5142 case CXCursor_ObjCSuperClassRef:
5143 return MakeCXCursor(getCursorObjCSuperClassRef(C).first, tu);
5144
5145 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005146 const ObjCProtocolDecl *Prot = getCursorObjCProtocolRef(C).first;
5147 if (const ObjCProtocolDecl *Def = Prot->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005148 return MakeCXCursor(Def, tu);
5149
5150 return MakeCXCursor(Prot, tu);
5151 }
5152
5153 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005154 const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
5155 if (const ObjCInterfaceDecl *Def = Class->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005156 return MakeCXCursor(Def, tu);
5157
5158 return MakeCXCursor(Class, tu);
5159 }
5160
5161 case CXCursor_TypeRef:
5162 return MakeCXCursor(getCursorTypeRef(C).first, tu );
5163
5164 case CXCursor_TemplateRef:
5165 return MakeCXCursor(getCursorTemplateRef(C).first, tu );
5166
5167 case CXCursor_NamespaceRef:
5168 return MakeCXCursor(getCursorNamespaceRef(C).first, tu );
5169
5170 case CXCursor_MemberRef:
5171 return MakeCXCursor(getCursorMemberRef(C).first, tu );
5172
5173 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005174 const CXXBaseSpecifier *B = cxcursor::getCursorCXXBaseSpecifier(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005175 return clang_getTypeDeclaration(cxtype::MakeCXType(B->getType(),
5176 tu ));
5177 }
5178
5179 case CXCursor_LabelRef:
5180 // FIXME: We end up faking the "parent" declaration here because we
5181 // don't want to make CXCursor larger.
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005182 return MakeCXCursor(getCursorLabelRef(C).first,
5183 cxtu::getASTUnit(tu)->getASTContext()
5184 .getTranslationUnitDecl(),
Guy Benyei11169dd2012-12-18 14:30:41 +00005185 tu);
5186
5187 case CXCursor_OverloadedDeclRef:
5188 return C;
5189
5190 case CXCursor_VariableRef:
5191 return MakeCXCursor(getCursorVariableRef(C).first, tu);
5192
5193 default:
5194 // We would prefer to enumerate all non-reference cursor kinds here.
5195 llvm_unreachable("Unhandled reference cursor kind");
5196 }
5197}
5198
5199CXCursor clang_getCursorDefinition(CXCursor C) {
5200 if (clang_isInvalid(C.kind))
5201 return clang_getNullCursor();
5202
5203 CXTranslationUnit TU = getCursorTU(C);
5204
5205 bool WasReference = false;
5206 if (clang_isReference(C.kind) || clang_isExpression(C.kind)) {
5207 C = clang_getCursorReferenced(C);
5208 WasReference = true;
5209 }
5210
5211 if (C.kind == CXCursor_MacroExpansion)
5212 return clang_getCursorReferenced(C);
5213
5214 if (!clang_isDeclaration(C.kind))
5215 return clang_getNullCursor();
5216
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005217 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005218 if (!D)
5219 return clang_getNullCursor();
5220
5221 switch (D->getKind()) {
5222 // Declaration kinds that don't really separate the notions of
5223 // declaration and definition.
5224 case Decl::Namespace:
5225 case Decl::Typedef:
5226 case Decl::TypeAlias:
5227 case Decl::TypeAliasTemplate:
5228 case Decl::TemplateTypeParm:
5229 case Decl::EnumConstant:
5230 case Decl::Field:
John McCall5e77d762013-04-16 07:28:30 +00005231 case Decl::MSProperty:
Guy Benyei11169dd2012-12-18 14:30:41 +00005232 case Decl::IndirectField:
5233 case Decl::ObjCIvar:
5234 case Decl::ObjCAtDefsField:
5235 case Decl::ImplicitParam:
5236 case Decl::ParmVar:
5237 case Decl::NonTypeTemplateParm:
5238 case Decl::TemplateTemplateParm:
5239 case Decl::ObjCCategoryImpl:
5240 case Decl::ObjCImplementation:
5241 case Decl::AccessSpec:
5242 case Decl::LinkageSpec:
5243 case Decl::ObjCPropertyImpl:
5244 case Decl::FileScopeAsm:
5245 case Decl::StaticAssert:
5246 case Decl::Block:
Tareq A. Siraj6dfa25a2013-04-16 19:37:38 +00005247 case Decl::Captured:
Guy Benyei11169dd2012-12-18 14:30:41 +00005248 case Decl::Label: // FIXME: Is this right??
5249 case Decl::ClassScopeFunctionSpecialization:
5250 case Decl::Import:
Alexey Bataeva769e072013-03-22 06:34:35 +00005251 case Decl::OMPThreadPrivate:
Douglas Gregor85f3f952015-07-07 03:57:15 +00005252 case Decl::ObjCTypeParam:
David Majnemerd9b1a4f2015-11-04 03:40:30 +00005253 case Decl::BuiltinTemplate:
Guy Benyei11169dd2012-12-18 14:30:41 +00005254 return C;
5255
5256 // Declaration kinds that don't make any sense here, but are
5257 // nonetheless harmless.
David Blaikief005d3c2013-02-22 17:44:58 +00005258 case Decl::Empty:
Guy Benyei11169dd2012-12-18 14:30:41 +00005259 case Decl::TranslationUnit:
Richard Smithf19e1272015-03-07 00:04:49 +00005260 case Decl::ExternCContext:
Guy Benyei11169dd2012-12-18 14:30:41 +00005261 break;
5262
5263 // Declaration kinds for which the definition is not resolvable.
5264 case Decl::UnresolvedUsingTypename:
5265 case Decl::UnresolvedUsingValue:
5266 break;
5267
5268 case Decl::UsingDirective:
5269 return MakeCXCursor(cast<UsingDirectiveDecl>(D)->getNominatedNamespace(),
5270 TU);
5271
5272 case Decl::NamespaceAlias:
5273 return MakeCXCursor(cast<NamespaceAliasDecl>(D)->getNamespace(), TU);
5274
5275 case Decl::Enum:
5276 case Decl::Record:
5277 case Decl::CXXRecord:
5278 case Decl::ClassTemplateSpecialization:
5279 case Decl::ClassTemplatePartialSpecialization:
5280 if (TagDecl *Def = cast<TagDecl>(D)->getDefinition())
5281 return MakeCXCursor(Def, TU);
5282 return clang_getNullCursor();
5283
5284 case Decl::Function:
5285 case Decl::CXXMethod:
5286 case Decl::CXXConstructor:
5287 case Decl::CXXDestructor:
5288 case Decl::CXXConversion: {
Craig Topper69186e72014-06-08 08:38:04 +00005289 const FunctionDecl *Def = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005290 if (cast<FunctionDecl>(D)->getBody(Def))
Dmitri Gribenko9c256e32013-01-14 00:46:27 +00005291 return MakeCXCursor(Def, TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005292 return clang_getNullCursor();
5293 }
5294
Larisse Voufo39a1e502013-08-06 01:03:05 +00005295 case Decl::Var:
5296 case Decl::VarTemplateSpecialization:
5297 case Decl::VarTemplatePartialSpecialization: {
Guy Benyei11169dd2012-12-18 14:30:41 +00005298 // Ask the variable if it has a definition.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005299 if (const VarDecl *Def = cast<VarDecl>(D)->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005300 return MakeCXCursor(Def, TU);
5301 return clang_getNullCursor();
5302 }
5303
5304 case Decl::FunctionTemplate: {
Craig Topper69186e72014-06-08 08:38:04 +00005305 const FunctionDecl *Def = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005306 if (cast<FunctionTemplateDecl>(D)->getTemplatedDecl()->getBody(Def))
5307 return MakeCXCursor(Def->getDescribedFunctionTemplate(), TU);
5308 return clang_getNullCursor();
5309 }
5310
5311 case Decl::ClassTemplate: {
5312 if (RecordDecl *Def = cast<ClassTemplateDecl>(D)->getTemplatedDecl()
5313 ->getDefinition())
5314 return MakeCXCursor(cast<CXXRecordDecl>(Def)->getDescribedClassTemplate(),
5315 TU);
5316 return clang_getNullCursor();
5317 }
5318
Larisse Voufo39a1e502013-08-06 01:03:05 +00005319 case Decl::VarTemplate: {
5320 if (VarDecl *Def =
5321 cast<VarTemplateDecl>(D)->getTemplatedDecl()->getDefinition())
5322 return MakeCXCursor(cast<VarDecl>(Def)->getDescribedVarTemplate(), TU);
5323 return clang_getNullCursor();
5324 }
5325
Guy Benyei11169dd2012-12-18 14:30:41 +00005326 case Decl::Using:
5327 return MakeCursorOverloadedDeclRef(cast<UsingDecl>(D),
5328 D->getLocation(), TU);
5329
5330 case Decl::UsingShadow:
5331 return clang_getCursorDefinition(
5332 MakeCXCursor(cast<UsingShadowDecl>(D)->getTargetDecl(),
5333 TU));
5334
5335 case Decl::ObjCMethod: {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005336 const ObjCMethodDecl *Method = cast<ObjCMethodDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00005337 if (Method->isThisDeclarationADefinition())
5338 return C;
5339
5340 // Dig out the method definition in the associated
5341 // @implementation, if we have it.
5342 // FIXME: The ASTs should make finding the definition easier.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005343 if (const ObjCInterfaceDecl *Class
Guy Benyei11169dd2012-12-18 14:30:41 +00005344 = dyn_cast<ObjCInterfaceDecl>(Method->getDeclContext()))
5345 if (ObjCImplementationDecl *ClassImpl = Class->getImplementation())
5346 if (ObjCMethodDecl *Def = ClassImpl->getMethod(Method->getSelector(),
5347 Method->isInstanceMethod()))
5348 if (Def->isThisDeclarationADefinition())
5349 return MakeCXCursor(Def, TU);
5350
5351 return clang_getNullCursor();
5352 }
5353
5354 case Decl::ObjCCategory:
5355 if (ObjCCategoryImplDecl *Impl
5356 = cast<ObjCCategoryDecl>(D)->getImplementation())
5357 return MakeCXCursor(Impl, TU);
5358 return clang_getNullCursor();
5359
5360 case Decl::ObjCProtocol:
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005361 if (const ObjCProtocolDecl *Def = cast<ObjCProtocolDecl>(D)->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005362 return MakeCXCursor(Def, TU);
5363 return clang_getNullCursor();
5364
5365 case Decl::ObjCInterface: {
5366 // There are two notions of a "definition" for an Objective-C
5367 // class: the interface and its implementation. When we resolved a
5368 // reference to an Objective-C class, produce the @interface as
5369 // the definition; when we were provided with the interface,
5370 // produce the @implementation as the definition.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005371 const ObjCInterfaceDecl *IFace = cast<ObjCInterfaceDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00005372 if (WasReference) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005373 if (const ObjCInterfaceDecl *Def = IFace->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005374 return MakeCXCursor(Def, TU);
5375 } else if (ObjCImplementationDecl *Impl = IFace->getImplementation())
5376 return MakeCXCursor(Impl, TU);
5377 return clang_getNullCursor();
5378 }
5379
5380 case Decl::ObjCProperty:
5381 // FIXME: We don't really know where to find the
5382 // ObjCPropertyImplDecls that implement this property.
5383 return clang_getNullCursor();
5384
5385 case Decl::ObjCCompatibleAlias:
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005386 if (const ObjCInterfaceDecl *Class
Guy Benyei11169dd2012-12-18 14:30:41 +00005387 = cast<ObjCCompatibleAliasDecl>(D)->getClassInterface())
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005388 if (const ObjCInterfaceDecl *Def = Class->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005389 return MakeCXCursor(Def, TU);
5390
5391 return clang_getNullCursor();
5392
5393 case Decl::Friend:
5394 if (NamedDecl *Friend = cast<FriendDecl>(D)->getFriendDecl())
5395 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
5396 return clang_getNullCursor();
5397
5398 case Decl::FriendTemplate:
5399 if (NamedDecl *Friend = cast<FriendTemplateDecl>(D)->getFriendDecl())
5400 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
5401 return clang_getNullCursor();
5402 }
5403
5404 return clang_getNullCursor();
5405}
5406
5407unsigned clang_isCursorDefinition(CXCursor C) {
5408 if (!clang_isDeclaration(C.kind))
5409 return 0;
5410
5411 return clang_getCursorDefinition(C) == C;
5412}
5413
5414CXCursor clang_getCanonicalCursor(CXCursor C) {
5415 if (!clang_isDeclaration(C.kind))
5416 return C;
5417
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005418 if (const Decl *D = getCursorDecl(C)) {
5419 if (const ObjCCategoryImplDecl *CatImplD = dyn_cast<ObjCCategoryImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00005420 if (ObjCCategoryDecl *CatD = CatImplD->getCategoryDecl())
5421 return MakeCXCursor(CatD, getCursorTU(C));
5422
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005423 if (const ObjCImplDecl *ImplD = dyn_cast<ObjCImplDecl>(D))
5424 if (const ObjCInterfaceDecl *IFD = ImplD->getClassInterface())
Guy Benyei11169dd2012-12-18 14:30:41 +00005425 return MakeCXCursor(IFD, getCursorTU(C));
5426
5427 return MakeCXCursor(D->getCanonicalDecl(), getCursorTU(C));
5428 }
5429
5430 return C;
5431}
5432
5433int clang_Cursor_getObjCSelectorIndex(CXCursor cursor) {
5434 return cxcursor::getSelectorIdentifierIndexAndLoc(cursor).first;
5435}
5436
5437unsigned clang_getNumOverloadedDecls(CXCursor C) {
5438 if (C.kind != CXCursor_OverloadedDeclRef)
5439 return 0;
5440
5441 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005442 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Guy Benyei11169dd2012-12-18 14:30:41 +00005443 return E->getNumDecls();
5444
5445 if (OverloadedTemplateStorage *S
5446 = Storage.dyn_cast<OverloadedTemplateStorage*>())
5447 return S->size();
5448
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005449 const Decl *D = Storage.get<const Decl *>();
5450 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00005451 return Using->shadow_size();
5452
5453 return 0;
5454}
5455
5456CXCursor clang_getOverloadedDecl(CXCursor cursor, unsigned index) {
5457 if (cursor.kind != CXCursor_OverloadedDeclRef)
5458 return clang_getNullCursor();
5459
5460 if (index >= clang_getNumOverloadedDecls(cursor))
5461 return clang_getNullCursor();
5462
5463 CXTranslationUnit TU = getCursorTU(cursor);
5464 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(cursor).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005465 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Guy Benyei11169dd2012-12-18 14:30:41 +00005466 return MakeCXCursor(E->decls_begin()[index], TU);
5467
5468 if (OverloadedTemplateStorage *S
5469 = Storage.dyn_cast<OverloadedTemplateStorage*>())
5470 return MakeCXCursor(S->begin()[index], TU);
5471
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005472 const Decl *D = Storage.get<const Decl *>();
5473 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005474 // FIXME: This is, unfortunately, linear time.
5475 UsingDecl::shadow_iterator Pos = Using->shadow_begin();
5476 std::advance(Pos, index);
5477 return MakeCXCursor(cast<UsingShadowDecl>(*Pos)->getTargetDecl(), TU);
5478 }
5479
5480 return clang_getNullCursor();
5481}
5482
5483void clang_getDefinitionSpellingAndExtent(CXCursor C,
5484 const char **startBuf,
5485 const char **endBuf,
5486 unsigned *startLine,
5487 unsigned *startColumn,
5488 unsigned *endLine,
5489 unsigned *endColumn) {
5490 assert(getCursorDecl(C) && "CXCursor has null decl");
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005491 const FunctionDecl *FD = dyn_cast<FunctionDecl>(getCursorDecl(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00005492 CompoundStmt *Body = dyn_cast<CompoundStmt>(FD->getBody());
5493
5494 SourceManager &SM = FD->getASTContext().getSourceManager();
5495 *startBuf = SM.getCharacterData(Body->getLBracLoc());
5496 *endBuf = SM.getCharacterData(Body->getRBracLoc());
5497 *startLine = SM.getSpellingLineNumber(Body->getLBracLoc());
5498 *startColumn = SM.getSpellingColumnNumber(Body->getLBracLoc());
5499 *endLine = SM.getSpellingLineNumber(Body->getRBracLoc());
5500 *endColumn = SM.getSpellingColumnNumber(Body->getRBracLoc());
5501}
5502
5503
5504CXSourceRange clang_getCursorReferenceNameRange(CXCursor C, unsigned NameFlags,
5505 unsigned PieceIndex) {
5506 RefNamePieces Pieces;
5507
5508 switch (C.kind) {
5509 case CXCursor_MemberRefExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005510 if (const MemberExpr *E = dyn_cast<MemberExpr>(getCursorExpr(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00005511 Pieces = buildPieces(NameFlags, true, E->getMemberNameInfo(),
5512 E->getQualifierLoc().getSourceRange());
5513 break;
5514
5515 case CXCursor_DeclRefExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005516 if (const DeclRefExpr *E = dyn_cast<DeclRefExpr>(getCursorExpr(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00005517 Pieces = buildPieces(NameFlags, false, E->getNameInfo(),
5518 E->getQualifierLoc().getSourceRange(),
5519 E->getOptionalExplicitTemplateArgs());
5520 break;
5521
5522 case CXCursor_CallExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005523 if (const CXXOperatorCallExpr *OCE =
Guy Benyei11169dd2012-12-18 14:30:41 +00005524 dyn_cast<CXXOperatorCallExpr>(getCursorExpr(C))) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005525 const Expr *Callee = OCE->getCallee();
5526 if (const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Callee))
Guy Benyei11169dd2012-12-18 14:30:41 +00005527 Callee = ICE->getSubExpr();
5528
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005529 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(Callee))
Guy Benyei11169dd2012-12-18 14:30:41 +00005530 Pieces = buildPieces(NameFlags, false, DRE->getNameInfo(),
5531 DRE->getQualifierLoc().getSourceRange());
5532 }
5533 break;
5534
5535 default:
5536 break;
5537 }
5538
5539 if (Pieces.empty()) {
5540 if (PieceIndex == 0)
5541 return clang_getCursorExtent(C);
5542 } else if (PieceIndex < Pieces.size()) {
5543 SourceRange R = Pieces[PieceIndex];
5544 if (R.isValid())
5545 return cxloc::translateSourceRange(getCursorContext(C), R);
5546 }
5547
5548 return clang_getNullRange();
5549}
5550
5551void clang_enableStackTraces(void) {
5552 llvm::sys::PrintStackTraceOnErrorSignal();
5553}
5554
5555void clang_executeOnThread(void (*fn)(void*), void *user_data,
5556 unsigned stack_size) {
5557 llvm::llvm_execute_on_thread(fn, user_data, stack_size);
5558}
5559
5560} // end: extern "C"
5561
5562//===----------------------------------------------------------------------===//
5563// Token-based Operations.
5564//===----------------------------------------------------------------------===//
5565
5566/* CXToken layout:
5567 * int_data[0]: a CXTokenKind
5568 * int_data[1]: starting token location
5569 * int_data[2]: token length
5570 * int_data[3]: reserved
5571 * ptr_data: for identifiers and keywords, an IdentifierInfo*.
5572 * otherwise unused.
5573 */
5574extern "C" {
5575
5576CXTokenKind clang_getTokenKind(CXToken CXTok) {
5577 return static_cast<CXTokenKind>(CXTok.int_data[0]);
5578}
5579
5580CXString clang_getTokenSpelling(CXTranslationUnit TU, CXToken CXTok) {
5581 switch (clang_getTokenKind(CXTok)) {
5582 case CXToken_Identifier:
5583 case CXToken_Keyword:
5584 // We know we have an IdentifierInfo*, so use that.
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005585 return cxstring::createRef(static_cast<IdentifierInfo *>(CXTok.ptr_data)
Guy Benyei11169dd2012-12-18 14:30:41 +00005586 ->getNameStart());
5587
5588 case CXToken_Literal: {
5589 // We have stashed the starting pointer in the ptr_data field. Use it.
5590 const char *Text = static_cast<const char *>(CXTok.ptr_data);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00005591 return cxstring::createDup(StringRef(Text, CXTok.int_data[2]));
Guy Benyei11169dd2012-12-18 14:30:41 +00005592 }
5593
5594 case CXToken_Punctuation:
5595 case CXToken_Comment:
5596 break;
5597 }
5598
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005599 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005600 LOG_BAD_TU(TU);
5601 return cxstring::createEmpty();
5602 }
5603
Guy Benyei11169dd2012-12-18 14:30:41 +00005604 // We have to find the starting buffer pointer the hard way, by
5605 // deconstructing the source location.
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005606 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005607 if (!CXXUnit)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00005608 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00005609
5610 SourceLocation Loc = SourceLocation::getFromRawEncoding(CXTok.int_data[1]);
5611 std::pair<FileID, unsigned> LocInfo
5612 = CXXUnit->getSourceManager().getDecomposedSpellingLoc(Loc);
5613 bool Invalid = false;
5614 StringRef Buffer
5615 = CXXUnit->getSourceManager().getBufferData(LocInfo.first, &Invalid);
5616 if (Invalid)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00005617 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00005618
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00005619 return cxstring::createDup(Buffer.substr(LocInfo.second, CXTok.int_data[2]));
Guy Benyei11169dd2012-12-18 14:30:41 +00005620}
5621
5622CXSourceLocation clang_getTokenLocation(CXTranslationUnit TU, CXToken CXTok) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005623 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005624 LOG_BAD_TU(TU);
5625 return clang_getNullLocation();
5626 }
5627
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005628 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005629 if (!CXXUnit)
5630 return clang_getNullLocation();
5631
5632 return cxloc::translateSourceLocation(CXXUnit->getASTContext(),
5633 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
5634}
5635
5636CXSourceRange clang_getTokenExtent(CXTranslationUnit TU, CXToken CXTok) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005637 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005638 LOG_BAD_TU(TU);
5639 return clang_getNullRange();
5640 }
5641
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005642 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005643 if (!CXXUnit)
5644 return clang_getNullRange();
5645
5646 return cxloc::translateSourceRange(CXXUnit->getASTContext(),
5647 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
5648}
5649
5650static void getTokens(ASTUnit *CXXUnit, SourceRange Range,
5651 SmallVectorImpl<CXToken> &CXTokens) {
5652 SourceManager &SourceMgr = CXXUnit->getSourceManager();
5653 std::pair<FileID, unsigned> BeginLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005654 = SourceMgr.getDecomposedSpellingLoc(Range.getBegin());
Guy Benyei11169dd2012-12-18 14:30:41 +00005655 std::pair<FileID, unsigned> EndLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005656 = SourceMgr.getDecomposedSpellingLoc(Range.getEnd());
Guy Benyei11169dd2012-12-18 14:30:41 +00005657
5658 // Cannot tokenize across files.
5659 if (BeginLocInfo.first != EndLocInfo.first)
5660 return;
5661
5662 // Create a lexer
5663 bool Invalid = false;
5664 StringRef Buffer
5665 = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
5666 if (Invalid)
5667 return;
5668
5669 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
5670 CXXUnit->getASTContext().getLangOpts(),
5671 Buffer.begin(), Buffer.data() + BeginLocInfo.second, Buffer.end());
5672 Lex.SetCommentRetentionState(true);
5673
5674 // Lex tokens until we hit the end of the range.
5675 const char *EffectiveBufferEnd = Buffer.data() + EndLocInfo.second;
5676 Token Tok;
5677 bool previousWasAt = false;
5678 do {
5679 // Lex the next token
5680 Lex.LexFromRawLexer(Tok);
5681 if (Tok.is(tok::eof))
5682 break;
5683
5684 // Initialize the CXToken.
5685 CXToken CXTok;
5686
5687 // - Common fields
5688 CXTok.int_data[1] = Tok.getLocation().getRawEncoding();
5689 CXTok.int_data[2] = Tok.getLength();
5690 CXTok.int_data[3] = 0;
5691
5692 // - Kind-specific fields
5693 if (Tok.isLiteral()) {
5694 CXTok.int_data[0] = CXToken_Literal;
Dmitri Gribenkof9304482013-01-23 15:56:07 +00005695 CXTok.ptr_data = const_cast<char *>(Tok.getLiteralData());
Guy Benyei11169dd2012-12-18 14:30:41 +00005696 } else if (Tok.is(tok::raw_identifier)) {
5697 // Lookup the identifier to determine whether we have a keyword.
5698 IdentifierInfo *II
5699 = CXXUnit->getPreprocessor().LookUpIdentifierInfo(Tok);
5700
5701 if ((II->getObjCKeywordID() != tok::objc_not_keyword) && previousWasAt) {
5702 CXTok.int_data[0] = CXToken_Keyword;
5703 }
5704 else {
5705 CXTok.int_data[0] = Tok.is(tok::identifier)
5706 ? CXToken_Identifier
5707 : CXToken_Keyword;
5708 }
5709 CXTok.ptr_data = II;
5710 } else if (Tok.is(tok::comment)) {
5711 CXTok.int_data[0] = CXToken_Comment;
Craig Topper69186e72014-06-08 08:38:04 +00005712 CXTok.ptr_data = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005713 } else {
5714 CXTok.int_data[0] = CXToken_Punctuation;
Craig Topper69186e72014-06-08 08:38:04 +00005715 CXTok.ptr_data = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005716 }
5717 CXTokens.push_back(CXTok);
5718 previousWasAt = Tok.is(tok::at);
5719 } while (Lex.getBufferLocation() <= EffectiveBufferEnd);
5720}
5721
5722void clang_tokenize(CXTranslationUnit TU, CXSourceRange Range,
5723 CXToken **Tokens, unsigned *NumTokens) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00005724 LOG_FUNC_SECTION {
5725 *Log << TU << ' ' << Range;
5726 }
5727
Guy Benyei11169dd2012-12-18 14:30:41 +00005728 if (Tokens)
Craig Topper69186e72014-06-08 08:38:04 +00005729 *Tokens = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005730 if (NumTokens)
5731 *NumTokens = 0;
5732
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005733 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005734 LOG_BAD_TU(TU);
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00005735 return;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005736 }
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00005737
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005738 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005739 if (!CXXUnit || !Tokens || !NumTokens)
5740 return;
5741
5742 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
5743
5744 SourceRange R = cxloc::translateCXSourceRange(Range);
5745 if (R.isInvalid())
5746 return;
5747
5748 SmallVector<CXToken, 32> CXTokens;
5749 getTokens(CXXUnit, R, CXTokens);
5750
5751 if (CXTokens.empty())
5752 return;
5753
5754 *Tokens = (CXToken *)malloc(sizeof(CXToken) * CXTokens.size());
5755 memmove(*Tokens, CXTokens.data(), sizeof(CXToken) * CXTokens.size());
5756 *NumTokens = CXTokens.size();
5757}
5758
5759void clang_disposeTokens(CXTranslationUnit TU,
5760 CXToken *Tokens, unsigned NumTokens) {
5761 free(Tokens);
5762}
5763
5764} // end: extern "C"
5765
5766//===----------------------------------------------------------------------===//
5767// Token annotation APIs.
5768//===----------------------------------------------------------------------===//
5769
Guy Benyei11169dd2012-12-18 14:30:41 +00005770static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
5771 CXCursor parent,
5772 CXClientData client_data);
5773static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
5774 CXClientData client_data);
5775
5776namespace {
5777class AnnotateTokensWorker {
Guy Benyei11169dd2012-12-18 14:30:41 +00005778 CXToken *Tokens;
5779 CXCursor *Cursors;
5780 unsigned NumTokens;
5781 unsigned TokIdx;
5782 unsigned PreprocessingTokIdx;
5783 CursorVisitor AnnotateVis;
5784 SourceManager &SrcMgr;
5785 bool HasContextSensitiveKeywords;
5786
5787 struct PostChildrenInfo {
5788 CXCursor Cursor;
5789 SourceRange CursorRange;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005790 unsigned BeforeReachingCursorIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00005791 unsigned BeforeChildrenTokenIdx;
5792 };
Dmitri Gribenkof8579502013-01-12 19:30:44 +00005793 SmallVector<PostChildrenInfo, 8> PostChildrenInfos;
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005794
5795 CXToken &getTok(unsigned Idx) {
5796 assert(Idx < NumTokens);
5797 return Tokens[Idx];
5798 }
5799 const CXToken &getTok(unsigned Idx) const {
5800 assert(Idx < NumTokens);
5801 return Tokens[Idx];
5802 }
Guy Benyei11169dd2012-12-18 14:30:41 +00005803 bool MoreTokens() const { return TokIdx < NumTokens; }
5804 unsigned NextToken() const { return TokIdx; }
5805 void AdvanceToken() { ++TokIdx; }
5806 SourceLocation GetTokenLoc(unsigned tokI) {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005807 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[1]);
Guy Benyei11169dd2012-12-18 14:30:41 +00005808 }
5809 bool isFunctionMacroToken(unsigned tokI) const {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005810 return getTok(tokI).int_data[3] != 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00005811 }
5812 SourceLocation getFunctionMacroTokenLoc(unsigned tokI) const {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005813 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[3]);
Guy Benyei11169dd2012-12-18 14:30:41 +00005814 }
5815
5816 void annotateAndAdvanceTokens(CXCursor, RangeComparisonResult, SourceRange);
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005817 bool annotateAndAdvanceFunctionMacroTokens(CXCursor, RangeComparisonResult,
Guy Benyei11169dd2012-12-18 14:30:41 +00005818 SourceRange);
5819
5820public:
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005821 AnnotateTokensWorker(CXToken *tokens, CXCursor *cursors, unsigned numTokens,
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005822 CXTranslationUnit TU, SourceRange RegionOfInterest)
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005823 : Tokens(tokens), Cursors(cursors),
Guy Benyei11169dd2012-12-18 14:30:41 +00005824 NumTokens(numTokens), TokIdx(0), PreprocessingTokIdx(0),
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005825 AnnotateVis(TU,
Guy Benyei11169dd2012-12-18 14:30:41 +00005826 AnnotateTokensVisitor, this,
5827 /*VisitPreprocessorLast=*/true,
5828 /*VisitIncludedEntities=*/false,
5829 RegionOfInterest,
5830 /*VisitDeclsOnly=*/false,
5831 AnnotateTokensPostChildrenVisitor),
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005832 SrcMgr(cxtu::getASTUnit(TU)->getSourceManager()),
Guy Benyei11169dd2012-12-18 14:30:41 +00005833 HasContextSensitiveKeywords(false) { }
5834
5835 void VisitChildren(CXCursor C) { AnnotateVis.VisitChildren(C); }
5836 enum CXChildVisitResult Visit(CXCursor cursor, CXCursor parent);
5837 bool postVisitChildren(CXCursor cursor);
5838 void AnnotateTokens();
5839
5840 /// \brief Determine whether the annotator saw any cursors that have
5841 /// context-sensitive keywords.
5842 bool hasContextSensitiveKeywords() const {
5843 return HasContextSensitiveKeywords;
5844 }
5845
5846 ~AnnotateTokensWorker() {
5847 assert(PostChildrenInfos.empty());
5848 }
5849};
Alexander Kornienkoab9db512015-06-22 23:07:51 +00005850}
Guy Benyei11169dd2012-12-18 14:30:41 +00005851
5852void AnnotateTokensWorker::AnnotateTokens() {
5853 // Walk the AST within the region of interest, annotating tokens
5854 // along the way.
5855 AnnotateVis.visitFileRegion();
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005856}
Guy Benyei11169dd2012-12-18 14:30:41 +00005857
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005858static inline void updateCursorAnnotation(CXCursor &Cursor,
5859 const CXCursor &updateC) {
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005860 if (clang_isInvalid(updateC.kind) || !clang_isInvalid(Cursor.kind))
Guy Benyei11169dd2012-12-18 14:30:41 +00005861 return;
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005862 Cursor = updateC;
Guy Benyei11169dd2012-12-18 14:30:41 +00005863}
5864
5865/// \brief It annotates and advances tokens with a cursor until the comparison
5866//// between the cursor location and the source range is the same as
5867/// \arg compResult.
5868///
5869/// Pass RangeBefore to annotate tokens with a cursor until a range is reached.
5870/// Pass RangeOverlap to annotate tokens inside a range.
5871void AnnotateTokensWorker::annotateAndAdvanceTokens(CXCursor updateC,
5872 RangeComparisonResult compResult,
5873 SourceRange range) {
5874 while (MoreTokens()) {
5875 const unsigned I = NextToken();
5876 if (isFunctionMacroToken(I))
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005877 if (!annotateAndAdvanceFunctionMacroTokens(updateC, compResult, range))
5878 return;
Guy Benyei11169dd2012-12-18 14:30:41 +00005879
5880 SourceLocation TokLoc = GetTokenLoc(I);
5881 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005882 updateCursorAnnotation(Cursors[I], updateC);
Guy Benyei11169dd2012-12-18 14:30:41 +00005883 AdvanceToken();
5884 continue;
5885 }
5886 break;
5887 }
5888}
5889
5890/// \brief Special annotation handling for macro argument tokens.
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005891/// \returns true if it advanced beyond all macro tokens, false otherwise.
5892bool AnnotateTokensWorker::annotateAndAdvanceFunctionMacroTokens(
Guy Benyei11169dd2012-12-18 14:30:41 +00005893 CXCursor updateC,
5894 RangeComparisonResult compResult,
5895 SourceRange range) {
5896 assert(MoreTokens());
5897 assert(isFunctionMacroToken(NextToken()) &&
5898 "Should be called only for macro arg tokens");
5899
5900 // This works differently than annotateAndAdvanceTokens; because expanded
5901 // macro arguments can have arbitrary translation-unit source order, we do not
5902 // advance the token index one by one until a token fails the range test.
5903 // We only advance once past all of the macro arg tokens if all of them
5904 // pass the range test. If one of them fails we keep the token index pointing
5905 // at the start of the macro arg tokens so that the failing token will be
5906 // annotated by a subsequent annotation try.
5907
5908 bool atLeastOneCompFail = false;
5909
5910 unsigned I = NextToken();
5911 for (; I < NumTokens && isFunctionMacroToken(I); ++I) {
5912 SourceLocation TokLoc = getFunctionMacroTokenLoc(I);
5913 if (TokLoc.isFileID())
5914 continue; // not macro arg token, it's parens or comma.
5915 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
5916 if (clang_isInvalid(clang_getCursorKind(Cursors[I])))
5917 Cursors[I] = updateC;
5918 } else
5919 atLeastOneCompFail = true;
5920 }
5921
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005922 if (atLeastOneCompFail)
5923 return false;
5924
5925 TokIdx = I; // All of the tokens were handled, advance beyond all of them.
5926 return true;
Guy Benyei11169dd2012-12-18 14:30:41 +00005927}
5928
5929enum CXChildVisitResult
5930AnnotateTokensWorker::Visit(CXCursor cursor, CXCursor parent) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005931 SourceRange cursorRange = getRawCursorExtent(cursor);
5932 if (cursorRange.isInvalid())
5933 return CXChildVisit_Recurse;
5934
5935 if (!HasContextSensitiveKeywords) {
5936 // Objective-C properties can have context-sensitive keywords.
5937 if (cursor.kind == CXCursor_ObjCPropertyDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005938 if (const ObjCPropertyDecl *Property
Guy Benyei11169dd2012-12-18 14:30:41 +00005939 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(cursor)))
5940 HasContextSensitiveKeywords = Property->getPropertyAttributesAsWritten() != 0;
5941 }
5942 // Objective-C methods can have context-sensitive keywords.
5943 else if (cursor.kind == CXCursor_ObjCInstanceMethodDecl ||
5944 cursor.kind == CXCursor_ObjCClassMethodDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005945 if (const ObjCMethodDecl *Method
Guy Benyei11169dd2012-12-18 14:30:41 +00005946 = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
5947 if (Method->getObjCDeclQualifier())
5948 HasContextSensitiveKeywords = true;
5949 else {
Aaron Ballman43b68be2014-03-07 17:50:17 +00005950 for (const auto *P : Method->params()) {
5951 if (P->getObjCDeclQualifier()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005952 HasContextSensitiveKeywords = true;
5953 break;
5954 }
5955 }
5956 }
5957 }
5958 }
5959 // C++ methods can have context-sensitive keywords.
5960 else if (cursor.kind == CXCursor_CXXMethod) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005961 if (const CXXMethodDecl *Method
Guy Benyei11169dd2012-12-18 14:30:41 +00005962 = dyn_cast_or_null<CXXMethodDecl>(getCursorDecl(cursor))) {
5963 if (Method->hasAttr<FinalAttr>() || Method->hasAttr<OverrideAttr>())
5964 HasContextSensitiveKeywords = true;
5965 }
5966 }
5967 // C++ classes can have context-sensitive keywords.
5968 else if (cursor.kind == CXCursor_StructDecl ||
5969 cursor.kind == CXCursor_ClassDecl ||
5970 cursor.kind == CXCursor_ClassTemplate ||
5971 cursor.kind == CXCursor_ClassTemplatePartialSpecialization) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005972 if (const Decl *D = getCursorDecl(cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +00005973 if (D->hasAttr<FinalAttr>())
5974 HasContextSensitiveKeywords = true;
5975 }
5976 }
Argyrios Kyrtzidis990b3862013-06-04 18:24:30 +00005977
5978 // Don't override a property annotation with its getter/setter method.
5979 if (cursor.kind == CXCursor_ObjCInstanceMethodDecl &&
5980 parent.kind == CXCursor_ObjCPropertyDecl)
5981 return CXChildVisit_Continue;
Guy Benyei11169dd2012-12-18 14:30:41 +00005982
5983 if (clang_isPreprocessing(cursor.kind)) {
5984 // Items in the preprocessing record are kept separate from items in
5985 // declarations, so we keep a separate token index.
5986 unsigned SavedTokIdx = TokIdx;
5987 TokIdx = PreprocessingTokIdx;
5988
5989 // Skip tokens up until we catch up to the beginning of the preprocessing
5990 // entry.
5991 while (MoreTokens()) {
5992 const unsigned I = NextToken();
5993 SourceLocation TokLoc = GetTokenLoc(I);
5994 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
5995 case RangeBefore:
5996 AdvanceToken();
5997 continue;
5998 case RangeAfter:
5999 case RangeOverlap:
6000 break;
6001 }
6002 break;
6003 }
6004
6005 // Look at all of the tokens within this range.
6006 while (MoreTokens()) {
6007 const unsigned I = NextToken();
6008 SourceLocation TokLoc = GetTokenLoc(I);
6009 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
6010 case RangeBefore:
6011 llvm_unreachable("Infeasible");
6012 case RangeAfter:
6013 break;
6014 case RangeOverlap:
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00006015 // For macro expansions, just note where the beginning of the macro
6016 // expansion occurs.
6017 if (cursor.kind == CXCursor_MacroExpansion) {
6018 if (TokLoc == cursorRange.getBegin())
6019 Cursors[I] = cursor;
6020 AdvanceToken();
6021 break;
6022 }
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006023 // We may have already annotated macro names inside macro definitions.
6024 if (Cursors[I].kind != CXCursor_MacroExpansion)
6025 Cursors[I] = cursor;
Guy Benyei11169dd2012-12-18 14:30:41 +00006026 AdvanceToken();
Guy Benyei11169dd2012-12-18 14:30:41 +00006027 continue;
6028 }
6029 break;
6030 }
6031
6032 // Save the preprocessing token index; restore the non-preprocessing
6033 // token index.
6034 PreprocessingTokIdx = TokIdx;
6035 TokIdx = SavedTokIdx;
6036 return CXChildVisit_Recurse;
6037 }
6038
6039 if (cursorRange.isInvalid())
6040 return CXChildVisit_Continue;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00006041
6042 unsigned BeforeReachingCursorIdx = NextToken();
Guy Benyei11169dd2012-12-18 14:30:41 +00006043 const enum CXCursorKind cursorK = clang_getCursorKind(cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00006044 const enum CXCursorKind K = clang_getCursorKind(parent);
6045 const CXCursor updateC =
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00006046 (clang_isInvalid(K) || K == CXCursor_TranslationUnit ||
6047 // Attributes are annotated out-of-order, skip tokens until we reach it.
6048 clang_isAttribute(cursor.kind))
Guy Benyei11169dd2012-12-18 14:30:41 +00006049 ? clang_getNullCursor() : parent;
6050
6051 annotateAndAdvanceTokens(updateC, RangeBefore, cursorRange);
6052
6053 // Avoid having the cursor of an expression "overwrite" the annotation of the
6054 // variable declaration that it belongs to.
6055 // This can happen for C++ constructor expressions whose range generally
6056 // include the variable declaration, e.g.:
6057 // MyCXXClass foo; // Make sure we don't annotate 'foo' as a CallExpr cursor.
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00006058 if (clang_isExpression(cursorK) && MoreTokens()) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00006059 const Expr *E = getCursorExpr(cursor);
Dmitri Gribenkoa1691182013-01-26 18:12:08 +00006060 if (const Decl *D = getCursorParentDecl(cursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00006061 const unsigned I = NextToken();
6062 if (E->getLocStart().isValid() && D->getLocation().isValid() &&
6063 E->getLocStart() == D->getLocation() &&
6064 E->getLocStart() == GetTokenLoc(I)) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006065 updateCursorAnnotation(Cursors[I], updateC);
Guy Benyei11169dd2012-12-18 14:30:41 +00006066 AdvanceToken();
6067 }
6068 }
6069 }
6070
6071 // Before recursing into the children keep some state that we are going
6072 // to use in the AnnotateTokensWorker::postVisitChildren callback to do some
6073 // extra work after the child nodes are visited.
6074 // Note that we don't call VisitChildren here to avoid traversing statements
6075 // code-recursively which can blow the stack.
6076
6077 PostChildrenInfo Info;
6078 Info.Cursor = cursor;
6079 Info.CursorRange = cursorRange;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00006080 Info.BeforeReachingCursorIdx = BeforeReachingCursorIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00006081 Info.BeforeChildrenTokenIdx = NextToken();
6082 PostChildrenInfos.push_back(Info);
6083
6084 return CXChildVisit_Recurse;
6085}
6086
6087bool AnnotateTokensWorker::postVisitChildren(CXCursor cursor) {
6088 if (PostChildrenInfos.empty())
6089 return false;
6090 const PostChildrenInfo &Info = PostChildrenInfos.back();
6091 if (!clang_equalCursors(Info.Cursor, cursor))
6092 return false;
6093
6094 const unsigned BeforeChildren = Info.BeforeChildrenTokenIdx;
6095 const unsigned AfterChildren = NextToken();
6096 SourceRange cursorRange = Info.CursorRange;
6097
6098 // Scan the tokens that are at the end of the cursor, but are not captured
6099 // but the child cursors.
6100 annotateAndAdvanceTokens(cursor, RangeOverlap, cursorRange);
6101
6102 // Scan the tokens that are at the beginning of the cursor, but are not
6103 // capture by the child cursors.
6104 for (unsigned I = BeforeChildren; I != AfterChildren; ++I) {
6105 if (!clang_isInvalid(clang_getCursorKind(Cursors[I])))
6106 break;
6107
6108 Cursors[I] = cursor;
6109 }
6110
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00006111 // Attributes are annotated out-of-order, rewind TokIdx to when we first
6112 // encountered the attribute cursor.
6113 if (clang_isAttribute(cursor.kind))
6114 TokIdx = Info.BeforeReachingCursorIdx;
6115
Guy Benyei11169dd2012-12-18 14:30:41 +00006116 PostChildrenInfos.pop_back();
6117 return false;
6118}
6119
6120static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
6121 CXCursor parent,
6122 CXClientData client_data) {
6123 return static_cast<AnnotateTokensWorker*>(client_data)->Visit(cursor, parent);
6124}
6125
6126static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
6127 CXClientData client_data) {
6128 return static_cast<AnnotateTokensWorker*>(client_data)->
6129 postVisitChildren(cursor);
6130}
6131
6132namespace {
6133
6134/// \brief Uses the macro expansions in the preprocessing record to find
6135/// and mark tokens that are macro arguments. This info is used by the
6136/// AnnotateTokensWorker.
6137class MarkMacroArgTokensVisitor {
6138 SourceManager &SM;
6139 CXToken *Tokens;
6140 unsigned NumTokens;
6141 unsigned CurIdx;
6142
6143public:
6144 MarkMacroArgTokensVisitor(SourceManager &SM,
6145 CXToken *tokens, unsigned numTokens)
6146 : SM(SM), Tokens(tokens), NumTokens(numTokens), CurIdx(0) { }
6147
6148 CXChildVisitResult visit(CXCursor cursor, CXCursor parent) {
6149 if (cursor.kind != CXCursor_MacroExpansion)
6150 return CXChildVisit_Continue;
6151
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006152 SourceRange macroRange = getCursorMacroExpansion(cursor).getSourceRange();
Guy Benyei11169dd2012-12-18 14:30:41 +00006153 if (macroRange.getBegin() == macroRange.getEnd())
6154 return CXChildVisit_Continue; // it's not a function macro.
6155
6156 for (; CurIdx < NumTokens; ++CurIdx) {
6157 if (!SM.isBeforeInTranslationUnit(getTokenLoc(CurIdx),
6158 macroRange.getBegin()))
6159 break;
6160 }
6161
6162 if (CurIdx == NumTokens)
6163 return CXChildVisit_Break;
6164
6165 for (; CurIdx < NumTokens; ++CurIdx) {
6166 SourceLocation tokLoc = getTokenLoc(CurIdx);
6167 if (!SM.isBeforeInTranslationUnit(tokLoc, macroRange.getEnd()))
6168 break;
6169
6170 setFunctionMacroTokenLoc(CurIdx, SM.getMacroArgExpandedLocation(tokLoc));
6171 }
6172
6173 if (CurIdx == NumTokens)
6174 return CXChildVisit_Break;
6175
6176 return CXChildVisit_Continue;
6177 }
6178
6179private:
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00006180 CXToken &getTok(unsigned Idx) {
6181 assert(Idx < NumTokens);
6182 return Tokens[Idx];
6183 }
6184 const CXToken &getTok(unsigned Idx) const {
6185 assert(Idx < NumTokens);
6186 return Tokens[Idx];
6187 }
6188
Guy Benyei11169dd2012-12-18 14:30:41 +00006189 SourceLocation getTokenLoc(unsigned tokI) {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00006190 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[1]);
Guy Benyei11169dd2012-12-18 14:30:41 +00006191 }
6192
6193 void setFunctionMacroTokenLoc(unsigned tokI, SourceLocation loc) {
6194 // The third field is reserved and currently not used. Use it here
6195 // to mark macro arg expanded tokens with their expanded locations.
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00006196 getTok(tokI).int_data[3] = loc.getRawEncoding();
Guy Benyei11169dd2012-12-18 14:30:41 +00006197 }
6198};
6199
6200} // end anonymous namespace
6201
6202static CXChildVisitResult
6203MarkMacroArgTokensVisitorDelegate(CXCursor cursor, CXCursor parent,
6204 CXClientData client_data) {
6205 return static_cast<MarkMacroArgTokensVisitor*>(client_data)->visit(cursor,
6206 parent);
6207}
6208
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006209/// \brief Used by \c annotatePreprocessorTokens.
6210/// \returns true if lexing was finished, false otherwise.
6211static bool lexNext(Lexer &Lex, Token &Tok,
6212 unsigned &NextIdx, unsigned NumTokens) {
6213 if (NextIdx >= NumTokens)
6214 return true;
6215
6216 ++NextIdx;
6217 Lex.LexFromRawLexer(Tok);
6218 if (Tok.is(tok::eof))
6219 return true;
6220
6221 return false;
6222}
6223
Guy Benyei11169dd2012-12-18 14:30:41 +00006224static void annotatePreprocessorTokens(CXTranslationUnit TU,
6225 SourceRange RegionOfInterest,
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006226 CXCursor *Cursors,
6227 CXToken *Tokens,
6228 unsigned NumTokens) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006229 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00006230
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006231 Preprocessor &PP = CXXUnit->getPreprocessor();
Guy Benyei11169dd2012-12-18 14:30:41 +00006232 SourceManager &SourceMgr = CXXUnit->getSourceManager();
6233 std::pair<FileID, unsigned> BeginLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00006234 = SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getBegin());
Guy Benyei11169dd2012-12-18 14:30:41 +00006235 std::pair<FileID, unsigned> EndLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00006236 = SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getEnd());
Guy Benyei11169dd2012-12-18 14:30:41 +00006237
6238 if (BeginLocInfo.first != EndLocInfo.first)
6239 return;
6240
6241 StringRef Buffer;
6242 bool Invalid = false;
6243 Buffer = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
6244 if (Buffer.empty() || Invalid)
6245 return;
6246
6247 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
6248 CXXUnit->getASTContext().getLangOpts(),
6249 Buffer.begin(), Buffer.data() + BeginLocInfo.second,
6250 Buffer.end());
6251 Lex.SetCommentRetentionState(true);
6252
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006253 unsigned NextIdx = 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00006254 // Lex tokens in raw mode until we hit the end of the range, to avoid
6255 // entering #includes or expanding macros.
6256 while (true) {
6257 Token Tok;
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006258 if (lexNext(Lex, Tok, NextIdx, NumTokens))
6259 break;
6260 unsigned TokIdx = NextIdx-1;
6261 assert(Tok.getLocation() ==
6262 SourceLocation::getFromRawEncoding(Tokens[TokIdx].int_data[1]));
Guy Benyei11169dd2012-12-18 14:30:41 +00006263
6264 reprocess:
6265 if (Tok.is(tok::hash) && Tok.isAtStartOfLine()) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006266 // We have found a preprocessing directive. Annotate the tokens
6267 // appropriately.
Guy Benyei11169dd2012-12-18 14:30:41 +00006268 //
6269 // FIXME: Some simple tests here could identify macro definitions and
6270 // #undefs, to provide specific cursor kinds for those.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006271
6272 SourceLocation BeginLoc = Tok.getLocation();
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006273 if (lexNext(Lex, Tok, NextIdx, NumTokens))
6274 break;
6275
Craig Topper69186e72014-06-08 08:38:04 +00006276 MacroInfo *MI = nullptr;
Alp Toker2d57cea2014-05-17 04:53:25 +00006277 if (Tok.is(tok::raw_identifier) && Tok.getRawIdentifier() == "define") {
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006278 if (lexNext(Lex, Tok, NextIdx, NumTokens))
6279 break;
6280
6281 if (Tok.is(tok::raw_identifier)) {
Alp Toker2d57cea2014-05-17 04:53:25 +00006282 IdentifierInfo &II =
6283 PP.getIdentifierTable().get(Tok.getRawIdentifier());
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006284 SourceLocation MappedTokLoc =
6285 CXXUnit->mapLocationToPreamble(Tok.getLocation());
6286 MI = getMacroInfo(II, MappedTokLoc, TU);
6287 }
6288 }
6289
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006290 bool finished = false;
Guy Benyei11169dd2012-12-18 14:30:41 +00006291 do {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006292 if (lexNext(Lex, Tok, NextIdx, NumTokens)) {
6293 finished = true;
6294 break;
6295 }
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006296 // If we are in a macro definition, check if the token was ever a
6297 // macro name and annotate it if that's the case.
6298 if (MI) {
6299 SourceLocation SaveLoc = Tok.getLocation();
6300 Tok.setLocation(CXXUnit->mapLocationToPreamble(SaveLoc));
Richard Smith66a81862015-05-04 02:25:31 +00006301 MacroDefinitionRecord *MacroDef =
6302 checkForMacroInMacroDefinition(MI, Tok, TU);
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006303 Tok.setLocation(SaveLoc);
6304 if (MacroDef)
Richard Smith66a81862015-05-04 02:25:31 +00006305 Cursors[NextIdx - 1] =
6306 MakeMacroExpansionCursor(MacroDef, Tok.getLocation(), TU);
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006307 }
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006308 } while (!Tok.isAtStartOfLine());
6309
6310 unsigned LastIdx = finished ? NextIdx-1 : NextIdx-2;
6311 assert(TokIdx <= LastIdx);
6312 SourceLocation EndLoc =
6313 SourceLocation::getFromRawEncoding(Tokens[LastIdx].int_data[1]);
6314 CXCursor Cursor =
6315 MakePreprocessingDirectiveCursor(SourceRange(BeginLoc, EndLoc), TU);
6316
6317 for (; TokIdx <= LastIdx; ++TokIdx)
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006318 updateCursorAnnotation(Cursors[TokIdx], Cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00006319
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006320 if (finished)
6321 break;
6322 goto reprocess;
Guy Benyei11169dd2012-12-18 14:30:41 +00006323 }
Guy Benyei11169dd2012-12-18 14:30:41 +00006324 }
6325}
6326
6327// This gets run a separate thread to avoid stack blowout.
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00006328static void clang_annotateTokensImpl(CXTranslationUnit TU, ASTUnit *CXXUnit,
6329 CXToken *Tokens, unsigned NumTokens,
6330 CXCursor *Cursors) {
Dmitri Gribenko183436e2013-01-26 21:49:50 +00006331 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00006332 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
6333 setThreadBackgroundPriority();
6334
6335 // Determine the region of interest, which contains all of the tokens.
6336 SourceRange RegionOfInterest;
6337 RegionOfInterest.setBegin(
6338 cxloc::translateSourceLocation(clang_getTokenLocation(TU, Tokens[0])));
6339 RegionOfInterest.setEnd(
6340 cxloc::translateSourceLocation(clang_getTokenLocation(TU,
6341 Tokens[NumTokens-1])));
6342
Guy Benyei11169dd2012-12-18 14:30:41 +00006343 // Relex the tokens within the source range to look for preprocessing
6344 // directives.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006345 annotatePreprocessorTokens(TU, RegionOfInterest, Cursors, Tokens, NumTokens);
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00006346
6347 // If begin location points inside a macro argument, set it to the expansion
6348 // location so we can have the full context when annotating semantically.
6349 {
6350 SourceManager &SM = CXXUnit->getSourceManager();
6351 SourceLocation Loc =
6352 SM.getMacroArgExpandedLocation(RegionOfInterest.getBegin());
6353 if (Loc.isMacroID())
6354 RegionOfInterest.setBegin(SM.getExpansionLoc(Loc));
6355 }
6356
Guy Benyei11169dd2012-12-18 14:30:41 +00006357 if (CXXUnit->getPreprocessor().getPreprocessingRecord()) {
6358 // Search and mark tokens that are macro argument expansions.
6359 MarkMacroArgTokensVisitor Visitor(CXXUnit->getSourceManager(),
6360 Tokens, NumTokens);
6361 CursorVisitor MacroArgMarker(TU,
6362 MarkMacroArgTokensVisitorDelegate, &Visitor,
6363 /*VisitPreprocessorLast=*/true,
6364 /*VisitIncludedEntities=*/false,
6365 RegionOfInterest);
6366 MacroArgMarker.visitPreprocessedEntitiesInRegion();
6367 }
6368
6369 // Annotate all of the source locations in the region of interest that map to
6370 // a specific cursor.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006371 AnnotateTokensWorker W(Tokens, Cursors, NumTokens, TU, RegionOfInterest);
Guy Benyei11169dd2012-12-18 14:30:41 +00006372
6373 // FIXME: We use a ridiculous stack size here because the data-recursion
6374 // algorithm uses a large stack frame than the non-data recursive version,
6375 // and AnnotationTokensWorker currently transforms the data-recursion
6376 // algorithm back into a traditional recursion by explicitly calling
6377 // VisitChildren(). We will need to remove this explicit recursive call.
6378 W.AnnotateTokens();
6379
6380 // If we ran into any entities that involve context-sensitive keywords,
6381 // take another pass through the tokens to mark them as such.
6382 if (W.hasContextSensitiveKeywords()) {
6383 for (unsigned I = 0; I != NumTokens; ++I) {
6384 if (clang_getTokenKind(Tokens[I]) != CXToken_Identifier)
6385 continue;
6386
6387 if (Cursors[I].kind == CXCursor_ObjCPropertyDecl) {
6388 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006389 if (const ObjCPropertyDecl *Property
Guy Benyei11169dd2012-12-18 14:30:41 +00006390 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(Cursors[I]))) {
6391 if (Property->getPropertyAttributesAsWritten() != 0 &&
6392 llvm::StringSwitch<bool>(II->getName())
6393 .Case("readonly", true)
6394 .Case("assign", true)
6395 .Case("unsafe_unretained", true)
6396 .Case("readwrite", true)
6397 .Case("retain", true)
6398 .Case("copy", true)
6399 .Case("nonatomic", true)
6400 .Case("atomic", true)
6401 .Case("getter", true)
6402 .Case("setter", true)
6403 .Case("strong", true)
6404 .Case("weak", true)
6405 .Default(false))
6406 Tokens[I].int_data[0] = CXToken_Keyword;
6407 }
6408 continue;
6409 }
6410
6411 if (Cursors[I].kind == CXCursor_ObjCInstanceMethodDecl ||
6412 Cursors[I].kind == CXCursor_ObjCClassMethodDecl) {
6413 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
6414 if (llvm::StringSwitch<bool>(II->getName())
6415 .Case("in", true)
6416 .Case("out", true)
6417 .Case("inout", true)
6418 .Case("oneway", true)
6419 .Case("bycopy", true)
6420 .Case("byref", true)
6421 .Default(false))
6422 Tokens[I].int_data[0] = CXToken_Keyword;
6423 continue;
6424 }
6425
6426 if (Cursors[I].kind == CXCursor_CXXFinalAttr ||
6427 Cursors[I].kind == CXCursor_CXXOverrideAttr) {
6428 Tokens[I].int_data[0] = CXToken_Keyword;
6429 continue;
6430 }
6431 }
6432 }
6433}
6434
6435extern "C" {
6436
6437void clang_annotateTokens(CXTranslationUnit TU,
6438 CXToken *Tokens, unsigned NumTokens,
6439 CXCursor *Cursors) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006440 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006441 LOG_BAD_TU(TU);
6442 return;
6443 }
6444 if (NumTokens == 0 || !Tokens || !Cursors) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006445 LOG_FUNC_SECTION { *Log << "<null input>"; }
Guy Benyei11169dd2012-12-18 14:30:41 +00006446 return;
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006447 }
6448
6449 LOG_FUNC_SECTION {
6450 *Log << TU << ' ';
6451 CXSourceLocation bloc = clang_getTokenLocation(TU, Tokens[0]);
6452 CXSourceLocation eloc = clang_getTokenLocation(TU, Tokens[NumTokens-1]);
6453 *Log << clang_getRange(bloc, eloc);
6454 }
Guy Benyei11169dd2012-12-18 14:30:41 +00006455
6456 // Any token we don't specifically annotate will have a NULL cursor.
6457 CXCursor C = clang_getNullCursor();
6458 for (unsigned I = 0; I != NumTokens; ++I)
6459 Cursors[I] = C;
6460
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006461 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00006462 if (!CXXUnit)
6463 return;
6464
6465 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00006466
6467 auto AnnotateTokensImpl = [=]() {
6468 clang_annotateTokensImpl(TU, CXXUnit, Tokens, NumTokens, Cursors);
6469 };
Guy Benyei11169dd2012-12-18 14:30:41 +00006470 llvm::CrashRecoveryContext CRC;
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00006471 if (!RunSafely(CRC, AnnotateTokensImpl, GetSafetyThreadStackSize() * 2)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00006472 fprintf(stderr, "libclang: crash detected while annotating tokens\n");
6473 }
6474}
6475
6476} // end: extern "C"
6477
6478//===----------------------------------------------------------------------===//
6479// Operations for querying linkage of a cursor.
6480//===----------------------------------------------------------------------===//
6481
6482extern "C" {
6483CXLinkageKind clang_getCursorLinkage(CXCursor cursor) {
6484 if (!clang_isDeclaration(cursor.kind))
6485 return CXLinkage_Invalid;
6486
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006487 const Decl *D = cxcursor::getCursorDecl(cursor);
6488 if (const NamedDecl *ND = dyn_cast_or_null<NamedDecl>(D))
Rafael Espindola3ae00052013-05-13 00:12:11 +00006489 switch (ND->getLinkageInternal()) {
Rafael Espindola50df3a02013-05-25 17:16:20 +00006490 case NoLinkage:
6491 case VisibleNoLinkage: return CXLinkage_NoLinkage;
Guy Benyei11169dd2012-12-18 14:30:41 +00006492 case InternalLinkage: return CXLinkage_Internal;
6493 case UniqueExternalLinkage: return CXLinkage_UniqueExternal;
6494 case ExternalLinkage: return CXLinkage_External;
6495 };
6496
6497 return CXLinkage_Invalid;
6498}
6499} // end: extern "C"
6500
6501//===----------------------------------------------------------------------===//
Ehsan Akhgari93697fa2015-11-23 19:56:46 +00006502// Operations for querying visibility of a cursor.
6503//===----------------------------------------------------------------------===//
6504
6505extern "C" {
6506CXVisibilityKind clang_getCursorVisibility(CXCursor cursor) {
6507 if (!clang_isDeclaration(cursor.kind))
6508 return CXVisibility_Invalid;
6509
6510 const Decl *D = cxcursor::getCursorDecl(cursor);
6511 if (const NamedDecl *ND = dyn_cast_or_null<NamedDecl>(D))
6512 switch (ND->getVisibility()) {
6513 case HiddenVisibility: return CXVisibility_Hidden;
6514 case ProtectedVisibility: return CXVisibility_Protected;
6515 case DefaultVisibility: return CXVisibility_Default;
6516 };
6517
6518 return CXVisibility_Invalid;
6519}
6520} // end: extern "C"
6521
6522//===----------------------------------------------------------------------===//
Guy Benyei11169dd2012-12-18 14:30:41 +00006523// Operations for querying language of a cursor.
6524//===----------------------------------------------------------------------===//
6525
6526static CXLanguageKind getDeclLanguage(const Decl *D) {
6527 if (!D)
6528 return CXLanguage_C;
6529
6530 switch (D->getKind()) {
6531 default:
6532 break;
6533 case Decl::ImplicitParam:
6534 case Decl::ObjCAtDefsField:
6535 case Decl::ObjCCategory:
6536 case Decl::ObjCCategoryImpl:
6537 case Decl::ObjCCompatibleAlias:
6538 case Decl::ObjCImplementation:
6539 case Decl::ObjCInterface:
6540 case Decl::ObjCIvar:
6541 case Decl::ObjCMethod:
6542 case Decl::ObjCProperty:
6543 case Decl::ObjCPropertyImpl:
6544 case Decl::ObjCProtocol:
Douglas Gregor85f3f952015-07-07 03:57:15 +00006545 case Decl::ObjCTypeParam:
Guy Benyei11169dd2012-12-18 14:30:41 +00006546 return CXLanguage_ObjC;
6547 case Decl::CXXConstructor:
6548 case Decl::CXXConversion:
6549 case Decl::CXXDestructor:
6550 case Decl::CXXMethod:
6551 case Decl::CXXRecord:
6552 case Decl::ClassTemplate:
6553 case Decl::ClassTemplatePartialSpecialization:
6554 case Decl::ClassTemplateSpecialization:
6555 case Decl::Friend:
6556 case Decl::FriendTemplate:
6557 case Decl::FunctionTemplate:
6558 case Decl::LinkageSpec:
6559 case Decl::Namespace:
6560 case Decl::NamespaceAlias:
6561 case Decl::NonTypeTemplateParm:
6562 case Decl::StaticAssert:
6563 case Decl::TemplateTemplateParm:
6564 case Decl::TemplateTypeParm:
6565 case Decl::UnresolvedUsingTypename:
6566 case Decl::UnresolvedUsingValue:
6567 case Decl::Using:
6568 case Decl::UsingDirective:
6569 case Decl::UsingShadow:
6570 return CXLanguage_CPlusPlus;
6571 }
6572
6573 return CXLanguage_C;
6574}
6575
6576extern "C" {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006577
6578static CXAvailabilityKind getCursorAvailabilityForDecl(const Decl *D) {
6579 if (isa<FunctionDecl>(D) && cast<FunctionDecl>(D)->isDeleted())
Manuel Klimek8e3a7ed2015-09-25 17:53:16 +00006580 return CXAvailability_NotAvailable;
Guy Benyei11169dd2012-12-18 14:30:41 +00006581
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006582 switch (D->getAvailability()) {
6583 case AR_Available:
6584 case AR_NotYetIntroduced:
6585 if (const EnumConstantDecl *EnumConst = dyn_cast<EnumConstantDecl>(D))
Benjamin Kramer656363d2013-10-15 18:53:18 +00006586 return getCursorAvailabilityForDecl(
6587 cast<Decl>(EnumConst->getDeclContext()));
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006588 return CXAvailability_Available;
6589
6590 case AR_Deprecated:
6591 return CXAvailability_Deprecated;
6592
6593 case AR_Unavailable:
6594 return CXAvailability_NotAvailable;
6595 }
Benjamin Kramer656363d2013-10-15 18:53:18 +00006596
6597 llvm_unreachable("Unknown availability kind!");
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006598}
6599
Guy Benyei11169dd2012-12-18 14:30:41 +00006600enum CXAvailabilityKind clang_getCursorAvailability(CXCursor cursor) {
6601 if (clang_isDeclaration(cursor.kind))
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006602 if (const Decl *D = cxcursor::getCursorDecl(cursor))
6603 return getCursorAvailabilityForDecl(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00006604
6605 return CXAvailability_Available;
6606}
6607
6608static CXVersion convertVersion(VersionTuple In) {
6609 CXVersion Out = { -1, -1, -1 };
6610 if (In.empty())
6611 return Out;
6612
6613 Out.Major = In.getMajor();
6614
NAKAMURA Takumic2b5d1f2013-02-21 02:32:34 +00006615 Optional<unsigned> Minor = In.getMinor();
6616 if (Minor.hasValue())
Guy Benyei11169dd2012-12-18 14:30:41 +00006617 Out.Minor = *Minor;
6618 else
6619 return Out;
6620
NAKAMURA Takumic2b5d1f2013-02-21 02:32:34 +00006621 Optional<unsigned> Subminor = In.getSubminor();
6622 if (Subminor.hasValue())
Guy Benyei11169dd2012-12-18 14:30:41 +00006623 Out.Subminor = *Subminor;
6624
6625 return Out;
6626}
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006627
6628static int getCursorPlatformAvailabilityForDecl(const Decl *D,
6629 int *always_deprecated,
6630 CXString *deprecated_message,
6631 int *always_unavailable,
6632 CXString *unavailable_message,
6633 CXPlatformAvailability *availability,
6634 int availability_size) {
6635 bool HadAvailAttr = false;
6636 int N = 0;
Aaron Ballmanb97112e2014-03-08 22:19:01 +00006637 for (auto A : D->attrs()) {
6638 if (DeprecatedAttr *Deprecated = dyn_cast<DeprecatedAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006639 HadAvailAttr = true;
6640 if (always_deprecated)
6641 *always_deprecated = 1;
Nico Weberaacf0312014-04-24 05:16:45 +00006642 if (deprecated_message) {
Argyrios Kyrtzidisedfe07f2014-04-24 06:05:40 +00006643 clang_disposeString(*deprecated_message);
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006644 *deprecated_message = cxstring::createDup(Deprecated->getMessage());
Nico Weberaacf0312014-04-24 05:16:45 +00006645 }
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006646 continue;
6647 }
6648
Aaron Ballmanb97112e2014-03-08 22:19:01 +00006649 if (UnavailableAttr *Unavailable = dyn_cast<UnavailableAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006650 HadAvailAttr = true;
6651 if (always_unavailable)
6652 *always_unavailable = 1;
6653 if (unavailable_message) {
Argyrios Kyrtzidisedfe07f2014-04-24 06:05:40 +00006654 clang_disposeString(*unavailable_message);
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006655 *unavailable_message = cxstring::createDup(Unavailable->getMessage());
6656 }
6657 continue;
6658 }
6659
Aaron Ballmanb97112e2014-03-08 22:19:01 +00006660 if (AvailabilityAttr *Avail = dyn_cast<AvailabilityAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006661 HadAvailAttr = true;
6662 if (N < availability_size) {
6663 availability[N].Platform
6664 = cxstring::createDup(Avail->getPlatform()->getName());
6665 availability[N].Introduced = convertVersion(Avail->getIntroduced());
6666 availability[N].Deprecated = convertVersion(Avail->getDeprecated());
6667 availability[N].Obsoleted = convertVersion(Avail->getObsoleted());
6668 availability[N].Unavailable = Avail->getUnavailable();
6669 availability[N].Message = cxstring::createDup(Avail->getMessage());
6670 }
6671 ++N;
6672 }
6673 }
6674
6675 if (!HadAvailAttr)
6676 if (const EnumConstantDecl *EnumConst = dyn_cast<EnumConstantDecl>(D))
6677 return getCursorPlatformAvailabilityForDecl(
6678 cast<Decl>(EnumConst->getDeclContext()),
6679 always_deprecated,
6680 deprecated_message,
6681 always_unavailable,
6682 unavailable_message,
6683 availability,
6684 availability_size);
Guy Benyei11169dd2012-12-18 14:30:41 +00006685
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006686 return N;
6687}
6688
Guy Benyei11169dd2012-12-18 14:30:41 +00006689int clang_getCursorPlatformAvailability(CXCursor cursor,
6690 int *always_deprecated,
6691 CXString *deprecated_message,
6692 int *always_unavailable,
6693 CXString *unavailable_message,
6694 CXPlatformAvailability *availability,
6695 int availability_size) {
6696 if (always_deprecated)
6697 *always_deprecated = 0;
6698 if (deprecated_message)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006699 *deprecated_message = cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006700 if (always_unavailable)
6701 *always_unavailable = 0;
6702 if (unavailable_message)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006703 *unavailable_message = cxstring::createEmpty();
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006704
Guy Benyei11169dd2012-12-18 14:30:41 +00006705 if (!clang_isDeclaration(cursor.kind))
6706 return 0;
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006707
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006708 const Decl *D = cxcursor::getCursorDecl(cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00006709 if (!D)
6710 return 0;
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006711
6712 return getCursorPlatformAvailabilityForDecl(D, always_deprecated,
6713 deprecated_message,
6714 always_unavailable,
6715 unavailable_message,
6716 availability,
6717 availability_size);
Guy Benyei11169dd2012-12-18 14:30:41 +00006718}
6719
6720void clang_disposeCXPlatformAvailability(CXPlatformAvailability *availability) {
6721 clang_disposeString(availability->Platform);
6722 clang_disposeString(availability->Message);
6723}
6724
6725CXLanguageKind clang_getCursorLanguage(CXCursor cursor) {
6726 if (clang_isDeclaration(cursor.kind))
6727 return getDeclLanguage(cxcursor::getCursorDecl(cursor));
6728
6729 return CXLanguage_Invalid;
6730}
6731
6732 /// \brief If the given cursor is the "templated" declaration
6733 /// descibing a class or function template, return the class or
6734 /// function template.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006735static const Decl *maybeGetTemplateCursor(const Decl *D) {
Guy Benyei11169dd2012-12-18 14:30:41 +00006736 if (!D)
Craig Topper69186e72014-06-08 08:38:04 +00006737 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006738
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006739 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00006740 if (FunctionTemplateDecl *FunTmpl = FD->getDescribedFunctionTemplate())
6741 return FunTmpl;
6742
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006743 if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00006744 if (ClassTemplateDecl *ClassTmpl = RD->getDescribedClassTemplate())
6745 return ClassTmpl;
6746
6747 return D;
6748}
6749
Argyrios Kyrtzidis4e0854f2014-10-15 17:05:31 +00006750
6751enum CX_StorageClass clang_Cursor_getStorageClass(CXCursor C) {
6752 StorageClass sc = SC_None;
6753 const Decl *D = getCursorDecl(C);
6754 if (D) {
6755 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
6756 sc = FD->getStorageClass();
6757 } else if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
6758 sc = VD->getStorageClass();
6759 } else {
6760 return CX_SC_Invalid;
6761 }
6762 } else {
6763 return CX_SC_Invalid;
6764 }
6765 switch (sc) {
6766 case SC_None:
6767 return CX_SC_None;
6768 case SC_Extern:
6769 return CX_SC_Extern;
6770 case SC_Static:
6771 return CX_SC_Static;
6772 case SC_PrivateExtern:
6773 return CX_SC_PrivateExtern;
Argyrios Kyrtzidis4e0854f2014-10-15 17:05:31 +00006774 case SC_Auto:
6775 return CX_SC_Auto;
6776 case SC_Register:
6777 return CX_SC_Register;
Argyrios Kyrtzidis4e0854f2014-10-15 17:05:31 +00006778 }
Kaelyn Takataab61e702014-10-15 18:03:26 +00006779 llvm_unreachable("Unhandled storage class!");
Argyrios Kyrtzidis4e0854f2014-10-15 17:05:31 +00006780}
6781
Guy Benyei11169dd2012-12-18 14:30:41 +00006782CXCursor clang_getCursorSemanticParent(CXCursor cursor) {
6783 if (clang_isDeclaration(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006784 if (const Decl *D = getCursorDecl(cursor)) {
6785 const DeclContext *DC = D->getDeclContext();
Guy Benyei11169dd2012-12-18 14:30:41 +00006786 if (!DC)
6787 return clang_getNullCursor();
6788
6789 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
6790 getCursorTU(cursor));
6791 }
6792 }
6793
6794 if (clang_isStatement(cursor.kind) || clang_isExpression(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006795 if (const Decl *D = getCursorDecl(cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +00006796 return MakeCXCursor(D, getCursorTU(cursor));
6797 }
6798
6799 return clang_getNullCursor();
6800}
6801
6802CXCursor clang_getCursorLexicalParent(CXCursor cursor) {
6803 if (clang_isDeclaration(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006804 if (const Decl *D = getCursorDecl(cursor)) {
6805 const DeclContext *DC = D->getLexicalDeclContext();
Guy Benyei11169dd2012-12-18 14:30:41 +00006806 if (!DC)
6807 return clang_getNullCursor();
6808
6809 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
6810 getCursorTU(cursor));
6811 }
6812 }
6813
6814 // FIXME: Note that we can't easily compute the lexical context of a
6815 // statement or expression, so we return nothing.
6816 return clang_getNullCursor();
6817}
6818
6819CXFile clang_getIncludedFile(CXCursor cursor) {
6820 if (cursor.kind != CXCursor_InclusionDirective)
Craig Topper69186e72014-06-08 08:38:04 +00006821 return nullptr;
6822
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00006823 const InclusionDirective *ID = getCursorInclusionDirective(cursor);
Dmitri Gribenkof9304482013-01-23 15:56:07 +00006824 return const_cast<FileEntry *>(ID->getFile());
Guy Benyei11169dd2012-12-18 14:30:41 +00006825}
6826
Argyrios Kyrtzidis9adfd8a2013-04-18 22:15:49 +00006827unsigned clang_Cursor_getObjCPropertyAttributes(CXCursor C, unsigned reserved) {
6828 if (C.kind != CXCursor_ObjCPropertyDecl)
6829 return CXObjCPropertyAttr_noattr;
6830
6831 unsigned Result = CXObjCPropertyAttr_noattr;
6832 const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(getCursorDecl(C));
6833 ObjCPropertyDecl::PropertyAttributeKind Attr =
6834 PD->getPropertyAttributesAsWritten();
6835
6836#define SET_CXOBJCPROP_ATTR(A) \
6837 if (Attr & ObjCPropertyDecl::OBJC_PR_##A) \
6838 Result |= CXObjCPropertyAttr_##A
6839 SET_CXOBJCPROP_ATTR(readonly);
6840 SET_CXOBJCPROP_ATTR(getter);
6841 SET_CXOBJCPROP_ATTR(assign);
6842 SET_CXOBJCPROP_ATTR(readwrite);
6843 SET_CXOBJCPROP_ATTR(retain);
6844 SET_CXOBJCPROP_ATTR(copy);
6845 SET_CXOBJCPROP_ATTR(nonatomic);
6846 SET_CXOBJCPROP_ATTR(setter);
6847 SET_CXOBJCPROP_ATTR(atomic);
6848 SET_CXOBJCPROP_ATTR(weak);
6849 SET_CXOBJCPROP_ATTR(strong);
6850 SET_CXOBJCPROP_ATTR(unsafe_unretained);
6851#undef SET_CXOBJCPROP_ATTR
6852
6853 return Result;
6854}
6855
Argyrios Kyrtzidis9d9bc012013-04-18 23:29:12 +00006856unsigned clang_Cursor_getObjCDeclQualifiers(CXCursor C) {
6857 if (!clang_isDeclaration(C.kind))
6858 return CXObjCDeclQualifier_None;
6859
6860 Decl::ObjCDeclQualifier QT = Decl::OBJC_TQ_None;
6861 const Decl *D = getCursorDecl(C);
6862 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6863 QT = MD->getObjCDeclQualifier();
6864 else if (const ParmVarDecl *PD = dyn_cast<ParmVarDecl>(D))
6865 QT = PD->getObjCDeclQualifier();
6866 if (QT == Decl::OBJC_TQ_None)
6867 return CXObjCDeclQualifier_None;
6868
6869 unsigned Result = CXObjCDeclQualifier_None;
6870 if (QT & Decl::OBJC_TQ_In) Result |= CXObjCDeclQualifier_In;
6871 if (QT & Decl::OBJC_TQ_Inout) Result |= CXObjCDeclQualifier_Inout;
6872 if (QT & Decl::OBJC_TQ_Out) Result |= CXObjCDeclQualifier_Out;
6873 if (QT & Decl::OBJC_TQ_Bycopy) Result |= CXObjCDeclQualifier_Bycopy;
6874 if (QT & Decl::OBJC_TQ_Byref) Result |= CXObjCDeclQualifier_Byref;
6875 if (QT & Decl::OBJC_TQ_Oneway) Result |= CXObjCDeclQualifier_Oneway;
6876
6877 return Result;
6878}
6879
Argyrios Kyrtzidis7b50fc52013-07-05 20:44:37 +00006880unsigned clang_Cursor_isObjCOptional(CXCursor C) {
6881 if (!clang_isDeclaration(C.kind))
6882 return 0;
6883
6884 const Decl *D = getCursorDecl(C);
6885 if (const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(D))
6886 return PD->getPropertyImplementation() == ObjCPropertyDecl::Optional;
6887 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6888 return MD->getImplementationControl() == ObjCMethodDecl::Optional;
6889
6890 return 0;
6891}
6892
Argyrios Kyrtzidis23814e42013-04-18 23:53:05 +00006893unsigned clang_Cursor_isVariadic(CXCursor C) {
6894 if (!clang_isDeclaration(C.kind))
6895 return 0;
6896
6897 const Decl *D = getCursorDecl(C);
6898 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
6899 return FD->isVariadic();
6900 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6901 return MD->isVariadic();
6902
6903 return 0;
6904}
6905
Guy Benyei11169dd2012-12-18 14:30:41 +00006906CXSourceRange clang_Cursor_getCommentRange(CXCursor C) {
6907 if (!clang_isDeclaration(C.kind))
6908 return clang_getNullRange();
6909
6910 const Decl *D = getCursorDecl(C);
6911 ASTContext &Context = getCursorContext(C);
6912 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6913 if (!RC)
6914 return clang_getNullRange();
6915
6916 return cxloc::translateSourceRange(Context, RC->getSourceRange());
6917}
6918
6919CXString clang_Cursor_getRawCommentText(CXCursor C) {
6920 if (!clang_isDeclaration(C.kind))
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006921 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006922
6923 const Decl *D = getCursorDecl(C);
6924 ASTContext &Context = getCursorContext(C);
6925 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6926 StringRef RawText = RC ? RC->getRawText(Context.getSourceManager()) :
6927 StringRef();
6928
6929 // Don't duplicate the string because RawText points directly into source
6930 // code.
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006931 return cxstring::createRef(RawText);
Guy Benyei11169dd2012-12-18 14:30:41 +00006932}
6933
6934CXString clang_Cursor_getBriefCommentText(CXCursor C) {
6935 if (!clang_isDeclaration(C.kind))
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006936 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006937
6938 const Decl *D = getCursorDecl(C);
6939 const ASTContext &Context = getCursorContext(C);
6940 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6941
6942 if (RC) {
6943 StringRef BriefText = RC->getBriefText(Context);
6944
6945 // Don't duplicate the string because RawComment ensures that this memory
6946 // will not go away.
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006947 return cxstring::createRef(BriefText);
Guy Benyei11169dd2012-12-18 14:30:41 +00006948 }
6949
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006950 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006951}
6952
Guy Benyei11169dd2012-12-18 14:30:41 +00006953CXModule clang_Cursor_getModule(CXCursor C) {
6954 if (C.kind == CXCursor_ModuleImportDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006955 if (const ImportDecl *ImportD =
6956 dyn_cast_or_null<ImportDecl>(getCursorDecl(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00006957 return ImportD->getImportedModule();
6958 }
6959
Craig Topper69186e72014-06-08 08:38:04 +00006960 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006961}
6962
Argyrios Kyrtzidisf6d49c32014-05-14 23:14:37 +00006963CXModule clang_getModuleForFile(CXTranslationUnit TU, CXFile File) {
6964 if (isNotUsableTU(TU)) {
6965 LOG_BAD_TU(TU);
6966 return nullptr;
6967 }
6968 if (!File)
6969 return nullptr;
6970 FileEntry *FE = static_cast<FileEntry *>(File);
6971
6972 ASTUnit &Unit = *cxtu::getASTUnit(TU);
6973 HeaderSearch &HS = Unit.getPreprocessor().getHeaderSearchInfo();
6974 ModuleMap::KnownHeader Header = HS.findModuleForHeader(FE);
6975
Richard Smithfeb54b62014-10-23 02:01:19 +00006976 return Header.getModule();
Argyrios Kyrtzidisf6d49c32014-05-14 23:14:37 +00006977}
6978
Argyrios Kyrtzidis12fdb9e2013-04-26 22:47:49 +00006979CXFile clang_Module_getASTFile(CXModule CXMod) {
6980 if (!CXMod)
Craig Topper69186e72014-06-08 08:38:04 +00006981 return nullptr;
Argyrios Kyrtzidis12fdb9e2013-04-26 22:47:49 +00006982 Module *Mod = static_cast<Module*>(CXMod);
6983 return const_cast<FileEntry *>(Mod->getASTFile());
6984}
6985
Guy Benyei11169dd2012-12-18 14:30:41 +00006986CXModule clang_Module_getParent(CXModule CXMod) {
6987 if (!CXMod)
Craig Topper69186e72014-06-08 08:38:04 +00006988 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006989 Module *Mod = static_cast<Module*>(CXMod);
6990 return Mod->Parent;
6991}
6992
6993CXString clang_Module_getName(CXModule CXMod) {
6994 if (!CXMod)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006995 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006996 Module *Mod = static_cast<Module*>(CXMod);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006997 return cxstring::createDup(Mod->Name);
Guy Benyei11169dd2012-12-18 14:30:41 +00006998}
6999
7000CXString clang_Module_getFullName(CXModule CXMod) {
7001 if (!CXMod)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00007002 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00007003 Module *Mod = static_cast<Module*>(CXMod);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00007004 return cxstring::createDup(Mod->getFullModuleName());
Guy Benyei11169dd2012-12-18 14:30:41 +00007005}
7006
Argyrios Kyrtzidis884337f2014-05-15 04:44:25 +00007007int clang_Module_isSystem(CXModule CXMod) {
7008 if (!CXMod)
7009 return 0;
7010 Module *Mod = static_cast<Module*>(CXMod);
7011 return Mod->IsSystem;
7012}
7013
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00007014unsigned clang_Module_getNumTopLevelHeaders(CXTranslationUnit TU,
7015 CXModule CXMod) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00007016 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00007017 LOG_BAD_TU(TU);
7018 return 0;
7019 }
7020 if (!CXMod)
Guy Benyei11169dd2012-12-18 14:30:41 +00007021 return 0;
7022 Module *Mod = static_cast<Module*>(CXMod);
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00007023 FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
7024 ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
7025 return TopHeaders.size();
Guy Benyei11169dd2012-12-18 14:30:41 +00007026}
7027
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00007028CXFile clang_Module_getTopLevelHeader(CXTranslationUnit TU,
7029 CXModule CXMod, unsigned Index) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00007030 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00007031 LOG_BAD_TU(TU);
Craig Topper69186e72014-06-08 08:38:04 +00007032 return nullptr;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00007033 }
7034 if (!CXMod)
Craig Topper69186e72014-06-08 08:38:04 +00007035 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00007036 Module *Mod = static_cast<Module*>(CXMod);
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00007037 FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
Guy Benyei11169dd2012-12-18 14:30:41 +00007038
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00007039 ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
7040 if (Index < TopHeaders.size())
7041 return const_cast<FileEntry *>(TopHeaders[Index]);
Guy Benyei11169dd2012-12-18 14:30:41 +00007042
Craig Topper69186e72014-06-08 08:38:04 +00007043 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00007044}
7045
7046} // end: extern "C"
7047
7048//===----------------------------------------------------------------------===//
7049// C++ AST instrospection.
7050//===----------------------------------------------------------------------===//
7051
7052extern "C" {
Saleem Abdulrasool6ea75db2015-10-27 15:50:22 +00007053unsigned clang_CXXField_isMutable(CXCursor C) {
7054 if (!clang_isDeclaration(C.kind))
7055 return 0;
7056
7057 if (const auto D = cxcursor::getCursorDecl(C))
7058 if (const auto FD = dyn_cast_or_null<FieldDecl>(D))
7059 return FD->isMutable() ? 1 : 0;
7060 return 0;
7061}
7062
Dmitri Gribenko62770be2013-05-17 18:38:35 +00007063unsigned clang_CXXMethod_isPureVirtual(CXCursor C) {
7064 if (!clang_isDeclaration(C.kind))
7065 return 0;
7066
Dmitri Gribenko62770be2013-05-17 18:38:35 +00007067 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00007068 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00007069 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Dmitri Gribenko62770be2013-05-17 18:38:35 +00007070 return (Method && Method->isVirtual() && Method->isPure()) ? 1 : 0;
7071}
7072
Dmitri Gribenkoe570ede2014-04-07 14:59:13 +00007073unsigned clang_CXXMethod_isConst(CXCursor C) {
7074 if (!clang_isDeclaration(C.kind))
7075 return 0;
7076
7077 const Decl *D = cxcursor::getCursorDecl(C);
7078 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00007079 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Dmitri Gribenkoe570ede2014-04-07 14:59:13 +00007080 return (Method && (Method->getTypeQualifiers() & Qualifiers::Const)) ? 1 : 0;
7081}
7082
Guy Benyei11169dd2012-12-18 14:30:41 +00007083unsigned clang_CXXMethod_isStatic(CXCursor C) {
7084 if (!clang_isDeclaration(C.kind))
7085 return 0;
7086
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00007087 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00007088 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00007089 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00007090 return (Method && Method->isStatic()) ? 1 : 0;
7091}
7092
7093unsigned clang_CXXMethod_isVirtual(CXCursor C) {
7094 if (!clang_isDeclaration(C.kind))
7095 return 0;
7096
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00007097 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00007098 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00007099 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00007100 return (Method && Method->isVirtual()) ? 1 : 0;
7101}
7102} // end: extern "C"
7103
7104//===----------------------------------------------------------------------===//
7105// Attribute introspection.
7106//===----------------------------------------------------------------------===//
7107
7108extern "C" {
7109CXType clang_getIBOutletCollectionType(CXCursor C) {
7110 if (C.kind != CXCursor_IBOutletCollectionAttr)
7111 return cxtype::MakeCXType(QualType(), cxcursor::getCursorTU(C));
7112
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00007113 const IBOutletCollectionAttr *A =
Guy Benyei11169dd2012-12-18 14:30:41 +00007114 cast<IBOutletCollectionAttr>(cxcursor::getCursorAttr(C));
7115
7116 return cxtype::MakeCXType(A->getInterface(), cxcursor::getCursorTU(C));
7117}
7118} // end: extern "C"
7119
7120//===----------------------------------------------------------------------===//
7121// Inspecting memory usage.
7122//===----------------------------------------------------------------------===//
7123
7124typedef std::vector<CXTUResourceUsageEntry> MemUsageEntries;
7125
7126static inline void createCXTUResourceUsageEntry(MemUsageEntries &entries,
7127 enum CXTUResourceUsageKind k,
7128 unsigned long amount) {
7129 CXTUResourceUsageEntry entry = { k, amount };
7130 entries.push_back(entry);
7131}
7132
7133extern "C" {
7134
7135const char *clang_getTUResourceUsageName(CXTUResourceUsageKind kind) {
7136 const char *str = "";
7137 switch (kind) {
7138 case CXTUResourceUsage_AST:
7139 str = "ASTContext: expressions, declarations, and types";
7140 break;
7141 case CXTUResourceUsage_Identifiers:
7142 str = "ASTContext: identifiers";
7143 break;
7144 case CXTUResourceUsage_Selectors:
7145 str = "ASTContext: selectors";
7146 break;
7147 case CXTUResourceUsage_GlobalCompletionResults:
7148 str = "Code completion: cached global results";
7149 break;
7150 case CXTUResourceUsage_SourceManagerContentCache:
7151 str = "SourceManager: content cache allocator";
7152 break;
7153 case CXTUResourceUsage_AST_SideTables:
7154 str = "ASTContext: side tables";
7155 break;
7156 case CXTUResourceUsage_SourceManager_Membuffer_Malloc:
7157 str = "SourceManager: malloc'ed memory buffers";
7158 break;
7159 case CXTUResourceUsage_SourceManager_Membuffer_MMap:
7160 str = "SourceManager: mmap'ed memory buffers";
7161 break;
7162 case CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc:
7163 str = "ExternalASTSource: malloc'ed memory buffers";
7164 break;
7165 case CXTUResourceUsage_ExternalASTSource_Membuffer_MMap:
7166 str = "ExternalASTSource: mmap'ed memory buffers";
7167 break;
7168 case CXTUResourceUsage_Preprocessor:
7169 str = "Preprocessor: malloc'ed memory";
7170 break;
7171 case CXTUResourceUsage_PreprocessingRecord:
7172 str = "Preprocessor: PreprocessingRecord";
7173 break;
7174 case CXTUResourceUsage_SourceManager_DataStructures:
7175 str = "SourceManager: data structures and tables";
7176 break;
7177 case CXTUResourceUsage_Preprocessor_HeaderSearch:
7178 str = "Preprocessor: header search tables";
7179 break;
7180 }
7181 return str;
7182}
7183
7184CXTUResourceUsage clang_getCXTUResourceUsage(CXTranslationUnit TU) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00007185 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00007186 LOG_BAD_TU(TU);
Craig Topper69186e72014-06-08 08:38:04 +00007187 CXTUResourceUsage usage = { (void*) nullptr, 0, nullptr };
Guy Benyei11169dd2012-12-18 14:30:41 +00007188 return usage;
7189 }
7190
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007191 ASTUnit *astUnit = cxtu::getASTUnit(TU);
Ahmed Charlesb8984322014-03-07 20:03:18 +00007192 std::unique_ptr<MemUsageEntries> entries(new MemUsageEntries());
Guy Benyei11169dd2012-12-18 14:30:41 +00007193 ASTContext &astContext = astUnit->getASTContext();
7194
7195 // How much memory is used by AST nodes and types?
7196 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST,
7197 (unsigned long) astContext.getASTAllocatedMemory());
7198
7199 // How much memory is used by identifiers?
7200 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Identifiers,
7201 (unsigned long) astContext.Idents.getAllocator().getTotalMemory());
7202
7203 // How much memory is used for selectors?
7204 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Selectors,
7205 (unsigned long) astContext.Selectors.getTotalMemory());
7206
7207 // How much memory is used by ASTContext's side tables?
7208 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST_SideTables,
7209 (unsigned long) astContext.getSideTableAllocatedMemory());
7210
7211 // How much memory is used for caching global code completion results?
7212 unsigned long completionBytes = 0;
7213 if (GlobalCodeCompletionAllocator *completionAllocator =
Alp Tokerf994cef2014-07-05 03:08:06 +00007214 astUnit->getCachedCompletionAllocator().get()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00007215 completionBytes = completionAllocator->getTotalMemory();
7216 }
7217 createCXTUResourceUsageEntry(*entries,
7218 CXTUResourceUsage_GlobalCompletionResults,
7219 completionBytes);
7220
7221 // How much memory is being used by SourceManager's content cache?
7222 createCXTUResourceUsageEntry(*entries,
7223 CXTUResourceUsage_SourceManagerContentCache,
7224 (unsigned long) astContext.getSourceManager().getContentCacheSize());
7225
7226 // How much memory is being used by the MemoryBuffer's in SourceManager?
7227 const SourceManager::MemoryBufferSizes &srcBufs =
7228 astUnit->getSourceManager().getMemoryBufferSizes();
7229
7230 createCXTUResourceUsageEntry(*entries,
7231 CXTUResourceUsage_SourceManager_Membuffer_Malloc,
7232 (unsigned long) srcBufs.malloc_bytes);
7233 createCXTUResourceUsageEntry(*entries,
7234 CXTUResourceUsage_SourceManager_Membuffer_MMap,
7235 (unsigned long) srcBufs.mmap_bytes);
7236 createCXTUResourceUsageEntry(*entries,
7237 CXTUResourceUsage_SourceManager_DataStructures,
7238 (unsigned long) astContext.getSourceManager()
7239 .getDataStructureSizes());
7240
7241 // How much memory is being used by the ExternalASTSource?
7242 if (ExternalASTSource *esrc = astContext.getExternalSource()) {
7243 const ExternalASTSource::MemoryBufferSizes &sizes =
7244 esrc->getMemoryBufferSizes();
7245
7246 createCXTUResourceUsageEntry(*entries,
7247 CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc,
7248 (unsigned long) sizes.malloc_bytes);
7249 createCXTUResourceUsageEntry(*entries,
7250 CXTUResourceUsage_ExternalASTSource_Membuffer_MMap,
7251 (unsigned long) sizes.mmap_bytes);
7252 }
7253
7254 // How much memory is being used by the Preprocessor?
7255 Preprocessor &pp = astUnit->getPreprocessor();
7256 createCXTUResourceUsageEntry(*entries,
7257 CXTUResourceUsage_Preprocessor,
7258 pp.getTotalMemory());
7259
7260 if (PreprocessingRecord *pRec = pp.getPreprocessingRecord()) {
7261 createCXTUResourceUsageEntry(*entries,
7262 CXTUResourceUsage_PreprocessingRecord,
7263 pRec->getTotalMemory());
7264 }
7265
7266 createCXTUResourceUsageEntry(*entries,
7267 CXTUResourceUsage_Preprocessor_HeaderSearch,
7268 pp.getHeaderSearchInfo().getTotalMemory());
Craig Topper69186e72014-06-08 08:38:04 +00007269
Guy Benyei11169dd2012-12-18 14:30:41 +00007270 CXTUResourceUsage usage = { (void*) entries.get(),
7271 (unsigned) entries->size(),
Alexander Kornienko6ee521c2015-01-23 15:36:10 +00007272 !entries->empty() ? &(*entries)[0] : nullptr };
Ahmed Charles9a16beb2014-03-07 19:33:25 +00007273 entries.release();
Guy Benyei11169dd2012-12-18 14:30:41 +00007274 return usage;
7275}
7276
7277void clang_disposeCXTUResourceUsage(CXTUResourceUsage usage) {
7278 if (usage.data)
7279 delete (MemUsageEntries*) usage.data;
7280}
7281
Argyrios Kyrtzidis0e282ef2013-12-06 18:55:45 +00007282CXSourceRangeList *clang_getSkippedRanges(CXTranslationUnit TU, CXFile file) {
7283 CXSourceRangeList *skipped = new CXSourceRangeList;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00007284 skipped->count = 0;
Craig Topper69186e72014-06-08 08:38:04 +00007285 skipped->ranges = nullptr;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00007286
Dmitri Gribenko852d6222014-02-11 15:02:48 +00007287 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00007288 LOG_BAD_TU(TU);
7289 return skipped;
7290 }
7291
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00007292 if (!file)
7293 return skipped;
7294
7295 ASTUnit *astUnit = cxtu::getASTUnit(TU);
7296 PreprocessingRecord *ppRec = astUnit->getPreprocessor().getPreprocessingRecord();
7297 if (!ppRec)
7298 return skipped;
7299
7300 ASTContext &Ctx = astUnit->getASTContext();
7301 SourceManager &sm = Ctx.getSourceManager();
7302 FileEntry *fileEntry = static_cast<FileEntry *>(file);
7303 FileID wantedFileID = sm.translateFile(fileEntry);
7304
7305 const std::vector<SourceRange> &SkippedRanges = ppRec->getSkippedRanges();
7306 std::vector<SourceRange> wantedRanges;
7307 for (std::vector<SourceRange>::const_iterator i = SkippedRanges.begin(), ei = SkippedRanges.end();
7308 i != ei; ++i) {
7309 if (sm.getFileID(i->getBegin()) == wantedFileID || sm.getFileID(i->getEnd()) == wantedFileID)
7310 wantedRanges.push_back(*i);
7311 }
7312
7313 skipped->count = wantedRanges.size();
7314 skipped->ranges = new CXSourceRange[skipped->count];
7315 for (unsigned i = 0, ei = skipped->count; i != ei; ++i)
7316 skipped->ranges[i] = cxloc::translateSourceRange(Ctx, wantedRanges[i]);
7317
7318 return skipped;
7319}
7320
Argyrios Kyrtzidis0e282ef2013-12-06 18:55:45 +00007321void clang_disposeSourceRangeList(CXSourceRangeList *ranges) {
7322 if (ranges) {
7323 delete[] ranges->ranges;
7324 delete ranges;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00007325 }
7326}
7327
Guy Benyei11169dd2012-12-18 14:30:41 +00007328} // end extern "C"
7329
7330void clang::PrintLibclangResourceUsage(CXTranslationUnit TU) {
7331 CXTUResourceUsage Usage = clang_getCXTUResourceUsage(TU);
7332 for (unsigned I = 0; I != Usage.numEntries; ++I)
7333 fprintf(stderr, " %s: %lu\n",
7334 clang_getTUResourceUsageName(Usage.entries[I].kind),
7335 Usage.entries[I].amount);
7336
7337 clang_disposeCXTUResourceUsage(Usage);
7338}
7339
7340//===----------------------------------------------------------------------===//
7341// Misc. utility functions.
7342//===----------------------------------------------------------------------===//
7343
7344/// Default to using an 8 MB stack size on "safety" threads.
7345static unsigned SafetyStackThreadSize = 8 << 20;
7346
7347namespace clang {
7348
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00007349bool RunSafely(llvm::CrashRecoveryContext &CRC, llvm::function_ref<void()> Fn,
Guy Benyei11169dd2012-12-18 14:30:41 +00007350 unsigned Size) {
7351 if (!Size)
7352 Size = GetSafetyThreadStackSize();
7353 if (Size)
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00007354 return CRC.RunSafelyOnThread(Fn, Size);
7355 return CRC.RunSafely(Fn);
Guy Benyei11169dd2012-12-18 14:30:41 +00007356}
7357
7358unsigned GetSafetyThreadStackSize() {
7359 return SafetyStackThreadSize;
7360}
7361
7362void SetSafetyThreadStackSize(unsigned Value) {
7363 SafetyStackThreadSize = Value;
7364}
7365
Alexander Kornienkoab9db512015-06-22 23:07:51 +00007366}
Guy Benyei11169dd2012-12-18 14:30:41 +00007367
7368void clang::setThreadBackgroundPriority() {
7369 if (getenv("LIBCLANG_BGPRIO_DISABLE"))
7370 return;
7371
Alp Toker1a86ad22014-07-06 06:24:00 +00007372#ifdef USE_DARWIN_THREADS
Guy Benyei11169dd2012-12-18 14:30:41 +00007373 setpriority(PRIO_DARWIN_THREAD, 0, PRIO_DARWIN_BG);
7374#endif
7375}
7376
7377void cxindex::printDiagsToStderr(ASTUnit *Unit) {
7378 if (!Unit)
7379 return;
7380
7381 for (ASTUnit::stored_diag_iterator D = Unit->stored_diag_begin(),
7382 DEnd = Unit->stored_diag_end();
7383 D != DEnd; ++D) {
Ben Langmuir749323f2014-04-22 17:40:12 +00007384 CXStoredDiagnostic Diag(*D, Unit->getLangOpts());
Guy Benyei11169dd2012-12-18 14:30:41 +00007385 CXString Msg = clang_formatDiagnostic(&Diag,
7386 clang_defaultDiagnosticDisplayOptions());
7387 fprintf(stderr, "%s\n", clang_getCString(Msg));
7388 clang_disposeString(Msg);
7389 }
7390#ifdef LLVM_ON_WIN32
7391 // On Windows, force a flush, since there may be multiple copies of
7392 // stderr and stdout in the file system, all with different buffers
7393 // but writing to the same device.
7394 fflush(stderr);
7395#endif
7396}
7397
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007398MacroInfo *cxindex::getMacroInfo(const IdentifierInfo &II,
7399 SourceLocation MacroDefLoc,
7400 CXTranslationUnit TU){
7401 if (MacroDefLoc.isInvalid() || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00007402 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007403 if (!II.hadMacroDefinition())
Craig Topper69186e72014-06-08 08:38:04 +00007404 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007405
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007406 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00007407 Preprocessor &PP = Unit->getPreprocessor();
Richard Smith20e883e2015-04-29 23:20:19 +00007408 MacroDirective *MD = PP.getLocalMacroDirectiveHistory(&II);
Argyrios Kyrtzidisb6210df2013-03-26 17:17:01 +00007409 if (MD) {
7410 for (MacroDirective::DefInfo
7411 Def = MD->getDefinition(); Def; Def = Def.getPreviousDefinition()) {
7412 if (MacroDefLoc == Def.getMacroInfo()->getDefinitionLoc())
7413 return Def.getMacroInfo();
7414 }
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007415 }
7416
Craig Topper69186e72014-06-08 08:38:04 +00007417 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007418}
7419
Richard Smith66a81862015-05-04 02:25:31 +00007420const MacroInfo *cxindex::getMacroInfo(const MacroDefinitionRecord *MacroDef,
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00007421 CXTranslationUnit TU) {
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007422 if (!MacroDef || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00007423 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007424 const IdentifierInfo *II = MacroDef->getName();
7425 if (!II)
Craig Topper69186e72014-06-08 08:38:04 +00007426 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007427
7428 return getMacroInfo(*II, MacroDef->getLocation(), TU);
7429}
7430
Richard Smith66a81862015-05-04 02:25:31 +00007431MacroDefinitionRecord *
7432cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI, const Token &Tok,
7433 CXTranslationUnit TU) {
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007434 if (!MI || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00007435 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007436 if (Tok.isNot(tok::raw_identifier))
Craig Topper69186e72014-06-08 08:38:04 +00007437 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007438
7439 if (MI->getNumTokens() == 0)
Craig Topper69186e72014-06-08 08:38:04 +00007440 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007441 SourceRange DefRange(MI->getReplacementToken(0).getLocation(),
7442 MI->getDefinitionEndLoc());
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007443 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007444
7445 // Check that the token is inside the definition and not its argument list.
7446 SourceManager &SM = Unit->getSourceManager();
7447 if (SM.isBeforeInTranslationUnit(Tok.getLocation(), DefRange.getBegin()))
Craig Topper69186e72014-06-08 08:38:04 +00007448 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007449 if (SM.isBeforeInTranslationUnit(DefRange.getEnd(), Tok.getLocation()))
Craig Topper69186e72014-06-08 08:38:04 +00007450 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007451
7452 Preprocessor &PP = Unit->getPreprocessor();
7453 PreprocessingRecord *PPRec = PP.getPreprocessingRecord();
7454 if (!PPRec)
Craig Topper69186e72014-06-08 08:38:04 +00007455 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007456
Alp Toker2d57cea2014-05-17 04:53:25 +00007457 IdentifierInfo &II = PP.getIdentifierTable().get(Tok.getRawIdentifier());
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007458 if (!II.hadMacroDefinition())
Craig Topper69186e72014-06-08 08:38:04 +00007459 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007460
7461 // Check that the identifier is not one of the macro arguments.
7462 if (std::find(MI->arg_begin(), MI->arg_end(), &II) != MI->arg_end())
Craig Topper69186e72014-06-08 08:38:04 +00007463 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007464
Richard Smith20e883e2015-04-29 23:20:19 +00007465 MacroDirective *InnerMD = PP.getLocalMacroDirectiveHistory(&II);
Argyrios Kyrtzidis09c9e812013-02-20 00:54:57 +00007466 if (!InnerMD)
Craig Topper69186e72014-06-08 08:38:04 +00007467 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007468
Argyrios Kyrtzidisb6210df2013-03-26 17:17:01 +00007469 return PPRec->findMacroDefinition(InnerMD->getMacroInfo());
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007470}
7471
Richard Smith66a81862015-05-04 02:25:31 +00007472MacroDefinitionRecord *
7473cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI, SourceLocation Loc,
7474 CXTranslationUnit TU) {
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007475 if (Loc.isInvalid() || !MI || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00007476 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007477
7478 if (MI->getNumTokens() == 0)
Craig Topper69186e72014-06-08 08:38:04 +00007479 return nullptr;
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007480 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007481 Preprocessor &PP = Unit->getPreprocessor();
7482 if (!PP.getPreprocessingRecord())
Craig Topper69186e72014-06-08 08:38:04 +00007483 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007484 Loc = Unit->getSourceManager().getSpellingLoc(Loc);
7485 Token Tok;
7486 if (PP.getRawToken(Loc, Tok))
Craig Topper69186e72014-06-08 08:38:04 +00007487 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007488
7489 return checkForMacroInMacroDefinition(MI, Tok, TU);
7490}
7491
Guy Benyei11169dd2012-12-18 14:30:41 +00007492extern "C" {
7493
7494CXString clang_getClangVersion() {
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00007495 return cxstring::createDup(getClangFullVersion());
Guy Benyei11169dd2012-12-18 14:30:41 +00007496}
7497
7498} // end: extern "C"
7499
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007500Logger &cxindex::Logger::operator<<(CXTranslationUnit TU) {
7501 if (TU) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007502 if (ASTUnit *Unit = cxtu::getASTUnit(TU)) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007503 LogOS << '<' << Unit->getMainFileName() << '>';
Argyrios Kyrtzidis37f2ab42013-03-05 20:21:14 +00007504 if (Unit->isMainFileAST())
7505 LogOS << " (" << Unit->getASTFileName() << ')';
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007506 return *this;
7507 }
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00007508 } else {
7509 LogOS << "<NULL TU>";
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007510 }
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007511 return *this;
7512}
7513
Argyrios Kyrtzidisba4b5f82013-03-08 02:32:26 +00007514Logger &cxindex::Logger::operator<<(const FileEntry *FE) {
7515 *this << FE->getName();
7516 return *this;
7517}
7518
7519Logger &cxindex::Logger::operator<<(CXCursor cursor) {
7520 CXString cursorName = clang_getCursorDisplayName(cursor);
7521 *this << cursorName << "@" << clang_getCursorLocation(cursor);
7522 clang_disposeString(cursorName);
7523 return *this;
7524}
7525
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007526Logger &cxindex::Logger::operator<<(CXSourceLocation Loc) {
7527 CXFile File;
7528 unsigned Line, Column;
Craig Topper69186e72014-06-08 08:38:04 +00007529 clang_getFileLocation(Loc, &File, &Line, &Column, nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007530 CXString FileName = clang_getFileName(File);
7531 *this << llvm::format("(%s:%d:%d)", clang_getCString(FileName), Line, Column);
7532 clang_disposeString(FileName);
7533 return *this;
7534}
7535
7536Logger &cxindex::Logger::operator<<(CXSourceRange range) {
7537 CXSourceLocation BLoc = clang_getRangeStart(range);
7538 CXSourceLocation ELoc = clang_getRangeEnd(range);
7539
7540 CXFile BFile;
7541 unsigned BLine, BColumn;
Craig Topper69186e72014-06-08 08:38:04 +00007542 clang_getFileLocation(BLoc, &BFile, &BLine, &BColumn, nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007543
7544 CXFile EFile;
7545 unsigned ELine, EColumn;
Craig Topper69186e72014-06-08 08:38:04 +00007546 clang_getFileLocation(ELoc, &EFile, &ELine, &EColumn, nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007547
7548 CXString BFileName = clang_getFileName(BFile);
7549 if (BFile == EFile) {
7550 *this << llvm::format("[%s %d:%d-%d:%d]", clang_getCString(BFileName),
7551 BLine, BColumn, ELine, EColumn);
7552 } else {
7553 CXString EFileName = clang_getFileName(EFile);
7554 *this << llvm::format("[%s:%d:%d - ", clang_getCString(BFileName),
7555 BLine, BColumn)
7556 << llvm::format("%s:%d:%d]", clang_getCString(EFileName),
7557 ELine, EColumn);
7558 clang_disposeString(EFileName);
7559 }
7560 clang_disposeString(BFileName);
7561 return *this;
7562}
7563
7564Logger &cxindex::Logger::operator<<(CXString Str) {
7565 *this << clang_getCString(Str);
7566 return *this;
7567}
7568
7569Logger &cxindex::Logger::operator<<(const llvm::format_object_base &Fmt) {
7570 LogOS << Fmt;
7571 return *this;
7572}
7573
Chandler Carruth37ad2582014-06-27 15:14:39 +00007574static llvm::ManagedStatic<llvm::sys::Mutex> LoggingMutex;
7575
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007576cxindex::Logger::~Logger() {
Chandler Carruth37ad2582014-06-27 15:14:39 +00007577 llvm::sys::ScopedLock L(*LoggingMutex);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007578
7579 static llvm::TimeRecord sBeginTR = llvm::TimeRecord::getCurrentTime();
7580
Dmitri Gribenkof8579502013-01-12 19:30:44 +00007581 raw_ostream &OS = llvm::errs();
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007582 OS << "[libclang:" << Name << ':';
7583
Alp Toker1a86ad22014-07-06 06:24:00 +00007584#ifdef USE_DARWIN_THREADS
7585 // TODO: Portability.
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007586 mach_port_t tid = pthread_mach_thread_np(pthread_self());
7587 OS << tid << ':';
7588#endif
7589
7590 llvm::TimeRecord TR = llvm::TimeRecord::getCurrentTime();
7591 OS << llvm::format("%7.4f] ", TR.getWallTime() - sBeginTR.getWallTime());
Yaron Keren09fb7c62015-03-10 07:33:23 +00007592 OS << Msg << '\n';
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007593
7594 if (Trace) {
Zachary Turner1fe2a8d2015-03-05 19:15:09 +00007595 llvm::sys::PrintStackTrace(OS);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007596 OS << "--------------------------------------------------\n";
7597 }
7598}