blob: 642a67b985c97aa765d1c2147a25d3be0abac110 [file] [log] [blame]
Guy Benyei11169dd2012-12-18 14:30:41 +00001//===- CIndex.cpp - Clang-C Source Indexing Library -----------------------===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file implements the main API hooks in the Clang-C Source Indexing
11// library.
12//
13//===----------------------------------------------------------------------===//
14
15#include "CIndexer.h"
16#include "CIndexDiagnostic.h"
Chandler Carruth4b417452013-01-19 08:09:44 +000017#include "CLog.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000018#include "CXCursor.h"
19#include "CXSourceLocation.h"
20#include "CXString.h"
21#include "CXTranslationUnit.h"
22#include "CXType.h"
23#include "CursorVisitor.h"
David Blaikie0a4e61f2013-09-13 18:32:52 +000024#include "clang/AST/Attr.h"
Eli Bendersky44a206f2014-07-31 18:04:56 +000025#include "clang/AST/Mangle.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000026#include "clang/AST/StmtVisitor.h"
27#include "clang/Basic/Diagnostic.h"
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +000028#include "clang/Basic/DiagnosticCategories.h"
29#include "clang/Basic/DiagnosticIDs.h"
Eli Bendersky79759592014-08-01 15:01:10 +000030#include "clang/Basic/TargetInfo.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000031#include "clang/Basic/Version.h"
32#include "clang/Frontend/ASTUnit.h"
33#include "clang/Frontend/CompilerInstance.h"
34#include "clang/Frontend/FrontendDiagnostic.h"
Dmitri Gribenko9e605112013-11-13 22:16:51 +000035#include "clang/Index/CommentToXML.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000036#include "clang/Lex/HeaderSearch.h"
37#include "clang/Lex/Lexer.h"
38#include "clang/Lex/PreprocessingRecord.h"
39#include "clang/Lex/Preprocessor.h"
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +000040#include "clang/Serialization/SerializationDiagnostic.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000041#include "llvm/ADT/Optional.h"
42#include "llvm/ADT/STLExtras.h"
43#include "llvm/ADT/StringSwitch.h"
Alp Toker1d257e12014-06-04 03:28:55 +000044#include "llvm/Config/llvm-config.h"
Eli Bendersky79759592014-08-01 15:01:10 +000045#include "llvm/IR/DataLayout.h"
46#include "llvm/IR/Mangler.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000047#include "llvm/Support/Compiler.h"
48#include "llvm/Support/CrashRecoveryContext.h"
Chandler Carruth4b417452013-01-19 08:09:44 +000049#include "llvm/Support/Format.h"
Chandler Carruth37ad2582014-06-27 15:14:39 +000050#include "llvm/Support/ManagedStatic.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000051#include "llvm/Support/MemoryBuffer.h"
52#include "llvm/Support/Mutex.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000053#include "llvm/Support/Program.h"
54#include "llvm/Support/SaveAndRestore.h"
55#include "llvm/Support/Signals.h"
Adrian Prantlbc068582015-07-08 01:00:30 +000056#include "llvm/Support/TargetSelect.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000057#include "llvm/Support/Threading.h"
58#include "llvm/Support/Timer.h"
59#include "llvm/Support/raw_ostream.h"
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +000060
Alp Toker1a86ad22014-07-06 06:24:00 +000061#if LLVM_ENABLE_THREADS != 0 && defined(__APPLE__)
62#define USE_DARWIN_THREADS
63#endif
64
65#ifdef USE_DARWIN_THREADS
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +000066#include <pthread.h>
67#endif
Guy Benyei11169dd2012-12-18 14:30:41 +000068
69using namespace clang;
70using namespace clang::cxcursor;
Guy Benyei11169dd2012-12-18 14:30:41 +000071using namespace clang::cxtu;
72using namespace clang::cxindex;
73
Dmitri Gribenkod36209e2013-01-26 21:32:42 +000074CXTranslationUnit cxtu::MakeCXTranslationUnit(CIndexer *CIdx, ASTUnit *AU) {
75 if (!AU)
Craig Topper69186e72014-06-08 08:38:04 +000076 return nullptr;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +000077 assert(CIdx);
Guy Benyei11169dd2012-12-18 14:30:41 +000078 CXTranslationUnit D = new CXTranslationUnitImpl();
79 D->CIdx = CIdx;
Dmitri Gribenkod36209e2013-01-26 21:32:42 +000080 D->TheASTUnit = AU;
Dmitri Gribenko74895212013-02-03 13:52:47 +000081 D->StringPool = new cxstring::CXStringPool();
Craig Topper69186e72014-06-08 08:38:04 +000082 D->Diagnostics = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +000083 D->OverridenCursorsPool = createOverridenCXCursorsPool();
Craig Topper69186e72014-06-08 08:38:04 +000084 D->CommentToXML = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +000085 return D;
86}
87
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +000088bool cxtu::isASTReadError(ASTUnit *AU) {
89 for (ASTUnit::stored_diag_iterator D = AU->stored_diag_begin(),
90 DEnd = AU->stored_diag_end();
91 D != DEnd; ++D) {
92 if (D->getLevel() >= DiagnosticsEngine::Error &&
93 DiagnosticIDs::getCategoryNumberForDiag(D->getID()) ==
94 diag::DiagCat_AST_Deserialization_Issue)
95 return true;
96 }
97 return false;
98}
99
Guy Benyei11169dd2012-12-18 14:30:41 +0000100cxtu::CXTUOwner::~CXTUOwner() {
101 if (TU)
102 clang_disposeTranslationUnit(TU);
103}
104
105/// \brief Compare two source ranges to determine their relative position in
106/// the translation unit.
107static RangeComparisonResult RangeCompare(SourceManager &SM,
108 SourceRange R1,
109 SourceRange R2) {
110 assert(R1.isValid() && "First range is invalid?");
111 assert(R2.isValid() && "Second range is invalid?");
112 if (R1.getEnd() != R2.getBegin() &&
113 SM.isBeforeInTranslationUnit(R1.getEnd(), R2.getBegin()))
114 return RangeBefore;
115 if (R2.getEnd() != R1.getBegin() &&
116 SM.isBeforeInTranslationUnit(R2.getEnd(), R1.getBegin()))
117 return RangeAfter;
118 return RangeOverlap;
119}
120
121/// \brief Determine if a source location falls within, before, or after a
122/// a given source range.
123static RangeComparisonResult LocationCompare(SourceManager &SM,
124 SourceLocation L, SourceRange R) {
125 assert(R.isValid() && "First range is invalid?");
126 assert(L.isValid() && "Second range is invalid?");
127 if (L == R.getBegin() || L == R.getEnd())
128 return RangeOverlap;
129 if (SM.isBeforeInTranslationUnit(L, R.getBegin()))
130 return RangeBefore;
131 if (SM.isBeforeInTranslationUnit(R.getEnd(), L))
132 return RangeAfter;
133 return RangeOverlap;
134}
135
136/// \brief Translate a Clang source range into a CIndex source range.
137///
138/// Clang internally represents ranges where the end location points to the
139/// start of the token at the end. However, for external clients it is more
140/// useful to have a CXSourceRange be a proper half-open interval. This routine
141/// does the appropriate translation.
142CXSourceRange cxloc::translateSourceRange(const SourceManager &SM,
143 const LangOptions &LangOpts,
144 const CharSourceRange &R) {
145 // We want the last character in this location, so we will adjust the
146 // location accordingly.
147 SourceLocation EndLoc = R.getEnd();
148 if (EndLoc.isValid() && EndLoc.isMacroID() && !SM.isMacroArgExpansion(EndLoc))
149 EndLoc = SM.getExpansionRange(EndLoc).second;
Yaron Keren8b563662015-10-03 10:46:20 +0000150 if (R.isTokenRange() && EndLoc.isValid()) {
Guy Benyei11169dd2012-12-18 14:30:41 +0000151 unsigned Length = Lexer::MeasureTokenLength(SM.getSpellingLoc(EndLoc),
152 SM, LangOpts);
153 EndLoc = EndLoc.getLocWithOffset(Length);
154 }
155
Bill Wendlingeade3622013-01-23 08:25:41 +0000156 CXSourceRange Result = {
Dmitri Gribenkof9304482013-01-23 15:56:07 +0000157 { &SM, &LangOpts },
Bill Wendlingeade3622013-01-23 08:25:41 +0000158 R.getBegin().getRawEncoding(),
159 EndLoc.getRawEncoding()
160 };
Guy Benyei11169dd2012-12-18 14:30:41 +0000161 return Result;
162}
163
164//===----------------------------------------------------------------------===//
165// Cursor visitor.
166//===----------------------------------------------------------------------===//
167
168static SourceRange getRawCursorExtent(CXCursor C);
169static SourceRange getFullCursorExtent(CXCursor C, SourceManager &SrcMgr);
170
171
172RangeComparisonResult CursorVisitor::CompareRegionOfInterest(SourceRange R) {
173 return RangeCompare(AU->getSourceManager(), R, RegionOfInterest);
174}
175
176/// \brief Visit the given cursor and, if requested by the visitor,
177/// its children.
178///
179/// \param Cursor the cursor to visit.
180///
181/// \param CheckedRegionOfInterest if true, then the caller already checked
182/// that this cursor is within the region of interest.
183///
184/// \returns true if the visitation should be aborted, false if it
185/// should continue.
186bool CursorVisitor::Visit(CXCursor Cursor, bool CheckedRegionOfInterest) {
187 if (clang_isInvalid(Cursor.kind))
188 return false;
189
190 if (clang_isDeclaration(Cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +0000191 const Decl *D = getCursorDecl(Cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +0000192 if (!D) {
193 assert(0 && "Invalid declaration cursor");
194 return true; // abort.
195 }
196
197 // Ignore implicit declarations, unless it's an objc method because
198 // currently we should report implicit methods for properties when indexing.
199 if (D->isImplicit() && !isa<ObjCMethodDecl>(D))
200 return false;
201 }
202
203 // If we have a range of interest, and this cursor doesn't intersect with it,
204 // we're done.
205 if (RegionOfInterest.isValid() && !CheckedRegionOfInterest) {
206 SourceRange Range = getRawCursorExtent(Cursor);
207 if (Range.isInvalid() || CompareRegionOfInterest(Range))
208 return false;
209 }
210
211 switch (Visitor(Cursor, Parent, ClientData)) {
212 case CXChildVisit_Break:
213 return true;
214
215 case CXChildVisit_Continue:
216 return false;
217
218 case CXChildVisit_Recurse: {
219 bool ret = VisitChildren(Cursor);
220 if (PostChildrenVisitor)
221 if (PostChildrenVisitor(Cursor, ClientData))
222 return true;
223 return ret;
224 }
225 }
226
227 llvm_unreachable("Invalid CXChildVisitResult!");
228}
229
230static bool visitPreprocessedEntitiesInRange(SourceRange R,
231 PreprocessingRecord &PPRec,
232 CursorVisitor &Visitor) {
233 SourceManager &SM = Visitor.getASTUnit()->getSourceManager();
234 FileID FID;
235
236 if (!Visitor.shouldVisitIncludedEntities()) {
237 // If the begin/end of the range lie in the same FileID, do the optimization
238 // where we skip preprocessed entities that do not come from the same FileID.
239 FID = SM.getFileID(SM.getFileLoc(R.getBegin()));
240 if (FID != SM.getFileID(SM.getFileLoc(R.getEnd())))
241 FID = FileID();
242 }
243
Benjamin Kramerb4ef6682015-02-06 17:25:10 +0000244 const auto &Entities = PPRec.getPreprocessedEntitiesInRange(R);
245 return Visitor.visitPreprocessedEntities(Entities.begin(), Entities.end(),
Guy Benyei11169dd2012-12-18 14:30:41 +0000246 PPRec, FID);
247}
248
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000249bool CursorVisitor::visitFileRegion() {
Guy Benyei11169dd2012-12-18 14:30:41 +0000250 if (RegionOfInterest.isInvalid())
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000251 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000252
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +0000253 ASTUnit *Unit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +0000254 SourceManager &SM = Unit->getSourceManager();
255
256 std::pair<FileID, unsigned>
257 Begin = SM.getDecomposedLoc(SM.getFileLoc(RegionOfInterest.getBegin())),
258 End = SM.getDecomposedLoc(SM.getFileLoc(RegionOfInterest.getEnd()));
259
260 if (End.first != Begin.first) {
261 // If the end does not reside in the same file, try to recover by
262 // picking the end of the file of begin location.
263 End.first = Begin.first;
264 End.second = SM.getFileIDSize(Begin.first);
265 }
266
267 assert(Begin.first == End.first);
268 if (Begin.second > End.second)
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000269 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000270
271 FileID File = Begin.first;
272 unsigned Offset = Begin.second;
273 unsigned Length = End.second - Begin.second;
274
275 if (!VisitDeclsOnly && !VisitPreprocessorLast)
276 if (visitPreprocessedEntitiesInRegion())
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000277 return true; // visitation break.
Guy Benyei11169dd2012-12-18 14:30:41 +0000278
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000279 if (visitDeclsFromFileRegion(File, Offset, Length))
280 return true; // visitation break.
Guy Benyei11169dd2012-12-18 14:30:41 +0000281
282 if (!VisitDeclsOnly && VisitPreprocessorLast)
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000283 return visitPreprocessedEntitiesInRegion();
284
285 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000286}
287
288static bool isInLexicalContext(Decl *D, DeclContext *DC) {
289 if (!DC)
290 return false;
291
292 for (DeclContext *DeclDC = D->getLexicalDeclContext();
293 DeclDC; DeclDC = DeclDC->getLexicalParent()) {
294 if (DeclDC == DC)
295 return true;
296 }
297 return false;
298}
299
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000300bool CursorVisitor::visitDeclsFromFileRegion(FileID File,
Guy Benyei11169dd2012-12-18 14:30:41 +0000301 unsigned Offset, unsigned Length) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +0000302 ASTUnit *Unit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +0000303 SourceManager &SM = Unit->getSourceManager();
304 SourceRange Range = RegionOfInterest;
305
306 SmallVector<Decl *, 16> Decls;
307 Unit->findFileRegionDecls(File, Offset, Length, Decls);
308
309 // If we didn't find any file level decls for the file, try looking at the
310 // file that it was included from.
311 while (Decls.empty() || Decls.front()->isTopLevelDeclInObjCContainer()) {
312 bool Invalid = false;
313 const SrcMgr::SLocEntry &SLEntry = SM.getSLocEntry(File, &Invalid);
314 if (Invalid)
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000315 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000316
317 SourceLocation Outer;
318 if (SLEntry.isFile())
319 Outer = SLEntry.getFile().getIncludeLoc();
320 else
321 Outer = SLEntry.getExpansion().getExpansionLocStart();
322 if (Outer.isInvalid())
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000323 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000324
Benjamin Kramer867ea1d2014-03-02 13:01:17 +0000325 std::tie(File, Offset) = SM.getDecomposedExpansionLoc(Outer);
Guy Benyei11169dd2012-12-18 14:30:41 +0000326 Length = 0;
327 Unit->findFileRegionDecls(File, Offset, Length, Decls);
328 }
329
330 assert(!Decls.empty());
331
332 bool VisitedAtLeastOnce = false;
Craig Topper69186e72014-06-08 08:38:04 +0000333 DeclContext *CurDC = nullptr;
Craig Topper2341c0d2013-07-04 03:08:24 +0000334 SmallVectorImpl<Decl *>::iterator DIt = Decls.begin();
335 for (SmallVectorImpl<Decl *>::iterator DE = Decls.end(); DIt != DE; ++DIt) {
Guy Benyei11169dd2012-12-18 14:30:41 +0000336 Decl *D = *DIt;
337 if (D->getSourceRange().isInvalid())
338 continue;
339
340 if (isInLexicalContext(D, CurDC))
341 continue;
342
343 CurDC = dyn_cast<DeclContext>(D);
344
345 if (TagDecl *TD = dyn_cast<TagDecl>(D))
346 if (!TD->isFreeStanding())
347 continue;
348
349 RangeComparisonResult CompRes = RangeCompare(SM, D->getSourceRange(),Range);
350 if (CompRes == RangeBefore)
351 continue;
352 if (CompRes == RangeAfter)
353 break;
354
355 assert(CompRes == RangeOverlap);
356 VisitedAtLeastOnce = true;
357
358 if (isa<ObjCContainerDecl>(D)) {
359 FileDI_current = &DIt;
360 FileDE_current = DE;
361 } else {
Craig Topper69186e72014-06-08 08:38:04 +0000362 FileDI_current = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +0000363 }
364
365 if (Visit(MakeCXCursor(D, TU, Range), /*CheckedRegionOfInterest=*/true))
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000366 return true; // visitation break.
Guy Benyei11169dd2012-12-18 14:30:41 +0000367 }
368
369 if (VisitedAtLeastOnce)
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000370 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000371
372 // No Decls overlapped with the range. Move up the lexical context until there
373 // is a context that contains the range or we reach the translation unit
374 // level.
375 DeclContext *DC = DIt == Decls.begin() ? (*DIt)->getLexicalDeclContext()
376 : (*(DIt-1))->getLexicalDeclContext();
377
378 while (DC && !DC->isTranslationUnit()) {
379 Decl *D = cast<Decl>(DC);
380 SourceRange CurDeclRange = D->getSourceRange();
381 if (CurDeclRange.isInvalid())
382 break;
383
384 if (RangeCompare(SM, CurDeclRange, Range) == RangeOverlap) {
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000385 if (Visit(MakeCXCursor(D, TU, Range), /*CheckedRegionOfInterest=*/true))
386 return true; // visitation break.
Guy Benyei11169dd2012-12-18 14:30:41 +0000387 }
388
389 DC = D->getLexicalDeclContext();
390 }
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000391
392 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000393}
394
395bool CursorVisitor::visitPreprocessedEntitiesInRegion() {
396 if (!AU->getPreprocessor().getPreprocessingRecord())
397 return false;
398
399 PreprocessingRecord &PPRec
400 = *AU->getPreprocessor().getPreprocessingRecord();
401 SourceManager &SM = AU->getSourceManager();
402
403 if (RegionOfInterest.isValid()) {
404 SourceRange MappedRange = AU->mapRangeToPreamble(RegionOfInterest);
405 SourceLocation B = MappedRange.getBegin();
406 SourceLocation E = MappedRange.getEnd();
407
408 if (AU->isInPreambleFileID(B)) {
409 if (SM.isLoadedSourceLocation(E))
410 return visitPreprocessedEntitiesInRange(SourceRange(B, E),
411 PPRec, *this);
412
413 // Beginning of range lies in the preamble but it also extends beyond
414 // it into the main file. Split the range into 2 parts, one covering
415 // the preamble and another covering the main file. This allows subsequent
416 // calls to visitPreprocessedEntitiesInRange to accept a source range that
417 // lies in the same FileID, allowing it to skip preprocessed entities that
418 // do not come from the same FileID.
419 bool breaked =
420 visitPreprocessedEntitiesInRange(
421 SourceRange(B, AU->getEndOfPreambleFileID()),
422 PPRec, *this);
423 if (breaked) return true;
424 return visitPreprocessedEntitiesInRange(
425 SourceRange(AU->getStartOfMainFileID(), E),
426 PPRec, *this);
427 }
428
429 return visitPreprocessedEntitiesInRange(SourceRange(B, E), PPRec, *this);
430 }
431
432 bool OnlyLocalDecls
433 = !AU->isMainFileAST() && AU->getOnlyLocalDecls();
434
435 if (OnlyLocalDecls)
436 return visitPreprocessedEntities(PPRec.local_begin(), PPRec.local_end(),
437 PPRec);
438
439 return visitPreprocessedEntities(PPRec.begin(), PPRec.end(), PPRec);
440}
441
442template<typename InputIterator>
443bool CursorVisitor::visitPreprocessedEntities(InputIterator First,
444 InputIterator Last,
445 PreprocessingRecord &PPRec,
446 FileID FID) {
447 for (; First != Last; ++First) {
448 if (!FID.isInvalid() && !PPRec.isEntityInFileID(First, FID))
449 continue;
450
451 PreprocessedEntity *PPE = *First;
Argyrios Kyrtzidis1030f262013-05-07 20:37:17 +0000452 if (!PPE)
453 continue;
454
Guy Benyei11169dd2012-12-18 14:30:41 +0000455 if (MacroExpansion *ME = dyn_cast<MacroExpansion>(PPE)) {
456 if (Visit(MakeMacroExpansionCursor(ME, TU)))
457 return true;
Richard Smith66a81862015-05-04 02:25:31 +0000458
Guy Benyei11169dd2012-12-18 14:30:41 +0000459 continue;
460 }
Richard Smith66a81862015-05-04 02:25:31 +0000461
462 if (MacroDefinitionRecord *MD = dyn_cast<MacroDefinitionRecord>(PPE)) {
Guy Benyei11169dd2012-12-18 14:30:41 +0000463 if (Visit(MakeMacroDefinitionCursor(MD, TU)))
464 return true;
Richard Smith66a81862015-05-04 02:25:31 +0000465
Guy Benyei11169dd2012-12-18 14:30:41 +0000466 continue;
467 }
468
469 if (InclusionDirective *ID = dyn_cast<InclusionDirective>(PPE)) {
470 if (Visit(MakeInclusionDirectiveCursor(ID, TU)))
471 return true;
472
473 continue;
474 }
475 }
476
477 return false;
478}
479
480/// \brief Visit the children of the given cursor.
481///
482/// \returns true if the visitation should be aborted, false if it
483/// should continue.
484bool CursorVisitor::VisitChildren(CXCursor Cursor) {
485 if (clang_isReference(Cursor.kind) &&
486 Cursor.kind != CXCursor_CXXBaseSpecifier) {
487 // By definition, references have no children.
488 return false;
489 }
490
491 // Set the Parent field to Cursor, then back to its old value once we're
492 // done.
493 SetParentRAII SetParent(Parent, StmtParent, Cursor);
494
495 if (clang_isDeclaration(Cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +0000496 Decl *D = const_cast<Decl *>(getCursorDecl(Cursor));
Guy Benyei11169dd2012-12-18 14:30:41 +0000497 if (!D)
498 return false;
499
500 return VisitAttributes(D) || Visit(D);
501 }
502
503 if (clang_isStatement(Cursor.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +0000504 if (const Stmt *S = getCursorStmt(Cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +0000505 return Visit(S);
506
507 return false;
508 }
509
510 if (clang_isExpression(Cursor.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +0000511 if (const Expr *E = getCursorExpr(Cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +0000512 return Visit(E);
513
514 return false;
515 }
516
517 if (clang_isTranslationUnit(Cursor.kind)) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +0000518 CXTranslationUnit TU = getCursorTU(Cursor);
519 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +0000520
521 int VisitOrder[2] = { VisitPreprocessorLast, !VisitPreprocessorLast };
522 for (unsigned I = 0; I != 2; ++I) {
523 if (VisitOrder[I]) {
524 if (!CXXUnit->isMainFileAST() && CXXUnit->getOnlyLocalDecls() &&
525 RegionOfInterest.isInvalid()) {
526 for (ASTUnit::top_level_iterator TL = CXXUnit->top_level_begin(),
527 TLEnd = CXXUnit->top_level_end();
528 TL != TLEnd; ++TL) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +0000529 if (Visit(MakeCXCursor(*TL, TU, RegionOfInterest), true))
Guy Benyei11169dd2012-12-18 14:30:41 +0000530 return true;
531 }
532 } else if (VisitDeclContext(
533 CXXUnit->getASTContext().getTranslationUnitDecl()))
534 return true;
535 continue;
536 }
537
538 // Walk the preprocessing record.
539 if (CXXUnit->getPreprocessor().getPreprocessingRecord())
540 visitPreprocessedEntitiesInRegion();
541 }
542
543 return false;
544 }
545
546 if (Cursor.kind == CXCursor_CXXBaseSpecifier) {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +0000547 if (const CXXBaseSpecifier *Base = getCursorCXXBaseSpecifier(Cursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +0000548 if (TypeSourceInfo *BaseTSInfo = Base->getTypeSourceInfo()) {
549 return Visit(BaseTSInfo->getTypeLoc());
550 }
551 }
552 }
553
554 if (Cursor.kind == CXCursor_IBOutletCollectionAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +0000555 const IBOutletCollectionAttr *A =
Guy Benyei11169dd2012-12-18 14:30:41 +0000556 cast<IBOutletCollectionAttr>(cxcursor::getCursorAttr(Cursor));
Richard Smithb1f9a282013-10-31 01:56:18 +0000557 if (const ObjCObjectType *ObjT = A->getInterface()->getAs<ObjCObjectType>())
Richard Smithb87c4652013-10-31 21:23:20 +0000558 return Visit(cxcursor::MakeCursorObjCClassRef(
559 ObjT->getInterface(),
560 A->getInterfaceLoc()->getTypeLoc().getLocStart(), TU));
Guy Benyei11169dd2012-12-18 14:30:41 +0000561 }
562
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +0000563 // If pointing inside a macro definition, check if the token is an identifier
564 // that was ever defined as a macro. In such a case, create a "pseudo" macro
565 // expansion cursor for that token.
566 SourceLocation BeginLoc = RegionOfInterest.getBegin();
567 if (Cursor.kind == CXCursor_MacroDefinition &&
568 BeginLoc == RegionOfInterest.getEnd()) {
569 SourceLocation Loc = AU->mapLocationToPreamble(BeginLoc);
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +0000570 const MacroInfo *MI =
571 getMacroInfo(cxcursor::getCursorMacroDefinition(Cursor), TU);
Richard Smith66a81862015-05-04 02:25:31 +0000572 if (MacroDefinitionRecord *MacroDef =
573 checkForMacroInMacroDefinition(MI, Loc, TU))
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +0000574 return Visit(cxcursor::MakeMacroExpansionCursor(MacroDef, BeginLoc, TU));
575 }
576
Guy Benyei11169dd2012-12-18 14:30:41 +0000577 // Nothing to visit at the moment.
578 return false;
579}
580
581bool CursorVisitor::VisitBlockDecl(BlockDecl *B) {
582 if (TypeSourceInfo *TSInfo = B->getSignatureAsWritten())
583 if (Visit(TSInfo->getTypeLoc()))
584 return true;
585
586 if (Stmt *Body = B->getBody())
587 return Visit(MakeCXCursor(Body, StmtParent, TU, RegionOfInterest));
588
589 return false;
590}
591
Ted Kremenek03325582013-02-21 01:29:01 +0000592Optional<bool> CursorVisitor::shouldVisitCursor(CXCursor Cursor) {
Guy Benyei11169dd2012-12-18 14:30:41 +0000593 if (RegionOfInterest.isValid()) {
594 SourceRange Range = getFullCursorExtent(Cursor, AU->getSourceManager());
595 if (Range.isInvalid())
David Blaikie7a30dc52013-02-21 01:47:18 +0000596 return None;
Guy Benyei11169dd2012-12-18 14:30:41 +0000597
598 switch (CompareRegionOfInterest(Range)) {
599 case RangeBefore:
600 // This declaration comes before the region of interest; skip it.
David Blaikie7a30dc52013-02-21 01:47:18 +0000601 return None;
Guy Benyei11169dd2012-12-18 14:30:41 +0000602
603 case RangeAfter:
604 // This declaration comes after the region of interest; we're done.
605 return false;
606
607 case RangeOverlap:
608 // This declaration overlaps the region of interest; visit it.
609 break;
610 }
611 }
612 return true;
613}
614
615bool CursorVisitor::VisitDeclContext(DeclContext *DC) {
616 DeclContext::decl_iterator I = DC->decls_begin(), E = DC->decls_end();
617
618 // FIXME: Eventually remove. This part of a hack to support proper
619 // iteration over all Decls contained lexically within an ObjC container.
620 SaveAndRestore<DeclContext::decl_iterator*> DI_saved(DI_current, &I);
621 SaveAndRestore<DeclContext::decl_iterator> DE_saved(DE_current, E);
622
623 for ( ; I != E; ++I) {
624 Decl *D = *I;
625 if (D->getLexicalDeclContext() != DC)
626 continue;
627 CXCursor Cursor = MakeCXCursor(D, TU, RegionOfInterest);
628
629 // Ignore synthesized ivars here, otherwise if we have something like:
630 // @synthesize prop = _prop;
631 // and '_prop' is not declared, we will encounter a '_prop' ivar before
632 // encountering the 'prop' synthesize declaration and we will think that
633 // we passed the region-of-interest.
634 if (ObjCIvarDecl *ivarD = dyn_cast<ObjCIvarDecl>(D)) {
635 if (ivarD->getSynthesize())
636 continue;
637 }
638
639 // FIXME: ObjCClassRef/ObjCProtocolRef for forward class/protocol
640 // declarations is a mismatch with the compiler semantics.
641 if (Cursor.kind == CXCursor_ObjCInterfaceDecl) {
642 ObjCInterfaceDecl *ID = cast<ObjCInterfaceDecl>(D);
643 if (!ID->isThisDeclarationADefinition())
644 Cursor = MakeCursorObjCClassRef(ID, ID->getLocation(), TU);
645
646 } else if (Cursor.kind == CXCursor_ObjCProtocolDecl) {
647 ObjCProtocolDecl *PD = cast<ObjCProtocolDecl>(D);
648 if (!PD->isThisDeclarationADefinition())
649 Cursor = MakeCursorObjCProtocolRef(PD, PD->getLocation(), TU);
650 }
651
Ted Kremenek03325582013-02-21 01:29:01 +0000652 const Optional<bool> &V = shouldVisitCursor(Cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +0000653 if (!V.hasValue())
654 continue;
655 if (!V.getValue())
656 return false;
657 if (Visit(Cursor, true))
658 return true;
659 }
660 return false;
661}
662
663bool CursorVisitor::VisitTranslationUnitDecl(TranslationUnitDecl *D) {
664 llvm_unreachable("Translation units are visited directly by Visit()");
665}
666
Sergey Kalinichev8f3b1872015-11-15 13:48:32 +0000667bool CursorVisitor::VisitTypeAliasTemplateDecl(TypeAliasTemplateDecl *D) {
668 if (VisitTemplateParameters(D->getTemplateParameters()))
669 return true;
670
671 return Visit(MakeCXCursor(D->getTemplatedDecl(), TU, RegionOfInterest));
672}
673
Guy Benyei11169dd2012-12-18 14:30:41 +0000674bool CursorVisitor::VisitTypeAliasDecl(TypeAliasDecl *D) {
675 if (TypeSourceInfo *TSInfo = D->getTypeSourceInfo())
676 return Visit(TSInfo->getTypeLoc());
677
678 return false;
679}
680
681bool CursorVisitor::VisitTypedefDecl(TypedefDecl *D) {
682 if (TypeSourceInfo *TSInfo = D->getTypeSourceInfo())
683 return Visit(TSInfo->getTypeLoc());
684
685 return false;
686}
687
688bool CursorVisitor::VisitTagDecl(TagDecl *D) {
689 return VisitDeclContext(D);
690}
691
692bool CursorVisitor::VisitClassTemplateSpecializationDecl(
693 ClassTemplateSpecializationDecl *D) {
694 bool ShouldVisitBody = false;
695 switch (D->getSpecializationKind()) {
696 case TSK_Undeclared:
697 case TSK_ImplicitInstantiation:
698 // Nothing to visit
699 return false;
700
701 case TSK_ExplicitInstantiationDeclaration:
702 case TSK_ExplicitInstantiationDefinition:
703 break;
704
705 case TSK_ExplicitSpecialization:
706 ShouldVisitBody = true;
707 break;
708 }
709
710 // Visit the template arguments used in the specialization.
711 if (TypeSourceInfo *SpecType = D->getTypeAsWritten()) {
712 TypeLoc TL = SpecType->getTypeLoc();
David Blaikie6adc78e2013-02-18 22:06:02 +0000713 if (TemplateSpecializationTypeLoc TSTLoc =
714 TL.getAs<TemplateSpecializationTypeLoc>()) {
715 for (unsigned I = 0, N = TSTLoc.getNumArgs(); I != N; ++I)
716 if (VisitTemplateArgumentLoc(TSTLoc.getArgLoc(I)))
Guy Benyei11169dd2012-12-18 14:30:41 +0000717 return true;
718 }
719 }
720
721 if (ShouldVisitBody && VisitCXXRecordDecl(D))
722 return true;
723
724 return false;
725}
726
727bool CursorVisitor::VisitClassTemplatePartialSpecializationDecl(
728 ClassTemplatePartialSpecializationDecl *D) {
729 // FIXME: Visit the "outer" template parameter lists on the TagDecl
730 // before visiting these template parameters.
731 if (VisitTemplateParameters(D->getTemplateParameters()))
732 return true;
733
734 // Visit the partial specialization arguments.
Enea Zaffanella6dbe1872013-08-10 07:24:53 +0000735 const ASTTemplateArgumentListInfo *Info = D->getTemplateArgsAsWritten();
736 const TemplateArgumentLoc *TemplateArgs = Info->getTemplateArgs();
737 for (unsigned I = 0, N = Info->NumTemplateArgs; I != N; ++I)
Guy Benyei11169dd2012-12-18 14:30:41 +0000738 if (VisitTemplateArgumentLoc(TemplateArgs[I]))
739 return true;
740
741 return VisitCXXRecordDecl(D);
742}
743
744bool CursorVisitor::VisitTemplateTypeParmDecl(TemplateTypeParmDecl *D) {
745 // Visit the default argument.
746 if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited())
747 if (TypeSourceInfo *DefArg = D->getDefaultArgumentInfo())
748 if (Visit(DefArg->getTypeLoc()))
749 return true;
750
751 return false;
752}
753
754bool CursorVisitor::VisitEnumConstantDecl(EnumConstantDecl *D) {
755 if (Expr *Init = D->getInitExpr())
756 return Visit(MakeCXCursor(Init, StmtParent, TU, RegionOfInterest));
757 return false;
758}
759
760bool CursorVisitor::VisitDeclaratorDecl(DeclaratorDecl *DD) {
Argyrios Kyrtzidis2ec76742013-04-05 21:04:10 +0000761 unsigned NumParamList = DD->getNumTemplateParameterLists();
762 for (unsigned i = 0; i < NumParamList; i++) {
763 TemplateParameterList* Params = DD->getTemplateParameterList(i);
764 if (VisitTemplateParameters(Params))
765 return true;
766 }
767
Guy Benyei11169dd2012-12-18 14:30:41 +0000768 if (TypeSourceInfo *TSInfo = DD->getTypeSourceInfo())
769 if (Visit(TSInfo->getTypeLoc()))
770 return true;
771
772 // Visit the nested-name-specifier, if present.
773 if (NestedNameSpecifierLoc QualifierLoc = DD->getQualifierLoc())
774 if (VisitNestedNameSpecifierLoc(QualifierLoc))
775 return true;
776
777 return false;
778}
779
Benjamin Kramer4cadf292014-03-07 21:51:58 +0000780/// \brief Compare two base or member initializers based on their source order.
781static int CompareCXXCtorInitializers(CXXCtorInitializer *const *X,
782 CXXCtorInitializer *const *Y) {
783 return (*X)->getSourceOrder() - (*Y)->getSourceOrder();
784}
785
Guy Benyei11169dd2012-12-18 14:30:41 +0000786bool CursorVisitor::VisitFunctionDecl(FunctionDecl *ND) {
Argyrios Kyrtzidis2ec76742013-04-05 21:04:10 +0000787 unsigned NumParamList = ND->getNumTemplateParameterLists();
788 for (unsigned i = 0; i < NumParamList; i++) {
789 TemplateParameterList* Params = ND->getTemplateParameterList(i);
790 if (VisitTemplateParameters(Params))
791 return true;
792 }
793
Guy Benyei11169dd2012-12-18 14:30:41 +0000794 if (TypeSourceInfo *TSInfo = ND->getTypeSourceInfo()) {
795 // Visit the function declaration's syntactic components in the order
796 // written. This requires a bit of work.
797 TypeLoc TL = TSInfo->getTypeLoc().IgnoreParens();
David Blaikie6adc78e2013-02-18 22:06:02 +0000798 FunctionTypeLoc FTL = TL.getAs<FunctionTypeLoc>();
Guy Benyei11169dd2012-12-18 14:30:41 +0000799
800 // If we have a function declared directly (without the use of a typedef),
801 // visit just the return type. Otherwise, just visit the function's type
802 // now.
Alp Toker42a16a62014-01-25 23:51:36 +0000803 if ((FTL && !isa<CXXConversionDecl>(ND) && Visit(FTL.getReturnLoc())) ||
Guy Benyei11169dd2012-12-18 14:30:41 +0000804 (!FTL && Visit(TL)))
805 return true;
806
807 // Visit the nested-name-specifier, if present.
808 if (NestedNameSpecifierLoc QualifierLoc = ND->getQualifierLoc())
809 if (VisitNestedNameSpecifierLoc(QualifierLoc))
810 return true;
811
812 // Visit the declaration name.
Argyrios Kyrtzidis4a4d2b42014-02-09 08:13:47 +0000813 if (!isa<CXXDestructorDecl>(ND))
814 if (VisitDeclarationNameInfo(ND->getNameInfo()))
815 return true;
Guy Benyei11169dd2012-12-18 14:30:41 +0000816
817 // FIXME: Visit explicitly-specified template arguments!
818
819 // Visit the function parameters, if we have a function type.
David Blaikie6adc78e2013-02-18 22:06:02 +0000820 if (FTL && VisitFunctionTypeLoc(FTL, true))
Guy Benyei11169dd2012-12-18 14:30:41 +0000821 return true;
822
Bill Wendling44426052012-12-20 19:22:21 +0000823 // FIXME: Attributes?
Guy Benyei11169dd2012-12-18 14:30:41 +0000824 }
825
826 if (ND->doesThisDeclarationHaveABody() && !ND->isLateTemplateParsed()) {
827 if (CXXConstructorDecl *Constructor = dyn_cast<CXXConstructorDecl>(ND)) {
828 // Find the initializers that were written in the source.
829 SmallVector<CXXCtorInitializer *, 4> WrittenInits;
Aaron Ballman0ad78302014-03-13 17:34:31 +0000830 for (auto *I : Constructor->inits()) {
831 if (!I->isWritten())
Guy Benyei11169dd2012-12-18 14:30:41 +0000832 continue;
833
Aaron Ballman0ad78302014-03-13 17:34:31 +0000834 WrittenInits.push_back(I);
Guy Benyei11169dd2012-12-18 14:30:41 +0000835 }
836
837 // Sort the initializers in source order
Benjamin Kramer4cadf292014-03-07 21:51:58 +0000838 llvm::array_pod_sort(WrittenInits.begin(), WrittenInits.end(),
839 &CompareCXXCtorInitializers);
840
Guy Benyei11169dd2012-12-18 14:30:41 +0000841 // Visit the initializers in source order
842 for (unsigned I = 0, N = WrittenInits.size(); I != N; ++I) {
843 CXXCtorInitializer *Init = WrittenInits[I];
844 if (Init->isAnyMemberInitializer()) {
845 if (Visit(MakeCursorMemberRef(Init->getAnyMember(),
846 Init->getMemberLocation(), TU)))
847 return true;
848 } else if (TypeSourceInfo *TInfo = Init->getTypeSourceInfo()) {
849 if (Visit(TInfo->getTypeLoc()))
850 return true;
851 }
852
853 // Visit the initializer value.
854 if (Expr *Initializer = Init->getInit())
855 if (Visit(MakeCXCursor(Initializer, ND, TU, RegionOfInterest)))
856 return true;
857 }
858 }
859
860 if (Visit(MakeCXCursor(ND->getBody(), StmtParent, TU, RegionOfInterest)))
861 return true;
862 }
863
864 return false;
865}
866
867bool CursorVisitor::VisitFieldDecl(FieldDecl *D) {
868 if (VisitDeclaratorDecl(D))
869 return true;
870
871 if (Expr *BitWidth = D->getBitWidth())
872 return Visit(MakeCXCursor(BitWidth, StmtParent, TU, RegionOfInterest));
873
874 return false;
875}
876
877bool CursorVisitor::VisitVarDecl(VarDecl *D) {
878 if (VisitDeclaratorDecl(D))
879 return true;
880
881 if (Expr *Init = D->getInit())
882 return Visit(MakeCXCursor(Init, StmtParent, TU, RegionOfInterest));
883
884 return false;
885}
886
887bool CursorVisitor::VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl *D) {
888 if (VisitDeclaratorDecl(D))
889 return true;
890
891 if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited())
892 if (Expr *DefArg = D->getDefaultArgument())
893 return Visit(MakeCXCursor(DefArg, StmtParent, TU, RegionOfInterest));
894
895 return false;
896}
897
898bool CursorVisitor::VisitFunctionTemplateDecl(FunctionTemplateDecl *D) {
899 // FIXME: Visit the "outer" template parameter lists on the FunctionDecl
900 // before visiting these template parameters.
901 if (VisitTemplateParameters(D->getTemplateParameters()))
902 return true;
903
904 return VisitFunctionDecl(D->getTemplatedDecl());
905}
906
907bool CursorVisitor::VisitClassTemplateDecl(ClassTemplateDecl *D) {
908 // FIXME: Visit the "outer" template parameter lists on the TagDecl
909 // before visiting these template parameters.
910 if (VisitTemplateParameters(D->getTemplateParameters()))
911 return true;
912
913 return VisitCXXRecordDecl(D->getTemplatedDecl());
914}
915
916bool CursorVisitor::VisitTemplateTemplateParmDecl(TemplateTemplateParmDecl *D) {
917 if (VisitTemplateParameters(D->getTemplateParameters()))
918 return true;
919
920 if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited() &&
921 VisitTemplateArgumentLoc(D->getDefaultArgument()))
922 return true;
923
924 return false;
925}
926
Douglas Gregor9bda6cf2015-07-07 03:58:14 +0000927bool CursorVisitor::VisitObjCTypeParamDecl(ObjCTypeParamDecl *D) {
928 // Visit the bound, if it's explicit.
929 if (D->hasExplicitBound()) {
930 if (auto TInfo = D->getTypeSourceInfo()) {
931 if (Visit(TInfo->getTypeLoc()))
932 return true;
933 }
934 }
935
936 return false;
937}
938
Guy Benyei11169dd2012-12-18 14:30:41 +0000939bool CursorVisitor::VisitObjCMethodDecl(ObjCMethodDecl *ND) {
Alp Toker314cc812014-01-25 16:55:45 +0000940 if (TypeSourceInfo *TSInfo = ND->getReturnTypeSourceInfo())
Guy Benyei11169dd2012-12-18 14:30:41 +0000941 if (Visit(TSInfo->getTypeLoc()))
942 return true;
943
Aaron Ballman43b68be2014-03-07 17:50:17 +0000944 for (const auto *P : ND->params()) {
945 if (Visit(MakeCXCursor(P, TU, RegionOfInterest)))
Guy Benyei11169dd2012-12-18 14:30:41 +0000946 return true;
947 }
948
949 if (ND->isThisDeclarationADefinition() &&
950 Visit(MakeCXCursor(ND->getBody(), StmtParent, TU, RegionOfInterest)))
951 return true;
952
953 return false;
954}
955
956template <typename DeclIt>
957static void addRangedDeclsInContainer(DeclIt *DI_current, DeclIt DE_current,
958 SourceManager &SM, SourceLocation EndLoc,
959 SmallVectorImpl<Decl *> &Decls) {
960 DeclIt next = *DI_current;
961 while (++next != DE_current) {
962 Decl *D_next = *next;
963 if (!D_next)
964 break;
965 SourceLocation L = D_next->getLocStart();
966 if (!L.isValid())
967 break;
968 if (SM.isBeforeInTranslationUnit(L, EndLoc)) {
969 *DI_current = next;
970 Decls.push_back(D_next);
971 continue;
972 }
973 break;
974 }
975}
976
Guy Benyei11169dd2012-12-18 14:30:41 +0000977bool CursorVisitor::VisitObjCContainerDecl(ObjCContainerDecl *D) {
978 // FIXME: Eventually convert back to just 'VisitDeclContext()'. Essentially
979 // an @implementation can lexically contain Decls that are not properly
980 // nested in the AST. When we identify such cases, we need to retrofit
981 // this nesting here.
982 if (!DI_current && !FileDI_current)
983 return VisitDeclContext(D);
984
985 // Scan the Decls that immediately come after the container
986 // in the current DeclContext. If any fall within the
987 // container's lexical region, stash them into a vector
988 // for later processing.
989 SmallVector<Decl *, 24> DeclsInContainer;
990 SourceLocation EndLoc = D->getSourceRange().getEnd();
991 SourceManager &SM = AU->getSourceManager();
992 if (EndLoc.isValid()) {
993 if (DI_current) {
994 addRangedDeclsInContainer(DI_current, DE_current, SM, EndLoc,
995 DeclsInContainer);
996 } else {
997 addRangedDeclsInContainer(FileDI_current, FileDE_current, SM, EndLoc,
998 DeclsInContainer);
999 }
1000 }
1001
1002 // The common case.
1003 if (DeclsInContainer.empty())
1004 return VisitDeclContext(D);
1005
1006 // Get all the Decls in the DeclContext, and sort them with the
1007 // additional ones we've collected. Then visit them.
Aaron Ballman629afae2014-03-07 19:56:05 +00001008 for (auto *SubDecl : D->decls()) {
1009 if (!SubDecl || SubDecl->getLexicalDeclContext() != D ||
1010 SubDecl->getLocStart().isInvalid())
Guy Benyei11169dd2012-12-18 14:30:41 +00001011 continue;
Aaron Ballman629afae2014-03-07 19:56:05 +00001012 DeclsInContainer.push_back(SubDecl);
Guy Benyei11169dd2012-12-18 14:30:41 +00001013 }
1014
1015 // Now sort the Decls so that they appear in lexical order.
1016 std::sort(DeclsInContainer.begin(), DeclsInContainer.end(),
Benjamin Kramerbbdd7642014-03-01 14:48:57 +00001017 [&SM](Decl *A, Decl *B) {
1018 SourceLocation L_A = A->getLocStart();
1019 SourceLocation L_B = B->getLocStart();
1020 assert(L_A.isValid() && L_B.isValid());
1021 return SM.isBeforeInTranslationUnit(L_A, L_B);
1022 });
Guy Benyei11169dd2012-12-18 14:30:41 +00001023
1024 // Now visit the decls.
1025 for (SmallVectorImpl<Decl*>::iterator I = DeclsInContainer.begin(),
1026 E = DeclsInContainer.end(); I != E; ++I) {
1027 CXCursor Cursor = MakeCXCursor(*I, TU, RegionOfInterest);
Ted Kremenek03325582013-02-21 01:29:01 +00001028 const Optional<bool> &V = shouldVisitCursor(Cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00001029 if (!V.hasValue())
1030 continue;
1031 if (!V.getValue())
1032 return false;
1033 if (Visit(Cursor, true))
1034 return true;
1035 }
1036 return false;
1037}
1038
1039bool CursorVisitor::VisitObjCCategoryDecl(ObjCCategoryDecl *ND) {
1040 if (Visit(MakeCursorObjCClassRef(ND->getClassInterface(), ND->getLocation(),
1041 TU)))
1042 return true;
1043
Douglas Gregore9d95f12015-07-07 03:57:35 +00001044 if (VisitObjCTypeParamList(ND->getTypeParamList()))
1045 return true;
1046
Guy Benyei11169dd2012-12-18 14:30:41 +00001047 ObjCCategoryDecl::protocol_loc_iterator PL = ND->protocol_loc_begin();
1048 for (ObjCCategoryDecl::protocol_iterator I = ND->protocol_begin(),
1049 E = ND->protocol_end(); I != E; ++I, ++PL)
1050 if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
1051 return true;
1052
1053 return VisitObjCContainerDecl(ND);
1054}
1055
1056bool CursorVisitor::VisitObjCProtocolDecl(ObjCProtocolDecl *PID) {
1057 if (!PID->isThisDeclarationADefinition())
1058 return Visit(MakeCursorObjCProtocolRef(PID, PID->getLocation(), TU));
1059
1060 ObjCProtocolDecl::protocol_loc_iterator PL = PID->protocol_loc_begin();
1061 for (ObjCProtocolDecl::protocol_iterator I = PID->protocol_begin(),
1062 E = PID->protocol_end(); I != E; ++I, ++PL)
1063 if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
1064 return true;
1065
1066 return VisitObjCContainerDecl(PID);
1067}
1068
1069bool CursorVisitor::VisitObjCPropertyDecl(ObjCPropertyDecl *PD) {
1070 if (PD->getTypeSourceInfo() && Visit(PD->getTypeSourceInfo()->getTypeLoc()))
1071 return true;
1072
1073 // FIXME: This implements a workaround with @property declarations also being
1074 // installed in the DeclContext for the @interface. Eventually this code
1075 // should be removed.
1076 ObjCCategoryDecl *CDecl = dyn_cast<ObjCCategoryDecl>(PD->getDeclContext());
1077 if (!CDecl || !CDecl->IsClassExtension())
1078 return false;
1079
1080 ObjCInterfaceDecl *ID = CDecl->getClassInterface();
1081 if (!ID)
1082 return false;
1083
1084 IdentifierInfo *PropertyId = PD->getIdentifier();
1085 ObjCPropertyDecl *prevDecl =
1086 ObjCPropertyDecl::findPropertyDecl(cast<DeclContext>(ID), PropertyId);
1087
1088 if (!prevDecl)
1089 return false;
1090
1091 // Visit synthesized methods since they will be skipped when visiting
1092 // the @interface.
1093 if (ObjCMethodDecl *MD = prevDecl->getGetterMethodDecl())
1094 if (MD->isPropertyAccessor() && MD->getLexicalDeclContext() == CDecl)
1095 if (Visit(MakeCXCursor(MD, TU, RegionOfInterest)))
1096 return true;
1097
1098 if (ObjCMethodDecl *MD = prevDecl->getSetterMethodDecl())
1099 if (MD->isPropertyAccessor() && MD->getLexicalDeclContext() == CDecl)
1100 if (Visit(MakeCXCursor(MD, TU, RegionOfInterest)))
1101 return true;
1102
1103 return false;
1104}
1105
Douglas Gregore9d95f12015-07-07 03:57:35 +00001106bool CursorVisitor::VisitObjCTypeParamList(ObjCTypeParamList *typeParamList) {
1107 if (!typeParamList)
1108 return false;
1109
1110 for (auto *typeParam : *typeParamList) {
1111 // Visit the type parameter.
1112 if (Visit(MakeCXCursor(typeParam, TU, RegionOfInterest)))
1113 return true;
Douglas Gregore9d95f12015-07-07 03:57:35 +00001114 }
1115
1116 return false;
1117}
1118
Guy Benyei11169dd2012-12-18 14:30:41 +00001119bool CursorVisitor::VisitObjCInterfaceDecl(ObjCInterfaceDecl *D) {
1120 if (!D->isThisDeclarationADefinition()) {
1121 // Forward declaration is treated like a reference.
1122 return Visit(MakeCursorObjCClassRef(D, D->getLocation(), TU));
1123 }
1124
Douglas Gregore9d95f12015-07-07 03:57:35 +00001125 // Objective-C type parameters.
1126 if (VisitObjCTypeParamList(D->getTypeParamListAsWritten()))
1127 return true;
1128
Guy Benyei11169dd2012-12-18 14:30:41 +00001129 // Issue callbacks for super class.
1130 if (D->getSuperClass() &&
1131 Visit(MakeCursorObjCSuperClassRef(D->getSuperClass(),
1132 D->getSuperClassLoc(),
1133 TU)))
1134 return true;
1135
Douglas Gregore9d95f12015-07-07 03:57:35 +00001136 if (TypeSourceInfo *SuperClassTInfo = D->getSuperClassTInfo())
1137 if (Visit(SuperClassTInfo->getTypeLoc()))
1138 return true;
1139
Guy Benyei11169dd2012-12-18 14:30:41 +00001140 ObjCInterfaceDecl::protocol_loc_iterator PL = D->protocol_loc_begin();
1141 for (ObjCInterfaceDecl::protocol_iterator I = D->protocol_begin(),
1142 E = D->protocol_end(); I != E; ++I, ++PL)
1143 if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
1144 return true;
1145
1146 return VisitObjCContainerDecl(D);
1147}
1148
1149bool CursorVisitor::VisitObjCImplDecl(ObjCImplDecl *D) {
1150 return VisitObjCContainerDecl(D);
1151}
1152
1153bool CursorVisitor::VisitObjCCategoryImplDecl(ObjCCategoryImplDecl *D) {
1154 // 'ID' could be null when dealing with invalid code.
1155 if (ObjCInterfaceDecl *ID = D->getClassInterface())
1156 if (Visit(MakeCursorObjCClassRef(ID, D->getLocation(), TU)))
1157 return true;
1158
1159 return VisitObjCImplDecl(D);
1160}
1161
1162bool CursorVisitor::VisitObjCImplementationDecl(ObjCImplementationDecl *D) {
1163#if 0
1164 // Issue callbacks for super class.
1165 // FIXME: No source location information!
1166 if (D->getSuperClass() &&
1167 Visit(MakeCursorObjCSuperClassRef(D->getSuperClass(),
1168 D->getSuperClassLoc(),
1169 TU)))
1170 return true;
1171#endif
1172
1173 return VisitObjCImplDecl(D);
1174}
1175
1176bool CursorVisitor::VisitObjCPropertyImplDecl(ObjCPropertyImplDecl *PD) {
1177 if (ObjCIvarDecl *Ivar = PD->getPropertyIvarDecl())
1178 if (PD->isIvarNameSpecified())
1179 return Visit(MakeCursorMemberRef(Ivar, PD->getPropertyIvarDeclLoc(), TU));
1180
1181 return false;
1182}
1183
1184bool CursorVisitor::VisitNamespaceDecl(NamespaceDecl *D) {
1185 return VisitDeclContext(D);
1186}
1187
1188bool CursorVisitor::VisitNamespaceAliasDecl(NamespaceAliasDecl *D) {
1189 // Visit nested-name-specifier.
1190 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1191 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1192 return true;
1193
1194 return Visit(MakeCursorNamespaceRef(D->getAliasedNamespace(),
1195 D->getTargetNameLoc(), TU));
1196}
1197
1198bool CursorVisitor::VisitUsingDecl(UsingDecl *D) {
1199 // Visit nested-name-specifier.
1200 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc()) {
1201 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1202 return true;
1203 }
1204
1205 if (Visit(MakeCursorOverloadedDeclRef(D, D->getLocation(), TU)))
1206 return true;
1207
1208 return VisitDeclarationNameInfo(D->getNameInfo());
1209}
1210
1211bool CursorVisitor::VisitUsingDirectiveDecl(UsingDirectiveDecl *D) {
1212 // Visit nested-name-specifier.
1213 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1214 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1215 return true;
1216
1217 return Visit(MakeCursorNamespaceRef(D->getNominatedNamespaceAsWritten(),
1218 D->getIdentLocation(), TU));
1219}
1220
1221bool CursorVisitor::VisitUnresolvedUsingValueDecl(UnresolvedUsingValueDecl *D) {
1222 // Visit nested-name-specifier.
1223 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc()) {
1224 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1225 return true;
1226 }
1227
1228 return VisitDeclarationNameInfo(D->getNameInfo());
1229}
1230
1231bool CursorVisitor::VisitUnresolvedUsingTypenameDecl(
1232 UnresolvedUsingTypenameDecl *D) {
1233 // Visit nested-name-specifier.
1234 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1235 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1236 return true;
1237
1238 return false;
1239}
1240
1241bool CursorVisitor::VisitDeclarationNameInfo(DeclarationNameInfo Name) {
1242 switch (Name.getName().getNameKind()) {
1243 case clang::DeclarationName::Identifier:
1244 case clang::DeclarationName::CXXLiteralOperatorName:
1245 case clang::DeclarationName::CXXOperatorName:
1246 case clang::DeclarationName::CXXUsingDirective:
1247 return false;
1248
1249 case clang::DeclarationName::CXXConstructorName:
1250 case clang::DeclarationName::CXXDestructorName:
1251 case clang::DeclarationName::CXXConversionFunctionName:
1252 if (TypeSourceInfo *TSInfo = Name.getNamedTypeInfo())
1253 return Visit(TSInfo->getTypeLoc());
1254 return false;
1255
1256 case clang::DeclarationName::ObjCZeroArgSelector:
1257 case clang::DeclarationName::ObjCOneArgSelector:
1258 case clang::DeclarationName::ObjCMultiArgSelector:
1259 // FIXME: Per-identifier location info?
1260 return false;
1261 }
1262
1263 llvm_unreachable("Invalid DeclarationName::Kind!");
1264}
1265
1266bool CursorVisitor::VisitNestedNameSpecifier(NestedNameSpecifier *NNS,
1267 SourceRange Range) {
1268 // FIXME: This whole routine is a hack to work around the lack of proper
1269 // source information in nested-name-specifiers (PR5791). Since we do have
1270 // a beginning source location, we can visit the first component of the
1271 // nested-name-specifier, if it's a single-token component.
1272 if (!NNS)
1273 return false;
1274
1275 // Get the first component in the nested-name-specifier.
1276 while (NestedNameSpecifier *Prefix = NNS->getPrefix())
1277 NNS = Prefix;
1278
1279 switch (NNS->getKind()) {
1280 case NestedNameSpecifier::Namespace:
1281 return Visit(MakeCursorNamespaceRef(NNS->getAsNamespace(), Range.getBegin(),
1282 TU));
1283
1284 case NestedNameSpecifier::NamespaceAlias:
1285 return Visit(MakeCursorNamespaceRef(NNS->getAsNamespaceAlias(),
1286 Range.getBegin(), TU));
1287
1288 case NestedNameSpecifier::TypeSpec: {
1289 // If the type has a form where we know that the beginning of the source
1290 // range matches up with a reference cursor. Visit the appropriate reference
1291 // cursor.
1292 const Type *T = NNS->getAsType();
1293 if (const TypedefType *Typedef = dyn_cast<TypedefType>(T))
1294 return Visit(MakeCursorTypeRef(Typedef->getDecl(), Range.getBegin(), TU));
1295 if (const TagType *Tag = dyn_cast<TagType>(T))
1296 return Visit(MakeCursorTypeRef(Tag->getDecl(), Range.getBegin(), TU));
1297 if (const TemplateSpecializationType *TST
1298 = dyn_cast<TemplateSpecializationType>(T))
1299 return VisitTemplateName(TST->getTemplateName(), Range.getBegin());
1300 break;
1301 }
1302
1303 case NestedNameSpecifier::TypeSpecWithTemplate:
1304 case NestedNameSpecifier::Global:
1305 case NestedNameSpecifier::Identifier:
Nikola Smiljanic67860242014-09-26 00:28:20 +00001306 case NestedNameSpecifier::Super:
Guy Benyei11169dd2012-12-18 14:30:41 +00001307 break;
1308 }
1309
1310 return false;
1311}
1312
1313bool
1314CursorVisitor::VisitNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier) {
1315 SmallVector<NestedNameSpecifierLoc, 4> Qualifiers;
1316 for (; Qualifier; Qualifier = Qualifier.getPrefix())
1317 Qualifiers.push_back(Qualifier);
1318
1319 while (!Qualifiers.empty()) {
1320 NestedNameSpecifierLoc Q = Qualifiers.pop_back_val();
1321 NestedNameSpecifier *NNS = Q.getNestedNameSpecifier();
1322 switch (NNS->getKind()) {
1323 case NestedNameSpecifier::Namespace:
1324 if (Visit(MakeCursorNamespaceRef(NNS->getAsNamespace(),
1325 Q.getLocalBeginLoc(),
1326 TU)))
1327 return true;
1328
1329 break;
1330
1331 case NestedNameSpecifier::NamespaceAlias:
1332 if (Visit(MakeCursorNamespaceRef(NNS->getAsNamespaceAlias(),
1333 Q.getLocalBeginLoc(),
1334 TU)))
1335 return true;
1336
1337 break;
1338
1339 case NestedNameSpecifier::TypeSpec:
1340 case NestedNameSpecifier::TypeSpecWithTemplate:
1341 if (Visit(Q.getTypeLoc()))
1342 return true;
1343
1344 break;
1345
1346 case NestedNameSpecifier::Global:
1347 case NestedNameSpecifier::Identifier:
Nikola Smiljanic67860242014-09-26 00:28:20 +00001348 case NestedNameSpecifier::Super:
Guy Benyei11169dd2012-12-18 14:30:41 +00001349 break;
1350 }
1351 }
1352
1353 return false;
1354}
1355
1356bool CursorVisitor::VisitTemplateParameters(
1357 const TemplateParameterList *Params) {
1358 if (!Params)
1359 return false;
1360
1361 for (TemplateParameterList::const_iterator P = Params->begin(),
1362 PEnd = Params->end();
1363 P != PEnd; ++P) {
1364 if (Visit(MakeCXCursor(*P, TU, RegionOfInterest)))
1365 return true;
1366 }
1367
1368 return false;
1369}
1370
1371bool CursorVisitor::VisitTemplateName(TemplateName Name, SourceLocation Loc) {
1372 switch (Name.getKind()) {
1373 case TemplateName::Template:
1374 return Visit(MakeCursorTemplateRef(Name.getAsTemplateDecl(), Loc, TU));
1375
1376 case TemplateName::OverloadedTemplate:
1377 // Visit the overloaded template set.
1378 if (Visit(MakeCursorOverloadedDeclRef(Name, Loc, TU)))
1379 return true;
1380
1381 return false;
1382
1383 case TemplateName::DependentTemplate:
1384 // FIXME: Visit nested-name-specifier.
1385 return false;
1386
1387 case TemplateName::QualifiedTemplate:
1388 // FIXME: Visit nested-name-specifier.
1389 return Visit(MakeCursorTemplateRef(
1390 Name.getAsQualifiedTemplateName()->getDecl(),
1391 Loc, TU));
1392
1393 case TemplateName::SubstTemplateTemplateParm:
1394 return Visit(MakeCursorTemplateRef(
1395 Name.getAsSubstTemplateTemplateParm()->getParameter(),
1396 Loc, TU));
1397
1398 case TemplateName::SubstTemplateTemplateParmPack:
1399 return Visit(MakeCursorTemplateRef(
1400 Name.getAsSubstTemplateTemplateParmPack()->getParameterPack(),
1401 Loc, TU));
1402 }
1403
1404 llvm_unreachable("Invalid TemplateName::Kind!");
1405}
1406
1407bool CursorVisitor::VisitTemplateArgumentLoc(const TemplateArgumentLoc &TAL) {
1408 switch (TAL.getArgument().getKind()) {
1409 case TemplateArgument::Null:
1410 case TemplateArgument::Integral:
1411 case TemplateArgument::Pack:
1412 return false;
1413
1414 case TemplateArgument::Type:
1415 if (TypeSourceInfo *TSInfo = TAL.getTypeSourceInfo())
1416 return Visit(TSInfo->getTypeLoc());
1417 return false;
1418
1419 case TemplateArgument::Declaration:
1420 if (Expr *E = TAL.getSourceDeclExpression())
1421 return Visit(MakeCXCursor(E, StmtParent, TU, RegionOfInterest));
1422 return false;
1423
1424 case TemplateArgument::NullPtr:
1425 if (Expr *E = TAL.getSourceNullPtrExpression())
1426 return Visit(MakeCXCursor(E, StmtParent, TU, RegionOfInterest));
1427 return false;
1428
1429 case TemplateArgument::Expression:
1430 if (Expr *E = TAL.getSourceExpression())
1431 return Visit(MakeCXCursor(E, StmtParent, TU, RegionOfInterest));
1432 return false;
1433
1434 case TemplateArgument::Template:
1435 case TemplateArgument::TemplateExpansion:
1436 if (VisitNestedNameSpecifierLoc(TAL.getTemplateQualifierLoc()))
1437 return true;
1438
1439 return VisitTemplateName(TAL.getArgument().getAsTemplateOrTemplatePattern(),
1440 TAL.getTemplateNameLoc());
1441 }
1442
1443 llvm_unreachable("Invalid TemplateArgument::Kind!");
1444}
1445
1446bool CursorVisitor::VisitLinkageSpecDecl(LinkageSpecDecl *D) {
1447 return VisitDeclContext(D);
1448}
1449
1450bool CursorVisitor::VisitQualifiedTypeLoc(QualifiedTypeLoc TL) {
1451 return Visit(TL.getUnqualifiedLoc());
1452}
1453
1454bool CursorVisitor::VisitBuiltinTypeLoc(BuiltinTypeLoc TL) {
1455 ASTContext &Context = AU->getASTContext();
1456
1457 // Some builtin types (such as Objective-C's "id", "sel", and
1458 // "Class") have associated declarations. Create cursors for those.
1459 QualType VisitType;
1460 switch (TL.getTypePtr()->getKind()) {
1461
1462 case BuiltinType::Void:
1463 case BuiltinType::NullPtr:
1464 case BuiltinType::Dependent:
Guy Benyeid8a08ea2012-12-18 14:38:23 +00001465 case BuiltinType::OCLImage1d:
1466 case BuiltinType::OCLImage1dArray:
1467 case BuiltinType::OCLImage1dBuffer:
1468 case BuiltinType::OCLImage2d:
1469 case BuiltinType::OCLImage2dArray:
Alexey Bader9c8453f2015-09-15 11:18:52 +00001470 case BuiltinType::OCLImage2dDepth:
1471 case BuiltinType::OCLImage2dArrayDepth:
1472 case BuiltinType::OCLImage2dMSAA:
1473 case BuiltinType::OCLImage2dArrayMSAA:
1474 case BuiltinType::OCLImage2dMSAADepth:
1475 case BuiltinType::OCLImage2dArrayMSAADepth:
Guy Benyeid8a08ea2012-12-18 14:38:23 +00001476 case BuiltinType::OCLImage3d:
NAKAMURA Takumi288c42e2013-02-07 12:47:42 +00001477 case BuiltinType::OCLSampler:
Guy Benyei1b4fb3e2013-01-20 12:31:11 +00001478 case BuiltinType::OCLEvent:
Alexey Bader9c8453f2015-09-15 11:18:52 +00001479 case BuiltinType::OCLClkEvent:
1480 case BuiltinType::OCLQueue:
1481 case BuiltinType::OCLNDRange:
1482 case BuiltinType::OCLReserveID:
Guy Benyei11169dd2012-12-18 14:30:41 +00001483#define BUILTIN_TYPE(Id, SingletonId)
1484#define SIGNED_TYPE(Id, SingletonId) case BuiltinType::Id:
1485#define UNSIGNED_TYPE(Id, SingletonId) case BuiltinType::Id:
1486#define FLOATING_TYPE(Id, SingletonId) case BuiltinType::Id:
1487#define PLACEHOLDER_TYPE(Id, SingletonId) case BuiltinType::Id:
1488#include "clang/AST/BuiltinTypes.def"
1489 break;
1490
1491 case BuiltinType::ObjCId:
1492 VisitType = Context.getObjCIdType();
1493 break;
1494
1495 case BuiltinType::ObjCClass:
1496 VisitType = Context.getObjCClassType();
1497 break;
1498
1499 case BuiltinType::ObjCSel:
1500 VisitType = Context.getObjCSelType();
1501 break;
1502 }
1503
1504 if (!VisitType.isNull()) {
1505 if (const TypedefType *Typedef = VisitType->getAs<TypedefType>())
1506 return Visit(MakeCursorTypeRef(Typedef->getDecl(), TL.getBuiltinLoc(),
1507 TU));
1508 }
1509
1510 return false;
1511}
1512
1513bool CursorVisitor::VisitTypedefTypeLoc(TypedefTypeLoc TL) {
1514 return Visit(MakeCursorTypeRef(TL.getTypedefNameDecl(), TL.getNameLoc(), TU));
1515}
1516
1517bool CursorVisitor::VisitUnresolvedUsingTypeLoc(UnresolvedUsingTypeLoc TL) {
1518 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1519}
1520
1521bool CursorVisitor::VisitTagTypeLoc(TagTypeLoc TL) {
1522 if (TL.isDefinition())
1523 return Visit(MakeCXCursor(TL.getDecl(), TU, RegionOfInterest));
1524
1525 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1526}
1527
1528bool CursorVisitor::VisitTemplateTypeParmTypeLoc(TemplateTypeParmTypeLoc TL) {
1529 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1530}
1531
1532bool CursorVisitor::VisitObjCInterfaceTypeLoc(ObjCInterfaceTypeLoc TL) {
Hans Wennborg59dbe862015-09-29 20:56:43 +00001533 return Visit(MakeCursorObjCClassRef(TL.getIFaceDecl(), TL.getNameLoc(), TU));
Guy Benyei11169dd2012-12-18 14:30:41 +00001534}
1535
1536bool CursorVisitor::VisitObjCObjectTypeLoc(ObjCObjectTypeLoc TL) {
1537 if (TL.hasBaseTypeAsWritten() && Visit(TL.getBaseLoc()))
1538 return true;
1539
Douglas Gregore9d95f12015-07-07 03:57:35 +00001540 for (unsigned I = 0, N = TL.getNumTypeArgs(); I != N; ++I) {
1541 if (Visit(TL.getTypeArgTInfo(I)->getTypeLoc()))
1542 return true;
1543 }
1544
Guy Benyei11169dd2012-12-18 14:30:41 +00001545 for (unsigned I = 0, N = TL.getNumProtocols(); I != N; ++I) {
1546 if (Visit(MakeCursorObjCProtocolRef(TL.getProtocol(I), TL.getProtocolLoc(I),
1547 TU)))
1548 return true;
1549 }
1550
1551 return false;
1552}
1553
1554bool CursorVisitor::VisitObjCObjectPointerTypeLoc(ObjCObjectPointerTypeLoc TL) {
1555 return Visit(TL.getPointeeLoc());
1556}
1557
1558bool CursorVisitor::VisitParenTypeLoc(ParenTypeLoc TL) {
1559 return Visit(TL.getInnerLoc());
1560}
1561
1562bool CursorVisitor::VisitPointerTypeLoc(PointerTypeLoc TL) {
1563 return Visit(TL.getPointeeLoc());
1564}
1565
1566bool CursorVisitor::VisitBlockPointerTypeLoc(BlockPointerTypeLoc TL) {
1567 return Visit(TL.getPointeeLoc());
1568}
1569
1570bool CursorVisitor::VisitMemberPointerTypeLoc(MemberPointerTypeLoc TL) {
1571 return Visit(TL.getPointeeLoc());
1572}
1573
1574bool CursorVisitor::VisitLValueReferenceTypeLoc(LValueReferenceTypeLoc TL) {
1575 return Visit(TL.getPointeeLoc());
1576}
1577
1578bool CursorVisitor::VisitRValueReferenceTypeLoc(RValueReferenceTypeLoc TL) {
1579 return Visit(TL.getPointeeLoc());
1580}
1581
1582bool CursorVisitor::VisitAttributedTypeLoc(AttributedTypeLoc TL) {
1583 return Visit(TL.getModifiedLoc());
1584}
1585
1586bool CursorVisitor::VisitFunctionTypeLoc(FunctionTypeLoc TL,
1587 bool SkipResultType) {
Alp Toker42a16a62014-01-25 23:51:36 +00001588 if (!SkipResultType && Visit(TL.getReturnLoc()))
Guy Benyei11169dd2012-12-18 14:30:41 +00001589 return true;
1590
Alp Tokerb3fd5cf2014-01-21 00:32:38 +00001591 for (unsigned I = 0, N = TL.getNumParams(); I != N; ++I)
1592 if (Decl *D = TL.getParam(I))
Guy Benyei11169dd2012-12-18 14:30:41 +00001593 if (Visit(MakeCXCursor(D, TU, RegionOfInterest)))
1594 return true;
1595
1596 return false;
1597}
1598
1599bool CursorVisitor::VisitArrayTypeLoc(ArrayTypeLoc TL) {
1600 if (Visit(TL.getElementLoc()))
1601 return true;
1602
1603 if (Expr *Size = TL.getSizeExpr())
1604 return Visit(MakeCXCursor(Size, StmtParent, TU, RegionOfInterest));
1605
1606 return false;
1607}
1608
Reid Kleckner8a365022013-06-24 17:51:48 +00001609bool CursorVisitor::VisitDecayedTypeLoc(DecayedTypeLoc TL) {
1610 return Visit(TL.getOriginalLoc());
1611}
1612
Reid Kleckner0503a872013-12-05 01:23:43 +00001613bool CursorVisitor::VisitAdjustedTypeLoc(AdjustedTypeLoc TL) {
1614 return Visit(TL.getOriginalLoc());
1615}
1616
Guy Benyei11169dd2012-12-18 14:30:41 +00001617bool CursorVisitor::VisitTemplateSpecializationTypeLoc(
1618 TemplateSpecializationTypeLoc TL) {
1619 // Visit the template name.
1620 if (VisitTemplateName(TL.getTypePtr()->getTemplateName(),
1621 TL.getTemplateNameLoc()))
1622 return true;
1623
1624 // Visit the template arguments.
1625 for (unsigned I = 0, N = TL.getNumArgs(); I != N; ++I)
1626 if (VisitTemplateArgumentLoc(TL.getArgLoc(I)))
1627 return true;
1628
1629 return false;
1630}
1631
1632bool CursorVisitor::VisitTypeOfExprTypeLoc(TypeOfExprTypeLoc TL) {
1633 return Visit(MakeCXCursor(TL.getUnderlyingExpr(), StmtParent, TU));
1634}
1635
1636bool CursorVisitor::VisitTypeOfTypeLoc(TypeOfTypeLoc TL) {
1637 if (TypeSourceInfo *TSInfo = TL.getUnderlyingTInfo())
1638 return Visit(TSInfo->getTypeLoc());
1639
1640 return false;
1641}
1642
1643bool CursorVisitor::VisitUnaryTransformTypeLoc(UnaryTransformTypeLoc TL) {
1644 if (TypeSourceInfo *TSInfo = TL.getUnderlyingTInfo())
1645 return Visit(TSInfo->getTypeLoc());
1646
1647 return false;
1648}
1649
1650bool CursorVisitor::VisitDependentNameTypeLoc(DependentNameTypeLoc TL) {
Hans Wennborg59dbe862015-09-29 20:56:43 +00001651 return VisitNestedNameSpecifierLoc(TL.getQualifierLoc());
Guy Benyei11169dd2012-12-18 14:30:41 +00001652}
1653
1654bool CursorVisitor::VisitDependentTemplateSpecializationTypeLoc(
1655 DependentTemplateSpecializationTypeLoc TL) {
1656 // Visit the nested-name-specifier, if there is one.
1657 if (TL.getQualifierLoc() &&
1658 VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
1659 return true;
1660
1661 // Visit the template arguments.
1662 for (unsigned I = 0, N = TL.getNumArgs(); I != N; ++I)
1663 if (VisitTemplateArgumentLoc(TL.getArgLoc(I)))
1664 return true;
1665
1666 return false;
1667}
1668
1669bool CursorVisitor::VisitElaboratedTypeLoc(ElaboratedTypeLoc TL) {
1670 if (VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
1671 return true;
1672
1673 return Visit(TL.getNamedTypeLoc());
1674}
1675
1676bool CursorVisitor::VisitPackExpansionTypeLoc(PackExpansionTypeLoc TL) {
1677 return Visit(TL.getPatternLoc());
1678}
1679
1680bool CursorVisitor::VisitDecltypeTypeLoc(DecltypeTypeLoc TL) {
1681 if (Expr *E = TL.getUnderlyingExpr())
1682 return Visit(MakeCXCursor(E, StmtParent, TU));
1683
1684 return false;
1685}
1686
1687bool CursorVisitor::VisitInjectedClassNameTypeLoc(InjectedClassNameTypeLoc TL) {
1688 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1689}
1690
1691bool CursorVisitor::VisitAtomicTypeLoc(AtomicTypeLoc TL) {
1692 return Visit(TL.getValueLoc());
1693}
1694
1695#define DEFAULT_TYPELOC_IMPL(CLASS, PARENT) \
1696bool CursorVisitor::Visit##CLASS##TypeLoc(CLASS##TypeLoc TL) { \
1697 return Visit##PARENT##Loc(TL); \
1698}
1699
1700DEFAULT_TYPELOC_IMPL(Complex, Type)
1701DEFAULT_TYPELOC_IMPL(ConstantArray, ArrayType)
1702DEFAULT_TYPELOC_IMPL(IncompleteArray, ArrayType)
1703DEFAULT_TYPELOC_IMPL(VariableArray, ArrayType)
1704DEFAULT_TYPELOC_IMPL(DependentSizedArray, ArrayType)
1705DEFAULT_TYPELOC_IMPL(DependentSizedExtVector, Type)
1706DEFAULT_TYPELOC_IMPL(Vector, Type)
1707DEFAULT_TYPELOC_IMPL(ExtVector, VectorType)
1708DEFAULT_TYPELOC_IMPL(FunctionProto, FunctionType)
1709DEFAULT_TYPELOC_IMPL(FunctionNoProto, FunctionType)
1710DEFAULT_TYPELOC_IMPL(Record, TagType)
1711DEFAULT_TYPELOC_IMPL(Enum, TagType)
1712DEFAULT_TYPELOC_IMPL(SubstTemplateTypeParm, Type)
1713DEFAULT_TYPELOC_IMPL(SubstTemplateTypeParmPack, Type)
1714DEFAULT_TYPELOC_IMPL(Auto, Type)
1715
1716bool CursorVisitor::VisitCXXRecordDecl(CXXRecordDecl *D) {
1717 // Visit the nested-name-specifier, if present.
1718 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1719 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1720 return true;
1721
1722 if (D->isCompleteDefinition()) {
Aaron Ballman574705e2014-03-13 15:41:46 +00001723 for (const auto &I : D->bases()) {
1724 if (Visit(cxcursor::MakeCursorCXXBaseSpecifier(&I, TU)))
Guy Benyei11169dd2012-12-18 14:30:41 +00001725 return true;
1726 }
1727 }
1728
1729 return VisitTagDecl(D);
1730}
1731
1732bool CursorVisitor::VisitAttributes(Decl *D) {
Aaron Ballmanb97112e2014-03-08 22:19:01 +00001733 for (const auto *I : D->attrs())
1734 if (Visit(MakeCXCursor(I, D, TU)))
Guy Benyei11169dd2012-12-18 14:30:41 +00001735 return true;
1736
1737 return false;
1738}
1739
1740//===----------------------------------------------------------------------===//
1741// Data-recursive visitor methods.
1742//===----------------------------------------------------------------------===//
1743
1744namespace {
1745#define DEF_JOB(NAME, DATA, KIND)\
1746class NAME : public VisitorJob {\
1747public:\
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001748 NAME(const DATA *d, CXCursor parent) : \
1749 VisitorJob(parent, VisitorJob::KIND, d) {} \
Guy Benyei11169dd2012-12-18 14:30:41 +00001750 static bool classof(const VisitorJob *VJ) { return VJ->getKind() == KIND; }\
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001751 const DATA *get() const { return static_cast<const DATA*>(data[0]); }\
Guy Benyei11169dd2012-12-18 14:30:41 +00001752};
1753
1754DEF_JOB(StmtVisit, Stmt, StmtVisitKind)
1755DEF_JOB(MemberExprParts, MemberExpr, MemberExprPartsKind)
1756DEF_JOB(DeclRefExprParts, DeclRefExpr, DeclRefExprPartsKind)
1757DEF_JOB(OverloadExprParts, OverloadExpr, OverloadExprPartsKind)
1758DEF_JOB(ExplicitTemplateArgsVisit, ASTTemplateArgumentListInfo,
1759 ExplicitTemplateArgsVisitKind)
1760DEF_JOB(SizeOfPackExprParts, SizeOfPackExpr, SizeOfPackExprPartsKind)
1761DEF_JOB(LambdaExprParts, LambdaExpr, LambdaExprPartsKind)
1762DEF_JOB(PostChildrenVisit, void, PostChildrenVisitKind)
1763#undef DEF_JOB
1764
1765class DeclVisit : public VisitorJob {
1766public:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001767 DeclVisit(const Decl *D, CXCursor parent, bool isFirst) :
Guy Benyei11169dd2012-12-18 14:30:41 +00001768 VisitorJob(parent, VisitorJob::DeclVisitKind,
Craig Topper69186e72014-06-08 08:38:04 +00001769 D, isFirst ? (void*) 1 : (void*) nullptr) {}
Guy Benyei11169dd2012-12-18 14:30:41 +00001770 static bool classof(const VisitorJob *VJ) {
1771 return VJ->getKind() == DeclVisitKind;
1772 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001773 const Decl *get() const { return static_cast<const Decl *>(data[0]); }
Dmitri Gribenkoe5423a72015-03-23 19:23:50 +00001774 bool isFirst() const { return data[1] != nullptr; }
Guy Benyei11169dd2012-12-18 14:30:41 +00001775};
1776class TypeLocVisit : public VisitorJob {
1777public:
1778 TypeLocVisit(TypeLoc tl, CXCursor parent) :
1779 VisitorJob(parent, VisitorJob::TypeLocVisitKind,
1780 tl.getType().getAsOpaquePtr(), tl.getOpaqueData()) {}
1781
1782 static bool classof(const VisitorJob *VJ) {
1783 return VJ->getKind() == TypeLocVisitKind;
1784 }
1785
1786 TypeLoc get() const {
1787 QualType T = QualType::getFromOpaquePtr(data[0]);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001788 return TypeLoc(T, const_cast<void *>(data[1]));
Guy Benyei11169dd2012-12-18 14:30:41 +00001789 }
1790};
1791
1792class LabelRefVisit : public VisitorJob {
1793public:
1794 LabelRefVisit(LabelDecl *LD, SourceLocation labelLoc, CXCursor parent)
1795 : VisitorJob(parent, VisitorJob::LabelRefVisitKind, LD,
1796 labelLoc.getPtrEncoding()) {}
1797
1798 static bool classof(const VisitorJob *VJ) {
1799 return VJ->getKind() == VisitorJob::LabelRefVisitKind;
1800 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001801 const LabelDecl *get() const {
1802 return static_cast<const LabelDecl *>(data[0]);
1803 }
Guy Benyei11169dd2012-12-18 14:30:41 +00001804 SourceLocation getLoc() const {
1805 return SourceLocation::getFromPtrEncoding(data[1]); }
1806};
1807
1808class NestedNameSpecifierLocVisit : public VisitorJob {
1809public:
1810 NestedNameSpecifierLocVisit(NestedNameSpecifierLoc Qualifier, CXCursor parent)
1811 : VisitorJob(parent, VisitorJob::NestedNameSpecifierLocVisitKind,
1812 Qualifier.getNestedNameSpecifier(),
1813 Qualifier.getOpaqueData()) { }
1814
1815 static bool classof(const VisitorJob *VJ) {
1816 return VJ->getKind() == VisitorJob::NestedNameSpecifierLocVisitKind;
1817 }
1818
1819 NestedNameSpecifierLoc get() const {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001820 return NestedNameSpecifierLoc(
1821 const_cast<NestedNameSpecifier *>(
1822 static_cast<const NestedNameSpecifier *>(data[0])),
1823 const_cast<void *>(data[1]));
Guy Benyei11169dd2012-12-18 14:30:41 +00001824 }
1825};
1826
1827class DeclarationNameInfoVisit : public VisitorJob {
1828public:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001829 DeclarationNameInfoVisit(const Stmt *S, CXCursor parent)
Dmitri Gribenkodd7dacf2013-02-03 13:19:54 +00001830 : VisitorJob(parent, VisitorJob::DeclarationNameInfoVisitKind, S) {}
Guy Benyei11169dd2012-12-18 14:30:41 +00001831 static bool classof(const VisitorJob *VJ) {
1832 return VJ->getKind() == VisitorJob::DeclarationNameInfoVisitKind;
1833 }
1834 DeclarationNameInfo get() const {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001835 const Stmt *S = static_cast<const Stmt *>(data[0]);
Guy Benyei11169dd2012-12-18 14:30:41 +00001836 switch (S->getStmtClass()) {
1837 default:
1838 llvm_unreachable("Unhandled Stmt");
1839 case clang::Stmt::MSDependentExistsStmtClass:
1840 return cast<MSDependentExistsStmt>(S)->getNameInfo();
1841 case Stmt::CXXDependentScopeMemberExprClass:
1842 return cast<CXXDependentScopeMemberExpr>(S)->getMemberNameInfo();
1843 case Stmt::DependentScopeDeclRefExprClass:
1844 return cast<DependentScopeDeclRefExpr>(S)->getNameInfo();
Alexander Musmand9ed09f2014-07-21 09:42:05 +00001845 case Stmt::OMPCriticalDirectiveClass:
1846 return cast<OMPCriticalDirective>(S)->getDirectiveName();
Guy Benyei11169dd2012-12-18 14:30:41 +00001847 }
1848 }
1849};
1850class MemberRefVisit : public VisitorJob {
1851public:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001852 MemberRefVisit(const FieldDecl *D, SourceLocation L, CXCursor parent)
Guy Benyei11169dd2012-12-18 14:30:41 +00001853 : VisitorJob(parent, VisitorJob::MemberRefVisitKind, D,
1854 L.getPtrEncoding()) {}
1855 static bool classof(const VisitorJob *VJ) {
1856 return VJ->getKind() == VisitorJob::MemberRefVisitKind;
1857 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001858 const FieldDecl *get() const {
1859 return static_cast<const FieldDecl *>(data[0]);
Guy Benyei11169dd2012-12-18 14:30:41 +00001860 }
1861 SourceLocation getLoc() const {
1862 return SourceLocation::getFromRawEncoding((unsigned)(uintptr_t) data[1]);
1863 }
1864};
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001865class EnqueueVisitor : public ConstStmtVisitor<EnqueueVisitor, void> {
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001866 friend class OMPClauseEnqueue;
Guy Benyei11169dd2012-12-18 14:30:41 +00001867 VisitorWorkList &WL;
1868 CXCursor Parent;
1869public:
1870 EnqueueVisitor(VisitorWorkList &wl, CXCursor parent)
1871 : WL(wl), Parent(parent) {}
1872
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001873 void VisitAddrLabelExpr(const AddrLabelExpr *E);
1874 void VisitBlockExpr(const BlockExpr *B);
1875 void VisitCompoundLiteralExpr(const CompoundLiteralExpr *E);
1876 void VisitCompoundStmt(const CompoundStmt *S);
1877 void VisitCXXDefaultArgExpr(const CXXDefaultArgExpr *E) { /* Do nothing. */ }
1878 void VisitMSDependentExistsStmt(const MSDependentExistsStmt *S);
1879 void VisitCXXDependentScopeMemberExpr(const CXXDependentScopeMemberExpr *E);
1880 void VisitCXXNewExpr(const CXXNewExpr *E);
1881 void VisitCXXScalarValueInitExpr(const CXXScalarValueInitExpr *E);
1882 void VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *E);
1883 void VisitCXXPseudoDestructorExpr(const CXXPseudoDestructorExpr *E);
1884 void VisitCXXTemporaryObjectExpr(const CXXTemporaryObjectExpr *E);
1885 void VisitCXXTypeidExpr(const CXXTypeidExpr *E);
1886 void VisitCXXUnresolvedConstructExpr(const CXXUnresolvedConstructExpr *E);
1887 void VisitCXXUuidofExpr(const CXXUuidofExpr *E);
1888 void VisitCXXCatchStmt(const CXXCatchStmt *S);
Argyrios Kyrtzidis99891242014-11-13 09:03:21 +00001889 void VisitCXXForRangeStmt(const CXXForRangeStmt *S);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001890 void VisitDeclRefExpr(const DeclRefExpr *D);
1891 void VisitDeclStmt(const DeclStmt *S);
1892 void VisitDependentScopeDeclRefExpr(const DependentScopeDeclRefExpr *E);
1893 void VisitDesignatedInitExpr(const DesignatedInitExpr *E);
1894 void VisitExplicitCastExpr(const ExplicitCastExpr *E);
1895 void VisitForStmt(const ForStmt *FS);
1896 void VisitGotoStmt(const GotoStmt *GS);
1897 void VisitIfStmt(const IfStmt *If);
1898 void VisitInitListExpr(const InitListExpr *IE);
1899 void VisitMemberExpr(const MemberExpr *M);
1900 void VisitOffsetOfExpr(const OffsetOfExpr *E);
1901 void VisitObjCEncodeExpr(const ObjCEncodeExpr *E);
1902 void VisitObjCMessageExpr(const ObjCMessageExpr *M);
1903 void VisitOverloadExpr(const OverloadExpr *E);
1904 void VisitUnaryExprOrTypeTraitExpr(const UnaryExprOrTypeTraitExpr *E);
1905 void VisitStmt(const Stmt *S);
1906 void VisitSwitchStmt(const SwitchStmt *S);
1907 void VisitWhileStmt(const WhileStmt *W);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001908 void VisitTypeTraitExpr(const TypeTraitExpr *E);
1909 void VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *E);
1910 void VisitExpressionTraitExpr(const ExpressionTraitExpr *E);
1911 void VisitUnresolvedMemberExpr(const UnresolvedMemberExpr *U);
1912 void VisitVAArgExpr(const VAArgExpr *E);
1913 void VisitSizeOfPackExpr(const SizeOfPackExpr *E);
1914 void VisitPseudoObjectExpr(const PseudoObjectExpr *E);
1915 void VisitOpaqueValueExpr(const OpaqueValueExpr *E);
1916 void VisitLambdaExpr(const LambdaExpr *E);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001917 void VisitOMPExecutableDirective(const OMPExecutableDirective *D);
Alexander Musman3aaab662014-08-19 11:27:13 +00001918 void VisitOMPLoopDirective(const OMPLoopDirective *D);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001919 void VisitOMPParallelDirective(const OMPParallelDirective *D);
Alexey Bataev1b59ab52014-02-27 08:29:12 +00001920 void VisitOMPSimdDirective(const OMPSimdDirective *D);
Alexey Bataevf29276e2014-06-18 04:14:57 +00001921 void VisitOMPForDirective(const OMPForDirective *D);
Alexander Musmanf82886e2014-09-18 05:12:34 +00001922 void VisitOMPForSimdDirective(const OMPForSimdDirective *D);
Alexey Bataevd3f8dd22014-06-25 11:44:49 +00001923 void VisitOMPSectionsDirective(const OMPSectionsDirective *D);
Alexey Bataev1e0498a2014-06-26 08:21:58 +00001924 void VisitOMPSectionDirective(const OMPSectionDirective *D);
Alexey Bataevd1e40fb2014-06-26 12:05:45 +00001925 void VisitOMPSingleDirective(const OMPSingleDirective *D);
Alexander Musman80c22892014-07-17 08:54:58 +00001926 void VisitOMPMasterDirective(const OMPMasterDirective *D);
Alexander Musmand9ed09f2014-07-21 09:42:05 +00001927 void VisitOMPCriticalDirective(const OMPCriticalDirective *D);
Alexey Bataev4acb8592014-07-07 13:01:15 +00001928 void VisitOMPParallelForDirective(const OMPParallelForDirective *D);
Alexander Musmane4e893b2014-09-23 09:33:00 +00001929 void VisitOMPParallelForSimdDirective(const OMPParallelForSimdDirective *D);
Alexey Bataev84d0b3e2014-07-08 08:12:03 +00001930 void VisitOMPParallelSectionsDirective(const OMPParallelSectionsDirective *D);
Alexey Bataev9c2e8ee2014-07-11 11:25:16 +00001931 void VisitOMPTaskDirective(const OMPTaskDirective *D);
Alexey Bataev68446b72014-07-18 07:47:19 +00001932 void VisitOMPTaskyieldDirective(const OMPTaskyieldDirective *D);
Alexey Bataev4d1dfea2014-07-18 09:11:51 +00001933 void VisitOMPBarrierDirective(const OMPBarrierDirective *D);
Alexey Bataev2df347a2014-07-18 10:17:07 +00001934 void VisitOMPTaskwaitDirective(const OMPTaskwaitDirective *D);
Alexey Bataevc30dd2d2015-06-18 12:14:09 +00001935 void VisitOMPTaskgroupDirective(const OMPTaskgroupDirective *D);
Alexey Bataev6d4ed052015-07-01 06:57:41 +00001936 void
1937 VisitOMPCancellationPointDirective(const OMPCancellationPointDirective *D);
Alexey Bataev80909872015-07-02 11:25:17 +00001938 void VisitOMPCancelDirective(const OMPCancelDirective *D);
Alexey Bataev6125da92014-07-21 11:26:11 +00001939 void VisitOMPFlushDirective(const OMPFlushDirective *D);
Alexey Bataev9fb6e642014-07-22 06:45:04 +00001940 void VisitOMPOrderedDirective(const OMPOrderedDirective *D);
Alexey Bataev0162e452014-07-22 10:10:35 +00001941 void VisitOMPAtomicDirective(const OMPAtomicDirective *D);
Alexey Bataev0bd520b2014-09-19 08:19:49 +00001942 void VisitOMPTargetDirective(const OMPTargetDirective *D);
Michael Wong65f367f2015-07-21 13:44:28 +00001943 void VisitOMPTargetDataDirective(const OMPTargetDataDirective *D);
Alexey Bataev13314bf2014-10-09 04:18:56 +00001944 void VisitOMPTeamsDirective(const OMPTeamsDirective *D);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001945
Guy Benyei11169dd2012-12-18 14:30:41 +00001946private:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001947 void AddDeclarationNameInfo(const Stmt *S);
Guy Benyei11169dd2012-12-18 14:30:41 +00001948 void AddNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier);
1949 void AddExplicitTemplateArgs(const ASTTemplateArgumentListInfo *A);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001950 void AddMemberRef(const FieldDecl *D, SourceLocation L);
1951 void AddStmt(const Stmt *S);
1952 void AddDecl(const Decl *D, bool isFirst = true);
Guy Benyei11169dd2012-12-18 14:30:41 +00001953 void AddTypeLoc(TypeSourceInfo *TI);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001954 void EnqueueChildren(const Stmt *S);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001955 void EnqueueChildren(const OMPClause *S);
Guy Benyei11169dd2012-12-18 14:30:41 +00001956};
Alexander Kornienkoab9db512015-06-22 23:07:51 +00001957} // end anonyous namespace
Guy Benyei11169dd2012-12-18 14:30:41 +00001958
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001959void EnqueueVisitor::AddDeclarationNameInfo(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001960 // 'S' should always be non-null, since it comes from the
1961 // statement we are visiting.
1962 WL.push_back(DeclarationNameInfoVisit(S, Parent));
1963}
1964
1965void
1966EnqueueVisitor::AddNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier) {
1967 if (Qualifier)
1968 WL.push_back(NestedNameSpecifierLocVisit(Qualifier, Parent));
1969}
1970
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001971void EnqueueVisitor::AddStmt(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001972 if (S)
1973 WL.push_back(StmtVisit(S, Parent));
1974}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001975void EnqueueVisitor::AddDecl(const Decl *D, bool isFirst) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001976 if (D)
1977 WL.push_back(DeclVisit(D, Parent, isFirst));
1978}
1979void EnqueueVisitor::
1980 AddExplicitTemplateArgs(const ASTTemplateArgumentListInfo *A) {
1981 if (A)
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001982 WL.push_back(ExplicitTemplateArgsVisit(A, Parent));
Guy Benyei11169dd2012-12-18 14:30:41 +00001983}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001984void EnqueueVisitor::AddMemberRef(const FieldDecl *D, SourceLocation L) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001985 if (D)
1986 WL.push_back(MemberRefVisit(D, L, Parent));
1987}
1988void EnqueueVisitor::AddTypeLoc(TypeSourceInfo *TI) {
1989 if (TI)
1990 WL.push_back(TypeLocVisit(TI->getTypeLoc(), Parent));
1991 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001992void EnqueueVisitor::EnqueueChildren(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001993 unsigned size = WL.size();
Benjamin Kramer642f1732015-07-02 21:03:14 +00001994 for (const Stmt *SubStmt : S->children()) {
1995 AddStmt(SubStmt);
Guy Benyei11169dd2012-12-18 14:30:41 +00001996 }
1997 if (size == WL.size())
1998 return;
1999 // Now reverse the entries we just added. This will match the DFS
2000 // ordering performed by the worklist.
2001 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
2002 std::reverse(I, E);
2003}
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002004namespace {
2005class OMPClauseEnqueue : public ConstOMPClauseVisitor<OMPClauseEnqueue> {
2006 EnqueueVisitor *Visitor;
Alexey Bataev756c1962013-09-24 03:17:45 +00002007 /// \brief Process clauses with list of variables.
2008 template <typename T>
2009 void VisitOMPClauseList(T *Node);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002010public:
2011 OMPClauseEnqueue(EnqueueVisitor *Visitor) : Visitor(Visitor) { }
2012#define OPENMP_CLAUSE(Name, Class) \
2013 void Visit##Class(const Class *C);
2014#include "clang/Basic/OpenMPKinds.def"
2015};
2016
Alexey Bataevaadd52e2014-02-13 05:29:23 +00002017void OMPClauseEnqueue::VisitOMPIfClause(const OMPIfClause *C) {
2018 Visitor->AddStmt(C->getCondition());
2019}
2020
Alexey Bataev3778b602014-07-17 07:32:53 +00002021void OMPClauseEnqueue::VisitOMPFinalClause(const OMPFinalClause *C) {
2022 Visitor->AddStmt(C->getCondition());
2023}
2024
Alexey Bataev568a8332014-03-06 06:15:19 +00002025void OMPClauseEnqueue::VisitOMPNumThreadsClause(const OMPNumThreadsClause *C) {
2026 Visitor->AddStmt(C->getNumThreads());
2027}
2028
Alexey Bataev62c87d22014-03-21 04:51:18 +00002029void OMPClauseEnqueue::VisitOMPSafelenClause(const OMPSafelenClause *C) {
2030 Visitor->AddStmt(C->getSafelen());
2031}
2032
Alexey Bataev66b15b52015-08-21 11:14:16 +00002033void OMPClauseEnqueue::VisitOMPSimdlenClause(const OMPSimdlenClause *C) {
2034 Visitor->AddStmt(C->getSimdlen());
2035}
2036
Alexander Musman8bd31e62014-05-27 15:12:19 +00002037void OMPClauseEnqueue::VisitOMPCollapseClause(const OMPCollapseClause *C) {
2038 Visitor->AddStmt(C->getNumForLoops());
2039}
2040
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002041void OMPClauseEnqueue::VisitOMPDefaultClause(const OMPDefaultClause *C) { }
Alexey Bataev756c1962013-09-24 03:17:45 +00002042
Alexey Bataevbcbadb62014-05-06 06:04:14 +00002043void OMPClauseEnqueue::VisitOMPProcBindClause(const OMPProcBindClause *C) { }
2044
Alexey Bataev56dafe82014-06-20 07:16:17 +00002045void OMPClauseEnqueue::VisitOMPScheduleClause(const OMPScheduleClause *C) {
2046 Visitor->AddStmt(C->getChunkSize());
Alexey Bataev040d5402015-05-12 08:35:28 +00002047 Visitor->AddStmt(C->getHelperChunkSize());
Alexey Bataev56dafe82014-06-20 07:16:17 +00002048}
2049
Alexey Bataev10e775f2015-07-30 11:36:16 +00002050void OMPClauseEnqueue::VisitOMPOrderedClause(const OMPOrderedClause *C) {
2051 Visitor->AddStmt(C->getNumForLoops());
2052}
Alexey Bataev142e1fc2014-06-20 09:44:06 +00002053
Alexey Bataev236070f2014-06-20 11:19:47 +00002054void OMPClauseEnqueue::VisitOMPNowaitClause(const OMPNowaitClause *) {}
2055
Alexey Bataev7aea99a2014-07-17 12:19:31 +00002056void OMPClauseEnqueue::VisitOMPUntiedClause(const OMPUntiedClause *) {}
2057
Alexey Bataev74ba3a52014-07-17 12:47:03 +00002058void OMPClauseEnqueue::VisitOMPMergeableClause(const OMPMergeableClause *) {}
2059
Alexey Bataevf98b00c2014-07-23 02:27:21 +00002060void OMPClauseEnqueue::VisitOMPReadClause(const OMPReadClause *) {}
2061
Alexey Bataevdea47612014-07-23 07:46:59 +00002062void OMPClauseEnqueue::VisitOMPWriteClause(const OMPWriteClause *) {}
2063
Alexey Bataev67a4f222014-07-23 10:25:33 +00002064void OMPClauseEnqueue::VisitOMPUpdateClause(const OMPUpdateClause *) {}
2065
Alexey Bataev459dec02014-07-24 06:46:57 +00002066void OMPClauseEnqueue::VisitOMPCaptureClause(const OMPCaptureClause *) {}
2067
Alexey Bataev82bad8b2014-07-24 08:55:34 +00002068void OMPClauseEnqueue::VisitOMPSeqCstClause(const OMPSeqCstClause *) {}
2069
Alexey Bataev346265e2015-09-25 10:37:12 +00002070void OMPClauseEnqueue::VisitOMPThreadsClause(const OMPThreadsClause *) {}
2071
Alexey Bataevd14d1e62015-09-28 06:39:35 +00002072void OMPClauseEnqueue::VisitOMPSIMDClause(const OMPSIMDClause *) {}
2073
Michael Wonge710d542015-08-07 16:16:36 +00002074void OMPClauseEnqueue::VisitOMPDeviceClause(const OMPDeviceClause *C) {
2075 Visitor->AddStmt(C->getDevice());
2076}
2077
Kelvin Li099bb8c2015-11-24 20:50:12 +00002078void OMPClauseEnqueue::VisitOMPNumTeamsClause(const OMPNumTeamsClause *C) {
2079 Visitor->AddStmt(C->getNumTeams());
2080}
2081
Alexey Bataev756c1962013-09-24 03:17:45 +00002082template<typename T>
2083void OMPClauseEnqueue::VisitOMPClauseList(T *Node) {
Alexey Bataev03b340a2014-10-21 03:16:40 +00002084 for (const auto *I : Node->varlists()) {
Aaron Ballman2205d2a2014-03-14 15:55:35 +00002085 Visitor->AddStmt(I);
Alexey Bataev03b340a2014-10-21 03:16:40 +00002086 }
Alexey Bataev756c1962013-09-24 03:17:45 +00002087}
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002088
2089void OMPClauseEnqueue::VisitOMPPrivateClause(const OMPPrivateClause *C) {
Alexey Bataev756c1962013-09-24 03:17:45 +00002090 VisitOMPClauseList(C);
Alexey Bataev03b340a2014-10-21 03:16:40 +00002091 for (const auto *E : C->private_copies()) {
2092 Visitor->AddStmt(E);
2093 }
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002094}
Alexey Bataevd5af8e42013-10-01 05:32:34 +00002095void OMPClauseEnqueue::VisitOMPFirstprivateClause(
2096 const OMPFirstprivateClause *C) {
2097 VisitOMPClauseList(C);
2098}
Alexander Musman1bb328c2014-06-04 13:06:39 +00002099void OMPClauseEnqueue::VisitOMPLastprivateClause(
2100 const OMPLastprivateClause *C) {
2101 VisitOMPClauseList(C);
Alexey Bataev38e89532015-04-16 04:54:05 +00002102 for (auto *E : C->private_copies()) {
2103 Visitor->AddStmt(E);
2104 }
2105 for (auto *E : C->source_exprs()) {
2106 Visitor->AddStmt(E);
2107 }
2108 for (auto *E : C->destination_exprs()) {
2109 Visitor->AddStmt(E);
2110 }
2111 for (auto *E : C->assignment_ops()) {
2112 Visitor->AddStmt(E);
2113 }
Alexander Musman1bb328c2014-06-04 13:06:39 +00002114}
Alexey Bataev758e55e2013-09-06 18:03:48 +00002115void OMPClauseEnqueue::VisitOMPSharedClause(const OMPSharedClause *C) {
Alexey Bataev756c1962013-09-24 03:17:45 +00002116 VisitOMPClauseList(C);
Alexey Bataev758e55e2013-09-06 18:03:48 +00002117}
Alexey Bataevc5e02582014-06-16 07:08:35 +00002118void OMPClauseEnqueue::VisitOMPReductionClause(const OMPReductionClause *C) {
2119 VisitOMPClauseList(C);
Alexey Bataevf24e7b12015-10-08 09:10:53 +00002120 for (auto *E : C->privates()) {
2121 Visitor->AddStmt(E);
2122 }
Alexey Bataev794ba0d2015-04-10 10:43:45 +00002123 for (auto *E : C->lhs_exprs()) {
2124 Visitor->AddStmt(E);
2125 }
2126 for (auto *E : C->rhs_exprs()) {
2127 Visitor->AddStmt(E);
2128 }
2129 for (auto *E : C->reduction_ops()) {
2130 Visitor->AddStmt(E);
2131 }
Alexey Bataevc5e02582014-06-16 07:08:35 +00002132}
Alexander Musman8dba6642014-04-22 13:09:42 +00002133void OMPClauseEnqueue::VisitOMPLinearClause(const OMPLinearClause *C) {
2134 VisitOMPClauseList(C);
Alexey Bataevbd9fec12015-08-18 06:47:21 +00002135 for (const auto *E : C->privates()) {
2136 Visitor->AddStmt(E);
2137 }
Alexander Musman3276a272015-03-21 10:12:56 +00002138 for (const auto *E : C->inits()) {
2139 Visitor->AddStmt(E);
2140 }
2141 for (const auto *E : C->updates()) {
2142 Visitor->AddStmt(E);
2143 }
2144 for (const auto *E : C->finals()) {
2145 Visitor->AddStmt(E);
2146 }
Alexander Musman8dba6642014-04-22 13:09:42 +00002147 Visitor->AddStmt(C->getStep());
Alexander Musman3276a272015-03-21 10:12:56 +00002148 Visitor->AddStmt(C->getCalcStep());
Alexander Musman8dba6642014-04-22 13:09:42 +00002149}
Alexander Musmanf0d76e72014-05-29 14:36:25 +00002150void OMPClauseEnqueue::VisitOMPAlignedClause(const OMPAlignedClause *C) {
2151 VisitOMPClauseList(C);
2152 Visitor->AddStmt(C->getAlignment());
2153}
Alexey Bataevd48bcd82014-03-31 03:36:38 +00002154void OMPClauseEnqueue::VisitOMPCopyinClause(const OMPCopyinClause *C) {
2155 VisitOMPClauseList(C);
Alexey Bataevf56f98c2015-04-16 05:39:01 +00002156 for (auto *E : C->source_exprs()) {
2157 Visitor->AddStmt(E);
2158 }
2159 for (auto *E : C->destination_exprs()) {
2160 Visitor->AddStmt(E);
2161 }
2162 for (auto *E : C->assignment_ops()) {
2163 Visitor->AddStmt(E);
2164 }
Alexey Bataevd48bcd82014-03-31 03:36:38 +00002165}
Alexey Bataevbae9a792014-06-27 10:37:06 +00002166void
2167OMPClauseEnqueue::VisitOMPCopyprivateClause(const OMPCopyprivateClause *C) {
2168 VisitOMPClauseList(C);
Alexey Bataeva63048e2015-03-23 06:18:07 +00002169 for (auto *E : C->source_exprs()) {
2170 Visitor->AddStmt(E);
2171 }
2172 for (auto *E : C->destination_exprs()) {
2173 Visitor->AddStmt(E);
2174 }
2175 for (auto *E : C->assignment_ops()) {
2176 Visitor->AddStmt(E);
2177 }
Alexey Bataevbae9a792014-06-27 10:37:06 +00002178}
Alexey Bataev6125da92014-07-21 11:26:11 +00002179void OMPClauseEnqueue::VisitOMPFlushClause(const OMPFlushClause *C) {
2180 VisitOMPClauseList(C);
2181}
Alexey Bataev1c2cfbc2015-06-23 14:25:19 +00002182void OMPClauseEnqueue::VisitOMPDependClause(const OMPDependClause *C) {
2183 VisitOMPClauseList(C);
2184}
Kelvin Li0bff7af2015-11-23 05:32:03 +00002185void OMPClauseEnqueue::VisitOMPMapClause(const OMPMapClause *C) {
2186 VisitOMPClauseList(C);
2187}
Alexander Kornienkoab9db512015-06-22 23:07:51 +00002188}
Alexey Bataev756c1962013-09-24 03:17:45 +00002189
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002190void EnqueueVisitor::EnqueueChildren(const OMPClause *S) {
2191 unsigned size = WL.size();
2192 OMPClauseEnqueue Visitor(this);
2193 Visitor.Visit(S);
2194 if (size == WL.size())
2195 return;
2196 // Now reverse the entries we just added. This will match the DFS
2197 // ordering performed by the worklist.
2198 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
2199 std::reverse(I, E);
2200}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002201void EnqueueVisitor::VisitAddrLabelExpr(const AddrLabelExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002202 WL.push_back(LabelRefVisit(E->getLabel(), E->getLabelLoc(), Parent));
2203}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002204void EnqueueVisitor::VisitBlockExpr(const BlockExpr *B) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002205 AddDecl(B->getBlockDecl());
2206}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002207void EnqueueVisitor::VisitCompoundLiteralExpr(const CompoundLiteralExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002208 EnqueueChildren(E);
2209 AddTypeLoc(E->getTypeSourceInfo());
2210}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002211void EnqueueVisitor::VisitCompoundStmt(const CompoundStmt *S) {
Pete Cooper57d3f142015-07-30 17:22:52 +00002212 for (auto &I : llvm::reverse(S->body()))
2213 AddStmt(I);
Guy Benyei11169dd2012-12-18 14:30:41 +00002214}
2215void EnqueueVisitor::
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002216VisitMSDependentExistsStmt(const MSDependentExistsStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002217 AddStmt(S->getSubStmt());
2218 AddDeclarationNameInfo(S);
2219 if (NestedNameSpecifierLoc QualifierLoc = S->getQualifierLoc())
2220 AddNestedNameSpecifierLoc(QualifierLoc);
2221}
2222
2223void EnqueueVisitor::
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002224VisitCXXDependentScopeMemberExpr(const CXXDependentScopeMemberExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002225 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
2226 AddDeclarationNameInfo(E);
2227 if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
2228 AddNestedNameSpecifierLoc(QualifierLoc);
2229 if (!E->isImplicitAccess())
2230 AddStmt(E->getBase());
2231}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002232void EnqueueVisitor::VisitCXXNewExpr(const CXXNewExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002233 // Enqueue the initializer , if any.
2234 AddStmt(E->getInitializer());
2235 // Enqueue the array size, if any.
2236 AddStmt(E->getArraySize());
2237 // Enqueue the allocated type.
2238 AddTypeLoc(E->getAllocatedTypeSourceInfo());
2239 // Enqueue the placement arguments.
2240 for (unsigned I = E->getNumPlacementArgs(); I > 0; --I)
2241 AddStmt(E->getPlacementArg(I-1));
2242}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002243void EnqueueVisitor::VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *CE) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002244 for (unsigned I = CE->getNumArgs(); I > 1 /* Yes, this is 1 */; --I)
2245 AddStmt(CE->getArg(I-1));
2246 AddStmt(CE->getCallee());
2247 AddStmt(CE->getArg(0));
2248}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002249void EnqueueVisitor::VisitCXXPseudoDestructorExpr(
2250 const CXXPseudoDestructorExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002251 // Visit the name of the type being destroyed.
2252 AddTypeLoc(E->getDestroyedTypeInfo());
2253 // Visit the scope type that looks disturbingly like the nested-name-specifier
2254 // but isn't.
2255 AddTypeLoc(E->getScopeTypeInfo());
2256 // Visit the nested-name-specifier.
2257 if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
2258 AddNestedNameSpecifierLoc(QualifierLoc);
2259 // Visit base expression.
2260 AddStmt(E->getBase());
2261}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002262void EnqueueVisitor::VisitCXXScalarValueInitExpr(
2263 const CXXScalarValueInitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002264 AddTypeLoc(E->getTypeSourceInfo());
2265}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002266void EnqueueVisitor::VisitCXXTemporaryObjectExpr(
2267 const CXXTemporaryObjectExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002268 EnqueueChildren(E);
2269 AddTypeLoc(E->getTypeSourceInfo());
2270}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002271void EnqueueVisitor::VisitCXXTypeidExpr(const CXXTypeidExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002272 EnqueueChildren(E);
2273 if (E->isTypeOperand())
2274 AddTypeLoc(E->getTypeOperandSourceInfo());
2275}
2276
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002277void EnqueueVisitor::VisitCXXUnresolvedConstructExpr(
2278 const CXXUnresolvedConstructExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002279 EnqueueChildren(E);
2280 AddTypeLoc(E->getTypeSourceInfo());
2281}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002282void EnqueueVisitor::VisitCXXUuidofExpr(const CXXUuidofExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002283 EnqueueChildren(E);
2284 if (E->isTypeOperand())
2285 AddTypeLoc(E->getTypeOperandSourceInfo());
2286}
2287
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002288void EnqueueVisitor::VisitCXXCatchStmt(const CXXCatchStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002289 EnqueueChildren(S);
2290 AddDecl(S->getExceptionDecl());
2291}
2292
Argyrios Kyrtzidis99891242014-11-13 09:03:21 +00002293void EnqueueVisitor::VisitCXXForRangeStmt(const CXXForRangeStmt *S) {
Argyrios Kyrtzidiscde70692014-11-13 09:50:19 +00002294 AddStmt(S->getBody());
Argyrios Kyrtzidis99891242014-11-13 09:03:21 +00002295 AddStmt(S->getRangeInit());
Argyrios Kyrtzidiscde70692014-11-13 09:50:19 +00002296 AddDecl(S->getLoopVariable());
Argyrios Kyrtzidis99891242014-11-13 09:03:21 +00002297}
2298
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002299void EnqueueVisitor::VisitDeclRefExpr(const DeclRefExpr *DR) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002300 if (DR->hasExplicitTemplateArgs()) {
2301 AddExplicitTemplateArgs(&DR->getExplicitTemplateArgs());
2302 }
2303 WL.push_back(DeclRefExprParts(DR, Parent));
2304}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002305void EnqueueVisitor::VisitDependentScopeDeclRefExpr(
2306 const DependentScopeDeclRefExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002307 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
2308 AddDeclarationNameInfo(E);
2309 AddNestedNameSpecifierLoc(E->getQualifierLoc());
2310}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002311void EnqueueVisitor::VisitDeclStmt(const DeclStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002312 unsigned size = WL.size();
2313 bool isFirst = true;
Aaron Ballman535bbcc2014-03-14 17:01:24 +00002314 for (const auto *D : S->decls()) {
2315 AddDecl(D, isFirst);
Guy Benyei11169dd2012-12-18 14:30:41 +00002316 isFirst = false;
2317 }
2318 if (size == WL.size())
2319 return;
2320 // Now reverse the entries we just added. This will match the DFS
2321 // ordering performed by the worklist.
2322 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
2323 std::reverse(I, E);
2324}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002325void EnqueueVisitor::VisitDesignatedInitExpr(const DesignatedInitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002326 AddStmt(E->getInit());
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002327 for (DesignatedInitExpr::const_reverse_designators_iterator
Guy Benyei11169dd2012-12-18 14:30:41 +00002328 D = E->designators_rbegin(), DEnd = E->designators_rend();
2329 D != DEnd; ++D) {
2330 if (D->isFieldDesignator()) {
2331 if (FieldDecl *Field = D->getField())
2332 AddMemberRef(Field, D->getFieldLoc());
2333 continue;
2334 }
2335 if (D->isArrayDesignator()) {
2336 AddStmt(E->getArrayIndex(*D));
2337 continue;
2338 }
2339 assert(D->isArrayRangeDesignator() && "Unknown designator kind");
2340 AddStmt(E->getArrayRangeEnd(*D));
2341 AddStmt(E->getArrayRangeStart(*D));
2342 }
2343}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002344void EnqueueVisitor::VisitExplicitCastExpr(const ExplicitCastExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002345 EnqueueChildren(E);
2346 AddTypeLoc(E->getTypeInfoAsWritten());
2347}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002348void EnqueueVisitor::VisitForStmt(const ForStmt *FS) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002349 AddStmt(FS->getBody());
2350 AddStmt(FS->getInc());
2351 AddStmt(FS->getCond());
2352 AddDecl(FS->getConditionVariable());
2353 AddStmt(FS->getInit());
2354}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002355void EnqueueVisitor::VisitGotoStmt(const GotoStmt *GS) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002356 WL.push_back(LabelRefVisit(GS->getLabel(), GS->getLabelLoc(), Parent));
2357}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002358void EnqueueVisitor::VisitIfStmt(const IfStmt *If) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002359 AddStmt(If->getElse());
2360 AddStmt(If->getThen());
2361 AddStmt(If->getCond());
2362 AddDecl(If->getConditionVariable());
2363}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002364void EnqueueVisitor::VisitInitListExpr(const InitListExpr *IE) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002365 // We care about the syntactic form of the initializer list, only.
2366 if (InitListExpr *Syntactic = IE->getSyntacticForm())
2367 IE = Syntactic;
2368 EnqueueChildren(IE);
2369}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002370void EnqueueVisitor::VisitMemberExpr(const MemberExpr *M) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002371 WL.push_back(MemberExprParts(M, Parent));
2372
2373 // If the base of the member access expression is an implicit 'this', don't
2374 // visit it.
2375 // FIXME: If we ever want to show these implicit accesses, this will be
2376 // unfortunate. However, clang_getCursor() relies on this behavior.
Argyrios Kyrtzidis58d0e7a2015-03-13 04:40:07 +00002377 if (M->isImplicitAccess())
2378 return;
2379
2380 // Ignore base anonymous struct/union fields, otherwise they will shadow the
2381 // real field that that we are interested in.
2382 if (auto *SubME = dyn_cast<MemberExpr>(M->getBase())) {
2383 if (auto *FD = dyn_cast_or_null<FieldDecl>(SubME->getMemberDecl())) {
2384 if (FD->isAnonymousStructOrUnion()) {
2385 AddStmt(SubME->getBase());
2386 return;
2387 }
2388 }
2389 }
2390
2391 AddStmt(M->getBase());
Guy Benyei11169dd2012-12-18 14:30:41 +00002392}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002393void EnqueueVisitor::VisitObjCEncodeExpr(const ObjCEncodeExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002394 AddTypeLoc(E->getEncodedTypeSourceInfo());
2395}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002396void EnqueueVisitor::VisitObjCMessageExpr(const ObjCMessageExpr *M) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002397 EnqueueChildren(M);
2398 AddTypeLoc(M->getClassReceiverTypeInfo());
2399}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002400void EnqueueVisitor::VisitOffsetOfExpr(const OffsetOfExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002401 // Visit the components of the offsetof expression.
2402 for (unsigned N = E->getNumComponents(), I = N; I > 0; --I) {
2403 typedef OffsetOfExpr::OffsetOfNode OffsetOfNode;
2404 const OffsetOfNode &Node = E->getComponent(I-1);
2405 switch (Node.getKind()) {
2406 case OffsetOfNode::Array:
2407 AddStmt(E->getIndexExpr(Node.getArrayExprIndex()));
2408 break;
2409 case OffsetOfNode::Field:
2410 AddMemberRef(Node.getField(), Node.getSourceRange().getEnd());
2411 break;
2412 case OffsetOfNode::Identifier:
2413 case OffsetOfNode::Base:
2414 continue;
2415 }
2416 }
2417 // Visit the type into which we're computing the offset.
2418 AddTypeLoc(E->getTypeSourceInfo());
2419}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002420void EnqueueVisitor::VisitOverloadExpr(const OverloadExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002421 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
2422 WL.push_back(OverloadExprParts(E, Parent));
2423}
2424void EnqueueVisitor::VisitUnaryExprOrTypeTraitExpr(
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002425 const UnaryExprOrTypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002426 EnqueueChildren(E);
2427 if (E->isArgumentType())
2428 AddTypeLoc(E->getArgumentTypeInfo());
2429}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002430void EnqueueVisitor::VisitStmt(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002431 EnqueueChildren(S);
2432}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002433void EnqueueVisitor::VisitSwitchStmt(const SwitchStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002434 AddStmt(S->getBody());
2435 AddStmt(S->getCond());
2436 AddDecl(S->getConditionVariable());
2437}
2438
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002439void EnqueueVisitor::VisitWhileStmt(const WhileStmt *W) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002440 AddStmt(W->getBody());
2441 AddStmt(W->getCond());
2442 AddDecl(W->getConditionVariable());
2443}
2444
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002445void EnqueueVisitor::VisitTypeTraitExpr(const TypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002446 for (unsigned I = E->getNumArgs(); I > 0; --I)
2447 AddTypeLoc(E->getArg(I-1));
2448}
2449
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002450void EnqueueVisitor::VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002451 AddTypeLoc(E->getQueriedTypeSourceInfo());
2452}
2453
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002454void EnqueueVisitor::VisitExpressionTraitExpr(const ExpressionTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002455 EnqueueChildren(E);
2456}
2457
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002458void EnqueueVisitor::VisitUnresolvedMemberExpr(const UnresolvedMemberExpr *U) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002459 VisitOverloadExpr(U);
2460 if (!U->isImplicitAccess())
2461 AddStmt(U->getBase());
2462}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002463void EnqueueVisitor::VisitVAArgExpr(const VAArgExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002464 AddStmt(E->getSubExpr());
2465 AddTypeLoc(E->getWrittenTypeInfo());
2466}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002467void EnqueueVisitor::VisitSizeOfPackExpr(const SizeOfPackExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002468 WL.push_back(SizeOfPackExprParts(E, Parent));
2469}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002470void EnqueueVisitor::VisitOpaqueValueExpr(const OpaqueValueExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002471 // If the opaque value has a source expression, just transparently
2472 // visit that. This is useful for (e.g.) pseudo-object expressions.
2473 if (Expr *SourceExpr = E->getSourceExpr())
2474 return Visit(SourceExpr);
2475}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002476void EnqueueVisitor::VisitLambdaExpr(const LambdaExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002477 AddStmt(E->getBody());
2478 WL.push_back(LambdaExprParts(E, Parent));
2479}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002480void EnqueueVisitor::VisitPseudoObjectExpr(const PseudoObjectExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002481 // Treat the expression like its syntactic form.
2482 Visit(E->getSyntacticForm());
2483}
2484
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002485void EnqueueVisitor::VisitOMPExecutableDirective(
2486 const OMPExecutableDirective *D) {
2487 EnqueueChildren(D);
2488 for (ArrayRef<OMPClause *>::iterator I = D->clauses().begin(),
2489 E = D->clauses().end();
2490 I != E; ++I)
2491 EnqueueChildren(*I);
2492}
2493
Alexander Musman3aaab662014-08-19 11:27:13 +00002494void EnqueueVisitor::VisitOMPLoopDirective(const OMPLoopDirective *D) {
2495 VisitOMPExecutableDirective(D);
2496}
2497
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002498void EnqueueVisitor::VisitOMPParallelDirective(const OMPParallelDirective *D) {
2499 VisitOMPExecutableDirective(D);
2500}
2501
Alexey Bataev1b59ab52014-02-27 08:29:12 +00002502void EnqueueVisitor::VisitOMPSimdDirective(const OMPSimdDirective *D) {
Alexander Musman3aaab662014-08-19 11:27:13 +00002503 VisitOMPLoopDirective(D);
Alexey Bataev1b59ab52014-02-27 08:29:12 +00002504}
2505
Alexey Bataevf29276e2014-06-18 04:14:57 +00002506void EnqueueVisitor::VisitOMPForDirective(const OMPForDirective *D) {
Alexander Musman3aaab662014-08-19 11:27:13 +00002507 VisitOMPLoopDirective(D);
Alexey Bataevf29276e2014-06-18 04:14:57 +00002508}
2509
Alexander Musmanf82886e2014-09-18 05:12:34 +00002510void EnqueueVisitor::VisitOMPForSimdDirective(const OMPForSimdDirective *D) {
2511 VisitOMPLoopDirective(D);
2512}
2513
Alexey Bataevd3f8dd22014-06-25 11:44:49 +00002514void EnqueueVisitor::VisitOMPSectionsDirective(const OMPSectionsDirective *D) {
2515 VisitOMPExecutableDirective(D);
2516}
2517
Alexey Bataev1e0498a2014-06-26 08:21:58 +00002518void EnqueueVisitor::VisitOMPSectionDirective(const OMPSectionDirective *D) {
2519 VisitOMPExecutableDirective(D);
2520}
2521
Alexey Bataevd1e40fb2014-06-26 12:05:45 +00002522void EnqueueVisitor::VisitOMPSingleDirective(const OMPSingleDirective *D) {
2523 VisitOMPExecutableDirective(D);
2524}
2525
Alexander Musman80c22892014-07-17 08:54:58 +00002526void EnqueueVisitor::VisitOMPMasterDirective(const OMPMasterDirective *D) {
2527 VisitOMPExecutableDirective(D);
2528}
2529
Alexander Musmand9ed09f2014-07-21 09:42:05 +00002530void EnqueueVisitor::VisitOMPCriticalDirective(const OMPCriticalDirective *D) {
2531 VisitOMPExecutableDirective(D);
2532 AddDeclarationNameInfo(D);
2533}
2534
Alexey Bataev4acb8592014-07-07 13:01:15 +00002535void
2536EnqueueVisitor::VisitOMPParallelForDirective(const OMPParallelForDirective *D) {
Alexander Musman3aaab662014-08-19 11:27:13 +00002537 VisitOMPLoopDirective(D);
Alexey Bataev4acb8592014-07-07 13:01:15 +00002538}
2539
Alexander Musmane4e893b2014-09-23 09:33:00 +00002540void EnqueueVisitor::VisitOMPParallelForSimdDirective(
2541 const OMPParallelForSimdDirective *D) {
2542 VisitOMPLoopDirective(D);
2543}
2544
Alexey Bataev84d0b3e2014-07-08 08:12:03 +00002545void EnqueueVisitor::VisitOMPParallelSectionsDirective(
2546 const OMPParallelSectionsDirective *D) {
2547 VisitOMPExecutableDirective(D);
2548}
2549
Alexey Bataev9c2e8ee2014-07-11 11:25:16 +00002550void EnqueueVisitor::VisitOMPTaskDirective(const OMPTaskDirective *D) {
2551 VisitOMPExecutableDirective(D);
2552}
2553
Alexey Bataev68446b72014-07-18 07:47:19 +00002554void
2555EnqueueVisitor::VisitOMPTaskyieldDirective(const OMPTaskyieldDirective *D) {
2556 VisitOMPExecutableDirective(D);
2557}
2558
Alexey Bataev4d1dfea2014-07-18 09:11:51 +00002559void EnqueueVisitor::VisitOMPBarrierDirective(const OMPBarrierDirective *D) {
2560 VisitOMPExecutableDirective(D);
2561}
2562
Alexey Bataev2df347a2014-07-18 10:17:07 +00002563void EnqueueVisitor::VisitOMPTaskwaitDirective(const OMPTaskwaitDirective *D) {
2564 VisitOMPExecutableDirective(D);
2565}
2566
Alexey Bataevc30dd2d2015-06-18 12:14:09 +00002567void EnqueueVisitor::VisitOMPTaskgroupDirective(
2568 const OMPTaskgroupDirective *D) {
2569 VisitOMPExecutableDirective(D);
2570}
2571
Alexey Bataev6125da92014-07-21 11:26:11 +00002572void EnqueueVisitor::VisitOMPFlushDirective(const OMPFlushDirective *D) {
2573 VisitOMPExecutableDirective(D);
2574}
2575
Alexey Bataev9fb6e642014-07-22 06:45:04 +00002576void EnqueueVisitor::VisitOMPOrderedDirective(const OMPOrderedDirective *D) {
2577 VisitOMPExecutableDirective(D);
2578}
2579
Alexey Bataev0162e452014-07-22 10:10:35 +00002580void EnqueueVisitor::VisitOMPAtomicDirective(const OMPAtomicDirective *D) {
2581 VisitOMPExecutableDirective(D);
2582}
2583
Alexey Bataev0bd520b2014-09-19 08:19:49 +00002584void EnqueueVisitor::VisitOMPTargetDirective(const OMPTargetDirective *D) {
2585 VisitOMPExecutableDirective(D);
2586}
2587
Michael Wong65f367f2015-07-21 13:44:28 +00002588void EnqueueVisitor::VisitOMPTargetDataDirective(const
2589 OMPTargetDataDirective *D) {
2590 VisitOMPExecutableDirective(D);
2591}
2592
Alexey Bataev13314bf2014-10-09 04:18:56 +00002593void EnqueueVisitor::VisitOMPTeamsDirective(const OMPTeamsDirective *D) {
2594 VisitOMPExecutableDirective(D);
2595}
2596
Alexey Bataev6d4ed052015-07-01 06:57:41 +00002597void EnqueueVisitor::VisitOMPCancellationPointDirective(
2598 const OMPCancellationPointDirective *D) {
2599 VisitOMPExecutableDirective(D);
2600}
2601
Alexey Bataev80909872015-07-02 11:25:17 +00002602void EnqueueVisitor::VisitOMPCancelDirective(const OMPCancelDirective *D) {
2603 VisitOMPExecutableDirective(D);
2604}
2605
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002606void CursorVisitor::EnqueueWorkList(VisitorWorkList &WL, const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002607 EnqueueVisitor(WL, MakeCXCursor(S, StmtParent, TU,RegionOfInterest)).Visit(S);
2608}
2609
2610bool CursorVisitor::IsInRegionOfInterest(CXCursor C) {
2611 if (RegionOfInterest.isValid()) {
2612 SourceRange Range = getRawCursorExtent(C);
2613 if (Range.isInvalid() || CompareRegionOfInterest(Range))
2614 return false;
2615 }
2616 return true;
2617}
2618
2619bool CursorVisitor::RunVisitorWorkList(VisitorWorkList &WL) {
2620 while (!WL.empty()) {
2621 // Dequeue the worklist item.
Robert Wilhelm25284cc2013-08-23 16:11:15 +00002622 VisitorJob LI = WL.pop_back_val();
Guy Benyei11169dd2012-12-18 14:30:41 +00002623
2624 // Set the Parent field, then back to its old value once we're done.
2625 SetParentRAII SetParent(Parent, StmtParent, LI.getParent());
2626
2627 switch (LI.getKind()) {
2628 case VisitorJob::DeclVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002629 const Decl *D = cast<DeclVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002630 if (!D)
2631 continue;
2632
2633 // For now, perform default visitation for Decls.
2634 if (Visit(MakeCXCursor(D, TU, RegionOfInterest,
2635 cast<DeclVisit>(&LI)->isFirst())))
2636 return true;
2637
2638 continue;
2639 }
2640 case VisitorJob::ExplicitTemplateArgsVisitKind: {
2641 const ASTTemplateArgumentListInfo *ArgList =
2642 cast<ExplicitTemplateArgsVisit>(&LI)->get();
2643 for (const TemplateArgumentLoc *Arg = ArgList->getTemplateArgs(),
2644 *ArgEnd = Arg + ArgList->NumTemplateArgs;
2645 Arg != ArgEnd; ++Arg) {
2646 if (VisitTemplateArgumentLoc(*Arg))
2647 return true;
2648 }
2649 continue;
2650 }
2651 case VisitorJob::TypeLocVisitKind: {
2652 // Perform default visitation for TypeLocs.
2653 if (Visit(cast<TypeLocVisit>(&LI)->get()))
2654 return true;
2655 continue;
2656 }
2657 case VisitorJob::LabelRefVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002658 const LabelDecl *LS = cast<LabelRefVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002659 if (LabelStmt *stmt = LS->getStmt()) {
2660 if (Visit(MakeCursorLabelRef(stmt, cast<LabelRefVisit>(&LI)->getLoc(),
2661 TU))) {
2662 return true;
2663 }
2664 }
2665 continue;
2666 }
2667
2668 case VisitorJob::NestedNameSpecifierLocVisitKind: {
2669 NestedNameSpecifierLocVisit *V = cast<NestedNameSpecifierLocVisit>(&LI);
2670 if (VisitNestedNameSpecifierLoc(V->get()))
2671 return true;
2672 continue;
2673 }
2674
2675 case VisitorJob::DeclarationNameInfoVisitKind: {
2676 if (VisitDeclarationNameInfo(cast<DeclarationNameInfoVisit>(&LI)
2677 ->get()))
2678 return true;
2679 continue;
2680 }
2681 case VisitorJob::MemberRefVisitKind: {
2682 MemberRefVisit *V = cast<MemberRefVisit>(&LI);
2683 if (Visit(MakeCursorMemberRef(V->get(), V->getLoc(), TU)))
2684 return true;
2685 continue;
2686 }
2687 case VisitorJob::StmtVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002688 const Stmt *S = cast<StmtVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002689 if (!S)
2690 continue;
2691
2692 // Update the current cursor.
2693 CXCursor Cursor = MakeCXCursor(S, StmtParent, TU, RegionOfInterest);
2694 if (!IsInRegionOfInterest(Cursor))
2695 continue;
2696 switch (Visitor(Cursor, Parent, ClientData)) {
2697 case CXChildVisit_Break: return true;
2698 case CXChildVisit_Continue: break;
2699 case CXChildVisit_Recurse:
2700 if (PostChildrenVisitor)
Craig Topper69186e72014-06-08 08:38:04 +00002701 WL.push_back(PostChildrenVisit(nullptr, Cursor));
Guy Benyei11169dd2012-12-18 14:30:41 +00002702 EnqueueWorkList(WL, S);
2703 break;
2704 }
2705 continue;
2706 }
2707 case VisitorJob::MemberExprPartsKind: {
2708 // Handle the other pieces in the MemberExpr besides the base.
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002709 const MemberExpr *M = cast<MemberExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002710
2711 // Visit the nested-name-specifier
2712 if (NestedNameSpecifierLoc QualifierLoc = M->getQualifierLoc())
2713 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2714 return true;
2715
2716 // Visit the declaration name.
2717 if (VisitDeclarationNameInfo(M->getMemberNameInfo()))
2718 return true;
2719
2720 // Visit the explicitly-specified template arguments, if any.
2721 if (M->hasExplicitTemplateArgs()) {
2722 for (const TemplateArgumentLoc *Arg = M->getTemplateArgs(),
2723 *ArgEnd = Arg + M->getNumTemplateArgs();
2724 Arg != ArgEnd; ++Arg) {
2725 if (VisitTemplateArgumentLoc(*Arg))
2726 return true;
2727 }
2728 }
2729 continue;
2730 }
2731 case VisitorJob::DeclRefExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002732 const DeclRefExpr *DR = cast<DeclRefExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002733 // Visit nested-name-specifier, if present.
2734 if (NestedNameSpecifierLoc QualifierLoc = DR->getQualifierLoc())
2735 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2736 return true;
2737 // Visit declaration name.
2738 if (VisitDeclarationNameInfo(DR->getNameInfo()))
2739 return true;
2740 continue;
2741 }
2742 case VisitorJob::OverloadExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002743 const OverloadExpr *O = cast<OverloadExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002744 // Visit the nested-name-specifier.
2745 if (NestedNameSpecifierLoc QualifierLoc = O->getQualifierLoc())
2746 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2747 return true;
2748 // Visit the declaration name.
2749 if (VisitDeclarationNameInfo(O->getNameInfo()))
2750 return true;
2751 // Visit the overloaded declaration reference.
2752 if (Visit(MakeCursorOverloadedDeclRef(O, TU)))
2753 return true;
2754 continue;
2755 }
2756 case VisitorJob::SizeOfPackExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002757 const SizeOfPackExpr *E = cast<SizeOfPackExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002758 NamedDecl *Pack = E->getPack();
2759 if (isa<TemplateTypeParmDecl>(Pack)) {
2760 if (Visit(MakeCursorTypeRef(cast<TemplateTypeParmDecl>(Pack),
2761 E->getPackLoc(), TU)))
2762 return true;
2763
2764 continue;
2765 }
2766
2767 if (isa<TemplateTemplateParmDecl>(Pack)) {
2768 if (Visit(MakeCursorTemplateRef(cast<TemplateTemplateParmDecl>(Pack),
2769 E->getPackLoc(), TU)))
2770 return true;
2771
2772 continue;
2773 }
2774
2775 // Non-type template parameter packs and function parameter packs are
2776 // treated like DeclRefExpr cursors.
2777 continue;
2778 }
2779
2780 case VisitorJob::LambdaExprPartsKind: {
2781 // Visit captures.
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002782 const LambdaExpr *E = cast<LambdaExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002783 for (LambdaExpr::capture_iterator C = E->explicit_capture_begin(),
2784 CEnd = E->explicit_capture_end();
2785 C != CEnd; ++C) {
Richard Smithba71c082013-05-16 06:20:58 +00002786 // FIXME: Lambda init-captures.
2787 if (!C->capturesVariable())
Guy Benyei11169dd2012-12-18 14:30:41 +00002788 continue;
Richard Smithba71c082013-05-16 06:20:58 +00002789
Guy Benyei11169dd2012-12-18 14:30:41 +00002790 if (Visit(MakeCursorVariableRef(C->getCapturedVar(),
2791 C->getLocation(),
2792 TU)))
2793 return true;
2794 }
2795
2796 // Visit parameters and return type, if present.
2797 if (E->hasExplicitParameters() || E->hasExplicitResultType()) {
2798 TypeLoc TL = E->getCallOperator()->getTypeSourceInfo()->getTypeLoc();
2799 if (E->hasExplicitParameters() && E->hasExplicitResultType()) {
2800 // Visit the whole type.
2801 if (Visit(TL))
2802 return true;
David Blaikie6adc78e2013-02-18 22:06:02 +00002803 } else if (FunctionProtoTypeLoc Proto =
2804 TL.getAs<FunctionProtoTypeLoc>()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002805 if (E->hasExplicitParameters()) {
2806 // Visit parameters.
Alp Tokerb3fd5cf2014-01-21 00:32:38 +00002807 for (unsigned I = 0, N = Proto.getNumParams(); I != N; ++I)
2808 if (Visit(MakeCXCursor(Proto.getParam(I), TU)))
Guy Benyei11169dd2012-12-18 14:30:41 +00002809 return true;
2810 } else {
2811 // Visit result type.
Alp Toker42a16a62014-01-25 23:51:36 +00002812 if (Visit(Proto.getReturnLoc()))
Guy Benyei11169dd2012-12-18 14:30:41 +00002813 return true;
2814 }
2815 }
2816 }
2817 break;
2818 }
2819
2820 case VisitorJob::PostChildrenVisitKind:
2821 if (PostChildrenVisitor(Parent, ClientData))
2822 return true;
2823 break;
2824 }
2825 }
2826 return false;
2827}
2828
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002829bool CursorVisitor::Visit(const Stmt *S) {
Craig Topper69186e72014-06-08 08:38:04 +00002830 VisitorWorkList *WL = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00002831 if (!WorkListFreeList.empty()) {
2832 WL = WorkListFreeList.back();
2833 WL->clear();
2834 WorkListFreeList.pop_back();
2835 }
2836 else {
2837 WL = new VisitorWorkList();
2838 WorkListCache.push_back(WL);
2839 }
2840 EnqueueWorkList(*WL, S);
2841 bool result = RunVisitorWorkList(*WL);
2842 WorkListFreeList.push_back(WL);
2843 return result;
2844}
2845
2846namespace {
Dmitri Gribenkof8579502013-01-12 19:30:44 +00002847typedef SmallVector<SourceRange, 4> RefNamePieces;
Craig Topper69186e72014-06-08 08:38:04 +00002848RefNamePieces
2849buildPieces(unsigned NameFlags, bool IsMemberRefExpr,
Craig Toppere335f252015-10-04 04:53:55 +00002850 const DeclarationNameInfo &NI, SourceRange QLoc,
Craig Topper69186e72014-06-08 08:38:04 +00002851 const ASTTemplateArgumentListInfo *TemplateArgs = nullptr) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002852 const bool WantQualifier = NameFlags & CXNameRange_WantQualifier;
2853 const bool WantTemplateArgs = NameFlags & CXNameRange_WantTemplateArgs;
2854 const bool WantSinglePiece = NameFlags & CXNameRange_WantSinglePiece;
2855
2856 const DeclarationName::NameKind Kind = NI.getName().getNameKind();
2857
2858 RefNamePieces Pieces;
2859
2860 if (WantQualifier && QLoc.isValid())
2861 Pieces.push_back(QLoc);
2862
2863 if (Kind != DeclarationName::CXXOperatorName || IsMemberRefExpr)
2864 Pieces.push_back(NI.getLoc());
2865
2866 if (WantTemplateArgs && TemplateArgs)
2867 Pieces.push_back(SourceRange(TemplateArgs->LAngleLoc,
2868 TemplateArgs->RAngleLoc));
2869
2870 if (Kind == DeclarationName::CXXOperatorName) {
2871 Pieces.push_back(SourceLocation::getFromRawEncoding(
2872 NI.getInfo().CXXOperatorName.BeginOpNameLoc));
2873 Pieces.push_back(SourceLocation::getFromRawEncoding(
2874 NI.getInfo().CXXOperatorName.EndOpNameLoc));
2875 }
2876
2877 if (WantSinglePiece) {
2878 SourceRange R(Pieces.front().getBegin(), Pieces.back().getEnd());
2879 Pieces.clear();
2880 Pieces.push_back(R);
2881 }
2882
2883 return Pieces;
2884}
Alexander Kornienkoab9db512015-06-22 23:07:51 +00002885}
Guy Benyei11169dd2012-12-18 14:30:41 +00002886
2887//===----------------------------------------------------------------------===//
2888// Misc. API hooks.
2889//===----------------------------------------------------------------------===//
2890
Chad Rosier05c71aa2013-03-27 18:28:23 +00002891static void fatal_error_handler(void *user_data, const std::string& reason,
2892 bool gen_crash_diag) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002893 // Write the result out to stderr avoiding errs() because raw_ostreams can
2894 // call report_fatal_error.
2895 fprintf(stderr, "LIBCLANG FATAL ERROR: %s\n", reason.c_str());
2896 ::abort();
2897}
2898
Chandler Carruth66660742014-06-27 16:37:27 +00002899namespace {
2900struct RegisterFatalErrorHandler {
2901 RegisterFatalErrorHandler() {
2902 llvm::install_fatal_error_handler(fatal_error_handler, nullptr);
2903 }
2904};
2905}
2906
2907static llvm::ManagedStatic<RegisterFatalErrorHandler> RegisterFatalErrorHandlerOnce;
2908
Guy Benyei11169dd2012-12-18 14:30:41 +00002909extern "C" {
2910CXIndex clang_createIndex(int excludeDeclarationsFromPCH,
2911 int displayDiagnostics) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002912 // We use crash recovery to make some of our APIs more reliable, implicitly
2913 // enable it.
Argyrios Kyrtzidis3701f542013-11-27 08:58:09 +00002914 if (!getenv("LIBCLANG_DISABLE_CRASH_RECOVERY"))
2915 llvm::CrashRecoveryContext::Enable();
Guy Benyei11169dd2012-12-18 14:30:41 +00002916
Chandler Carruth66660742014-06-27 16:37:27 +00002917 // Look through the managed static to trigger construction of the managed
2918 // static which registers our fatal error handler. This ensures it is only
2919 // registered once.
2920 (void)*RegisterFatalErrorHandlerOnce;
Guy Benyei11169dd2012-12-18 14:30:41 +00002921
Adrian Prantlbc068582015-07-08 01:00:30 +00002922 // Initialize targets for clang module support.
2923 llvm::InitializeAllTargets();
2924 llvm::InitializeAllTargetMCs();
2925 llvm::InitializeAllAsmPrinters();
2926 llvm::InitializeAllAsmParsers();
2927
Adrian Prantlfb2398d2015-07-17 01:19:54 +00002928 CIndexer *CIdxr = new CIndexer();
2929
Guy Benyei11169dd2012-12-18 14:30:41 +00002930 if (excludeDeclarationsFromPCH)
2931 CIdxr->setOnlyLocalDecls();
2932 if (displayDiagnostics)
2933 CIdxr->setDisplayDiagnostics();
2934
2935 if (getenv("LIBCLANG_BGPRIO_INDEX"))
2936 CIdxr->setCXGlobalOptFlags(CIdxr->getCXGlobalOptFlags() |
2937 CXGlobalOpt_ThreadBackgroundPriorityForIndexing);
2938 if (getenv("LIBCLANG_BGPRIO_EDIT"))
2939 CIdxr->setCXGlobalOptFlags(CIdxr->getCXGlobalOptFlags() |
2940 CXGlobalOpt_ThreadBackgroundPriorityForEditing);
2941
2942 return CIdxr;
2943}
2944
2945void clang_disposeIndex(CXIndex CIdx) {
2946 if (CIdx)
2947 delete static_cast<CIndexer *>(CIdx);
2948}
2949
2950void clang_CXIndex_setGlobalOptions(CXIndex CIdx, unsigned options) {
2951 if (CIdx)
2952 static_cast<CIndexer *>(CIdx)->setCXGlobalOptFlags(options);
2953}
2954
2955unsigned clang_CXIndex_getGlobalOptions(CXIndex CIdx) {
2956 if (CIdx)
2957 return static_cast<CIndexer *>(CIdx)->getCXGlobalOptFlags();
2958 return 0;
2959}
2960
2961void clang_toggleCrashRecovery(unsigned isEnabled) {
2962 if (isEnabled)
2963 llvm::CrashRecoveryContext::Enable();
2964 else
2965 llvm::CrashRecoveryContext::Disable();
2966}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002967
Guy Benyei11169dd2012-12-18 14:30:41 +00002968CXTranslationUnit clang_createTranslationUnit(CXIndex CIdx,
2969 const char *ast_filename) {
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00002970 CXTranslationUnit TU;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002971 enum CXErrorCode Result =
2972 clang_createTranslationUnit2(CIdx, ast_filename, &TU);
Reid Klecknerfd48fc62014-02-12 23:56:20 +00002973 (void)Result;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002974 assert((TU && Result == CXError_Success) ||
2975 (!TU && Result != CXError_Success));
2976 return TU;
2977}
2978
2979enum CXErrorCode clang_createTranslationUnit2(CXIndex CIdx,
2980 const char *ast_filename,
2981 CXTranslationUnit *out_TU) {
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00002982 if (out_TU)
Craig Topper69186e72014-06-08 08:38:04 +00002983 *out_TU = nullptr;
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00002984
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002985 if (!CIdx || !ast_filename || !out_TU)
2986 return CXError_InvalidArguments;
Guy Benyei11169dd2012-12-18 14:30:41 +00002987
Argyrios Kyrtzidis27021012013-05-24 22:24:07 +00002988 LOG_FUNC_SECTION {
2989 *Log << ast_filename;
2990 }
2991
Guy Benyei11169dd2012-12-18 14:30:41 +00002992 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
2993 FileSystemOptions FileSystemOpts;
2994
Justin Bognerd512c1e2014-10-15 00:33:06 +00002995 IntrusiveRefCntPtr<DiagnosticsEngine> Diags =
2996 CompilerInstance::createDiagnostics(new DiagnosticOptions());
David Blaikie6f7382d2014-08-10 19:08:04 +00002997 std::unique_ptr<ASTUnit> AU = ASTUnit::LoadFromASTFile(
Adrian Prantlfb2398d2015-07-17 01:19:54 +00002998 ast_filename, CXXIdx->getPCHContainerOperations()->getRawReader(), Diags,
Adrian Prantl6b21ab22015-08-27 19:46:20 +00002999 FileSystemOpts, /*UseDebugInfo=*/false,
3000 CXXIdx->getOnlyLocalDecls(), None,
David Blaikie6f7382d2014-08-10 19:08:04 +00003001 /*CaptureDiagnostics=*/true,
3002 /*AllowPCHWithCompilerErrors=*/true,
3003 /*UserFilesAreVolatile=*/true);
3004 *out_TU = MakeCXTranslationUnit(CXXIdx, AU.release());
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003005 return *out_TU ? CXError_Success : CXError_Failure;
Guy Benyei11169dd2012-12-18 14:30:41 +00003006}
3007
3008unsigned clang_defaultEditingTranslationUnitOptions() {
3009 return CXTranslationUnit_PrecompiledPreamble |
3010 CXTranslationUnit_CacheCompletionResults;
3011}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003012
Guy Benyei11169dd2012-12-18 14:30:41 +00003013CXTranslationUnit
3014clang_createTranslationUnitFromSourceFile(CXIndex CIdx,
3015 const char *source_filename,
3016 int num_command_line_args,
3017 const char * const *command_line_args,
3018 unsigned num_unsaved_files,
3019 struct CXUnsavedFile *unsaved_files) {
3020 unsigned Options = CXTranslationUnit_DetailedPreprocessingRecord;
3021 return clang_parseTranslationUnit(CIdx, source_filename,
3022 command_line_args, num_command_line_args,
3023 unsaved_files, num_unsaved_files,
3024 Options);
3025}
3026
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003027static CXErrorCode
3028clang_parseTranslationUnit_Impl(CXIndex CIdx, const char *source_filename,
3029 const char *const *command_line_args,
3030 int num_command_line_args,
3031 ArrayRef<CXUnsavedFile> unsaved_files,
3032 unsigned options, CXTranslationUnit *out_TU) {
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00003033 // Set up the initial return values.
3034 if (out_TU)
Craig Topper69186e72014-06-08 08:38:04 +00003035 *out_TU = nullptr;
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00003036
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003037 // Check arguments.
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003038 if (!CIdx || !out_TU)
3039 return CXError_InvalidArguments;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003040
Guy Benyei11169dd2012-12-18 14:30:41 +00003041 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
3042
3043 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
3044 setThreadBackgroundPriority();
3045
3046 bool PrecompilePreamble = options & CXTranslationUnit_PrecompiledPreamble;
3047 // FIXME: Add a flag for modules.
3048 TranslationUnitKind TUKind
3049 = (options & CXTranslationUnit_Incomplete)? TU_Prefix : TU_Complete;
Alp Toker8c8a8752013-12-03 06:53:35 +00003050 bool CacheCodeCompletionResults
Guy Benyei11169dd2012-12-18 14:30:41 +00003051 = options & CXTranslationUnit_CacheCompletionResults;
3052 bool IncludeBriefCommentsInCodeCompletion
3053 = options & CXTranslationUnit_IncludeBriefCommentsInCodeCompletion;
3054 bool SkipFunctionBodies = options & CXTranslationUnit_SkipFunctionBodies;
3055 bool ForSerialization = options & CXTranslationUnit_ForSerialization;
3056
3057 // Configure the diagnostics.
3058 IntrusiveRefCntPtr<DiagnosticsEngine>
Sean Silvaf1b49e22013-01-20 01:58:28 +00003059 Diags(CompilerInstance::createDiagnostics(new DiagnosticOptions));
Guy Benyei11169dd2012-12-18 14:30:41 +00003060
3061 // Recover resources if we crash before exiting this function.
3062 llvm::CrashRecoveryContextCleanupRegistrar<DiagnosticsEngine,
3063 llvm::CrashRecoveryContextReleaseRefCleanup<DiagnosticsEngine> >
Alp Tokerf994cef2014-07-05 03:08:06 +00003064 DiagCleanup(Diags.get());
Guy Benyei11169dd2012-12-18 14:30:41 +00003065
Ahmed Charlesb8984322014-03-07 20:03:18 +00003066 std::unique_ptr<std::vector<ASTUnit::RemappedFile>> RemappedFiles(
3067 new std::vector<ASTUnit::RemappedFile>());
Guy Benyei11169dd2012-12-18 14:30:41 +00003068
3069 // Recover resources if we crash before exiting this function.
3070 llvm::CrashRecoveryContextCleanupRegistrar<
3071 std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
3072
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003073 for (auto &UF : unsaved_files) {
Rafael Espindolad87f8d72014-08-27 20:03:29 +00003074 std::unique_ptr<llvm::MemoryBuffer> MB =
Alp Toker9d85b182014-07-07 01:23:14 +00003075 llvm::MemoryBuffer::getMemBufferCopy(getContents(UF), UF.Filename);
Rafael Espindolad87f8d72014-08-27 20:03:29 +00003076 RemappedFiles->push_back(std::make_pair(UF.Filename, MB.release()));
Guy Benyei11169dd2012-12-18 14:30:41 +00003077 }
3078
Ahmed Charlesb8984322014-03-07 20:03:18 +00003079 std::unique_ptr<std::vector<const char *>> Args(
3080 new std::vector<const char *>());
Guy Benyei11169dd2012-12-18 14:30:41 +00003081
3082 // Recover resources if we crash before exiting this method.
3083 llvm::CrashRecoveryContextCleanupRegistrar<std::vector<const char*> >
3084 ArgsCleanup(Args.get());
3085
3086 // Since the Clang C library is primarily used by batch tools dealing with
3087 // (often very broken) source code, where spell-checking can have a
3088 // significant negative impact on performance (particularly when
3089 // precompiled headers are involved), we disable it by default.
3090 // Only do this if we haven't found a spell-checking-related argument.
3091 bool FoundSpellCheckingArgument = false;
3092 for (int I = 0; I != num_command_line_args; ++I) {
3093 if (strcmp(command_line_args[I], "-fno-spell-checking") == 0 ||
3094 strcmp(command_line_args[I], "-fspell-checking") == 0) {
3095 FoundSpellCheckingArgument = true;
3096 break;
3097 }
3098 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003099 Args->insert(Args->end(), command_line_args,
3100 command_line_args + num_command_line_args);
3101
Benjamin Kramerc02670e2015-11-18 16:14:27 +00003102 if (!FoundSpellCheckingArgument)
3103 Args->insert(Args->begin() + 1, "-fno-spell-checking");
3104
Guy Benyei11169dd2012-12-18 14:30:41 +00003105 // The 'source_filename' argument is optional. If the caller does not
3106 // specify it then it is assumed that the source file is specified
3107 // in the actual argument list.
3108 // Put the source file after command_line_args otherwise if '-x' flag is
3109 // present it will be unused.
3110 if (source_filename)
3111 Args->push_back(source_filename);
3112
3113 // Do we need the detailed preprocessing record?
3114 if (options & CXTranslationUnit_DetailedPreprocessingRecord) {
3115 Args->push_back("-Xclang");
3116 Args->push_back("-detailed-preprocessing-record");
3117 }
3118
3119 unsigned NumErrors = Diags->getClient()->getNumErrors();
Ahmed Charlesb8984322014-03-07 20:03:18 +00003120 std::unique_ptr<ASTUnit> ErrUnit;
3121 std::unique_ptr<ASTUnit> Unit(ASTUnit::LoadFromCommandLine(
Adrian Prantlbb165fb2015-06-20 18:53:08 +00003122 Args->data(), Args->data() + Args->size(),
3123 CXXIdx->getPCHContainerOperations(), Diags,
Ahmed Charlesb8984322014-03-07 20:03:18 +00003124 CXXIdx->getClangResourcesPath(), CXXIdx->getOnlyLocalDecls(),
3125 /*CaptureDiagnostics=*/true, *RemappedFiles.get(),
3126 /*RemappedFilesKeepOriginalName=*/true, PrecompilePreamble, TUKind,
3127 CacheCodeCompletionResults, IncludeBriefCommentsInCodeCompletion,
3128 /*AllowPCHWithCompilerErrors=*/true, SkipFunctionBodies,
Argyrios Kyrtzidisa3e2ff12015-11-20 03:36:21 +00003129 /*UserFilesAreVolatile=*/true, ForSerialization,
3130 CXXIdx->getPCHContainerOperations()->getRawReader().getFormat(),
3131 &ErrUnit));
Guy Benyei11169dd2012-12-18 14:30:41 +00003132
Artem Belevich0ff05cd2015-07-13 23:27:56 +00003133 // Early failures in LoadFromCommandLine may return with ErrUnit unset.
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003134 if (!Unit && !ErrUnit)
3135 return CXError_ASTReadError;
Artem Belevich0ff05cd2015-07-13 23:27:56 +00003136
Guy Benyei11169dd2012-12-18 14:30:41 +00003137 if (NumErrors != Diags->getClient()->getNumErrors()) {
3138 // Make sure to check that 'Unit' is non-NULL.
3139 if (CXXIdx->getDisplayDiagnostics())
3140 printDiagsToStderr(Unit ? Unit.get() : ErrUnit.get());
3141 }
3142
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003143 if (isASTReadError(Unit ? Unit.get() : ErrUnit.get()))
3144 return CXError_ASTReadError;
3145
3146 *out_TU = MakeCXTranslationUnit(CXXIdx, Unit.release());
3147 return *out_TU ? CXError_Success : CXError_Failure;
Guy Benyei11169dd2012-12-18 14:30:41 +00003148}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003149
3150CXTranslationUnit
3151clang_parseTranslationUnit(CXIndex CIdx,
3152 const char *source_filename,
3153 const char *const *command_line_args,
3154 int num_command_line_args,
3155 struct CXUnsavedFile *unsaved_files,
3156 unsigned num_unsaved_files,
3157 unsigned options) {
3158 CXTranslationUnit TU;
3159 enum CXErrorCode Result = clang_parseTranslationUnit2(
3160 CIdx, source_filename, command_line_args, num_command_line_args,
3161 unsaved_files, num_unsaved_files, options, &TU);
Reid Kleckner6eaf05a2014-02-13 01:19:59 +00003162 (void)Result;
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00003163 assert((TU && Result == CXError_Success) ||
3164 (!TU && Result != CXError_Success));
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003165 return TU;
3166}
3167
3168enum CXErrorCode clang_parseTranslationUnit2(
Benjamin Kramerc02670e2015-11-18 16:14:27 +00003169 CXIndex CIdx, const char *source_filename,
3170 const char *const *command_line_args, int num_command_line_args,
3171 struct CXUnsavedFile *unsaved_files, unsigned num_unsaved_files,
3172 unsigned options, CXTranslationUnit *out_TU) {
3173 SmallVector<const char *, 4> Args;
3174 Args.push_back("clang");
3175 Args.append(command_line_args, command_line_args + num_command_line_args);
3176 return clang_parseTranslationUnit2FullArgv(
3177 CIdx, source_filename, Args.data(), Args.size(), unsaved_files,
3178 num_unsaved_files, options, out_TU);
3179}
3180
3181enum CXErrorCode clang_parseTranslationUnit2FullArgv(
3182 CXIndex CIdx, const char *source_filename,
3183 const char *const *command_line_args, int num_command_line_args,
3184 struct CXUnsavedFile *unsaved_files, unsigned num_unsaved_files,
3185 unsigned options, CXTranslationUnit *out_TU) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00003186 LOG_FUNC_SECTION {
3187 *Log << source_filename << ": ";
3188 for (int i = 0; i != num_command_line_args; ++i)
3189 *Log << command_line_args[i] << " ";
3190 }
3191
Alp Toker9d85b182014-07-07 01:23:14 +00003192 if (num_unsaved_files && !unsaved_files)
3193 return CXError_InvalidArguments;
3194
Alp Toker5c532982014-07-07 22:42:03 +00003195 CXErrorCode result = CXError_Failure;
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003196 auto ParseTranslationUnitImpl = [=, &result] {
3197 result = clang_parseTranslationUnit_Impl(
3198 CIdx, source_filename, command_line_args, num_command_line_args,
3199 llvm::makeArrayRef(unsaved_files, num_unsaved_files), options, out_TU);
3200 };
Guy Benyei11169dd2012-12-18 14:30:41 +00003201 llvm::CrashRecoveryContext CRC;
3202
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003203 if (!RunSafely(CRC, ParseTranslationUnitImpl)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003204 fprintf(stderr, "libclang: crash detected during parsing: {\n");
3205 fprintf(stderr, " 'source_filename' : '%s'\n", source_filename);
3206 fprintf(stderr, " 'command_line_args' : [");
3207 for (int i = 0; i != num_command_line_args; ++i) {
3208 if (i)
3209 fprintf(stderr, ", ");
3210 fprintf(stderr, "'%s'", command_line_args[i]);
3211 }
3212 fprintf(stderr, "],\n");
3213 fprintf(stderr, " 'unsaved_files' : [");
3214 for (unsigned i = 0; i != num_unsaved_files; ++i) {
3215 if (i)
3216 fprintf(stderr, ", ");
3217 fprintf(stderr, "('%s', '...', %ld)", unsaved_files[i].Filename,
3218 unsaved_files[i].Length);
3219 }
3220 fprintf(stderr, "],\n");
3221 fprintf(stderr, " 'options' : %d,\n", options);
3222 fprintf(stderr, "}\n");
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003223
3224 return CXError_Crashed;
Guy Benyei11169dd2012-12-18 14:30:41 +00003225 } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003226 if (CXTranslationUnit *TU = out_TU)
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003227 PrintLibclangResourceUsage(*TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003228 }
Alp Toker5c532982014-07-07 22:42:03 +00003229
3230 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003231}
3232
3233unsigned clang_defaultSaveOptions(CXTranslationUnit TU) {
3234 return CXSaveTranslationUnit_None;
3235}
3236
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003237static CXSaveError clang_saveTranslationUnit_Impl(CXTranslationUnit TU,
3238 const char *FileName,
3239 unsigned options) {
3240 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00003241 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
3242 setThreadBackgroundPriority();
3243
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003244 bool hadError = cxtu::getASTUnit(TU)->Save(FileName);
3245 return hadError ? CXSaveError_Unknown : CXSaveError_None;
Guy Benyei11169dd2012-12-18 14:30:41 +00003246}
3247
3248int clang_saveTranslationUnit(CXTranslationUnit TU, const char *FileName,
3249 unsigned options) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00003250 LOG_FUNC_SECTION {
3251 *Log << TU << ' ' << FileName;
3252 }
3253
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003254 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003255 LOG_BAD_TU(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003256 return CXSaveError_InvalidTU;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003257 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003258
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003259 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003260 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
3261 if (!CXXUnit->hasSema())
3262 return CXSaveError_InvalidTU;
3263
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003264 CXSaveError result;
3265 auto SaveTranslationUnitImpl = [=, &result]() {
3266 result = clang_saveTranslationUnit_Impl(TU, FileName, options);
3267 };
Guy Benyei11169dd2012-12-18 14:30:41 +00003268
3269 if (!CXXUnit->getDiagnostics().hasUnrecoverableErrorOccurred() ||
3270 getenv("LIBCLANG_NOTHREADS")) {
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003271 SaveTranslationUnitImpl();
Guy Benyei11169dd2012-12-18 14:30:41 +00003272
3273 if (getenv("LIBCLANG_RESOURCE_USAGE"))
3274 PrintLibclangResourceUsage(TU);
3275
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003276 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003277 }
3278
3279 // We have an AST that has invalid nodes due to compiler errors.
3280 // Use a crash recovery thread for protection.
3281
3282 llvm::CrashRecoveryContext CRC;
3283
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003284 if (!RunSafely(CRC, SaveTranslationUnitImpl)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003285 fprintf(stderr, "libclang: crash detected during AST saving: {\n");
3286 fprintf(stderr, " 'filename' : '%s'\n", FileName);
3287 fprintf(stderr, " 'options' : %d,\n", options);
3288 fprintf(stderr, "}\n");
3289
3290 return CXSaveError_Unknown;
3291
3292 } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
3293 PrintLibclangResourceUsage(TU);
3294 }
3295
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003296 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003297}
3298
3299void clang_disposeTranslationUnit(CXTranslationUnit CTUnit) {
3300 if (CTUnit) {
3301 // If the translation unit has been marked as unsafe to free, just discard
3302 // it.
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003303 ASTUnit *Unit = cxtu::getASTUnit(CTUnit);
3304 if (Unit && Unit->isUnsafeToFree())
Guy Benyei11169dd2012-12-18 14:30:41 +00003305 return;
3306
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003307 delete cxtu::getASTUnit(CTUnit);
Dmitri Gribenkob95b3f12013-01-26 22:44:19 +00003308 delete CTUnit->StringPool;
Guy Benyei11169dd2012-12-18 14:30:41 +00003309 delete static_cast<CXDiagnosticSetImpl *>(CTUnit->Diagnostics);
3310 disposeOverridenCXCursorsPool(CTUnit->OverridenCursorsPool);
Dmitri Gribenko9e605112013-11-13 22:16:51 +00003311 delete CTUnit->CommentToXML;
Guy Benyei11169dd2012-12-18 14:30:41 +00003312 delete CTUnit;
3313 }
3314}
3315
3316unsigned clang_defaultReparseOptions(CXTranslationUnit TU) {
3317 return CXReparse_None;
3318}
3319
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003320static CXErrorCode
3321clang_reparseTranslationUnit_Impl(CXTranslationUnit TU,
3322 ArrayRef<CXUnsavedFile> unsaved_files,
3323 unsigned options) {
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003324 // Check arguments.
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003325 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003326 LOG_BAD_TU(TU);
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003327 return CXError_InvalidArguments;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003328 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003329
3330 // Reset the associated diagnostics.
3331 delete static_cast<CXDiagnosticSetImpl*>(TU->Diagnostics);
Craig Topper69186e72014-06-08 08:38:04 +00003332 TU->Diagnostics = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00003333
Dmitri Gribenko183436e2013-01-26 21:49:50 +00003334 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00003335 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
3336 setThreadBackgroundPriority();
3337
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003338 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003339 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
Ahmed Charlesb8984322014-03-07 20:03:18 +00003340
3341 std::unique_ptr<std::vector<ASTUnit::RemappedFile>> RemappedFiles(
3342 new std::vector<ASTUnit::RemappedFile>());
3343
Guy Benyei11169dd2012-12-18 14:30:41 +00003344 // Recover resources if we crash before exiting this function.
3345 llvm::CrashRecoveryContextCleanupRegistrar<
3346 std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
Alp Toker9d85b182014-07-07 01:23:14 +00003347
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003348 for (auto &UF : unsaved_files) {
Rafael Espindolad87f8d72014-08-27 20:03:29 +00003349 std::unique_ptr<llvm::MemoryBuffer> MB =
Alp Toker9d85b182014-07-07 01:23:14 +00003350 llvm::MemoryBuffer::getMemBufferCopy(getContents(UF), UF.Filename);
Rafael Espindolad87f8d72014-08-27 20:03:29 +00003351 RemappedFiles->push_back(std::make_pair(UF.Filename, MB.release()));
Guy Benyei11169dd2012-12-18 14:30:41 +00003352 }
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003353
Adrian Prantlbb165fb2015-06-20 18:53:08 +00003354 if (!CXXUnit->Reparse(CXXIdx->getPCHContainerOperations(),
3355 *RemappedFiles.get()))
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003356 return CXError_Success;
3357 if (isASTReadError(CXXUnit))
3358 return CXError_ASTReadError;
3359 return CXError_Failure;
Guy Benyei11169dd2012-12-18 14:30:41 +00003360}
3361
3362int clang_reparseTranslationUnit(CXTranslationUnit TU,
3363 unsigned num_unsaved_files,
3364 struct CXUnsavedFile *unsaved_files,
3365 unsigned options) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00003366 LOG_FUNC_SECTION {
3367 *Log << TU;
3368 }
3369
Alp Toker9d85b182014-07-07 01:23:14 +00003370 if (num_unsaved_files && !unsaved_files)
3371 return CXError_InvalidArguments;
3372
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003373 CXErrorCode result;
3374 auto ReparseTranslationUnitImpl = [=, &result]() {
3375 result = clang_reparseTranslationUnit_Impl(
3376 TU, llvm::makeArrayRef(unsaved_files, num_unsaved_files), options);
3377 };
Guy Benyei11169dd2012-12-18 14:30:41 +00003378
3379 if (getenv("LIBCLANG_NOTHREADS")) {
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003380 ReparseTranslationUnitImpl();
Alp Toker5c532982014-07-07 22:42:03 +00003381 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003382 }
3383
3384 llvm::CrashRecoveryContext CRC;
3385
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003386 if (!RunSafely(CRC, ReparseTranslationUnitImpl)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003387 fprintf(stderr, "libclang: crash detected during reparsing\n");
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003388 cxtu::getASTUnit(TU)->setUnsafeToFree(true);
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003389 return CXError_Crashed;
Guy Benyei11169dd2012-12-18 14:30:41 +00003390 } else if (getenv("LIBCLANG_RESOURCE_USAGE"))
3391 PrintLibclangResourceUsage(TU);
3392
Alp Toker5c532982014-07-07 22:42:03 +00003393 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003394}
3395
3396
3397CXString clang_getTranslationUnitSpelling(CXTranslationUnit CTUnit) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003398 if (isNotUsableTU(CTUnit)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003399 LOG_BAD_TU(CTUnit);
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003400 return cxstring::createEmpty();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003401 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003402
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003403 ASTUnit *CXXUnit = cxtu::getASTUnit(CTUnit);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003404 return cxstring::createDup(CXXUnit->getOriginalSourceFileName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003405}
3406
3407CXCursor clang_getTranslationUnitCursor(CXTranslationUnit TU) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003408 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003409 LOG_BAD_TU(TU);
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00003410 return clang_getNullCursor();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003411 }
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00003412
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003413 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003414 return MakeCXCursor(CXXUnit->getASTContext().getTranslationUnitDecl(), TU);
3415}
3416
3417} // end: extern "C"
3418
3419//===----------------------------------------------------------------------===//
3420// CXFile Operations.
3421//===----------------------------------------------------------------------===//
3422
3423extern "C" {
3424CXString clang_getFileName(CXFile SFile) {
3425 if (!SFile)
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00003426 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00003427
3428 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003429 return cxstring::createRef(FEnt->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003430}
3431
3432time_t clang_getFileTime(CXFile SFile) {
3433 if (!SFile)
3434 return 0;
3435
3436 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
3437 return FEnt->getModificationTime();
3438}
3439
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003440CXFile clang_getFile(CXTranslationUnit TU, const char *file_name) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003441 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003442 LOG_BAD_TU(TU);
Craig Topper69186e72014-06-08 08:38:04 +00003443 return nullptr;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003444 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003445
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003446 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003447
3448 FileManager &FMgr = CXXUnit->getFileManager();
3449 return const_cast<FileEntry *>(FMgr.getFile(file_name));
3450}
3451
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003452unsigned clang_isFileMultipleIncludeGuarded(CXTranslationUnit TU,
3453 CXFile file) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003454 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003455 LOG_BAD_TU(TU);
3456 return 0;
3457 }
3458
3459 if (!file)
Guy Benyei11169dd2012-12-18 14:30:41 +00003460 return 0;
3461
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003462 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003463 FileEntry *FEnt = static_cast<FileEntry *>(file);
3464 return CXXUnit->getPreprocessor().getHeaderSearchInfo()
3465 .isFileMultipleIncludeGuarded(FEnt);
3466}
3467
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003468int clang_getFileUniqueID(CXFile file, CXFileUniqueID *outID) {
3469 if (!file || !outID)
3470 return 1;
3471
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003472 FileEntry *FEnt = static_cast<FileEntry *>(file);
Rafael Espindolaf8f91b82013-08-01 21:42:11 +00003473 const llvm::sys::fs::UniqueID &ID = FEnt->getUniqueID();
3474 outID->data[0] = ID.getDevice();
3475 outID->data[1] = ID.getFile();
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003476 outID->data[2] = FEnt->getModificationTime();
3477 return 0;
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003478}
3479
Argyrios Kyrtzidisac3997e2014-08-16 00:26:19 +00003480int clang_File_isEqual(CXFile file1, CXFile file2) {
3481 if (file1 == file2)
3482 return true;
3483
3484 if (!file1 || !file2)
3485 return false;
3486
3487 FileEntry *FEnt1 = static_cast<FileEntry *>(file1);
3488 FileEntry *FEnt2 = static_cast<FileEntry *>(file2);
3489 return FEnt1->getUniqueID() == FEnt2->getUniqueID();
3490}
3491
Guy Benyei11169dd2012-12-18 14:30:41 +00003492} // end: extern "C"
3493
3494//===----------------------------------------------------------------------===//
3495// CXCursor Operations.
3496//===----------------------------------------------------------------------===//
3497
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003498static const Decl *getDeclFromExpr(const Stmt *E) {
3499 if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003500 return getDeclFromExpr(CE->getSubExpr());
3501
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003502 if (const DeclRefExpr *RefExpr = dyn_cast<DeclRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003503 return RefExpr->getDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003504 if (const MemberExpr *ME = dyn_cast<MemberExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003505 return ME->getMemberDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003506 if (const ObjCIvarRefExpr *RE = dyn_cast<ObjCIvarRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003507 return RE->getDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003508 if (const ObjCPropertyRefExpr *PRE = dyn_cast<ObjCPropertyRefExpr>(E)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003509 if (PRE->isExplicitProperty())
3510 return PRE->getExplicitProperty();
3511 // It could be messaging both getter and setter as in:
3512 // ++myobj.myprop;
3513 // in which case prefer to associate the setter since it is less obvious
3514 // from inspecting the source that the setter is going to get called.
3515 if (PRE->isMessagingSetter())
3516 return PRE->getImplicitPropertySetter();
3517 return PRE->getImplicitPropertyGetter();
3518 }
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003519 if (const PseudoObjectExpr *POE = dyn_cast<PseudoObjectExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003520 return getDeclFromExpr(POE->getSyntacticForm());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003521 if (const OpaqueValueExpr *OVE = dyn_cast<OpaqueValueExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003522 if (Expr *Src = OVE->getSourceExpr())
3523 return getDeclFromExpr(Src);
3524
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003525 if (const CallExpr *CE = dyn_cast<CallExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003526 return getDeclFromExpr(CE->getCallee());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003527 if (const CXXConstructExpr *CE = dyn_cast<CXXConstructExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003528 if (!CE->isElidable())
3529 return CE->getConstructor();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003530 if (const ObjCMessageExpr *OME = dyn_cast<ObjCMessageExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003531 return OME->getMethodDecl();
3532
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003533 if (const ObjCProtocolExpr *PE = dyn_cast<ObjCProtocolExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003534 return PE->getProtocol();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003535 if (const SubstNonTypeTemplateParmPackExpr *NTTP
Guy Benyei11169dd2012-12-18 14:30:41 +00003536 = dyn_cast<SubstNonTypeTemplateParmPackExpr>(E))
3537 return NTTP->getParameterPack();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003538 if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003539 if (isa<NonTypeTemplateParmDecl>(SizeOfPack->getPack()) ||
3540 isa<ParmVarDecl>(SizeOfPack->getPack()))
3541 return SizeOfPack->getPack();
Craig Topper69186e72014-06-08 08:38:04 +00003542
3543 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00003544}
3545
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003546static SourceLocation getLocationFromExpr(const Expr *E) {
3547 if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003548 return getLocationFromExpr(CE->getSubExpr());
3549
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003550 if (const ObjCMessageExpr *Msg = dyn_cast<ObjCMessageExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003551 return /*FIXME:*/Msg->getLeftLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003552 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003553 return DRE->getLocation();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003554 if (const MemberExpr *Member = dyn_cast<MemberExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003555 return Member->getMemberLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003556 if (const ObjCIvarRefExpr *Ivar = dyn_cast<ObjCIvarRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003557 return Ivar->getLocation();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003558 if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003559 return SizeOfPack->getPackLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003560 if (const ObjCPropertyRefExpr *PropRef = dyn_cast<ObjCPropertyRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003561 return PropRef->getLocation();
3562
3563 return E->getLocStart();
3564}
3565
Aaron Ballmana85d3f82015-11-12 15:25:06 +00003566static std::string getMangledStructor(std::unique_ptr<MangleContext> &M,
3567 std::unique_ptr<llvm::DataLayout> &DL,
3568 const NamedDecl *ND,
3569 unsigned StructorType) {
3570 std::string FrontendBuf;
3571 llvm::raw_string_ostream FOS(FrontendBuf);
3572
3573 if (const auto *CD = dyn_cast_or_null<CXXConstructorDecl>(ND))
3574 M->mangleCXXCtor(CD, static_cast<CXXCtorType>(StructorType), FOS);
3575 else if (const auto *DD = dyn_cast_or_null<CXXDestructorDecl>(ND))
3576 M->mangleCXXDtor(DD, static_cast<CXXDtorType>(StructorType), FOS);
3577
3578 std::string BackendBuf;
3579 llvm::raw_string_ostream BOS(BackendBuf);
3580
3581 llvm::Mangler::getNameWithPrefix(BOS, llvm::Twine(FOS.str()), *DL);
3582
3583 return BOS.str();
3584}
3585
Guy Benyei11169dd2012-12-18 14:30:41 +00003586extern "C" {
3587
3588unsigned clang_visitChildren(CXCursor parent,
3589 CXCursorVisitor visitor,
3590 CXClientData client_data) {
3591 CursorVisitor CursorVis(getCursorTU(parent), visitor, client_data,
3592 /*VisitPreprocessorLast=*/false);
3593 return CursorVis.VisitChildren(parent);
3594}
3595
3596#ifndef __has_feature
3597#define __has_feature(x) 0
3598#endif
3599#if __has_feature(blocks)
3600typedef enum CXChildVisitResult
3601 (^CXCursorVisitorBlock)(CXCursor cursor, CXCursor parent);
3602
3603static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
3604 CXClientData client_data) {
3605 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
3606 return block(cursor, parent);
3607}
3608#else
3609// If we are compiled with a compiler that doesn't have native blocks support,
3610// define and call the block manually, so the
3611typedef struct _CXChildVisitResult
3612{
3613 void *isa;
3614 int flags;
3615 int reserved;
3616 enum CXChildVisitResult(*invoke)(struct _CXChildVisitResult*, CXCursor,
3617 CXCursor);
3618} *CXCursorVisitorBlock;
3619
3620static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
3621 CXClientData client_data) {
3622 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
3623 return block->invoke(block, cursor, parent);
3624}
3625#endif
3626
3627
3628unsigned clang_visitChildrenWithBlock(CXCursor parent,
3629 CXCursorVisitorBlock block) {
3630 return clang_visitChildren(parent, visitWithBlock, block);
3631}
3632
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003633static CXString getDeclSpelling(const Decl *D) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003634 if (!D)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003635 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003636
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003637 const NamedDecl *ND = dyn_cast<NamedDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00003638 if (!ND) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003639 if (const ObjCPropertyImplDecl *PropImpl =
3640 dyn_cast<ObjCPropertyImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00003641 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003642 return cxstring::createDup(Property->getIdentifier()->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003643
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003644 if (const ImportDecl *ImportD = dyn_cast<ImportDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00003645 if (Module *Mod = ImportD->getImportedModule())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003646 return cxstring::createDup(Mod->getFullModuleName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003647
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003648 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003649 }
3650
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003651 if (const ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(ND))
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003652 return cxstring::createDup(OMD->getSelector().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003653
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003654 if (const ObjCCategoryImplDecl *CIMP = dyn_cast<ObjCCategoryImplDecl>(ND))
Guy Benyei11169dd2012-12-18 14:30:41 +00003655 // No, this isn't the same as the code below. getIdentifier() is non-virtual
3656 // and returns different names. NamedDecl returns the class name and
3657 // ObjCCategoryImplDecl returns the category name.
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003658 return cxstring::createRef(CIMP->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003659
3660 if (isa<UsingDirectiveDecl>(D))
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003661 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003662
3663 SmallString<1024> S;
3664 llvm::raw_svector_ostream os(S);
3665 ND->printName(os);
3666
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003667 return cxstring::createDup(os.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003668}
3669
3670CXString clang_getCursorSpelling(CXCursor C) {
3671 if (clang_isTranslationUnit(C.kind))
Dmitri Gribenko2c173b42013-01-11 19:28:44 +00003672 return clang_getTranslationUnitSpelling(getCursorTU(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00003673
3674 if (clang_isReference(C.kind)) {
3675 switch (C.kind) {
3676 case CXCursor_ObjCSuperClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003677 const ObjCInterfaceDecl *Super = getCursorObjCSuperClassRef(C).first;
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003678 return cxstring::createRef(Super->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003679 }
3680 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003681 const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003682 return cxstring::createRef(Class->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003683 }
3684 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003685 const ObjCProtocolDecl *OID = getCursorObjCProtocolRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003686 assert(OID && "getCursorSpelling(): Missing protocol decl");
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003687 return cxstring::createRef(OID->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003688 }
3689 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003690 const CXXBaseSpecifier *B = getCursorCXXBaseSpecifier(C);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003691 return cxstring::createDup(B->getType().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003692 }
3693 case CXCursor_TypeRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003694 const TypeDecl *Type = getCursorTypeRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003695 assert(Type && "Missing type decl");
3696
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003697 return cxstring::createDup(getCursorContext(C).getTypeDeclType(Type).
Guy Benyei11169dd2012-12-18 14:30:41 +00003698 getAsString());
3699 }
3700 case CXCursor_TemplateRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003701 const TemplateDecl *Template = getCursorTemplateRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003702 assert(Template && "Missing template decl");
3703
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003704 return cxstring::createDup(Template->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003705 }
3706
3707 case CXCursor_NamespaceRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003708 const NamedDecl *NS = getCursorNamespaceRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003709 assert(NS && "Missing namespace decl");
3710
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003711 return cxstring::createDup(NS->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003712 }
3713
3714 case CXCursor_MemberRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003715 const FieldDecl *Field = getCursorMemberRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003716 assert(Field && "Missing member decl");
3717
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003718 return cxstring::createDup(Field->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003719 }
3720
3721 case CXCursor_LabelRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003722 const LabelStmt *Label = getCursorLabelRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003723 assert(Label && "Missing label");
3724
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003725 return cxstring::createRef(Label->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003726 }
3727
3728 case CXCursor_OverloadedDeclRef: {
3729 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003730 if (const Decl *D = Storage.dyn_cast<const Decl *>()) {
3731 if (const NamedDecl *ND = dyn_cast<NamedDecl>(D))
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003732 return cxstring::createDup(ND->getNameAsString());
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003733 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003734 }
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003735 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003736 return cxstring::createDup(E->getName().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003737 OverloadedTemplateStorage *Ovl
3738 = Storage.get<OverloadedTemplateStorage*>();
3739 if (Ovl->size() == 0)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003740 return cxstring::createEmpty();
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003741 return cxstring::createDup((*Ovl->begin())->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003742 }
3743
3744 case CXCursor_VariableRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003745 const VarDecl *Var = getCursorVariableRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003746 assert(Var && "Missing variable decl");
3747
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003748 return cxstring::createDup(Var->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003749 }
3750
3751 default:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003752 return cxstring::createRef("<not implemented>");
Guy Benyei11169dd2012-12-18 14:30:41 +00003753 }
3754 }
3755
3756 if (clang_isExpression(C.kind)) {
Argyrios Kyrtzidis3227d862014-03-03 19:40:52 +00003757 const Expr *E = getCursorExpr(C);
3758
3759 if (C.kind == CXCursor_ObjCStringLiteral ||
3760 C.kind == CXCursor_StringLiteral) {
3761 const StringLiteral *SLit;
3762 if (const ObjCStringLiteral *OSL = dyn_cast<ObjCStringLiteral>(E)) {
3763 SLit = OSL->getString();
3764 } else {
3765 SLit = cast<StringLiteral>(E);
3766 }
3767 SmallString<256> Buf;
3768 llvm::raw_svector_ostream OS(Buf);
3769 SLit->outputString(OS);
3770 return cxstring::createDup(OS.str());
3771 }
3772
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003773 const Decl *D = getDeclFromExpr(getCursorExpr(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00003774 if (D)
3775 return getDeclSpelling(D);
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003776 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003777 }
3778
3779 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003780 const Stmt *S = getCursorStmt(C);
3781 if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S))
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003782 return cxstring::createRef(Label->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003783
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003784 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003785 }
3786
3787 if (C.kind == CXCursor_MacroExpansion)
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003788 return cxstring::createRef(getCursorMacroExpansion(C).getName()
Guy Benyei11169dd2012-12-18 14:30:41 +00003789 ->getNameStart());
3790
3791 if (C.kind == CXCursor_MacroDefinition)
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003792 return cxstring::createRef(getCursorMacroDefinition(C)->getName()
Guy Benyei11169dd2012-12-18 14:30:41 +00003793 ->getNameStart());
3794
3795 if (C.kind == CXCursor_InclusionDirective)
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003796 return cxstring::createDup(getCursorInclusionDirective(C)->getFileName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003797
3798 if (clang_isDeclaration(C.kind))
3799 return getDeclSpelling(getCursorDecl(C));
3800
3801 if (C.kind == CXCursor_AnnotateAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00003802 const AnnotateAttr *AA = cast<AnnotateAttr>(cxcursor::getCursorAttr(C));
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003803 return cxstring::createDup(AA->getAnnotation());
Guy Benyei11169dd2012-12-18 14:30:41 +00003804 }
3805
3806 if (C.kind == CXCursor_AsmLabelAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00003807 const AsmLabelAttr *AA = cast<AsmLabelAttr>(cxcursor::getCursorAttr(C));
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003808 return cxstring::createDup(AA->getLabel());
Guy Benyei11169dd2012-12-18 14:30:41 +00003809 }
3810
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00003811 if (C.kind == CXCursor_PackedAttr) {
3812 return cxstring::createRef("packed");
3813 }
3814
Saleem Abdulrasool79c69712015-09-05 18:53:43 +00003815 if (C.kind == CXCursor_VisibilityAttr) {
3816 const VisibilityAttr *AA = cast<VisibilityAttr>(cxcursor::getCursorAttr(C));
3817 switch (AA->getVisibility()) {
3818 case VisibilityAttr::VisibilityType::Default:
3819 return cxstring::createRef("default");
3820 case VisibilityAttr::VisibilityType::Hidden:
3821 return cxstring::createRef("hidden");
3822 case VisibilityAttr::VisibilityType::Protected:
3823 return cxstring::createRef("protected");
3824 }
3825 llvm_unreachable("unknown visibility type");
3826 }
3827
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003828 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003829}
3830
3831CXSourceRange clang_Cursor_getSpellingNameRange(CXCursor C,
3832 unsigned pieceIndex,
3833 unsigned options) {
3834 if (clang_Cursor_isNull(C))
3835 return clang_getNullRange();
3836
3837 ASTContext &Ctx = getCursorContext(C);
3838
3839 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003840 const Stmt *S = getCursorStmt(C);
3841 if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003842 if (pieceIndex > 0)
3843 return clang_getNullRange();
3844 return cxloc::translateSourceRange(Ctx, Label->getIdentLoc());
3845 }
3846
3847 return clang_getNullRange();
3848 }
3849
3850 if (C.kind == CXCursor_ObjCMessageExpr) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003851 if (const ObjCMessageExpr *
Guy Benyei11169dd2012-12-18 14:30:41 +00003852 ME = dyn_cast_or_null<ObjCMessageExpr>(getCursorExpr(C))) {
3853 if (pieceIndex >= ME->getNumSelectorLocs())
3854 return clang_getNullRange();
3855 return cxloc::translateSourceRange(Ctx, ME->getSelectorLoc(pieceIndex));
3856 }
3857 }
3858
3859 if (C.kind == CXCursor_ObjCInstanceMethodDecl ||
3860 C.kind == CXCursor_ObjCClassMethodDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003861 if (const ObjCMethodDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003862 MD = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(C))) {
3863 if (pieceIndex >= MD->getNumSelectorLocs())
3864 return clang_getNullRange();
3865 return cxloc::translateSourceRange(Ctx, MD->getSelectorLoc(pieceIndex));
3866 }
3867 }
3868
3869 if (C.kind == CXCursor_ObjCCategoryDecl ||
3870 C.kind == CXCursor_ObjCCategoryImplDecl) {
3871 if (pieceIndex > 0)
3872 return clang_getNullRange();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003873 if (const ObjCCategoryDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003874 CD = dyn_cast_or_null<ObjCCategoryDecl>(getCursorDecl(C)))
3875 return cxloc::translateSourceRange(Ctx, CD->getCategoryNameLoc());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003876 if (const ObjCCategoryImplDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003877 CID = dyn_cast_or_null<ObjCCategoryImplDecl>(getCursorDecl(C)))
3878 return cxloc::translateSourceRange(Ctx, CID->getCategoryNameLoc());
3879 }
3880
3881 if (C.kind == CXCursor_ModuleImportDecl) {
3882 if (pieceIndex > 0)
3883 return clang_getNullRange();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003884 if (const ImportDecl *ImportD =
3885 dyn_cast_or_null<ImportDecl>(getCursorDecl(C))) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003886 ArrayRef<SourceLocation> Locs = ImportD->getIdentifierLocs();
3887 if (!Locs.empty())
3888 return cxloc::translateSourceRange(Ctx,
3889 SourceRange(Locs.front(), Locs.back()));
3890 }
3891 return clang_getNullRange();
3892 }
3893
Argyrios Kyrtzidisa2a1e532014-08-26 20:23:26 +00003894 if (C.kind == CXCursor_CXXMethod || C.kind == CXCursor_Destructor ||
3895 C.kind == CXCursor_ConversionFunction) {
3896 if (pieceIndex > 0)
3897 return clang_getNullRange();
3898 if (const FunctionDecl *FD =
3899 dyn_cast_or_null<FunctionDecl>(getCursorDecl(C))) {
3900 DeclarationNameInfo FunctionName = FD->getNameInfo();
3901 return cxloc::translateSourceRange(Ctx, FunctionName.getSourceRange());
3902 }
3903 return clang_getNullRange();
3904 }
3905
Guy Benyei11169dd2012-12-18 14:30:41 +00003906 // FIXME: A CXCursor_InclusionDirective should give the location of the
3907 // filename, but we don't keep track of this.
3908
3909 // FIXME: A CXCursor_AnnotateAttr should give the location of the annotation
3910 // but we don't keep track of this.
3911
3912 // FIXME: A CXCursor_AsmLabelAttr should give the location of the label
3913 // but we don't keep track of this.
3914
3915 // Default handling, give the location of the cursor.
3916
3917 if (pieceIndex > 0)
3918 return clang_getNullRange();
3919
3920 CXSourceLocation CXLoc = clang_getCursorLocation(C);
3921 SourceLocation Loc = cxloc::translateSourceLocation(CXLoc);
3922 return cxloc::translateSourceRange(Ctx, Loc);
3923}
3924
Eli Bendersky44a206f2014-07-31 18:04:56 +00003925CXString clang_Cursor_getMangling(CXCursor C) {
3926 if (clang_isInvalid(C.kind) || !clang_isDeclaration(C.kind))
3927 return cxstring::createEmpty();
3928
Eli Bendersky44a206f2014-07-31 18:04:56 +00003929 // Mangling only works for functions and variables.
Eli Bendersky79759592014-08-01 15:01:10 +00003930 const Decl *D = getCursorDecl(C);
Eli Bendersky44a206f2014-07-31 18:04:56 +00003931 if (!D || !(isa<FunctionDecl>(D) || isa<VarDecl>(D)))
3932 return cxstring::createEmpty();
3933
Eli Bendersky79759592014-08-01 15:01:10 +00003934 // First apply frontend mangling.
Eli Bendersky44a206f2014-07-31 18:04:56 +00003935 const NamedDecl *ND = cast<NamedDecl>(D);
Eli Bendersky79759592014-08-01 15:01:10 +00003936 ASTContext &Ctx = ND->getASTContext();
3937 std::unique_ptr<MangleContext> MC(Ctx.createMangleContext());
Eli Bendersky44a206f2014-07-31 18:04:56 +00003938
Eli Bendersky79759592014-08-01 15:01:10 +00003939 std::string FrontendBuf;
3940 llvm::raw_string_ostream FrontendBufOS(FrontendBuf);
Ehsan Akhgarif8d44de2015-10-08 00:01:20 +00003941 if (MC->shouldMangleDeclName(ND)) {
3942 MC->mangleName(ND, FrontendBufOS);
3943 } else {
3944 ND->printName(FrontendBufOS);
3945 }
Eli Bendersky44a206f2014-07-31 18:04:56 +00003946
Eli Bendersky79759592014-08-01 15:01:10 +00003947 // Now apply backend mangling.
3948 std::unique_ptr<llvm::DataLayout> DL(
Eric Christopher964a5f32015-08-05 23:48:05 +00003949 new llvm::DataLayout(Ctx.getTargetInfo().getDataLayoutString()));
Eli Bendersky79759592014-08-01 15:01:10 +00003950
3951 std::string FinalBuf;
3952 llvm::raw_string_ostream FinalBufOS(FinalBuf);
Rafael Espindolab633d202015-06-23 13:59:36 +00003953 llvm::Mangler::getNameWithPrefix(FinalBufOS, llvm::Twine(FrontendBufOS.str()),
3954 *DL);
Eli Bendersky79759592014-08-01 15:01:10 +00003955
3956 return cxstring::createDup(FinalBufOS.str());
Eli Bendersky44a206f2014-07-31 18:04:56 +00003957}
3958
Saleem Abdulrasool60034432015-11-12 03:57:22 +00003959CXStringSet *clang_Cursor_getCXXManglings(CXCursor C) {
3960 if (clang_isInvalid(C.kind) || !clang_isDeclaration(C.kind))
3961 return nullptr;
3962
3963 const Decl *D = getCursorDecl(C);
3964 if (!(isa<CXXRecordDecl>(D) || isa<CXXMethodDecl>(D)))
3965 return nullptr;
3966
3967 const NamedDecl *ND = cast<NamedDecl>(D);
3968
3969 ASTContext &Ctx = ND->getASTContext();
3970 std::unique_ptr<MangleContext> M(Ctx.createMangleContext());
3971 std::unique_ptr<llvm::DataLayout> DL(
3972 new llvm::DataLayout(Ctx.getTargetInfo().getDataLayoutString()));
3973
3974 std::vector<std::string> Manglings;
3975
3976 auto hasDefaultCXXMethodCC = [](ASTContext &C, const CXXMethodDecl *MD) {
3977 auto DefaultCC = C.getDefaultCallingConvention(/*IsVariadic=*/false,
3978 /*IsCSSMethod=*/true);
3979 auto CC = MD->getType()->getAs<FunctionProtoType>()->getCallConv();
3980 return CC == DefaultCC;
3981 };
3982
3983 if (const auto *CD = dyn_cast_or_null<CXXConstructorDecl>(ND)) {
3984 Manglings.emplace_back(getMangledStructor(M, DL, CD, Ctor_Base));
3985
3986 if (Ctx.getTargetInfo().getCXXABI().isItaniumFamily())
3987 if (!CD->getParent()->isAbstract())
3988 Manglings.emplace_back(getMangledStructor(M, DL, CD, Ctor_Complete));
3989
3990 if (Ctx.getTargetInfo().getCXXABI().isMicrosoft())
3991 if (CD->hasAttr<DLLExportAttr>() && CD->isDefaultConstructor())
3992 if (!(hasDefaultCXXMethodCC(Ctx, CD) && CD->getNumParams() == 0))
3993 Manglings.emplace_back(getMangledStructor(M, DL, CD,
3994 Ctor_DefaultClosure));
3995 } else if (const auto *DD = dyn_cast_or_null<CXXDestructorDecl>(ND)) {
3996 Manglings.emplace_back(getMangledStructor(M, DL, DD, Dtor_Base));
3997 if (Ctx.getTargetInfo().getCXXABI().isItaniumFamily()) {
3998 Manglings.emplace_back(getMangledStructor(M, DL, DD, Dtor_Complete));
3999
4000 if (!DD->isVirtual())
4001 Manglings.emplace_back(getMangledStructor(M, DL, DD, Dtor_Deleting));
4002 }
4003 }
4004
4005 return cxstring::createSet(Manglings);
4006}
4007
Guy Benyei11169dd2012-12-18 14:30:41 +00004008CXString clang_getCursorDisplayName(CXCursor C) {
4009 if (!clang_isDeclaration(C.kind))
4010 return clang_getCursorSpelling(C);
4011
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004012 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004013 if (!D)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00004014 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00004015
4016 PrintingPolicy Policy = getCursorContext(C).getPrintingPolicy();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004017 if (const FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004018 D = FunTmpl->getTemplatedDecl();
4019
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004020 if (const FunctionDecl *Function = dyn_cast<FunctionDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004021 SmallString<64> Str;
4022 llvm::raw_svector_ostream OS(Str);
4023 OS << *Function;
4024 if (Function->getPrimaryTemplate())
4025 OS << "<>";
4026 OS << "(";
4027 for (unsigned I = 0, N = Function->getNumParams(); I != N; ++I) {
4028 if (I)
4029 OS << ", ";
4030 OS << Function->getParamDecl(I)->getType().getAsString(Policy);
4031 }
4032
4033 if (Function->isVariadic()) {
4034 if (Function->getNumParams())
4035 OS << ", ";
4036 OS << "...";
4037 }
4038 OS << ")";
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004039 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00004040 }
4041
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004042 if (const ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004043 SmallString<64> Str;
4044 llvm::raw_svector_ostream OS(Str);
4045 OS << *ClassTemplate;
4046 OS << "<";
4047 TemplateParameterList *Params = ClassTemplate->getTemplateParameters();
4048 for (unsigned I = 0, N = Params->size(); I != N; ++I) {
4049 if (I)
4050 OS << ", ";
4051
4052 NamedDecl *Param = Params->getParam(I);
4053 if (Param->getIdentifier()) {
4054 OS << Param->getIdentifier()->getName();
4055 continue;
4056 }
4057
4058 // There is no parameter name, which makes this tricky. Try to come up
4059 // with something useful that isn't too long.
4060 if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(Param))
4061 OS << (TTP->wasDeclaredWithTypename()? "typename" : "class");
4062 else if (NonTypeTemplateParmDecl *NTTP
4063 = dyn_cast<NonTypeTemplateParmDecl>(Param))
4064 OS << NTTP->getType().getAsString(Policy);
4065 else
4066 OS << "template<...> class";
4067 }
4068
4069 OS << ">";
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004070 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00004071 }
4072
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004073 if (const ClassTemplateSpecializationDecl *ClassSpec
Guy Benyei11169dd2012-12-18 14:30:41 +00004074 = dyn_cast<ClassTemplateSpecializationDecl>(D)) {
4075 // If the type was explicitly written, use that.
4076 if (TypeSourceInfo *TSInfo = ClassSpec->getTypeAsWritten())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004077 return cxstring::createDup(TSInfo->getType().getAsString(Policy));
Guy Benyei11169dd2012-12-18 14:30:41 +00004078
Benjamin Kramer9170e912013-02-22 15:46:01 +00004079 SmallString<128> Str;
Guy Benyei11169dd2012-12-18 14:30:41 +00004080 llvm::raw_svector_ostream OS(Str);
4081 OS << *ClassSpec;
Benjamin Kramer9170e912013-02-22 15:46:01 +00004082 TemplateSpecializationType::PrintTemplateArgumentList(OS,
Guy Benyei11169dd2012-12-18 14:30:41 +00004083 ClassSpec->getTemplateArgs().data(),
4084 ClassSpec->getTemplateArgs().size(),
4085 Policy);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004086 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00004087 }
4088
4089 return clang_getCursorSpelling(C);
4090}
4091
4092CXString clang_getCursorKindSpelling(enum CXCursorKind Kind) {
4093 switch (Kind) {
4094 case CXCursor_FunctionDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004095 return cxstring::createRef("FunctionDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004096 case CXCursor_TypedefDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004097 return cxstring::createRef("TypedefDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004098 case CXCursor_EnumDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004099 return cxstring::createRef("EnumDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004100 case CXCursor_EnumConstantDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004101 return cxstring::createRef("EnumConstantDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004102 case CXCursor_StructDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004103 return cxstring::createRef("StructDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004104 case CXCursor_UnionDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004105 return cxstring::createRef("UnionDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004106 case CXCursor_ClassDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004107 return cxstring::createRef("ClassDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004108 case CXCursor_FieldDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004109 return cxstring::createRef("FieldDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004110 case CXCursor_VarDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004111 return cxstring::createRef("VarDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004112 case CXCursor_ParmDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004113 return cxstring::createRef("ParmDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004114 case CXCursor_ObjCInterfaceDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004115 return cxstring::createRef("ObjCInterfaceDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004116 case CXCursor_ObjCCategoryDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004117 return cxstring::createRef("ObjCCategoryDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004118 case CXCursor_ObjCProtocolDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004119 return cxstring::createRef("ObjCProtocolDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004120 case CXCursor_ObjCPropertyDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004121 return cxstring::createRef("ObjCPropertyDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004122 case CXCursor_ObjCIvarDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004123 return cxstring::createRef("ObjCIvarDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004124 case CXCursor_ObjCInstanceMethodDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004125 return cxstring::createRef("ObjCInstanceMethodDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004126 case CXCursor_ObjCClassMethodDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004127 return cxstring::createRef("ObjCClassMethodDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004128 case CXCursor_ObjCImplementationDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004129 return cxstring::createRef("ObjCImplementationDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004130 case CXCursor_ObjCCategoryImplDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004131 return cxstring::createRef("ObjCCategoryImplDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004132 case CXCursor_CXXMethod:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004133 return cxstring::createRef("CXXMethod");
Guy Benyei11169dd2012-12-18 14:30:41 +00004134 case CXCursor_UnexposedDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004135 return cxstring::createRef("UnexposedDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004136 case CXCursor_ObjCSuperClassRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004137 return cxstring::createRef("ObjCSuperClassRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004138 case CXCursor_ObjCProtocolRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004139 return cxstring::createRef("ObjCProtocolRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004140 case CXCursor_ObjCClassRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004141 return cxstring::createRef("ObjCClassRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004142 case CXCursor_TypeRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004143 return cxstring::createRef("TypeRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004144 case CXCursor_TemplateRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004145 return cxstring::createRef("TemplateRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004146 case CXCursor_NamespaceRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004147 return cxstring::createRef("NamespaceRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004148 case CXCursor_MemberRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004149 return cxstring::createRef("MemberRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004150 case CXCursor_LabelRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004151 return cxstring::createRef("LabelRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004152 case CXCursor_OverloadedDeclRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004153 return cxstring::createRef("OverloadedDeclRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004154 case CXCursor_VariableRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004155 return cxstring::createRef("VariableRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004156 case CXCursor_IntegerLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004157 return cxstring::createRef("IntegerLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00004158 case CXCursor_FloatingLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004159 return cxstring::createRef("FloatingLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00004160 case CXCursor_ImaginaryLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004161 return cxstring::createRef("ImaginaryLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00004162 case CXCursor_StringLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004163 return cxstring::createRef("StringLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00004164 case CXCursor_CharacterLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004165 return cxstring::createRef("CharacterLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00004166 case CXCursor_ParenExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004167 return cxstring::createRef("ParenExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004168 case CXCursor_UnaryOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004169 return cxstring::createRef("UnaryOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00004170 case CXCursor_ArraySubscriptExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004171 return cxstring::createRef("ArraySubscriptExpr");
Alexey Bataev1a3320e2015-08-25 14:24:04 +00004172 case CXCursor_OMPArraySectionExpr:
4173 return cxstring::createRef("OMPArraySectionExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004174 case CXCursor_BinaryOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004175 return cxstring::createRef("BinaryOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00004176 case CXCursor_CompoundAssignOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004177 return cxstring::createRef("CompoundAssignOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00004178 case CXCursor_ConditionalOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004179 return cxstring::createRef("ConditionalOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00004180 case CXCursor_CStyleCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004181 return cxstring::createRef("CStyleCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004182 case CXCursor_CompoundLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004183 return cxstring::createRef("CompoundLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004184 case CXCursor_InitListExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004185 return cxstring::createRef("InitListExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004186 case CXCursor_AddrLabelExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004187 return cxstring::createRef("AddrLabelExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004188 case CXCursor_StmtExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004189 return cxstring::createRef("StmtExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004190 case CXCursor_GenericSelectionExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004191 return cxstring::createRef("GenericSelectionExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004192 case CXCursor_GNUNullExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004193 return cxstring::createRef("GNUNullExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004194 case CXCursor_CXXStaticCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004195 return cxstring::createRef("CXXStaticCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004196 case CXCursor_CXXDynamicCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004197 return cxstring::createRef("CXXDynamicCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004198 case CXCursor_CXXReinterpretCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004199 return cxstring::createRef("CXXReinterpretCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004200 case CXCursor_CXXConstCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004201 return cxstring::createRef("CXXConstCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004202 case CXCursor_CXXFunctionalCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004203 return cxstring::createRef("CXXFunctionalCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004204 case CXCursor_CXXTypeidExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004205 return cxstring::createRef("CXXTypeidExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004206 case CXCursor_CXXBoolLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004207 return cxstring::createRef("CXXBoolLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004208 case CXCursor_CXXNullPtrLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004209 return cxstring::createRef("CXXNullPtrLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004210 case CXCursor_CXXThisExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004211 return cxstring::createRef("CXXThisExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004212 case CXCursor_CXXThrowExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004213 return cxstring::createRef("CXXThrowExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004214 case CXCursor_CXXNewExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004215 return cxstring::createRef("CXXNewExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004216 case CXCursor_CXXDeleteExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004217 return cxstring::createRef("CXXDeleteExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004218 case CXCursor_UnaryExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004219 return cxstring::createRef("UnaryExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004220 case CXCursor_ObjCStringLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004221 return cxstring::createRef("ObjCStringLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00004222 case CXCursor_ObjCBoolLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004223 return cxstring::createRef("ObjCBoolLiteralExpr");
Argyrios Kyrtzidisc2233be2013-04-23 17:57:17 +00004224 case CXCursor_ObjCSelfExpr:
4225 return cxstring::createRef("ObjCSelfExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004226 case CXCursor_ObjCEncodeExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004227 return cxstring::createRef("ObjCEncodeExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004228 case CXCursor_ObjCSelectorExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004229 return cxstring::createRef("ObjCSelectorExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004230 case CXCursor_ObjCProtocolExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004231 return cxstring::createRef("ObjCProtocolExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004232 case CXCursor_ObjCBridgedCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004233 return cxstring::createRef("ObjCBridgedCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004234 case CXCursor_BlockExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004235 return cxstring::createRef("BlockExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004236 case CXCursor_PackExpansionExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004237 return cxstring::createRef("PackExpansionExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004238 case CXCursor_SizeOfPackExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004239 return cxstring::createRef("SizeOfPackExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004240 case CXCursor_LambdaExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004241 return cxstring::createRef("LambdaExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004242 case CXCursor_UnexposedExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004243 return cxstring::createRef("UnexposedExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004244 case CXCursor_DeclRefExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004245 return cxstring::createRef("DeclRefExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004246 case CXCursor_MemberRefExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004247 return cxstring::createRef("MemberRefExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004248 case CXCursor_CallExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004249 return cxstring::createRef("CallExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004250 case CXCursor_ObjCMessageExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004251 return cxstring::createRef("ObjCMessageExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004252 case CXCursor_UnexposedStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004253 return cxstring::createRef("UnexposedStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004254 case CXCursor_DeclStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004255 return cxstring::createRef("DeclStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004256 case CXCursor_LabelStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004257 return cxstring::createRef("LabelStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004258 case CXCursor_CompoundStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004259 return cxstring::createRef("CompoundStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004260 case CXCursor_CaseStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004261 return cxstring::createRef("CaseStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004262 case CXCursor_DefaultStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004263 return cxstring::createRef("DefaultStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004264 case CXCursor_IfStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004265 return cxstring::createRef("IfStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004266 case CXCursor_SwitchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004267 return cxstring::createRef("SwitchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004268 case CXCursor_WhileStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004269 return cxstring::createRef("WhileStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004270 case CXCursor_DoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004271 return cxstring::createRef("DoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004272 case CXCursor_ForStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004273 return cxstring::createRef("ForStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004274 case CXCursor_GotoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004275 return cxstring::createRef("GotoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004276 case CXCursor_IndirectGotoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004277 return cxstring::createRef("IndirectGotoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004278 case CXCursor_ContinueStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004279 return cxstring::createRef("ContinueStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004280 case CXCursor_BreakStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004281 return cxstring::createRef("BreakStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004282 case CXCursor_ReturnStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004283 return cxstring::createRef("ReturnStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004284 case CXCursor_GCCAsmStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004285 return cxstring::createRef("GCCAsmStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004286 case CXCursor_MSAsmStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004287 return cxstring::createRef("MSAsmStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004288 case CXCursor_ObjCAtTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004289 return cxstring::createRef("ObjCAtTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004290 case CXCursor_ObjCAtCatchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004291 return cxstring::createRef("ObjCAtCatchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004292 case CXCursor_ObjCAtFinallyStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004293 return cxstring::createRef("ObjCAtFinallyStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004294 case CXCursor_ObjCAtThrowStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004295 return cxstring::createRef("ObjCAtThrowStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004296 case CXCursor_ObjCAtSynchronizedStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004297 return cxstring::createRef("ObjCAtSynchronizedStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004298 case CXCursor_ObjCAutoreleasePoolStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004299 return cxstring::createRef("ObjCAutoreleasePoolStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004300 case CXCursor_ObjCForCollectionStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004301 return cxstring::createRef("ObjCForCollectionStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004302 case CXCursor_CXXCatchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004303 return cxstring::createRef("CXXCatchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004304 case CXCursor_CXXTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004305 return cxstring::createRef("CXXTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004306 case CXCursor_CXXForRangeStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004307 return cxstring::createRef("CXXForRangeStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004308 case CXCursor_SEHTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004309 return cxstring::createRef("SEHTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004310 case CXCursor_SEHExceptStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004311 return cxstring::createRef("SEHExceptStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004312 case CXCursor_SEHFinallyStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004313 return cxstring::createRef("SEHFinallyStmt");
Nico Weber9b982072014-07-07 00:12:30 +00004314 case CXCursor_SEHLeaveStmt:
4315 return cxstring::createRef("SEHLeaveStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004316 case CXCursor_NullStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004317 return cxstring::createRef("NullStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004318 case CXCursor_InvalidFile:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004319 return cxstring::createRef("InvalidFile");
Guy Benyei11169dd2012-12-18 14:30:41 +00004320 case CXCursor_InvalidCode:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004321 return cxstring::createRef("InvalidCode");
Guy Benyei11169dd2012-12-18 14:30:41 +00004322 case CXCursor_NoDeclFound:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004323 return cxstring::createRef("NoDeclFound");
Guy Benyei11169dd2012-12-18 14:30:41 +00004324 case CXCursor_NotImplemented:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004325 return cxstring::createRef("NotImplemented");
Guy Benyei11169dd2012-12-18 14:30:41 +00004326 case CXCursor_TranslationUnit:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004327 return cxstring::createRef("TranslationUnit");
Guy Benyei11169dd2012-12-18 14:30:41 +00004328 case CXCursor_UnexposedAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004329 return cxstring::createRef("UnexposedAttr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004330 case CXCursor_IBActionAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004331 return cxstring::createRef("attribute(ibaction)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004332 case CXCursor_IBOutletAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004333 return cxstring::createRef("attribute(iboutlet)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004334 case CXCursor_IBOutletCollectionAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004335 return cxstring::createRef("attribute(iboutletcollection)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004336 case CXCursor_CXXFinalAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004337 return cxstring::createRef("attribute(final)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004338 case CXCursor_CXXOverrideAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004339 return cxstring::createRef("attribute(override)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004340 case CXCursor_AnnotateAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004341 return cxstring::createRef("attribute(annotate)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004342 case CXCursor_AsmLabelAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004343 return cxstring::createRef("asm label");
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00004344 case CXCursor_PackedAttr:
4345 return cxstring::createRef("attribute(packed)");
Joey Gouly81228382014-05-01 15:41:58 +00004346 case CXCursor_PureAttr:
4347 return cxstring::createRef("attribute(pure)");
4348 case CXCursor_ConstAttr:
4349 return cxstring::createRef("attribute(const)");
4350 case CXCursor_NoDuplicateAttr:
4351 return cxstring::createRef("attribute(noduplicate)");
Eli Bendersky2581e662014-05-28 19:29:58 +00004352 case CXCursor_CUDAConstantAttr:
4353 return cxstring::createRef("attribute(constant)");
4354 case CXCursor_CUDADeviceAttr:
4355 return cxstring::createRef("attribute(device)");
4356 case CXCursor_CUDAGlobalAttr:
4357 return cxstring::createRef("attribute(global)");
4358 case CXCursor_CUDAHostAttr:
4359 return cxstring::createRef("attribute(host)");
Eli Bendersky9b071472014-08-08 14:59:00 +00004360 case CXCursor_CUDASharedAttr:
4361 return cxstring::createRef("attribute(shared)");
Saleem Abdulrasool79c69712015-09-05 18:53:43 +00004362 case CXCursor_VisibilityAttr:
4363 return cxstring::createRef("attribute(visibility)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004364 case CXCursor_PreprocessingDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004365 return cxstring::createRef("preprocessing directive");
Guy Benyei11169dd2012-12-18 14:30:41 +00004366 case CXCursor_MacroDefinition:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004367 return cxstring::createRef("macro definition");
Guy Benyei11169dd2012-12-18 14:30:41 +00004368 case CXCursor_MacroExpansion:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004369 return cxstring::createRef("macro expansion");
Guy Benyei11169dd2012-12-18 14:30:41 +00004370 case CXCursor_InclusionDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004371 return cxstring::createRef("inclusion directive");
Guy Benyei11169dd2012-12-18 14:30:41 +00004372 case CXCursor_Namespace:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004373 return cxstring::createRef("Namespace");
Guy Benyei11169dd2012-12-18 14:30:41 +00004374 case CXCursor_LinkageSpec:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004375 return cxstring::createRef("LinkageSpec");
Guy Benyei11169dd2012-12-18 14:30:41 +00004376 case CXCursor_CXXBaseSpecifier:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004377 return cxstring::createRef("C++ base class specifier");
Guy Benyei11169dd2012-12-18 14:30:41 +00004378 case CXCursor_Constructor:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004379 return cxstring::createRef("CXXConstructor");
Guy Benyei11169dd2012-12-18 14:30:41 +00004380 case CXCursor_Destructor:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004381 return cxstring::createRef("CXXDestructor");
Guy Benyei11169dd2012-12-18 14:30:41 +00004382 case CXCursor_ConversionFunction:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004383 return cxstring::createRef("CXXConversion");
Guy Benyei11169dd2012-12-18 14:30:41 +00004384 case CXCursor_TemplateTypeParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004385 return cxstring::createRef("TemplateTypeParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00004386 case CXCursor_NonTypeTemplateParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004387 return cxstring::createRef("NonTypeTemplateParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00004388 case CXCursor_TemplateTemplateParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004389 return cxstring::createRef("TemplateTemplateParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00004390 case CXCursor_FunctionTemplate:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004391 return cxstring::createRef("FunctionTemplate");
Guy Benyei11169dd2012-12-18 14:30:41 +00004392 case CXCursor_ClassTemplate:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004393 return cxstring::createRef("ClassTemplate");
Guy Benyei11169dd2012-12-18 14:30:41 +00004394 case CXCursor_ClassTemplatePartialSpecialization:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004395 return cxstring::createRef("ClassTemplatePartialSpecialization");
Guy Benyei11169dd2012-12-18 14:30:41 +00004396 case CXCursor_NamespaceAlias:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004397 return cxstring::createRef("NamespaceAlias");
Guy Benyei11169dd2012-12-18 14:30:41 +00004398 case CXCursor_UsingDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004399 return cxstring::createRef("UsingDirective");
Guy Benyei11169dd2012-12-18 14:30:41 +00004400 case CXCursor_UsingDeclaration:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004401 return cxstring::createRef("UsingDeclaration");
Guy Benyei11169dd2012-12-18 14:30:41 +00004402 case CXCursor_TypeAliasDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004403 return cxstring::createRef("TypeAliasDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004404 case CXCursor_ObjCSynthesizeDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004405 return cxstring::createRef("ObjCSynthesizeDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004406 case CXCursor_ObjCDynamicDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004407 return cxstring::createRef("ObjCDynamicDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004408 case CXCursor_CXXAccessSpecifier:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004409 return cxstring::createRef("CXXAccessSpecifier");
Guy Benyei11169dd2012-12-18 14:30:41 +00004410 case CXCursor_ModuleImportDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004411 return cxstring::createRef("ModuleImport");
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00004412 case CXCursor_OMPParallelDirective:
Alexey Bataev1b59ab52014-02-27 08:29:12 +00004413 return cxstring::createRef("OMPParallelDirective");
4414 case CXCursor_OMPSimdDirective:
4415 return cxstring::createRef("OMPSimdDirective");
Alexey Bataevf29276e2014-06-18 04:14:57 +00004416 case CXCursor_OMPForDirective:
4417 return cxstring::createRef("OMPForDirective");
Alexander Musmanf82886e2014-09-18 05:12:34 +00004418 case CXCursor_OMPForSimdDirective:
4419 return cxstring::createRef("OMPForSimdDirective");
Alexey Bataevd3f8dd22014-06-25 11:44:49 +00004420 case CXCursor_OMPSectionsDirective:
4421 return cxstring::createRef("OMPSectionsDirective");
Alexey Bataev1e0498a2014-06-26 08:21:58 +00004422 case CXCursor_OMPSectionDirective:
4423 return cxstring::createRef("OMPSectionDirective");
Alexey Bataevd1e40fb2014-06-26 12:05:45 +00004424 case CXCursor_OMPSingleDirective:
4425 return cxstring::createRef("OMPSingleDirective");
Alexander Musman80c22892014-07-17 08:54:58 +00004426 case CXCursor_OMPMasterDirective:
4427 return cxstring::createRef("OMPMasterDirective");
Alexander Musmand9ed09f2014-07-21 09:42:05 +00004428 case CXCursor_OMPCriticalDirective:
4429 return cxstring::createRef("OMPCriticalDirective");
Alexey Bataev4acb8592014-07-07 13:01:15 +00004430 case CXCursor_OMPParallelForDirective:
4431 return cxstring::createRef("OMPParallelForDirective");
Alexander Musmane4e893b2014-09-23 09:33:00 +00004432 case CXCursor_OMPParallelForSimdDirective:
4433 return cxstring::createRef("OMPParallelForSimdDirective");
Alexey Bataev84d0b3e2014-07-08 08:12:03 +00004434 case CXCursor_OMPParallelSectionsDirective:
4435 return cxstring::createRef("OMPParallelSectionsDirective");
Alexey Bataev9c2e8ee2014-07-11 11:25:16 +00004436 case CXCursor_OMPTaskDirective:
4437 return cxstring::createRef("OMPTaskDirective");
Alexey Bataev68446b72014-07-18 07:47:19 +00004438 case CXCursor_OMPTaskyieldDirective:
4439 return cxstring::createRef("OMPTaskyieldDirective");
Alexey Bataev4d1dfea2014-07-18 09:11:51 +00004440 case CXCursor_OMPBarrierDirective:
4441 return cxstring::createRef("OMPBarrierDirective");
Alexey Bataev2df347a2014-07-18 10:17:07 +00004442 case CXCursor_OMPTaskwaitDirective:
4443 return cxstring::createRef("OMPTaskwaitDirective");
Alexey Bataevc30dd2d2015-06-18 12:14:09 +00004444 case CXCursor_OMPTaskgroupDirective:
4445 return cxstring::createRef("OMPTaskgroupDirective");
Alexey Bataev6125da92014-07-21 11:26:11 +00004446 case CXCursor_OMPFlushDirective:
4447 return cxstring::createRef("OMPFlushDirective");
Alexey Bataev9fb6e642014-07-22 06:45:04 +00004448 case CXCursor_OMPOrderedDirective:
4449 return cxstring::createRef("OMPOrderedDirective");
Alexey Bataev0162e452014-07-22 10:10:35 +00004450 case CXCursor_OMPAtomicDirective:
4451 return cxstring::createRef("OMPAtomicDirective");
Alexey Bataev0bd520b2014-09-19 08:19:49 +00004452 case CXCursor_OMPTargetDirective:
4453 return cxstring::createRef("OMPTargetDirective");
Michael Wong65f367f2015-07-21 13:44:28 +00004454 case CXCursor_OMPTargetDataDirective:
4455 return cxstring::createRef("OMPTargetDataDirective");
Alexey Bataev13314bf2014-10-09 04:18:56 +00004456 case CXCursor_OMPTeamsDirective:
4457 return cxstring::createRef("OMPTeamsDirective");
Alexey Bataev6d4ed052015-07-01 06:57:41 +00004458 case CXCursor_OMPCancellationPointDirective:
4459 return cxstring::createRef("OMPCancellationPointDirective");
Alexey Bataev80909872015-07-02 11:25:17 +00004460 case CXCursor_OMPCancelDirective:
4461 return cxstring::createRef("OMPCancelDirective");
Francisco Lopes da Silva975a9f62015-01-21 16:24:11 +00004462 case CXCursor_OverloadCandidate:
4463 return cxstring::createRef("OverloadCandidate");
Sergey Kalinichev8f3b1872015-11-15 13:48:32 +00004464 case CXCursor_TypeAliasTemplateDecl:
4465 return cxstring::createRef("TypeAliasTemplateDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004466 }
4467
4468 llvm_unreachable("Unhandled CXCursorKind");
4469}
4470
4471struct GetCursorData {
4472 SourceLocation TokenBeginLoc;
4473 bool PointsAtMacroArgExpansion;
4474 bool VisitedObjCPropertyImplDecl;
4475 SourceLocation VisitedDeclaratorDeclStartLoc;
4476 CXCursor &BestCursor;
4477
4478 GetCursorData(SourceManager &SM,
4479 SourceLocation tokenBegin, CXCursor &outputCursor)
4480 : TokenBeginLoc(tokenBegin), BestCursor(outputCursor) {
4481 PointsAtMacroArgExpansion = SM.isMacroArgExpansion(tokenBegin);
4482 VisitedObjCPropertyImplDecl = false;
4483 }
4484};
4485
4486static enum CXChildVisitResult GetCursorVisitor(CXCursor cursor,
4487 CXCursor parent,
4488 CXClientData client_data) {
4489 GetCursorData *Data = static_cast<GetCursorData *>(client_data);
4490 CXCursor *BestCursor = &Data->BestCursor;
4491
4492 // If we point inside a macro argument we should provide info of what the
4493 // token is so use the actual cursor, don't replace it with a macro expansion
4494 // cursor.
4495 if (cursor.kind == CXCursor_MacroExpansion && Data->PointsAtMacroArgExpansion)
4496 return CXChildVisit_Recurse;
4497
4498 if (clang_isDeclaration(cursor.kind)) {
4499 // Avoid having the implicit methods override the property decls.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004500 if (const ObjCMethodDecl *MD
Guy Benyei11169dd2012-12-18 14:30:41 +00004501 = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
4502 if (MD->isImplicit())
4503 return CXChildVisit_Break;
4504
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004505 } else if (const ObjCInterfaceDecl *ID
Guy Benyei11169dd2012-12-18 14:30:41 +00004506 = dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(cursor))) {
4507 // Check that when we have multiple @class references in the same line,
4508 // that later ones do not override the previous ones.
4509 // If we have:
4510 // @class Foo, Bar;
4511 // source ranges for both start at '@', so 'Bar' will end up overriding
4512 // 'Foo' even though the cursor location was at 'Foo'.
4513 if (BestCursor->kind == CXCursor_ObjCInterfaceDecl ||
4514 BestCursor->kind == CXCursor_ObjCClassRef)
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004515 if (const ObjCInterfaceDecl *PrevID
Guy Benyei11169dd2012-12-18 14:30:41 +00004516 = dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(*BestCursor))){
4517 if (PrevID != ID &&
4518 !PrevID->isThisDeclarationADefinition() &&
4519 !ID->isThisDeclarationADefinition())
4520 return CXChildVisit_Break;
4521 }
4522
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004523 } else if (const DeclaratorDecl *DD
Guy Benyei11169dd2012-12-18 14:30:41 +00004524 = dyn_cast_or_null<DeclaratorDecl>(getCursorDecl(cursor))) {
4525 SourceLocation StartLoc = DD->getSourceRange().getBegin();
4526 // Check that when we have multiple declarators in the same line,
4527 // that later ones do not override the previous ones.
4528 // If we have:
4529 // int Foo, Bar;
4530 // source ranges for both start at 'int', so 'Bar' will end up overriding
4531 // 'Foo' even though the cursor location was at 'Foo'.
4532 if (Data->VisitedDeclaratorDeclStartLoc == StartLoc)
4533 return CXChildVisit_Break;
4534 Data->VisitedDeclaratorDeclStartLoc = StartLoc;
4535
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004536 } else if (const ObjCPropertyImplDecl *PropImp
Guy Benyei11169dd2012-12-18 14:30:41 +00004537 = dyn_cast_or_null<ObjCPropertyImplDecl>(getCursorDecl(cursor))) {
4538 (void)PropImp;
4539 // Check that when we have multiple @synthesize in the same line,
4540 // that later ones do not override the previous ones.
4541 // If we have:
4542 // @synthesize Foo, Bar;
4543 // source ranges for both start at '@', so 'Bar' will end up overriding
4544 // 'Foo' even though the cursor location was at 'Foo'.
4545 if (Data->VisitedObjCPropertyImplDecl)
4546 return CXChildVisit_Break;
4547 Data->VisitedObjCPropertyImplDecl = true;
4548 }
4549 }
4550
4551 if (clang_isExpression(cursor.kind) &&
4552 clang_isDeclaration(BestCursor->kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004553 if (const Decl *D = getCursorDecl(*BestCursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004554 // Avoid having the cursor of an expression replace the declaration cursor
4555 // when the expression source range overlaps the declaration range.
4556 // This can happen for C++ constructor expressions whose range generally
4557 // include the variable declaration, e.g.:
4558 // MyCXXClass foo; // Make sure pointing at 'foo' returns a VarDecl cursor.
4559 if (D->getLocation().isValid() && Data->TokenBeginLoc.isValid() &&
4560 D->getLocation() == Data->TokenBeginLoc)
4561 return CXChildVisit_Break;
4562 }
4563 }
4564
4565 // If our current best cursor is the construction of a temporary object,
4566 // don't replace that cursor with a type reference, because we want
4567 // clang_getCursor() to point at the constructor.
4568 if (clang_isExpression(BestCursor->kind) &&
4569 isa<CXXTemporaryObjectExpr>(getCursorExpr(*BestCursor)) &&
4570 cursor.kind == CXCursor_TypeRef) {
4571 // Keep the cursor pointing at CXXTemporaryObjectExpr but also mark it
4572 // as having the actual point on the type reference.
4573 *BestCursor = getTypeRefedCallExprCursor(*BestCursor);
4574 return CXChildVisit_Recurse;
4575 }
Douglas Gregore9d95f12015-07-07 03:57:35 +00004576
4577 // If we already have an Objective-C superclass reference, don't
4578 // update it further.
4579 if (BestCursor->kind == CXCursor_ObjCSuperClassRef)
4580 return CXChildVisit_Break;
4581
Guy Benyei11169dd2012-12-18 14:30:41 +00004582 *BestCursor = cursor;
4583 return CXChildVisit_Recurse;
4584}
4585
4586CXCursor clang_getCursor(CXTranslationUnit TU, CXSourceLocation Loc) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00004587 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004588 LOG_BAD_TU(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004589 return clang_getNullCursor();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004590 }
Guy Benyei11169dd2012-12-18 14:30:41 +00004591
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004592 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004593 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
4594
4595 SourceLocation SLoc = cxloc::translateSourceLocation(Loc);
4596 CXCursor Result = cxcursor::getCursor(TU, SLoc);
4597
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004598 LOG_FUNC_SECTION {
Guy Benyei11169dd2012-12-18 14:30:41 +00004599 CXFile SearchFile;
4600 unsigned SearchLine, SearchColumn;
4601 CXFile ResultFile;
4602 unsigned ResultLine, ResultColumn;
4603 CXString SearchFileName, ResultFileName, KindSpelling, USR;
4604 const char *IsDef = clang_isCursorDefinition(Result)? " (Definition)" : "";
4605 CXSourceLocation ResultLoc = clang_getCursorLocation(Result);
Craig Topper69186e72014-06-08 08:38:04 +00004606
4607 clang_getFileLocation(Loc, &SearchFile, &SearchLine, &SearchColumn,
4608 nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004609 clang_getFileLocation(ResultLoc, &ResultFile, &ResultLine,
Craig Topper69186e72014-06-08 08:38:04 +00004610 &ResultColumn, nullptr);
Guy Benyei11169dd2012-12-18 14:30:41 +00004611 SearchFileName = clang_getFileName(SearchFile);
4612 ResultFileName = clang_getFileName(ResultFile);
4613 KindSpelling = clang_getCursorKindSpelling(Result.kind);
4614 USR = clang_getCursorUSR(Result);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004615 *Log << llvm::format("(%s:%d:%d) = %s",
4616 clang_getCString(SearchFileName), SearchLine, SearchColumn,
4617 clang_getCString(KindSpelling))
4618 << llvm::format("(%s:%d:%d):%s%s",
4619 clang_getCString(ResultFileName), ResultLine, ResultColumn,
4620 clang_getCString(USR), IsDef);
Guy Benyei11169dd2012-12-18 14:30:41 +00004621 clang_disposeString(SearchFileName);
4622 clang_disposeString(ResultFileName);
4623 clang_disposeString(KindSpelling);
4624 clang_disposeString(USR);
4625
4626 CXCursor Definition = clang_getCursorDefinition(Result);
4627 if (!clang_equalCursors(Definition, clang_getNullCursor())) {
4628 CXSourceLocation DefinitionLoc = clang_getCursorLocation(Definition);
4629 CXString DefinitionKindSpelling
4630 = clang_getCursorKindSpelling(Definition.kind);
4631 CXFile DefinitionFile;
4632 unsigned DefinitionLine, DefinitionColumn;
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004633 clang_getFileLocation(DefinitionLoc, &DefinitionFile,
Craig Topper69186e72014-06-08 08:38:04 +00004634 &DefinitionLine, &DefinitionColumn, nullptr);
Guy Benyei11169dd2012-12-18 14:30:41 +00004635 CXString DefinitionFileName = clang_getFileName(DefinitionFile);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004636 *Log << llvm::format(" -> %s(%s:%d:%d)",
4637 clang_getCString(DefinitionKindSpelling),
4638 clang_getCString(DefinitionFileName),
4639 DefinitionLine, DefinitionColumn);
Guy Benyei11169dd2012-12-18 14:30:41 +00004640 clang_disposeString(DefinitionFileName);
4641 clang_disposeString(DefinitionKindSpelling);
4642 }
4643 }
4644
4645 return Result;
4646}
4647
4648CXCursor clang_getNullCursor(void) {
4649 return MakeCXCursorInvalid(CXCursor_InvalidFile);
4650}
4651
4652unsigned clang_equalCursors(CXCursor X, CXCursor Y) {
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00004653 // Clear out the "FirstInDeclGroup" part in a declaration cursor, since we
4654 // can't set consistently. For example, when visiting a DeclStmt we will set
4655 // it but we don't set it on the result of clang_getCursorDefinition for
4656 // a reference of the same declaration.
4657 // FIXME: Setting "FirstInDeclGroup" in CXCursors is a hack that only works
4658 // when visiting a DeclStmt currently, the AST should be enhanced to be able
4659 // to provide that kind of info.
4660 if (clang_isDeclaration(X.kind))
Craig Topper69186e72014-06-08 08:38:04 +00004661 X.data[1] = nullptr;
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00004662 if (clang_isDeclaration(Y.kind))
Craig Topper69186e72014-06-08 08:38:04 +00004663 Y.data[1] = nullptr;
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00004664
Guy Benyei11169dd2012-12-18 14:30:41 +00004665 return X == Y;
4666}
4667
4668unsigned clang_hashCursor(CXCursor C) {
4669 unsigned Index = 0;
4670 if (clang_isExpression(C.kind) || clang_isStatement(C.kind))
4671 Index = 1;
4672
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004673 return llvm::DenseMapInfo<std::pair<unsigned, const void*> >::getHashValue(
Guy Benyei11169dd2012-12-18 14:30:41 +00004674 std::make_pair(C.kind, C.data[Index]));
4675}
4676
4677unsigned clang_isInvalid(enum CXCursorKind K) {
4678 return K >= CXCursor_FirstInvalid && K <= CXCursor_LastInvalid;
4679}
4680
4681unsigned clang_isDeclaration(enum CXCursorKind K) {
4682 return (K >= CXCursor_FirstDecl && K <= CXCursor_LastDecl) ||
4683 (K >= CXCursor_FirstExtraDecl && K <= CXCursor_LastExtraDecl);
4684}
4685
4686unsigned clang_isReference(enum CXCursorKind K) {
4687 return K >= CXCursor_FirstRef && K <= CXCursor_LastRef;
4688}
4689
4690unsigned clang_isExpression(enum CXCursorKind K) {
4691 return K >= CXCursor_FirstExpr && K <= CXCursor_LastExpr;
4692}
4693
4694unsigned clang_isStatement(enum CXCursorKind K) {
4695 return K >= CXCursor_FirstStmt && K <= CXCursor_LastStmt;
4696}
4697
4698unsigned clang_isAttribute(enum CXCursorKind K) {
4699 return K >= CXCursor_FirstAttr && K <= CXCursor_LastAttr;
4700}
4701
4702unsigned clang_isTranslationUnit(enum CXCursorKind K) {
4703 return K == CXCursor_TranslationUnit;
4704}
4705
4706unsigned clang_isPreprocessing(enum CXCursorKind K) {
4707 return K >= CXCursor_FirstPreprocessing && K <= CXCursor_LastPreprocessing;
4708}
4709
4710unsigned clang_isUnexposed(enum CXCursorKind K) {
4711 switch (K) {
4712 case CXCursor_UnexposedDecl:
4713 case CXCursor_UnexposedExpr:
4714 case CXCursor_UnexposedStmt:
4715 case CXCursor_UnexposedAttr:
4716 return true;
4717 default:
4718 return false;
4719 }
4720}
4721
4722CXCursorKind clang_getCursorKind(CXCursor C) {
4723 return C.kind;
4724}
4725
4726CXSourceLocation clang_getCursorLocation(CXCursor C) {
4727 if (clang_isReference(C.kind)) {
4728 switch (C.kind) {
4729 case CXCursor_ObjCSuperClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004730 std::pair<const ObjCInterfaceDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004731 = getCursorObjCSuperClassRef(C);
4732 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4733 }
4734
4735 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004736 std::pair<const ObjCProtocolDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004737 = getCursorObjCProtocolRef(C);
4738 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4739 }
4740
4741 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004742 std::pair<const ObjCInterfaceDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004743 = getCursorObjCClassRef(C);
4744 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4745 }
4746
4747 case CXCursor_TypeRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004748 std::pair<const TypeDecl *, SourceLocation> P = getCursorTypeRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004749 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4750 }
4751
4752 case CXCursor_TemplateRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004753 std::pair<const TemplateDecl *, SourceLocation> P =
4754 getCursorTemplateRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004755 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4756 }
4757
4758 case CXCursor_NamespaceRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004759 std::pair<const NamedDecl *, SourceLocation> P = getCursorNamespaceRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004760 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4761 }
4762
4763 case CXCursor_MemberRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004764 std::pair<const FieldDecl *, SourceLocation> P = getCursorMemberRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004765 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4766 }
4767
4768 case CXCursor_VariableRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004769 std::pair<const VarDecl *, SourceLocation> P = getCursorVariableRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004770 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4771 }
4772
4773 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004774 const CXXBaseSpecifier *BaseSpec = getCursorCXXBaseSpecifier(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004775 if (!BaseSpec)
4776 return clang_getNullLocation();
4777
4778 if (TypeSourceInfo *TSInfo = BaseSpec->getTypeSourceInfo())
4779 return cxloc::translateSourceLocation(getCursorContext(C),
4780 TSInfo->getTypeLoc().getBeginLoc());
4781
4782 return cxloc::translateSourceLocation(getCursorContext(C),
4783 BaseSpec->getLocStart());
4784 }
4785
4786 case CXCursor_LabelRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004787 std::pair<const LabelStmt *, SourceLocation> P = getCursorLabelRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004788 return cxloc::translateSourceLocation(getCursorContext(C), P.second);
4789 }
4790
4791 case CXCursor_OverloadedDeclRef:
4792 return cxloc::translateSourceLocation(getCursorContext(C),
4793 getCursorOverloadedDeclRef(C).second);
4794
4795 default:
4796 // FIXME: Need a way to enumerate all non-reference cases.
4797 llvm_unreachable("Missed a reference kind");
4798 }
4799 }
4800
4801 if (clang_isExpression(C.kind))
4802 return cxloc::translateSourceLocation(getCursorContext(C),
4803 getLocationFromExpr(getCursorExpr(C)));
4804
4805 if (clang_isStatement(C.kind))
4806 return cxloc::translateSourceLocation(getCursorContext(C),
4807 getCursorStmt(C)->getLocStart());
4808
4809 if (C.kind == CXCursor_PreprocessingDirective) {
4810 SourceLocation L = cxcursor::getCursorPreprocessingDirective(C).getBegin();
4811 return cxloc::translateSourceLocation(getCursorContext(C), L);
4812 }
4813
4814 if (C.kind == CXCursor_MacroExpansion) {
4815 SourceLocation L
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00004816 = cxcursor::getCursorMacroExpansion(C).getSourceRange().getBegin();
Guy Benyei11169dd2012-12-18 14:30:41 +00004817 return cxloc::translateSourceLocation(getCursorContext(C), L);
4818 }
4819
4820 if (C.kind == CXCursor_MacroDefinition) {
4821 SourceLocation L = cxcursor::getCursorMacroDefinition(C)->getLocation();
4822 return cxloc::translateSourceLocation(getCursorContext(C), L);
4823 }
4824
4825 if (C.kind == CXCursor_InclusionDirective) {
4826 SourceLocation L
4827 = cxcursor::getCursorInclusionDirective(C)->getSourceRange().getBegin();
4828 return cxloc::translateSourceLocation(getCursorContext(C), L);
4829 }
4830
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00004831 if (clang_isAttribute(C.kind)) {
4832 SourceLocation L
4833 = cxcursor::getCursorAttr(C)->getLocation();
4834 return cxloc::translateSourceLocation(getCursorContext(C), L);
4835 }
4836
Guy Benyei11169dd2012-12-18 14:30:41 +00004837 if (!clang_isDeclaration(C.kind))
4838 return clang_getNullLocation();
4839
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004840 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004841 if (!D)
4842 return clang_getNullLocation();
4843
4844 SourceLocation Loc = D->getLocation();
4845 // FIXME: Multiple variables declared in a single declaration
4846 // currently lack the information needed to correctly determine their
4847 // ranges when accounting for the type-specifier. We use context
4848 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4849 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004850 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004851 if (!cxcursor::isFirstInDeclGroup(C))
4852 Loc = VD->getLocation();
4853 }
4854
4855 // For ObjC methods, give the start location of the method name.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004856 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004857 Loc = MD->getSelectorStartLoc();
4858
4859 return cxloc::translateSourceLocation(getCursorContext(C), Loc);
4860}
4861
4862} // end extern "C"
4863
4864CXCursor cxcursor::getCursor(CXTranslationUnit TU, SourceLocation SLoc) {
4865 assert(TU);
4866
4867 // Guard against an invalid SourceLocation, or we may assert in one
4868 // of the following calls.
4869 if (SLoc.isInvalid())
4870 return clang_getNullCursor();
4871
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004872 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004873
4874 // Translate the given source location to make it point at the beginning of
4875 // the token under the cursor.
4876 SLoc = Lexer::GetBeginningOfToken(SLoc, CXXUnit->getSourceManager(),
4877 CXXUnit->getASTContext().getLangOpts());
4878
4879 CXCursor Result = MakeCXCursorInvalid(CXCursor_NoDeclFound);
4880 if (SLoc.isValid()) {
4881 GetCursorData ResultData(CXXUnit->getSourceManager(), SLoc, Result);
4882 CursorVisitor CursorVis(TU, GetCursorVisitor, &ResultData,
4883 /*VisitPreprocessorLast=*/true,
4884 /*VisitIncludedEntities=*/false,
4885 SourceLocation(SLoc));
4886 CursorVis.visitFileRegion();
4887 }
4888
4889 return Result;
4890}
4891
4892static SourceRange getRawCursorExtent(CXCursor C) {
4893 if (clang_isReference(C.kind)) {
4894 switch (C.kind) {
4895 case CXCursor_ObjCSuperClassRef:
4896 return getCursorObjCSuperClassRef(C).second;
4897
4898 case CXCursor_ObjCProtocolRef:
4899 return getCursorObjCProtocolRef(C).second;
4900
4901 case CXCursor_ObjCClassRef:
4902 return getCursorObjCClassRef(C).second;
4903
4904 case CXCursor_TypeRef:
4905 return getCursorTypeRef(C).second;
4906
4907 case CXCursor_TemplateRef:
4908 return getCursorTemplateRef(C).second;
4909
4910 case CXCursor_NamespaceRef:
4911 return getCursorNamespaceRef(C).second;
4912
4913 case CXCursor_MemberRef:
4914 return getCursorMemberRef(C).second;
4915
4916 case CXCursor_CXXBaseSpecifier:
4917 return getCursorCXXBaseSpecifier(C)->getSourceRange();
4918
4919 case CXCursor_LabelRef:
4920 return getCursorLabelRef(C).second;
4921
4922 case CXCursor_OverloadedDeclRef:
4923 return getCursorOverloadedDeclRef(C).second;
4924
4925 case CXCursor_VariableRef:
4926 return getCursorVariableRef(C).second;
4927
4928 default:
4929 // FIXME: Need a way to enumerate all non-reference cases.
4930 llvm_unreachable("Missed a reference kind");
4931 }
4932 }
4933
4934 if (clang_isExpression(C.kind))
4935 return getCursorExpr(C)->getSourceRange();
4936
4937 if (clang_isStatement(C.kind))
4938 return getCursorStmt(C)->getSourceRange();
4939
4940 if (clang_isAttribute(C.kind))
4941 return getCursorAttr(C)->getRange();
4942
4943 if (C.kind == CXCursor_PreprocessingDirective)
4944 return cxcursor::getCursorPreprocessingDirective(C);
4945
4946 if (C.kind == CXCursor_MacroExpansion) {
4947 ASTUnit *TU = getCursorASTUnit(C);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00004948 SourceRange Range = cxcursor::getCursorMacroExpansion(C).getSourceRange();
Guy Benyei11169dd2012-12-18 14:30:41 +00004949 return TU->mapRangeFromPreamble(Range);
4950 }
4951
4952 if (C.kind == CXCursor_MacroDefinition) {
4953 ASTUnit *TU = getCursorASTUnit(C);
4954 SourceRange Range = cxcursor::getCursorMacroDefinition(C)->getSourceRange();
4955 return TU->mapRangeFromPreamble(Range);
4956 }
4957
4958 if (C.kind == CXCursor_InclusionDirective) {
4959 ASTUnit *TU = getCursorASTUnit(C);
4960 SourceRange Range = cxcursor::getCursorInclusionDirective(C)->getSourceRange();
4961 return TU->mapRangeFromPreamble(Range);
4962 }
4963
4964 if (C.kind == CXCursor_TranslationUnit) {
4965 ASTUnit *TU = getCursorASTUnit(C);
4966 FileID MainID = TU->getSourceManager().getMainFileID();
4967 SourceLocation Start = TU->getSourceManager().getLocForStartOfFile(MainID);
4968 SourceLocation End = TU->getSourceManager().getLocForEndOfFile(MainID);
4969 return SourceRange(Start, End);
4970 }
4971
4972 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004973 const Decl *D = cxcursor::getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004974 if (!D)
4975 return SourceRange();
4976
4977 SourceRange R = D->getSourceRange();
4978 // FIXME: Multiple variables declared in a single declaration
4979 // currently lack the information needed to correctly determine their
4980 // ranges when accounting for the type-specifier. We use context
4981 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4982 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004983 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004984 if (!cxcursor::isFirstInDeclGroup(C))
4985 R.setBegin(VD->getLocation());
4986 }
4987 return R;
4988 }
4989 return SourceRange();
4990}
4991
4992/// \brief Retrieves the "raw" cursor extent, which is then extended to include
4993/// the decl-specifier-seq for declarations.
4994static SourceRange getFullCursorExtent(CXCursor C, SourceManager &SrcMgr) {
4995 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004996 const Decl *D = cxcursor::getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004997 if (!D)
4998 return SourceRange();
4999
5000 SourceRange R = D->getSourceRange();
5001
5002 // Adjust the start of the location for declarations preceded by
5003 // declaration specifiers.
5004 SourceLocation StartLoc;
5005 if (const DeclaratorDecl *DD = dyn_cast<DeclaratorDecl>(D)) {
5006 if (TypeSourceInfo *TI = DD->getTypeSourceInfo())
5007 StartLoc = TI->getTypeLoc().getLocStart();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005008 } else if (const TypedefDecl *Typedef = dyn_cast<TypedefDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005009 if (TypeSourceInfo *TI = Typedef->getTypeSourceInfo())
5010 StartLoc = TI->getTypeLoc().getLocStart();
5011 }
5012
5013 if (StartLoc.isValid() && R.getBegin().isValid() &&
5014 SrcMgr.isBeforeInTranslationUnit(StartLoc, R.getBegin()))
5015 R.setBegin(StartLoc);
5016
5017 // FIXME: Multiple variables declared in a single declaration
5018 // currently lack the information needed to correctly determine their
5019 // ranges when accounting for the type-specifier. We use context
5020 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
5021 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005022 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005023 if (!cxcursor::isFirstInDeclGroup(C))
5024 R.setBegin(VD->getLocation());
5025 }
5026
5027 return R;
5028 }
5029
5030 return getRawCursorExtent(C);
5031}
5032
5033extern "C" {
5034
5035CXSourceRange clang_getCursorExtent(CXCursor C) {
5036 SourceRange R = getRawCursorExtent(C);
5037 if (R.isInvalid())
5038 return clang_getNullRange();
5039
5040 return cxloc::translateSourceRange(getCursorContext(C), R);
5041}
5042
5043CXCursor clang_getCursorReferenced(CXCursor C) {
5044 if (clang_isInvalid(C.kind))
5045 return clang_getNullCursor();
5046
5047 CXTranslationUnit tu = getCursorTU(C);
5048 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005049 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005050 if (!D)
5051 return clang_getNullCursor();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005052 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00005053 return MakeCursorOverloadedDeclRef(Using, D->getLocation(), tu);
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005054 if (const ObjCPropertyImplDecl *PropImpl =
5055 dyn_cast<ObjCPropertyImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00005056 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
5057 return MakeCXCursor(Property, tu);
5058
5059 return C;
5060 }
5061
5062 if (clang_isExpression(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005063 const Expr *E = getCursorExpr(C);
5064 const Decl *D = getDeclFromExpr(E);
Guy Benyei11169dd2012-12-18 14:30:41 +00005065 if (D) {
5066 CXCursor declCursor = MakeCXCursor(D, tu);
5067 declCursor = getSelectorIdentifierCursor(getSelectorIdentifierIndex(C),
5068 declCursor);
5069 return declCursor;
5070 }
5071
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005072 if (const OverloadExpr *Ovl = dyn_cast_or_null<OverloadExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00005073 return MakeCursorOverloadedDeclRef(Ovl, tu);
5074
5075 return clang_getNullCursor();
5076 }
5077
5078 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005079 const Stmt *S = getCursorStmt(C);
5080 if (const GotoStmt *Goto = dyn_cast_or_null<GotoStmt>(S))
Guy Benyei11169dd2012-12-18 14:30:41 +00005081 if (LabelDecl *label = Goto->getLabel())
5082 if (LabelStmt *labelS = label->getStmt())
5083 return MakeCXCursor(labelS, getCursorDecl(C), tu);
5084
5085 return clang_getNullCursor();
5086 }
Richard Smith66a81862015-05-04 02:25:31 +00005087
Guy Benyei11169dd2012-12-18 14:30:41 +00005088 if (C.kind == CXCursor_MacroExpansion) {
Richard Smith66a81862015-05-04 02:25:31 +00005089 if (const MacroDefinitionRecord *Def =
5090 getCursorMacroExpansion(C).getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005091 return MakeMacroDefinitionCursor(Def, tu);
5092 }
5093
5094 if (!clang_isReference(C.kind))
5095 return clang_getNullCursor();
5096
5097 switch (C.kind) {
5098 case CXCursor_ObjCSuperClassRef:
5099 return MakeCXCursor(getCursorObjCSuperClassRef(C).first, tu);
5100
5101 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005102 const ObjCProtocolDecl *Prot = getCursorObjCProtocolRef(C).first;
5103 if (const ObjCProtocolDecl *Def = Prot->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005104 return MakeCXCursor(Def, tu);
5105
5106 return MakeCXCursor(Prot, tu);
5107 }
5108
5109 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005110 const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
5111 if (const ObjCInterfaceDecl *Def = Class->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005112 return MakeCXCursor(Def, tu);
5113
5114 return MakeCXCursor(Class, tu);
5115 }
5116
5117 case CXCursor_TypeRef:
5118 return MakeCXCursor(getCursorTypeRef(C).first, tu );
5119
5120 case CXCursor_TemplateRef:
5121 return MakeCXCursor(getCursorTemplateRef(C).first, tu );
5122
5123 case CXCursor_NamespaceRef:
5124 return MakeCXCursor(getCursorNamespaceRef(C).first, tu );
5125
5126 case CXCursor_MemberRef:
5127 return MakeCXCursor(getCursorMemberRef(C).first, tu );
5128
5129 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005130 const CXXBaseSpecifier *B = cxcursor::getCursorCXXBaseSpecifier(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005131 return clang_getTypeDeclaration(cxtype::MakeCXType(B->getType(),
5132 tu ));
5133 }
5134
5135 case CXCursor_LabelRef:
5136 // FIXME: We end up faking the "parent" declaration here because we
5137 // don't want to make CXCursor larger.
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005138 return MakeCXCursor(getCursorLabelRef(C).first,
5139 cxtu::getASTUnit(tu)->getASTContext()
5140 .getTranslationUnitDecl(),
Guy Benyei11169dd2012-12-18 14:30:41 +00005141 tu);
5142
5143 case CXCursor_OverloadedDeclRef:
5144 return C;
5145
5146 case CXCursor_VariableRef:
5147 return MakeCXCursor(getCursorVariableRef(C).first, tu);
5148
5149 default:
5150 // We would prefer to enumerate all non-reference cursor kinds here.
5151 llvm_unreachable("Unhandled reference cursor kind");
5152 }
5153}
5154
5155CXCursor clang_getCursorDefinition(CXCursor C) {
5156 if (clang_isInvalid(C.kind))
5157 return clang_getNullCursor();
5158
5159 CXTranslationUnit TU = getCursorTU(C);
5160
5161 bool WasReference = false;
5162 if (clang_isReference(C.kind) || clang_isExpression(C.kind)) {
5163 C = clang_getCursorReferenced(C);
5164 WasReference = true;
5165 }
5166
5167 if (C.kind == CXCursor_MacroExpansion)
5168 return clang_getCursorReferenced(C);
5169
5170 if (!clang_isDeclaration(C.kind))
5171 return clang_getNullCursor();
5172
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005173 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005174 if (!D)
5175 return clang_getNullCursor();
5176
5177 switch (D->getKind()) {
5178 // Declaration kinds that don't really separate the notions of
5179 // declaration and definition.
5180 case Decl::Namespace:
5181 case Decl::Typedef:
5182 case Decl::TypeAlias:
5183 case Decl::TypeAliasTemplate:
5184 case Decl::TemplateTypeParm:
5185 case Decl::EnumConstant:
5186 case Decl::Field:
John McCall5e77d762013-04-16 07:28:30 +00005187 case Decl::MSProperty:
Guy Benyei11169dd2012-12-18 14:30:41 +00005188 case Decl::IndirectField:
5189 case Decl::ObjCIvar:
5190 case Decl::ObjCAtDefsField:
5191 case Decl::ImplicitParam:
5192 case Decl::ParmVar:
5193 case Decl::NonTypeTemplateParm:
5194 case Decl::TemplateTemplateParm:
5195 case Decl::ObjCCategoryImpl:
5196 case Decl::ObjCImplementation:
5197 case Decl::AccessSpec:
5198 case Decl::LinkageSpec:
5199 case Decl::ObjCPropertyImpl:
5200 case Decl::FileScopeAsm:
5201 case Decl::StaticAssert:
5202 case Decl::Block:
Tareq A. Siraj6dfa25a2013-04-16 19:37:38 +00005203 case Decl::Captured:
Guy Benyei11169dd2012-12-18 14:30:41 +00005204 case Decl::Label: // FIXME: Is this right??
5205 case Decl::ClassScopeFunctionSpecialization:
5206 case Decl::Import:
Alexey Bataeva769e072013-03-22 06:34:35 +00005207 case Decl::OMPThreadPrivate:
Douglas Gregor85f3f952015-07-07 03:57:15 +00005208 case Decl::ObjCTypeParam:
David Majnemerd9b1a4f2015-11-04 03:40:30 +00005209 case Decl::BuiltinTemplate:
Guy Benyei11169dd2012-12-18 14:30:41 +00005210 return C;
5211
5212 // Declaration kinds that don't make any sense here, but are
5213 // nonetheless harmless.
David Blaikief005d3c2013-02-22 17:44:58 +00005214 case Decl::Empty:
Guy Benyei11169dd2012-12-18 14:30:41 +00005215 case Decl::TranslationUnit:
Richard Smithf19e1272015-03-07 00:04:49 +00005216 case Decl::ExternCContext:
Guy Benyei11169dd2012-12-18 14:30:41 +00005217 break;
5218
5219 // Declaration kinds for which the definition is not resolvable.
5220 case Decl::UnresolvedUsingTypename:
5221 case Decl::UnresolvedUsingValue:
5222 break;
5223
5224 case Decl::UsingDirective:
5225 return MakeCXCursor(cast<UsingDirectiveDecl>(D)->getNominatedNamespace(),
5226 TU);
5227
5228 case Decl::NamespaceAlias:
5229 return MakeCXCursor(cast<NamespaceAliasDecl>(D)->getNamespace(), TU);
5230
5231 case Decl::Enum:
5232 case Decl::Record:
5233 case Decl::CXXRecord:
5234 case Decl::ClassTemplateSpecialization:
5235 case Decl::ClassTemplatePartialSpecialization:
5236 if (TagDecl *Def = cast<TagDecl>(D)->getDefinition())
5237 return MakeCXCursor(Def, TU);
5238 return clang_getNullCursor();
5239
5240 case Decl::Function:
5241 case Decl::CXXMethod:
5242 case Decl::CXXConstructor:
5243 case Decl::CXXDestructor:
5244 case Decl::CXXConversion: {
Craig Topper69186e72014-06-08 08:38:04 +00005245 const FunctionDecl *Def = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005246 if (cast<FunctionDecl>(D)->getBody(Def))
Dmitri Gribenko9c256e32013-01-14 00:46:27 +00005247 return MakeCXCursor(Def, TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005248 return clang_getNullCursor();
5249 }
5250
Larisse Voufo39a1e502013-08-06 01:03:05 +00005251 case Decl::Var:
5252 case Decl::VarTemplateSpecialization:
5253 case Decl::VarTemplatePartialSpecialization: {
Guy Benyei11169dd2012-12-18 14:30:41 +00005254 // Ask the variable if it has a definition.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005255 if (const VarDecl *Def = cast<VarDecl>(D)->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005256 return MakeCXCursor(Def, TU);
5257 return clang_getNullCursor();
5258 }
5259
5260 case Decl::FunctionTemplate: {
Craig Topper69186e72014-06-08 08:38:04 +00005261 const FunctionDecl *Def = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005262 if (cast<FunctionTemplateDecl>(D)->getTemplatedDecl()->getBody(Def))
5263 return MakeCXCursor(Def->getDescribedFunctionTemplate(), TU);
5264 return clang_getNullCursor();
5265 }
5266
5267 case Decl::ClassTemplate: {
5268 if (RecordDecl *Def = cast<ClassTemplateDecl>(D)->getTemplatedDecl()
5269 ->getDefinition())
5270 return MakeCXCursor(cast<CXXRecordDecl>(Def)->getDescribedClassTemplate(),
5271 TU);
5272 return clang_getNullCursor();
5273 }
5274
Larisse Voufo39a1e502013-08-06 01:03:05 +00005275 case Decl::VarTemplate: {
5276 if (VarDecl *Def =
5277 cast<VarTemplateDecl>(D)->getTemplatedDecl()->getDefinition())
5278 return MakeCXCursor(cast<VarDecl>(Def)->getDescribedVarTemplate(), TU);
5279 return clang_getNullCursor();
5280 }
5281
Guy Benyei11169dd2012-12-18 14:30:41 +00005282 case Decl::Using:
5283 return MakeCursorOverloadedDeclRef(cast<UsingDecl>(D),
5284 D->getLocation(), TU);
5285
5286 case Decl::UsingShadow:
5287 return clang_getCursorDefinition(
5288 MakeCXCursor(cast<UsingShadowDecl>(D)->getTargetDecl(),
5289 TU));
5290
5291 case Decl::ObjCMethod: {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005292 const ObjCMethodDecl *Method = cast<ObjCMethodDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00005293 if (Method->isThisDeclarationADefinition())
5294 return C;
5295
5296 // Dig out the method definition in the associated
5297 // @implementation, if we have it.
5298 // FIXME: The ASTs should make finding the definition easier.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005299 if (const ObjCInterfaceDecl *Class
Guy Benyei11169dd2012-12-18 14:30:41 +00005300 = dyn_cast<ObjCInterfaceDecl>(Method->getDeclContext()))
5301 if (ObjCImplementationDecl *ClassImpl = Class->getImplementation())
5302 if (ObjCMethodDecl *Def = ClassImpl->getMethod(Method->getSelector(),
5303 Method->isInstanceMethod()))
5304 if (Def->isThisDeclarationADefinition())
5305 return MakeCXCursor(Def, TU);
5306
5307 return clang_getNullCursor();
5308 }
5309
5310 case Decl::ObjCCategory:
5311 if (ObjCCategoryImplDecl *Impl
5312 = cast<ObjCCategoryDecl>(D)->getImplementation())
5313 return MakeCXCursor(Impl, TU);
5314 return clang_getNullCursor();
5315
5316 case Decl::ObjCProtocol:
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005317 if (const ObjCProtocolDecl *Def = cast<ObjCProtocolDecl>(D)->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005318 return MakeCXCursor(Def, TU);
5319 return clang_getNullCursor();
5320
5321 case Decl::ObjCInterface: {
5322 // There are two notions of a "definition" for an Objective-C
5323 // class: the interface and its implementation. When we resolved a
5324 // reference to an Objective-C class, produce the @interface as
5325 // the definition; when we were provided with the interface,
5326 // produce the @implementation as the definition.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005327 const ObjCInterfaceDecl *IFace = cast<ObjCInterfaceDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00005328 if (WasReference) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005329 if (const ObjCInterfaceDecl *Def = IFace->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005330 return MakeCXCursor(Def, TU);
5331 } else if (ObjCImplementationDecl *Impl = IFace->getImplementation())
5332 return MakeCXCursor(Impl, TU);
5333 return clang_getNullCursor();
5334 }
5335
5336 case Decl::ObjCProperty:
5337 // FIXME: We don't really know where to find the
5338 // ObjCPropertyImplDecls that implement this property.
5339 return clang_getNullCursor();
5340
5341 case Decl::ObjCCompatibleAlias:
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005342 if (const ObjCInterfaceDecl *Class
Guy Benyei11169dd2012-12-18 14:30:41 +00005343 = cast<ObjCCompatibleAliasDecl>(D)->getClassInterface())
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005344 if (const ObjCInterfaceDecl *Def = Class->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005345 return MakeCXCursor(Def, TU);
5346
5347 return clang_getNullCursor();
5348
5349 case Decl::Friend:
5350 if (NamedDecl *Friend = cast<FriendDecl>(D)->getFriendDecl())
5351 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
5352 return clang_getNullCursor();
5353
5354 case Decl::FriendTemplate:
5355 if (NamedDecl *Friend = cast<FriendTemplateDecl>(D)->getFriendDecl())
5356 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
5357 return clang_getNullCursor();
5358 }
5359
5360 return clang_getNullCursor();
5361}
5362
5363unsigned clang_isCursorDefinition(CXCursor C) {
5364 if (!clang_isDeclaration(C.kind))
5365 return 0;
5366
5367 return clang_getCursorDefinition(C) == C;
5368}
5369
5370CXCursor clang_getCanonicalCursor(CXCursor C) {
5371 if (!clang_isDeclaration(C.kind))
5372 return C;
5373
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005374 if (const Decl *D = getCursorDecl(C)) {
5375 if (const ObjCCategoryImplDecl *CatImplD = dyn_cast<ObjCCategoryImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00005376 if (ObjCCategoryDecl *CatD = CatImplD->getCategoryDecl())
5377 return MakeCXCursor(CatD, getCursorTU(C));
5378
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005379 if (const ObjCImplDecl *ImplD = dyn_cast<ObjCImplDecl>(D))
5380 if (const ObjCInterfaceDecl *IFD = ImplD->getClassInterface())
Guy Benyei11169dd2012-12-18 14:30:41 +00005381 return MakeCXCursor(IFD, getCursorTU(C));
5382
5383 return MakeCXCursor(D->getCanonicalDecl(), getCursorTU(C));
5384 }
5385
5386 return C;
5387}
5388
5389int clang_Cursor_getObjCSelectorIndex(CXCursor cursor) {
5390 return cxcursor::getSelectorIdentifierIndexAndLoc(cursor).first;
5391}
5392
5393unsigned clang_getNumOverloadedDecls(CXCursor C) {
5394 if (C.kind != CXCursor_OverloadedDeclRef)
5395 return 0;
5396
5397 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005398 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Guy Benyei11169dd2012-12-18 14:30:41 +00005399 return E->getNumDecls();
5400
5401 if (OverloadedTemplateStorage *S
5402 = Storage.dyn_cast<OverloadedTemplateStorage*>())
5403 return S->size();
5404
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005405 const Decl *D = Storage.get<const Decl *>();
5406 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00005407 return Using->shadow_size();
5408
5409 return 0;
5410}
5411
5412CXCursor clang_getOverloadedDecl(CXCursor cursor, unsigned index) {
5413 if (cursor.kind != CXCursor_OverloadedDeclRef)
5414 return clang_getNullCursor();
5415
5416 if (index >= clang_getNumOverloadedDecls(cursor))
5417 return clang_getNullCursor();
5418
5419 CXTranslationUnit TU = getCursorTU(cursor);
5420 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(cursor).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005421 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Guy Benyei11169dd2012-12-18 14:30:41 +00005422 return MakeCXCursor(E->decls_begin()[index], TU);
5423
5424 if (OverloadedTemplateStorage *S
5425 = Storage.dyn_cast<OverloadedTemplateStorage*>())
5426 return MakeCXCursor(S->begin()[index], TU);
5427
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005428 const Decl *D = Storage.get<const Decl *>();
5429 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005430 // FIXME: This is, unfortunately, linear time.
5431 UsingDecl::shadow_iterator Pos = Using->shadow_begin();
5432 std::advance(Pos, index);
5433 return MakeCXCursor(cast<UsingShadowDecl>(*Pos)->getTargetDecl(), TU);
5434 }
5435
5436 return clang_getNullCursor();
5437}
5438
5439void clang_getDefinitionSpellingAndExtent(CXCursor C,
5440 const char **startBuf,
5441 const char **endBuf,
5442 unsigned *startLine,
5443 unsigned *startColumn,
5444 unsigned *endLine,
5445 unsigned *endColumn) {
5446 assert(getCursorDecl(C) && "CXCursor has null decl");
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005447 const FunctionDecl *FD = dyn_cast<FunctionDecl>(getCursorDecl(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00005448 CompoundStmt *Body = dyn_cast<CompoundStmt>(FD->getBody());
5449
5450 SourceManager &SM = FD->getASTContext().getSourceManager();
5451 *startBuf = SM.getCharacterData(Body->getLBracLoc());
5452 *endBuf = SM.getCharacterData(Body->getRBracLoc());
5453 *startLine = SM.getSpellingLineNumber(Body->getLBracLoc());
5454 *startColumn = SM.getSpellingColumnNumber(Body->getLBracLoc());
5455 *endLine = SM.getSpellingLineNumber(Body->getRBracLoc());
5456 *endColumn = SM.getSpellingColumnNumber(Body->getRBracLoc());
5457}
5458
5459
5460CXSourceRange clang_getCursorReferenceNameRange(CXCursor C, unsigned NameFlags,
5461 unsigned PieceIndex) {
5462 RefNamePieces Pieces;
5463
5464 switch (C.kind) {
5465 case CXCursor_MemberRefExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005466 if (const MemberExpr *E = dyn_cast<MemberExpr>(getCursorExpr(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00005467 Pieces = buildPieces(NameFlags, true, E->getMemberNameInfo(),
5468 E->getQualifierLoc().getSourceRange());
5469 break;
5470
5471 case CXCursor_DeclRefExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005472 if (const DeclRefExpr *E = dyn_cast<DeclRefExpr>(getCursorExpr(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00005473 Pieces = buildPieces(NameFlags, false, E->getNameInfo(),
5474 E->getQualifierLoc().getSourceRange(),
5475 E->getOptionalExplicitTemplateArgs());
5476 break;
5477
5478 case CXCursor_CallExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005479 if (const CXXOperatorCallExpr *OCE =
Guy Benyei11169dd2012-12-18 14:30:41 +00005480 dyn_cast<CXXOperatorCallExpr>(getCursorExpr(C))) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005481 const Expr *Callee = OCE->getCallee();
5482 if (const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Callee))
Guy Benyei11169dd2012-12-18 14:30:41 +00005483 Callee = ICE->getSubExpr();
5484
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005485 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(Callee))
Guy Benyei11169dd2012-12-18 14:30:41 +00005486 Pieces = buildPieces(NameFlags, false, DRE->getNameInfo(),
5487 DRE->getQualifierLoc().getSourceRange());
5488 }
5489 break;
5490
5491 default:
5492 break;
5493 }
5494
5495 if (Pieces.empty()) {
5496 if (PieceIndex == 0)
5497 return clang_getCursorExtent(C);
5498 } else if (PieceIndex < Pieces.size()) {
5499 SourceRange R = Pieces[PieceIndex];
5500 if (R.isValid())
5501 return cxloc::translateSourceRange(getCursorContext(C), R);
5502 }
5503
5504 return clang_getNullRange();
5505}
5506
5507void clang_enableStackTraces(void) {
5508 llvm::sys::PrintStackTraceOnErrorSignal();
5509}
5510
5511void clang_executeOnThread(void (*fn)(void*), void *user_data,
5512 unsigned stack_size) {
5513 llvm::llvm_execute_on_thread(fn, user_data, stack_size);
5514}
5515
5516} // end: extern "C"
5517
5518//===----------------------------------------------------------------------===//
5519// Token-based Operations.
5520//===----------------------------------------------------------------------===//
5521
5522/* CXToken layout:
5523 * int_data[0]: a CXTokenKind
5524 * int_data[1]: starting token location
5525 * int_data[2]: token length
5526 * int_data[3]: reserved
5527 * ptr_data: for identifiers and keywords, an IdentifierInfo*.
5528 * otherwise unused.
5529 */
5530extern "C" {
5531
5532CXTokenKind clang_getTokenKind(CXToken CXTok) {
5533 return static_cast<CXTokenKind>(CXTok.int_data[0]);
5534}
5535
5536CXString clang_getTokenSpelling(CXTranslationUnit TU, CXToken CXTok) {
5537 switch (clang_getTokenKind(CXTok)) {
5538 case CXToken_Identifier:
5539 case CXToken_Keyword:
5540 // We know we have an IdentifierInfo*, so use that.
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005541 return cxstring::createRef(static_cast<IdentifierInfo *>(CXTok.ptr_data)
Guy Benyei11169dd2012-12-18 14:30:41 +00005542 ->getNameStart());
5543
5544 case CXToken_Literal: {
5545 // We have stashed the starting pointer in the ptr_data field. Use it.
5546 const char *Text = static_cast<const char *>(CXTok.ptr_data);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00005547 return cxstring::createDup(StringRef(Text, CXTok.int_data[2]));
Guy Benyei11169dd2012-12-18 14:30:41 +00005548 }
5549
5550 case CXToken_Punctuation:
5551 case CXToken_Comment:
5552 break;
5553 }
5554
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005555 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005556 LOG_BAD_TU(TU);
5557 return cxstring::createEmpty();
5558 }
5559
Guy Benyei11169dd2012-12-18 14:30:41 +00005560 // We have to find the starting buffer pointer the hard way, by
5561 // deconstructing the source location.
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005562 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005563 if (!CXXUnit)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00005564 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00005565
5566 SourceLocation Loc = SourceLocation::getFromRawEncoding(CXTok.int_data[1]);
5567 std::pair<FileID, unsigned> LocInfo
5568 = CXXUnit->getSourceManager().getDecomposedSpellingLoc(Loc);
5569 bool Invalid = false;
5570 StringRef Buffer
5571 = CXXUnit->getSourceManager().getBufferData(LocInfo.first, &Invalid);
5572 if (Invalid)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00005573 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00005574
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00005575 return cxstring::createDup(Buffer.substr(LocInfo.second, CXTok.int_data[2]));
Guy Benyei11169dd2012-12-18 14:30:41 +00005576}
5577
5578CXSourceLocation clang_getTokenLocation(CXTranslationUnit TU, CXToken CXTok) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005579 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005580 LOG_BAD_TU(TU);
5581 return clang_getNullLocation();
5582 }
5583
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005584 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005585 if (!CXXUnit)
5586 return clang_getNullLocation();
5587
5588 return cxloc::translateSourceLocation(CXXUnit->getASTContext(),
5589 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
5590}
5591
5592CXSourceRange clang_getTokenExtent(CXTranslationUnit TU, CXToken CXTok) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005593 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005594 LOG_BAD_TU(TU);
5595 return clang_getNullRange();
5596 }
5597
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005598 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005599 if (!CXXUnit)
5600 return clang_getNullRange();
5601
5602 return cxloc::translateSourceRange(CXXUnit->getASTContext(),
5603 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
5604}
5605
5606static void getTokens(ASTUnit *CXXUnit, SourceRange Range,
5607 SmallVectorImpl<CXToken> &CXTokens) {
5608 SourceManager &SourceMgr = CXXUnit->getSourceManager();
5609 std::pair<FileID, unsigned> BeginLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005610 = SourceMgr.getDecomposedSpellingLoc(Range.getBegin());
Guy Benyei11169dd2012-12-18 14:30:41 +00005611 std::pair<FileID, unsigned> EndLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005612 = SourceMgr.getDecomposedSpellingLoc(Range.getEnd());
Guy Benyei11169dd2012-12-18 14:30:41 +00005613
5614 // Cannot tokenize across files.
5615 if (BeginLocInfo.first != EndLocInfo.first)
5616 return;
5617
5618 // Create a lexer
5619 bool Invalid = false;
5620 StringRef Buffer
5621 = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
5622 if (Invalid)
5623 return;
5624
5625 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
5626 CXXUnit->getASTContext().getLangOpts(),
5627 Buffer.begin(), Buffer.data() + BeginLocInfo.second, Buffer.end());
5628 Lex.SetCommentRetentionState(true);
5629
5630 // Lex tokens until we hit the end of the range.
5631 const char *EffectiveBufferEnd = Buffer.data() + EndLocInfo.second;
5632 Token Tok;
5633 bool previousWasAt = false;
5634 do {
5635 // Lex the next token
5636 Lex.LexFromRawLexer(Tok);
5637 if (Tok.is(tok::eof))
5638 break;
5639
5640 // Initialize the CXToken.
5641 CXToken CXTok;
5642
5643 // - Common fields
5644 CXTok.int_data[1] = Tok.getLocation().getRawEncoding();
5645 CXTok.int_data[2] = Tok.getLength();
5646 CXTok.int_data[3] = 0;
5647
5648 // - Kind-specific fields
5649 if (Tok.isLiteral()) {
5650 CXTok.int_data[0] = CXToken_Literal;
Dmitri Gribenkof9304482013-01-23 15:56:07 +00005651 CXTok.ptr_data = const_cast<char *>(Tok.getLiteralData());
Guy Benyei11169dd2012-12-18 14:30:41 +00005652 } else if (Tok.is(tok::raw_identifier)) {
5653 // Lookup the identifier to determine whether we have a keyword.
5654 IdentifierInfo *II
5655 = CXXUnit->getPreprocessor().LookUpIdentifierInfo(Tok);
5656
5657 if ((II->getObjCKeywordID() != tok::objc_not_keyword) && previousWasAt) {
5658 CXTok.int_data[0] = CXToken_Keyword;
5659 }
5660 else {
5661 CXTok.int_data[0] = Tok.is(tok::identifier)
5662 ? CXToken_Identifier
5663 : CXToken_Keyword;
5664 }
5665 CXTok.ptr_data = II;
5666 } else if (Tok.is(tok::comment)) {
5667 CXTok.int_data[0] = CXToken_Comment;
Craig Topper69186e72014-06-08 08:38:04 +00005668 CXTok.ptr_data = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005669 } else {
5670 CXTok.int_data[0] = CXToken_Punctuation;
Craig Topper69186e72014-06-08 08:38:04 +00005671 CXTok.ptr_data = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005672 }
5673 CXTokens.push_back(CXTok);
5674 previousWasAt = Tok.is(tok::at);
5675 } while (Lex.getBufferLocation() <= EffectiveBufferEnd);
5676}
5677
5678void clang_tokenize(CXTranslationUnit TU, CXSourceRange Range,
5679 CXToken **Tokens, unsigned *NumTokens) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00005680 LOG_FUNC_SECTION {
5681 *Log << TU << ' ' << Range;
5682 }
5683
Guy Benyei11169dd2012-12-18 14:30:41 +00005684 if (Tokens)
Craig Topper69186e72014-06-08 08:38:04 +00005685 *Tokens = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005686 if (NumTokens)
5687 *NumTokens = 0;
5688
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005689 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005690 LOG_BAD_TU(TU);
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00005691 return;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005692 }
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00005693
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005694 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005695 if (!CXXUnit || !Tokens || !NumTokens)
5696 return;
5697
5698 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
5699
5700 SourceRange R = cxloc::translateCXSourceRange(Range);
5701 if (R.isInvalid())
5702 return;
5703
5704 SmallVector<CXToken, 32> CXTokens;
5705 getTokens(CXXUnit, R, CXTokens);
5706
5707 if (CXTokens.empty())
5708 return;
5709
5710 *Tokens = (CXToken *)malloc(sizeof(CXToken) * CXTokens.size());
5711 memmove(*Tokens, CXTokens.data(), sizeof(CXToken) * CXTokens.size());
5712 *NumTokens = CXTokens.size();
5713}
5714
5715void clang_disposeTokens(CXTranslationUnit TU,
5716 CXToken *Tokens, unsigned NumTokens) {
5717 free(Tokens);
5718}
5719
5720} // end: extern "C"
5721
5722//===----------------------------------------------------------------------===//
5723// Token annotation APIs.
5724//===----------------------------------------------------------------------===//
5725
Guy Benyei11169dd2012-12-18 14:30:41 +00005726static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
5727 CXCursor parent,
5728 CXClientData client_data);
5729static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
5730 CXClientData client_data);
5731
5732namespace {
5733class AnnotateTokensWorker {
Guy Benyei11169dd2012-12-18 14:30:41 +00005734 CXToken *Tokens;
5735 CXCursor *Cursors;
5736 unsigned NumTokens;
5737 unsigned TokIdx;
5738 unsigned PreprocessingTokIdx;
5739 CursorVisitor AnnotateVis;
5740 SourceManager &SrcMgr;
5741 bool HasContextSensitiveKeywords;
5742
5743 struct PostChildrenInfo {
5744 CXCursor Cursor;
5745 SourceRange CursorRange;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005746 unsigned BeforeReachingCursorIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00005747 unsigned BeforeChildrenTokenIdx;
5748 };
Dmitri Gribenkof8579502013-01-12 19:30:44 +00005749 SmallVector<PostChildrenInfo, 8> PostChildrenInfos;
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005750
5751 CXToken &getTok(unsigned Idx) {
5752 assert(Idx < NumTokens);
5753 return Tokens[Idx];
5754 }
5755 const CXToken &getTok(unsigned Idx) const {
5756 assert(Idx < NumTokens);
5757 return Tokens[Idx];
5758 }
Guy Benyei11169dd2012-12-18 14:30:41 +00005759 bool MoreTokens() const { return TokIdx < NumTokens; }
5760 unsigned NextToken() const { return TokIdx; }
5761 void AdvanceToken() { ++TokIdx; }
5762 SourceLocation GetTokenLoc(unsigned tokI) {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005763 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[1]);
Guy Benyei11169dd2012-12-18 14:30:41 +00005764 }
5765 bool isFunctionMacroToken(unsigned tokI) const {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005766 return getTok(tokI).int_data[3] != 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00005767 }
5768 SourceLocation getFunctionMacroTokenLoc(unsigned tokI) const {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005769 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[3]);
Guy Benyei11169dd2012-12-18 14:30:41 +00005770 }
5771
5772 void annotateAndAdvanceTokens(CXCursor, RangeComparisonResult, SourceRange);
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005773 bool annotateAndAdvanceFunctionMacroTokens(CXCursor, RangeComparisonResult,
Guy Benyei11169dd2012-12-18 14:30:41 +00005774 SourceRange);
5775
5776public:
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005777 AnnotateTokensWorker(CXToken *tokens, CXCursor *cursors, unsigned numTokens,
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005778 CXTranslationUnit TU, SourceRange RegionOfInterest)
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005779 : Tokens(tokens), Cursors(cursors),
Guy Benyei11169dd2012-12-18 14:30:41 +00005780 NumTokens(numTokens), TokIdx(0), PreprocessingTokIdx(0),
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005781 AnnotateVis(TU,
Guy Benyei11169dd2012-12-18 14:30:41 +00005782 AnnotateTokensVisitor, this,
5783 /*VisitPreprocessorLast=*/true,
5784 /*VisitIncludedEntities=*/false,
5785 RegionOfInterest,
5786 /*VisitDeclsOnly=*/false,
5787 AnnotateTokensPostChildrenVisitor),
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005788 SrcMgr(cxtu::getASTUnit(TU)->getSourceManager()),
Guy Benyei11169dd2012-12-18 14:30:41 +00005789 HasContextSensitiveKeywords(false) { }
5790
5791 void VisitChildren(CXCursor C) { AnnotateVis.VisitChildren(C); }
5792 enum CXChildVisitResult Visit(CXCursor cursor, CXCursor parent);
5793 bool postVisitChildren(CXCursor cursor);
5794 void AnnotateTokens();
5795
5796 /// \brief Determine whether the annotator saw any cursors that have
5797 /// context-sensitive keywords.
5798 bool hasContextSensitiveKeywords() const {
5799 return HasContextSensitiveKeywords;
5800 }
5801
5802 ~AnnotateTokensWorker() {
5803 assert(PostChildrenInfos.empty());
5804 }
5805};
Alexander Kornienkoab9db512015-06-22 23:07:51 +00005806}
Guy Benyei11169dd2012-12-18 14:30:41 +00005807
5808void AnnotateTokensWorker::AnnotateTokens() {
5809 // Walk the AST within the region of interest, annotating tokens
5810 // along the way.
5811 AnnotateVis.visitFileRegion();
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005812}
Guy Benyei11169dd2012-12-18 14:30:41 +00005813
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005814static inline void updateCursorAnnotation(CXCursor &Cursor,
5815 const CXCursor &updateC) {
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005816 if (clang_isInvalid(updateC.kind) || !clang_isInvalid(Cursor.kind))
Guy Benyei11169dd2012-12-18 14:30:41 +00005817 return;
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005818 Cursor = updateC;
Guy Benyei11169dd2012-12-18 14:30:41 +00005819}
5820
5821/// \brief It annotates and advances tokens with a cursor until the comparison
5822//// between the cursor location and the source range is the same as
5823/// \arg compResult.
5824///
5825/// Pass RangeBefore to annotate tokens with a cursor until a range is reached.
5826/// Pass RangeOverlap to annotate tokens inside a range.
5827void AnnotateTokensWorker::annotateAndAdvanceTokens(CXCursor updateC,
5828 RangeComparisonResult compResult,
5829 SourceRange range) {
5830 while (MoreTokens()) {
5831 const unsigned I = NextToken();
5832 if (isFunctionMacroToken(I))
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005833 if (!annotateAndAdvanceFunctionMacroTokens(updateC, compResult, range))
5834 return;
Guy Benyei11169dd2012-12-18 14:30:41 +00005835
5836 SourceLocation TokLoc = GetTokenLoc(I);
5837 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005838 updateCursorAnnotation(Cursors[I], updateC);
Guy Benyei11169dd2012-12-18 14:30:41 +00005839 AdvanceToken();
5840 continue;
5841 }
5842 break;
5843 }
5844}
5845
5846/// \brief Special annotation handling for macro argument tokens.
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005847/// \returns true if it advanced beyond all macro tokens, false otherwise.
5848bool AnnotateTokensWorker::annotateAndAdvanceFunctionMacroTokens(
Guy Benyei11169dd2012-12-18 14:30:41 +00005849 CXCursor updateC,
5850 RangeComparisonResult compResult,
5851 SourceRange range) {
5852 assert(MoreTokens());
5853 assert(isFunctionMacroToken(NextToken()) &&
5854 "Should be called only for macro arg tokens");
5855
5856 // This works differently than annotateAndAdvanceTokens; because expanded
5857 // macro arguments can have arbitrary translation-unit source order, we do not
5858 // advance the token index one by one until a token fails the range test.
5859 // We only advance once past all of the macro arg tokens if all of them
5860 // pass the range test. If one of them fails we keep the token index pointing
5861 // at the start of the macro arg tokens so that the failing token will be
5862 // annotated by a subsequent annotation try.
5863
5864 bool atLeastOneCompFail = false;
5865
5866 unsigned I = NextToken();
5867 for (; I < NumTokens && isFunctionMacroToken(I); ++I) {
5868 SourceLocation TokLoc = getFunctionMacroTokenLoc(I);
5869 if (TokLoc.isFileID())
5870 continue; // not macro arg token, it's parens or comma.
5871 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
5872 if (clang_isInvalid(clang_getCursorKind(Cursors[I])))
5873 Cursors[I] = updateC;
5874 } else
5875 atLeastOneCompFail = true;
5876 }
5877
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005878 if (atLeastOneCompFail)
5879 return false;
5880
5881 TokIdx = I; // All of the tokens were handled, advance beyond all of them.
5882 return true;
Guy Benyei11169dd2012-12-18 14:30:41 +00005883}
5884
5885enum CXChildVisitResult
5886AnnotateTokensWorker::Visit(CXCursor cursor, CXCursor parent) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005887 SourceRange cursorRange = getRawCursorExtent(cursor);
5888 if (cursorRange.isInvalid())
5889 return CXChildVisit_Recurse;
5890
5891 if (!HasContextSensitiveKeywords) {
5892 // Objective-C properties can have context-sensitive keywords.
5893 if (cursor.kind == CXCursor_ObjCPropertyDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005894 if (const ObjCPropertyDecl *Property
Guy Benyei11169dd2012-12-18 14:30:41 +00005895 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(cursor)))
5896 HasContextSensitiveKeywords = Property->getPropertyAttributesAsWritten() != 0;
5897 }
5898 // Objective-C methods can have context-sensitive keywords.
5899 else if (cursor.kind == CXCursor_ObjCInstanceMethodDecl ||
5900 cursor.kind == CXCursor_ObjCClassMethodDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005901 if (const ObjCMethodDecl *Method
Guy Benyei11169dd2012-12-18 14:30:41 +00005902 = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
5903 if (Method->getObjCDeclQualifier())
5904 HasContextSensitiveKeywords = true;
5905 else {
Aaron Ballman43b68be2014-03-07 17:50:17 +00005906 for (const auto *P : Method->params()) {
5907 if (P->getObjCDeclQualifier()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005908 HasContextSensitiveKeywords = true;
5909 break;
5910 }
5911 }
5912 }
5913 }
5914 }
5915 // C++ methods can have context-sensitive keywords.
5916 else if (cursor.kind == CXCursor_CXXMethod) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005917 if (const CXXMethodDecl *Method
Guy Benyei11169dd2012-12-18 14:30:41 +00005918 = dyn_cast_or_null<CXXMethodDecl>(getCursorDecl(cursor))) {
5919 if (Method->hasAttr<FinalAttr>() || Method->hasAttr<OverrideAttr>())
5920 HasContextSensitiveKeywords = true;
5921 }
5922 }
5923 // C++ classes can have context-sensitive keywords.
5924 else if (cursor.kind == CXCursor_StructDecl ||
5925 cursor.kind == CXCursor_ClassDecl ||
5926 cursor.kind == CXCursor_ClassTemplate ||
5927 cursor.kind == CXCursor_ClassTemplatePartialSpecialization) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005928 if (const Decl *D = getCursorDecl(cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +00005929 if (D->hasAttr<FinalAttr>())
5930 HasContextSensitiveKeywords = true;
5931 }
5932 }
Argyrios Kyrtzidis990b3862013-06-04 18:24:30 +00005933
5934 // Don't override a property annotation with its getter/setter method.
5935 if (cursor.kind == CXCursor_ObjCInstanceMethodDecl &&
5936 parent.kind == CXCursor_ObjCPropertyDecl)
5937 return CXChildVisit_Continue;
Guy Benyei11169dd2012-12-18 14:30:41 +00005938
5939 if (clang_isPreprocessing(cursor.kind)) {
5940 // Items in the preprocessing record are kept separate from items in
5941 // declarations, so we keep a separate token index.
5942 unsigned SavedTokIdx = TokIdx;
5943 TokIdx = PreprocessingTokIdx;
5944
5945 // Skip tokens up until we catch up to the beginning of the preprocessing
5946 // entry.
5947 while (MoreTokens()) {
5948 const unsigned I = NextToken();
5949 SourceLocation TokLoc = GetTokenLoc(I);
5950 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
5951 case RangeBefore:
5952 AdvanceToken();
5953 continue;
5954 case RangeAfter:
5955 case RangeOverlap:
5956 break;
5957 }
5958 break;
5959 }
5960
5961 // Look at all of the tokens within this range.
5962 while (MoreTokens()) {
5963 const unsigned I = NextToken();
5964 SourceLocation TokLoc = GetTokenLoc(I);
5965 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
5966 case RangeBefore:
5967 llvm_unreachable("Infeasible");
5968 case RangeAfter:
5969 break;
5970 case RangeOverlap:
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005971 // For macro expansions, just note where the beginning of the macro
5972 // expansion occurs.
5973 if (cursor.kind == CXCursor_MacroExpansion) {
5974 if (TokLoc == cursorRange.getBegin())
5975 Cursors[I] = cursor;
5976 AdvanceToken();
5977 break;
5978 }
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005979 // We may have already annotated macro names inside macro definitions.
5980 if (Cursors[I].kind != CXCursor_MacroExpansion)
5981 Cursors[I] = cursor;
Guy Benyei11169dd2012-12-18 14:30:41 +00005982 AdvanceToken();
Guy Benyei11169dd2012-12-18 14:30:41 +00005983 continue;
5984 }
5985 break;
5986 }
5987
5988 // Save the preprocessing token index; restore the non-preprocessing
5989 // token index.
5990 PreprocessingTokIdx = TokIdx;
5991 TokIdx = SavedTokIdx;
5992 return CXChildVisit_Recurse;
5993 }
5994
5995 if (cursorRange.isInvalid())
5996 return CXChildVisit_Continue;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005997
5998 unsigned BeforeReachingCursorIdx = NextToken();
Guy Benyei11169dd2012-12-18 14:30:41 +00005999 const enum CXCursorKind cursorK = clang_getCursorKind(cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00006000 const enum CXCursorKind K = clang_getCursorKind(parent);
6001 const CXCursor updateC =
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00006002 (clang_isInvalid(K) || K == CXCursor_TranslationUnit ||
6003 // Attributes are annotated out-of-order, skip tokens until we reach it.
6004 clang_isAttribute(cursor.kind))
Guy Benyei11169dd2012-12-18 14:30:41 +00006005 ? clang_getNullCursor() : parent;
6006
6007 annotateAndAdvanceTokens(updateC, RangeBefore, cursorRange);
6008
6009 // Avoid having the cursor of an expression "overwrite" the annotation of the
6010 // variable declaration that it belongs to.
6011 // This can happen for C++ constructor expressions whose range generally
6012 // include the variable declaration, e.g.:
6013 // MyCXXClass foo; // Make sure we don't annotate 'foo' as a CallExpr cursor.
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00006014 if (clang_isExpression(cursorK) && MoreTokens()) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00006015 const Expr *E = getCursorExpr(cursor);
Dmitri Gribenkoa1691182013-01-26 18:12:08 +00006016 if (const Decl *D = getCursorParentDecl(cursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00006017 const unsigned I = NextToken();
6018 if (E->getLocStart().isValid() && D->getLocation().isValid() &&
6019 E->getLocStart() == D->getLocation() &&
6020 E->getLocStart() == GetTokenLoc(I)) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006021 updateCursorAnnotation(Cursors[I], updateC);
Guy Benyei11169dd2012-12-18 14:30:41 +00006022 AdvanceToken();
6023 }
6024 }
6025 }
6026
6027 // Before recursing into the children keep some state that we are going
6028 // to use in the AnnotateTokensWorker::postVisitChildren callback to do some
6029 // extra work after the child nodes are visited.
6030 // Note that we don't call VisitChildren here to avoid traversing statements
6031 // code-recursively which can blow the stack.
6032
6033 PostChildrenInfo Info;
6034 Info.Cursor = cursor;
6035 Info.CursorRange = cursorRange;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00006036 Info.BeforeReachingCursorIdx = BeforeReachingCursorIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00006037 Info.BeforeChildrenTokenIdx = NextToken();
6038 PostChildrenInfos.push_back(Info);
6039
6040 return CXChildVisit_Recurse;
6041}
6042
6043bool AnnotateTokensWorker::postVisitChildren(CXCursor cursor) {
6044 if (PostChildrenInfos.empty())
6045 return false;
6046 const PostChildrenInfo &Info = PostChildrenInfos.back();
6047 if (!clang_equalCursors(Info.Cursor, cursor))
6048 return false;
6049
6050 const unsigned BeforeChildren = Info.BeforeChildrenTokenIdx;
6051 const unsigned AfterChildren = NextToken();
6052 SourceRange cursorRange = Info.CursorRange;
6053
6054 // Scan the tokens that are at the end of the cursor, but are not captured
6055 // but the child cursors.
6056 annotateAndAdvanceTokens(cursor, RangeOverlap, cursorRange);
6057
6058 // Scan the tokens that are at the beginning of the cursor, but are not
6059 // capture by the child cursors.
6060 for (unsigned I = BeforeChildren; I != AfterChildren; ++I) {
6061 if (!clang_isInvalid(clang_getCursorKind(Cursors[I])))
6062 break;
6063
6064 Cursors[I] = cursor;
6065 }
6066
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00006067 // Attributes are annotated out-of-order, rewind TokIdx to when we first
6068 // encountered the attribute cursor.
6069 if (clang_isAttribute(cursor.kind))
6070 TokIdx = Info.BeforeReachingCursorIdx;
6071
Guy Benyei11169dd2012-12-18 14:30:41 +00006072 PostChildrenInfos.pop_back();
6073 return false;
6074}
6075
6076static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
6077 CXCursor parent,
6078 CXClientData client_data) {
6079 return static_cast<AnnotateTokensWorker*>(client_data)->Visit(cursor, parent);
6080}
6081
6082static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
6083 CXClientData client_data) {
6084 return static_cast<AnnotateTokensWorker*>(client_data)->
6085 postVisitChildren(cursor);
6086}
6087
6088namespace {
6089
6090/// \brief Uses the macro expansions in the preprocessing record to find
6091/// and mark tokens that are macro arguments. This info is used by the
6092/// AnnotateTokensWorker.
6093class MarkMacroArgTokensVisitor {
6094 SourceManager &SM;
6095 CXToken *Tokens;
6096 unsigned NumTokens;
6097 unsigned CurIdx;
6098
6099public:
6100 MarkMacroArgTokensVisitor(SourceManager &SM,
6101 CXToken *tokens, unsigned numTokens)
6102 : SM(SM), Tokens(tokens), NumTokens(numTokens), CurIdx(0) { }
6103
6104 CXChildVisitResult visit(CXCursor cursor, CXCursor parent) {
6105 if (cursor.kind != CXCursor_MacroExpansion)
6106 return CXChildVisit_Continue;
6107
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006108 SourceRange macroRange = getCursorMacroExpansion(cursor).getSourceRange();
Guy Benyei11169dd2012-12-18 14:30:41 +00006109 if (macroRange.getBegin() == macroRange.getEnd())
6110 return CXChildVisit_Continue; // it's not a function macro.
6111
6112 for (; CurIdx < NumTokens; ++CurIdx) {
6113 if (!SM.isBeforeInTranslationUnit(getTokenLoc(CurIdx),
6114 macroRange.getBegin()))
6115 break;
6116 }
6117
6118 if (CurIdx == NumTokens)
6119 return CXChildVisit_Break;
6120
6121 for (; CurIdx < NumTokens; ++CurIdx) {
6122 SourceLocation tokLoc = getTokenLoc(CurIdx);
6123 if (!SM.isBeforeInTranslationUnit(tokLoc, macroRange.getEnd()))
6124 break;
6125
6126 setFunctionMacroTokenLoc(CurIdx, SM.getMacroArgExpandedLocation(tokLoc));
6127 }
6128
6129 if (CurIdx == NumTokens)
6130 return CXChildVisit_Break;
6131
6132 return CXChildVisit_Continue;
6133 }
6134
6135private:
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00006136 CXToken &getTok(unsigned Idx) {
6137 assert(Idx < NumTokens);
6138 return Tokens[Idx];
6139 }
6140 const CXToken &getTok(unsigned Idx) const {
6141 assert(Idx < NumTokens);
6142 return Tokens[Idx];
6143 }
6144
Guy Benyei11169dd2012-12-18 14:30:41 +00006145 SourceLocation getTokenLoc(unsigned tokI) {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00006146 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[1]);
Guy Benyei11169dd2012-12-18 14:30:41 +00006147 }
6148
6149 void setFunctionMacroTokenLoc(unsigned tokI, SourceLocation loc) {
6150 // The third field is reserved and currently not used. Use it here
6151 // to mark macro arg expanded tokens with their expanded locations.
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00006152 getTok(tokI).int_data[3] = loc.getRawEncoding();
Guy Benyei11169dd2012-12-18 14:30:41 +00006153 }
6154};
6155
6156} // end anonymous namespace
6157
6158static CXChildVisitResult
6159MarkMacroArgTokensVisitorDelegate(CXCursor cursor, CXCursor parent,
6160 CXClientData client_data) {
6161 return static_cast<MarkMacroArgTokensVisitor*>(client_data)->visit(cursor,
6162 parent);
6163}
6164
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006165/// \brief Used by \c annotatePreprocessorTokens.
6166/// \returns true if lexing was finished, false otherwise.
6167static bool lexNext(Lexer &Lex, Token &Tok,
6168 unsigned &NextIdx, unsigned NumTokens) {
6169 if (NextIdx >= NumTokens)
6170 return true;
6171
6172 ++NextIdx;
6173 Lex.LexFromRawLexer(Tok);
6174 if (Tok.is(tok::eof))
6175 return true;
6176
6177 return false;
6178}
6179
Guy Benyei11169dd2012-12-18 14:30:41 +00006180static void annotatePreprocessorTokens(CXTranslationUnit TU,
6181 SourceRange RegionOfInterest,
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006182 CXCursor *Cursors,
6183 CXToken *Tokens,
6184 unsigned NumTokens) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006185 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00006186
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006187 Preprocessor &PP = CXXUnit->getPreprocessor();
Guy Benyei11169dd2012-12-18 14:30:41 +00006188 SourceManager &SourceMgr = CXXUnit->getSourceManager();
6189 std::pair<FileID, unsigned> BeginLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00006190 = SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getBegin());
Guy Benyei11169dd2012-12-18 14:30:41 +00006191 std::pair<FileID, unsigned> EndLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00006192 = SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getEnd());
Guy Benyei11169dd2012-12-18 14:30:41 +00006193
6194 if (BeginLocInfo.first != EndLocInfo.first)
6195 return;
6196
6197 StringRef Buffer;
6198 bool Invalid = false;
6199 Buffer = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
6200 if (Buffer.empty() || Invalid)
6201 return;
6202
6203 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
6204 CXXUnit->getASTContext().getLangOpts(),
6205 Buffer.begin(), Buffer.data() + BeginLocInfo.second,
6206 Buffer.end());
6207 Lex.SetCommentRetentionState(true);
6208
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006209 unsigned NextIdx = 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00006210 // Lex tokens in raw mode until we hit the end of the range, to avoid
6211 // entering #includes or expanding macros.
6212 while (true) {
6213 Token Tok;
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006214 if (lexNext(Lex, Tok, NextIdx, NumTokens))
6215 break;
6216 unsigned TokIdx = NextIdx-1;
6217 assert(Tok.getLocation() ==
6218 SourceLocation::getFromRawEncoding(Tokens[TokIdx].int_data[1]));
Guy Benyei11169dd2012-12-18 14:30:41 +00006219
6220 reprocess:
6221 if (Tok.is(tok::hash) && Tok.isAtStartOfLine()) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006222 // We have found a preprocessing directive. Annotate the tokens
6223 // appropriately.
Guy Benyei11169dd2012-12-18 14:30:41 +00006224 //
6225 // FIXME: Some simple tests here could identify macro definitions and
6226 // #undefs, to provide specific cursor kinds for those.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006227
6228 SourceLocation BeginLoc = Tok.getLocation();
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006229 if (lexNext(Lex, Tok, NextIdx, NumTokens))
6230 break;
6231
Craig Topper69186e72014-06-08 08:38:04 +00006232 MacroInfo *MI = nullptr;
Alp Toker2d57cea2014-05-17 04:53:25 +00006233 if (Tok.is(tok::raw_identifier) && Tok.getRawIdentifier() == "define") {
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006234 if (lexNext(Lex, Tok, NextIdx, NumTokens))
6235 break;
6236
6237 if (Tok.is(tok::raw_identifier)) {
Alp Toker2d57cea2014-05-17 04:53:25 +00006238 IdentifierInfo &II =
6239 PP.getIdentifierTable().get(Tok.getRawIdentifier());
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006240 SourceLocation MappedTokLoc =
6241 CXXUnit->mapLocationToPreamble(Tok.getLocation());
6242 MI = getMacroInfo(II, MappedTokLoc, TU);
6243 }
6244 }
6245
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006246 bool finished = false;
Guy Benyei11169dd2012-12-18 14:30:41 +00006247 do {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006248 if (lexNext(Lex, Tok, NextIdx, NumTokens)) {
6249 finished = true;
6250 break;
6251 }
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006252 // If we are in a macro definition, check if the token was ever a
6253 // macro name and annotate it if that's the case.
6254 if (MI) {
6255 SourceLocation SaveLoc = Tok.getLocation();
6256 Tok.setLocation(CXXUnit->mapLocationToPreamble(SaveLoc));
Richard Smith66a81862015-05-04 02:25:31 +00006257 MacroDefinitionRecord *MacroDef =
6258 checkForMacroInMacroDefinition(MI, Tok, TU);
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006259 Tok.setLocation(SaveLoc);
6260 if (MacroDef)
Richard Smith66a81862015-05-04 02:25:31 +00006261 Cursors[NextIdx - 1] =
6262 MakeMacroExpansionCursor(MacroDef, Tok.getLocation(), TU);
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006263 }
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006264 } while (!Tok.isAtStartOfLine());
6265
6266 unsigned LastIdx = finished ? NextIdx-1 : NextIdx-2;
6267 assert(TokIdx <= LastIdx);
6268 SourceLocation EndLoc =
6269 SourceLocation::getFromRawEncoding(Tokens[LastIdx].int_data[1]);
6270 CXCursor Cursor =
6271 MakePreprocessingDirectiveCursor(SourceRange(BeginLoc, EndLoc), TU);
6272
6273 for (; TokIdx <= LastIdx; ++TokIdx)
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006274 updateCursorAnnotation(Cursors[TokIdx], Cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00006275
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006276 if (finished)
6277 break;
6278 goto reprocess;
Guy Benyei11169dd2012-12-18 14:30:41 +00006279 }
Guy Benyei11169dd2012-12-18 14:30:41 +00006280 }
6281}
6282
6283// This gets run a separate thread to avoid stack blowout.
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00006284static void clang_annotateTokensImpl(CXTranslationUnit TU, ASTUnit *CXXUnit,
6285 CXToken *Tokens, unsigned NumTokens,
6286 CXCursor *Cursors) {
Dmitri Gribenko183436e2013-01-26 21:49:50 +00006287 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00006288 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
6289 setThreadBackgroundPriority();
6290
6291 // Determine the region of interest, which contains all of the tokens.
6292 SourceRange RegionOfInterest;
6293 RegionOfInterest.setBegin(
6294 cxloc::translateSourceLocation(clang_getTokenLocation(TU, Tokens[0])));
6295 RegionOfInterest.setEnd(
6296 cxloc::translateSourceLocation(clang_getTokenLocation(TU,
6297 Tokens[NumTokens-1])));
6298
Guy Benyei11169dd2012-12-18 14:30:41 +00006299 // Relex the tokens within the source range to look for preprocessing
6300 // directives.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006301 annotatePreprocessorTokens(TU, RegionOfInterest, Cursors, Tokens, NumTokens);
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00006302
6303 // If begin location points inside a macro argument, set it to the expansion
6304 // location so we can have the full context when annotating semantically.
6305 {
6306 SourceManager &SM = CXXUnit->getSourceManager();
6307 SourceLocation Loc =
6308 SM.getMacroArgExpandedLocation(RegionOfInterest.getBegin());
6309 if (Loc.isMacroID())
6310 RegionOfInterest.setBegin(SM.getExpansionLoc(Loc));
6311 }
6312
Guy Benyei11169dd2012-12-18 14:30:41 +00006313 if (CXXUnit->getPreprocessor().getPreprocessingRecord()) {
6314 // Search and mark tokens that are macro argument expansions.
6315 MarkMacroArgTokensVisitor Visitor(CXXUnit->getSourceManager(),
6316 Tokens, NumTokens);
6317 CursorVisitor MacroArgMarker(TU,
6318 MarkMacroArgTokensVisitorDelegate, &Visitor,
6319 /*VisitPreprocessorLast=*/true,
6320 /*VisitIncludedEntities=*/false,
6321 RegionOfInterest);
6322 MacroArgMarker.visitPreprocessedEntitiesInRegion();
6323 }
6324
6325 // Annotate all of the source locations in the region of interest that map to
6326 // a specific cursor.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006327 AnnotateTokensWorker W(Tokens, Cursors, NumTokens, TU, RegionOfInterest);
Guy Benyei11169dd2012-12-18 14:30:41 +00006328
6329 // FIXME: We use a ridiculous stack size here because the data-recursion
6330 // algorithm uses a large stack frame than the non-data recursive version,
6331 // and AnnotationTokensWorker currently transforms the data-recursion
6332 // algorithm back into a traditional recursion by explicitly calling
6333 // VisitChildren(). We will need to remove this explicit recursive call.
6334 W.AnnotateTokens();
6335
6336 // If we ran into any entities that involve context-sensitive keywords,
6337 // take another pass through the tokens to mark them as such.
6338 if (W.hasContextSensitiveKeywords()) {
6339 for (unsigned I = 0; I != NumTokens; ++I) {
6340 if (clang_getTokenKind(Tokens[I]) != CXToken_Identifier)
6341 continue;
6342
6343 if (Cursors[I].kind == CXCursor_ObjCPropertyDecl) {
6344 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006345 if (const ObjCPropertyDecl *Property
Guy Benyei11169dd2012-12-18 14:30:41 +00006346 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(Cursors[I]))) {
6347 if (Property->getPropertyAttributesAsWritten() != 0 &&
6348 llvm::StringSwitch<bool>(II->getName())
6349 .Case("readonly", true)
6350 .Case("assign", true)
6351 .Case("unsafe_unretained", true)
6352 .Case("readwrite", true)
6353 .Case("retain", true)
6354 .Case("copy", true)
6355 .Case("nonatomic", true)
6356 .Case("atomic", true)
6357 .Case("getter", true)
6358 .Case("setter", true)
6359 .Case("strong", true)
6360 .Case("weak", true)
6361 .Default(false))
6362 Tokens[I].int_data[0] = CXToken_Keyword;
6363 }
6364 continue;
6365 }
6366
6367 if (Cursors[I].kind == CXCursor_ObjCInstanceMethodDecl ||
6368 Cursors[I].kind == CXCursor_ObjCClassMethodDecl) {
6369 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
6370 if (llvm::StringSwitch<bool>(II->getName())
6371 .Case("in", true)
6372 .Case("out", true)
6373 .Case("inout", true)
6374 .Case("oneway", true)
6375 .Case("bycopy", true)
6376 .Case("byref", true)
6377 .Default(false))
6378 Tokens[I].int_data[0] = CXToken_Keyword;
6379 continue;
6380 }
6381
6382 if (Cursors[I].kind == CXCursor_CXXFinalAttr ||
6383 Cursors[I].kind == CXCursor_CXXOverrideAttr) {
6384 Tokens[I].int_data[0] = CXToken_Keyword;
6385 continue;
6386 }
6387 }
6388 }
6389}
6390
6391extern "C" {
6392
6393void clang_annotateTokens(CXTranslationUnit TU,
6394 CXToken *Tokens, unsigned NumTokens,
6395 CXCursor *Cursors) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006396 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006397 LOG_BAD_TU(TU);
6398 return;
6399 }
6400 if (NumTokens == 0 || !Tokens || !Cursors) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006401 LOG_FUNC_SECTION { *Log << "<null input>"; }
Guy Benyei11169dd2012-12-18 14:30:41 +00006402 return;
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006403 }
6404
6405 LOG_FUNC_SECTION {
6406 *Log << TU << ' ';
6407 CXSourceLocation bloc = clang_getTokenLocation(TU, Tokens[0]);
6408 CXSourceLocation eloc = clang_getTokenLocation(TU, Tokens[NumTokens-1]);
6409 *Log << clang_getRange(bloc, eloc);
6410 }
Guy Benyei11169dd2012-12-18 14:30:41 +00006411
6412 // Any token we don't specifically annotate will have a NULL cursor.
6413 CXCursor C = clang_getNullCursor();
6414 for (unsigned I = 0; I != NumTokens; ++I)
6415 Cursors[I] = C;
6416
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006417 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00006418 if (!CXXUnit)
6419 return;
6420
6421 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00006422
6423 auto AnnotateTokensImpl = [=]() {
6424 clang_annotateTokensImpl(TU, CXXUnit, Tokens, NumTokens, Cursors);
6425 };
Guy Benyei11169dd2012-12-18 14:30:41 +00006426 llvm::CrashRecoveryContext CRC;
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00006427 if (!RunSafely(CRC, AnnotateTokensImpl, GetSafetyThreadStackSize() * 2)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00006428 fprintf(stderr, "libclang: crash detected while annotating tokens\n");
6429 }
6430}
6431
6432} // end: extern "C"
6433
6434//===----------------------------------------------------------------------===//
6435// Operations for querying linkage of a cursor.
6436//===----------------------------------------------------------------------===//
6437
6438extern "C" {
6439CXLinkageKind clang_getCursorLinkage(CXCursor cursor) {
6440 if (!clang_isDeclaration(cursor.kind))
6441 return CXLinkage_Invalid;
6442
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006443 const Decl *D = cxcursor::getCursorDecl(cursor);
6444 if (const NamedDecl *ND = dyn_cast_or_null<NamedDecl>(D))
Rafael Espindola3ae00052013-05-13 00:12:11 +00006445 switch (ND->getLinkageInternal()) {
Rafael Espindola50df3a02013-05-25 17:16:20 +00006446 case NoLinkage:
6447 case VisibleNoLinkage: return CXLinkage_NoLinkage;
Guy Benyei11169dd2012-12-18 14:30:41 +00006448 case InternalLinkage: return CXLinkage_Internal;
6449 case UniqueExternalLinkage: return CXLinkage_UniqueExternal;
6450 case ExternalLinkage: return CXLinkage_External;
6451 };
6452
6453 return CXLinkage_Invalid;
6454}
6455} // end: extern "C"
6456
6457//===----------------------------------------------------------------------===//
Ehsan Akhgari93697fa2015-11-23 19:56:46 +00006458// Operations for querying visibility of a cursor.
6459//===----------------------------------------------------------------------===//
6460
6461extern "C" {
6462CXVisibilityKind clang_getCursorVisibility(CXCursor cursor) {
6463 if (!clang_isDeclaration(cursor.kind))
6464 return CXVisibility_Invalid;
6465
6466 const Decl *D = cxcursor::getCursorDecl(cursor);
6467 if (const NamedDecl *ND = dyn_cast_or_null<NamedDecl>(D))
6468 switch (ND->getVisibility()) {
6469 case HiddenVisibility: return CXVisibility_Hidden;
6470 case ProtectedVisibility: return CXVisibility_Protected;
6471 case DefaultVisibility: return CXVisibility_Default;
6472 };
6473
6474 return CXVisibility_Invalid;
6475}
6476} // end: extern "C"
6477
6478//===----------------------------------------------------------------------===//
Guy Benyei11169dd2012-12-18 14:30:41 +00006479// Operations for querying language of a cursor.
6480//===----------------------------------------------------------------------===//
6481
6482static CXLanguageKind getDeclLanguage(const Decl *D) {
6483 if (!D)
6484 return CXLanguage_C;
6485
6486 switch (D->getKind()) {
6487 default:
6488 break;
6489 case Decl::ImplicitParam:
6490 case Decl::ObjCAtDefsField:
6491 case Decl::ObjCCategory:
6492 case Decl::ObjCCategoryImpl:
6493 case Decl::ObjCCompatibleAlias:
6494 case Decl::ObjCImplementation:
6495 case Decl::ObjCInterface:
6496 case Decl::ObjCIvar:
6497 case Decl::ObjCMethod:
6498 case Decl::ObjCProperty:
6499 case Decl::ObjCPropertyImpl:
6500 case Decl::ObjCProtocol:
Douglas Gregor85f3f952015-07-07 03:57:15 +00006501 case Decl::ObjCTypeParam:
Guy Benyei11169dd2012-12-18 14:30:41 +00006502 return CXLanguage_ObjC;
6503 case Decl::CXXConstructor:
6504 case Decl::CXXConversion:
6505 case Decl::CXXDestructor:
6506 case Decl::CXXMethod:
6507 case Decl::CXXRecord:
6508 case Decl::ClassTemplate:
6509 case Decl::ClassTemplatePartialSpecialization:
6510 case Decl::ClassTemplateSpecialization:
6511 case Decl::Friend:
6512 case Decl::FriendTemplate:
6513 case Decl::FunctionTemplate:
6514 case Decl::LinkageSpec:
6515 case Decl::Namespace:
6516 case Decl::NamespaceAlias:
6517 case Decl::NonTypeTemplateParm:
6518 case Decl::StaticAssert:
6519 case Decl::TemplateTemplateParm:
6520 case Decl::TemplateTypeParm:
6521 case Decl::UnresolvedUsingTypename:
6522 case Decl::UnresolvedUsingValue:
6523 case Decl::Using:
6524 case Decl::UsingDirective:
6525 case Decl::UsingShadow:
6526 return CXLanguage_CPlusPlus;
6527 }
6528
6529 return CXLanguage_C;
6530}
6531
6532extern "C" {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006533
6534static CXAvailabilityKind getCursorAvailabilityForDecl(const Decl *D) {
6535 if (isa<FunctionDecl>(D) && cast<FunctionDecl>(D)->isDeleted())
Manuel Klimek8e3a7ed2015-09-25 17:53:16 +00006536 return CXAvailability_NotAvailable;
Guy Benyei11169dd2012-12-18 14:30:41 +00006537
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006538 switch (D->getAvailability()) {
6539 case AR_Available:
6540 case AR_NotYetIntroduced:
6541 if (const EnumConstantDecl *EnumConst = dyn_cast<EnumConstantDecl>(D))
Benjamin Kramer656363d2013-10-15 18:53:18 +00006542 return getCursorAvailabilityForDecl(
6543 cast<Decl>(EnumConst->getDeclContext()));
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006544 return CXAvailability_Available;
6545
6546 case AR_Deprecated:
6547 return CXAvailability_Deprecated;
6548
6549 case AR_Unavailable:
6550 return CXAvailability_NotAvailable;
6551 }
Benjamin Kramer656363d2013-10-15 18:53:18 +00006552
6553 llvm_unreachable("Unknown availability kind!");
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006554}
6555
Guy Benyei11169dd2012-12-18 14:30:41 +00006556enum CXAvailabilityKind clang_getCursorAvailability(CXCursor cursor) {
6557 if (clang_isDeclaration(cursor.kind))
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006558 if (const Decl *D = cxcursor::getCursorDecl(cursor))
6559 return getCursorAvailabilityForDecl(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00006560
6561 return CXAvailability_Available;
6562}
6563
6564static CXVersion convertVersion(VersionTuple In) {
6565 CXVersion Out = { -1, -1, -1 };
6566 if (In.empty())
6567 return Out;
6568
6569 Out.Major = In.getMajor();
6570
NAKAMURA Takumic2b5d1f2013-02-21 02:32:34 +00006571 Optional<unsigned> Minor = In.getMinor();
6572 if (Minor.hasValue())
Guy Benyei11169dd2012-12-18 14:30:41 +00006573 Out.Minor = *Minor;
6574 else
6575 return Out;
6576
NAKAMURA Takumic2b5d1f2013-02-21 02:32:34 +00006577 Optional<unsigned> Subminor = In.getSubminor();
6578 if (Subminor.hasValue())
Guy Benyei11169dd2012-12-18 14:30:41 +00006579 Out.Subminor = *Subminor;
6580
6581 return Out;
6582}
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006583
6584static int getCursorPlatformAvailabilityForDecl(const Decl *D,
6585 int *always_deprecated,
6586 CXString *deprecated_message,
6587 int *always_unavailable,
6588 CXString *unavailable_message,
6589 CXPlatformAvailability *availability,
6590 int availability_size) {
6591 bool HadAvailAttr = false;
6592 int N = 0;
Aaron Ballmanb97112e2014-03-08 22:19:01 +00006593 for (auto A : D->attrs()) {
6594 if (DeprecatedAttr *Deprecated = dyn_cast<DeprecatedAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006595 HadAvailAttr = true;
6596 if (always_deprecated)
6597 *always_deprecated = 1;
Nico Weberaacf0312014-04-24 05:16:45 +00006598 if (deprecated_message) {
Argyrios Kyrtzidisedfe07f2014-04-24 06:05:40 +00006599 clang_disposeString(*deprecated_message);
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006600 *deprecated_message = cxstring::createDup(Deprecated->getMessage());
Nico Weberaacf0312014-04-24 05:16:45 +00006601 }
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006602 continue;
6603 }
6604
Aaron Ballmanb97112e2014-03-08 22:19:01 +00006605 if (UnavailableAttr *Unavailable = dyn_cast<UnavailableAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006606 HadAvailAttr = true;
6607 if (always_unavailable)
6608 *always_unavailable = 1;
6609 if (unavailable_message) {
Argyrios Kyrtzidisedfe07f2014-04-24 06:05:40 +00006610 clang_disposeString(*unavailable_message);
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006611 *unavailable_message = cxstring::createDup(Unavailable->getMessage());
6612 }
6613 continue;
6614 }
6615
Aaron Ballmanb97112e2014-03-08 22:19:01 +00006616 if (AvailabilityAttr *Avail = dyn_cast<AvailabilityAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006617 HadAvailAttr = true;
6618 if (N < availability_size) {
6619 availability[N].Platform
6620 = cxstring::createDup(Avail->getPlatform()->getName());
6621 availability[N].Introduced = convertVersion(Avail->getIntroduced());
6622 availability[N].Deprecated = convertVersion(Avail->getDeprecated());
6623 availability[N].Obsoleted = convertVersion(Avail->getObsoleted());
6624 availability[N].Unavailable = Avail->getUnavailable();
6625 availability[N].Message = cxstring::createDup(Avail->getMessage());
6626 }
6627 ++N;
6628 }
6629 }
6630
6631 if (!HadAvailAttr)
6632 if (const EnumConstantDecl *EnumConst = dyn_cast<EnumConstantDecl>(D))
6633 return getCursorPlatformAvailabilityForDecl(
6634 cast<Decl>(EnumConst->getDeclContext()),
6635 always_deprecated,
6636 deprecated_message,
6637 always_unavailable,
6638 unavailable_message,
6639 availability,
6640 availability_size);
Guy Benyei11169dd2012-12-18 14:30:41 +00006641
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006642 return N;
6643}
6644
Guy Benyei11169dd2012-12-18 14:30:41 +00006645int clang_getCursorPlatformAvailability(CXCursor cursor,
6646 int *always_deprecated,
6647 CXString *deprecated_message,
6648 int *always_unavailable,
6649 CXString *unavailable_message,
6650 CXPlatformAvailability *availability,
6651 int availability_size) {
6652 if (always_deprecated)
6653 *always_deprecated = 0;
6654 if (deprecated_message)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006655 *deprecated_message = cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006656 if (always_unavailable)
6657 *always_unavailable = 0;
6658 if (unavailable_message)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006659 *unavailable_message = cxstring::createEmpty();
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006660
Guy Benyei11169dd2012-12-18 14:30:41 +00006661 if (!clang_isDeclaration(cursor.kind))
6662 return 0;
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006663
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006664 const Decl *D = cxcursor::getCursorDecl(cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00006665 if (!D)
6666 return 0;
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006667
6668 return getCursorPlatformAvailabilityForDecl(D, always_deprecated,
6669 deprecated_message,
6670 always_unavailable,
6671 unavailable_message,
6672 availability,
6673 availability_size);
Guy Benyei11169dd2012-12-18 14:30:41 +00006674}
6675
6676void clang_disposeCXPlatformAvailability(CXPlatformAvailability *availability) {
6677 clang_disposeString(availability->Platform);
6678 clang_disposeString(availability->Message);
6679}
6680
6681CXLanguageKind clang_getCursorLanguage(CXCursor cursor) {
6682 if (clang_isDeclaration(cursor.kind))
6683 return getDeclLanguage(cxcursor::getCursorDecl(cursor));
6684
6685 return CXLanguage_Invalid;
6686}
6687
6688 /// \brief If the given cursor is the "templated" declaration
6689 /// descibing a class or function template, return the class or
6690 /// function template.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006691static const Decl *maybeGetTemplateCursor(const Decl *D) {
Guy Benyei11169dd2012-12-18 14:30:41 +00006692 if (!D)
Craig Topper69186e72014-06-08 08:38:04 +00006693 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006694
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006695 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00006696 if (FunctionTemplateDecl *FunTmpl = FD->getDescribedFunctionTemplate())
6697 return FunTmpl;
6698
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006699 if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00006700 if (ClassTemplateDecl *ClassTmpl = RD->getDescribedClassTemplate())
6701 return ClassTmpl;
6702
6703 return D;
6704}
6705
Argyrios Kyrtzidis4e0854f2014-10-15 17:05:31 +00006706
6707enum CX_StorageClass clang_Cursor_getStorageClass(CXCursor C) {
6708 StorageClass sc = SC_None;
6709 const Decl *D = getCursorDecl(C);
6710 if (D) {
6711 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
6712 sc = FD->getStorageClass();
6713 } else if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
6714 sc = VD->getStorageClass();
6715 } else {
6716 return CX_SC_Invalid;
6717 }
6718 } else {
6719 return CX_SC_Invalid;
6720 }
6721 switch (sc) {
6722 case SC_None:
6723 return CX_SC_None;
6724 case SC_Extern:
6725 return CX_SC_Extern;
6726 case SC_Static:
6727 return CX_SC_Static;
6728 case SC_PrivateExtern:
6729 return CX_SC_PrivateExtern;
Argyrios Kyrtzidis4e0854f2014-10-15 17:05:31 +00006730 case SC_Auto:
6731 return CX_SC_Auto;
6732 case SC_Register:
6733 return CX_SC_Register;
Argyrios Kyrtzidis4e0854f2014-10-15 17:05:31 +00006734 }
Kaelyn Takataab61e702014-10-15 18:03:26 +00006735 llvm_unreachable("Unhandled storage class!");
Argyrios Kyrtzidis4e0854f2014-10-15 17:05:31 +00006736}
6737
Guy Benyei11169dd2012-12-18 14:30:41 +00006738CXCursor clang_getCursorSemanticParent(CXCursor cursor) {
6739 if (clang_isDeclaration(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006740 if (const Decl *D = getCursorDecl(cursor)) {
6741 const DeclContext *DC = D->getDeclContext();
Guy Benyei11169dd2012-12-18 14:30:41 +00006742 if (!DC)
6743 return clang_getNullCursor();
6744
6745 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
6746 getCursorTU(cursor));
6747 }
6748 }
6749
6750 if (clang_isStatement(cursor.kind) || clang_isExpression(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006751 if (const Decl *D = getCursorDecl(cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +00006752 return MakeCXCursor(D, getCursorTU(cursor));
6753 }
6754
6755 return clang_getNullCursor();
6756}
6757
6758CXCursor clang_getCursorLexicalParent(CXCursor cursor) {
6759 if (clang_isDeclaration(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006760 if (const Decl *D = getCursorDecl(cursor)) {
6761 const DeclContext *DC = D->getLexicalDeclContext();
Guy Benyei11169dd2012-12-18 14:30:41 +00006762 if (!DC)
6763 return clang_getNullCursor();
6764
6765 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
6766 getCursorTU(cursor));
6767 }
6768 }
6769
6770 // FIXME: Note that we can't easily compute the lexical context of a
6771 // statement or expression, so we return nothing.
6772 return clang_getNullCursor();
6773}
6774
6775CXFile clang_getIncludedFile(CXCursor cursor) {
6776 if (cursor.kind != CXCursor_InclusionDirective)
Craig Topper69186e72014-06-08 08:38:04 +00006777 return nullptr;
6778
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00006779 const InclusionDirective *ID = getCursorInclusionDirective(cursor);
Dmitri Gribenkof9304482013-01-23 15:56:07 +00006780 return const_cast<FileEntry *>(ID->getFile());
Guy Benyei11169dd2012-12-18 14:30:41 +00006781}
6782
Argyrios Kyrtzidis9adfd8a2013-04-18 22:15:49 +00006783unsigned clang_Cursor_getObjCPropertyAttributes(CXCursor C, unsigned reserved) {
6784 if (C.kind != CXCursor_ObjCPropertyDecl)
6785 return CXObjCPropertyAttr_noattr;
6786
6787 unsigned Result = CXObjCPropertyAttr_noattr;
6788 const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(getCursorDecl(C));
6789 ObjCPropertyDecl::PropertyAttributeKind Attr =
6790 PD->getPropertyAttributesAsWritten();
6791
6792#define SET_CXOBJCPROP_ATTR(A) \
6793 if (Attr & ObjCPropertyDecl::OBJC_PR_##A) \
6794 Result |= CXObjCPropertyAttr_##A
6795 SET_CXOBJCPROP_ATTR(readonly);
6796 SET_CXOBJCPROP_ATTR(getter);
6797 SET_CXOBJCPROP_ATTR(assign);
6798 SET_CXOBJCPROP_ATTR(readwrite);
6799 SET_CXOBJCPROP_ATTR(retain);
6800 SET_CXOBJCPROP_ATTR(copy);
6801 SET_CXOBJCPROP_ATTR(nonatomic);
6802 SET_CXOBJCPROP_ATTR(setter);
6803 SET_CXOBJCPROP_ATTR(atomic);
6804 SET_CXOBJCPROP_ATTR(weak);
6805 SET_CXOBJCPROP_ATTR(strong);
6806 SET_CXOBJCPROP_ATTR(unsafe_unretained);
6807#undef SET_CXOBJCPROP_ATTR
6808
6809 return Result;
6810}
6811
Argyrios Kyrtzidis9d9bc012013-04-18 23:29:12 +00006812unsigned clang_Cursor_getObjCDeclQualifiers(CXCursor C) {
6813 if (!clang_isDeclaration(C.kind))
6814 return CXObjCDeclQualifier_None;
6815
6816 Decl::ObjCDeclQualifier QT = Decl::OBJC_TQ_None;
6817 const Decl *D = getCursorDecl(C);
6818 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6819 QT = MD->getObjCDeclQualifier();
6820 else if (const ParmVarDecl *PD = dyn_cast<ParmVarDecl>(D))
6821 QT = PD->getObjCDeclQualifier();
6822 if (QT == Decl::OBJC_TQ_None)
6823 return CXObjCDeclQualifier_None;
6824
6825 unsigned Result = CXObjCDeclQualifier_None;
6826 if (QT & Decl::OBJC_TQ_In) Result |= CXObjCDeclQualifier_In;
6827 if (QT & Decl::OBJC_TQ_Inout) Result |= CXObjCDeclQualifier_Inout;
6828 if (QT & Decl::OBJC_TQ_Out) Result |= CXObjCDeclQualifier_Out;
6829 if (QT & Decl::OBJC_TQ_Bycopy) Result |= CXObjCDeclQualifier_Bycopy;
6830 if (QT & Decl::OBJC_TQ_Byref) Result |= CXObjCDeclQualifier_Byref;
6831 if (QT & Decl::OBJC_TQ_Oneway) Result |= CXObjCDeclQualifier_Oneway;
6832
6833 return Result;
6834}
6835
Argyrios Kyrtzidis7b50fc52013-07-05 20:44:37 +00006836unsigned clang_Cursor_isObjCOptional(CXCursor C) {
6837 if (!clang_isDeclaration(C.kind))
6838 return 0;
6839
6840 const Decl *D = getCursorDecl(C);
6841 if (const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(D))
6842 return PD->getPropertyImplementation() == ObjCPropertyDecl::Optional;
6843 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6844 return MD->getImplementationControl() == ObjCMethodDecl::Optional;
6845
6846 return 0;
6847}
6848
Argyrios Kyrtzidis23814e42013-04-18 23:53:05 +00006849unsigned clang_Cursor_isVariadic(CXCursor C) {
6850 if (!clang_isDeclaration(C.kind))
6851 return 0;
6852
6853 const Decl *D = getCursorDecl(C);
6854 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
6855 return FD->isVariadic();
6856 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6857 return MD->isVariadic();
6858
6859 return 0;
6860}
6861
Guy Benyei11169dd2012-12-18 14:30:41 +00006862CXSourceRange clang_Cursor_getCommentRange(CXCursor C) {
6863 if (!clang_isDeclaration(C.kind))
6864 return clang_getNullRange();
6865
6866 const Decl *D = getCursorDecl(C);
6867 ASTContext &Context = getCursorContext(C);
6868 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6869 if (!RC)
6870 return clang_getNullRange();
6871
6872 return cxloc::translateSourceRange(Context, RC->getSourceRange());
6873}
6874
6875CXString clang_Cursor_getRawCommentText(CXCursor C) {
6876 if (!clang_isDeclaration(C.kind))
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006877 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006878
6879 const Decl *D = getCursorDecl(C);
6880 ASTContext &Context = getCursorContext(C);
6881 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6882 StringRef RawText = RC ? RC->getRawText(Context.getSourceManager()) :
6883 StringRef();
6884
6885 // Don't duplicate the string because RawText points directly into source
6886 // code.
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006887 return cxstring::createRef(RawText);
Guy Benyei11169dd2012-12-18 14:30:41 +00006888}
6889
6890CXString clang_Cursor_getBriefCommentText(CXCursor C) {
6891 if (!clang_isDeclaration(C.kind))
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006892 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006893
6894 const Decl *D = getCursorDecl(C);
6895 const ASTContext &Context = getCursorContext(C);
6896 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6897
6898 if (RC) {
6899 StringRef BriefText = RC->getBriefText(Context);
6900
6901 // Don't duplicate the string because RawComment ensures that this memory
6902 // will not go away.
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006903 return cxstring::createRef(BriefText);
Guy Benyei11169dd2012-12-18 14:30:41 +00006904 }
6905
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006906 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006907}
6908
Guy Benyei11169dd2012-12-18 14:30:41 +00006909CXModule clang_Cursor_getModule(CXCursor C) {
6910 if (C.kind == CXCursor_ModuleImportDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006911 if (const ImportDecl *ImportD =
6912 dyn_cast_or_null<ImportDecl>(getCursorDecl(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00006913 return ImportD->getImportedModule();
6914 }
6915
Craig Topper69186e72014-06-08 08:38:04 +00006916 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006917}
6918
Argyrios Kyrtzidisf6d49c32014-05-14 23:14:37 +00006919CXModule clang_getModuleForFile(CXTranslationUnit TU, CXFile File) {
6920 if (isNotUsableTU(TU)) {
6921 LOG_BAD_TU(TU);
6922 return nullptr;
6923 }
6924 if (!File)
6925 return nullptr;
6926 FileEntry *FE = static_cast<FileEntry *>(File);
6927
6928 ASTUnit &Unit = *cxtu::getASTUnit(TU);
6929 HeaderSearch &HS = Unit.getPreprocessor().getHeaderSearchInfo();
6930 ModuleMap::KnownHeader Header = HS.findModuleForHeader(FE);
6931
Richard Smithfeb54b62014-10-23 02:01:19 +00006932 return Header.getModule();
Argyrios Kyrtzidisf6d49c32014-05-14 23:14:37 +00006933}
6934
Argyrios Kyrtzidis12fdb9e2013-04-26 22:47:49 +00006935CXFile clang_Module_getASTFile(CXModule CXMod) {
6936 if (!CXMod)
Craig Topper69186e72014-06-08 08:38:04 +00006937 return nullptr;
Argyrios Kyrtzidis12fdb9e2013-04-26 22:47:49 +00006938 Module *Mod = static_cast<Module*>(CXMod);
6939 return const_cast<FileEntry *>(Mod->getASTFile());
6940}
6941
Guy Benyei11169dd2012-12-18 14:30:41 +00006942CXModule clang_Module_getParent(CXModule CXMod) {
6943 if (!CXMod)
Craig Topper69186e72014-06-08 08:38:04 +00006944 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006945 Module *Mod = static_cast<Module*>(CXMod);
6946 return Mod->Parent;
6947}
6948
6949CXString clang_Module_getName(CXModule CXMod) {
6950 if (!CXMod)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006951 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006952 Module *Mod = static_cast<Module*>(CXMod);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006953 return cxstring::createDup(Mod->Name);
Guy Benyei11169dd2012-12-18 14:30:41 +00006954}
6955
6956CXString clang_Module_getFullName(CXModule CXMod) {
6957 if (!CXMod)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006958 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006959 Module *Mod = static_cast<Module*>(CXMod);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006960 return cxstring::createDup(Mod->getFullModuleName());
Guy Benyei11169dd2012-12-18 14:30:41 +00006961}
6962
Argyrios Kyrtzidis884337f2014-05-15 04:44:25 +00006963int clang_Module_isSystem(CXModule CXMod) {
6964 if (!CXMod)
6965 return 0;
6966 Module *Mod = static_cast<Module*>(CXMod);
6967 return Mod->IsSystem;
6968}
6969
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006970unsigned clang_Module_getNumTopLevelHeaders(CXTranslationUnit TU,
6971 CXModule CXMod) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006972 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006973 LOG_BAD_TU(TU);
6974 return 0;
6975 }
6976 if (!CXMod)
Guy Benyei11169dd2012-12-18 14:30:41 +00006977 return 0;
6978 Module *Mod = static_cast<Module*>(CXMod);
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006979 FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
6980 ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
6981 return TopHeaders.size();
Guy Benyei11169dd2012-12-18 14:30:41 +00006982}
6983
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006984CXFile clang_Module_getTopLevelHeader(CXTranslationUnit TU,
6985 CXModule CXMod, unsigned Index) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006986 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006987 LOG_BAD_TU(TU);
Craig Topper69186e72014-06-08 08:38:04 +00006988 return nullptr;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006989 }
6990 if (!CXMod)
Craig Topper69186e72014-06-08 08:38:04 +00006991 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006992 Module *Mod = static_cast<Module*>(CXMod);
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006993 FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
Guy Benyei11169dd2012-12-18 14:30:41 +00006994
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006995 ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
6996 if (Index < TopHeaders.size())
6997 return const_cast<FileEntry *>(TopHeaders[Index]);
Guy Benyei11169dd2012-12-18 14:30:41 +00006998
Craig Topper69186e72014-06-08 08:38:04 +00006999 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00007000}
7001
7002} // end: extern "C"
7003
7004//===----------------------------------------------------------------------===//
7005// C++ AST instrospection.
7006//===----------------------------------------------------------------------===//
7007
7008extern "C" {
Saleem Abdulrasool6ea75db2015-10-27 15:50:22 +00007009unsigned clang_CXXField_isMutable(CXCursor C) {
7010 if (!clang_isDeclaration(C.kind))
7011 return 0;
7012
7013 if (const auto D = cxcursor::getCursorDecl(C))
7014 if (const auto FD = dyn_cast_or_null<FieldDecl>(D))
7015 return FD->isMutable() ? 1 : 0;
7016 return 0;
7017}
7018
Dmitri Gribenko62770be2013-05-17 18:38:35 +00007019unsigned clang_CXXMethod_isPureVirtual(CXCursor C) {
7020 if (!clang_isDeclaration(C.kind))
7021 return 0;
7022
Dmitri Gribenko62770be2013-05-17 18:38:35 +00007023 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00007024 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00007025 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Dmitri Gribenko62770be2013-05-17 18:38:35 +00007026 return (Method && Method->isVirtual() && Method->isPure()) ? 1 : 0;
7027}
7028
Dmitri Gribenkoe570ede2014-04-07 14:59:13 +00007029unsigned clang_CXXMethod_isConst(CXCursor C) {
7030 if (!clang_isDeclaration(C.kind))
7031 return 0;
7032
7033 const Decl *D = cxcursor::getCursorDecl(C);
7034 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00007035 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Dmitri Gribenkoe570ede2014-04-07 14:59:13 +00007036 return (Method && (Method->getTypeQualifiers() & Qualifiers::Const)) ? 1 : 0;
7037}
7038
Guy Benyei11169dd2012-12-18 14:30:41 +00007039unsigned clang_CXXMethod_isStatic(CXCursor C) {
7040 if (!clang_isDeclaration(C.kind))
7041 return 0;
7042
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00007043 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00007044 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00007045 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00007046 return (Method && Method->isStatic()) ? 1 : 0;
7047}
7048
7049unsigned clang_CXXMethod_isVirtual(CXCursor C) {
7050 if (!clang_isDeclaration(C.kind))
7051 return 0;
7052
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00007053 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00007054 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00007055 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00007056 return (Method && Method->isVirtual()) ? 1 : 0;
7057}
7058} // end: extern "C"
7059
7060//===----------------------------------------------------------------------===//
7061// Attribute introspection.
7062//===----------------------------------------------------------------------===//
7063
7064extern "C" {
7065CXType clang_getIBOutletCollectionType(CXCursor C) {
7066 if (C.kind != CXCursor_IBOutletCollectionAttr)
7067 return cxtype::MakeCXType(QualType(), cxcursor::getCursorTU(C));
7068
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00007069 const IBOutletCollectionAttr *A =
Guy Benyei11169dd2012-12-18 14:30:41 +00007070 cast<IBOutletCollectionAttr>(cxcursor::getCursorAttr(C));
7071
7072 return cxtype::MakeCXType(A->getInterface(), cxcursor::getCursorTU(C));
7073}
7074} // end: extern "C"
7075
7076//===----------------------------------------------------------------------===//
7077// Inspecting memory usage.
7078//===----------------------------------------------------------------------===//
7079
7080typedef std::vector<CXTUResourceUsageEntry> MemUsageEntries;
7081
7082static inline void createCXTUResourceUsageEntry(MemUsageEntries &entries,
7083 enum CXTUResourceUsageKind k,
7084 unsigned long amount) {
7085 CXTUResourceUsageEntry entry = { k, amount };
7086 entries.push_back(entry);
7087}
7088
7089extern "C" {
7090
7091const char *clang_getTUResourceUsageName(CXTUResourceUsageKind kind) {
7092 const char *str = "";
7093 switch (kind) {
7094 case CXTUResourceUsage_AST:
7095 str = "ASTContext: expressions, declarations, and types";
7096 break;
7097 case CXTUResourceUsage_Identifiers:
7098 str = "ASTContext: identifiers";
7099 break;
7100 case CXTUResourceUsage_Selectors:
7101 str = "ASTContext: selectors";
7102 break;
7103 case CXTUResourceUsage_GlobalCompletionResults:
7104 str = "Code completion: cached global results";
7105 break;
7106 case CXTUResourceUsage_SourceManagerContentCache:
7107 str = "SourceManager: content cache allocator";
7108 break;
7109 case CXTUResourceUsage_AST_SideTables:
7110 str = "ASTContext: side tables";
7111 break;
7112 case CXTUResourceUsage_SourceManager_Membuffer_Malloc:
7113 str = "SourceManager: malloc'ed memory buffers";
7114 break;
7115 case CXTUResourceUsage_SourceManager_Membuffer_MMap:
7116 str = "SourceManager: mmap'ed memory buffers";
7117 break;
7118 case CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc:
7119 str = "ExternalASTSource: malloc'ed memory buffers";
7120 break;
7121 case CXTUResourceUsage_ExternalASTSource_Membuffer_MMap:
7122 str = "ExternalASTSource: mmap'ed memory buffers";
7123 break;
7124 case CXTUResourceUsage_Preprocessor:
7125 str = "Preprocessor: malloc'ed memory";
7126 break;
7127 case CXTUResourceUsage_PreprocessingRecord:
7128 str = "Preprocessor: PreprocessingRecord";
7129 break;
7130 case CXTUResourceUsage_SourceManager_DataStructures:
7131 str = "SourceManager: data structures and tables";
7132 break;
7133 case CXTUResourceUsage_Preprocessor_HeaderSearch:
7134 str = "Preprocessor: header search tables";
7135 break;
7136 }
7137 return str;
7138}
7139
7140CXTUResourceUsage clang_getCXTUResourceUsage(CXTranslationUnit TU) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00007141 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00007142 LOG_BAD_TU(TU);
Craig Topper69186e72014-06-08 08:38:04 +00007143 CXTUResourceUsage usage = { (void*) nullptr, 0, nullptr };
Guy Benyei11169dd2012-12-18 14:30:41 +00007144 return usage;
7145 }
7146
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007147 ASTUnit *astUnit = cxtu::getASTUnit(TU);
Ahmed Charlesb8984322014-03-07 20:03:18 +00007148 std::unique_ptr<MemUsageEntries> entries(new MemUsageEntries());
Guy Benyei11169dd2012-12-18 14:30:41 +00007149 ASTContext &astContext = astUnit->getASTContext();
7150
7151 // How much memory is used by AST nodes and types?
7152 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST,
7153 (unsigned long) astContext.getASTAllocatedMemory());
7154
7155 // How much memory is used by identifiers?
7156 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Identifiers,
7157 (unsigned long) astContext.Idents.getAllocator().getTotalMemory());
7158
7159 // How much memory is used for selectors?
7160 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Selectors,
7161 (unsigned long) astContext.Selectors.getTotalMemory());
7162
7163 // How much memory is used by ASTContext's side tables?
7164 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST_SideTables,
7165 (unsigned long) astContext.getSideTableAllocatedMemory());
7166
7167 // How much memory is used for caching global code completion results?
7168 unsigned long completionBytes = 0;
7169 if (GlobalCodeCompletionAllocator *completionAllocator =
Alp Tokerf994cef2014-07-05 03:08:06 +00007170 astUnit->getCachedCompletionAllocator().get()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00007171 completionBytes = completionAllocator->getTotalMemory();
7172 }
7173 createCXTUResourceUsageEntry(*entries,
7174 CXTUResourceUsage_GlobalCompletionResults,
7175 completionBytes);
7176
7177 // How much memory is being used by SourceManager's content cache?
7178 createCXTUResourceUsageEntry(*entries,
7179 CXTUResourceUsage_SourceManagerContentCache,
7180 (unsigned long) astContext.getSourceManager().getContentCacheSize());
7181
7182 // How much memory is being used by the MemoryBuffer's in SourceManager?
7183 const SourceManager::MemoryBufferSizes &srcBufs =
7184 astUnit->getSourceManager().getMemoryBufferSizes();
7185
7186 createCXTUResourceUsageEntry(*entries,
7187 CXTUResourceUsage_SourceManager_Membuffer_Malloc,
7188 (unsigned long) srcBufs.malloc_bytes);
7189 createCXTUResourceUsageEntry(*entries,
7190 CXTUResourceUsage_SourceManager_Membuffer_MMap,
7191 (unsigned long) srcBufs.mmap_bytes);
7192 createCXTUResourceUsageEntry(*entries,
7193 CXTUResourceUsage_SourceManager_DataStructures,
7194 (unsigned long) astContext.getSourceManager()
7195 .getDataStructureSizes());
7196
7197 // How much memory is being used by the ExternalASTSource?
7198 if (ExternalASTSource *esrc = astContext.getExternalSource()) {
7199 const ExternalASTSource::MemoryBufferSizes &sizes =
7200 esrc->getMemoryBufferSizes();
7201
7202 createCXTUResourceUsageEntry(*entries,
7203 CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc,
7204 (unsigned long) sizes.malloc_bytes);
7205 createCXTUResourceUsageEntry(*entries,
7206 CXTUResourceUsage_ExternalASTSource_Membuffer_MMap,
7207 (unsigned long) sizes.mmap_bytes);
7208 }
7209
7210 // How much memory is being used by the Preprocessor?
7211 Preprocessor &pp = astUnit->getPreprocessor();
7212 createCXTUResourceUsageEntry(*entries,
7213 CXTUResourceUsage_Preprocessor,
7214 pp.getTotalMemory());
7215
7216 if (PreprocessingRecord *pRec = pp.getPreprocessingRecord()) {
7217 createCXTUResourceUsageEntry(*entries,
7218 CXTUResourceUsage_PreprocessingRecord,
7219 pRec->getTotalMemory());
7220 }
7221
7222 createCXTUResourceUsageEntry(*entries,
7223 CXTUResourceUsage_Preprocessor_HeaderSearch,
7224 pp.getHeaderSearchInfo().getTotalMemory());
Craig Topper69186e72014-06-08 08:38:04 +00007225
Guy Benyei11169dd2012-12-18 14:30:41 +00007226 CXTUResourceUsage usage = { (void*) entries.get(),
7227 (unsigned) entries->size(),
Alexander Kornienko6ee521c2015-01-23 15:36:10 +00007228 !entries->empty() ? &(*entries)[0] : nullptr };
Ahmed Charles9a16beb2014-03-07 19:33:25 +00007229 entries.release();
Guy Benyei11169dd2012-12-18 14:30:41 +00007230 return usage;
7231}
7232
7233void clang_disposeCXTUResourceUsage(CXTUResourceUsage usage) {
7234 if (usage.data)
7235 delete (MemUsageEntries*) usage.data;
7236}
7237
Argyrios Kyrtzidis0e282ef2013-12-06 18:55:45 +00007238CXSourceRangeList *clang_getSkippedRanges(CXTranslationUnit TU, CXFile file) {
7239 CXSourceRangeList *skipped = new CXSourceRangeList;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00007240 skipped->count = 0;
Craig Topper69186e72014-06-08 08:38:04 +00007241 skipped->ranges = nullptr;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00007242
Dmitri Gribenko852d6222014-02-11 15:02:48 +00007243 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00007244 LOG_BAD_TU(TU);
7245 return skipped;
7246 }
7247
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00007248 if (!file)
7249 return skipped;
7250
7251 ASTUnit *astUnit = cxtu::getASTUnit(TU);
7252 PreprocessingRecord *ppRec = astUnit->getPreprocessor().getPreprocessingRecord();
7253 if (!ppRec)
7254 return skipped;
7255
7256 ASTContext &Ctx = astUnit->getASTContext();
7257 SourceManager &sm = Ctx.getSourceManager();
7258 FileEntry *fileEntry = static_cast<FileEntry *>(file);
7259 FileID wantedFileID = sm.translateFile(fileEntry);
7260
7261 const std::vector<SourceRange> &SkippedRanges = ppRec->getSkippedRanges();
7262 std::vector<SourceRange> wantedRanges;
7263 for (std::vector<SourceRange>::const_iterator i = SkippedRanges.begin(), ei = SkippedRanges.end();
7264 i != ei; ++i) {
7265 if (sm.getFileID(i->getBegin()) == wantedFileID || sm.getFileID(i->getEnd()) == wantedFileID)
7266 wantedRanges.push_back(*i);
7267 }
7268
7269 skipped->count = wantedRanges.size();
7270 skipped->ranges = new CXSourceRange[skipped->count];
7271 for (unsigned i = 0, ei = skipped->count; i != ei; ++i)
7272 skipped->ranges[i] = cxloc::translateSourceRange(Ctx, wantedRanges[i]);
7273
7274 return skipped;
7275}
7276
Argyrios Kyrtzidis0e282ef2013-12-06 18:55:45 +00007277void clang_disposeSourceRangeList(CXSourceRangeList *ranges) {
7278 if (ranges) {
7279 delete[] ranges->ranges;
7280 delete ranges;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00007281 }
7282}
7283
Guy Benyei11169dd2012-12-18 14:30:41 +00007284} // end extern "C"
7285
7286void clang::PrintLibclangResourceUsage(CXTranslationUnit TU) {
7287 CXTUResourceUsage Usage = clang_getCXTUResourceUsage(TU);
7288 for (unsigned I = 0; I != Usage.numEntries; ++I)
7289 fprintf(stderr, " %s: %lu\n",
7290 clang_getTUResourceUsageName(Usage.entries[I].kind),
7291 Usage.entries[I].amount);
7292
7293 clang_disposeCXTUResourceUsage(Usage);
7294}
7295
7296//===----------------------------------------------------------------------===//
7297// Misc. utility functions.
7298//===----------------------------------------------------------------------===//
7299
7300/// Default to using an 8 MB stack size on "safety" threads.
7301static unsigned SafetyStackThreadSize = 8 << 20;
7302
7303namespace clang {
7304
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00007305bool RunSafely(llvm::CrashRecoveryContext &CRC, llvm::function_ref<void()> Fn,
Guy Benyei11169dd2012-12-18 14:30:41 +00007306 unsigned Size) {
7307 if (!Size)
7308 Size = GetSafetyThreadStackSize();
7309 if (Size)
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00007310 return CRC.RunSafelyOnThread(Fn, Size);
7311 return CRC.RunSafely(Fn);
Guy Benyei11169dd2012-12-18 14:30:41 +00007312}
7313
7314unsigned GetSafetyThreadStackSize() {
7315 return SafetyStackThreadSize;
7316}
7317
7318void SetSafetyThreadStackSize(unsigned Value) {
7319 SafetyStackThreadSize = Value;
7320}
7321
Alexander Kornienkoab9db512015-06-22 23:07:51 +00007322}
Guy Benyei11169dd2012-12-18 14:30:41 +00007323
7324void clang::setThreadBackgroundPriority() {
7325 if (getenv("LIBCLANG_BGPRIO_DISABLE"))
7326 return;
7327
Alp Toker1a86ad22014-07-06 06:24:00 +00007328#ifdef USE_DARWIN_THREADS
Guy Benyei11169dd2012-12-18 14:30:41 +00007329 setpriority(PRIO_DARWIN_THREAD, 0, PRIO_DARWIN_BG);
7330#endif
7331}
7332
7333void cxindex::printDiagsToStderr(ASTUnit *Unit) {
7334 if (!Unit)
7335 return;
7336
7337 for (ASTUnit::stored_diag_iterator D = Unit->stored_diag_begin(),
7338 DEnd = Unit->stored_diag_end();
7339 D != DEnd; ++D) {
Ben Langmuir749323f2014-04-22 17:40:12 +00007340 CXStoredDiagnostic Diag(*D, Unit->getLangOpts());
Guy Benyei11169dd2012-12-18 14:30:41 +00007341 CXString Msg = clang_formatDiagnostic(&Diag,
7342 clang_defaultDiagnosticDisplayOptions());
7343 fprintf(stderr, "%s\n", clang_getCString(Msg));
7344 clang_disposeString(Msg);
7345 }
7346#ifdef LLVM_ON_WIN32
7347 // On Windows, force a flush, since there may be multiple copies of
7348 // stderr and stdout in the file system, all with different buffers
7349 // but writing to the same device.
7350 fflush(stderr);
7351#endif
7352}
7353
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007354MacroInfo *cxindex::getMacroInfo(const IdentifierInfo &II,
7355 SourceLocation MacroDefLoc,
7356 CXTranslationUnit TU){
7357 if (MacroDefLoc.isInvalid() || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00007358 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007359 if (!II.hadMacroDefinition())
Craig Topper69186e72014-06-08 08:38:04 +00007360 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007361
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007362 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00007363 Preprocessor &PP = Unit->getPreprocessor();
Richard Smith20e883e2015-04-29 23:20:19 +00007364 MacroDirective *MD = PP.getLocalMacroDirectiveHistory(&II);
Argyrios Kyrtzidisb6210df2013-03-26 17:17:01 +00007365 if (MD) {
7366 for (MacroDirective::DefInfo
7367 Def = MD->getDefinition(); Def; Def = Def.getPreviousDefinition()) {
7368 if (MacroDefLoc == Def.getMacroInfo()->getDefinitionLoc())
7369 return Def.getMacroInfo();
7370 }
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007371 }
7372
Craig Topper69186e72014-06-08 08:38:04 +00007373 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007374}
7375
Richard Smith66a81862015-05-04 02:25:31 +00007376const MacroInfo *cxindex::getMacroInfo(const MacroDefinitionRecord *MacroDef,
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00007377 CXTranslationUnit TU) {
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007378 if (!MacroDef || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00007379 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007380 const IdentifierInfo *II = MacroDef->getName();
7381 if (!II)
Craig Topper69186e72014-06-08 08:38:04 +00007382 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007383
7384 return getMacroInfo(*II, MacroDef->getLocation(), TU);
7385}
7386
Richard Smith66a81862015-05-04 02:25:31 +00007387MacroDefinitionRecord *
7388cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI, const Token &Tok,
7389 CXTranslationUnit TU) {
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007390 if (!MI || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00007391 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007392 if (Tok.isNot(tok::raw_identifier))
Craig Topper69186e72014-06-08 08:38:04 +00007393 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007394
7395 if (MI->getNumTokens() == 0)
Craig Topper69186e72014-06-08 08:38:04 +00007396 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007397 SourceRange DefRange(MI->getReplacementToken(0).getLocation(),
7398 MI->getDefinitionEndLoc());
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007399 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007400
7401 // Check that the token is inside the definition and not its argument list.
7402 SourceManager &SM = Unit->getSourceManager();
7403 if (SM.isBeforeInTranslationUnit(Tok.getLocation(), DefRange.getBegin()))
Craig Topper69186e72014-06-08 08:38:04 +00007404 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007405 if (SM.isBeforeInTranslationUnit(DefRange.getEnd(), Tok.getLocation()))
Craig Topper69186e72014-06-08 08:38:04 +00007406 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007407
7408 Preprocessor &PP = Unit->getPreprocessor();
7409 PreprocessingRecord *PPRec = PP.getPreprocessingRecord();
7410 if (!PPRec)
Craig Topper69186e72014-06-08 08:38:04 +00007411 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007412
Alp Toker2d57cea2014-05-17 04:53:25 +00007413 IdentifierInfo &II = PP.getIdentifierTable().get(Tok.getRawIdentifier());
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007414 if (!II.hadMacroDefinition())
Craig Topper69186e72014-06-08 08:38:04 +00007415 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007416
7417 // Check that the identifier is not one of the macro arguments.
7418 if (std::find(MI->arg_begin(), MI->arg_end(), &II) != MI->arg_end())
Craig Topper69186e72014-06-08 08:38:04 +00007419 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007420
Richard Smith20e883e2015-04-29 23:20:19 +00007421 MacroDirective *InnerMD = PP.getLocalMacroDirectiveHistory(&II);
Argyrios Kyrtzidis09c9e812013-02-20 00:54:57 +00007422 if (!InnerMD)
Craig Topper69186e72014-06-08 08:38:04 +00007423 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007424
Argyrios Kyrtzidisb6210df2013-03-26 17:17:01 +00007425 return PPRec->findMacroDefinition(InnerMD->getMacroInfo());
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007426}
7427
Richard Smith66a81862015-05-04 02:25:31 +00007428MacroDefinitionRecord *
7429cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI, SourceLocation Loc,
7430 CXTranslationUnit TU) {
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007431 if (Loc.isInvalid() || !MI || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00007432 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007433
7434 if (MI->getNumTokens() == 0)
Craig Topper69186e72014-06-08 08:38:04 +00007435 return nullptr;
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007436 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007437 Preprocessor &PP = Unit->getPreprocessor();
7438 if (!PP.getPreprocessingRecord())
Craig Topper69186e72014-06-08 08:38:04 +00007439 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007440 Loc = Unit->getSourceManager().getSpellingLoc(Loc);
7441 Token Tok;
7442 if (PP.getRawToken(Loc, Tok))
Craig Topper69186e72014-06-08 08:38:04 +00007443 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007444
7445 return checkForMacroInMacroDefinition(MI, Tok, TU);
7446}
7447
Guy Benyei11169dd2012-12-18 14:30:41 +00007448extern "C" {
7449
7450CXString clang_getClangVersion() {
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00007451 return cxstring::createDup(getClangFullVersion());
Guy Benyei11169dd2012-12-18 14:30:41 +00007452}
7453
7454} // end: extern "C"
7455
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007456Logger &cxindex::Logger::operator<<(CXTranslationUnit TU) {
7457 if (TU) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007458 if (ASTUnit *Unit = cxtu::getASTUnit(TU)) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007459 LogOS << '<' << Unit->getMainFileName() << '>';
Argyrios Kyrtzidis37f2ab42013-03-05 20:21:14 +00007460 if (Unit->isMainFileAST())
7461 LogOS << " (" << Unit->getASTFileName() << ')';
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007462 return *this;
7463 }
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00007464 } else {
7465 LogOS << "<NULL TU>";
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007466 }
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007467 return *this;
7468}
7469
Argyrios Kyrtzidisba4b5f82013-03-08 02:32:26 +00007470Logger &cxindex::Logger::operator<<(const FileEntry *FE) {
7471 *this << FE->getName();
7472 return *this;
7473}
7474
7475Logger &cxindex::Logger::operator<<(CXCursor cursor) {
7476 CXString cursorName = clang_getCursorDisplayName(cursor);
7477 *this << cursorName << "@" << clang_getCursorLocation(cursor);
7478 clang_disposeString(cursorName);
7479 return *this;
7480}
7481
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007482Logger &cxindex::Logger::operator<<(CXSourceLocation Loc) {
7483 CXFile File;
7484 unsigned Line, Column;
Craig Topper69186e72014-06-08 08:38:04 +00007485 clang_getFileLocation(Loc, &File, &Line, &Column, nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007486 CXString FileName = clang_getFileName(File);
7487 *this << llvm::format("(%s:%d:%d)", clang_getCString(FileName), Line, Column);
7488 clang_disposeString(FileName);
7489 return *this;
7490}
7491
7492Logger &cxindex::Logger::operator<<(CXSourceRange range) {
7493 CXSourceLocation BLoc = clang_getRangeStart(range);
7494 CXSourceLocation ELoc = clang_getRangeEnd(range);
7495
7496 CXFile BFile;
7497 unsigned BLine, BColumn;
Craig Topper69186e72014-06-08 08:38:04 +00007498 clang_getFileLocation(BLoc, &BFile, &BLine, &BColumn, nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007499
7500 CXFile EFile;
7501 unsigned ELine, EColumn;
Craig Topper69186e72014-06-08 08:38:04 +00007502 clang_getFileLocation(ELoc, &EFile, &ELine, &EColumn, nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007503
7504 CXString BFileName = clang_getFileName(BFile);
7505 if (BFile == EFile) {
7506 *this << llvm::format("[%s %d:%d-%d:%d]", clang_getCString(BFileName),
7507 BLine, BColumn, ELine, EColumn);
7508 } else {
7509 CXString EFileName = clang_getFileName(EFile);
7510 *this << llvm::format("[%s:%d:%d - ", clang_getCString(BFileName),
7511 BLine, BColumn)
7512 << llvm::format("%s:%d:%d]", clang_getCString(EFileName),
7513 ELine, EColumn);
7514 clang_disposeString(EFileName);
7515 }
7516 clang_disposeString(BFileName);
7517 return *this;
7518}
7519
7520Logger &cxindex::Logger::operator<<(CXString Str) {
7521 *this << clang_getCString(Str);
7522 return *this;
7523}
7524
7525Logger &cxindex::Logger::operator<<(const llvm::format_object_base &Fmt) {
7526 LogOS << Fmt;
7527 return *this;
7528}
7529
Chandler Carruth37ad2582014-06-27 15:14:39 +00007530static llvm::ManagedStatic<llvm::sys::Mutex> LoggingMutex;
7531
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007532cxindex::Logger::~Logger() {
Chandler Carruth37ad2582014-06-27 15:14:39 +00007533 llvm::sys::ScopedLock L(*LoggingMutex);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007534
7535 static llvm::TimeRecord sBeginTR = llvm::TimeRecord::getCurrentTime();
7536
Dmitri Gribenkof8579502013-01-12 19:30:44 +00007537 raw_ostream &OS = llvm::errs();
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007538 OS << "[libclang:" << Name << ':';
7539
Alp Toker1a86ad22014-07-06 06:24:00 +00007540#ifdef USE_DARWIN_THREADS
7541 // TODO: Portability.
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007542 mach_port_t tid = pthread_mach_thread_np(pthread_self());
7543 OS << tid << ':';
7544#endif
7545
7546 llvm::TimeRecord TR = llvm::TimeRecord::getCurrentTime();
7547 OS << llvm::format("%7.4f] ", TR.getWallTime() - sBeginTR.getWallTime());
Yaron Keren09fb7c62015-03-10 07:33:23 +00007548 OS << Msg << '\n';
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007549
7550 if (Trace) {
Zachary Turner1fe2a8d2015-03-05 19:15:09 +00007551 llvm::sys::PrintStackTrace(OS);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007552 OS << "--------------------------------------------------\n";
7553 }
7554}