1*67e74705SXin Li //===- CIndex.cpp - Clang-C Source Indexing Library -----------------------===//
2*67e74705SXin Li //
3*67e74705SXin Li // The LLVM Compiler Infrastructure
4*67e74705SXin Li //
5*67e74705SXin Li // This file is distributed under the University of Illinois Open Source
6*67e74705SXin Li // License. See LICENSE.TXT for details.
7*67e74705SXin Li //
8*67e74705SXin Li //===----------------------------------------------------------------------===//
9*67e74705SXin Li //
10*67e74705SXin Li // This file implements the main API hooks in the Clang-C Source Indexing
11*67e74705SXin Li // library.
12*67e74705SXin Li //
13*67e74705SXin Li //===----------------------------------------------------------------------===//
14*67e74705SXin Li
15*67e74705SXin Li #include "CIndexer.h"
16*67e74705SXin Li #include "CIndexDiagnostic.h"
17*67e74705SXin Li #include "CLog.h"
18*67e74705SXin Li #include "CXCursor.h"
19*67e74705SXin Li #include "CXSourceLocation.h"
20*67e74705SXin Li #include "CXString.h"
21*67e74705SXin Li #include "CXTranslationUnit.h"
22*67e74705SXin Li #include "CXType.h"
23*67e74705SXin Li #include "CursorVisitor.h"
24*67e74705SXin Li #include "clang/AST/Attr.h"
25*67e74705SXin Li #include "clang/AST/StmtVisitor.h"
26*67e74705SXin Li #include "clang/Basic/Diagnostic.h"
27*67e74705SXin Li #include "clang/Basic/DiagnosticCategories.h"
28*67e74705SXin Li #include "clang/Basic/DiagnosticIDs.h"
29*67e74705SXin Li #include "clang/Basic/Version.h"
30*67e74705SXin Li #include "clang/Frontend/ASTUnit.h"
31*67e74705SXin Li #include "clang/Frontend/CompilerInstance.h"
32*67e74705SXin Li #include "clang/Frontend/FrontendDiagnostic.h"
33*67e74705SXin Li #include "clang/Index/CodegenNameGenerator.h"
34*67e74705SXin Li #include "clang/Index/CommentToXML.h"
35*67e74705SXin Li #include "clang/Lex/HeaderSearch.h"
36*67e74705SXin Li #include "clang/Lex/Lexer.h"
37*67e74705SXin Li #include "clang/Lex/PreprocessingRecord.h"
38*67e74705SXin Li #include "clang/Lex/Preprocessor.h"
39*67e74705SXin Li #include "clang/Serialization/SerializationDiagnostic.h"
40*67e74705SXin Li #include "llvm/ADT/Optional.h"
41*67e74705SXin Li #include "llvm/ADT/STLExtras.h"
42*67e74705SXin Li #include "llvm/ADT/StringSwitch.h"
43*67e74705SXin Li #include "llvm/Config/llvm-config.h"
44*67e74705SXin Li #include "llvm/Support/Compiler.h"
45*67e74705SXin Li #include "llvm/Support/CrashRecoveryContext.h"
46*67e74705SXin Li #include "llvm/Support/Format.h"
47*67e74705SXin Li #include "llvm/Support/ManagedStatic.h"
48*67e74705SXin Li #include "llvm/Support/MemoryBuffer.h"
49*67e74705SXin Li #include "llvm/Support/Mutex.h"
50*67e74705SXin Li #include "llvm/Support/Program.h"
51*67e74705SXin Li #include "llvm/Support/SaveAndRestore.h"
52*67e74705SXin Li #include "llvm/Support/Signals.h"
53*67e74705SXin Li #include "llvm/Support/TargetSelect.h"
54*67e74705SXin Li #include "llvm/Support/Threading.h"
55*67e74705SXin Li #include "llvm/Support/Timer.h"
56*67e74705SXin Li #include "llvm/Support/raw_ostream.h"
57*67e74705SXin Li
58*67e74705SXin Li #if LLVM_ENABLE_THREADS != 0 && defined(__APPLE__)
59*67e74705SXin Li #define USE_DARWIN_THREADS
60*67e74705SXin Li #endif
61*67e74705SXin Li
62*67e74705SXin Li #ifdef USE_DARWIN_THREADS
63*67e74705SXin Li #include <pthread.h>
64*67e74705SXin Li #endif
65*67e74705SXin Li
66*67e74705SXin Li using namespace clang;
67*67e74705SXin Li using namespace clang::cxcursor;
68*67e74705SXin Li using namespace clang::cxtu;
69*67e74705SXin Li using namespace clang::cxindex;
70*67e74705SXin Li
MakeCXTranslationUnit(CIndexer * CIdx,ASTUnit * AU)71*67e74705SXin Li CXTranslationUnit cxtu::MakeCXTranslationUnit(CIndexer *CIdx, ASTUnit *AU) {
72*67e74705SXin Li if (!AU)
73*67e74705SXin Li return nullptr;
74*67e74705SXin Li assert(CIdx);
75*67e74705SXin Li CXTranslationUnit D = new CXTranslationUnitImpl();
76*67e74705SXin Li D->CIdx = CIdx;
77*67e74705SXin Li D->TheASTUnit = AU;
78*67e74705SXin Li D->StringPool = new cxstring::CXStringPool();
79*67e74705SXin Li D->Diagnostics = nullptr;
80*67e74705SXin Li D->OverridenCursorsPool = createOverridenCXCursorsPool();
81*67e74705SXin Li D->CommentToXML = nullptr;
82*67e74705SXin Li return D;
83*67e74705SXin Li }
84*67e74705SXin Li
isASTReadError(ASTUnit * AU)85*67e74705SXin Li bool cxtu::isASTReadError(ASTUnit *AU) {
86*67e74705SXin Li for (ASTUnit::stored_diag_iterator D = AU->stored_diag_begin(),
87*67e74705SXin Li DEnd = AU->stored_diag_end();
88*67e74705SXin Li D != DEnd; ++D) {
89*67e74705SXin Li if (D->getLevel() >= DiagnosticsEngine::Error &&
90*67e74705SXin Li DiagnosticIDs::getCategoryNumberForDiag(D->getID()) ==
91*67e74705SXin Li diag::DiagCat_AST_Deserialization_Issue)
92*67e74705SXin Li return true;
93*67e74705SXin Li }
94*67e74705SXin Li return false;
95*67e74705SXin Li }
96*67e74705SXin Li
~CXTUOwner()97*67e74705SXin Li cxtu::CXTUOwner::~CXTUOwner() {
98*67e74705SXin Li if (TU)
99*67e74705SXin Li clang_disposeTranslationUnit(TU);
100*67e74705SXin Li }
101*67e74705SXin Li
102*67e74705SXin Li /// \brief Compare two source ranges to determine their relative position in
103*67e74705SXin Li /// the translation unit.
RangeCompare(SourceManager & SM,SourceRange R1,SourceRange R2)104*67e74705SXin Li static RangeComparisonResult RangeCompare(SourceManager &SM,
105*67e74705SXin Li SourceRange R1,
106*67e74705SXin Li SourceRange R2) {
107*67e74705SXin Li assert(R1.isValid() && "First range is invalid?");
108*67e74705SXin Li assert(R2.isValid() && "Second range is invalid?");
109*67e74705SXin Li if (R1.getEnd() != R2.getBegin() &&
110*67e74705SXin Li SM.isBeforeInTranslationUnit(R1.getEnd(), R2.getBegin()))
111*67e74705SXin Li return RangeBefore;
112*67e74705SXin Li if (R2.getEnd() != R1.getBegin() &&
113*67e74705SXin Li SM.isBeforeInTranslationUnit(R2.getEnd(), R1.getBegin()))
114*67e74705SXin Li return RangeAfter;
115*67e74705SXin Li return RangeOverlap;
116*67e74705SXin Li }
117*67e74705SXin Li
118*67e74705SXin Li /// \brief Determine if a source location falls within, before, or after a
119*67e74705SXin Li /// a given source range.
LocationCompare(SourceManager & SM,SourceLocation L,SourceRange R)120*67e74705SXin Li static RangeComparisonResult LocationCompare(SourceManager &SM,
121*67e74705SXin Li SourceLocation L, SourceRange R) {
122*67e74705SXin Li assert(R.isValid() && "First range is invalid?");
123*67e74705SXin Li assert(L.isValid() && "Second range is invalid?");
124*67e74705SXin Li if (L == R.getBegin() || L == R.getEnd())
125*67e74705SXin Li return RangeOverlap;
126*67e74705SXin Li if (SM.isBeforeInTranslationUnit(L, R.getBegin()))
127*67e74705SXin Li return RangeBefore;
128*67e74705SXin Li if (SM.isBeforeInTranslationUnit(R.getEnd(), L))
129*67e74705SXin Li return RangeAfter;
130*67e74705SXin Li return RangeOverlap;
131*67e74705SXin Li }
132*67e74705SXin Li
133*67e74705SXin Li /// \brief Translate a Clang source range into a CIndex source range.
134*67e74705SXin Li ///
135*67e74705SXin Li /// Clang internally represents ranges where the end location points to the
136*67e74705SXin Li /// start of the token at the end. However, for external clients it is more
137*67e74705SXin Li /// useful to have a CXSourceRange be a proper half-open interval. This routine
138*67e74705SXin Li /// does the appropriate translation.
translateSourceRange(const SourceManager & SM,const LangOptions & LangOpts,const CharSourceRange & R)139*67e74705SXin Li CXSourceRange cxloc::translateSourceRange(const SourceManager &SM,
140*67e74705SXin Li const LangOptions &LangOpts,
141*67e74705SXin Li const CharSourceRange &R) {
142*67e74705SXin Li // We want the last character in this location, so we will adjust the
143*67e74705SXin Li // location accordingly.
144*67e74705SXin Li SourceLocation EndLoc = R.getEnd();
145*67e74705SXin Li if (EndLoc.isValid() && EndLoc.isMacroID() && !SM.isMacroArgExpansion(EndLoc))
146*67e74705SXin Li EndLoc = SM.getExpansionRange(EndLoc).second;
147*67e74705SXin Li if (R.isTokenRange() && EndLoc.isValid()) {
148*67e74705SXin Li unsigned Length = Lexer::MeasureTokenLength(SM.getSpellingLoc(EndLoc),
149*67e74705SXin Li SM, LangOpts);
150*67e74705SXin Li EndLoc = EndLoc.getLocWithOffset(Length);
151*67e74705SXin Li }
152*67e74705SXin Li
153*67e74705SXin Li CXSourceRange Result = {
154*67e74705SXin Li { &SM, &LangOpts },
155*67e74705SXin Li R.getBegin().getRawEncoding(),
156*67e74705SXin Li EndLoc.getRawEncoding()
157*67e74705SXin Li };
158*67e74705SXin Li return Result;
159*67e74705SXin Li }
160*67e74705SXin Li
161*67e74705SXin Li //===----------------------------------------------------------------------===//
162*67e74705SXin Li // Cursor visitor.
163*67e74705SXin Li //===----------------------------------------------------------------------===//
164*67e74705SXin Li
165*67e74705SXin Li static SourceRange getRawCursorExtent(CXCursor C);
166*67e74705SXin Li static SourceRange getFullCursorExtent(CXCursor C, SourceManager &SrcMgr);
167*67e74705SXin Li
168*67e74705SXin Li
CompareRegionOfInterest(SourceRange R)169*67e74705SXin Li RangeComparisonResult CursorVisitor::CompareRegionOfInterest(SourceRange R) {
170*67e74705SXin Li return RangeCompare(AU->getSourceManager(), R, RegionOfInterest);
171*67e74705SXin Li }
172*67e74705SXin Li
173*67e74705SXin Li /// \brief Visit the given cursor and, if requested by the visitor,
174*67e74705SXin Li /// its children.
175*67e74705SXin Li ///
176*67e74705SXin Li /// \param Cursor the cursor to visit.
177*67e74705SXin Li ///
178*67e74705SXin Li /// \param CheckedRegionOfInterest if true, then the caller already checked
179*67e74705SXin Li /// that this cursor is within the region of interest.
180*67e74705SXin Li ///
181*67e74705SXin Li /// \returns true if the visitation should be aborted, false if it
182*67e74705SXin Li /// should continue.
Visit(CXCursor Cursor,bool CheckedRegionOfInterest)183*67e74705SXin Li bool CursorVisitor::Visit(CXCursor Cursor, bool CheckedRegionOfInterest) {
184*67e74705SXin Li if (clang_isInvalid(Cursor.kind))
185*67e74705SXin Li return false;
186*67e74705SXin Li
187*67e74705SXin Li if (clang_isDeclaration(Cursor.kind)) {
188*67e74705SXin Li const Decl *D = getCursorDecl(Cursor);
189*67e74705SXin Li if (!D) {
190*67e74705SXin Li assert(0 && "Invalid declaration cursor");
191*67e74705SXin Li return true; // abort.
192*67e74705SXin Li }
193*67e74705SXin Li
194*67e74705SXin Li // Ignore implicit declarations, unless it's an objc method because
195*67e74705SXin Li // currently we should report implicit methods for properties when indexing.
196*67e74705SXin Li if (D->isImplicit() && !isa<ObjCMethodDecl>(D))
197*67e74705SXin Li return false;
198*67e74705SXin Li }
199*67e74705SXin Li
200*67e74705SXin Li // If we have a range of interest, and this cursor doesn't intersect with it,
201*67e74705SXin Li // we're done.
202*67e74705SXin Li if (RegionOfInterest.isValid() && !CheckedRegionOfInterest) {
203*67e74705SXin Li SourceRange Range = getRawCursorExtent(Cursor);
204*67e74705SXin Li if (Range.isInvalid() || CompareRegionOfInterest(Range))
205*67e74705SXin Li return false;
206*67e74705SXin Li }
207*67e74705SXin Li
208*67e74705SXin Li switch (Visitor(Cursor, Parent, ClientData)) {
209*67e74705SXin Li case CXChildVisit_Break:
210*67e74705SXin Li return true;
211*67e74705SXin Li
212*67e74705SXin Li case CXChildVisit_Continue:
213*67e74705SXin Li return false;
214*67e74705SXin Li
215*67e74705SXin Li case CXChildVisit_Recurse: {
216*67e74705SXin Li bool ret = VisitChildren(Cursor);
217*67e74705SXin Li if (PostChildrenVisitor)
218*67e74705SXin Li if (PostChildrenVisitor(Cursor, ClientData))
219*67e74705SXin Li return true;
220*67e74705SXin Li return ret;
221*67e74705SXin Li }
222*67e74705SXin Li }
223*67e74705SXin Li
224*67e74705SXin Li llvm_unreachable("Invalid CXChildVisitResult!");
225*67e74705SXin Li }
226*67e74705SXin Li
visitPreprocessedEntitiesInRange(SourceRange R,PreprocessingRecord & PPRec,CursorVisitor & Visitor)227*67e74705SXin Li static bool visitPreprocessedEntitiesInRange(SourceRange R,
228*67e74705SXin Li PreprocessingRecord &PPRec,
229*67e74705SXin Li CursorVisitor &Visitor) {
230*67e74705SXin Li SourceManager &SM = Visitor.getASTUnit()->getSourceManager();
231*67e74705SXin Li FileID FID;
232*67e74705SXin Li
233*67e74705SXin Li if (!Visitor.shouldVisitIncludedEntities()) {
234*67e74705SXin Li // If the begin/end of the range lie in the same FileID, do the optimization
235*67e74705SXin Li // where we skip preprocessed entities that do not come from the same FileID.
236*67e74705SXin Li FID = SM.getFileID(SM.getFileLoc(R.getBegin()));
237*67e74705SXin Li if (FID != SM.getFileID(SM.getFileLoc(R.getEnd())))
238*67e74705SXin Li FID = FileID();
239*67e74705SXin Li }
240*67e74705SXin Li
241*67e74705SXin Li const auto &Entities = PPRec.getPreprocessedEntitiesInRange(R);
242*67e74705SXin Li return Visitor.visitPreprocessedEntities(Entities.begin(), Entities.end(),
243*67e74705SXin Li PPRec, FID);
244*67e74705SXin Li }
245*67e74705SXin Li
visitFileRegion()246*67e74705SXin Li bool CursorVisitor::visitFileRegion() {
247*67e74705SXin Li if (RegionOfInterest.isInvalid())
248*67e74705SXin Li return false;
249*67e74705SXin Li
250*67e74705SXin Li ASTUnit *Unit = cxtu::getASTUnit(TU);
251*67e74705SXin Li SourceManager &SM = Unit->getSourceManager();
252*67e74705SXin Li
253*67e74705SXin Li std::pair<FileID, unsigned>
254*67e74705SXin Li Begin = SM.getDecomposedLoc(SM.getFileLoc(RegionOfInterest.getBegin())),
255*67e74705SXin Li End = SM.getDecomposedLoc(SM.getFileLoc(RegionOfInterest.getEnd()));
256*67e74705SXin Li
257*67e74705SXin Li if (End.first != Begin.first) {
258*67e74705SXin Li // If the end does not reside in the same file, try to recover by
259*67e74705SXin Li // picking the end of the file of begin location.
260*67e74705SXin Li End.first = Begin.first;
261*67e74705SXin Li End.second = SM.getFileIDSize(Begin.first);
262*67e74705SXin Li }
263*67e74705SXin Li
264*67e74705SXin Li assert(Begin.first == End.first);
265*67e74705SXin Li if (Begin.second > End.second)
266*67e74705SXin Li return false;
267*67e74705SXin Li
268*67e74705SXin Li FileID File = Begin.first;
269*67e74705SXin Li unsigned Offset = Begin.second;
270*67e74705SXin Li unsigned Length = End.second - Begin.second;
271*67e74705SXin Li
272*67e74705SXin Li if (!VisitDeclsOnly && !VisitPreprocessorLast)
273*67e74705SXin Li if (visitPreprocessedEntitiesInRegion())
274*67e74705SXin Li return true; // visitation break.
275*67e74705SXin Li
276*67e74705SXin Li if (visitDeclsFromFileRegion(File, Offset, Length))
277*67e74705SXin Li return true; // visitation break.
278*67e74705SXin Li
279*67e74705SXin Li if (!VisitDeclsOnly && VisitPreprocessorLast)
280*67e74705SXin Li return visitPreprocessedEntitiesInRegion();
281*67e74705SXin Li
282*67e74705SXin Li return false;
283*67e74705SXin Li }
284*67e74705SXin Li
isInLexicalContext(Decl * D,DeclContext * DC)285*67e74705SXin Li static bool isInLexicalContext(Decl *D, DeclContext *DC) {
286*67e74705SXin Li if (!DC)
287*67e74705SXin Li return false;
288*67e74705SXin Li
289*67e74705SXin Li for (DeclContext *DeclDC = D->getLexicalDeclContext();
290*67e74705SXin Li DeclDC; DeclDC = DeclDC->getLexicalParent()) {
291*67e74705SXin Li if (DeclDC == DC)
292*67e74705SXin Li return true;
293*67e74705SXin Li }
294*67e74705SXin Li return false;
295*67e74705SXin Li }
296*67e74705SXin Li
visitDeclsFromFileRegion(FileID File,unsigned Offset,unsigned Length)297*67e74705SXin Li bool CursorVisitor::visitDeclsFromFileRegion(FileID File,
298*67e74705SXin Li unsigned Offset, unsigned Length) {
299*67e74705SXin Li ASTUnit *Unit = cxtu::getASTUnit(TU);
300*67e74705SXin Li SourceManager &SM = Unit->getSourceManager();
301*67e74705SXin Li SourceRange Range = RegionOfInterest;
302*67e74705SXin Li
303*67e74705SXin Li SmallVector<Decl *, 16> Decls;
304*67e74705SXin Li Unit->findFileRegionDecls(File, Offset, Length, Decls);
305*67e74705SXin Li
306*67e74705SXin Li // If we didn't find any file level decls for the file, try looking at the
307*67e74705SXin Li // file that it was included from.
308*67e74705SXin Li while (Decls.empty() || Decls.front()->isTopLevelDeclInObjCContainer()) {
309*67e74705SXin Li bool Invalid = false;
310*67e74705SXin Li const SrcMgr::SLocEntry &SLEntry = SM.getSLocEntry(File, &Invalid);
311*67e74705SXin Li if (Invalid)
312*67e74705SXin Li return false;
313*67e74705SXin Li
314*67e74705SXin Li SourceLocation Outer;
315*67e74705SXin Li if (SLEntry.isFile())
316*67e74705SXin Li Outer = SLEntry.getFile().getIncludeLoc();
317*67e74705SXin Li else
318*67e74705SXin Li Outer = SLEntry.getExpansion().getExpansionLocStart();
319*67e74705SXin Li if (Outer.isInvalid())
320*67e74705SXin Li return false;
321*67e74705SXin Li
322*67e74705SXin Li std::tie(File, Offset) = SM.getDecomposedExpansionLoc(Outer);
323*67e74705SXin Li Length = 0;
324*67e74705SXin Li Unit->findFileRegionDecls(File, Offset, Length, Decls);
325*67e74705SXin Li }
326*67e74705SXin Li
327*67e74705SXin Li assert(!Decls.empty());
328*67e74705SXin Li
329*67e74705SXin Li bool VisitedAtLeastOnce = false;
330*67e74705SXin Li DeclContext *CurDC = nullptr;
331*67e74705SXin Li SmallVectorImpl<Decl *>::iterator DIt = Decls.begin();
332*67e74705SXin Li for (SmallVectorImpl<Decl *>::iterator DE = Decls.end(); DIt != DE; ++DIt) {
333*67e74705SXin Li Decl *D = *DIt;
334*67e74705SXin Li if (D->getSourceRange().isInvalid())
335*67e74705SXin Li continue;
336*67e74705SXin Li
337*67e74705SXin Li if (isInLexicalContext(D, CurDC))
338*67e74705SXin Li continue;
339*67e74705SXin Li
340*67e74705SXin Li CurDC = dyn_cast<DeclContext>(D);
341*67e74705SXin Li
342*67e74705SXin Li if (TagDecl *TD = dyn_cast<TagDecl>(D))
343*67e74705SXin Li if (!TD->isFreeStanding())
344*67e74705SXin Li continue;
345*67e74705SXin Li
346*67e74705SXin Li RangeComparisonResult CompRes = RangeCompare(SM, D->getSourceRange(),Range);
347*67e74705SXin Li if (CompRes == RangeBefore)
348*67e74705SXin Li continue;
349*67e74705SXin Li if (CompRes == RangeAfter)
350*67e74705SXin Li break;
351*67e74705SXin Li
352*67e74705SXin Li assert(CompRes == RangeOverlap);
353*67e74705SXin Li VisitedAtLeastOnce = true;
354*67e74705SXin Li
355*67e74705SXin Li if (isa<ObjCContainerDecl>(D)) {
356*67e74705SXin Li FileDI_current = &DIt;
357*67e74705SXin Li FileDE_current = DE;
358*67e74705SXin Li } else {
359*67e74705SXin Li FileDI_current = nullptr;
360*67e74705SXin Li }
361*67e74705SXin Li
362*67e74705SXin Li if (Visit(MakeCXCursor(D, TU, Range), /*CheckedRegionOfInterest=*/true))
363*67e74705SXin Li return true; // visitation break.
364*67e74705SXin Li }
365*67e74705SXin Li
366*67e74705SXin Li if (VisitedAtLeastOnce)
367*67e74705SXin Li return false;
368*67e74705SXin Li
369*67e74705SXin Li // No Decls overlapped with the range. Move up the lexical context until there
370*67e74705SXin Li // is a context that contains the range or we reach the translation unit
371*67e74705SXin Li // level.
372*67e74705SXin Li DeclContext *DC = DIt == Decls.begin() ? (*DIt)->getLexicalDeclContext()
373*67e74705SXin Li : (*(DIt-1))->getLexicalDeclContext();
374*67e74705SXin Li
375*67e74705SXin Li while (DC && !DC->isTranslationUnit()) {
376*67e74705SXin Li Decl *D = cast<Decl>(DC);
377*67e74705SXin Li SourceRange CurDeclRange = D->getSourceRange();
378*67e74705SXin Li if (CurDeclRange.isInvalid())
379*67e74705SXin Li break;
380*67e74705SXin Li
381*67e74705SXin Li if (RangeCompare(SM, CurDeclRange, Range) == RangeOverlap) {
382*67e74705SXin Li if (Visit(MakeCXCursor(D, TU, Range), /*CheckedRegionOfInterest=*/true))
383*67e74705SXin Li return true; // visitation break.
384*67e74705SXin Li }
385*67e74705SXin Li
386*67e74705SXin Li DC = D->getLexicalDeclContext();
387*67e74705SXin Li }
388*67e74705SXin Li
389*67e74705SXin Li return false;
390*67e74705SXin Li }
391*67e74705SXin Li
visitPreprocessedEntitiesInRegion()392*67e74705SXin Li bool CursorVisitor::visitPreprocessedEntitiesInRegion() {
393*67e74705SXin Li if (!AU->getPreprocessor().getPreprocessingRecord())
394*67e74705SXin Li return false;
395*67e74705SXin Li
396*67e74705SXin Li PreprocessingRecord &PPRec
397*67e74705SXin Li = *AU->getPreprocessor().getPreprocessingRecord();
398*67e74705SXin Li SourceManager &SM = AU->getSourceManager();
399*67e74705SXin Li
400*67e74705SXin Li if (RegionOfInterest.isValid()) {
401*67e74705SXin Li SourceRange MappedRange = AU->mapRangeToPreamble(RegionOfInterest);
402*67e74705SXin Li SourceLocation B = MappedRange.getBegin();
403*67e74705SXin Li SourceLocation E = MappedRange.getEnd();
404*67e74705SXin Li
405*67e74705SXin Li if (AU->isInPreambleFileID(B)) {
406*67e74705SXin Li if (SM.isLoadedSourceLocation(E))
407*67e74705SXin Li return visitPreprocessedEntitiesInRange(SourceRange(B, E),
408*67e74705SXin Li PPRec, *this);
409*67e74705SXin Li
410*67e74705SXin Li // Beginning of range lies in the preamble but it also extends beyond
411*67e74705SXin Li // it into the main file. Split the range into 2 parts, one covering
412*67e74705SXin Li // the preamble and another covering the main file. This allows subsequent
413*67e74705SXin Li // calls to visitPreprocessedEntitiesInRange to accept a source range that
414*67e74705SXin Li // lies in the same FileID, allowing it to skip preprocessed entities that
415*67e74705SXin Li // do not come from the same FileID.
416*67e74705SXin Li bool breaked =
417*67e74705SXin Li visitPreprocessedEntitiesInRange(
418*67e74705SXin Li SourceRange(B, AU->getEndOfPreambleFileID()),
419*67e74705SXin Li PPRec, *this);
420*67e74705SXin Li if (breaked) return true;
421*67e74705SXin Li return visitPreprocessedEntitiesInRange(
422*67e74705SXin Li SourceRange(AU->getStartOfMainFileID(), E),
423*67e74705SXin Li PPRec, *this);
424*67e74705SXin Li }
425*67e74705SXin Li
426*67e74705SXin Li return visitPreprocessedEntitiesInRange(SourceRange(B, E), PPRec, *this);
427*67e74705SXin Li }
428*67e74705SXin Li
429*67e74705SXin Li bool OnlyLocalDecls
430*67e74705SXin Li = !AU->isMainFileAST() && AU->getOnlyLocalDecls();
431*67e74705SXin Li
432*67e74705SXin Li if (OnlyLocalDecls)
433*67e74705SXin Li return visitPreprocessedEntities(PPRec.local_begin(), PPRec.local_end(),
434*67e74705SXin Li PPRec);
435*67e74705SXin Li
436*67e74705SXin Li return visitPreprocessedEntities(PPRec.begin(), PPRec.end(), PPRec);
437*67e74705SXin Li }
438*67e74705SXin Li
439*67e74705SXin Li template<typename InputIterator>
visitPreprocessedEntities(InputIterator First,InputIterator Last,PreprocessingRecord & PPRec,FileID FID)440*67e74705SXin Li bool CursorVisitor::visitPreprocessedEntities(InputIterator First,
441*67e74705SXin Li InputIterator Last,
442*67e74705SXin Li PreprocessingRecord &PPRec,
443*67e74705SXin Li FileID FID) {
444*67e74705SXin Li for (; First != Last; ++First) {
445*67e74705SXin Li if (!FID.isInvalid() && !PPRec.isEntityInFileID(First, FID))
446*67e74705SXin Li continue;
447*67e74705SXin Li
448*67e74705SXin Li PreprocessedEntity *PPE = *First;
449*67e74705SXin Li if (!PPE)
450*67e74705SXin Li continue;
451*67e74705SXin Li
452*67e74705SXin Li if (MacroExpansion *ME = dyn_cast<MacroExpansion>(PPE)) {
453*67e74705SXin Li if (Visit(MakeMacroExpansionCursor(ME, TU)))
454*67e74705SXin Li return true;
455*67e74705SXin Li
456*67e74705SXin Li continue;
457*67e74705SXin Li }
458*67e74705SXin Li
459*67e74705SXin Li if (MacroDefinitionRecord *MD = dyn_cast<MacroDefinitionRecord>(PPE)) {
460*67e74705SXin Li if (Visit(MakeMacroDefinitionCursor(MD, TU)))
461*67e74705SXin Li return true;
462*67e74705SXin Li
463*67e74705SXin Li continue;
464*67e74705SXin Li }
465*67e74705SXin Li
466*67e74705SXin Li if (InclusionDirective *ID = dyn_cast<InclusionDirective>(PPE)) {
467*67e74705SXin Li if (Visit(MakeInclusionDirectiveCursor(ID, TU)))
468*67e74705SXin Li return true;
469*67e74705SXin Li
470*67e74705SXin Li continue;
471*67e74705SXin Li }
472*67e74705SXin Li }
473*67e74705SXin Li
474*67e74705SXin Li return false;
475*67e74705SXin Li }
476*67e74705SXin Li
477*67e74705SXin Li /// \brief Visit the children of the given cursor.
478*67e74705SXin Li ///
479*67e74705SXin Li /// \returns true if the visitation should be aborted, false if it
480*67e74705SXin Li /// should continue.
VisitChildren(CXCursor Cursor)481*67e74705SXin Li bool CursorVisitor::VisitChildren(CXCursor Cursor) {
482*67e74705SXin Li if (clang_isReference(Cursor.kind) &&
483*67e74705SXin Li Cursor.kind != CXCursor_CXXBaseSpecifier) {
484*67e74705SXin Li // By definition, references have no children.
485*67e74705SXin Li return false;
486*67e74705SXin Li }
487*67e74705SXin Li
488*67e74705SXin Li // Set the Parent field to Cursor, then back to its old value once we're
489*67e74705SXin Li // done.
490*67e74705SXin Li SetParentRAII SetParent(Parent, StmtParent, Cursor);
491*67e74705SXin Li
492*67e74705SXin Li if (clang_isDeclaration(Cursor.kind)) {
493*67e74705SXin Li Decl *D = const_cast<Decl *>(getCursorDecl(Cursor));
494*67e74705SXin Li if (!D)
495*67e74705SXin Li return false;
496*67e74705SXin Li
497*67e74705SXin Li return VisitAttributes(D) || Visit(D);
498*67e74705SXin Li }
499*67e74705SXin Li
500*67e74705SXin Li if (clang_isStatement(Cursor.kind)) {
501*67e74705SXin Li if (const Stmt *S = getCursorStmt(Cursor))
502*67e74705SXin Li return Visit(S);
503*67e74705SXin Li
504*67e74705SXin Li return false;
505*67e74705SXin Li }
506*67e74705SXin Li
507*67e74705SXin Li if (clang_isExpression(Cursor.kind)) {
508*67e74705SXin Li if (const Expr *E = getCursorExpr(Cursor))
509*67e74705SXin Li return Visit(E);
510*67e74705SXin Li
511*67e74705SXin Li return false;
512*67e74705SXin Li }
513*67e74705SXin Li
514*67e74705SXin Li if (clang_isTranslationUnit(Cursor.kind)) {
515*67e74705SXin Li CXTranslationUnit TU = getCursorTU(Cursor);
516*67e74705SXin Li ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
517*67e74705SXin Li
518*67e74705SXin Li int VisitOrder[2] = { VisitPreprocessorLast, !VisitPreprocessorLast };
519*67e74705SXin Li for (unsigned I = 0; I != 2; ++I) {
520*67e74705SXin Li if (VisitOrder[I]) {
521*67e74705SXin Li if (!CXXUnit->isMainFileAST() && CXXUnit->getOnlyLocalDecls() &&
522*67e74705SXin Li RegionOfInterest.isInvalid()) {
523*67e74705SXin Li for (ASTUnit::top_level_iterator TL = CXXUnit->top_level_begin(),
524*67e74705SXin Li TLEnd = CXXUnit->top_level_end();
525*67e74705SXin Li TL != TLEnd; ++TL) {
526*67e74705SXin Li const Optional<bool> V = handleDeclForVisitation(*TL);
527*67e74705SXin Li if (!V.hasValue())
528*67e74705SXin Li continue;
529*67e74705SXin Li return V.getValue();
530*67e74705SXin Li }
531*67e74705SXin Li } else if (VisitDeclContext(
532*67e74705SXin Li CXXUnit->getASTContext().getTranslationUnitDecl()))
533*67e74705SXin Li return true;
534*67e74705SXin Li continue;
535*67e74705SXin Li }
536*67e74705SXin Li
537*67e74705SXin Li // Walk the preprocessing record.
538*67e74705SXin Li if (CXXUnit->getPreprocessor().getPreprocessingRecord())
539*67e74705SXin Li visitPreprocessedEntitiesInRegion();
540*67e74705SXin Li }
541*67e74705SXin Li
542*67e74705SXin Li return false;
543*67e74705SXin Li }
544*67e74705SXin Li
545*67e74705SXin Li if (Cursor.kind == CXCursor_CXXBaseSpecifier) {
546*67e74705SXin Li if (const CXXBaseSpecifier *Base = getCursorCXXBaseSpecifier(Cursor)) {
547*67e74705SXin Li if (TypeSourceInfo *BaseTSInfo = Base->getTypeSourceInfo()) {
548*67e74705SXin Li return Visit(BaseTSInfo->getTypeLoc());
549*67e74705SXin Li }
550*67e74705SXin Li }
551*67e74705SXin Li }
552*67e74705SXin Li
553*67e74705SXin Li if (Cursor.kind == CXCursor_IBOutletCollectionAttr) {
554*67e74705SXin Li const IBOutletCollectionAttr *A =
555*67e74705SXin Li cast<IBOutletCollectionAttr>(cxcursor::getCursorAttr(Cursor));
556*67e74705SXin Li if (const ObjCObjectType *ObjT = A->getInterface()->getAs<ObjCObjectType>())
557*67e74705SXin Li return Visit(cxcursor::MakeCursorObjCClassRef(
558*67e74705SXin Li ObjT->getInterface(),
559*67e74705SXin Li A->getInterfaceLoc()->getTypeLoc().getLocStart(), TU));
560*67e74705SXin Li }
561*67e74705SXin Li
562*67e74705SXin Li // If pointing inside a macro definition, check if the token is an identifier
563*67e74705SXin Li // that was ever defined as a macro. In such a case, create a "pseudo" macro
564*67e74705SXin Li // expansion cursor for that token.
565*67e74705SXin Li SourceLocation BeginLoc = RegionOfInterest.getBegin();
566*67e74705SXin Li if (Cursor.kind == CXCursor_MacroDefinition &&
567*67e74705SXin Li BeginLoc == RegionOfInterest.getEnd()) {
568*67e74705SXin Li SourceLocation Loc = AU->mapLocationToPreamble(BeginLoc);
569*67e74705SXin Li const MacroInfo *MI =
570*67e74705SXin Li getMacroInfo(cxcursor::getCursorMacroDefinition(Cursor), TU);
571*67e74705SXin Li if (MacroDefinitionRecord *MacroDef =
572*67e74705SXin Li checkForMacroInMacroDefinition(MI, Loc, TU))
573*67e74705SXin Li return Visit(cxcursor::MakeMacroExpansionCursor(MacroDef, BeginLoc, TU));
574*67e74705SXin Li }
575*67e74705SXin Li
576*67e74705SXin Li // Nothing to visit at the moment.
577*67e74705SXin Li return false;
578*67e74705SXin Li }
579*67e74705SXin Li
VisitBlockDecl(BlockDecl * B)580*67e74705SXin Li bool CursorVisitor::VisitBlockDecl(BlockDecl *B) {
581*67e74705SXin Li if (TypeSourceInfo *TSInfo = B->getSignatureAsWritten())
582*67e74705SXin Li if (Visit(TSInfo->getTypeLoc()))
583*67e74705SXin Li return true;
584*67e74705SXin Li
585*67e74705SXin Li if (Stmt *Body = B->getBody())
586*67e74705SXin Li return Visit(MakeCXCursor(Body, StmtParent, TU, RegionOfInterest));
587*67e74705SXin Li
588*67e74705SXin Li return false;
589*67e74705SXin Li }
590*67e74705SXin Li
shouldVisitCursor(CXCursor Cursor)591*67e74705SXin Li Optional<bool> CursorVisitor::shouldVisitCursor(CXCursor Cursor) {
592*67e74705SXin Li if (RegionOfInterest.isValid()) {
593*67e74705SXin Li SourceRange Range = getFullCursorExtent(Cursor, AU->getSourceManager());
594*67e74705SXin Li if (Range.isInvalid())
595*67e74705SXin Li return None;
596*67e74705SXin Li
597*67e74705SXin Li switch (CompareRegionOfInterest(Range)) {
598*67e74705SXin Li case RangeBefore:
599*67e74705SXin Li // This declaration comes before the region of interest; skip it.
600*67e74705SXin Li return None;
601*67e74705SXin Li
602*67e74705SXin Li case RangeAfter:
603*67e74705SXin Li // This declaration comes after the region of interest; we're done.
604*67e74705SXin Li return false;
605*67e74705SXin Li
606*67e74705SXin Li case RangeOverlap:
607*67e74705SXin Li // This declaration overlaps the region of interest; visit it.
608*67e74705SXin Li break;
609*67e74705SXin Li }
610*67e74705SXin Li }
611*67e74705SXin Li return true;
612*67e74705SXin Li }
613*67e74705SXin Li
VisitDeclContext(DeclContext * DC)614*67e74705SXin Li bool CursorVisitor::VisitDeclContext(DeclContext *DC) {
615*67e74705SXin Li DeclContext::decl_iterator I = DC->decls_begin(), E = DC->decls_end();
616*67e74705SXin Li
617*67e74705SXin Li // FIXME: Eventually remove. This part of a hack to support proper
618*67e74705SXin Li // iteration over all Decls contained lexically within an ObjC container.
619*67e74705SXin Li SaveAndRestore<DeclContext::decl_iterator*> DI_saved(DI_current, &I);
620*67e74705SXin Li SaveAndRestore<DeclContext::decl_iterator> DE_saved(DE_current, E);
621*67e74705SXin Li
622*67e74705SXin Li for ( ; I != E; ++I) {
623*67e74705SXin Li Decl *D = *I;
624*67e74705SXin Li if (D->getLexicalDeclContext() != DC)
625*67e74705SXin Li continue;
626*67e74705SXin Li const Optional<bool> V = handleDeclForVisitation(D);
627*67e74705SXin Li if (!V.hasValue())
628*67e74705SXin Li continue;
629*67e74705SXin Li return V.getValue();
630*67e74705SXin Li }
631*67e74705SXin Li return false;
632*67e74705SXin Li }
633*67e74705SXin Li
handleDeclForVisitation(const Decl * D)634*67e74705SXin Li Optional<bool> CursorVisitor::handleDeclForVisitation(const Decl *D) {
635*67e74705SXin Li CXCursor Cursor = MakeCXCursor(D, TU, RegionOfInterest);
636*67e74705SXin Li
637*67e74705SXin Li // Ignore synthesized ivars here, otherwise if we have something like:
638*67e74705SXin Li // @synthesize prop = _prop;
639*67e74705SXin Li // and '_prop' is not declared, we will encounter a '_prop' ivar before
640*67e74705SXin Li // encountering the 'prop' synthesize declaration and we will think that
641*67e74705SXin Li // we passed the region-of-interest.
642*67e74705SXin Li if (auto *ivarD = dyn_cast<ObjCIvarDecl>(D)) {
643*67e74705SXin Li if (ivarD->getSynthesize())
644*67e74705SXin Li return None;
645*67e74705SXin Li }
646*67e74705SXin Li
647*67e74705SXin Li // FIXME: ObjCClassRef/ObjCProtocolRef for forward class/protocol
648*67e74705SXin Li // declarations is a mismatch with the compiler semantics.
649*67e74705SXin Li if (Cursor.kind == CXCursor_ObjCInterfaceDecl) {
650*67e74705SXin Li auto *ID = cast<ObjCInterfaceDecl>(D);
651*67e74705SXin Li if (!ID->isThisDeclarationADefinition())
652*67e74705SXin Li Cursor = MakeCursorObjCClassRef(ID, ID->getLocation(), TU);
653*67e74705SXin Li
654*67e74705SXin Li } else if (Cursor.kind == CXCursor_ObjCProtocolDecl) {
655*67e74705SXin Li auto *PD = cast<ObjCProtocolDecl>(D);
656*67e74705SXin Li if (!PD->isThisDeclarationADefinition())
657*67e74705SXin Li Cursor = MakeCursorObjCProtocolRef(PD, PD->getLocation(), TU);
658*67e74705SXin Li }
659*67e74705SXin Li
660*67e74705SXin Li const Optional<bool> V = shouldVisitCursor(Cursor);
661*67e74705SXin Li if (!V.hasValue())
662*67e74705SXin Li return None;
663*67e74705SXin Li if (!V.getValue())
664*67e74705SXin Li return false;
665*67e74705SXin Li if (Visit(Cursor, true))
666*67e74705SXin Li return true;
667*67e74705SXin Li return None;
668*67e74705SXin Li }
669*67e74705SXin Li
VisitTranslationUnitDecl(TranslationUnitDecl * D)670*67e74705SXin Li bool CursorVisitor::VisitTranslationUnitDecl(TranslationUnitDecl *D) {
671*67e74705SXin Li llvm_unreachable("Translation units are visited directly by Visit()");
672*67e74705SXin Li }
673*67e74705SXin Li
VisitTypeAliasTemplateDecl(TypeAliasTemplateDecl * D)674*67e74705SXin Li bool CursorVisitor::VisitTypeAliasTemplateDecl(TypeAliasTemplateDecl *D) {
675*67e74705SXin Li if (VisitTemplateParameters(D->getTemplateParameters()))
676*67e74705SXin Li return true;
677*67e74705SXin Li
678*67e74705SXin Li return Visit(MakeCXCursor(D->getTemplatedDecl(), TU, RegionOfInterest));
679*67e74705SXin Li }
680*67e74705SXin Li
VisitTypeAliasDecl(TypeAliasDecl * D)681*67e74705SXin Li bool CursorVisitor::VisitTypeAliasDecl(TypeAliasDecl *D) {
682*67e74705SXin Li if (TypeSourceInfo *TSInfo = D->getTypeSourceInfo())
683*67e74705SXin Li return Visit(TSInfo->getTypeLoc());
684*67e74705SXin Li
685*67e74705SXin Li return false;
686*67e74705SXin Li }
687*67e74705SXin Li
VisitTypedefDecl(TypedefDecl * D)688*67e74705SXin Li bool CursorVisitor::VisitTypedefDecl(TypedefDecl *D) {
689*67e74705SXin Li if (TypeSourceInfo *TSInfo = D->getTypeSourceInfo())
690*67e74705SXin Li return Visit(TSInfo->getTypeLoc());
691*67e74705SXin Li
692*67e74705SXin Li return false;
693*67e74705SXin Li }
694*67e74705SXin Li
VisitTagDecl(TagDecl * D)695*67e74705SXin Li bool CursorVisitor::VisitTagDecl(TagDecl *D) {
696*67e74705SXin Li return VisitDeclContext(D);
697*67e74705SXin Li }
698*67e74705SXin Li
VisitClassTemplateSpecializationDecl(ClassTemplateSpecializationDecl * D)699*67e74705SXin Li bool CursorVisitor::VisitClassTemplateSpecializationDecl(
700*67e74705SXin Li ClassTemplateSpecializationDecl *D) {
701*67e74705SXin Li bool ShouldVisitBody = false;
702*67e74705SXin Li switch (D->getSpecializationKind()) {
703*67e74705SXin Li case TSK_Undeclared:
704*67e74705SXin Li case TSK_ImplicitInstantiation:
705*67e74705SXin Li // Nothing to visit
706*67e74705SXin Li return false;
707*67e74705SXin Li
708*67e74705SXin Li case TSK_ExplicitInstantiationDeclaration:
709*67e74705SXin Li case TSK_ExplicitInstantiationDefinition:
710*67e74705SXin Li break;
711*67e74705SXin Li
712*67e74705SXin Li case TSK_ExplicitSpecialization:
713*67e74705SXin Li ShouldVisitBody = true;
714*67e74705SXin Li break;
715*67e74705SXin Li }
716*67e74705SXin Li
717*67e74705SXin Li // Visit the template arguments used in the specialization.
718*67e74705SXin Li if (TypeSourceInfo *SpecType = D->getTypeAsWritten()) {
719*67e74705SXin Li TypeLoc TL = SpecType->getTypeLoc();
720*67e74705SXin Li if (TemplateSpecializationTypeLoc TSTLoc =
721*67e74705SXin Li TL.getAs<TemplateSpecializationTypeLoc>()) {
722*67e74705SXin Li for (unsigned I = 0, N = TSTLoc.getNumArgs(); I != N; ++I)
723*67e74705SXin Li if (VisitTemplateArgumentLoc(TSTLoc.getArgLoc(I)))
724*67e74705SXin Li return true;
725*67e74705SXin Li }
726*67e74705SXin Li }
727*67e74705SXin Li
728*67e74705SXin Li return ShouldVisitBody && VisitCXXRecordDecl(D);
729*67e74705SXin Li }
730*67e74705SXin Li
VisitClassTemplatePartialSpecializationDecl(ClassTemplatePartialSpecializationDecl * D)731*67e74705SXin Li bool CursorVisitor::VisitClassTemplatePartialSpecializationDecl(
732*67e74705SXin Li ClassTemplatePartialSpecializationDecl *D) {
733*67e74705SXin Li // FIXME: Visit the "outer" template parameter lists on the TagDecl
734*67e74705SXin Li // before visiting these template parameters.
735*67e74705SXin Li if (VisitTemplateParameters(D->getTemplateParameters()))
736*67e74705SXin Li return true;
737*67e74705SXin Li
738*67e74705SXin Li // Visit the partial specialization arguments.
739*67e74705SXin Li const ASTTemplateArgumentListInfo *Info = D->getTemplateArgsAsWritten();
740*67e74705SXin Li const TemplateArgumentLoc *TemplateArgs = Info->getTemplateArgs();
741*67e74705SXin Li for (unsigned I = 0, N = Info->NumTemplateArgs; I != N; ++I)
742*67e74705SXin Li if (VisitTemplateArgumentLoc(TemplateArgs[I]))
743*67e74705SXin Li return true;
744*67e74705SXin Li
745*67e74705SXin Li return VisitCXXRecordDecl(D);
746*67e74705SXin Li }
747*67e74705SXin Li
VisitTemplateTypeParmDecl(TemplateTypeParmDecl * D)748*67e74705SXin Li bool CursorVisitor::VisitTemplateTypeParmDecl(TemplateTypeParmDecl *D) {
749*67e74705SXin Li // Visit the default argument.
750*67e74705SXin Li if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited())
751*67e74705SXin Li if (TypeSourceInfo *DefArg = D->getDefaultArgumentInfo())
752*67e74705SXin Li if (Visit(DefArg->getTypeLoc()))
753*67e74705SXin Li return true;
754*67e74705SXin Li
755*67e74705SXin Li return false;
756*67e74705SXin Li }
757*67e74705SXin Li
VisitEnumConstantDecl(EnumConstantDecl * D)758*67e74705SXin Li bool CursorVisitor::VisitEnumConstantDecl(EnumConstantDecl *D) {
759*67e74705SXin Li if (Expr *Init = D->getInitExpr())
760*67e74705SXin Li return Visit(MakeCXCursor(Init, StmtParent, TU, RegionOfInterest));
761*67e74705SXin Li return false;
762*67e74705SXin Li }
763*67e74705SXin Li
VisitDeclaratorDecl(DeclaratorDecl * DD)764*67e74705SXin Li bool CursorVisitor::VisitDeclaratorDecl(DeclaratorDecl *DD) {
765*67e74705SXin Li unsigned NumParamList = DD->getNumTemplateParameterLists();
766*67e74705SXin Li for (unsigned i = 0; i < NumParamList; i++) {
767*67e74705SXin Li TemplateParameterList* Params = DD->getTemplateParameterList(i);
768*67e74705SXin Li if (VisitTemplateParameters(Params))
769*67e74705SXin Li return true;
770*67e74705SXin Li }
771*67e74705SXin Li
772*67e74705SXin Li if (TypeSourceInfo *TSInfo = DD->getTypeSourceInfo())
773*67e74705SXin Li if (Visit(TSInfo->getTypeLoc()))
774*67e74705SXin Li return true;
775*67e74705SXin Li
776*67e74705SXin Li // Visit the nested-name-specifier, if present.
777*67e74705SXin Li if (NestedNameSpecifierLoc QualifierLoc = DD->getQualifierLoc())
778*67e74705SXin Li if (VisitNestedNameSpecifierLoc(QualifierLoc))
779*67e74705SXin Li return true;
780*67e74705SXin Li
781*67e74705SXin Li return false;
782*67e74705SXin Li }
783*67e74705SXin Li
784*67e74705SXin Li /// \brief Compare two base or member initializers based on their source order.
CompareCXXCtorInitializers(CXXCtorInitializer * const * X,CXXCtorInitializer * const * Y)785*67e74705SXin Li static int CompareCXXCtorInitializers(CXXCtorInitializer *const *X,
786*67e74705SXin Li CXXCtorInitializer *const *Y) {
787*67e74705SXin Li return (*X)->getSourceOrder() - (*Y)->getSourceOrder();
788*67e74705SXin Li }
789*67e74705SXin Li
VisitFunctionDecl(FunctionDecl * ND)790*67e74705SXin Li bool CursorVisitor::VisitFunctionDecl(FunctionDecl *ND) {
791*67e74705SXin Li unsigned NumParamList = ND->getNumTemplateParameterLists();
792*67e74705SXin Li for (unsigned i = 0; i < NumParamList; i++) {
793*67e74705SXin Li TemplateParameterList* Params = ND->getTemplateParameterList(i);
794*67e74705SXin Li if (VisitTemplateParameters(Params))
795*67e74705SXin Li return true;
796*67e74705SXin Li }
797*67e74705SXin Li
798*67e74705SXin Li if (TypeSourceInfo *TSInfo = ND->getTypeSourceInfo()) {
799*67e74705SXin Li // Visit the function declaration's syntactic components in the order
800*67e74705SXin Li // written. This requires a bit of work.
801*67e74705SXin Li TypeLoc TL = TSInfo->getTypeLoc().IgnoreParens();
802*67e74705SXin Li FunctionTypeLoc FTL = TL.getAs<FunctionTypeLoc>();
803*67e74705SXin Li
804*67e74705SXin Li // If we have a function declared directly (without the use of a typedef),
805*67e74705SXin Li // visit just the return type. Otherwise, just visit the function's type
806*67e74705SXin Li // now.
807*67e74705SXin Li if ((FTL && !isa<CXXConversionDecl>(ND) && Visit(FTL.getReturnLoc())) ||
808*67e74705SXin Li (!FTL && Visit(TL)))
809*67e74705SXin Li return true;
810*67e74705SXin Li
811*67e74705SXin Li // Visit the nested-name-specifier, if present.
812*67e74705SXin Li if (NestedNameSpecifierLoc QualifierLoc = ND->getQualifierLoc())
813*67e74705SXin Li if (VisitNestedNameSpecifierLoc(QualifierLoc))
814*67e74705SXin Li return true;
815*67e74705SXin Li
816*67e74705SXin Li // Visit the declaration name.
817*67e74705SXin Li if (!isa<CXXDestructorDecl>(ND))
818*67e74705SXin Li if (VisitDeclarationNameInfo(ND->getNameInfo()))
819*67e74705SXin Li return true;
820*67e74705SXin Li
821*67e74705SXin Li // FIXME: Visit explicitly-specified template arguments!
822*67e74705SXin Li
823*67e74705SXin Li // Visit the function parameters, if we have a function type.
824*67e74705SXin Li if (FTL && VisitFunctionTypeLoc(FTL, true))
825*67e74705SXin Li return true;
826*67e74705SXin Li
827*67e74705SXin Li // FIXME: Attributes?
828*67e74705SXin Li }
829*67e74705SXin Li
830*67e74705SXin Li if (ND->doesThisDeclarationHaveABody() && !ND->isLateTemplateParsed()) {
831*67e74705SXin Li if (CXXConstructorDecl *Constructor = dyn_cast<CXXConstructorDecl>(ND)) {
832*67e74705SXin Li // Find the initializers that were written in the source.
833*67e74705SXin Li SmallVector<CXXCtorInitializer *, 4> WrittenInits;
834*67e74705SXin Li for (auto *I : Constructor->inits()) {
835*67e74705SXin Li if (!I->isWritten())
836*67e74705SXin Li continue;
837*67e74705SXin Li
838*67e74705SXin Li WrittenInits.push_back(I);
839*67e74705SXin Li }
840*67e74705SXin Li
841*67e74705SXin Li // Sort the initializers in source order
842*67e74705SXin Li llvm::array_pod_sort(WrittenInits.begin(), WrittenInits.end(),
843*67e74705SXin Li &CompareCXXCtorInitializers);
844*67e74705SXin Li
845*67e74705SXin Li // Visit the initializers in source order
846*67e74705SXin Li for (unsigned I = 0, N = WrittenInits.size(); I != N; ++I) {
847*67e74705SXin Li CXXCtorInitializer *Init = WrittenInits[I];
848*67e74705SXin Li if (Init->isAnyMemberInitializer()) {
849*67e74705SXin Li if (Visit(MakeCursorMemberRef(Init->getAnyMember(),
850*67e74705SXin Li Init->getMemberLocation(), TU)))
851*67e74705SXin Li return true;
852*67e74705SXin Li } else if (TypeSourceInfo *TInfo = Init->getTypeSourceInfo()) {
853*67e74705SXin Li if (Visit(TInfo->getTypeLoc()))
854*67e74705SXin Li return true;
855*67e74705SXin Li }
856*67e74705SXin Li
857*67e74705SXin Li // Visit the initializer value.
858*67e74705SXin Li if (Expr *Initializer = Init->getInit())
859*67e74705SXin Li if (Visit(MakeCXCursor(Initializer, ND, TU, RegionOfInterest)))
860*67e74705SXin Li return true;
861*67e74705SXin Li }
862*67e74705SXin Li }
863*67e74705SXin Li
864*67e74705SXin Li if (Visit(MakeCXCursor(ND->getBody(), StmtParent, TU, RegionOfInterest)))
865*67e74705SXin Li return true;
866*67e74705SXin Li }
867*67e74705SXin Li
868*67e74705SXin Li return false;
869*67e74705SXin Li }
870*67e74705SXin Li
VisitFieldDecl(FieldDecl * D)871*67e74705SXin Li bool CursorVisitor::VisitFieldDecl(FieldDecl *D) {
872*67e74705SXin Li if (VisitDeclaratorDecl(D))
873*67e74705SXin Li return true;
874*67e74705SXin Li
875*67e74705SXin Li if (Expr *BitWidth = D->getBitWidth())
876*67e74705SXin Li return Visit(MakeCXCursor(BitWidth, StmtParent, TU, RegionOfInterest));
877*67e74705SXin Li
878*67e74705SXin Li return false;
879*67e74705SXin Li }
880*67e74705SXin Li
VisitVarDecl(VarDecl * D)881*67e74705SXin Li bool CursorVisitor::VisitVarDecl(VarDecl *D) {
882*67e74705SXin Li if (VisitDeclaratorDecl(D))
883*67e74705SXin Li return true;
884*67e74705SXin Li
885*67e74705SXin Li if (Expr *Init = D->getInit())
886*67e74705SXin Li return Visit(MakeCXCursor(Init, StmtParent, TU, RegionOfInterest));
887*67e74705SXin Li
888*67e74705SXin Li return false;
889*67e74705SXin Li }
890*67e74705SXin Li
VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl * D)891*67e74705SXin Li bool CursorVisitor::VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl *D) {
892*67e74705SXin Li if (VisitDeclaratorDecl(D))
893*67e74705SXin Li return true;
894*67e74705SXin Li
895*67e74705SXin Li if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited())
896*67e74705SXin Li if (Expr *DefArg = D->getDefaultArgument())
897*67e74705SXin Li return Visit(MakeCXCursor(DefArg, StmtParent, TU, RegionOfInterest));
898*67e74705SXin Li
899*67e74705SXin Li return false;
900*67e74705SXin Li }
901*67e74705SXin Li
VisitFunctionTemplateDecl(FunctionTemplateDecl * D)902*67e74705SXin Li bool CursorVisitor::VisitFunctionTemplateDecl(FunctionTemplateDecl *D) {
903*67e74705SXin Li // FIXME: Visit the "outer" template parameter lists on the FunctionDecl
904*67e74705SXin Li // before visiting these template parameters.
905*67e74705SXin Li if (VisitTemplateParameters(D->getTemplateParameters()))
906*67e74705SXin Li return true;
907*67e74705SXin Li
908*67e74705SXin Li return VisitFunctionDecl(D->getTemplatedDecl());
909*67e74705SXin Li }
910*67e74705SXin Li
VisitClassTemplateDecl(ClassTemplateDecl * D)911*67e74705SXin Li bool CursorVisitor::VisitClassTemplateDecl(ClassTemplateDecl *D) {
912*67e74705SXin Li // FIXME: Visit the "outer" template parameter lists on the TagDecl
913*67e74705SXin Li // before visiting these template parameters.
914*67e74705SXin Li if (VisitTemplateParameters(D->getTemplateParameters()))
915*67e74705SXin Li return true;
916*67e74705SXin Li
917*67e74705SXin Li return VisitCXXRecordDecl(D->getTemplatedDecl());
918*67e74705SXin Li }
919*67e74705SXin Li
VisitTemplateTemplateParmDecl(TemplateTemplateParmDecl * D)920*67e74705SXin Li bool CursorVisitor::VisitTemplateTemplateParmDecl(TemplateTemplateParmDecl *D) {
921*67e74705SXin Li if (VisitTemplateParameters(D->getTemplateParameters()))
922*67e74705SXin Li return true;
923*67e74705SXin Li
924*67e74705SXin Li if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited() &&
925*67e74705SXin Li VisitTemplateArgumentLoc(D->getDefaultArgument()))
926*67e74705SXin Li return true;
927*67e74705SXin Li
928*67e74705SXin Li return false;
929*67e74705SXin Li }
930*67e74705SXin Li
VisitObjCTypeParamDecl(ObjCTypeParamDecl * D)931*67e74705SXin Li bool CursorVisitor::VisitObjCTypeParamDecl(ObjCTypeParamDecl *D) {
932*67e74705SXin Li // Visit the bound, if it's explicit.
933*67e74705SXin Li if (D->hasExplicitBound()) {
934*67e74705SXin Li if (auto TInfo = D->getTypeSourceInfo()) {
935*67e74705SXin Li if (Visit(TInfo->getTypeLoc()))
936*67e74705SXin Li return true;
937*67e74705SXin Li }
938*67e74705SXin Li }
939*67e74705SXin Li
940*67e74705SXin Li return false;
941*67e74705SXin Li }
942*67e74705SXin Li
VisitObjCMethodDecl(ObjCMethodDecl * ND)943*67e74705SXin Li bool CursorVisitor::VisitObjCMethodDecl(ObjCMethodDecl *ND) {
944*67e74705SXin Li if (TypeSourceInfo *TSInfo = ND->getReturnTypeSourceInfo())
945*67e74705SXin Li if (Visit(TSInfo->getTypeLoc()))
946*67e74705SXin Li return true;
947*67e74705SXin Li
948*67e74705SXin Li for (const auto *P : ND->parameters()) {
949*67e74705SXin Li if (Visit(MakeCXCursor(P, TU, RegionOfInterest)))
950*67e74705SXin Li return true;
951*67e74705SXin Li }
952*67e74705SXin Li
953*67e74705SXin Li return ND->isThisDeclarationADefinition() &&
954*67e74705SXin Li Visit(MakeCXCursor(ND->getBody(), StmtParent, TU, RegionOfInterest));
955*67e74705SXin Li }
956*67e74705SXin Li
957*67e74705SXin Li template <typename DeclIt>
addRangedDeclsInContainer(DeclIt * DI_current,DeclIt DE_current,SourceManager & SM,SourceLocation EndLoc,SmallVectorImpl<Decl * > & Decls)958*67e74705SXin Li static void addRangedDeclsInContainer(DeclIt *DI_current, DeclIt DE_current,
959*67e74705SXin Li SourceManager &SM, SourceLocation EndLoc,
960*67e74705SXin Li SmallVectorImpl<Decl *> &Decls) {
961*67e74705SXin Li DeclIt next = *DI_current;
962*67e74705SXin Li while (++next != DE_current) {
963*67e74705SXin Li Decl *D_next = *next;
964*67e74705SXin Li if (!D_next)
965*67e74705SXin Li break;
966*67e74705SXin Li SourceLocation L = D_next->getLocStart();
967*67e74705SXin Li if (!L.isValid())
968*67e74705SXin Li break;
969*67e74705SXin Li if (SM.isBeforeInTranslationUnit(L, EndLoc)) {
970*67e74705SXin Li *DI_current = next;
971*67e74705SXin Li Decls.push_back(D_next);
972*67e74705SXin Li continue;
973*67e74705SXin Li }
974*67e74705SXin Li break;
975*67e74705SXin Li }
976*67e74705SXin Li }
977*67e74705SXin Li
VisitObjCContainerDecl(ObjCContainerDecl * D)978*67e74705SXin Li bool CursorVisitor::VisitObjCContainerDecl(ObjCContainerDecl *D) {
979*67e74705SXin Li // FIXME: Eventually convert back to just 'VisitDeclContext()'. Essentially
980*67e74705SXin Li // an @implementation can lexically contain Decls that are not properly
981*67e74705SXin Li // nested in the AST. When we identify such cases, we need to retrofit
982*67e74705SXin Li // this nesting here.
983*67e74705SXin Li if (!DI_current && !FileDI_current)
984*67e74705SXin Li return VisitDeclContext(D);
985*67e74705SXin Li
986*67e74705SXin Li // Scan the Decls that immediately come after the container
987*67e74705SXin Li // in the current DeclContext. If any fall within the
988*67e74705SXin Li // container's lexical region, stash them into a vector
989*67e74705SXin Li // for later processing.
990*67e74705SXin Li SmallVector<Decl *, 24> DeclsInContainer;
991*67e74705SXin Li SourceLocation EndLoc = D->getSourceRange().getEnd();
992*67e74705SXin Li SourceManager &SM = AU->getSourceManager();
993*67e74705SXin Li if (EndLoc.isValid()) {
994*67e74705SXin Li if (DI_current) {
995*67e74705SXin Li addRangedDeclsInContainer(DI_current, DE_current, SM, EndLoc,
996*67e74705SXin Li DeclsInContainer);
997*67e74705SXin Li } else {
998*67e74705SXin Li addRangedDeclsInContainer(FileDI_current, FileDE_current, SM, EndLoc,
999*67e74705SXin Li DeclsInContainer);
1000*67e74705SXin Li }
1001*67e74705SXin Li }
1002*67e74705SXin Li
1003*67e74705SXin Li // The common case.
1004*67e74705SXin Li if (DeclsInContainer.empty())
1005*67e74705SXin Li return VisitDeclContext(D);
1006*67e74705SXin Li
1007*67e74705SXin Li // Get all the Decls in the DeclContext, and sort them with the
1008*67e74705SXin Li // additional ones we've collected. Then visit them.
1009*67e74705SXin Li for (auto *SubDecl : D->decls()) {
1010*67e74705SXin Li if (!SubDecl || SubDecl->getLexicalDeclContext() != D ||
1011*67e74705SXin Li SubDecl->getLocStart().isInvalid())
1012*67e74705SXin Li continue;
1013*67e74705SXin Li DeclsInContainer.push_back(SubDecl);
1014*67e74705SXin Li }
1015*67e74705SXin Li
1016*67e74705SXin Li // Now sort the Decls so that they appear in lexical order.
1017*67e74705SXin Li std::sort(DeclsInContainer.begin(), DeclsInContainer.end(),
1018*67e74705SXin Li [&SM](Decl *A, Decl *B) {
1019*67e74705SXin Li SourceLocation L_A = A->getLocStart();
1020*67e74705SXin Li SourceLocation L_B = B->getLocStart();
1021*67e74705SXin Li assert(L_A.isValid() && L_B.isValid());
1022*67e74705SXin Li return SM.isBeforeInTranslationUnit(L_A, L_B);
1023*67e74705SXin Li });
1024*67e74705SXin Li
1025*67e74705SXin Li // Now visit the decls.
1026*67e74705SXin Li for (SmallVectorImpl<Decl*>::iterator I = DeclsInContainer.begin(),
1027*67e74705SXin Li E = DeclsInContainer.end(); I != E; ++I) {
1028*67e74705SXin Li CXCursor Cursor = MakeCXCursor(*I, TU, RegionOfInterest);
1029*67e74705SXin Li const Optional<bool> &V = shouldVisitCursor(Cursor);
1030*67e74705SXin Li if (!V.hasValue())
1031*67e74705SXin Li continue;
1032*67e74705SXin Li if (!V.getValue())
1033*67e74705SXin Li return false;
1034*67e74705SXin Li if (Visit(Cursor, true))
1035*67e74705SXin Li return true;
1036*67e74705SXin Li }
1037*67e74705SXin Li return false;
1038*67e74705SXin Li }
1039*67e74705SXin Li
VisitObjCCategoryDecl(ObjCCategoryDecl * ND)1040*67e74705SXin Li bool CursorVisitor::VisitObjCCategoryDecl(ObjCCategoryDecl *ND) {
1041*67e74705SXin Li if (Visit(MakeCursorObjCClassRef(ND->getClassInterface(), ND->getLocation(),
1042*67e74705SXin Li TU)))
1043*67e74705SXin Li return true;
1044*67e74705SXin Li
1045*67e74705SXin Li if (VisitObjCTypeParamList(ND->getTypeParamList()))
1046*67e74705SXin Li return true;
1047*67e74705SXin Li
1048*67e74705SXin Li ObjCCategoryDecl::protocol_loc_iterator PL = ND->protocol_loc_begin();
1049*67e74705SXin Li for (ObjCCategoryDecl::protocol_iterator I = ND->protocol_begin(),
1050*67e74705SXin Li E = ND->protocol_end(); I != E; ++I, ++PL)
1051*67e74705SXin Li if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
1052*67e74705SXin Li return true;
1053*67e74705SXin Li
1054*67e74705SXin Li return VisitObjCContainerDecl(ND);
1055*67e74705SXin Li }
1056*67e74705SXin Li
VisitObjCProtocolDecl(ObjCProtocolDecl * PID)1057*67e74705SXin Li bool CursorVisitor::VisitObjCProtocolDecl(ObjCProtocolDecl *PID) {
1058*67e74705SXin Li if (!PID->isThisDeclarationADefinition())
1059*67e74705SXin Li return Visit(MakeCursorObjCProtocolRef(PID, PID->getLocation(), TU));
1060*67e74705SXin Li
1061*67e74705SXin Li ObjCProtocolDecl::protocol_loc_iterator PL = PID->protocol_loc_begin();
1062*67e74705SXin Li for (ObjCProtocolDecl::protocol_iterator I = PID->protocol_begin(),
1063*67e74705SXin Li E = PID->protocol_end(); I != E; ++I, ++PL)
1064*67e74705SXin Li if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
1065*67e74705SXin Li return true;
1066*67e74705SXin Li
1067*67e74705SXin Li return VisitObjCContainerDecl(PID);
1068*67e74705SXin Li }
1069*67e74705SXin Li
VisitObjCPropertyDecl(ObjCPropertyDecl * PD)1070*67e74705SXin Li bool CursorVisitor::VisitObjCPropertyDecl(ObjCPropertyDecl *PD) {
1071*67e74705SXin Li if (PD->getTypeSourceInfo() && Visit(PD->getTypeSourceInfo()->getTypeLoc()))
1072*67e74705SXin Li return true;
1073*67e74705SXin Li
1074*67e74705SXin Li // FIXME: This implements a workaround with @property declarations also being
1075*67e74705SXin Li // installed in the DeclContext for the @interface. Eventually this code
1076*67e74705SXin Li // should be removed.
1077*67e74705SXin Li ObjCCategoryDecl *CDecl = dyn_cast<ObjCCategoryDecl>(PD->getDeclContext());
1078*67e74705SXin Li if (!CDecl || !CDecl->IsClassExtension())
1079*67e74705SXin Li return false;
1080*67e74705SXin Li
1081*67e74705SXin Li ObjCInterfaceDecl *ID = CDecl->getClassInterface();
1082*67e74705SXin Li if (!ID)
1083*67e74705SXin Li return false;
1084*67e74705SXin Li
1085*67e74705SXin Li IdentifierInfo *PropertyId = PD->getIdentifier();
1086*67e74705SXin Li ObjCPropertyDecl *prevDecl =
1087*67e74705SXin Li ObjCPropertyDecl::findPropertyDecl(cast<DeclContext>(ID), PropertyId,
1088*67e74705SXin Li PD->getQueryKind());
1089*67e74705SXin Li
1090*67e74705SXin Li if (!prevDecl)
1091*67e74705SXin Li return false;
1092*67e74705SXin Li
1093*67e74705SXin Li // Visit synthesized methods since they will be skipped when visiting
1094*67e74705SXin Li // the @interface.
1095*67e74705SXin Li if (ObjCMethodDecl *MD = prevDecl->getGetterMethodDecl())
1096*67e74705SXin Li if (MD->isPropertyAccessor() && MD->getLexicalDeclContext() == CDecl)
1097*67e74705SXin Li if (Visit(MakeCXCursor(MD, TU, RegionOfInterest)))
1098*67e74705SXin Li return true;
1099*67e74705SXin Li
1100*67e74705SXin Li if (ObjCMethodDecl *MD = prevDecl->getSetterMethodDecl())
1101*67e74705SXin Li if (MD->isPropertyAccessor() && MD->getLexicalDeclContext() == CDecl)
1102*67e74705SXin Li if (Visit(MakeCXCursor(MD, TU, RegionOfInterest)))
1103*67e74705SXin Li return true;
1104*67e74705SXin Li
1105*67e74705SXin Li return false;
1106*67e74705SXin Li }
1107*67e74705SXin Li
VisitObjCTypeParamList(ObjCTypeParamList * typeParamList)1108*67e74705SXin Li bool CursorVisitor::VisitObjCTypeParamList(ObjCTypeParamList *typeParamList) {
1109*67e74705SXin Li if (!typeParamList)
1110*67e74705SXin Li return false;
1111*67e74705SXin Li
1112*67e74705SXin Li for (auto *typeParam : *typeParamList) {
1113*67e74705SXin Li // Visit the type parameter.
1114*67e74705SXin Li if (Visit(MakeCXCursor(typeParam, TU, RegionOfInterest)))
1115*67e74705SXin Li return true;
1116*67e74705SXin Li }
1117*67e74705SXin Li
1118*67e74705SXin Li return false;
1119*67e74705SXin Li }
1120*67e74705SXin Li
VisitObjCInterfaceDecl(ObjCInterfaceDecl * D)1121*67e74705SXin Li bool CursorVisitor::VisitObjCInterfaceDecl(ObjCInterfaceDecl *D) {
1122*67e74705SXin Li if (!D->isThisDeclarationADefinition()) {
1123*67e74705SXin Li // Forward declaration is treated like a reference.
1124*67e74705SXin Li return Visit(MakeCursorObjCClassRef(D, D->getLocation(), TU));
1125*67e74705SXin Li }
1126*67e74705SXin Li
1127*67e74705SXin Li // Objective-C type parameters.
1128*67e74705SXin Li if (VisitObjCTypeParamList(D->getTypeParamListAsWritten()))
1129*67e74705SXin Li return true;
1130*67e74705SXin Li
1131*67e74705SXin Li // Issue callbacks for super class.
1132*67e74705SXin Li if (D->getSuperClass() &&
1133*67e74705SXin Li Visit(MakeCursorObjCSuperClassRef(D->getSuperClass(),
1134*67e74705SXin Li D->getSuperClassLoc(),
1135*67e74705SXin Li TU)))
1136*67e74705SXin Li return true;
1137*67e74705SXin Li
1138*67e74705SXin Li if (TypeSourceInfo *SuperClassTInfo = D->getSuperClassTInfo())
1139*67e74705SXin Li if (Visit(SuperClassTInfo->getTypeLoc()))
1140*67e74705SXin Li return true;
1141*67e74705SXin Li
1142*67e74705SXin Li ObjCInterfaceDecl::protocol_loc_iterator PL = D->protocol_loc_begin();
1143*67e74705SXin Li for (ObjCInterfaceDecl::protocol_iterator I = D->protocol_begin(),
1144*67e74705SXin Li E = D->protocol_end(); I != E; ++I, ++PL)
1145*67e74705SXin Li if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
1146*67e74705SXin Li return true;
1147*67e74705SXin Li
1148*67e74705SXin Li return VisitObjCContainerDecl(D);
1149*67e74705SXin Li }
1150*67e74705SXin Li
VisitObjCImplDecl(ObjCImplDecl * D)1151*67e74705SXin Li bool CursorVisitor::VisitObjCImplDecl(ObjCImplDecl *D) {
1152*67e74705SXin Li return VisitObjCContainerDecl(D);
1153*67e74705SXin Li }
1154*67e74705SXin Li
VisitObjCCategoryImplDecl(ObjCCategoryImplDecl * D)1155*67e74705SXin Li bool CursorVisitor::VisitObjCCategoryImplDecl(ObjCCategoryImplDecl *D) {
1156*67e74705SXin Li // 'ID' could be null when dealing with invalid code.
1157*67e74705SXin Li if (ObjCInterfaceDecl *ID = D->getClassInterface())
1158*67e74705SXin Li if (Visit(MakeCursorObjCClassRef(ID, D->getLocation(), TU)))
1159*67e74705SXin Li return true;
1160*67e74705SXin Li
1161*67e74705SXin Li return VisitObjCImplDecl(D);
1162*67e74705SXin Li }
1163*67e74705SXin Li
VisitObjCImplementationDecl(ObjCImplementationDecl * D)1164*67e74705SXin Li bool CursorVisitor::VisitObjCImplementationDecl(ObjCImplementationDecl *D) {
1165*67e74705SXin Li #if 0
1166*67e74705SXin Li // Issue callbacks for super class.
1167*67e74705SXin Li // FIXME: No source location information!
1168*67e74705SXin Li if (D->getSuperClass() &&
1169*67e74705SXin Li Visit(MakeCursorObjCSuperClassRef(D->getSuperClass(),
1170*67e74705SXin Li D->getSuperClassLoc(),
1171*67e74705SXin Li TU)))
1172*67e74705SXin Li return true;
1173*67e74705SXin Li #endif
1174*67e74705SXin Li
1175*67e74705SXin Li return VisitObjCImplDecl(D);
1176*67e74705SXin Li }
1177*67e74705SXin Li
VisitObjCPropertyImplDecl(ObjCPropertyImplDecl * PD)1178*67e74705SXin Li bool CursorVisitor::VisitObjCPropertyImplDecl(ObjCPropertyImplDecl *PD) {
1179*67e74705SXin Li if (ObjCIvarDecl *Ivar = PD->getPropertyIvarDecl())
1180*67e74705SXin Li if (PD->isIvarNameSpecified())
1181*67e74705SXin Li return Visit(MakeCursorMemberRef(Ivar, PD->getPropertyIvarDeclLoc(), TU));
1182*67e74705SXin Li
1183*67e74705SXin Li return false;
1184*67e74705SXin Li }
1185*67e74705SXin Li
VisitNamespaceDecl(NamespaceDecl * D)1186*67e74705SXin Li bool CursorVisitor::VisitNamespaceDecl(NamespaceDecl *D) {
1187*67e74705SXin Li return VisitDeclContext(D);
1188*67e74705SXin Li }
1189*67e74705SXin Li
VisitNamespaceAliasDecl(NamespaceAliasDecl * D)1190*67e74705SXin Li bool CursorVisitor::VisitNamespaceAliasDecl(NamespaceAliasDecl *D) {
1191*67e74705SXin Li // Visit nested-name-specifier.
1192*67e74705SXin Li if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1193*67e74705SXin Li if (VisitNestedNameSpecifierLoc(QualifierLoc))
1194*67e74705SXin Li return true;
1195*67e74705SXin Li
1196*67e74705SXin Li return Visit(MakeCursorNamespaceRef(D->getAliasedNamespace(),
1197*67e74705SXin Li D->getTargetNameLoc(), TU));
1198*67e74705SXin Li }
1199*67e74705SXin Li
VisitUsingDecl(UsingDecl * D)1200*67e74705SXin Li bool CursorVisitor::VisitUsingDecl(UsingDecl *D) {
1201*67e74705SXin Li // Visit nested-name-specifier.
1202*67e74705SXin Li if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc()) {
1203*67e74705SXin Li if (VisitNestedNameSpecifierLoc(QualifierLoc))
1204*67e74705SXin Li return true;
1205*67e74705SXin Li }
1206*67e74705SXin Li
1207*67e74705SXin Li if (Visit(MakeCursorOverloadedDeclRef(D, D->getLocation(), TU)))
1208*67e74705SXin Li return true;
1209*67e74705SXin Li
1210*67e74705SXin Li return VisitDeclarationNameInfo(D->getNameInfo());
1211*67e74705SXin Li }
1212*67e74705SXin Li
VisitUsingDirectiveDecl(UsingDirectiveDecl * D)1213*67e74705SXin Li bool CursorVisitor::VisitUsingDirectiveDecl(UsingDirectiveDecl *D) {
1214*67e74705SXin Li // Visit nested-name-specifier.
1215*67e74705SXin Li if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1216*67e74705SXin Li if (VisitNestedNameSpecifierLoc(QualifierLoc))
1217*67e74705SXin Li return true;
1218*67e74705SXin Li
1219*67e74705SXin Li return Visit(MakeCursorNamespaceRef(D->getNominatedNamespaceAsWritten(),
1220*67e74705SXin Li D->getIdentLocation(), TU));
1221*67e74705SXin Li }
1222*67e74705SXin Li
VisitUnresolvedUsingValueDecl(UnresolvedUsingValueDecl * D)1223*67e74705SXin Li bool CursorVisitor::VisitUnresolvedUsingValueDecl(UnresolvedUsingValueDecl *D) {
1224*67e74705SXin Li // Visit nested-name-specifier.
1225*67e74705SXin Li if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc()) {
1226*67e74705SXin Li if (VisitNestedNameSpecifierLoc(QualifierLoc))
1227*67e74705SXin Li return true;
1228*67e74705SXin Li }
1229*67e74705SXin Li
1230*67e74705SXin Li return VisitDeclarationNameInfo(D->getNameInfo());
1231*67e74705SXin Li }
1232*67e74705SXin Li
VisitUnresolvedUsingTypenameDecl(UnresolvedUsingTypenameDecl * D)1233*67e74705SXin Li bool CursorVisitor::VisitUnresolvedUsingTypenameDecl(
1234*67e74705SXin Li UnresolvedUsingTypenameDecl *D) {
1235*67e74705SXin Li // Visit nested-name-specifier.
1236*67e74705SXin Li if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1237*67e74705SXin Li if (VisitNestedNameSpecifierLoc(QualifierLoc))
1238*67e74705SXin Li return true;
1239*67e74705SXin Li
1240*67e74705SXin Li return false;
1241*67e74705SXin Li }
1242*67e74705SXin Li
VisitStaticAssertDecl(StaticAssertDecl * D)1243*67e74705SXin Li bool CursorVisitor::VisitStaticAssertDecl(StaticAssertDecl *D) {
1244*67e74705SXin Li if (Visit(MakeCXCursor(D->getAssertExpr(), StmtParent, TU, RegionOfInterest)))
1245*67e74705SXin Li return true;
1246*67e74705SXin Li if (Visit(MakeCXCursor(D->getMessage(), StmtParent, TU, RegionOfInterest)))
1247*67e74705SXin Li return true;
1248*67e74705SXin Li return false;
1249*67e74705SXin Li }
1250*67e74705SXin Li
VisitDeclarationNameInfo(DeclarationNameInfo Name)1251*67e74705SXin Li bool CursorVisitor::VisitDeclarationNameInfo(DeclarationNameInfo Name) {
1252*67e74705SXin Li switch (Name.getName().getNameKind()) {
1253*67e74705SXin Li case clang::DeclarationName::Identifier:
1254*67e74705SXin Li case clang::DeclarationName::CXXLiteralOperatorName:
1255*67e74705SXin Li case clang::DeclarationName::CXXOperatorName:
1256*67e74705SXin Li case clang::DeclarationName::CXXUsingDirective:
1257*67e74705SXin Li return false;
1258*67e74705SXin Li
1259*67e74705SXin Li case clang::DeclarationName::CXXConstructorName:
1260*67e74705SXin Li case clang::DeclarationName::CXXDestructorName:
1261*67e74705SXin Li case clang::DeclarationName::CXXConversionFunctionName:
1262*67e74705SXin Li if (TypeSourceInfo *TSInfo = Name.getNamedTypeInfo())
1263*67e74705SXin Li return Visit(TSInfo->getTypeLoc());
1264*67e74705SXin Li return false;
1265*67e74705SXin Li
1266*67e74705SXin Li case clang::DeclarationName::ObjCZeroArgSelector:
1267*67e74705SXin Li case clang::DeclarationName::ObjCOneArgSelector:
1268*67e74705SXin Li case clang::DeclarationName::ObjCMultiArgSelector:
1269*67e74705SXin Li // FIXME: Per-identifier location info?
1270*67e74705SXin Li return false;
1271*67e74705SXin Li }
1272*67e74705SXin Li
1273*67e74705SXin Li llvm_unreachable("Invalid DeclarationName::Kind!");
1274*67e74705SXin Li }
1275*67e74705SXin Li
VisitNestedNameSpecifier(NestedNameSpecifier * NNS,SourceRange Range)1276*67e74705SXin Li bool CursorVisitor::VisitNestedNameSpecifier(NestedNameSpecifier *NNS,
1277*67e74705SXin Li SourceRange Range) {
1278*67e74705SXin Li // FIXME: This whole routine is a hack to work around the lack of proper
1279*67e74705SXin Li // source information in nested-name-specifiers (PR5791). Since we do have
1280*67e74705SXin Li // a beginning source location, we can visit the first component of the
1281*67e74705SXin Li // nested-name-specifier, if it's a single-token component.
1282*67e74705SXin Li if (!NNS)
1283*67e74705SXin Li return false;
1284*67e74705SXin Li
1285*67e74705SXin Li // Get the first component in the nested-name-specifier.
1286*67e74705SXin Li while (NestedNameSpecifier *Prefix = NNS->getPrefix())
1287*67e74705SXin Li NNS = Prefix;
1288*67e74705SXin Li
1289*67e74705SXin Li switch (NNS->getKind()) {
1290*67e74705SXin Li case NestedNameSpecifier::Namespace:
1291*67e74705SXin Li return Visit(MakeCursorNamespaceRef(NNS->getAsNamespace(), Range.getBegin(),
1292*67e74705SXin Li TU));
1293*67e74705SXin Li
1294*67e74705SXin Li case NestedNameSpecifier::NamespaceAlias:
1295*67e74705SXin Li return Visit(MakeCursorNamespaceRef(NNS->getAsNamespaceAlias(),
1296*67e74705SXin Li Range.getBegin(), TU));
1297*67e74705SXin Li
1298*67e74705SXin Li case NestedNameSpecifier::TypeSpec: {
1299*67e74705SXin Li // If the type has a form where we know that the beginning of the source
1300*67e74705SXin Li // range matches up with a reference cursor. Visit the appropriate reference
1301*67e74705SXin Li // cursor.
1302*67e74705SXin Li const Type *T = NNS->getAsType();
1303*67e74705SXin Li if (const TypedefType *Typedef = dyn_cast<TypedefType>(T))
1304*67e74705SXin Li return Visit(MakeCursorTypeRef(Typedef->getDecl(), Range.getBegin(), TU));
1305*67e74705SXin Li if (const TagType *Tag = dyn_cast<TagType>(T))
1306*67e74705SXin Li return Visit(MakeCursorTypeRef(Tag->getDecl(), Range.getBegin(), TU));
1307*67e74705SXin Li if (const TemplateSpecializationType *TST
1308*67e74705SXin Li = dyn_cast<TemplateSpecializationType>(T))
1309*67e74705SXin Li return VisitTemplateName(TST->getTemplateName(), Range.getBegin());
1310*67e74705SXin Li break;
1311*67e74705SXin Li }
1312*67e74705SXin Li
1313*67e74705SXin Li case NestedNameSpecifier::TypeSpecWithTemplate:
1314*67e74705SXin Li case NestedNameSpecifier::Global:
1315*67e74705SXin Li case NestedNameSpecifier::Identifier:
1316*67e74705SXin Li case NestedNameSpecifier::Super:
1317*67e74705SXin Li break;
1318*67e74705SXin Li }
1319*67e74705SXin Li
1320*67e74705SXin Li return false;
1321*67e74705SXin Li }
1322*67e74705SXin Li
1323*67e74705SXin Li bool
VisitNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier)1324*67e74705SXin Li CursorVisitor::VisitNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier) {
1325*67e74705SXin Li SmallVector<NestedNameSpecifierLoc, 4> Qualifiers;
1326*67e74705SXin Li for (; Qualifier; Qualifier = Qualifier.getPrefix())
1327*67e74705SXin Li Qualifiers.push_back(Qualifier);
1328*67e74705SXin Li
1329*67e74705SXin Li while (!Qualifiers.empty()) {
1330*67e74705SXin Li NestedNameSpecifierLoc Q = Qualifiers.pop_back_val();
1331*67e74705SXin Li NestedNameSpecifier *NNS = Q.getNestedNameSpecifier();
1332*67e74705SXin Li switch (NNS->getKind()) {
1333*67e74705SXin Li case NestedNameSpecifier::Namespace:
1334*67e74705SXin Li if (Visit(MakeCursorNamespaceRef(NNS->getAsNamespace(),
1335*67e74705SXin Li Q.getLocalBeginLoc(),
1336*67e74705SXin Li TU)))
1337*67e74705SXin Li return true;
1338*67e74705SXin Li
1339*67e74705SXin Li break;
1340*67e74705SXin Li
1341*67e74705SXin Li case NestedNameSpecifier::NamespaceAlias:
1342*67e74705SXin Li if (Visit(MakeCursorNamespaceRef(NNS->getAsNamespaceAlias(),
1343*67e74705SXin Li Q.getLocalBeginLoc(),
1344*67e74705SXin Li TU)))
1345*67e74705SXin Li return true;
1346*67e74705SXin Li
1347*67e74705SXin Li break;
1348*67e74705SXin Li
1349*67e74705SXin Li case NestedNameSpecifier::TypeSpec:
1350*67e74705SXin Li case NestedNameSpecifier::TypeSpecWithTemplate:
1351*67e74705SXin Li if (Visit(Q.getTypeLoc()))
1352*67e74705SXin Li return true;
1353*67e74705SXin Li
1354*67e74705SXin Li break;
1355*67e74705SXin Li
1356*67e74705SXin Li case NestedNameSpecifier::Global:
1357*67e74705SXin Li case NestedNameSpecifier::Identifier:
1358*67e74705SXin Li case NestedNameSpecifier::Super:
1359*67e74705SXin Li break;
1360*67e74705SXin Li }
1361*67e74705SXin Li }
1362*67e74705SXin Li
1363*67e74705SXin Li return false;
1364*67e74705SXin Li }
1365*67e74705SXin Li
VisitTemplateParameters(const TemplateParameterList * Params)1366*67e74705SXin Li bool CursorVisitor::VisitTemplateParameters(
1367*67e74705SXin Li const TemplateParameterList *Params) {
1368*67e74705SXin Li if (!Params)
1369*67e74705SXin Li return false;
1370*67e74705SXin Li
1371*67e74705SXin Li for (TemplateParameterList::const_iterator P = Params->begin(),
1372*67e74705SXin Li PEnd = Params->end();
1373*67e74705SXin Li P != PEnd; ++P) {
1374*67e74705SXin Li if (Visit(MakeCXCursor(*P, TU, RegionOfInterest)))
1375*67e74705SXin Li return true;
1376*67e74705SXin Li }
1377*67e74705SXin Li
1378*67e74705SXin Li return false;
1379*67e74705SXin Li }
1380*67e74705SXin Li
VisitTemplateName(TemplateName Name,SourceLocation Loc)1381*67e74705SXin Li bool CursorVisitor::VisitTemplateName(TemplateName Name, SourceLocation Loc) {
1382*67e74705SXin Li switch (Name.getKind()) {
1383*67e74705SXin Li case TemplateName::Template:
1384*67e74705SXin Li return Visit(MakeCursorTemplateRef(Name.getAsTemplateDecl(), Loc, TU));
1385*67e74705SXin Li
1386*67e74705SXin Li case TemplateName::OverloadedTemplate:
1387*67e74705SXin Li // Visit the overloaded template set.
1388*67e74705SXin Li if (Visit(MakeCursorOverloadedDeclRef(Name, Loc, TU)))
1389*67e74705SXin Li return true;
1390*67e74705SXin Li
1391*67e74705SXin Li return false;
1392*67e74705SXin Li
1393*67e74705SXin Li case TemplateName::DependentTemplate:
1394*67e74705SXin Li // FIXME: Visit nested-name-specifier.
1395*67e74705SXin Li return false;
1396*67e74705SXin Li
1397*67e74705SXin Li case TemplateName::QualifiedTemplate:
1398*67e74705SXin Li // FIXME: Visit nested-name-specifier.
1399*67e74705SXin Li return Visit(MakeCursorTemplateRef(
1400*67e74705SXin Li Name.getAsQualifiedTemplateName()->getDecl(),
1401*67e74705SXin Li Loc, TU));
1402*67e74705SXin Li
1403*67e74705SXin Li case TemplateName::SubstTemplateTemplateParm:
1404*67e74705SXin Li return Visit(MakeCursorTemplateRef(
1405*67e74705SXin Li Name.getAsSubstTemplateTemplateParm()->getParameter(),
1406*67e74705SXin Li Loc, TU));
1407*67e74705SXin Li
1408*67e74705SXin Li case TemplateName::SubstTemplateTemplateParmPack:
1409*67e74705SXin Li return Visit(MakeCursorTemplateRef(
1410*67e74705SXin Li Name.getAsSubstTemplateTemplateParmPack()->getParameterPack(),
1411*67e74705SXin Li Loc, TU));
1412*67e74705SXin Li }
1413*67e74705SXin Li
1414*67e74705SXin Li llvm_unreachable("Invalid TemplateName::Kind!");
1415*67e74705SXin Li }
1416*67e74705SXin Li
VisitTemplateArgumentLoc(const TemplateArgumentLoc & TAL)1417*67e74705SXin Li bool CursorVisitor::VisitTemplateArgumentLoc(const TemplateArgumentLoc &TAL) {
1418*67e74705SXin Li switch (TAL.getArgument().getKind()) {
1419*67e74705SXin Li case TemplateArgument::Null:
1420*67e74705SXin Li case TemplateArgument::Integral:
1421*67e74705SXin Li case TemplateArgument::Pack:
1422*67e74705SXin Li return false;
1423*67e74705SXin Li
1424*67e74705SXin Li case TemplateArgument::Type:
1425*67e74705SXin Li if (TypeSourceInfo *TSInfo = TAL.getTypeSourceInfo())
1426*67e74705SXin Li return Visit(TSInfo->getTypeLoc());
1427*67e74705SXin Li return false;
1428*67e74705SXin Li
1429*67e74705SXin Li case TemplateArgument::Declaration:
1430*67e74705SXin Li if (Expr *E = TAL.getSourceDeclExpression())
1431*67e74705SXin Li return Visit(MakeCXCursor(E, StmtParent, TU, RegionOfInterest));
1432*67e74705SXin Li return false;
1433*67e74705SXin Li
1434*67e74705SXin Li case TemplateArgument::NullPtr:
1435*67e74705SXin Li if (Expr *E = TAL.getSourceNullPtrExpression())
1436*67e74705SXin Li return Visit(MakeCXCursor(E, StmtParent, TU, RegionOfInterest));
1437*67e74705SXin Li return false;
1438*67e74705SXin Li
1439*67e74705SXin Li case TemplateArgument::Expression:
1440*67e74705SXin Li if (Expr *E = TAL.getSourceExpression())
1441*67e74705SXin Li return Visit(MakeCXCursor(E, StmtParent, TU, RegionOfInterest));
1442*67e74705SXin Li return false;
1443*67e74705SXin Li
1444*67e74705SXin Li case TemplateArgument::Template:
1445*67e74705SXin Li case TemplateArgument::TemplateExpansion:
1446*67e74705SXin Li if (VisitNestedNameSpecifierLoc(TAL.getTemplateQualifierLoc()))
1447*67e74705SXin Li return true;
1448*67e74705SXin Li
1449*67e74705SXin Li return VisitTemplateName(TAL.getArgument().getAsTemplateOrTemplatePattern(),
1450*67e74705SXin Li TAL.getTemplateNameLoc());
1451*67e74705SXin Li }
1452*67e74705SXin Li
1453*67e74705SXin Li llvm_unreachable("Invalid TemplateArgument::Kind!");
1454*67e74705SXin Li }
1455*67e74705SXin Li
VisitLinkageSpecDecl(LinkageSpecDecl * D)1456*67e74705SXin Li bool CursorVisitor::VisitLinkageSpecDecl(LinkageSpecDecl *D) {
1457*67e74705SXin Li return VisitDeclContext(D);
1458*67e74705SXin Li }
1459*67e74705SXin Li
VisitQualifiedTypeLoc(QualifiedTypeLoc TL)1460*67e74705SXin Li bool CursorVisitor::VisitQualifiedTypeLoc(QualifiedTypeLoc TL) {
1461*67e74705SXin Li return Visit(TL.getUnqualifiedLoc());
1462*67e74705SXin Li }
1463*67e74705SXin Li
VisitBuiltinTypeLoc(BuiltinTypeLoc TL)1464*67e74705SXin Li bool CursorVisitor::VisitBuiltinTypeLoc(BuiltinTypeLoc TL) {
1465*67e74705SXin Li ASTContext &Context = AU->getASTContext();
1466*67e74705SXin Li
1467*67e74705SXin Li // Some builtin types (such as Objective-C's "id", "sel", and
1468*67e74705SXin Li // "Class") have associated declarations. Create cursors for those.
1469*67e74705SXin Li QualType VisitType;
1470*67e74705SXin Li switch (TL.getTypePtr()->getKind()) {
1471*67e74705SXin Li
1472*67e74705SXin Li case BuiltinType::Void:
1473*67e74705SXin Li case BuiltinType::NullPtr:
1474*67e74705SXin Li case BuiltinType::Dependent:
1475*67e74705SXin Li #define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \
1476*67e74705SXin Li case BuiltinType::Id:
1477*67e74705SXin Li #include "clang/Basic/OpenCLImageTypes.def"
1478*67e74705SXin Li case BuiltinType::OCLSampler:
1479*67e74705SXin Li case BuiltinType::OCLEvent:
1480*67e74705SXin Li case BuiltinType::OCLClkEvent:
1481*67e74705SXin Li case BuiltinType::OCLQueue:
1482*67e74705SXin Li case BuiltinType::OCLNDRange:
1483*67e74705SXin Li case BuiltinType::OCLReserveID:
1484*67e74705SXin Li #define BUILTIN_TYPE(Id, SingletonId)
1485*67e74705SXin Li #define SIGNED_TYPE(Id, SingletonId) case BuiltinType::Id:
1486*67e74705SXin Li #define UNSIGNED_TYPE(Id, SingletonId) case BuiltinType::Id:
1487*67e74705SXin Li #define FLOATING_TYPE(Id, SingletonId) case BuiltinType::Id:
1488*67e74705SXin Li #define PLACEHOLDER_TYPE(Id, SingletonId) case BuiltinType::Id:
1489*67e74705SXin Li #include "clang/AST/BuiltinTypes.def"
1490*67e74705SXin Li break;
1491*67e74705SXin Li
1492*67e74705SXin Li case BuiltinType::ObjCId:
1493*67e74705SXin Li VisitType = Context.getObjCIdType();
1494*67e74705SXin Li break;
1495*67e74705SXin Li
1496*67e74705SXin Li case BuiltinType::ObjCClass:
1497*67e74705SXin Li VisitType = Context.getObjCClassType();
1498*67e74705SXin Li break;
1499*67e74705SXin Li
1500*67e74705SXin Li case BuiltinType::ObjCSel:
1501*67e74705SXin Li VisitType = Context.getObjCSelType();
1502*67e74705SXin Li break;
1503*67e74705SXin Li }
1504*67e74705SXin Li
1505*67e74705SXin Li if (!VisitType.isNull()) {
1506*67e74705SXin Li if (const TypedefType *Typedef = VisitType->getAs<TypedefType>())
1507*67e74705SXin Li return Visit(MakeCursorTypeRef(Typedef->getDecl(), TL.getBuiltinLoc(),
1508*67e74705SXin Li TU));
1509*67e74705SXin Li }
1510*67e74705SXin Li
1511*67e74705SXin Li return false;
1512*67e74705SXin Li }
1513*67e74705SXin Li
VisitTypedefTypeLoc(TypedefTypeLoc TL)1514*67e74705SXin Li bool CursorVisitor::VisitTypedefTypeLoc(TypedefTypeLoc TL) {
1515*67e74705SXin Li return Visit(MakeCursorTypeRef(TL.getTypedefNameDecl(), TL.getNameLoc(), TU));
1516*67e74705SXin Li }
1517*67e74705SXin Li
VisitUnresolvedUsingTypeLoc(UnresolvedUsingTypeLoc TL)1518*67e74705SXin Li bool CursorVisitor::VisitUnresolvedUsingTypeLoc(UnresolvedUsingTypeLoc TL) {
1519*67e74705SXin Li return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1520*67e74705SXin Li }
1521*67e74705SXin Li
VisitTagTypeLoc(TagTypeLoc TL)1522*67e74705SXin Li bool CursorVisitor::VisitTagTypeLoc(TagTypeLoc TL) {
1523*67e74705SXin Li if (TL.isDefinition())
1524*67e74705SXin Li return Visit(MakeCXCursor(TL.getDecl(), TU, RegionOfInterest));
1525*67e74705SXin Li
1526*67e74705SXin Li return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1527*67e74705SXin Li }
1528*67e74705SXin Li
VisitTemplateTypeParmTypeLoc(TemplateTypeParmTypeLoc TL)1529*67e74705SXin Li bool CursorVisitor::VisitTemplateTypeParmTypeLoc(TemplateTypeParmTypeLoc TL) {
1530*67e74705SXin Li return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1531*67e74705SXin Li }
1532*67e74705SXin Li
VisitObjCInterfaceTypeLoc(ObjCInterfaceTypeLoc TL)1533*67e74705SXin Li bool CursorVisitor::VisitObjCInterfaceTypeLoc(ObjCInterfaceTypeLoc TL) {
1534*67e74705SXin Li return Visit(MakeCursorObjCClassRef(TL.getIFaceDecl(), TL.getNameLoc(), TU));
1535*67e74705SXin Li }
1536*67e74705SXin Li
VisitObjCObjectTypeLoc(ObjCObjectTypeLoc TL)1537*67e74705SXin Li bool CursorVisitor::VisitObjCObjectTypeLoc(ObjCObjectTypeLoc TL) {
1538*67e74705SXin Li if (TL.hasBaseTypeAsWritten() && Visit(TL.getBaseLoc()))
1539*67e74705SXin Li return true;
1540*67e74705SXin Li
1541*67e74705SXin Li for (unsigned I = 0, N = TL.getNumTypeArgs(); I != N; ++I) {
1542*67e74705SXin Li if (Visit(TL.getTypeArgTInfo(I)->getTypeLoc()))
1543*67e74705SXin Li return true;
1544*67e74705SXin Li }
1545*67e74705SXin Li
1546*67e74705SXin Li for (unsigned I = 0, N = TL.getNumProtocols(); I != N; ++I) {
1547*67e74705SXin Li if (Visit(MakeCursorObjCProtocolRef(TL.getProtocol(I), TL.getProtocolLoc(I),
1548*67e74705SXin Li TU)))
1549*67e74705SXin Li return true;
1550*67e74705SXin Li }
1551*67e74705SXin Li
1552*67e74705SXin Li return false;
1553*67e74705SXin Li }
1554*67e74705SXin Li
VisitObjCObjectPointerTypeLoc(ObjCObjectPointerTypeLoc TL)1555*67e74705SXin Li bool CursorVisitor::VisitObjCObjectPointerTypeLoc(ObjCObjectPointerTypeLoc TL) {
1556*67e74705SXin Li return Visit(TL.getPointeeLoc());
1557*67e74705SXin Li }
1558*67e74705SXin Li
VisitParenTypeLoc(ParenTypeLoc TL)1559*67e74705SXin Li bool CursorVisitor::VisitParenTypeLoc(ParenTypeLoc TL) {
1560*67e74705SXin Li return Visit(TL.getInnerLoc());
1561*67e74705SXin Li }
1562*67e74705SXin Li
VisitPointerTypeLoc(PointerTypeLoc TL)1563*67e74705SXin Li bool CursorVisitor::VisitPointerTypeLoc(PointerTypeLoc TL) {
1564*67e74705SXin Li return Visit(TL.getPointeeLoc());
1565*67e74705SXin Li }
1566*67e74705SXin Li
VisitBlockPointerTypeLoc(BlockPointerTypeLoc TL)1567*67e74705SXin Li bool CursorVisitor::VisitBlockPointerTypeLoc(BlockPointerTypeLoc TL) {
1568*67e74705SXin Li return Visit(TL.getPointeeLoc());
1569*67e74705SXin Li }
1570*67e74705SXin Li
VisitMemberPointerTypeLoc(MemberPointerTypeLoc TL)1571*67e74705SXin Li bool CursorVisitor::VisitMemberPointerTypeLoc(MemberPointerTypeLoc TL) {
1572*67e74705SXin Li return Visit(TL.getPointeeLoc());
1573*67e74705SXin Li }
1574*67e74705SXin Li
VisitLValueReferenceTypeLoc(LValueReferenceTypeLoc TL)1575*67e74705SXin Li bool CursorVisitor::VisitLValueReferenceTypeLoc(LValueReferenceTypeLoc TL) {
1576*67e74705SXin Li return Visit(TL.getPointeeLoc());
1577*67e74705SXin Li }
1578*67e74705SXin Li
VisitRValueReferenceTypeLoc(RValueReferenceTypeLoc TL)1579*67e74705SXin Li bool CursorVisitor::VisitRValueReferenceTypeLoc(RValueReferenceTypeLoc TL) {
1580*67e74705SXin Li return Visit(TL.getPointeeLoc());
1581*67e74705SXin Li }
1582*67e74705SXin Li
VisitAttributedTypeLoc(AttributedTypeLoc TL)1583*67e74705SXin Li bool CursorVisitor::VisitAttributedTypeLoc(AttributedTypeLoc TL) {
1584*67e74705SXin Li return Visit(TL.getModifiedLoc());
1585*67e74705SXin Li }
1586*67e74705SXin Li
VisitFunctionTypeLoc(FunctionTypeLoc TL,bool SkipResultType)1587*67e74705SXin Li bool CursorVisitor::VisitFunctionTypeLoc(FunctionTypeLoc TL,
1588*67e74705SXin Li bool SkipResultType) {
1589*67e74705SXin Li if (!SkipResultType && Visit(TL.getReturnLoc()))
1590*67e74705SXin Li return true;
1591*67e74705SXin Li
1592*67e74705SXin Li for (unsigned I = 0, N = TL.getNumParams(); I != N; ++I)
1593*67e74705SXin Li if (Decl *D = TL.getParam(I))
1594*67e74705SXin Li if (Visit(MakeCXCursor(D, TU, RegionOfInterest)))
1595*67e74705SXin Li return true;
1596*67e74705SXin Li
1597*67e74705SXin Li return false;
1598*67e74705SXin Li }
1599*67e74705SXin Li
VisitArrayTypeLoc(ArrayTypeLoc TL)1600*67e74705SXin Li bool CursorVisitor::VisitArrayTypeLoc(ArrayTypeLoc TL) {
1601*67e74705SXin Li if (Visit(TL.getElementLoc()))
1602*67e74705SXin Li return true;
1603*67e74705SXin Li
1604*67e74705SXin Li if (Expr *Size = TL.getSizeExpr())
1605*67e74705SXin Li return Visit(MakeCXCursor(Size, StmtParent, TU, RegionOfInterest));
1606*67e74705SXin Li
1607*67e74705SXin Li return false;
1608*67e74705SXin Li }
1609*67e74705SXin Li
VisitDecayedTypeLoc(DecayedTypeLoc TL)1610*67e74705SXin Li bool CursorVisitor::VisitDecayedTypeLoc(DecayedTypeLoc TL) {
1611*67e74705SXin Li return Visit(TL.getOriginalLoc());
1612*67e74705SXin Li }
1613*67e74705SXin Li
VisitAdjustedTypeLoc(AdjustedTypeLoc TL)1614*67e74705SXin Li bool CursorVisitor::VisitAdjustedTypeLoc(AdjustedTypeLoc TL) {
1615*67e74705SXin Li return Visit(TL.getOriginalLoc());
1616*67e74705SXin Li }
1617*67e74705SXin Li
VisitTemplateSpecializationTypeLoc(TemplateSpecializationTypeLoc TL)1618*67e74705SXin Li bool CursorVisitor::VisitTemplateSpecializationTypeLoc(
1619*67e74705SXin Li TemplateSpecializationTypeLoc TL) {
1620*67e74705SXin Li // Visit the template name.
1621*67e74705SXin Li if (VisitTemplateName(TL.getTypePtr()->getTemplateName(),
1622*67e74705SXin Li TL.getTemplateNameLoc()))
1623*67e74705SXin Li return true;
1624*67e74705SXin Li
1625*67e74705SXin Li // Visit the template arguments.
1626*67e74705SXin Li for (unsigned I = 0, N = TL.getNumArgs(); I != N; ++I)
1627*67e74705SXin Li if (VisitTemplateArgumentLoc(TL.getArgLoc(I)))
1628*67e74705SXin Li return true;
1629*67e74705SXin Li
1630*67e74705SXin Li return false;
1631*67e74705SXin Li }
1632*67e74705SXin Li
VisitTypeOfExprTypeLoc(TypeOfExprTypeLoc TL)1633*67e74705SXin Li bool CursorVisitor::VisitTypeOfExprTypeLoc(TypeOfExprTypeLoc TL) {
1634*67e74705SXin Li return Visit(MakeCXCursor(TL.getUnderlyingExpr(), StmtParent, TU));
1635*67e74705SXin Li }
1636*67e74705SXin Li
VisitTypeOfTypeLoc(TypeOfTypeLoc TL)1637*67e74705SXin Li bool CursorVisitor::VisitTypeOfTypeLoc(TypeOfTypeLoc TL) {
1638*67e74705SXin Li if (TypeSourceInfo *TSInfo = TL.getUnderlyingTInfo())
1639*67e74705SXin Li return Visit(TSInfo->getTypeLoc());
1640*67e74705SXin Li
1641*67e74705SXin Li return false;
1642*67e74705SXin Li }
1643*67e74705SXin Li
VisitUnaryTransformTypeLoc(UnaryTransformTypeLoc TL)1644*67e74705SXin Li bool CursorVisitor::VisitUnaryTransformTypeLoc(UnaryTransformTypeLoc TL) {
1645*67e74705SXin Li if (TypeSourceInfo *TSInfo = TL.getUnderlyingTInfo())
1646*67e74705SXin Li return Visit(TSInfo->getTypeLoc());
1647*67e74705SXin Li
1648*67e74705SXin Li return false;
1649*67e74705SXin Li }
1650*67e74705SXin Li
VisitDependentNameTypeLoc(DependentNameTypeLoc TL)1651*67e74705SXin Li bool CursorVisitor::VisitDependentNameTypeLoc(DependentNameTypeLoc TL) {
1652*67e74705SXin Li return VisitNestedNameSpecifierLoc(TL.getQualifierLoc());
1653*67e74705SXin Li }
1654*67e74705SXin Li
VisitDependentTemplateSpecializationTypeLoc(DependentTemplateSpecializationTypeLoc TL)1655*67e74705SXin Li bool CursorVisitor::VisitDependentTemplateSpecializationTypeLoc(
1656*67e74705SXin Li DependentTemplateSpecializationTypeLoc TL) {
1657*67e74705SXin Li // Visit the nested-name-specifier, if there is one.
1658*67e74705SXin Li if (TL.getQualifierLoc() &&
1659*67e74705SXin Li VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
1660*67e74705SXin Li return true;
1661*67e74705SXin Li
1662*67e74705SXin Li // Visit the template arguments.
1663*67e74705SXin Li for (unsigned I = 0, N = TL.getNumArgs(); I != N; ++I)
1664*67e74705SXin Li if (VisitTemplateArgumentLoc(TL.getArgLoc(I)))
1665*67e74705SXin Li return true;
1666*67e74705SXin Li
1667*67e74705SXin Li return false;
1668*67e74705SXin Li }
1669*67e74705SXin Li
VisitElaboratedTypeLoc(ElaboratedTypeLoc TL)1670*67e74705SXin Li bool CursorVisitor::VisitElaboratedTypeLoc(ElaboratedTypeLoc TL) {
1671*67e74705SXin Li if (VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
1672*67e74705SXin Li return true;
1673*67e74705SXin Li
1674*67e74705SXin Li return Visit(TL.getNamedTypeLoc());
1675*67e74705SXin Li }
1676*67e74705SXin Li
VisitPackExpansionTypeLoc(PackExpansionTypeLoc TL)1677*67e74705SXin Li bool CursorVisitor::VisitPackExpansionTypeLoc(PackExpansionTypeLoc TL) {
1678*67e74705SXin Li return Visit(TL.getPatternLoc());
1679*67e74705SXin Li }
1680*67e74705SXin Li
VisitDecltypeTypeLoc(DecltypeTypeLoc TL)1681*67e74705SXin Li bool CursorVisitor::VisitDecltypeTypeLoc(DecltypeTypeLoc TL) {
1682*67e74705SXin Li if (Expr *E = TL.getUnderlyingExpr())
1683*67e74705SXin Li return Visit(MakeCXCursor(E, StmtParent, TU));
1684*67e74705SXin Li
1685*67e74705SXin Li return false;
1686*67e74705SXin Li }
1687*67e74705SXin Li
VisitInjectedClassNameTypeLoc(InjectedClassNameTypeLoc TL)1688*67e74705SXin Li bool CursorVisitor::VisitInjectedClassNameTypeLoc(InjectedClassNameTypeLoc TL) {
1689*67e74705SXin Li return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1690*67e74705SXin Li }
1691*67e74705SXin Li
VisitAtomicTypeLoc(AtomicTypeLoc TL)1692*67e74705SXin Li bool CursorVisitor::VisitAtomicTypeLoc(AtomicTypeLoc TL) {
1693*67e74705SXin Li return Visit(TL.getValueLoc());
1694*67e74705SXin Li }
1695*67e74705SXin Li
VisitPipeTypeLoc(PipeTypeLoc TL)1696*67e74705SXin Li bool CursorVisitor::VisitPipeTypeLoc(PipeTypeLoc TL) {
1697*67e74705SXin Li return Visit(TL.getValueLoc());
1698*67e74705SXin Li }
1699*67e74705SXin Li
1700*67e74705SXin Li #define DEFAULT_TYPELOC_IMPL(CLASS, PARENT) \
1701*67e74705SXin Li bool CursorVisitor::Visit##CLASS##TypeLoc(CLASS##TypeLoc TL) { \
1702*67e74705SXin Li return Visit##PARENT##Loc(TL); \
1703*67e74705SXin Li }
1704*67e74705SXin Li
DEFAULT_TYPELOC_IMPL(Complex,Type)1705*67e74705SXin Li DEFAULT_TYPELOC_IMPL(Complex, Type)
1706*67e74705SXin Li DEFAULT_TYPELOC_IMPL(ConstantArray, ArrayType)
1707*67e74705SXin Li DEFAULT_TYPELOC_IMPL(IncompleteArray, ArrayType)
1708*67e74705SXin Li DEFAULT_TYPELOC_IMPL(VariableArray, ArrayType)
1709*67e74705SXin Li DEFAULT_TYPELOC_IMPL(DependentSizedArray, ArrayType)
1710*67e74705SXin Li DEFAULT_TYPELOC_IMPL(DependentSizedExtVector, Type)
1711*67e74705SXin Li DEFAULT_TYPELOC_IMPL(Vector, Type)
1712*67e74705SXin Li DEFAULT_TYPELOC_IMPL(ExtVector, VectorType)
1713*67e74705SXin Li DEFAULT_TYPELOC_IMPL(FunctionProto, FunctionType)
1714*67e74705SXin Li DEFAULT_TYPELOC_IMPL(FunctionNoProto, FunctionType)
1715*67e74705SXin Li DEFAULT_TYPELOC_IMPL(Record, TagType)
1716*67e74705SXin Li DEFAULT_TYPELOC_IMPL(Enum, TagType)
1717*67e74705SXin Li DEFAULT_TYPELOC_IMPL(SubstTemplateTypeParm, Type)
1718*67e74705SXin Li DEFAULT_TYPELOC_IMPL(SubstTemplateTypeParmPack, Type)
1719*67e74705SXin Li DEFAULT_TYPELOC_IMPL(Auto, Type)
1720*67e74705SXin Li
1721*67e74705SXin Li bool CursorVisitor::VisitCXXRecordDecl(CXXRecordDecl *D) {
1722*67e74705SXin Li // Visit the nested-name-specifier, if present.
1723*67e74705SXin Li if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1724*67e74705SXin Li if (VisitNestedNameSpecifierLoc(QualifierLoc))
1725*67e74705SXin Li return true;
1726*67e74705SXin Li
1727*67e74705SXin Li if (D->isCompleteDefinition()) {
1728*67e74705SXin Li for (const auto &I : D->bases()) {
1729*67e74705SXin Li if (Visit(cxcursor::MakeCursorCXXBaseSpecifier(&I, TU)))
1730*67e74705SXin Li return true;
1731*67e74705SXin Li }
1732*67e74705SXin Li }
1733*67e74705SXin Li
1734*67e74705SXin Li return VisitTagDecl(D);
1735*67e74705SXin Li }
1736*67e74705SXin Li
VisitAttributes(Decl * D)1737*67e74705SXin Li bool CursorVisitor::VisitAttributes(Decl *D) {
1738*67e74705SXin Li for (const auto *I : D->attrs())
1739*67e74705SXin Li if (Visit(MakeCXCursor(I, D, TU)))
1740*67e74705SXin Li return true;
1741*67e74705SXin Li
1742*67e74705SXin Li return false;
1743*67e74705SXin Li }
1744*67e74705SXin Li
1745*67e74705SXin Li //===----------------------------------------------------------------------===//
1746*67e74705SXin Li // Data-recursive visitor methods.
1747*67e74705SXin Li //===----------------------------------------------------------------------===//
1748*67e74705SXin Li
1749*67e74705SXin Li namespace {
1750*67e74705SXin Li #define DEF_JOB(NAME, DATA, KIND)\
1751*67e74705SXin Li class NAME : public VisitorJob {\
1752*67e74705SXin Li public:\
1753*67e74705SXin Li NAME(const DATA *d, CXCursor parent) : \
1754*67e74705SXin Li VisitorJob(parent, VisitorJob::KIND, d) {} \
1755*67e74705SXin Li static bool classof(const VisitorJob *VJ) { return VJ->getKind() == KIND; }\
1756*67e74705SXin Li const DATA *get() const { return static_cast<const DATA*>(data[0]); }\
1757*67e74705SXin Li };
1758*67e74705SXin Li
1759*67e74705SXin Li DEF_JOB(StmtVisit, Stmt, StmtVisitKind)
1760*67e74705SXin Li DEF_JOB(MemberExprParts, MemberExpr, MemberExprPartsKind)
1761*67e74705SXin Li DEF_JOB(DeclRefExprParts, DeclRefExpr, DeclRefExprPartsKind)
1762*67e74705SXin Li DEF_JOB(OverloadExprParts, OverloadExpr, OverloadExprPartsKind)
1763*67e74705SXin Li DEF_JOB(SizeOfPackExprParts, SizeOfPackExpr, SizeOfPackExprPartsKind)
1764*67e74705SXin Li DEF_JOB(LambdaExprParts, LambdaExpr, LambdaExprPartsKind)
1765*67e74705SXin Li DEF_JOB(PostChildrenVisit, void, PostChildrenVisitKind)
1766*67e74705SXin Li #undef DEF_JOB
1767*67e74705SXin Li
1768*67e74705SXin Li class ExplicitTemplateArgsVisit : public VisitorJob {
1769*67e74705SXin Li public:
ExplicitTemplateArgsVisit(const TemplateArgumentLoc * Begin,const TemplateArgumentLoc * End,CXCursor parent)1770*67e74705SXin Li ExplicitTemplateArgsVisit(const TemplateArgumentLoc *Begin,
1771*67e74705SXin Li const TemplateArgumentLoc *End, CXCursor parent)
1772*67e74705SXin Li : VisitorJob(parent, VisitorJob::ExplicitTemplateArgsVisitKind, Begin,
1773*67e74705SXin Li End) {}
classof(const VisitorJob * VJ)1774*67e74705SXin Li static bool classof(const VisitorJob *VJ) {
1775*67e74705SXin Li return VJ->getKind() == ExplicitTemplateArgsVisitKind;
1776*67e74705SXin Li }
begin() const1777*67e74705SXin Li const TemplateArgumentLoc *begin() const {
1778*67e74705SXin Li return static_cast<const TemplateArgumentLoc *>(data[0]);
1779*67e74705SXin Li }
end()1780*67e74705SXin Li const TemplateArgumentLoc *end() {
1781*67e74705SXin Li return static_cast<const TemplateArgumentLoc *>(data[1]);
1782*67e74705SXin Li }
1783*67e74705SXin Li };
1784*67e74705SXin Li class DeclVisit : public VisitorJob {
1785*67e74705SXin Li public:
DeclVisit(const Decl * D,CXCursor parent,bool isFirst)1786*67e74705SXin Li DeclVisit(const Decl *D, CXCursor parent, bool isFirst) :
1787*67e74705SXin Li VisitorJob(parent, VisitorJob::DeclVisitKind,
1788*67e74705SXin Li D, isFirst ? (void*) 1 : (void*) nullptr) {}
classof(const VisitorJob * VJ)1789*67e74705SXin Li static bool classof(const VisitorJob *VJ) {
1790*67e74705SXin Li return VJ->getKind() == DeclVisitKind;
1791*67e74705SXin Li }
get() const1792*67e74705SXin Li const Decl *get() const { return static_cast<const Decl *>(data[0]); }
isFirst() const1793*67e74705SXin Li bool isFirst() const { return data[1] != nullptr; }
1794*67e74705SXin Li };
1795*67e74705SXin Li class TypeLocVisit : public VisitorJob {
1796*67e74705SXin Li public:
TypeLocVisit(TypeLoc tl,CXCursor parent)1797*67e74705SXin Li TypeLocVisit(TypeLoc tl, CXCursor parent) :
1798*67e74705SXin Li VisitorJob(parent, VisitorJob::TypeLocVisitKind,
1799*67e74705SXin Li tl.getType().getAsOpaquePtr(), tl.getOpaqueData()) {}
1800*67e74705SXin Li
classof(const VisitorJob * VJ)1801*67e74705SXin Li static bool classof(const VisitorJob *VJ) {
1802*67e74705SXin Li return VJ->getKind() == TypeLocVisitKind;
1803*67e74705SXin Li }
1804*67e74705SXin Li
get() const1805*67e74705SXin Li TypeLoc get() const {
1806*67e74705SXin Li QualType T = QualType::getFromOpaquePtr(data[0]);
1807*67e74705SXin Li return TypeLoc(T, const_cast<void *>(data[1]));
1808*67e74705SXin Li }
1809*67e74705SXin Li };
1810*67e74705SXin Li
1811*67e74705SXin Li class LabelRefVisit : public VisitorJob {
1812*67e74705SXin Li public:
LabelRefVisit(LabelDecl * LD,SourceLocation labelLoc,CXCursor parent)1813*67e74705SXin Li LabelRefVisit(LabelDecl *LD, SourceLocation labelLoc, CXCursor parent)
1814*67e74705SXin Li : VisitorJob(parent, VisitorJob::LabelRefVisitKind, LD,
1815*67e74705SXin Li labelLoc.getPtrEncoding()) {}
1816*67e74705SXin Li
classof(const VisitorJob * VJ)1817*67e74705SXin Li static bool classof(const VisitorJob *VJ) {
1818*67e74705SXin Li return VJ->getKind() == VisitorJob::LabelRefVisitKind;
1819*67e74705SXin Li }
get() const1820*67e74705SXin Li const LabelDecl *get() const {
1821*67e74705SXin Li return static_cast<const LabelDecl *>(data[0]);
1822*67e74705SXin Li }
getLoc() const1823*67e74705SXin Li SourceLocation getLoc() const {
1824*67e74705SXin Li return SourceLocation::getFromPtrEncoding(data[1]); }
1825*67e74705SXin Li };
1826*67e74705SXin Li
1827*67e74705SXin Li class NestedNameSpecifierLocVisit : public VisitorJob {
1828*67e74705SXin Li public:
NestedNameSpecifierLocVisit(NestedNameSpecifierLoc Qualifier,CXCursor parent)1829*67e74705SXin Li NestedNameSpecifierLocVisit(NestedNameSpecifierLoc Qualifier, CXCursor parent)
1830*67e74705SXin Li : VisitorJob(parent, VisitorJob::NestedNameSpecifierLocVisitKind,
1831*67e74705SXin Li Qualifier.getNestedNameSpecifier(),
1832*67e74705SXin Li Qualifier.getOpaqueData()) { }
1833*67e74705SXin Li
classof(const VisitorJob * VJ)1834*67e74705SXin Li static bool classof(const VisitorJob *VJ) {
1835*67e74705SXin Li return VJ->getKind() == VisitorJob::NestedNameSpecifierLocVisitKind;
1836*67e74705SXin Li }
1837*67e74705SXin Li
get() const1838*67e74705SXin Li NestedNameSpecifierLoc get() const {
1839*67e74705SXin Li return NestedNameSpecifierLoc(
1840*67e74705SXin Li const_cast<NestedNameSpecifier *>(
1841*67e74705SXin Li static_cast<const NestedNameSpecifier *>(data[0])),
1842*67e74705SXin Li const_cast<void *>(data[1]));
1843*67e74705SXin Li }
1844*67e74705SXin Li };
1845*67e74705SXin Li
1846*67e74705SXin Li class DeclarationNameInfoVisit : public VisitorJob {
1847*67e74705SXin Li public:
DeclarationNameInfoVisit(const Stmt * S,CXCursor parent)1848*67e74705SXin Li DeclarationNameInfoVisit(const Stmt *S, CXCursor parent)
1849*67e74705SXin Li : VisitorJob(parent, VisitorJob::DeclarationNameInfoVisitKind, S) {}
classof(const VisitorJob * VJ)1850*67e74705SXin Li static bool classof(const VisitorJob *VJ) {
1851*67e74705SXin Li return VJ->getKind() == VisitorJob::DeclarationNameInfoVisitKind;
1852*67e74705SXin Li }
get() const1853*67e74705SXin Li DeclarationNameInfo get() const {
1854*67e74705SXin Li const Stmt *S = static_cast<const Stmt *>(data[0]);
1855*67e74705SXin Li switch (S->getStmtClass()) {
1856*67e74705SXin Li default:
1857*67e74705SXin Li llvm_unreachable("Unhandled Stmt");
1858*67e74705SXin Li case clang::Stmt::MSDependentExistsStmtClass:
1859*67e74705SXin Li return cast<MSDependentExistsStmt>(S)->getNameInfo();
1860*67e74705SXin Li case Stmt::CXXDependentScopeMemberExprClass:
1861*67e74705SXin Li return cast<CXXDependentScopeMemberExpr>(S)->getMemberNameInfo();
1862*67e74705SXin Li case Stmt::DependentScopeDeclRefExprClass:
1863*67e74705SXin Li return cast<DependentScopeDeclRefExpr>(S)->getNameInfo();
1864*67e74705SXin Li case Stmt::OMPCriticalDirectiveClass:
1865*67e74705SXin Li return cast<OMPCriticalDirective>(S)->getDirectiveName();
1866*67e74705SXin Li }
1867*67e74705SXin Li }
1868*67e74705SXin Li };
1869*67e74705SXin Li class MemberRefVisit : public VisitorJob {
1870*67e74705SXin Li public:
MemberRefVisit(const FieldDecl * D,SourceLocation L,CXCursor parent)1871*67e74705SXin Li MemberRefVisit(const FieldDecl *D, SourceLocation L, CXCursor parent)
1872*67e74705SXin Li : VisitorJob(parent, VisitorJob::MemberRefVisitKind, D,
1873*67e74705SXin Li L.getPtrEncoding()) {}
classof(const VisitorJob * VJ)1874*67e74705SXin Li static bool classof(const VisitorJob *VJ) {
1875*67e74705SXin Li return VJ->getKind() == VisitorJob::MemberRefVisitKind;
1876*67e74705SXin Li }
get() const1877*67e74705SXin Li const FieldDecl *get() const {
1878*67e74705SXin Li return static_cast<const FieldDecl *>(data[0]);
1879*67e74705SXin Li }
getLoc() const1880*67e74705SXin Li SourceLocation getLoc() const {
1881*67e74705SXin Li return SourceLocation::getFromRawEncoding((unsigned)(uintptr_t) data[1]);
1882*67e74705SXin Li }
1883*67e74705SXin Li };
1884*67e74705SXin Li class EnqueueVisitor : public ConstStmtVisitor<EnqueueVisitor, void> {
1885*67e74705SXin Li friend class OMPClauseEnqueue;
1886*67e74705SXin Li VisitorWorkList &WL;
1887*67e74705SXin Li CXCursor Parent;
1888*67e74705SXin Li public:
EnqueueVisitor(VisitorWorkList & wl,CXCursor parent)1889*67e74705SXin Li EnqueueVisitor(VisitorWorkList &wl, CXCursor parent)
1890*67e74705SXin Li : WL(wl), Parent(parent) {}
1891*67e74705SXin Li
1892*67e74705SXin Li void VisitAddrLabelExpr(const AddrLabelExpr *E);
1893*67e74705SXin Li void VisitBlockExpr(const BlockExpr *B);
1894*67e74705SXin Li void VisitCompoundLiteralExpr(const CompoundLiteralExpr *E);
1895*67e74705SXin Li void VisitCompoundStmt(const CompoundStmt *S);
VisitCXXDefaultArgExpr(const CXXDefaultArgExpr * E)1896*67e74705SXin Li void VisitCXXDefaultArgExpr(const CXXDefaultArgExpr *E) { /* Do nothing. */ }
1897*67e74705SXin Li void VisitMSDependentExistsStmt(const MSDependentExistsStmt *S);
1898*67e74705SXin Li void VisitCXXDependentScopeMemberExpr(const CXXDependentScopeMemberExpr *E);
1899*67e74705SXin Li void VisitCXXNewExpr(const CXXNewExpr *E);
1900*67e74705SXin Li void VisitCXXScalarValueInitExpr(const CXXScalarValueInitExpr *E);
1901*67e74705SXin Li void VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *E);
1902*67e74705SXin Li void VisitCXXPseudoDestructorExpr(const CXXPseudoDestructorExpr *E);
1903*67e74705SXin Li void VisitCXXTemporaryObjectExpr(const CXXTemporaryObjectExpr *E);
1904*67e74705SXin Li void VisitCXXTypeidExpr(const CXXTypeidExpr *E);
1905*67e74705SXin Li void VisitCXXUnresolvedConstructExpr(const CXXUnresolvedConstructExpr *E);
1906*67e74705SXin Li void VisitCXXUuidofExpr(const CXXUuidofExpr *E);
1907*67e74705SXin Li void VisitCXXCatchStmt(const CXXCatchStmt *S);
1908*67e74705SXin Li void VisitCXXForRangeStmt(const CXXForRangeStmt *S);
1909*67e74705SXin Li void VisitDeclRefExpr(const DeclRefExpr *D);
1910*67e74705SXin Li void VisitDeclStmt(const DeclStmt *S);
1911*67e74705SXin Li void VisitDependentScopeDeclRefExpr(const DependentScopeDeclRefExpr *E);
1912*67e74705SXin Li void VisitDesignatedInitExpr(const DesignatedInitExpr *E);
1913*67e74705SXin Li void VisitExplicitCastExpr(const ExplicitCastExpr *E);
1914*67e74705SXin Li void VisitForStmt(const ForStmt *FS);
1915*67e74705SXin Li void VisitGotoStmt(const GotoStmt *GS);
1916*67e74705SXin Li void VisitIfStmt(const IfStmt *If);
1917*67e74705SXin Li void VisitInitListExpr(const InitListExpr *IE);
1918*67e74705SXin Li void VisitMemberExpr(const MemberExpr *M);
1919*67e74705SXin Li void VisitOffsetOfExpr(const OffsetOfExpr *E);
1920*67e74705SXin Li void VisitObjCEncodeExpr(const ObjCEncodeExpr *E);
1921*67e74705SXin Li void VisitObjCMessageExpr(const ObjCMessageExpr *M);
1922*67e74705SXin Li void VisitOverloadExpr(const OverloadExpr *E);
1923*67e74705SXin Li void VisitUnaryExprOrTypeTraitExpr(const UnaryExprOrTypeTraitExpr *E);
1924*67e74705SXin Li void VisitStmt(const Stmt *S);
1925*67e74705SXin Li void VisitSwitchStmt(const SwitchStmt *S);
1926*67e74705SXin Li void VisitWhileStmt(const WhileStmt *W);
1927*67e74705SXin Li void VisitTypeTraitExpr(const TypeTraitExpr *E);
1928*67e74705SXin Li void VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *E);
1929*67e74705SXin Li void VisitExpressionTraitExpr(const ExpressionTraitExpr *E);
1930*67e74705SXin Li void VisitUnresolvedMemberExpr(const UnresolvedMemberExpr *U);
1931*67e74705SXin Li void VisitVAArgExpr(const VAArgExpr *E);
1932*67e74705SXin Li void VisitSizeOfPackExpr(const SizeOfPackExpr *E);
1933*67e74705SXin Li void VisitPseudoObjectExpr(const PseudoObjectExpr *E);
1934*67e74705SXin Li void VisitOpaqueValueExpr(const OpaqueValueExpr *E);
1935*67e74705SXin Li void VisitLambdaExpr(const LambdaExpr *E);
1936*67e74705SXin Li void VisitOMPExecutableDirective(const OMPExecutableDirective *D);
1937*67e74705SXin Li void VisitOMPLoopDirective(const OMPLoopDirective *D);
1938*67e74705SXin Li void VisitOMPParallelDirective(const OMPParallelDirective *D);
1939*67e74705SXin Li void VisitOMPSimdDirective(const OMPSimdDirective *D);
1940*67e74705SXin Li void VisitOMPForDirective(const OMPForDirective *D);
1941*67e74705SXin Li void VisitOMPForSimdDirective(const OMPForSimdDirective *D);
1942*67e74705SXin Li void VisitOMPSectionsDirective(const OMPSectionsDirective *D);
1943*67e74705SXin Li void VisitOMPSectionDirective(const OMPSectionDirective *D);
1944*67e74705SXin Li void VisitOMPSingleDirective(const OMPSingleDirective *D);
1945*67e74705SXin Li void VisitOMPMasterDirective(const OMPMasterDirective *D);
1946*67e74705SXin Li void VisitOMPCriticalDirective(const OMPCriticalDirective *D);
1947*67e74705SXin Li void VisitOMPParallelForDirective(const OMPParallelForDirective *D);
1948*67e74705SXin Li void VisitOMPParallelForSimdDirective(const OMPParallelForSimdDirective *D);
1949*67e74705SXin Li void VisitOMPParallelSectionsDirective(const OMPParallelSectionsDirective *D);
1950*67e74705SXin Li void VisitOMPTaskDirective(const OMPTaskDirective *D);
1951*67e74705SXin Li void VisitOMPTaskyieldDirective(const OMPTaskyieldDirective *D);
1952*67e74705SXin Li void VisitOMPBarrierDirective(const OMPBarrierDirective *D);
1953*67e74705SXin Li void VisitOMPTaskwaitDirective(const OMPTaskwaitDirective *D);
1954*67e74705SXin Li void VisitOMPTaskgroupDirective(const OMPTaskgroupDirective *D);
1955*67e74705SXin Li void
1956*67e74705SXin Li VisitOMPCancellationPointDirective(const OMPCancellationPointDirective *D);
1957*67e74705SXin Li void VisitOMPCancelDirective(const OMPCancelDirective *D);
1958*67e74705SXin Li void VisitOMPFlushDirective(const OMPFlushDirective *D);
1959*67e74705SXin Li void VisitOMPOrderedDirective(const OMPOrderedDirective *D);
1960*67e74705SXin Li void VisitOMPAtomicDirective(const OMPAtomicDirective *D);
1961*67e74705SXin Li void VisitOMPTargetDirective(const OMPTargetDirective *D);
1962*67e74705SXin Li void VisitOMPTargetDataDirective(const OMPTargetDataDirective *D);
1963*67e74705SXin Li void VisitOMPTargetEnterDataDirective(const OMPTargetEnterDataDirective *D);
1964*67e74705SXin Li void VisitOMPTargetExitDataDirective(const OMPTargetExitDataDirective *D);
1965*67e74705SXin Li void VisitOMPTargetParallelDirective(const OMPTargetParallelDirective *D);
1966*67e74705SXin Li void
1967*67e74705SXin Li VisitOMPTargetParallelForDirective(const OMPTargetParallelForDirective *D);
1968*67e74705SXin Li void VisitOMPTeamsDirective(const OMPTeamsDirective *D);
1969*67e74705SXin Li void VisitOMPTaskLoopDirective(const OMPTaskLoopDirective *D);
1970*67e74705SXin Li void VisitOMPTaskLoopSimdDirective(const OMPTaskLoopSimdDirective *D);
1971*67e74705SXin Li void VisitOMPDistributeDirective(const OMPDistributeDirective *D);
1972*67e74705SXin Li void VisitOMPDistributeParallelForDirective(
1973*67e74705SXin Li const OMPDistributeParallelForDirective *D);
1974*67e74705SXin Li void VisitOMPDistributeParallelForSimdDirective(
1975*67e74705SXin Li const OMPDistributeParallelForSimdDirective *D);
1976*67e74705SXin Li void VisitOMPDistributeSimdDirective(const OMPDistributeSimdDirective *D);
1977*67e74705SXin Li void VisitOMPTargetParallelForSimdDirective(
1978*67e74705SXin Li const OMPTargetParallelForSimdDirective *D);
1979*67e74705SXin Li
1980*67e74705SXin Li private:
1981*67e74705SXin Li void AddDeclarationNameInfo(const Stmt *S);
1982*67e74705SXin Li void AddNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier);
1983*67e74705SXin Li void AddExplicitTemplateArgs(const TemplateArgumentLoc *A,
1984*67e74705SXin Li unsigned NumTemplateArgs);
1985*67e74705SXin Li void AddMemberRef(const FieldDecl *D, SourceLocation L);
1986*67e74705SXin Li void AddStmt(const Stmt *S);
1987*67e74705SXin Li void AddDecl(const Decl *D, bool isFirst = true);
1988*67e74705SXin Li void AddTypeLoc(TypeSourceInfo *TI);
1989*67e74705SXin Li void EnqueueChildren(const Stmt *S);
1990*67e74705SXin Li void EnqueueChildren(const OMPClause *S);
1991*67e74705SXin Li };
1992*67e74705SXin Li } // end anonyous namespace
1993*67e74705SXin Li
AddDeclarationNameInfo(const Stmt * S)1994*67e74705SXin Li void EnqueueVisitor::AddDeclarationNameInfo(const Stmt *S) {
1995*67e74705SXin Li // 'S' should always be non-null, since it comes from the
1996*67e74705SXin Li // statement we are visiting.
1997*67e74705SXin Li WL.push_back(DeclarationNameInfoVisit(S, Parent));
1998*67e74705SXin Li }
1999*67e74705SXin Li
2000*67e74705SXin Li void
AddNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier)2001*67e74705SXin Li EnqueueVisitor::AddNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier) {
2002*67e74705SXin Li if (Qualifier)
2003*67e74705SXin Li WL.push_back(NestedNameSpecifierLocVisit(Qualifier, Parent));
2004*67e74705SXin Li }
2005*67e74705SXin Li
AddStmt(const Stmt * S)2006*67e74705SXin Li void EnqueueVisitor::AddStmt(const Stmt *S) {
2007*67e74705SXin Li if (S)
2008*67e74705SXin Li WL.push_back(StmtVisit(S, Parent));
2009*67e74705SXin Li }
AddDecl(const Decl * D,bool isFirst)2010*67e74705SXin Li void EnqueueVisitor::AddDecl(const Decl *D, bool isFirst) {
2011*67e74705SXin Li if (D)
2012*67e74705SXin Li WL.push_back(DeclVisit(D, Parent, isFirst));
2013*67e74705SXin Li }
AddExplicitTemplateArgs(const TemplateArgumentLoc * A,unsigned NumTemplateArgs)2014*67e74705SXin Li void EnqueueVisitor::AddExplicitTemplateArgs(const TemplateArgumentLoc *A,
2015*67e74705SXin Li unsigned NumTemplateArgs) {
2016*67e74705SXin Li WL.push_back(ExplicitTemplateArgsVisit(A, A + NumTemplateArgs, Parent));
2017*67e74705SXin Li }
AddMemberRef(const FieldDecl * D,SourceLocation L)2018*67e74705SXin Li void EnqueueVisitor::AddMemberRef(const FieldDecl *D, SourceLocation L) {
2019*67e74705SXin Li if (D)
2020*67e74705SXin Li WL.push_back(MemberRefVisit(D, L, Parent));
2021*67e74705SXin Li }
AddTypeLoc(TypeSourceInfo * TI)2022*67e74705SXin Li void EnqueueVisitor::AddTypeLoc(TypeSourceInfo *TI) {
2023*67e74705SXin Li if (TI)
2024*67e74705SXin Li WL.push_back(TypeLocVisit(TI->getTypeLoc(), Parent));
2025*67e74705SXin Li }
EnqueueChildren(const Stmt * S)2026*67e74705SXin Li void EnqueueVisitor::EnqueueChildren(const Stmt *S) {
2027*67e74705SXin Li unsigned size = WL.size();
2028*67e74705SXin Li for (const Stmt *SubStmt : S->children()) {
2029*67e74705SXin Li AddStmt(SubStmt);
2030*67e74705SXin Li }
2031*67e74705SXin Li if (size == WL.size())
2032*67e74705SXin Li return;
2033*67e74705SXin Li // Now reverse the entries we just added. This will match the DFS
2034*67e74705SXin Li // ordering performed by the worklist.
2035*67e74705SXin Li VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
2036*67e74705SXin Li std::reverse(I, E);
2037*67e74705SXin Li }
2038*67e74705SXin Li namespace {
2039*67e74705SXin Li class OMPClauseEnqueue : public ConstOMPClauseVisitor<OMPClauseEnqueue> {
2040*67e74705SXin Li EnqueueVisitor *Visitor;
2041*67e74705SXin Li /// \brief Process clauses with list of variables.
2042*67e74705SXin Li template <typename T>
2043*67e74705SXin Li void VisitOMPClauseList(T *Node);
2044*67e74705SXin Li public:
OMPClauseEnqueue(EnqueueVisitor * Visitor)2045*67e74705SXin Li OMPClauseEnqueue(EnqueueVisitor *Visitor) : Visitor(Visitor) { }
2046*67e74705SXin Li #define OPENMP_CLAUSE(Name, Class) \
2047*67e74705SXin Li void Visit##Class(const Class *C);
2048*67e74705SXin Li #include "clang/Basic/OpenMPKinds.def"
2049*67e74705SXin Li void VisitOMPClauseWithPreInit(const OMPClauseWithPreInit *C);
2050*67e74705SXin Li void VisitOMPClauseWithPostUpdate(const OMPClauseWithPostUpdate *C);
2051*67e74705SXin Li };
2052*67e74705SXin Li
VisitOMPClauseWithPreInit(const OMPClauseWithPreInit * C)2053*67e74705SXin Li void OMPClauseEnqueue::VisitOMPClauseWithPreInit(
2054*67e74705SXin Li const OMPClauseWithPreInit *C) {
2055*67e74705SXin Li Visitor->AddStmt(C->getPreInitStmt());
2056*67e74705SXin Li }
2057*67e74705SXin Li
VisitOMPClauseWithPostUpdate(const OMPClauseWithPostUpdate * C)2058*67e74705SXin Li void OMPClauseEnqueue::VisitOMPClauseWithPostUpdate(
2059*67e74705SXin Li const OMPClauseWithPostUpdate *C) {
2060*67e74705SXin Li VisitOMPClauseWithPreInit(C);
2061*67e74705SXin Li Visitor->AddStmt(C->getPostUpdateExpr());
2062*67e74705SXin Li }
2063*67e74705SXin Li
VisitOMPIfClause(const OMPIfClause * C)2064*67e74705SXin Li void OMPClauseEnqueue::VisitOMPIfClause(const OMPIfClause *C) {
2065*67e74705SXin Li Visitor->AddStmt(C->getCondition());
2066*67e74705SXin Li }
2067*67e74705SXin Li
VisitOMPFinalClause(const OMPFinalClause * C)2068*67e74705SXin Li void OMPClauseEnqueue::VisitOMPFinalClause(const OMPFinalClause *C) {
2069*67e74705SXin Li Visitor->AddStmt(C->getCondition());
2070*67e74705SXin Li }
2071*67e74705SXin Li
VisitOMPNumThreadsClause(const OMPNumThreadsClause * C)2072*67e74705SXin Li void OMPClauseEnqueue::VisitOMPNumThreadsClause(const OMPNumThreadsClause *C) {
2073*67e74705SXin Li Visitor->AddStmt(C->getNumThreads());
2074*67e74705SXin Li }
2075*67e74705SXin Li
VisitOMPSafelenClause(const OMPSafelenClause * C)2076*67e74705SXin Li void OMPClauseEnqueue::VisitOMPSafelenClause(const OMPSafelenClause *C) {
2077*67e74705SXin Li Visitor->AddStmt(C->getSafelen());
2078*67e74705SXin Li }
2079*67e74705SXin Li
VisitOMPSimdlenClause(const OMPSimdlenClause * C)2080*67e74705SXin Li void OMPClauseEnqueue::VisitOMPSimdlenClause(const OMPSimdlenClause *C) {
2081*67e74705SXin Li Visitor->AddStmt(C->getSimdlen());
2082*67e74705SXin Li }
2083*67e74705SXin Li
VisitOMPCollapseClause(const OMPCollapseClause * C)2084*67e74705SXin Li void OMPClauseEnqueue::VisitOMPCollapseClause(const OMPCollapseClause *C) {
2085*67e74705SXin Li Visitor->AddStmt(C->getNumForLoops());
2086*67e74705SXin Li }
2087*67e74705SXin Li
VisitOMPDefaultClause(const OMPDefaultClause * C)2088*67e74705SXin Li void OMPClauseEnqueue::VisitOMPDefaultClause(const OMPDefaultClause *C) { }
2089*67e74705SXin Li
VisitOMPProcBindClause(const OMPProcBindClause * C)2090*67e74705SXin Li void OMPClauseEnqueue::VisitOMPProcBindClause(const OMPProcBindClause *C) { }
2091*67e74705SXin Li
VisitOMPScheduleClause(const OMPScheduleClause * C)2092*67e74705SXin Li void OMPClauseEnqueue::VisitOMPScheduleClause(const OMPScheduleClause *C) {
2093*67e74705SXin Li VisitOMPClauseWithPreInit(C);
2094*67e74705SXin Li Visitor->AddStmt(C->getChunkSize());
2095*67e74705SXin Li }
2096*67e74705SXin Li
VisitOMPOrderedClause(const OMPOrderedClause * C)2097*67e74705SXin Li void OMPClauseEnqueue::VisitOMPOrderedClause(const OMPOrderedClause *C) {
2098*67e74705SXin Li Visitor->AddStmt(C->getNumForLoops());
2099*67e74705SXin Li }
2100*67e74705SXin Li
VisitOMPNowaitClause(const OMPNowaitClause *)2101*67e74705SXin Li void OMPClauseEnqueue::VisitOMPNowaitClause(const OMPNowaitClause *) {}
2102*67e74705SXin Li
VisitOMPUntiedClause(const OMPUntiedClause *)2103*67e74705SXin Li void OMPClauseEnqueue::VisitOMPUntiedClause(const OMPUntiedClause *) {}
2104*67e74705SXin Li
VisitOMPMergeableClause(const OMPMergeableClause *)2105*67e74705SXin Li void OMPClauseEnqueue::VisitOMPMergeableClause(const OMPMergeableClause *) {}
2106*67e74705SXin Li
VisitOMPReadClause(const OMPReadClause *)2107*67e74705SXin Li void OMPClauseEnqueue::VisitOMPReadClause(const OMPReadClause *) {}
2108*67e74705SXin Li
VisitOMPWriteClause(const OMPWriteClause *)2109*67e74705SXin Li void OMPClauseEnqueue::VisitOMPWriteClause(const OMPWriteClause *) {}
2110*67e74705SXin Li
VisitOMPUpdateClause(const OMPUpdateClause *)2111*67e74705SXin Li void OMPClauseEnqueue::VisitOMPUpdateClause(const OMPUpdateClause *) {}
2112*67e74705SXin Li
VisitOMPCaptureClause(const OMPCaptureClause *)2113*67e74705SXin Li void OMPClauseEnqueue::VisitOMPCaptureClause(const OMPCaptureClause *) {}
2114*67e74705SXin Li
VisitOMPSeqCstClause(const OMPSeqCstClause *)2115*67e74705SXin Li void OMPClauseEnqueue::VisitOMPSeqCstClause(const OMPSeqCstClause *) {}
2116*67e74705SXin Li
VisitOMPThreadsClause(const OMPThreadsClause *)2117*67e74705SXin Li void OMPClauseEnqueue::VisitOMPThreadsClause(const OMPThreadsClause *) {}
2118*67e74705SXin Li
VisitOMPSIMDClause(const OMPSIMDClause *)2119*67e74705SXin Li void OMPClauseEnqueue::VisitOMPSIMDClause(const OMPSIMDClause *) {}
2120*67e74705SXin Li
VisitOMPNogroupClause(const OMPNogroupClause *)2121*67e74705SXin Li void OMPClauseEnqueue::VisitOMPNogroupClause(const OMPNogroupClause *) {}
2122*67e74705SXin Li
VisitOMPDeviceClause(const OMPDeviceClause * C)2123*67e74705SXin Li void OMPClauseEnqueue::VisitOMPDeviceClause(const OMPDeviceClause *C) {
2124*67e74705SXin Li Visitor->AddStmt(C->getDevice());
2125*67e74705SXin Li }
2126*67e74705SXin Li
VisitOMPNumTeamsClause(const OMPNumTeamsClause * C)2127*67e74705SXin Li void OMPClauseEnqueue::VisitOMPNumTeamsClause(const OMPNumTeamsClause *C) {
2128*67e74705SXin Li Visitor->AddStmt(C->getNumTeams());
2129*67e74705SXin Li }
2130*67e74705SXin Li
VisitOMPThreadLimitClause(const OMPThreadLimitClause * C)2131*67e74705SXin Li void OMPClauseEnqueue::VisitOMPThreadLimitClause(const OMPThreadLimitClause *C) {
2132*67e74705SXin Li Visitor->AddStmt(C->getThreadLimit());
2133*67e74705SXin Li }
2134*67e74705SXin Li
VisitOMPPriorityClause(const OMPPriorityClause * C)2135*67e74705SXin Li void OMPClauseEnqueue::VisitOMPPriorityClause(const OMPPriorityClause *C) {
2136*67e74705SXin Li Visitor->AddStmt(C->getPriority());
2137*67e74705SXin Li }
2138*67e74705SXin Li
VisitOMPGrainsizeClause(const OMPGrainsizeClause * C)2139*67e74705SXin Li void OMPClauseEnqueue::VisitOMPGrainsizeClause(const OMPGrainsizeClause *C) {
2140*67e74705SXin Li Visitor->AddStmt(C->getGrainsize());
2141*67e74705SXin Li }
2142*67e74705SXin Li
VisitOMPNumTasksClause(const OMPNumTasksClause * C)2143*67e74705SXin Li void OMPClauseEnqueue::VisitOMPNumTasksClause(const OMPNumTasksClause *C) {
2144*67e74705SXin Li Visitor->AddStmt(C->getNumTasks());
2145*67e74705SXin Li }
2146*67e74705SXin Li
VisitOMPHintClause(const OMPHintClause * C)2147*67e74705SXin Li void OMPClauseEnqueue::VisitOMPHintClause(const OMPHintClause *C) {
2148*67e74705SXin Li Visitor->AddStmt(C->getHint());
2149*67e74705SXin Li }
2150*67e74705SXin Li
2151*67e74705SXin Li template<typename T>
VisitOMPClauseList(T * Node)2152*67e74705SXin Li void OMPClauseEnqueue::VisitOMPClauseList(T *Node) {
2153*67e74705SXin Li for (const auto *I : Node->varlists()) {
2154*67e74705SXin Li Visitor->AddStmt(I);
2155*67e74705SXin Li }
2156*67e74705SXin Li }
2157*67e74705SXin Li
VisitOMPPrivateClause(const OMPPrivateClause * C)2158*67e74705SXin Li void OMPClauseEnqueue::VisitOMPPrivateClause(const OMPPrivateClause *C) {
2159*67e74705SXin Li VisitOMPClauseList(C);
2160*67e74705SXin Li for (const auto *E : C->private_copies()) {
2161*67e74705SXin Li Visitor->AddStmt(E);
2162*67e74705SXin Li }
2163*67e74705SXin Li }
VisitOMPFirstprivateClause(const OMPFirstprivateClause * C)2164*67e74705SXin Li void OMPClauseEnqueue::VisitOMPFirstprivateClause(
2165*67e74705SXin Li const OMPFirstprivateClause *C) {
2166*67e74705SXin Li VisitOMPClauseList(C);
2167*67e74705SXin Li VisitOMPClauseWithPreInit(C);
2168*67e74705SXin Li for (const auto *E : C->private_copies()) {
2169*67e74705SXin Li Visitor->AddStmt(E);
2170*67e74705SXin Li }
2171*67e74705SXin Li for (const auto *E : C->inits()) {
2172*67e74705SXin Li Visitor->AddStmt(E);
2173*67e74705SXin Li }
2174*67e74705SXin Li }
VisitOMPLastprivateClause(const OMPLastprivateClause * C)2175*67e74705SXin Li void OMPClauseEnqueue::VisitOMPLastprivateClause(
2176*67e74705SXin Li const OMPLastprivateClause *C) {
2177*67e74705SXin Li VisitOMPClauseList(C);
2178*67e74705SXin Li VisitOMPClauseWithPostUpdate(C);
2179*67e74705SXin Li for (auto *E : C->private_copies()) {
2180*67e74705SXin Li Visitor->AddStmt(E);
2181*67e74705SXin Li }
2182*67e74705SXin Li for (auto *E : C->source_exprs()) {
2183*67e74705SXin Li Visitor->AddStmt(E);
2184*67e74705SXin Li }
2185*67e74705SXin Li for (auto *E : C->destination_exprs()) {
2186*67e74705SXin Li Visitor->AddStmt(E);
2187*67e74705SXin Li }
2188*67e74705SXin Li for (auto *E : C->assignment_ops()) {
2189*67e74705SXin Li Visitor->AddStmt(E);
2190*67e74705SXin Li }
2191*67e74705SXin Li }
VisitOMPSharedClause(const OMPSharedClause * C)2192*67e74705SXin Li void OMPClauseEnqueue::VisitOMPSharedClause(const OMPSharedClause *C) {
2193*67e74705SXin Li VisitOMPClauseList(C);
2194*67e74705SXin Li }
VisitOMPReductionClause(const OMPReductionClause * C)2195*67e74705SXin Li void OMPClauseEnqueue::VisitOMPReductionClause(const OMPReductionClause *C) {
2196*67e74705SXin Li VisitOMPClauseList(C);
2197*67e74705SXin Li VisitOMPClauseWithPostUpdate(C);
2198*67e74705SXin Li for (auto *E : C->privates()) {
2199*67e74705SXin Li Visitor->AddStmt(E);
2200*67e74705SXin Li }
2201*67e74705SXin Li for (auto *E : C->lhs_exprs()) {
2202*67e74705SXin Li Visitor->AddStmt(E);
2203*67e74705SXin Li }
2204*67e74705SXin Li for (auto *E : C->rhs_exprs()) {
2205*67e74705SXin Li Visitor->AddStmt(E);
2206*67e74705SXin Li }
2207*67e74705SXin Li for (auto *E : C->reduction_ops()) {
2208*67e74705SXin Li Visitor->AddStmt(E);
2209*67e74705SXin Li }
2210*67e74705SXin Li }
VisitOMPLinearClause(const OMPLinearClause * C)2211*67e74705SXin Li void OMPClauseEnqueue::VisitOMPLinearClause(const OMPLinearClause *C) {
2212*67e74705SXin Li VisitOMPClauseList(C);
2213*67e74705SXin Li VisitOMPClauseWithPostUpdate(C);
2214*67e74705SXin Li for (const auto *E : C->privates()) {
2215*67e74705SXin Li Visitor->AddStmt(E);
2216*67e74705SXin Li }
2217*67e74705SXin Li for (const auto *E : C->inits()) {
2218*67e74705SXin Li Visitor->AddStmt(E);
2219*67e74705SXin Li }
2220*67e74705SXin Li for (const auto *E : C->updates()) {
2221*67e74705SXin Li Visitor->AddStmt(E);
2222*67e74705SXin Li }
2223*67e74705SXin Li for (const auto *E : C->finals()) {
2224*67e74705SXin Li Visitor->AddStmt(E);
2225*67e74705SXin Li }
2226*67e74705SXin Li Visitor->AddStmt(C->getStep());
2227*67e74705SXin Li Visitor->AddStmt(C->getCalcStep());
2228*67e74705SXin Li }
VisitOMPAlignedClause(const OMPAlignedClause * C)2229*67e74705SXin Li void OMPClauseEnqueue::VisitOMPAlignedClause(const OMPAlignedClause *C) {
2230*67e74705SXin Li VisitOMPClauseList(C);
2231*67e74705SXin Li Visitor->AddStmt(C->getAlignment());
2232*67e74705SXin Li }
VisitOMPCopyinClause(const OMPCopyinClause * C)2233*67e74705SXin Li void OMPClauseEnqueue::VisitOMPCopyinClause(const OMPCopyinClause *C) {
2234*67e74705SXin Li VisitOMPClauseList(C);
2235*67e74705SXin Li for (auto *E : C->source_exprs()) {
2236*67e74705SXin Li Visitor->AddStmt(E);
2237*67e74705SXin Li }
2238*67e74705SXin Li for (auto *E : C->destination_exprs()) {
2239*67e74705SXin Li Visitor->AddStmt(E);
2240*67e74705SXin Li }
2241*67e74705SXin Li for (auto *E : C->assignment_ops()) {
2242*67e74705SXin Li Visitor->AddStmt(E);
2243*67e74705SXin Li }
2244*67e74705SXin Li }
2245*67e74705SXin Li void
VisitOMPCopyprivateClause(const OMPCopyprivateClause * C)2246*67e74705SXin Li OMPClauseEnqueue::VisitOMPCopyprivateClause(const OMPCopyprivateClause *C) {
2247*67e74705SXin Li VisitOMPClauseList(C);
2248*67e74705SXin Li for (auto *E : C->source_exprs()) {
2249*67e74705SXin Li Visitor->AddStmt(E);
2250*67e74705SXin Li }
2251*67e74705SXin Li for (auto *E : C->destination_exprs()) {
2252*67e74705SXin Li Visitor->AddStmt(E);
2253*67e74705SXin Li }
2254*67e74705SXin Li for (auto *E : C->assignment_ops()) {
2255*67e74705SXin Li Visitor->AddStmt(E);
2256*67e74705SXin Li }
2257*67e74705SXin Li }
VisitOMPFlushClause(const OMPFlushClause * C)2258*67e74705SXin Li void OMPClauseEnqueue::VisitOMPFlushClause(const OMPFlushClause *C) {
2259*67e74705SXin Li VisitOMPClauseList(C);
2260*67e74705SXin Li }
VisitOMPDependClause(const OMPDependClause * C)2261*67e74705SXin Li void OMPClauseEnqueue::VisitOMPDependClause(const OMPDependClause *C) {
2262*67e74705SXin Li VisitOMPClauseList(C);
2263*67e74705SXin Li }
VisitOMPMapClause(const OMPMapClause * C)2264*67e74705SXin Li void OMPClauseEnqueue::VisitOMPMapClause(const OMPMapClause *C) {
2265*67e74705SXin Li VisitOMPClauseList(C);
2266*67e74705SXin Li }
VisitOMPDistScheduleClause(const OMPDistScheduleClause * C)2267*67e74705SXin Li void OMPClauseEnqueue::VisitOMPDistScheduleClause(
2268*67e74705SXin Li const OMPDistScheduleClause *C) {
2269*67e74705SXin Li VisitOMPClauseWithPreInit(C);
2270*67e74705SXin Li Visitor->AddStmt(C->getChunkSize());
2271*67e74705SXin Li }
VisitOMPDefaultmapClause(const OMPDefaultmapClause *)2272*67e74705SXin Li void OMPClauseEnqueue::VisitOMPDefaultmapClause(
2273*67e74705SXin Li const OMPDefaultmapClause * /*C*/) {}
VisitOMPToClause(const OMPToClause * C)2274*67e74705SXin Li void OMPClauseEnqueue::VisitOMPToClause(const OMPToClause *C) {
2275*67e74705SXin Li VisitOMPClauseList(C);
2276*67e74705SXin Li }
VisitOMPFromClause(const OMPFromClause * C)2277*67e74705SXin Li void OMPClauseEnqueue::VisitOMPFromClause(const OMPFromClause *C) {
2278*67e74705SXin Li VisitOMPClauseList(C);
2279*67e74705SXin Li }
VisitOMPUseDevicePtrClause(const OMPUseDevicePtrClause * C)2280*67e74705SXin Li void OMPClauseEnqueue::VisitOMPUseDevicePtrClause(const OMPUseDevicePtrClause *C) {
2281*67e74705SXin Li VisitOMPClauseList(C);
2282*67e74705SXin Li }
VisitOMPIsDevicePtrClause(const OMPIsDevicePtrClause * C)2283*67e74705SXin Li void OMPClauseEnqueue::VisitOMPIsDevicePtrClause(const OMPIsDevicePtrClause *C) {
2284*67e74705SXin Li VisitOMPClauseList(C);
2285*67e74705SXin Li }
2286*67e74705SXin Li }
2287*67e74705SXin Li
EnqueueChildren(const OMPClause * S)2288*67e74705SXin Li void EnqueueVisitor::EnqueueChildren(const OMPClause *S) {
2289*67e74705SXin Li unsigned size = WL.size();
2290*67e74705SXin Li OMPClauseEnqueue Visitor(this);
2291*67e74705SXin Li Visitor.Visit(S);
2292*67e74705SXin Li if (size == WL.size())
2293*67e74705SXin Li return;
2294*67e74705SXin Li // Now reverse the entries we just added. This will match the DFS
2295*67e74705SXin Li // ordering performed by the worklist.
2296*67e74705SXin Li VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
2297*67e74705SXin Li std::reverse(I, E);
2298*67e74705SXin Li }
VisitAddrLabelExpr(const AddrLabelExpr * E)2299*67e74705SXin Li void EnqueueVisitor::VisitAddrLabelExpr(const AddrLabelExpr *E) {
2300*67e74705SXin Li WL.push_back(LabelRefVisit(E->getLabel(), E->getLabelLoc(), Parent));
2301*67e74705SXin Li }
VisitBlockExpr(const BlockExpr * B)2302*67e74705SXin Li void EnqueueVisitor::VisitBlockExpr(const BlockExpr *B) {
2303*67e74705SXin Li AddDecl(B->getBlockDecl());
2304*67e74705SXin Li }
VisitCompoundLiteralExpr(const CompoundLiteralExpr * E)2305*67e74705SXin Li void EnqueueVisitor::VisitCompoundLiteralExpr(const CompoundLiteralExpr *E) {
2306*67e74705SXin Li EnqueueChildren(E);
2307*67e74705SXin Li AddTypeLoc(E->getTypeSourceInfo());
2308*67e74705SXin Li }
VisitCompoundStmt(const CompoundStmt * S)2309*67e74705SXin Li void EnqueueVisitor::VisitCompoundStmt(const CompoundStmt *S) {
2310*67e74705SXin Li for (auto &I : llvm::reverse(S->body()))
2311*67e74705SXin Li AddStmt(I);
2312*67e74705SXin Li }
2313*67e74705SXin Li void EnqueueVisitor::
VisitMSDependentExistsStmt(const MSDependentExistsStmt * S)2314*67e74705SXin Li VisitMSDependentExistsStmt(const MSDependentExistsStmt *S) {
2315*67e74705SXin Li AddStmt(S->getSubStmt());
2316*67e74705SXin Li AddDeclarationNameInfo(S);
2317*67e74705SXin Li if (NestedNameSpecifierLoc QualifierLoc = S->getQualifierLoc())
2318*67e74705SXin Li AddNestedNameSpecifierLoc(QualifierLoc);
2319*67e74705SXin Li }
2320*67e74705SXin Li
2321*67e74705SXin Li void EnqueueVisitor::
VisitCXXDependentScopeMemberExpr(const CXXDependentScopeMemberExpr * E)2322*67e74705SXin Li VisitCXXDependentScopeMemberExpr(const CXXDependentScopeMemberExpr *E) {
2323*67e74705SXin Li if (E->hasExplicitTemplateArgs())
2324*67e74705SXin Li AddExplicitTemplateArgs(E->getTemplateArgs(), E->getNumTemplateArgs());
2325*67e74705SXin Li AddDeclarationNameInfo(E);
2326*67e74705SXin Li if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
2327*67e74705SXin Li AddNestedNameSpecifierLoc(QualifierLoc);
2328*67e74705SXin Li if (!E->isImplicitAccess())
2329*67e74705SXin Li AddStmt(E->getBase());
2330*67e74705SXin Li }
VisitCXXNewExpr(const CXXNewExpr * E)2331*67e74705SXin Li void EnqueueVisitor::VisitCXXNewExpr(const CXXNewExpr *E) {
2332*67e74705SXin Li // Enqueue the initializer , if any.
2333*67e74705SXin Li AddStmt(E->getInitializer());
2334*67e74705SXin Li // Enqueue the array size, if any.
2335*67e74705SXin Li AddStmt(E->getArraySize());
2336*67e74705SXin Li // Enqueue the allocated type.
2337*67e74705SXin Li AddTypeLoc(E->getAllocatedTypeSourceInfo());
2338*67e74705SXin Li // Enqueue the placement arguments.
2339*67e74705SXin Li for (unsigned I = E->getNumPlacementArgs(); I > 0; --I)
2340*67e74705SXin Li AddStmt(E->getPlacementArg(I-1));
2341*67e74705SXin Li }
VisitCXXOperatorCallExpr(const CXXOperatorCallExpr * CE)2342*67e74705SXin Li void EnqueueVisitor::VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *CE) {
2343*67e74705SXin Li for (unsigned I = CE->getNumArgs(); I > 1 /* Yes, this is 1 */; --I)
2344*67e74705SXin Li AddStmt(CE->getArg(I-1));
2345*67e74705SXin Li AddStmt(CE->getCallee());
2346*67e74705SXin Li AddStmt(CE->getArg(0));
2347*67e74705SXin Li }
VisitCXXPseudoDestructorExpr(const CXXPseudoDestructorExpr * E)2348*67e74705SXin Li void EnqueueVisitor::VisitCXXPseudoDestructorExpr(
2349*67e74705SXin Li const CXXPseudoDestructorExpr *E) {
2350*67e74705SXin Li // Visit the name of the type being destroyed.
2351*67e74705SXin Li AddTypeLoc(E->getDestroyedTypeInfo());
2352*67e74705SXin Li // Visit the scope type that looks disturbingly like the nested-name-specifier
2353*67e74705SXin Li // but isn't.
2354*67e74705SXin Li AddTypeLoc(E->getScopeTypeInfo());
2355*67e74705SXin Li // Visit the nested-name-specifier.
2356*67e74705SXin Li if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
2357*67e74705SXin Li AddNestedNameSpecifierLoc(QualifierLoc);
2358*67e74705SXin Li // Visit base expression.
2359*67e74705SXin Li AddStmt(E->getBase());
2360*67e74705SXin Li }
VisitCXXScalarValueInitExpr(const CXXScalarValueInitExpr * E)2361*67e74705SXin Li void EnqueueVisitor::VisitCXXScalarValueInitExpr(
2362*67e74705SXin Li const CXXScalarValueInitExpr *E) {
2363*67e74705SXin Li AddTypeLoc(E->getTypeSourceInfo());
2364*67e74705SXin Li }
VisitCXXTemporaryObjectExpr(const CXXTemporaryObjectExpr * E)2365*67e74705SXin Li void EnqueueVisitor::VisitCXXTemporaryObjectExpr(
2366*67e74705SXin Li const CXXTemporaryObjectExpr *E) {
2367*67e74705SXin Li EnqueueChildren(E);
2368*67e74705SXin Li AddTypeLoc(E->getTypeSourceInfo());
2369*67e74705SXin Li }
VisitCXXTypeidExpr(const CXXTypeidExpr * E)2370*67e74705SXin Li void EnqueueVisitor::VisitCXXTypeidExpr(const CXXTypeidExpr *E) {
2371*67e74705SXin Li EnqueueChildren(E);
2372*67e74705SXin Li if (E->isTypeOperand())
2373*67e74705SXin Li AddTypeLoc(E->getTypeOperandSourceInfo());
2374*67e74705SXin Li }
2375*67e74705SXin Li
VisitCXXUnresolvedConstructExpr(const CXXUnresolvedConstructExpr * E)2376*67e74705SXin Li void EnqueueVisitor::VisitCXXUnresolvedConstructExpr(
2377*67e74705SXin Li const CXXUnresolvedConstructExpr *E) {
2378*67e74705SXin Li EnqueueChildren(E);
2379*67e74705SXin Li AddTypeLoc(E->getTypeSourceInfo());
2380*67e74705SXin Li }
VisitCXXUuidofExpr(const CXXUuidofExpr * E)2381*67e74705SXin Li void EnqueueVisitor::VisitCXXUuidofExpr(const CXXUuidofExpr *E) {
2382*67e74705SXin Li EnqueueChildren(E);
2383*67e74705SXin Li if (E->isTypeOperand())
2384*67e74705SXin Li AddTypeLoc(E->getTypeOperandSourceInfo());
2385*67e74705SXin Li }
2386*67e74705SXin Li
VisitCXXCatchStmt(const CXXCatchStmt * S)2387*67e74705SXin Li void EnqueueVisitor::VisitCXXCatchStmt(const CXXCatchStmt *S) {
2388*67e74705SXin Li EnqueueChildren(S);
2389*67e74705SXin Li AddDecl(S->getExceptionDecl());
2390*67e74705SXin Li }
2391*67e74705SXin Li
VisitCXXForRangeStmt(const CXXForRangeStmt * S)2392*67e74705SXin Li void EnqueueVisitor::VisitCXXForRangeStmt(const CXXForRangeStmt *S) {
2393*67e74705SXin Li AddStmt(S->getBody());
2394*67e74705SXin Li AddStmt(S->getRangeInit());
2395*67e74705SXin Li AddDecl(S->getLoopVariable());
2396*67e74705SXin Li }
2397*67e74705SXin Li
VisitDeclRefExpr(const DeclRefExpr * DR)2398*67e74705SXin Li void EnqueueVisitor::VisitDeclRefExpr(const DeclRefExpr *DR) {
2399*67e74705SXin Li if (DR->hasExplicitTemplateArgs())
2400*67e74705SXin Li AddExplicitTemplateArgs(DR->getTemplateArgs(), DR->getNumTemplateArgs());
2401*67e74705SXin Li WL.push_back(DeclRefExprParts(DR, Parent));
2402*67e74705SXin Li }
VisitDependentScopeDeclRefExpr(const DependentScopeDeclRefExpr * E)2403*67e74705SXin Li void EnqueueVisitor::VisitDependentScopeDeclRefExpr(
2404*67e74705SXin Li const DependentScopeDeclRefExpr *E) {
2405*67e74705SXin Li if (E->hasExplicitTemplateArgs())
2406*67e74705SXin Li AddExplicitTemplateArgs(E->getTemplateArgs(), E->getNumTemplateArgs());
2407*67e74705SXin Li AddDeclarationNameInfo(E);
2408*67e74705SXin Li AddNestedNameSpecifierLoc(E->getQualifierLoc());
2409*67e74705SXin Li }
VisitDeclStmt(const DeclStmt * S)2410*67e74705SXin Li void EnqueueVisitor::VisitDeclStmt(const DeclStmt *S) {
2411*67e74705SXin Li unsigned size = WL.size();
2412*67e74705SXin Li bool isFirst = true;
2413*67e74705SXin Li for (const auto *D : S->decls()) {
2414*67e74705SXin Li AddDecl(D, isFirst);
2415*67e74705SXin Li isFirst = false;
2416*67e74705SXin Li }
2417*67e74705SXin Li if (size == WL.size())
2418*67e74705SXin Li return;
2419*67e74705SXin Li // Now reverse the entries we just added. This will match the DFS
2420*67e74705SXin Li // ordering performed by the worklist.
2421*67e74705SXin Li VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
2422*67e74705SXin Li std::reverse(I, E);
2423*67e74705SXin Li }
VisitDesignatedInitExpr(const DesignatedInitExpr * E)2424*67e74705SXin Li void EnqueueVisitor::VisitDesignatedInitExpr(const DesignatedInitExpr *E) {
2425*67e74705SXin Li AddStmt(E->getInit());
2426*67e74705SXin Li for (const DesignatedInitExpr::Designator &D :
2427*67e74705SXin Li llvm::reverse(E->designators())) {
2428*67e74705SXin Li if (D.isFieldDesignator()) {
2429*67e74705SXin Li if (FieldDecl *Field = D.getField())
2430*67e74705SXin Li AddMemberRef(Field, D.getFieldLoc());
2431*67e74705SXin Li continue;
2432*67e74705SXin Li }
2433*67e74705SXin Li if (D.isArrayDesignator()) {
2434*67e74705SXin Li AddStmt(E->getArrayIndex(D));
2435*67e74705SXin Li continue;
2436*67e74705SXin Li }
2437*67e74705SXin Li assert(D.isArrayRangeDesignator() && "Unknown designator kind");
2438*67e74705SXin Li AddStmt(E->getArrayRangeEnd(D));
2439*67e74705SXin Li AddStmt(E->getArrayRangeStart(D));
2440*67e74705SXin Li }
2441*67e74705SXin Li }
VisitExplicitCastExpr(const ExplicitCastExpr * E)2442*67e74705SXin Li void EnqueueVisitor::VisitExplicitCastExpr(const ExplicitCastExpr *E) {
2443*67e74705SXin Li EnqueueChildren(E);
2444*67e74705SXin Li AddTypeLoc(E->getTypeInfoAsWritten());
2445*67e74705SXin Li }
VisitForStmt(const ForStmt * FS)2446*67e74705SXin Li void EnqueueVisitor::VisitForStmt(const ForStmt *FS) {
2447*67e74705SXin Li AddStmt(FS->getBody());
2448*67e74705SXin Li AddStmt(FS->getInc());
2449*67e74705SXin Li AddStmt(FS->getCond());
2450*67e74705SXin Li AddDecl(FS->getConditionVariable());
2451*67e74705SXin Li AddStmt(FS->getInit());
2452*67e74705SXin Li }
VisitGotoStmt(const GotoStmt * GS)2453*67e74705SXin Li void EnqueueVisitor::VisitGotoStmt(const GotoStmt *GS) {
2454*67e74705SXin Li WL.push_back(LabelRefVisit(GS->getLabel(), GS->getLabelLoc(), Parent));
2455*67e74705SXin Li }
VisitIfStmt(const IfStmt * If)2456*67e74705SXin Li void EnqueueVisitor::VisitIfStmt(const IfStmt *If) {
2457*67e74705SXin Li AddStmt(If->getElse());
2458*67e74705SXin Li AddStmt(If->getThen());
2459*67e74705SXin Li AddStmt(If->getCond());
2460*67e74705SXin Li AddDecl(If->getConditionVariable());
2461*67e74705SXin Li }
VisitInitListExpr(const InitListExpr * IE)2462*67e74705SXin Li void EnqueueVisitor::VisitInitListExpr(const InitListExpr *IE) {
2463*67e74705SXin Li // We care about the syntactic form of the initializer list, only.
2464*67e74705SXin Li if (InitListExpr *Syntactic = IE->getSyntacticForm())
2465*67e74705SXin Li IE = Syntactic;
2466*67e74705SXin Li EnqueueChildren(IE);
2467*67e74705SXin Li }
VisitMemberExpr(const MemberExpr * M)2468*67e74705SXin Li void EnqueueVisitor::VisitMemberExpr(const MemberExpr *M) {
2469*67e74705SXin Li WL.push_back(MemberExprParts(M, Parent));
2470*67e74705SXin Li
2471*67e74705SXin Li // If the base of the member access expression is an implicit 'this', don't
2472*67e74705SXin Li // visit it.
2473*67e74705SXin Li // FIXME: If we ever want to show these implicit accesses, this will be
2474*67e74705SXin Li // unfortunate. However, clang_getCursor() relies on this behavior.
2475*67e74705SXin Li if (M->isImplicitAccess())
2476*67e74705SXin Li return;
2477*67e74705SXin Li
2478*67e74705SXin Li // Ignore base anonymous struct/union fields, otherwise they will shadow the
2479*67e74705SXin Li // real field that that we are interested in.
2480*67e74705SXin Li if (auto *SubME = dyn_cast<MemberExpr>(M->getBase())) {
2481*67e74705SXin Li if (auto *FD = dyn_cast_or_null<FieldDecl>(SubME->getMemberDecl())) {
2482*67e74705SXin Li if (FD->isAnonymousStructOrUnion()) {
2483*67e74705SXin Li AddStmt(SubME->getBase());
2484*67e74705SXin Li return;
2485*67e74705SXin Li }
2486*67e74705SXin Li }
2487*67e74705SXin Li }
2488*67e74705SXin Li
2489*67e74705SXin Li AddStmt(M->getBase());
2490*67e74705SXin Li }
VisitObjCEncodeExpr(const ObjCEncodeExpr * E)2491*67e74705SXin Li void EnqueueVisitor::VisitObjCEncodeExpr(const ObjCEncodeExpr *E) {
2492*67e74705SXin Li AddTypeLoc(E->getEncodedTypeSourceInfo());
2493*67e74705SXin Li }
VisitObjCMessageExpr(const ObjCMessageExpr * M)2494*67e74705SXin Li void EnqueueVisitor::VisitObjCMessageExpr(const ObjCMessageExpr *M) {
2495*67e74705SXin Li EnqueueChildren(M);
2496*67e74705SXin Li AddTypeLoc(M->getClassReceiverTypeInfo());
2497*67e74705SXin Li }
VisitOffsetOfExpr(const OffsetOfExpr * E)2498*67e74705SXin Li void EnqueueVisitor::VisitOffsetOfExpr(const OffsetOfExpr *E) {
2499*67e74705SXin Li // Visit the components of the offsetof expression.
2500*67e74705SXin Li for (unsigned N = E->getNumComponents(), I = N; I > 0; --I) {
2501*67e74705SXin Li const OffsetOfNode &Node = E->getComponent(I-1);
2502*67e74705SXin Li switch (Node.getKind()) {
2503*67e74705SXin Li case OffsetOfNode::Array:
2504*67e74705SXin Li AddStmt(E->getIndexExpr(Node.getArrayExprIndex()));
2505*67e74705SXin Li break;
2506*67e74705SXin Li case OffsetOfNode::Field:
2507*67e74705SXin Li AddMemberRef(Node.getField(), Node.getSourceRange().getEnd());
2508*67e74705SXin Li break;
2509*67e74705SXin Li case OffsetOfNode::Identifier:
2510*67e74705SXin Li case OffsetOfNode::Base:
2511*67e74705SXin Li continue;
2512*67e74705SXin Li }
2513*67e74705SXin Li }
2514*67e74705SXin Li // Visit the type into which we're computing the offset.
2515*67e74705SXin Li AddTypeLoc(E->getTypeSourceInfo());
2516*67e74705SXin Li }
VisitOverloadExpr(const OverloadExpr * E)2517*67e74705SXin Li void EnqueueVisitor::VisitOverloadExpr(const OverloadExpr *E) {
2518*67e74705SXin Li if (E->hasExplicitTemplateArgs())
2519*67e74705SXin Li AddExplicitTemplateArgs(E->getTemplateArgs(), E->getNumTemplateArgs());
2520*67e74705SXin Li WL.push_back(OverloadExprParts(E, Parent));
2521*67e74705SXin Li }
VisitUnaryExprOrTypeTraitExpr(const UnaryExprOrTypeTraitExpr * E)2522*67e74705SXin Li void EnqueueVisitor::VisitUnaryExprOrTypeTraitExpr(
2523*67e74705SXin Li const UnaryExprOrTypeTraitExpr *E) {
2524*67e74705SXin Li EnqueueChildren(E);
2525*67e74705SXin Li if (E->isArgumentType())
2526*67e74705SXin Li AddTypeLoc(E->getArgumentTypeInfo());
2527*67e74705SXin Li }
VisitStmt(const Stmt * S)2528*67e74705SXin Li void EnqueueVisitor::VisitStmt(const Stmt *S) {
2529*67e74705SXin Li EnqueueChildren(S);
2530*67e74705SXin Li }
VisitSwitchStmt(const SwitchStmt * S)2531*67e74705SXin Li void EnqueueVisitor::VisitSwitchStmt(const SwitchStmt *S) {
2532*67e74705SXin Li AddStmt(S->getBody());
2533*67e74705SXin Li AddStmt(S->getCond());
2534*67e74705SXin Li AddDecl(S->getConditionVariable());
2535*67e74705SXin Li }
2536*67e74705SXin Li
VisitWhileStmt(const WhileStmt * W)2537*67e74705SXin Li void EnqueueVisitor::VisitWhileStmt(const WhileStmt *W) {
2538*67e74705SXin Li AddStmt(W->getBody());
2539*67e74705SXin Li AddStmt(W->getCond());
2540*67e74705SXin Li AddDecl(W->getConditionVariable());
2541*67e74705SXin Li }
2542*67e74705SXin Li
VisitTypeTraitExpr(const TypeTraitExpr * E)2543*67e74705SXin Li void EnqueueVisitor::VisitTypeTraitExpr(const TypeTraitExpr *E) {
2544*67e74705SXin Li for (unsigned I = E->getNumArgs(); I > 0; --I)
2545*67e74705SXin Li AddTypeLoc(E->getArg(I-1));
2546*67e74705SXin Li }
2547*67e74705SXin Li
VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr * E)2548*67e74705SXin Li void EnqueueVisitor::VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *E) {
2549*67e74705SXin Li AddTypeLoc(E->getQueriedTypeSourceInfo());
2550*67e74705SXin Li }
2551*67e74705SXin Li
VisitExpressionTraitExpr(const ExpressionTraitExpr * E)2552*67e74705SXin Li void EnqueueVisitor::VisitExpressionTraitExpr(const ExpressionTraitExpr *E) {
2553*67e74705SXin Li EnqueueChildren(E);
2554*67e74705SXin Li }
2555*67e74705SXin Li
VisitUnresolvedMemberExpr(const UnresolvedMemberExpr * U)2556*67e74705SXin Li void EnqueueVisitor::VisitUnresolvedMemberExpr(const UnresolvedMemberExpr *U) {
2557*67e74705SXin Li VisitOverloadExpr(U);
2558*67e74705SXin Li if (!U->isImplicitAccess())
2559*67e74705SXin Li AddStmt(U->getBase());
2560*67e74705SXin Li }
VisitVAArgExpr(const VAArgExpr * E)2561*67e74705SXin Li void EnqueueVisitor::VisitVAArgExpr(const VAArgExpr *E) {
2562*67e74705SXin Li AddStmt(E->getSubExpr());
2563*67e74705SXin Li AddTypeLoc(E->getWrittenTypeInfo());
2564*67e74705SXin Li }
VisitSizeOfPackExpr(const SizeOfPackExpr * E)2565*67e74705SXin Li void EnqueueVisitor::VisitSizeOfPackExpr(const SizeOfPackExpr *E) {
2566*67e74705SXin Li WL.push_back(SizeOfPackExprParts(E, Parent));
2567*67e74705SXin Li }
VisitOpaqueValueExpr(const OpaqueValueExpr * E)2568*67e74705SXin Li void EnqueueVisitor::VisitOpaqueValueExpr(const OpaqueValueExpr *E) {
2569*67e74705SXin Li // If the opaque value has a source expression, just transparently
2570*67e74705SXin Li // visit that. This is useful for (e.g.) pseudo-object expressions.
2571*67e74705SXin Li if (Expr *SourceExpr = E->getSourceExpr())
2572*67e74705SXin Li return Visit(SourceExpr);
2573*67e74705SXin Li }
VisitLambdaExpr(const LambdaExpr * E)2574*67e74705SXin Li void EnqueueVisitor::VisitLambdaExpr(const LambdaExpr *E) {
2575*67e74705SXin Li AddStmt(E->getBody());
2576*67e74705SXin Li WL.push_back(LambdaExprParts(E, Parent));
2577*67e74705SXin Li }
VisitPseudoObjectExpr(const PseudoObjectExpr * E)2578*67e74705SXin Li void EnqueueVisitor::VisitPseudoObjectExpr(const PseudoObjectExpr *E) {
2579*67e74705SXin Li // Treat the expression like its syntactic form.
2580*67e74705SXin Li Visit(E->getSyntacticForm());
2581*67e74705SXin Li }
2582*67e74705SXin Li
VisitOMPExecutableDirective(const OMPExecutableDirective * D)2583*67e74705SXin Li void EnqueueVisitor::VisitOMPExecutableDirective(
2584*67e74705SXin Li const OMPExecutableDirective *D) {
2585*67e74705SXin Li EnqueueChildren(D);
2586*67e74705SXin Li for (ArrayRef<OMPClause *>::iterator I = D->clauses().begin(),
2587*67e74705SXin Li E = D->clauses().end();
2588*67e74705SXin Li I != E; ++I)
2589*67e74705SXin Li EnqueueChildren(*I);
2590*67e74705SXin Li }
2591*67e74705SXin Li
VisitOMPLoopDirective(const OMPLoopDirective * D)2592*67e74705SXin Li void EnqueueVisitor::VisitOMPLoopDirective(const OMPLoopDirective *D) {
2593*67e74705SXin Li VisitOMPExecutableDirective(D);
2594*67e74705SXin Li }
2595*67e74705SXin Li
VisitOMPParallelDirective(const OMPParallelDirective * D)2596*67e74705SXin Li void EnqueueVisitor::VisitOMPParallelDirective(const OMPParallelDirective *D) {
2597*67e74705SXin Li VisitOMPExecutableDirective(D);
2598*67e74705SXin Li }
2599*67e74705SXin Li
VisitOMPSimdDirective(const OMPSimdDirective * D)2600*67e74705SXin Li void EnqueueVisitor::VisitOMPSimdDirective(const OMPSimdDirective *D) {
2601*67e74705SXin Li VisitOMPLoopDirective(D);
2602*67e74705SXin Li }
2603*67e74705SXin Li
VisitOMPForDirective(const OMPForDirective * D)2604*67e74705SXin Li void EnqueueVisitor::VisitOMPForDirective(const OMPForDirective *D) {
2605*67e74705SXin Li VisitOMPLoopDirective(D);
2606*67e74705SXin Li }
2607*67e74705SXin Li
VisitOMPForSimdDirective(const OMPForSimdDirective * D)2608*67e74705SXin Li void EnqueueVisitor::VisitOMPForSimdDirective(const OMPForSimdDirective *D) {
2609*67e74705SXin Li VisitOMPLoopDirective(D);
2610*67e74705SXin Li }
2611*67e74705SXin Li
VisitOMPSectionsDirective(const OMPSectionsDirective * D)2612*67e74705SXin Li void EnqueueVisitor::VisitOMPSectionsDirective(const OMPSectionsDirective *D) {
2613*67e74705SXin Li VisitOMPExecutableDirective(D);
2614*67e74705SXin Li }
2615*67e74705SXin Li
VisitOMPSectionDirective(const OMPSectionDirective * D)2616*67e74705SXin Li void EnqueueVisitor::VisitOMPSectionDirective(const OMPSectionDirective *D) {
2617*67e74705SXin Li VisitOMPExecutableDirective(D);
2618*67e74705SXin Li }
2619*67e74705SXin Li
VisitOMPSingleDirective(const OMPSingleDirective * D)2620*67e74705SXin Li void EnqueueVisitor::VisitOMPSingleDirective(const OMPSingleDirective *D) {
2621*67e74705SXin Li VisitOMPExecutableDirective(D);
2622*67e74705SXin Li }
2623*67e74705SXin Li
VisitOMPMasterDirective(const OMPMasterDirective * D)2624*67e74705SXin Li void EnqueueVisitor::VisitOMPMasterDirective(const OMPMasterDirective *D) {
2625*67e74705SXin Li VisitOMPExecutableDirective(D);
2626*67e74705SXin Li }
2627*67e74705SXin Li
VisitOMPCriticalDirective(const OMPCriticalDirective * D)2628*67e74705SXin Li void EnqueueVisitor::VisitOMPCriticalDirective(const OMPCriticalDirective *D) {
2629*67e74705SXin Li VisitOMPExecutableDirective(D);
2630*67e74705SXin Li AddDeclarationNameInfo(D);
2631*67e74705SXin Li }
2632*67e74705SXin Li
2633*67e74705SXin Li void
VisitOMPParallelForDirective(const OMPParallelForDirective * D)2634*67e74705SXin Li EnqueueVisitor::VisitOMPParallelForDirective(const OMPParallelForDirective *D) {
2635*67e74705SXin Li VisitOMPLoopDirective(D);
2636*67e74705SXin Li }
2637*67e74705SXin Li
VisitOMPParallelForSimdDirective(const OMPParallelForSimdDirective * D)2638*67e74705SXin Li void EnqueueVisitor::VisitOMPParallelForSimdDirective(
2639*67e74705SXin Li const OMPParallelForSimdDirective *D) {
2640*67e74705SXin Li VisitOMPLoopDirective(D);
2641*67e74705SXin Li }
2642*67e74705SXin Li
VisitOMPParallelSectionsDirective(const OMPParallelSectionsDirective * D)2643*67e74705SXin Li void EnqueueVisitor::VisitOMPParallelSectionsDirective(
2644*67e74705SXin Li const OMPParallelSectionsDirective *D) {
2645*67e74705SXin Li VisitOMPExecutableDirective(D);
2646*67e74705SXin Li }
2647*67e74705SXin Li
VisitOMPTaskDirective(const OMPTaskDirective * D)2648*67e74705SXin Li void EnqueueVisitor::VisitOMPTaskDirective(const OMPTaskDirective *D) {
2649*67e74705SXin Li VisitOMPExecutableDirective(D);
2650*67e74705SXin Li }
2651*67e74705SXin Li
2652*67e74705SXin Li void
VisitOMPTaskyieldDirective(const OMPTaskyieldDirective * D)2653*67e74705SXin Li EnqueueVisitor::VisitOMPTaskyieldDirective(const OMPTaskyieldDirective *D) {
2654*67e74705SXin Li VisitOMPExecutableDirective(D);
2655*67e74705SXin Li }
2656*67e74705SXin Li
VisitOMPBarrierDirective(const OMPBarrierDirective * D)2657*67e74705SXin Li void EnqueueVisitor::VisitOMPBarrierDirective(const OMPBarrierDirective *D) {
2658*67e74705SXin Li VisitOMPExecutableDirective(D);
2659*67e74705SXin Li }
2660*67e74705SXin Li
VisitOMPTaskwaitDirective(const OMPTaskwaitDirective * D)2661*67e74705SXin Li void EnqueueVisitor::VisitOMPTaskwaitDirective(const OMPTaskwaitDirective *D) {
2662*67e74705SXin Li VisitOMPExecutableDirective(D);
2663*67e74705SXin Li }
2664*67e74705SXin Li
VisitOMPTaskgroupDirective(const OMPTaskgroupDirective * D)2665*67e74705SXin Li void EnqueueVisitor::VisitOMPTaskgroupDirective(
2666*67e74705SXin Li const OMPTaskgroupDirective *D) {
2667*67e74705SXin Li VisitOMPExecutableDirective(D);
2668*67e74705SXin Li }
2669*67e74705SXin Li
VisitOMPFlushDirective(const OMPFlushDirective * D)2670*67e74705SXin Li void EnqueueVisitor::VisitOMPFlushDirective(const OMPFlushDirective *D) {
2671*67e74705SXin Li VisitOMPExecutableDirective(D);
2672*67e74705SXin Li }
2673*67e74705SXin Li
VisitOMPOrderedDirective(const OMPOrderedDirective * D)2674*67e74705SXin Li void EnqueueVisitor::VisitOMPOrderedDirective(const OMPOrderedDirective *D) {
2675*67e74705SXin Li VisitOMPExecutableDirective(D);
2676*67e74705SXin Li }
2677*67e74705SXin Li
VisitOMPAtomicDirective(const OMPAtomicDirective * D)2678*67e74705SXin Li void EnqueueVisitor::VisitOMPAtomicDirective(const OMPAtomicDirective *D) {
2679*67e74705SXin Li VisitOMPExecutableDirective(D);
2680*67e74705SXin Li }
2681*67e74705SXin Li
VisitOMPTargetDirective(const OMPTargetDirective * D)2682*67e74705SXin Li void EnqueueVisitor::VisitOMPTargetDirective(const OMPTargetDirective *D) {
2683*67e74705SXin Li VisitOMPExecutableDirective(D);
2684*67e74705SXin Li }
2685*67e74705SXin Li
VisitOMPTargetDataDirective(const OMPTargetDataDirective * D)2686*67e74705SXin Li void EnqueueVisitor::VisitOMPTargetDataDirective(const
2687*67e74705SXin Li OMPTargetDataDirective *D) {
2688*67e74705SXin Li VisitOMPExecutableDirective(D);
2689*67e74705SXin Li }
2690*67e74705SXin Li
VisitOMPTargetEnterDataDirective(const OMPTargetEnterDataDirective * D)2691*67e74705SXin Li void EnqueueVisitor::VisitOMPTargetEnterDataDirective(
2692*67e74705SXin Li const OMPTargetEnterDataDirective *D) {
2693*67e74705SXin Li VisitOMPExecutableDirective(D);
2694*67e74705SXin Li }
2695*67e74705SXin Li
VisitOMPTargetExitDataDirective(const OMPTargetExitDataDirective * D)2696*67e74705SXin Li void EnqueueVisitor::VisitOMPTargetExitDataDirective(
2697*67e74705SXin Li const OMPTargetExitDataDirective *D) {
2698*67e74705SXin Li VisitOMPExecutableDirective(D);
2699*67e74705SXin Li }
2700*67e74705SXin Li
VisitOMPTargetParallelDirective(const OMPTargetParallelDirective * D)2701*67e74705SXin Li void EnqueueVisitor::VisitOMPTargetParallelDirective(
2702*67e74705SXin Li const OMPTargetParallelDirective *D) {
2703*67e74705SXin Li VisitOMPExecutableDirective(D);
2704*67e74705SXin Li }
2705*67e74705SXin Li
VisitOMPTargetParallelForDirective(const OMPTargetParallelForDirective * D)2706*67e74705SXin Li void EnqueueVisitor::VisitOMPTargetParallelForDirective(
2707*67e74705SXin Li const OMPTargetParallelForDirective *D) {
2708*67e74705SXin Li VisitOMPLoopDirective(D);
2709*67e74705SXin Li }
2710*67e74705SXin Li
VisitOMPTeamsDirective(const OMPTeamsDirective * D)2711*67e74705SXin Li void EnqueueVisitor::VisitOMPTeamsDirective(const OMPTeamsDirective *D) {
2712*67e74705SXin Li VisitOMPExecutableDirective(D);
2713*67e74705SXin Li }
2714*67e74705SXin Li
VisitOMPCancellationPointDirective(const OMPCancellationPointDirective * D)2715*67e74705SXin Li void EnqueueVisitor::VisitOMPCancellationPointDirective(
2716*67e74705SXin Li const OMPCancellationPointDirective *D) {
2717*67e74705SXin Li VisitOMPExecutableDirective(D);
2718*67e74705SXin Li }
2719*67e74705SXin Li
VisitOMPCancelDirective(const OMPCancelDirective * D)2720*67e74705SXin Li void EnqueueVisitor::VisitOMPCancelDirective(const OMPCancelDirective *D) {
2721*67e74705SXin Li VisitOMPExecutableDirective(D);
2722*67e74705SXin Li }
2723*67e74705SXin Li
VisitOMPTaskLoopDirective(const OMPTaskLoopDirective * D)2724*67e74705SXin Li void EnqueueVisitor::VisitOMPTaskLoopDirective(const OMPTaskLoopDirective *D) {
2725*67e74705SXin Li VisitOMPLoopDirective(D);
2726*67e74705SXin Li }
2727*67e74705SXin Li
VisitOMPTaskLoopSimdDirective(const OMPTaskLoopSimdDirective * D)2728*67e74705SXin Li void EnqueueVisitor::VisitOMPTaskLoopSimdDirective(
2729*67e74705SXin Li const OMPTaskLoopSimdDirective *D) {
2730*67e74705SXin Li VisitOMPLoopDirective(D);
2731*67e74705SXin Li }
2732*67e74705SXin Li
VisitOMPDistributeDirective(const OMPDistributeDirective * D)2733*67e74705SXin Li void EnqueueVisitor::VisitOMPDistributeDirective(
2734*67e74705SXin Li const OMPDistributeDirective *D) {
2735*67e74705SXin Li VisitOMPLoopDirective(D);
2736*67e74705SXin Li }
2737*67e74705SXin Li
VisitOMPDistributeParallelForDirective(const OMPDistributeParallelForDirective * D)2738*67e74705SXin Li void EnqueueVisitor::VisitOMPDistributeParallelForDirective(
2739*67e74705SXin Li const OMPDistributeParallelForDirective *D) {
2740*67e74705SXin Li VisitOMPLoopDirective(D);
2741*67e74705SXin Li }
2742*67e74705SXin Li
VisitOMPDistributeParallelForSimdDirective(const OMPDistributeParallelForSimdDirective * D)2743*67e74705SXin Li void EnqueueVisitor::VisitOMPDistributeParallelForSimdDirective(
2744*67e74705SXin Li const OMPDistributeParallelForSimdDirective *D) {
2745*67e74705SXin Li VisitOMPLoopDirective(D);
2746*67e74705SXin Li }
2747*67e74705SXin Li
VisitOMPDistributeSimdDirective(const OMPDistributeSimdDirective * D)2748*67e74705SXin Li void EnqueueVisitor::VisitOMPDistributeSimdDirective(
2749*67e74705SXin Li const OMPDistributeSimdDirective *D) {
2750*67e74705SXin Li VisitOMPLoopDirective(D);
2751*67e74705SXin Li }
2752*67e74705SXin Li
VisitOMPTargetParallelForSimdDirective(const OMPTargetParallelForSimdDirective * D)2753*67e74705SXin Li void EnqueueVisitor::VisitOMPTargetParallelForSimdDirective(
2754*67e74705SXin Li const OMPTargetParallelForSimdDirective *D) {
2755*67e74705SXin Li VisitOMPLoopDirective(D);
2756*67e74705SXin Li }
2757*67e74705SXin Li
EnqueueWorkList(VisitorWorkList & WL,const Stmt * S)2758*67e74705SXin Li void CursorVisitor::EnqueueWorkList(VisitorWorkList &WL, const Stmt *S) {
2759*67e74705SXin Li EnqueueVisitor(WL, MakeCXCursor(S, StmtParent, TU,RegionOfInterest)).Visit(S);
2760*67e74705SXin Li }
2761*67e74705SXin Li
IsInRegionOfInterest(CXCursor C)2762*67e74705SXin Li bool CursorVisitor::IsInRegionOfInterest(CXCursor C) {
2763*67e74705SXin Li if (RegionOfInterest.isValid()) {
2764*67e74705SXin Li SourceRange Range = getRawCursorExtent(C);
2765*67e74705SXin Li if (Range.isInvalid() || CompareRegionOfInterest(Range))
2766*67e74705SXin Li return false;
2767*67e74705SXin Li }
2768*67e74705SXin Li return true;
2769*67e74705SXin Li }
2770*67e74705SXin Li
RunVisitorWorkList(VisitorWorkList & WL)2771*67e74705SXin Li bool CursorVisitor::RunVisitorWorkList(VisitorWorkList &WL) {
2772*67e74705SXin Li while (!WL.empty()) {
2773*67e74705SXin Li // Dequeue the worklist item.
2774*67e74705SXin Li VisitorJob LI = WL.pop_back_val();
2775*67e74705SXin Li
2776*67e74705SXin Li // Set the Parent field, then back to its old value once we're done.
2777*67e74705SXin Li SetParentRAII SetParent(Parent, StmtParent, LI.getParent());
2778*67e74705SXin Li
2779*67e74705SXin Li switch (LI.getKind()) {
2780*67e74705SXin Li case VisitorJob::DeclVisitKind: {
2781*67e74705SXin Li const Decl *D = cast<DeclVisit>(&LI)->get();
2782*67e74705SXin Li if (!D)
2783*67e74705SXin Li continue;
2784*67e74705SXin Li
2785*67e74705SXin Li // For now, perform default visitation for Decls.
2786*67e74705SXin Li if (Visit(MakeCXCursor(D, TU, RegionOfInterest,
2787*67e74705SXin Li cast<DeclVisit>(&LI)->isFirst())))
2788*67e74705SXin Li return true;
2789*67e74705SXin Li
2790*67e74705SXin Li continue;
2791*67e74705SXin Li }
2792*67e74705SXin Li case VisitorJob::ExplicitTemplateArgsVisitKind: {
2793*67e74705SXin Li for (const TemplateArgumentLoc &Arg :
2794*67e74705SXin Li *cast<ExplicitTemplateArgsVisit>(&LI)) {
2795*67e74705SXin Li if (VisitTemplateArgumentLoc(Arg))
2796*67e74705SXin Li return true;
2797*67e74705SXin Li }
2798*67e74705SXin Li continue;
2799*67e74705SXin Li }
2800*67e74705SXin Li case VisitorJob::TypeLocVisitKind: {
2801*67e74705SXin Li // Perform default visitation for TypeLocs.
2802*67e74705SXin Li if (Visit(cast<TypeLocVisit>(&LI)->get()))
2803*67e74705SXin Li return true;
2804*67e74705SXin Li continue;
2805*67e74705SXin Li }
2806*67e74705SXin Li case VisitorJob::LabelRefVisitKind: {
2807*67e74705SXin Li const LabelDecl *LS = cast<LabelRefVisit>(&LI)->get();
2808*67e74705SXin Li if (LabelStmt *stmt = LS->getStmt()) {
2809*67e74705SXin Li if (Visit(MakeCursorLabelRef(stmt, cast<LabelRefVisit>(&LI)->getLoc(),
2810*67e74705SXin Li TU))) {
2811*67e74705SXin Li return true;
2812*67e74705SXin Li }
2813*67e74705SXin Li }
2814*67e74705SXin Li continue;
2815*67e74705SXin Li }
2816*67e74705SXin Li
2817*67e74705SXin Li case VisitorJob::NestedNameSpecifierLocVisitKind: {
2818*67e74705SXin Li NestedNameSpecifierLocVisit *V = cast<NestedNameSpecifierLocVisit>(&LI);
2819*67e74705SXin Li if (VisitNestedNameSpecifierLoc(V->get()))
2820*67e74705SXin Li return true;
2821*67e74705SXin Li continue;
2822*67e74705SXin Li }
2823*67e74705SXin Li
2824*67e74705SXin Li case VisitorJob::DeclarationNameInfoVisitKind: {
2825*67e74705SXin Li if (VisitDeclarationNameInfo(cast<DeclarationNameInfoVisit>(&LI)
2826*67e74705SXin Li ->get()))
2827*67e74705SXin Li return true;
2828*67e74705SXin Li continue;
2829*67e74705SXin Li }
2830*67e74705SXin Li case VisitorJob::MemberRefVisitKind: {
2831*67e74705SXin Li MemberRefVisit *V = cast<MemberRefVisit>(&LI);
2832*67e74705SXin Li if (Visit(MakeCursorMemberRef(V->get(), V->getLoc(), TU)))
2833*67e74705SXin Li return true;
2834*67e74705SXin Li continue;
2835*67e74705SXin Li }
2836*67e74705SXin Li case VisitorJob::StmtVisitKind: {
2837*67e74705SXin Li const Stmt *S = cast<StmtVisit>(&LI)->get();
2838*67e74705SXin Li if (!S)
2839*67e74705SXin Li continue;
2840*67e74705SXin Li
2841*67e74705SXin Li // Update the current cursor.
2842*67e74705SXin Li CXCursor Cursor = MakeCXCursor(S, StmtParent, TU, RegionOfInterest);
2843*67e74705SXin Li if (!IsInRegionOfInterest(Cursor))
2844*67e74705SXin Li continue;
2845*67e74705SXin Li switch (Visitor(Cursor, Parent, ClientData)) {
2846*67e74705SXin Li case CXChildVisit_Break: return true;
2847*67e74705SXin Li case CXChildVisit_Continue: break;
2848*67e74705SXin Li case CXChildVisit_Recurse:
2849*67e74705SXin Li if (PostChildrenVisitor)
2850*67e74705SXin Li WL.push_back(PostChildrenVisit(nullptr, Cursor));
2851*67e74705SXin Li EnqueueWorkList(WL, S);
2852*67e74705SXin Li break;
2853*67e74705SXin Li }
2854*67e74705SXin Li continue;
2855*67e74705SXin Li }
2856*67e74705SXin Li case VisitorJob::MemberExprPartsKind: {
2857*67e74705SXin Li // Handle the other pieces in the MemberExpr besides the base.
2858*67e74705SXin Li const MemberExpr *M = cast<MemberExprParts>(&LI)->get();
2859*67e74705SXin Li
2860*67e74705SXin Li // Visit the nested-name-specifier
2861*67e74705SXin Li if (NestedNameSpecifierLoc QualifierLoc = M->getQualifierLoc())
2862*67e74705SXin Li if (VisitNestedNameSpecifierLoc(QualifierLoc))
2863*67e74705SXin Li return true;
2864*67e74705SXin Li
2865*67e74705SXin Li // Visit the declaration name.
2866*67e74705SXin Li if (VisitDeclarationNameInfo(M->getMemberNameInfo()))
2867*67e74705SXin Li return true;
2868*67e74705SXin Li
2869*67e74705SXin Li // Visit the explicitly-specified template arguments, if any.
2870*67e74705SXin Li if (M->hasExplicitTemplateArgs()) {
2871*67e74705SXin Li for (const TemplateArgumentLoc *Arg = M->getTemplateArgs(),
2872*67e74705SXin Li *ArgEnd = Arg + M->getNumTemplateArgs();
2873*67e74705SXin Li Arg != ArgEnd; ++Arg) {
2874*67e74705SXin Li if (VisitTemplateArgumentLoc(*Arg))
2875*67e74705SXin Li return true;
2876*67e74705SXin Li }
2877*67e74705SXin Li }
2878*67e74705SXin Li continue;
2879*67e74705SXin Li }
2880*67e74705SXin Li case VisitorJob::DeclRefExprPartsKind: {
2881*67e74705SXin Li const DeclRefExpr *DR = cast<DeclRefExprParts>(&LI)->get();
2882*67e74705SXin Li // Visit nested-name-specifier, if present.
2883*67e74705SXin Li if (NestedNameSpecifierLoc QualifierLoc = DR->getQualifierLoc())
2884*67e74705SXin Li if (VisitNestedNameSpecifierLoc(QualifierLoc))
2885*67e74705SXin Li return true;
2886*67e74705SXin Li // Visit declaration name.
2887*67e74705SXin Li if (VisitDeclarationNameInfo(DR->getNameInfo()))
2888*67e74705SXin Li return true;
2889*67e74705SXin Li continue;
2890*67e74705SXin Li }
2891*67e74705SXin Li case VisitorJob::OverloadExprPartsKind: {
2892*67e74705SXin Li const OverloadExpr *O = cast<OverloadExprParts>(&LI)->get();
2893*67e74705SXin Li // Visit the nested-name-specifier.
2894*67e74705SXin Li if (NestedNameSpecifierLoc QualifierLoc = O->getQualifierLoc())
2895*67e74705SXin Li if (VisitNestedNameSpecifierLoc(QualifierLoc))
2896*67e74705SXin Li return true;
2897*67e74705SXin Li // Visit the declaration name.
2898*67e74705SXin Li if (VisitDeclarationNameInfo(O->getNameInfo()))
2899*67e74705SXin Li return true;
2900*67e74705SXin Li // Visit the overloaded declaration reference.
2901*67e74705SXin Li if (Visit(MakeCursorOverloadedDeclRef(O, TU)))
2902*67e74705SXin Li return true;
2903*67e74705SXin Li continue;
2904*67e74705SXin Li }
2905*67e74705SXin Li case VisitorJob::SizeOfPackExprPartsKind: {
2906*67e74705SXin Li const SizeOfPackExpr *E = cast<SizeOfPackExprParts>(&LI)->get();
2907*67e74705SXin Li NamedDecl *Pack = E->getPack();
2908*67e74705SXin Li if (isa<TemplateTypeParmDecl>(Pack)) {
2909*67e74705SXin Li if (Visit(MakeCursorTypeRef(cast<TemplateTypeParmDecl>(Pack),
2910*67e74705SXin Li E->getPackLoc(), TU)))
2911*67e74705SXin Li return true;
2912*67e74705SXin Li
2913*67e74705SXin Li continue;
2914*67e74705SXin Li }
2915*67e74705SXin Li
2916*67e74705SXin Li if (isa<TemplateTemplateParmDecl>(Pack)) {
2917*67e74705SXin Li if (Visit(MakeCursorTemplateRef(cast<TemplateTemplateParmDecl>(Pack),
2918*67e74705SXin Li E->getPackLoc(), TU)))
2919*67e74705SXin Li return true;
2920*67e74705SXin Li
2921*67e74705SXin Li continue;
2922*67e74705SXin Li }
2923*67e74705SXin Li
2924*67e74705SXin Li // Non-type template parameter packs and function parameter packs are
2925*67e74705SXin Li // treated like DeclRefExpr cursors.
2926*67e74705SXin Li continue;
2927*67e74705SXin Li }
2928*67e74705SXin Li
2929*67e74705SXin Li case VisitorJob::LambdaExprPartsKind: {
2930*67e74705SXin Li // Visit captures.
2931*67e74705SXin Li const LambdaExpr *E = cast<LambdaExprParts>(&LI)->get();
2932*67e74705SXin Li for (LambdaExpr::capture_iterator C = E->explicit_capture_begin(),
2933*67e74705SXin Li CEnd = E->explicit_capture_end();
2934*67e74705SXin Li C != CEnd; ++C) {
2935*67e74705SXin Li // FIXME: Lambda init-captures.
2936*67e74705SXin Li if (!C->capturesVariable())
2937*67e74705SXin Li continue;
2938*67e74705SXin Li
2939*67e74705SXin Li if (Visit(MakeCursorVariableRef(C->getCapturedVar(),
2940*67e74705SXin Li C->getLocation(),
2941*67e74705SXin Li TU)))
2942*67e74705SXin Li return true;
2943*67e74705SXin Li }
2944*67e74705SXin Li
2945*67e74705SXin Li // Visit parameters and return type, if present.
2946*67e74705SXin Li if (E->hasExplicitParameters() || E->hasExplicitResultType()) {
2947*67e74705SXin Li TypeLoc TL = E->getCallOperator()->getTypeSourceInfo()->getTypeLoc();
2948*67e74705SXin Li if (E->hasExplicitParameters() && E->hasExplicitResultType()) {
2949*67e74705SXin Li // Visit the whole type.
2950*67e74705SXin Li if (Visit(TL))
2951*67e74705SXin Li return true;
2952*67e74705SXin Li } else if (FunctionProtoTypeLoc Proto =
2953*67e74705SXin Li TL.getAs<FunctionProtoTypeLoc>()) {
2954*67e74705SXin Li if (E->hasExplicitParameters()) {
2955*67e74705SXin Li // Visit parameters.
2956*67e74705SXin Li for (unsigned I = 0, N = Proto.getNumParams(); I != N; ++I)
2957*67e74705SXin Li if (Visit(MakeCXCursor(Proto.getParam(I), TU)))
2958*67e74705SXin Li return true;
2959*67e74705SXin Li } else {
2960*67e74705SXin Li // Visit result type.
2961*67e74705SXin Li if (Visit(Proto.getReturnLoc()))
2962*67e74705SXin Li return true;
2963*67e74705SXin Li }
2964*67e74705SXin Li }
2965*67e74705SXin Li }
2966*67e74705SXin Li break;
2967*67e74705SXin Li }
2968*67e74705SXin Li
2969*67e74705SXin Li case VisitorJob::PostChildrenVisitKind:
2970*67e74705SXin Li if (PostChildrenVisitor(Parent, ClientData))
2971*67e74705SXin Li return true;
2972*67e74705SXin Li break;
2973*67e74705SXin Li }
2974*67e74705SXin Li }
2975*67e74705SXin Li return false;
2976*67e74705SXin Li }
2977*67e74705SXin Li
Visit(const Stmt * S)2978*67e74705SXin Li bool CursorVisitor::Visit(const Stmt *S) {
2979*67e74705SXin Li VisitorWorkList *WL = nullptr;
2980*67e74705SXin Li if (!WorkListFreeList.empty()) {
2981*67e74705SXin Li WL = WorkListFreeList.back();
2982*67e74705SXin Li WL->clear();
2983*67e74705SXin Li WorkListFreeList.pop_back();
2984*67e74705SXin Li }
2985*67e74705SXin Li else {
2986*67e74705SXin Li WL = new VisitorWorkList();
2987*67e74705SXin Li WorkListCache.push_back(WL);
2988*67e74705SXin Li }
2989*67e74705SXin Li EnqueueWorkList(*WL, S);
2990*67e74705SXin Li bool result = RunVisitorWorkList(*WL);
2991*67e74705SXin Li WorkListFreeList.push_back(WL);
2992*67e74705SXin Li return result;
2993*67e74705SXin Li }
2994*67e74705SXin Li
2995*67e74705SXin Li namespace {
2996*67e74705SXin Li typedef SmallVector<SourceRange, 4> RefNamePieces;
buildPieces(unsigned NameFlags,bool IsMemberRefExpr,const DeclarationNameInfo & NI,SourceRange QLoc,const SourceRange * TemplateArgsLoc=nullptr)2997*67e74705SXin Li RefNamePieces buildPieces(unsigned NameFlags, bool IsMemberRefExpr,
2998*67e74705SXin Li const DeclarationNameInfo &NI, SourceRange QLoc,
2999*67e74705SXin Li const SourceRange *TemplateArgsLoc = nullptr) {
3000*67e74705SXin Li const bool WantQualifier = NameFlags & CXNameRange_WantQualifier;
3001*67e74705SXin Li const bool WantTemplateArgs = NameFlags & CXNameRange_WantTemplateArgs;
3002*67e74705SXin Li const bool WantSinglePiece = NameFlags & CXNameRange_WantSinglePiece;
3003*67e74705SXin Li
3004*67e74705SXin Li const DeclarationName::NameKind Kind = NI.getName().getNameKind();
3005*67e74705SXin Li
3006*67e74705SXin Li RefNamePieces Pieces;
3007*67e74705SXin Li
3008*67e74705SXin Li if (WantQualifier && QLoc.isValid())
3009*67e74705SXin Li Pieces.push_back(QLoc);
3010*67e74705SXin Li
3011*67e74705SXin Li if (Kind != DeclarationName::CXXOperatorName || IsMemberRefExpr)
3012*67e74705SXin Li Pieces.push_back(NI.getLoc());
3013*67e74705SXin Li
3014*67e74705SXin Li if (WantTemplateArgs && TemplateArgsLoc && TemplateArgsLoc->isValid())
3015*67e74705SXin Li Pieces.push_back(*TemplateArgsLoc);
3016*67e74705SXin Li
3017*67e74705SXin Li if (Kind == DeclarationName::CXXOperatorName) {
3018*67e74705SXin Li Pieces.push_back(SourceLocation::getFromRawEncoding(
3019*67e74705SXin Li NI.getInfo().CXXOperatorName.BeginOpNameLoc));
3020*67e74705SXin Li Pieces.push_back(SourceLocation::getFromRawEncoding(
3021*67e74705SXin Li NI.getInfo().CXXOperatorName.EndOpNameLoc));
3022*67e74705SXin Li }
3023*67e74705SXin Li
3024*67e74705SXin Li if (WantSinglePiece) {
3025*67e74705SXin Li SourceRange R(Pieces.front().getBegin(), Pieces.back().getEnd());
3026*67e74705SXin Li Pieces.clear();
3027*67e74705SXin Li Pieces.push_back(R);
3028*67e74705SXin Li }
3029*67e74705SXin Li
3030*67e74705SXin Li return Pieces;
3031*67e74705SXin Li }
3032*67e74705SXin Li }
3033*67e74705SXin Li
3034*67e74705SXin Li //===----------------------------------------------------------------------===//
3035*67e74705SXin Li // Misc. API hooks.
3036*67e74705SXin Li //===----------------------------------------------------------------------===//
3037*67e74705SXin Li
fatal_error_handler(void * user_data,const std::string & reason,bool gen_crash_diag)3038*67e74705SXin Li static void fatal_error_handler(void *user_data, const std::string& reason,
3039*67e74705SXin Li bool gen_crash_diag) {
3040*67e74705SXin Li // Write the result out to stderr avoiding errs() because raw_ostreams can
3041*67e74705SXin Li // call report_fatal_error.
3042*67e74705SXin Li fprintf(stderr, "LIBCLANG FATAL ERROR: %s\n", reason.c_str());
3043*67e74705SXin Li ::abort();
3044*67e74705SXin Li }
3045*67e74705SXin Li
3046*67e74705SXin Li namespace {
3047*67e74705SXin Li struct RegisterFatalErrorHandler {
RegisterFatalErrorHandler__anonef1af4320511::RegisterFatalErrorHandler3048*67e74705SXin Li RegisterFatalErrorHandler() {
3049*67e74705SXin Li llvm::install_fatal_error_handler(fatal_error_handler, nullptr);
3050*67e74705SXin Li }
3051*67e74705SXin Li };
3052*67e74705SXin Li }
3053*67e74705SXin Li
3054*67e74705SXin Li static llvm::ManagedStatic<RegisterFatalErrorHandler> RegisterFatalErrorHandlerOnce;
3055*67e74705SXin Li
3056*67e74705SXin Li extern "C" {
clang_createIndex(int excludeDeclarationsFromPCH,int displayDiagnostics)3057*67e74705SXin Li CXIndex clang_createIndex(int excludeDeclarationsFromPCH,
3058*67e74705SXin Li int displayDiagnostics) {
3059*67e74705SXin Li // We use crash recovery to make some of our APIs more reliable, implicitly
3060*67e74705SXin Li // enable it.
3061*67e74705SXin Li if (!getenv("LIBCLANG_DISABLE_CRASH_RECOVERY"))
3062*67e74705SXin Li llvm::CrashRecoveryContext::Enable();
3063*67e74705SXin Li
3064*67e74705SXin Li // Look through the managed static to trigger construction of the managed
3065*67e74705SXin Li // static which registers our fatal error handler. This ensures it is only
3066*67e74705SXin Li // registered once.
3067*67e74705SXin Li (void)*RegisterFatalErrorHandlerOnce;
3068*67e74705SXin Li
3069*67e74705SXin Li // Initialize targets for clang module support.
3070*67e74705SXin Li llvm::InitializeAllTargets();
3071*67e74705SXin Li llvm::InitializeAllTargetMCs();
3072*67e74705SXin Li llvm::InitializeAllAsmPrinters();
3073*67e74705SXin Li llvm::InitializeAllAsmParsers();
3074*67e74705SXin Li
3075*67e74705SXin Li CIndexer *CIdxr = new CIndexer();
3076*67e74705SXin Li
3077*67e74705SXin Li if (excludeDeclarationsFromPCH)
3078*67e74705SXin Li CIdxr->setOnlyLocalDecls();
3079*67e74705SXin Li if (displayDiagnostics)
3080*67e74705SXin Li CIdxr->setDisplayDiagnostics();
3081*67e74705SXin Li
3082*67e74705SXin Li if (getenv("LIBCLANG_BGPRIO_INDEX"))
3083*67e74705SXin Li CIdxr->setCXGlobalOptFlags(CIdxr->getCXGlobalOptFlags() |
3084*67e74705SXin Li CXGlobalOpt_ThreadBackgroundPriorityForIndexing);
3085*67e74705SXin Li if (getenv("LIBCLANG_BGPRIO_EDIT"))
3086*67e74705SXin Li CIdxr->setCXGlobalOptFlags(CIdxr->getCXGlobalOptFlags() |
3087*67e74705SXin Li CXGlobalOpt_ThreadBackgroundPriorityForEditing);
3088*67e74705SXin Li
3089*67e74705SXin Li return CIdxr;
3090*67e74705SXin Li }
3091*67e74705SXin Li
clang_disposeIndex(CXIndex CIdx)3092*67e74705SXin Li void clang_disposeIndex(CXIndex CIdx) {
3093*67e74705SXin Li if (CIdx)
3094*67e74705SXin Li delete static_cast<CIndexer *>(CIdx);
3095*67e74705SXin Li }
3096*67e74705SXin Li
clang_CXIndex_setGlobalOptions(CXIndex CIdx,unsigned options)3097*67e74705SXin Li void clang_CXIndex_setGlobalOptions(CXIndex CIdx, unsigned options) {
3098*67e74705SXin Li if (CIdx)
3099*67e74705SXin Li static_cast<CIndexer *>(CIdx)->setCXGlobalOptFlags(options);
3100*67e74705SXin Li }
3101*67e74705SXin Li
clang_CXIndex_getGlobalOptions(CXIndex CIdx)3102*67e74705SXin Li unsigned clang_CXIndex_getGlobalOptions(CXIndex CIdx) {
3103*67e74705SXin Li if (CIdx)
3104*67e74705SXin Li return static_cast<CIndexer *>(CIdx)->getCXGlobalOptFlags();
3105*67e74705SXin Li return 0;
3106*67e74705SXin Li }
3107*67e74705SXin Li
clang_toggleCrashRecovery(unsigned isEnabled)3108*67e74705SXin Li void clang_toggleCrashRecovery(unsigned isEnabled) {
3109*67e74705SXin Li if (isEnabled)
3110*67e74705SXin Li llvm::CrashRecoveryContext::Enable();
3111*67e74705SXin Li else
3112*67e74705SXin Li llvm::CrashRecoveryContext::Disable();
3113*67e74705SXin Li }
3114*67e74705SXin Li
clang_createTranslationUnit(CXIndex CIdx,const char * ast_filename)3115*67e74705SXin Li CXTranslationUnit clang_createTranslationUnit(CXIndex CIdx,
3116*67e74705SXin Li const char *ast_filename) {
3117*67e74705SXin Li CXTranslationUnit TU;
3118*67e74705SXin Li enum CXErrorCode Result =
3119*67e74705SXin Li clang_createTranslationUnit2(CIdx, ast_filename, &TU);
3120*67e74705SXin Li (void)Result;
3121*67e74705SXin Li assert((TU && Result == CXError_Success) ||
3122*67e74705SXin Li (!TU && Result != CXError_Success));
3123*67e74705SXin Li return TU;
3124*67e74705SXin Li }
3125*67e74705SXin Li
clang_createTranslationUnit2(CXIndex CIdx,const char * ast_filename,CXTranslationUnit * out_TU)3126*67e74705SXin Li enum CXErrorCode clang_createTranslationUnit2(CXIndex CIdx,
3127*67e74705SXin Li const char *ast_filename,
3128*67e74705SXin Li CXTranslationUnit *out_TU) {
3129*67e74705SXin Li if (out_TU)
3130*67e74705SXin Li *out_TU = nullptr;
3131*67e74705SXin Li
3132*67e74705SXin Li if (!CIdx || !ast_filename || !out_TU)
3133*67e74705SXin Li return CXError_InvalidArguments;
3134*67e74705SXin Li
3135*67e74705SXin Li LOG_FUNC_SECTION {
3136*67e74705SXin Li *Log << ast_filename;
3137*67e74705SXin Li }
3138*67e74705SXin Li
3139*67e74705SXin Li CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
3140*67e74705SXin Li FileSystemOptions FileSystemOpts;
3141*67e74705SXin Li
3142*67e74705SXin Li IntrusiveRefCntPtr<DiagnosticsEngine> Diags =
3143*67e74705SXin Li CompilerInstance::createDiagnostics(new DiagnosticOptions());
3144*67e74705SXin Li std::unique_ptr<ASTUnit> AU = ASTUnit::LoadFromASTFile(
3145*67e74705SXin Li ast_filename, CXXIdx->getPCHContainerOperations()->getRawReader(), Diags,
3146*67e74705SXin Li FileSystemOpts, /*UseDebugInfo=*/false,
3147*67e74705SXin Li CXXIdx->getOnlyLocalDecls(), None,
3148*67e74705SXin Li /*CaptureDiagnostics=*/true,
3149*67e74705SXin Li /*AllowPCHWithCompilerErrors=*/true,
3150*67e74705SXin Li /*UserFilesAreVolatile=*/true);
3151*67e74705SXin Li *out_TU = MakeCXTranslationUnit(CXXIdx, AU.release());
3152*67e74705SXin Li return *out_TU ? CXError_Success : CXError_Failure;
3153*67e74705SXin Li }
3154*67e74705SXin Li
clang_defaultEditingTranslationUnitOptions()3155*67e74705SXin Li unsigned clang_defaultEditingTranslationUnitOptions() {
3156*67e74705SXin Li return CXTranslationUnit_PrecompiledPreamble |
3157*67e74705SXin Li CXTranslationUnit_CacheCompletionResults;
3158*67e74705SXin Li }
3159*67e74705SXin Li
3160*67e74705SXin Li CXTranslationUnit
clang_createTranslationUnitFromSourceFile(CXIndex CIdx,const char * source_filename,int num_command_line_args,const char * const * command_line_args,unsigned num_unsaved_files,struct CXUnsavedFile * unsaved_files)3161*67e74705SXin Li clang_createTranslationUnitFromSourceFile(CXIndex CIdx,
3162*67e74705SXin Li const char *source_filename,
3163*67e74705SXin Li int num_command_line_args,
3164*67e74705SXin Li const char * const *command_line_args,
3165*67e74705SXin Li unsigned num_unsaved_files,
3166*67e74705SXin Li struct CXUnsavedFile *unsaved_files) {
3167*67e74705SXin Li unsigned Options = CXTranslationUnit_DetailedPreprocessingRecord;
3168*67e74705SXin Li return clang_parseTranslationUnit(CIdx, source_filename,
3169*67e74705SXin Li command_line_args, num_command_line_args,
3170*67e74705SXin Li unsaved_files, num_unsaved_files,
3171*67e74705SXin Li Options);
3172*67e74705SXin Li }
3173*67e74705SXin Li
3174*67e74705SXin Li static CXErrorCode
clang_parseTranslationUnit_Impl(CXIndex CIdx,const char * source_filename,const char * const * command_line_args,int num_command_line_args,ArrayRef<CXUnsavedFile> unsaved_files,unsigned options,CXTranslationUnit * out_TU)3175*67e74705SXin Li clang_parseTranslationUnit_Impl(CXIndex CIdx, const char *source_filename,
3176*67e74705SXin Li const char *const *command_line_args,
3177*67e74705SXin Li int num_command_line_args,
3178*67e74705SXin Li ArrayRef<CXUnsavedFile> unsaved_files,
3179*67e74705SXin Li unsigned options, CXTranslationUnit *out_TU) {
3180*67e74705SXin Li // Set up the initial return values.
3181*67e74705SXin Li if (out_TU)
3182*67e74705SXin Li *out_TU = nullptr;
3183*67e74705SXin Li
3184*67e74705SXin Li // Check arguments.
3185*67e74705SXin Li if (!CIdx || !out_TU)
3186*67e74705SXin Li return CXError_InvalidArguments;
3187*67e74705SXin Li
3188*67e74705SXin Li CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
3189*67e74705SXin Li
3190*67e74705SXin Li if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
3191*67e74705SXin Li setThreadBackgroundPriority();
3192*67e74705SXin Li
3193*67e74705SXin Li bool PrecompilePreamble = options & CXTranslationUnit_PrecompiledPreamble;
3194*67e74705SXin Li bool CreatePreambleOnFirstParse =
3195*67e74705SXin Li options & CXTranslationUnit_CreatePreambleOnFirstParse;
3196*67e74705SXin Li // FIXME: Add a flag for modules.
3197*67e74705SXin Li TranslationUnitKind TUKind
3198*67e74705SXin Li = (options & CXTranslationUnit_Incomplete)? TU_Prefix : TU_Complete;
3199*67e74705SXin Li bool CacheCodeCompletionResults
3200*67e74705SXin Li = options & CXTranslationUnit_CacheCompletionResults;
3201*67e74705SXin Li bool IncludeBriefCommentsInCodeCompletion
3202*67e74705SXin Li = options & CXTranslationUnit_IncludeBriefCommentsInCodeCompletion;
3203*67e74705SXin Li bool SkipFunctionBodies = options & CXTranslationUnit_SkipFunctionBodies;
3204*67e74705SXin Li bool ForSerialization = options & CXTranslationUnit_ForSerialization;
3205*67e74705SXin Li
3206*67e74705SXin Li // Configure the diagnostics.
3207*67e74705SXin Li IntrusiveRefCntPtr<DiagnosticsEngine>
3208*67e74705SXin Li Diags(CompilerInstance::createDiagnostics(new DiagnosticOptions));
3209*67e74705SXin Li
3210*67e74705SXin Li if (options & CXTranslationUnit_KeepGoing)
3211*67e74705SXin Li Diags->setFatalsAsError(true);
3212*67e74705SXin Li
3213*67e74705SXin Li // Recover resources if we crash before exiting this function.
3214*67e74705SXin Li llvm::CrashRecoveryContextCleanupRegistrar<DiagnosticsEngine,
3215*67e74705SXin Li llvm::CrashRecoveryContextReleaseRefCleanup<DiagnosticsEngine> >
3216*67e74705SXin Li DiagCleanup(Diags.get());
3217*67e74705SXin Li
3218*67e74705SXin Li std::unique_ptr<std::vector<ASTUnit::RemappedFile>> RemappedFiles(
3219*67e74705SXin Li new std::vector<ASTUnit::RemappedFile>());
3220*67e74705SXin Li
3221*67e74705SXin Li // Recover resources if we crash before exiting this function.
3222*67e74705SXin Li llvm::CrashRecoveryContextCleanupRegistrar<
3223*67e74705SXin Li std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
3224*67e74705SXin Li
3225*67e74705SXin Li for (auto &UF : unsaved_files) {
3226*67e74705SXin Li std::unique_ptr<llvm::MemoryBuffer> MB =
3227*67e74705SXin Li llvm::MemoryBuffer::getMemBufferCopy(getContents(UF), UF.Filename);
3228*67e74705SXin Li RemappedFiles->push_back(std::make_pair(UF.Filename, MB.release()));
3229*67e74705SXin Li }
3230*67e74705SXin Li
3231*67e74705SXin Li std::unique_ptr<std::vector<const char *>> Args(
3232*67e74705SXin Li new std::vector<const char *>());
3233*67e74705SXin Li
3234*67e74705SXin Li // Recover resources if we crash before exiting this method.
3235*67e74705SXin Li llvm::CrashRecoveryContextCleanupRegistrar<std::vector<const char*> >
3236*67e74705SXin Li ArgsCleanup(Args.get());
3237*67e74705SXin Li
3238*67e74705SXin Li // Since the Clang C library is primarily used by batch tools dealing with
3239*67e74705SXin Li // (often very broken) source code, where spell-checking can have a
3240*67e74705SXin Li // significant negative impact on performance (particularly when
3241*67e74705SXin Li // precompiled headers are involved), we disable it by default.
3242*67e74705SXin Li // Only do this if we haven't found a spell-checking-related argument.
3243*67e74705SXin Li bool FoundSpellCheckingArgument = false;
3244*67e74705SXin Li for (int I = 0; I != num_command_line_args; ++I) {
3245*67e74705SXin Li if (strcmp(command_line_args[I], "-fno-spell-checking") == 0 ||
3246*67e74705SXin Li strcmp(command_line_args[I], "-fspell-checking") == 0) {
3247*67e74705SXin Li FoundSpellCheckingArgument = true;
3248*67e74705SXin Li break;
3249*67e74705SXin Li }
3250*67e74705SXin Li }
3251*67e74705SXin Li Args->insert(Args->end(), command_line_args,
3252*67e74705SXin Li command_line_args + num_command_line_args);
3253*67e74705SXin Li
3254*67e74705SXin Li if (!FoundSpellCheckingArgument)
3255*67e74705SXin Li Args->insert(Args->begin() + 1, "-fno-spell-checking");
3256*67e74705SXin Li
3257*67e74705SXin Li // The 'source_filename' argument is optional. If the caller does not
3258*67e74705SXin Li // specify it then it is assumed that the source file is specified
3259*67e74705SXin Li // in the actual argument list.
3260*67e74705SXin Li // Put the source file after command_line_args otherwise if '-x' flag is
3261*67e74705SXin Li // present it will be unused.
3262*67e74705SXin Li if (source_filename)
3263*67e74705SXin Li Args->push_back(source_filename);
3264*67e74705SXin Li
3265*67e74705SXin Li // Do we need the detailed preprocessing record?
3266*67e74705SXin Li if (options & CXTranslationUnit_DetailedPreprocessingRecord) {
3267*67e74705SXin Li Args->push_back("-Xclang");
3268*67e74705SXin Li Args->push_back("-detailed-preprocessing-record");
3269*67e74705SXin Li }
3270*67e74705SXin Li
3271*67e74705SXin Li unsigned NumErrors = Diags->getClient()->getNumErrors();
3272*67e74705SXin Li std::unique_ptr<ASTUnit> ErrUnit;
3273*67e74705SXin Li // Unless the user specified that they want the preamble on the first parse
3274*67e74705SXin Li // set it up to be created on the first reparse. This makes the first parse
3275*67e74705SXin Li // faster, trading for a slower (first) reparse.
3276*67e74705SXin Li unsigned PrecompilePreambleAfterNParses =
3277*67e74705SXin Li !PrecompilePreamble ? 0 : 2 - CreatePreambleOnFirstParse;
3278*67e74705SXin Li std::unique_ptr<ASTUnit> Unit(ASTUnit::LoadFromCommandLine(
3279*67e74705SXin Li Args->data(), Args->data() + Args->size(),
3280*67e74705SXin Li CXXIdx->getPCHContainerOperations(), Diags,
3281*67e74705SXin Li CXXIdx->getClangResourcesPath(), CXXIdx->getOnlyLocalDecls(),
3282*67e74705SXin Li /*CaptureDiagnostics=*/true, *RemappedFiles.get(),
3283*67e74705SXin Li /*RemappedFilesKeepOriginalName=*/true, PrecompilePreambleAfterNParses,
3284*67e74705SXin Li TUKind, CacheCodeCompletionResults, IncludeBriefCommentsInCodeCompletion,
3285*67e74705SXin Li /*AllowPCHWithCompilerErrors=*/true, SkipFunctionBodies,
3286*67e74705SXin Li /*UserFilesAreVolatile=*/true, ForSerialization,
3287*67e74705SXin Li CXXIdx->getPCHContainerOperations()->getRawReader().getFormat(),
3288*67e74705SXin Li &ErrUnit));
3289*67e74705SXin Li
3290*67e74705SXin Li // Early failures in LoadFromCommandLine may return with ErrUnit unset.
3291*67e74705SXin Li if (!Unit && !ErrUnit)
3292*67e74705SXin Li return CXError_ASTReadError;
3293*67e74705SXin Li
3294*67e74705SXin Li if (NumErrors != Diags->getClient()->getNumErrors()) {
3295*67e74705SXin Li // Make sure to check that 'Unit' is non-NULL.
3296*67e74705SXin Li if (CXXIdx->getDisplayDiagnostics())
3297*67e74705SXin Li printDiagsToStderr(Unit ? Unit.get() : ErrUnit.get());
3298*67e74705SXin Li }
3299*67e74705SXin Li
3300*67e74705SXin Li if (isASTReadError(Unit ? Unit.get() : ErrUnit.get()))
3301*67e74705SXin Li return CXError_ASTReadError;
3302*67e74705SXin Li
3303*67e74705SXin Li *out_TU = MakeCXTranslationUnit(CXXIdx, Unit.release());
3304*67e74705SXin Li return *out_TU ? CXError_Success : CXError_Failure;
3305*67e74705SXin Li }
3306*67e74705SXin Li
3307*67e74705SXin Li CXTranslationUnit
clang_parseTranslationUnit(CXIndex CIdx,const char * source_filename,const char * const * command_line_args,int num_command_line_args,struct CXUnsavedFile * unsaved_files,unsigned num_unsaved_files,unsigned options)3308*67e74705SXin Li clang_parseTranslationUnit(CXIndex CIdx,
3309*67e74705SXin Li const char *source_filename,
3310*67e74705SXin Li const char *const *command_line_args,
3311*67e74705SXin Li int num_command_line_args,
3312*67e74705SXin Li struct CXUnsavedFile *unsaved_files,
3313*67e74705SXin Li unsigned num_unsaved_files,
3314*67e74705SXin Li unsigned options) {
3315*67e74705SXin Li CXTranslationUnit TU;
3316*67e74705SXin Li enum CXErrorCode Result = clang_parseTranslationUnit2(
3317*67e74705SXin Li CIdx, source_filename, command_line_args, num_command_line_args,
3318*67e74705SXin Li unsaved_files, num_unsaved_files, options, &TU);
3319*67e74705SXin Li (void)Result;
3320*67e74705SXin Li assert((TU && Result == CXError_Success) ||
3321*67e74705SXin Li (!TU && Result != CXError_Success));
3322*67e74705SXin Li return TU;
3323*67e74705SXin Li }
3324*67e74705SXin Li
clang_parseTranslationUnit2(CXIndex CIdx,const char * source_filename,const char * const * command_line_args,int num_command_line_args,struct CXUnsavedFile * unsaved_files,unsigned num_unsaved_files,unsigned options,CXTranslationUnit * out_TU)3325*67e74705SXin Li enum CXErrorCode clang_parseTranslationUnit2(
3326*67e74705SXin Li CXIndex CIdx, const char *source_filename,
3327*67e74705SXin Li const char *const *command_line_args, int num_command_line_args,
3328*67e74705SXin Li struct CXUnsavedFile *unsaved_files, unsigned num_unsaved_files,
3329*67e74705SXin Li unsigned options, CXTranslationUnit *out_TU) {
3330*67e74705SXin Li SmallVector<const char *, 4> Args;
3331*67e74705SXin Li Args.push_back("clang");
3332*67e74705SXin Li Args.append(command_line_args, command_line_args + num_command_line_args);
3333*67e74705SXin Li return clang_parseTranslationUnit2FullArgv(
3334*67e74705SXin Li CIdx, source_filename, Args.data(), Args.size(), unsaved_files,
3335*67e74705SXin Li num_unsaved_files, options, out_TU);
3336*67e74705SXin Li }
3337*67e74705SXin Li
clang_parseTranslationUnit2FullArgv(CXIndex CIdx,const char * source_filename,const char * const * command_line_args,int num_command_line_args,struct CXUnsavedFile * unsaved_files,unsigned num_unsaved_files,unsigned options,CXTranslationUnit * out_TU)3338*67e74705SXin Li enum CXErrorCode clang_parseTranslationUnit2FullArgv(
3339*67e74705SXin Li CXIndex CIdx, const char *source_filename,
3340*67e74705SXin Li const char *const *command_line_args, int num_command_line_args,
3341*67e74705SXin Li struct CXUnsavedFile *unsaved_files, unsigned num_unsaved_files,
3342*67e74705SXin Li unsigned options, CXTranslationUnit *out_TU) {
3343*67e74705SXin Li LOG_FUNC_SECTION {
3344*67e74705SXin Li *Log << source_filename << ": ";
3345*67e74705SXin Li for (int i = 0; i != num_command_line_args; ++i)
3346*67e74705SXin Li *Log << command_line_args[i] << " ";
3347*67e74705SXin Li }
3348*67e74705SXin Li
3349*67e74705SXin Li if (num_unsaved_files && !unsaved_files)
3350*67e74705SXin Li return CXError_InvalidArguments;
3351*67e74705SXin Li
3352*67e74705SXin Li CXErrorCode result = CXError_Failure;
3353*67e74705SXin Li auto ParseTranslationUnitImpl = [=, &result] {
3354*67e74705SXin Li result = clang_parseTranslationUnit_Impl(
3355*67e74705SXin Li CIdx, source_filename, command_line_args, num_command_line_args,
3356*67e74705SXin Li llvm::makeArrayRef(unsaved_files, num_unsaved_files), options, out_TU);
3357*67e74705SXin Li };
3358*67e74705SXin Li llvm::CrashRecoveryContext CRC;
3359*67e74705SXin Li
3360*67e74705SXin Li if (!RunSafely(CRC, ParseTranslationUnitImpl)) {
3361*67e74705SXin Li fprintf(stderr, "libclang: crash detected during parsing: {\n");
3362*67e74705SXin Li fprintf(stderr, " 'source_filename' : '%s'\n", source_filename);
3363*67e74705SXin Li fprintf(stderr, " 'command_line_args' : [");
3364*67e74705SXin Li for (int i = 0; i != num_command_line_args; ++i) {
3365*67e74705SXin Li if (i)
3366*67e74705SXin Li fprintf(stderr, ", ");
3367*67e74705SXin Li fprintf(stderr, "'%s'", command_line_args[i]);
3368*67e74705SXin Li }
3369*67e74705SXin Li fprintf(stderr, "],\n");
3370*67e74705SXin Li fprintf(stderr, " 'unsaved_files' : [");
3371*67e74705SXin Li for (unsigned i = 0; i != num_unsaved_files; ++i) {
3372*67e74705SXin Li if (i)
3373*67e74705SXin Li fprintf(stderr, ", ");
3374*67e74705SXin Li fprintf(stderr, "('%s', '...', %ld)", unsaved_files[i].Filename,
3375*67e74705SXin Li unsaved_files[i].Length);
3376*67e74705SXin Li }
3377*67e74705SXin Li fprintf(stderr, "],\n");
3378*67e74705SXin Li fprintf(stderr, " 'options' : %d,\n", options);
3379*67e74705SXin Li fprintf(stderr, "}\n");
3380*67e74705SXin Li
3381*67e74705SXin Li return CXError_Crashed;
3382*67e74705SXin Li } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
3383*67e74705SXin Li if (CXTranslationUnit *TU = out_TU)
3384*67e74705SXin Li PrintLibclangResourceUsage(*TU);
3385*67e74705SXin Li }
3386*67e74705SXin Li
3387*67e74705SXin Li return result;
3388*67e74705SXin Li }
3389*67e74705SXin Li
clang_Type_getObjCEncoding(CXType CT)3390*67e74705SXin Li CXString clang_Type_getObjCEncoding(CXType CT) {
3391*67e74705SXin Li CXTranslationUnit tu = static_cast<CXTranslationUnit>(CT.data[1]);
3392*67e74705SXin Li ASTContext &Ctx = getASTUnit(tu)->getASTContext();
3393*67e74705SXin Li std::string encoding;
3394*67e74705SXin Li Ctx.getObjCEncodingForType(QualType::getFromOpaquePtr(CT.data[0]),
3395*67e74705SXin Li encoding);
3396*67e74705SXin Li
3397*67e74705SXin Li return cxstring::createDup(encoding);
3398*67e74705SXin Li }
3399*67e74705SXin Li
getMacroIdentifier(CXCursor C)3400*67e74705SXin Li static const IdentifierInfo *getMacroIdentifier(CXCursor C) {
3401*67e74705SXin Li if (C.kind == CXCursor_MacroDefinition) {
3402*67e74705SXin Li if (const MacroDefinitionRecord *MDR = getCursorMacroDefinition(C))
3403*67e74705SXin Li return MDR->getName();
3404*67e74705SXin Li } else if (C.kind == CXCursor_MacroExpansion) {
3405*67e74705SXin Li MacroExpansionCursor ME = getCursorMacroExpansion(C);
3406*67e74705SXin Li return ME.getName();
3407*67e74705SXin Li }
3408*67e74705SXin Li return nullptr;
3409*67e74705SXin Li }
3410*67e74705SXin Li
clang_Cursor_isMacroFunctionLike(CXCursor C)3411*67e74705SXin Li unsigned clang_Cursor_isMacroFunctionLike(CXCursor C) {
3412*67e74705SXin Li const IdentifierInfo *II = getMacroIdentifier(C);
3413*67e74705SXin Li if (!II) {
3414*67e74705SXin Li return false;
3415*67e74705SXin Li }
3416*67e74705SXin Li ASTUnit *ASTU = getCursorASTUnit(C);
3417*67e74705SXin Li Preprocessor &PP = ASTU->getPreprocessor();
3418*67e74705SXin Li if (const MacroInfo *MI = PP.getMacroInfo(II))
3419*67e74705SXin Li return MI->isFunctionLike();
3420*67e74705SXin Li return false;
3421*67e74705SXin Li }
3422*67e74705SXin Li
clang_Cursor_isMacroBuiltin(CXCursor C)3423*67e74705SXin Li unsigned clang_Cursor_isMacroBuiltin(CXCursor C) {
3424*67e74705SXin Li const IdentifierInfo *II = getMacroIdentifier(C);
3425*67e74705SXin Li if (!II) {
3426*67e74705SXin Li return false;
3427*67e74705SXin Li }
3428*67e74705SXin Li ASTUnit *ASTU = getCursorASTUnit(C);
3429*67e74705SXin Li Preprocessor &PP = ASTU->getPreprocessor();
3430*67e74705SXin Li if (const MacroInfo *MI = PP.getMacroInfo(II))
3431*67e74705SXin Li return MI->isBuiltinMacro();
3432*67e74705SXin Li return false;
3433*67e74705SXin Li }
3434*67e74705SXin Li
clang_Cursor_isFunctionInlined(CXCursor C)3435*67e74705SXin Li unsigned clang_Cursor_isFunctionInlined(CXCursor C) {
3436*67e74705SXin Li const Decl *D = getCursorDecl(C);
3437*67e74705SXin Li const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(D);
3438*67e74705SXin Li if (!FD) {
3439*67e74705SXin Li return false;
3440*67e74705SXin Li }
3441*67e74705SXin Li return FD->isInlined();
3442*67e74705SXin Li }
3443*67e74705SXin Li
getCFSTR_value(CallExpr * callExpr)3444*67e74705SXin Li static StringLiteral* getCFSTR_value(CallExpr *callExpr) {
3445*67e74705SXin Li if (callExpr->getNumArgs() != 1) {
3446*67e74705SXin Li return nullptr;
3447*67e74705SXin Li }
3448*67e74705SXin Li
3449*67e74705SXin Li StringLiteral *S = nullptr;
3450*67e74705SXin Li auto *arg = callExpr->getArg(0);
3451*67e74705SXin Li if (arg->getStmtClass() == Stmt::ImplicitCastExprClass) {
3452*67e74705SXin Li ImplicitCastExpr *I = static_cast<ImplicitCastExpr *>(arg);
3453*67e74705SXin Li auto *subExpr = I->getSubExprAsWritten();
3454*67e74705SXin Li
3455*67e74705SXin Li if(subExpr->getStmtClass() != Stmt::StringLiteralClass){
3456*67e74705SXin Li return nullptr;
3457*67e74705SXin Li }
3458*67e74705SXin Li
3459*67e74705SXin Li S = static_cast<StringLiteral *>(I->getSubExprAsWritten());
3460*67e74705SXin Li } else if (arg->getStmtClass() == Stmt::StringLiteralClass) {
3461*67e74705SXin Li S = static_cast<StringLiteral *>(callExpr->getArg(0));
3462*67e74705SXin Li } else {
3463*67e74705SXin Li return nullptr;
3464*67e74705SXin Li }
3465*67e74705SXin Li return S;
3466*67e74705SXin Li }
3467*67e74705SXin Li
3468*67e74705SXin Li struct ExprEvalResult {
3469*67e74705SXin Li CXEvalResultKind EvalType;
3470*67e74705SXin Li union {
3471*67e74705SXin Li int intVal;
3472*67e74705SXin Li double floatVal;
3473*67e74705SXin Li char *stringVal;
3474*67e74705SXin Li } EvalData;
~ExprEvalResultExprEvalResult3475*67e74705SXin Li ~ExprEvalResult() {
3476*67e74705SXin Li if (EvalType != CXEval_UnExposed && EvalType != CXEval_Float &&
3477*67e74705SXin Li EvalType != CXEval_Int) {
3478*67e74705SXin Li delete EvalData.stringVal;
3479*67e74705SXin Li }
3480*67e74705SXin Li }
3481*67e74705SXin Li };
3482*67e74705SXin Li
clang_EvalResult_dispose(CXEvalResult E)3483*67e74705SXin Li void clang_EvalResult_dispose(CXEvalResult E) {
3484*67e74705SXin Li delete static_cast<ExprEvalResult *>(E);
3485*67e74705SXin Li }
3486*67e74705SXin Li
clang_EvalResult_getKind(CXEvalResult E)3487*67e74705SXin Li CXEvalResultKind clang_EvalResult_getKind(CXEvalResult E) {
3488*67e74705SXin Li if (!E) {
3489*67e74705SXin Li return CXEval_UnExposed;
3490*67e74705SXin Li }
3491*67e74705SXin Li return ((ExprEvalResult *)E)->EvalType;
3492*67e74705SXin Li }
3493*67e74705SXin Li
clang_EvalResult_getAsInt(CXEvalResult E)3494*67e74705SXin Li int clang_EvalResult_getAsInt(CXEvalResult E) {
3495*67e74705SXin Li if (!E) {
3496*67e74705SXin Li return 0;
3497*67e74705SXin Li }
3498*67e74705SXin Li return ((ExprEvalResult *)E)->EvalData.intVal;
3499*67e74705SXin Li }
3500*67e74705SXin Li
clang_EvalResult_getAsDouble(CXEvalResult E)3501*67e74705SXin Li double clang_EvalResult_getAsDouble(CXEvalResult E) {
3502*67e74705SXin Li if (!E) {
3503*67e74705SXin Li return 0;
3504*67e74705SXin Li }
3505*67e74705SXin Li return ((ExprEvalResult *)E)->EvalData.floatVal;
3506*67e74705SXin Li }
3507*67e74705SXin Li
clang_EvalResult_getAsStr(CXEvalResult E)3508*67e74705SXin Li const char* clang_EvalResult_getAsStr(CXEvalResult E) {
3509*67e74705SXin Li if (!E) {
3510*67e74705SXin Li return nullptr;
3511*67e74705SXin Li }
3512*67e74705SXin Li return ((ExprEvalResult *)E)->EvalData.stringVal;
3513*67e74705SXin Li }
3514*67e74705SXin Li
evaluateExpr(Expr * expr,CXCursor C)3515*67e74705SXin Li static const ExprEvalResult* evaluateExpr(Expr *expr, CXCursor C) {
3516*67e74705SXin Li Expr::EvalResult ER;
3517*67e74705SXin Li ASTContext &ctx = getCursorContext(C);
3518*67e74705SXin Li if (!expr)
3519*67e74705SXin Li return nullptr;
3520*67e74705SXin Li
3521*67e74705SXin Li expr = expr->IgnoreParens();
3522*67e74705SXin Li if (!expr->EvaluateAsRValue(ER, ctx))
3523*67e74705SXin Li return nullptr;
3524*67e74705SXin Li
3525*67e74705SXin Li QualType rettype;
3526*67e74705SXin Li CallExpr *callExpr;
3527*67e74705SXin Li auto result = llvm::make_unique<ExprEvalResult>();
3528*67e74705SXin Li result->EvalType = CXEval_UnExposed;
3529*67e74705SXin Li
3530*67e74705SXin Li if (ER.Val.isInt()) {
3531*67e74705SXin Li result->EvalType = CXEval_Int;
3532*67e74705SXin Li result->EvalData.intVal = ER.Val.getInt().getExtValue();
3533*67e74705SXin Li return result.release();
3534*67e74705SXin Li }
3535*67e74705SXin Li
3536*67e74705SXin Li if (ER.Val.isFloat()) {
3537*67e74705SXin Li llvm::SmallVector<char, 100> Buffer;
3538*67e74705SXin Li ER.Val.getFloat().toString(Buffer);
3539*67e74705SXin Li std::string floatStr(Buffer.data(), Buffer.size());
3540*67e74705SXin Li result->EvalType = CXEval_Float;
3541*67e74705SXin Li bool ignored;
3542*67e74705SXin Li llvm::APFloat apFloat = ER.Val.getFloat();
3543*67e74705SXin Li apFloat.convert(llvm::APFloat::IEEEdouble,
3544*67e74705SXin Li llvm::APFloat::rmNearestTiesToEven, &ignored);
3545*67e74705SXin Li result->EvalData.floatVal = apFloat.convertToDouble();
3546*67e74705SXin Li return result.release();
3547*67e74705SXin Li }
3548*67e74705SXin Li
3549*67e74705SXin Li if (expr->getStmtClass() == Stmt::ImplicitCastExprClass) {
3550*67e74705SXin Li const ImplicitCastExpr *I = dyn_cast<ImplicitCastExpr>(expr);
3551*67e74705SXin Li auto *subExpr = I->getSubExprAsWritten();
3552*67e74705SXin Li if (subExpr->getStmtClass() == Stmt::StringLiteralClass ||
3553*67e74705SXin Li subExpr->getStmtClass() == Stmt::ObjCStringLiteralClass) {
3554*67e74705SXin Li const StringLiteral *StrE = nullptr;
3555*67e74705SXin Li const ObjCStringLiteral *ObjCExpr;
3556*67e74705SXin Li ObjCExpr = dyn_cast<ObjCStringLiteral>(subExpr);
3557*67e74705SXin Li
3558*67e74705SXin Li if (ObjCExpr) {
3559*67e74705SXin Li StrE = ObjCExpr->getString();
3560*67e74705SXin Li result->EvalType = CXEval_ObjCStrLiteral;
3561*67e74705SXin Li } else {
3562*67e74705SXin Li StrE = cast<StringLiteral>(I->getSubExprAsWritten());
3563*67e74705SXin Li result->EvalType = CXEval_StrLiteral;
3564*67e74705SXin Li }
3565*67e74705SXin Li
3566*67e74705SXin Li std::string strRef(StrE->getString().str());
3567*67e74705SXin Li result->EvalData.stringVal = new char[strRef.size() + 1];
3568*67e74705SXin Li strncpy((char *)result->EvalData.stringVal, strRef.c_str(),
3569*67e74705SXin Li strRef.size());
3570*67e74705SXin Li result->EvalData.stringVal[strRef.size()] = '\0';
3571*67e74705SXin Li return result.release();
3572*67e74705SXin Li }
3573*67e74705SXin Li } else if (expr->getStmtClass() == Stmt::ObjCStringLiteralClass ||
3574*67e74705SXin Li expr->getStmtClass() == Stmt::StringLiteralClass) {
3575*67e74705SXin Li const StringLiteral *StrE = nullptr;
3576*67e74705SXin Li const ObjCStringLiteral *ObjCExpr;
3577*67e74705SXin Li ObjCExpr = dyn_cast<ObjCStringLiteral>(expr);
3578*67e74705SXin Li
3579*67e74705SXin Li if (ObjCExpr) {
3580*67e74705SXin Li StrE = ObjCExpr->getString();
3581*67e74705SXin Li result->EvalType = CXEval_ObjCStrLiteral;
3582*67e74705SXin Li } else {
3583*67e74705SXin Li StrE = cast<StringLiteral>(expr);
3584*67e74705SXin Li result->EvalType = CXEval_StrLiteral;
3585*67e74705SXin Li }
3586*67e74705SXin Li
3587*67e74705SXin Li std::string strRef(StrE->getString().str());
3588*67e74705SXin Li result->EvalData.stringVal = new char[strRef.size() + 1];
3589*67e74705SXin Li strncpy((char *)result->EvalData.stringVal, strRef.c_str(), strRef.size());
3590*67e74705SXin Li result->EvalData.stringVal[strRef.size()] = '\0';
3591*67e74705SXin Li return result.release();
3592*67e74705SXin Li }
3593*67e74705SXin Li
3594*67e74705SXin Li if (expr->getStmtClass() == Stmt::CStyleCastExprClass) {
3595*67e74705SXin Li CStyleCastExpr *CC = static_cast<CStyleCastExpr *>(expr);
3596*67e74705SXin Li
3597*67e74705SXin Li rettype = CC->getType();
3598*67e74705SXin Li if (rettype.getAsString() == "CFStringRef" &&
3599*67e74705SXin Li CC->getSubExpr()->getStmtClass() == Stmt::CallExprClass) {
3600*67e74705SXin Li
3601*67e74705SXin Li callExpr = static_cast<CallExpr *>(CC->getSubExpr());
3602*67e74705SXin Li StringLiteral *S = getCFSTR_value(callExpr);
3603*67e74705SXin Li if (S) {
3604*67e74705SXin Li std::string strLiteral(S->getString().str());
3605*67e74705SXin Li result->EvalType = CXEval_CFStr;
3606*67e74705SXin Li
3607*67e74705SXin Li result->EvalData.stringVal = new char[strLiteral.size() + 1];
3608*67e74705SXin Li strncpy((char *)result->EvalData.stringVal, strLiteral.c_str(),
3609*67e74705SXin Li strLiteral.size());
3610*67e74705SXin Li result->EvalData.stringVal[strLiteral.size()] = '\0';
3611*67e74705SXin Li return result.release();
3612*67e74705SXin Li }
3613*67e74705SXin Li }
3614*67e74705SXin Li
3615*67e74705SXin Li } else if (expr->getStmtClass() == Stmt::CallExprClass) {
3616*67e74705SXin Li callExpr = static_cast<CallExpr *>(expr);
3617*67e74705SXin Li rettype = callExpr->getCallReturnType(ctx);
3618*67e74705SXin Li
3619*67e74705SXin Li if (rettype->isVectorType() || callExpr->getNumArgs() > 1)
3620*67e74705SXin Li return nullptr;
3621*67e74705SXin Li
3622*67e74705SXin Li if (rettype->isIntegralType(ctx) || rettype->isRealFloatingType()) {
3623*67e74705SXin Li if (callExpr->getNumArgs() == 1 &&
3624*67e74705SXin Li !callExpr->getArg(0)->getType()->isIntegralType(ctx))
3625*67e74705SXin Li return nullptr;
3626*67e74705SXin Li } else if (rettype.getAsString() == "CFStringRef") {
3627*67e74705SXin Li
3628*67e74705SXin Li StringLiteral *S = getCFSTR_value(callExpr);
3629*67e74705SXin Li if (S) {
3630*67e74705SXin Li std::string strLiteral(S->getString().str());
3631*67e74705SXin Li result->EvalType = CXEval_CFStr;
3632*67e74705SXin Li result->EvalData.stringVal = new char[strLiteral.size() + 1];
3633*67e74705SXin Li strncpy((char *)result->EvalData.stringVal, strLiteral.c_str(),
3634*67e74705SXin Li strLiteral.size());
3635*67e74705SXin Li result->EvalData.stringVal[strLiteral.size()] = '\0';
3636*67e74705SXin Li return result.release();
3637*67e74705SXin Li }
3638*67e74705SXin Li }
3639*67e74705SXin Li } else if (expr->getStmtClass() == Stmt::DeclRefExprClass) {
3640*67e74705SXin Li DeclRefExpr *D = static_cast<DeclRefExpr *>(expr);
3641*67e74705SXin Li ValueDecl *V = D->getDecl();
3642*67e74705SXin Li if (V->getKind() == Decl::Function) {
3643*67e74705SXin Li std::string strName = V->getNameAsString();
3644*67e74705SXin Li result->EvalType = CXEval_Other;
3645*67e74705SXin Li result->EvalData.stringVal = new char[strName.size() + 1];
3646*67e74705SXin Li strncpy(result->EvalData.stringVal, strName.c_str(), strName.size());
3647*67e74705SXin Li result->EvalData.stringVal[strName.size()] = '\0';
3648*67e74705SXin Li return result.release();
3649*67e74705SXin Li }
3650*67e74705SXin Li }
3651*67e74705SXin Li
3652*67e74705SXin Li return nullptr;
3653*67e74705SXin Li }
3654*67e74705SXin Li
clang_Cursor_Evaluate(CXCursor C)3655*67e74705SXin Li CXEvalResult clang_Cursor_Evaluate(CXCursor C) {
3656*67e74705SXin Li const Decl *D = getCursorDecl(C);
3657*67e74705SXin Li if (D) {
3658*67e74705SXin Li const Expr *expr = nullptr;
3659*67e74705SXin Li if (auto *Var = dyn_cast<VarDecl>(D)) {
3660*67e74705SXin Li expr = Var->getInit();
3661*67e74705SXin Li } else if (auto *Field = dyn_cast<FieldDecl>(D)) {
3662*67e74705SXin Li expr = Field->getInClassInitializer();
3663*67e74705SXin Li }
3664*67e74705SXin Li if (expr)
3665*67e74705SXin Li return const_cast<CXEvalResult>(reinterpret_cast<const void *>(
3666*67e74705SXin Li evaluateExpr(const_cast<Expr *>(expr), C)));
3667*67e74705SXin Li return nullptr;
3668*67e74705SXin Li }
3669*67e74705SXin Li
3670*67e74705SXin Li const CompoundStmt *compoundStmt = dyn_cast_or_null<CompoundStmt>(getCursorStmt(C));
3671*67e74705SXin Li if (compoundStmt) {
3672*67e74705SXin Li Expr *expr = nullptr;
3673*67e74705SXin Li for (auto *bodyIterator : compoundStmt->body()) {
3674*67e74705SXin Li if ((expr = dyn_cast<Expr>(bodyIterator))) {
3675*67e74705SXin Li break;
3676*67e74705SXin Li }
3677*67e74705SXin Li }
3678*67e74705SXin Li if (expr)
3679*67e74705SXin Li return const_cast<CXEvalResult>(
3680*67e74705SXin Li reinterpret_cast<const void *>(evaluateExpr(expr, C)));
3681*67e74705SXin Li }
3682*67e74705SXin Li return nullptr;
3683*67e74705SXin Li }
3684*67e74705SXin Li
clang_Cursor_hasAttrs(CXCursor C)3685*67e74705SXin Li unsigned clang_Cursor_hasAttrs(CXCursor C) {
3686*67e74705SXin Li const Decl *D = getCursorDecl(C);
3687*67e74705SXin Li if (!D) {
3688*67e74705SXin Li return 0;
3689*67e74705SXin Li }
3690*67e74705SXin Li
3691*67e74705SXin Li if (D->hasAttrs()) {
3692*67e74705SXin Li return 1;
3693*67e74705SXin Li }
3694*67e74705SXin Li
3695*67e74705SXin Li return 0;
3696*67e74705SXin Li }
clang_defaultSaveOptions(CXTranslationUnit TU)3697*67e74705SXin Li unsigned clang_defaultSaveOptions(CXTranslationUnit TU) {
3698*67e74705SXin Li return CXSaveTranslationUnit_None;
3699*67e74705SXin Li }
3700*67e74705SXin Li
clang_saveTranslationUnit_Impl(CXTranslationUnit TU,const char * FileName,unsigned options)3701*67e74705SXin Li static CXSaveError clang_saveTranslationUnit_Impl(CXTranslationUnit TU,
3702*67e74705SXin Li const char *FileName,
3703*67e74705SXin Li unsigned options) {
3704*67e74705SXin Li CIndexer *CXXIdx = TU->CIdx;
3705*67e74705SXin Li if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
3706*67e74705SXin Li setThreadBackgroundPriority();
3707*67e74705SXin Li
3708*67e74705SXin Li bool hadError = cxtu::getASTUnit(TU)->Save(FileName);
3709*67e74705SXin Li return hadError ? CXSaveError_Unknown : CXSaveError_None;
3710*67e74705SXin Li }
3711*67e74705SXin Li
clang_saveTranslationUnit(CXTranslationUnit TU,const char * FileName,unsigned options)3712*67e74705SXin Li int clang_saveTranslationUnit(CXTranslationUnit TU, const char *FileName,
3713*67e74705SXin Li unsigned options) {
3714*67e74705SXin Li LOG_FUNC_SECTION {
3715*67e74705SXin Li *Log << TU << ' ' << FileName;
3716*67e74705SXin Li }
3717*67e74705SXin Li
3718*67e74705SXin Li if (isNotUsableTU(TU)) {
3719*67e74705SXin Li LOG_BAD_TU(TU);
3720*67e74705SXin Li return CXSaveError_InvalidTU;
3721*67e74705SXin Li }
3722*67e74705SXin Li
3723*67e74705SXin Li ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
3724*67e74705SXin Li ASTUnit::ConcurrencyCheck Check(*CXXUnit);
3725*67e74705SXin Li if (!CXXUnit->hasSema())
3726*67e74705SXin Li return CXSaveError_InvalidTU;
3727*67e74705SXin Li
3728*67e74705SXin Li CXSaveError result;
3729*67e74705SXin Li auto SaveTranslationUnitImpl = [=, &result]() {
3730*67e74705SXin Li result = clang_saveTranslationUnit_Impl(TU, FileName, options);
3731*67e74705SXin Li };
3732*67e74705SXin Li
3733*67e74705SXin Li if (!CXXUnit->getDiagnostics().hasUnrecoverableErrorOccurred() ||
3734*67e74705SXin Li getenv("LIBCLANG_NOTHREADS")) {
3735*67e74705SXin Li SaveTranslationUnitImpl();
3736*67e74705SXin Li
3737*67e74705SXin Li if (getenv("LIBCLANG_RESOURCE_USAGE"))
3738*67e74705SXin Li PrintLibclangResourceUsage(TU);
3739*67e74705SXin Li
3740*67e74705SXin Li return result;
3741*67e74705SXin Li }
3742*67e74705SXin Li
3743*67e74705SXin Li // We have an AST that has invalid nodes due to compiler errors.
3744*67e74705SXin Li // Use a crash recovery thread for protection.
3745*67e74705SXin Li
3746*67e74705SXin Li llvm::CrashRecoveryContext CRC;
3747*67e74705SXin Li
3748*67e74705SXin Li if (!RunSafely(CRC, SaveTranslationUnitImpl)) {
3749*67e74705SXin Li fprintf(stderr, "libclang: crash detected during AST saving: {\n");
3750*67e74705SXin Li fprintf(stderr, " 'filename' : '%s'\n", FileName);
3751*67e74705SXin Li fprintf(stderr, " 'options' : %d,\n", options);
3752*67e74705SXin Li fprintf(stderr, "}\n");
3753*67e74705SXin Li
3754*67e74705SXin Li return CXSaveError_Unknown;
3755*67e74705SXin Li
3756*67e74705SXin Li } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
3757*67e74705SXin Li PrintLibclangResourceUsage(TU);
3758*67e74705SXin Li }
3759*67e74705SXin Li
3760*67e74705SXin Li return result;
3761*67e74705SXin Li }
3762*67e74705SXin Li
clang_disposeTranslationUnit(CXTranslationUnit CTUnit)3763*67e74705SXin Li void clang_disposeTranslationUnit(CXTranslationUnit CTUnit) {
3764*67e74705SXin Li if (CTUnit) {
3765*67e74705SXin Li // If the translation unit has been marked as unsafe to free, just discard
3766*67e74705SXin Li // it.
3767*67e74705SXin Li ASTUnit *Unit = cxtu::getASTUnit(CTUnit);
3768*67e74705SXin Li if (Unit && Unit->isUnsafeToFree())
3769*67e74705SXin Li return;
3770*67e74705SXin Li
3771*67e74705SXin Li delete cxtu::getASTUnit(CTUnit);
3772*67e74705SXin Li delete CTUnit->StringPool;
3773*67e74705SXin Li delete static_cast<CXDiagnosticSetImpl *>(CTUnit->Diagnostics);
3774*67e74705SXin Li disposeOverridenCXCursorsPool(CTUnit->OverridenCursorsPool);
3775*67e74705SXin Li delete CTUnit->CommentToXML;
3776*67e74705SXin Li delete CTUnit;
3777*67e74705SXin Li }
3778*67e74705SXin Li }
3779*67e74705SXin Li
clang_defaultReparseOptions(CXTranslationUnit TU)3780*67e74705SXin Li unsigned clang_defaultReparseOptions(CXTranslationUnit TU) {
3781*67e74705SXin Li return CXReparse_None;
3782*67e74705SXin Li }
3783*67e74705SXin Li
3784*67e74705SXin Li static CXErrorCode
clang_reparseTranslationUnit_Impl(CXTranslationUnit TU,ArrayRef<CXUnsavedFile> unsaved_files,unsigned options)3785*67e74705SXin Li clang_reparseTranslationUnit_Impl(CXTranslationUnit TU,
3786*67e74705SXin Li ArrayRef<CXUnsavedFile> unsaved_files,
3787*67e74705SXin Li unsigned options) {
3788*67e74705SXin Li // Check arguments.
3789*67e74705SXin Li if (isNotUsableTU(TU)) {
3790*67e74705SXin Li LOG_BAD_TU(TU);
3791*67e74705SXin Li return CXError_InvalidArguments;
3792*67e74705SXin Li }
3793*67e74705SXin Li
3794*67e74705SXin Li // Reset the associated diagnostics.
3795*67e74705SXin Li delete static_cast<CXDiagnosticSetImpl*>(TU->Diagnostics);
3796*67e74705SXin Li TU->Diagnostics = nullptr;
3797*67e74705SXin Li
3798*67e74705SXin Li CIndexer *CXXIdx = TU->CIdx;
3799*67e74705SXin Li if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
3800*67e74705SXin Li setThreadBackgroundPriority();
3801*67e74705SXin Li
3802*67e74705SXin Li ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
3803*67e74705SXin Li ASTUnit::ConcurrencyCheck Check(*CXXUnit);
3804*67e74705SXin Li
3805*67e74705SXin Li std::unique_ptr<std::vector<ASTUnit::RemappedFile>> RemappedFiles(
3806*67e74705SXin Li new std::vector<ASTUnit::RemappedFile>());
3807*67e74705SXin Li
3808*67e74705SXin Li // Recover resources if we crash before exiting this function.
3809*67e74705SXin Li llvm::CrashRecoveryContextCleanupRegistrar<
3810*67e74705SXin Li std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
3811*67e74705SXin Li
3812*67e74705SXin Li for (auto &UF : unsaved_files) {
3813*67e74705SXin Li std::unique_ptr<llvm::MemoryBuffer> MB =
3814*67e74705SXin Li llvm::MemoryBuffer::getMemBufferCopy(getContents(UF), UF.Filename);
3815*67e74705SXin Li RemappedFiles->push_back(std::make_pair(UF.Filename, MB.release()));
3816*67e74705SXin Li }
3817*67e74705SXin Li
3818*67e74705SXin Li if (!CXXUnit->Reparse(CXXIdx->getPCHContainerOperations(),
3819*67e74705SXin Li *RemappedFiles.get()))
3820*67e74705SXin Li return CXError_Success;
3821*67e74705SXin Li if (isASTReadError(CXXUnit))
3822*67e74705SXin Li return CXError_ASTReadError;
3823*67e74705SXin Li return CXError_Failure;
3824*67e74705SXin Li }
3825*67e74705SXin Li
clang_reparseTranslationUnit(CXTranslationUnit TU,unsigned num_unsaved_files,struct CXUnsavedFile * unsaved_files,unsigned options)3826*67e74705SXin Li int clang_reparseTranslationUnit(CXTranslationUnit TU,
3827*67e74705SXin Li unsigned num_unsaved_files,
3828*67e74705SXin Li struct CXUnsavedFile *unsaved_files,
3829*67e74705SXin Li unsigned options) {
3830*67e74705SXin Li LOG_FUNC_SECTION {
3831*67e74705SXin Li *Log << TU;
3832*67e74705SXin Li }
3833*67e74705SXin Li
3834*67e74705SXin Li if (num_unsaved_files && !unsaved_files)
3835*67e74705SXin Li return CXError_InvalidArguments;
3836*67e74705SXin Li
3837*67e74705SXin Li CXErrorCode result;
3838*67e74705SXin Li auto ReparseTranslationUnitImpl = [=, &result]() {
3839*67e74705SXin Li result = clang_reparseTranslationUnit_Impl(
3840*67e74705SXin Li TU, llvm::makeArrayRef(unsaved_files, num_unsaved_files), options);
3841*67e74705SXin Li };
3842*67e74705SXin Li
3843*67e74705SXin Li if (getenv("LIBCLANG_NOTHREADS")) {
3844*67e74705SXin Li ReparseTranslationUnitImpl();
3845*67e74705SXin Li return result;
3846*67e74705SXin Li }
3847*67e74705SXin Li
3848*67e74705SXin Li llvm::CrashRecoveryContext CRC;
3849*67e74705SXin Li
3850*67e74705SXin Li if (!RunSafely(CRC, ReparseTranslationUnitImpl)) {
3851*67e74705SXin Li fprintf(stderr, "libclang: crash detected during reparsing\n");
3852*67e74705SXin Li cxtu::getASTUnit(TU)->setUnsafeToFree(true);
3853*67e74705SXin Li return CXError_Crashed;
3854*67e74705SXin Li } else if (getenv("LIBCLANG_RESOURCE_USAGE"))
3855*67e74705SXin Li PrintLibclangResourceUsage(TU);
3856*67e74705SXin Li
3857*67e74705SXin Li return result;
3858*67e74705SXin Li }
3859*67e74705SXin Li
3860*67e74705SXin Li
clang_getTranslationUnitSpelling(CXTranslationUnit CTUnit)3861*67e74705SXin Li CXString clang_getTranslationUnitSpelling(CXTranslationUnit CTUnit) {
3862*67e74705SXin Li if (isNotUsableTU(CTUnit)) {
3863*67e74705SXin Li LOG_BAD_TU(CTUnit);
3864*67e74705SXin Li return cxstring::createEmpty();
3865*67e74705SXin Li }
3866*67e74705SXin Li
3867*67e74705SXin Li ASTUnit *CXXUnit = cxtu::getASTUnit(CTUnit);
3868*67e74705SXin Li return cxstring::createDup(CXXUnit->getOriginalSourceFileName());
3869*67e74705SXin Li }
3870*67e74705SXin Li
clang_getTranslationUnitCursor(CXTranslationUnit TU)3871*67e74705SXin Li CXCursor clang_getTranslationUnitCursor(CXTranslationUnit TU) {
3872*67e74705SXin Li if (isNotUsableTU(TU)) {
3873*67e74705SXin Li LOG_BAD_TU(TU);
3874*67e74705SXin Li return clang_getNullCursor();
3875*67e74705SXin Li }
3876*67e74705SXin Li
3877*67e74705SXin Li ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
3878*67e74705SXin Li return MakeCXCursor(CXXUnit->getASTContext().getTranslationUnitDecl(), TU);
3879*67e74705SXin Li }
3880*67e74705SXin Li
3881*67e74705SXin Li } // end: extern "C"
3882*67e74705SXin Li
3883*67e74705SXin Li //===----------------------------------------------------------------------===//
3884*67e74705SXin Li // CXFile Operations.
3885*67e74705SXin Li //===----------------------------------------------------------------------===//
3886*67e74705SXin Li
3887*67e74705SXin Li extern "C" {
clang_getFileName(CXFile SFile)3888*67e74705SXin Li CXString clang_getFileName(CXFile SFile) {
3889*67e74705SXin Li if (!SFile)
3890*67e74705SXin Li return cxstring::createNull();
3891*67e74705SXin Li
3892*67e74705SXin Li FileEntry *FEnt = static_cast<FileEntry *>(SFile);
3893*67e74705SXin Li return cxstring::createRef(FEnt->getName());
3894*67e74705SXin Li }
3895*67e74705SXin Li
clang_getFileTime(CXFile SFile)3896*67e74705SXin Li time_t clang_getFileTime(CXFile SFile) {
3897*67e74705SXin Li if (!SFile)
3898*67e74705SXin Li return 0;
3899*67e74705SXin Li
3900*67e74705SXin Li FileEntry *FEnt = static_cast<FileEntry *>(SFile);
3901*67e74705SXin Li return FEnt->getModificationTime();
3902*67e74705SXin Li }
3903*67e74705SXin Li
clang_getFile(CXTranslationUnit TU,const char * file_name)3904*67e74705SXin Li CXFile clang_getFile(CXTranslationUnit TU, const char *file_name) {
3905*67e74705SXin Li if (isNotUsableTU(TU)) {
3906*67e74705SXin Li LOG_BAD_TU(TU);
3907*67e74705SXin Li return nullptr;
3908*67e74705SXin Li }
3909*67e74705SXin Li
3910*67e74705SXin Li ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
3911*67e74705SXin Li
3912*67e74705SXin Li FileManager &FMgr = CXXUnit->getFileManager();
3913*67e74705SXin Li return const_cast<FileEntry *>(FMgr.getFile(file_name));
3914*67e74705SXin Li }
3915*67e74705SXin Li
clang_isFileMultipleIncludeGuarded(CXTranslationUnit TU,CXFile file)3916*67e74705SXin Li unsigned clang_isFileMultipleIncludeGuarded(CXTranslationUnit TU,
3917*67e74705SXin Li CXFile file) {
3918*67e74705SXin Li if (isNotUsableTU(TU)) {
3919*67e74705SXin Li LOG_BAD_TU(TU);
3920*67e74705SXin Li return 0;
3921*67e74705SXin Li }
3922*67e74705SXin Li
3923*67e74705SXin Li if (!file)
3924*67e74705SXin Li return 0;
3925*67e74705SXin Li
3926*67e74705SXin Li ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
3927*67e74705SXin Li FileEntry *FEnt = static_cast<FileEntry *>(file);
3928*67e74705SXin Li return CXXUnit->getPreprocessor().getHeaderSearchInfo()
3929*67e74705SXin Li .isFileMultipleIncludeGuarded(FEnt);
3930*67e74705SXin Li }
3931*67e74705SXin Li
clang_getFileUniqueID(CXFile file,CXFileUniqueID * outID)3932*67e74705SXin Li int clang_getFileUniqueID(CXFile file, CXFileUniqueID *outID) {
3933*67e74705SXin Li if (!file || !outID)
3934*67e74705SXin Li return 1;
3935*67e74705SXin Li
3936*67e74705SXin Li FileEntry *FEnt = static_cast<FileEntry *>(file);
3937*67e74705SXin Li const llvm::sys::fs::UniqueID &ID = FEnt->getUniqueID();
3938*67e74705SXin Li outID->data[0] = ID.getDevice();
3939*67e74705SXin Li outID->data[1] = ID.getFile();
3940*67e74705SXin Li outID->data[2] = FEnt->getModificationTime();
3941*67e74705SXin Li return 0;
3942*67e74705SXin Li }
3943*67e74705SXin Li
clang_File_isEqual(CXFile file1,CXFile file2)3944*67e74705SXin Li int clang_File_isEqual(CXFile file1, CXFile file2) {
3945*67e74705SXin Li if (file1 == file2)
3946*67e74705SXin Li return true;
3947*67e74705SXin Li
3948*67e74705SXin Li if (!file1 || !file2)
3949*67e74705SXin Li return false;
3950*67e74705SXin Li
3951*67e74705SXin Li FileEntry *FEnt1 = static_cast<FileEntry *>(file1);
3952*67e74705SXin Li FileEntry *FEnt2 = static_cast<FileEntry *>(file2);
3953*67e74705SXin Li return FEnt1->getUniqueID() == FEnt2->getUniqueID();
3954*67e74705SXin Li }
3955*67e74705SXin Li
3956*67e74705SXin Li } // end: extern "C"
3957*67e74705SXin Li
3958*67e74705SXin Li //===----------------------------------------------------------------------===//
3959*67e74705SXin Li // CXCursor Operations.
3960*67e74705SXin Li //===----------------------------------------------------------------------===//
3961*67e74705SXin Li
getDeclFromExpr(const Stmt * E)3962*67e74705SXin Li static const Decl *getDeclFromExpr(const Stmt *E) {
3963*67e74705SXin Li if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
3964*67e74705SXin Li return getDeclFromExpr(CE->getSubExpr());
3965*67e74705SXin Li
3966*67e74705SXin Li if (const DeclRefExpr *RefExpr = dyn_cast<DeclRefExpr>(E))
3967*67e74705SXin Li return RefExpr->getDecl();
3968*67e74705SXin Li if (const MemberExpr *ME = dyn_cast<MemberExpr>(E))
3969*67e74705SXin Li return ME->getMemberDecl();
3970*67e74705SXin Li if (const ObjCIvarRefExpr *RE = dyn_cast<ObjCIvarRefExpr>(E))
3971*67e74705SXin Li return RE->getDecl();
3972*67e74705SXin Li if (const ObjCPropertyRefExpr *PRE = dyn_cast<ObjCPropertyRefExpr>(E)) {
3973*67e74705SXin Li if (PRE->isExplicitProperty())
3974*67e74705SXin Li return PRE->getExplicitProperty();
3975*67e74705SXin Li // It could be messaging both getter and setter as in:
3976*67e74705SXin Li // ++myobj.myprop;
3977*67e74705SXin Li // in which case prefer to associate the setter since it is less obvious
3978*67e74705SXin Li // from inspecting the source that the setter is going to get called.
3979*67e74705SXin Li if (PRE->isMessagingSetter())
3980*67e74705SXin Li return PRE->getImplicitPropertySetter();
3981*67e74705SXin Li return PRE->getImplicitPropertyGetter();
3982*67e74705SXin Li }
3983*67e74705SXin Li if (const PseudoObjectExpr *POE = dyn_cast<PseudoObjectExpr>(E))
3984*67e74705SXin Li return getDeclFromExpr(POE->getSyntacticForm());
3985*67e74705SXin Li if (const OpaqueValueExpr *OVE = dyn_cast<OpaqueValueExpr>(E))
3986*67e74705SXin Li if (Expr *Src = OVE->getSourceExpr())
3987*67e74705SXin Li return getDeclFromExpr(Src);
3988*67e74705SXin Li
3989*67e74705SXin Li if (const CallExpr *CE = dyn_cast<CallExpr>(E))
3990*67e74705SXin Li return getDeclFromExpr(CE->getCallee());
3991*67e74705SXin Li if (const CXXConstructExpr *CE = dyn_cast<CXXConstructExpr>(E))
3992*67e74705SXin Li if (!CE->isElidable())
3993*67e74705SXin Li return CE->getConstructor();
3994*67e74705SXin Li if (const CXXInheritedCtorInitExpr *CE =
3995*67e74705SXin Li dyn_cast<CXXInheritedCtorInitExpr>(E))
3996*67e74705SXin Li return CE->getConstructor();
3997*67e74705SXin Li if (const ObjCMessageExpr *OME = dyn_cast<ObjCMessageExpr>(E))
3998*67e74705SXin Li return OME->getMethodDecl();
3999*67e74705SXin Li
4000*67e74705SXin Li if (const ObjCProtocolExpr *PE = dyn_cast<ObjCProtocolExpr>(E))
4001*67e74705SXin Li return PE->getProtocol();
4002*67e74705SXin Li if (const SubstNonTypeTemplateParmPackExpr *NTTP
4003*67e74705SXin Li = dyn_cast<SubstNonTypeTemplateParmPackExpr>(E))
4004*67e74705SXin Li return NTTP->getParameterPack();
4005*67e74705SXin Li if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
4006*67e74705SXin Li if (isa<NonTypeTemplateParmDecl>(SizeOfPack->getPack()) ||
4007*67e74705SXin Li isa<ParmVarDecl>(SizeOfPack->getPack()))
4008*67e74705SXin Li return SizeOfPack->getPack();
4009*67e74705SXin Li
4010*67e74705SXin Li return nullptr;
4011*67e74705SXin Li }
4012*67e74705SXin Li
getLocationFromExpr(const Expr * E)4013*67e74705SXin Li static SourceLocation getLocationFromExpr(const Expr *E) {
4014*67e74705SXin Li if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
4015*67e74705SXin Li return getLocationFromExpr(CE->getSubExpr());
4016*67e74705SXin Li
4017*67e74705SXin Li if (const ObjCMessageExpr *Msg = dyn_cast<ObjCMessageExpr>(E))
4018*67e74705SXin Li return /*FIXME:*/Msg->getLeftLoc();
4019*67e74705SXin Li if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E))
4020*67e74705SXin Li return DRE->getLocation();
4021*67e74705SXin Li if (const MemberExpr *Member = dyn_cast<MemberExpr>(E))
4022*67e74705SXin Li return Member->getMemberLoc();
4023*67e74705SXin Li if (const ObjCIvarRefExpr *Ivar = dyn_cast<ObjCIvarRefExpr>(E))
4024*67e74705SXin Li return Ivar->getLocation();
4025*67e74705SXin Li if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
4026*67e74705SXin Li return SizeOfPack->getPackLoc();
4027*67e74705SXin Li if (const ObjCPropertyRefExpr *PropRef = dyn_cast<ObjCPropertyRefExpr>(E))
4028*67e74705SXin Li return PropRef->getLocation();
4029*67e74705SXin Li
4030*67e74705SXin Li return E->getLocStart();
4031*67e74705SXin Li }
4032*67e74705SXin Li
4033*67e74705SXin Li extern "C" {
4034*67e74705SXin Li
clang_visitChildren(CXCursor parent,CXCursorVisitor visitor,CXClientData client_data)4035*67e74705SXin Li unsigned clang_visitChildren(CXCursor parent,
4036*67e74705SXin Li CXCursorVisitor visitor,
4037*67e74705SXin Li CXClientData client_data) {
4038*67e74705SXin Li CursorVisitor CursorVis(getCursorTU(parent), visitor, client_data,
4039*67e74705SXin Li /*VisitPreprocessorLast=*/false);
4040*67e74705SXin Li return CursorVis.VisitChildren(parent);
4041*67e74705SXin Li }
4042*67e74705SXin Li
4043*67e74705SXin Li #ifndef __has_feature
4044*67e74705SXin Li #define __has_feature(x) 0
4045*67e74705SXin Li #endif
4046*67e74705SXin Li #if __has_feature(blocks)
4047*67e74705SXin Li typedef enum CXChildVisitResult
4048*67e74705SXin Li (^CXCursorVisitorBlock)(CXCursor cursor, CXCursor parent);
4049*67e74705SXin Li
visitWithBlock(CXCursor cursor,CXCursor parent,CXClientData client_data)4050*67e74705SXin Li static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
4051*67e74705SXin Li CXClientData client_data) {
4052*67e74705SXin Li CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
4053*67e74705SXin Li return block(cursor, parent);
4054*67e74705SXin Li }
4055*67e74705SXin Li #else
4056*67e74705SXin Li // If we are compiled with a compiler that doesn't have native blocks support,
4057*67e74705SXin Li // define and call the block manually, so the
4058*67e74705SXin Li typedef struct _CXChildVisitResult
4059*67e74705SXin Li {
4060*67e74705SXin Li void *isa;
4061*67e74705SXin Li int flags;
4062*67e74705SXin Li int reserved;
4063*67e74705SXin Li enum CXChildVisitResult(*invoke)(struct _CXChildVisitResult*, CXCursor,
4064*67e74705SXin Li CXCursor);
4065*67e74705SXin Li } *CXCursorVisitorBlock;
4066*67e74705SXin Li
visitWithBlock(CXCursor cursor,CXCursor parent,CXClientData client_data)4067*67e74705SXin Li static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
4068*67e74705SXin Li CXClientData client_data) {
4069*67e74705SXin Li CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
4070*67e74705SXin Li return block->invoke(block, cursor, parent);
4071*67e74705SXin Li }
4072*67e74705SXin Li #endif
4073*67e74705SXin Li
4074*67e74705SXin Li
clang_visitChildrenWithBlock(CXCursor parent,CXCursorVisitorBlock block)4075*67e74705SXin Li unsigned clang_visitChildrenWithBlock(CXCursor parent,
4076*67e74705SXin Li CXCursorVisitorBlock block) {
4077*67e74705SXin Li return clang_visitChildren(parent, visitWithBlock, block);
4078*67e74705SXin Li }
4079*67e74705SXin Li
getDeclSpelling(const Decl * D)4080*67e74705SXin Li static CXString getDeclSpelling(const Decl *D) {
4081*67e74705SXin Li if (!D)
4082*67e74705SXin Li return cxstring::createEmpty();
4083*67e74705SXin Li
4084*67e74705SXin Li const NamedDecl *ND = dyn_cast<NamedDecl>(D);
4085*67e74705SXin Li if (!ND) {
4086*67e74705SXin Li if (const ObjCPropertyImplDecl *PropImpl =
4087*67e74705SXin Li dyn_cast<ObjCPropertyImplDecl>(D))
4088*67e74705SXin Li if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
4089*67e74705SXin Li return cxstring::createDup(Property->getIdentifier()->getName());
4090*67e74705SXin Li
4091*67e74705SXin Li if (const ImportDecl *ImportD = dyn_cast<ImportDecl>(D))
4092*67e74705SXin Li if (Module *Mod = ImportD->getImportedModule())
4093*67e74705SXin Li return cxstring::createDup(Mod->getFullModuleName());
4094*67e74705SXin Li
4095*67e74705SXin Li return cxstring::createEmpty();
4096*67e74705SXin Li }
4097*67e74705SXin Li
4098*67e74705SXin Li if (const ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(ND))
4099*67e74705SXin Li return cxstring::createDup(OMD->getSelector().getAsString());
4100*67e74705SXin Li
4101*67e74705SXin Li if (const ObjCCategoryImplDecl *CIMP = dyn_cast<ObjCCategoryImplDecl>(ND))
4102*67e74705SXin Li // No, this isn't the same as the code below. getIdentifier() is non-virtual
4103*67e74705SXin Li // and returns different names. NamedDecl returns the class name and
4104*67e74705SXin Li // ObjCCategoryImplDecl returns the category name.
4105*67e74705SXin Li return cxstring::createRef(CIMP->getIdentifier()->getNameStart());
4106*67e74705SXin Li
4107*67e74705SXin Li if (isa<UsingDirectiveDecl>(D))
4108*67e74705SXin Li return cxstring::createEmpty();
4109*67e74705SXin Li
4110*67e74705SXin Li SmallString<1024> S;
4111*67e74705SXin Li llvm::raw_svector_ostream os(S);
4112*67e74705SXin Li ND->printName(os);
4113*67e74705SXin Li
4114*67e74705SXin Li return cxstring::createDup(os.str());
4115*67e74705SXin Li }
4116*67e74705SXin Li
clang_getCursorSpelling(CXCursor C)4117*67e74705SXin Li CXString clang_getCursorSpelling(CXCursor C) {
4118*67e74705SXin Li if (clang_isTranslationUnit(C.kind))
4119*67e74705SXin Li return clang_getTranslationUnitSpelling(getCursorTU(C));
4120*67e74705SXin Li
4121*67e74705SXin Li if (clang_isReference(C.kind)) {
4122*67e74705SXin Li switch (C.kind) {
4123*67e74705SXin Li case CXCursor_ObjCSuperClassRef: {
4124*67e74705SXin Li const ObjCInterfaceDecl *Super = getCursorObjCSuperClassRef(C).first;
4125*67e74705SXin Li return cxstring::createRef(Super->getIdentifier()->getNameStart());
4126*67e74705SXin Li }
4127*67e74705SXin Li case CXCursor_ObjCClassRef: {
4128*67e74705SXin Li const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
4129*67e74705SXin Li return cxstring::createRef(Class->getIdentifier()->getNameStart());
4130*67e74705SXin Li }
4131*67e74705SXin Li case CXCursor_ObjCProtocolRef: {
4132*67e74705SXin Li const ObjCProtocolDecl *OID = getCursorObjCProtocolRef(C).first;
4133*67e74705SXin Li assert(OID && "getCursorSpelling(): Missing protocol decl");
4134*67e74705SXin Li return cxstring::createRef(OID->getIdentifier()->getNameStart());
4135*67e74705SXin Li }
4136*67e74705SXin Li case CXCursor_CXXBaseSpecifier: {
4137*67e74705SXin Li const CXXBaseSpecifier *B = getCursorCXXBaseSpecifier(C);
4138*67e74705SXin Li return cxstring::createDup(B->getType().getAsString());
4139*67e74705SXin Li }
4140*67e74705SXin Li case CXCursor_TypeRef: {
4141*67e74705SXin Li const TypeDecl *Type = getCursorTypeRef(C).first;
4142*67e74705SXin Li assert(Type && "Missing type decl");
4143*67e74705SXin Li
4144*67e74705SXin Li return cxstring::createDup(getCursorContext(C).getTypeDeclType(Type).
4145*67e74705SXin Li getAsString());
4146*67e74705SXin Li }
4147*67e74705SXin Li case CXCursor_TemplateRef: {
4148*67e74705SXin Li const TemplateDecl *Template = getCursorTemplateRef(C).first;
4149*67e74705SXin Li assert(Template && "Missing template decl");
4150*67e74705SXin Li
4151*67e74705SXin Li return cxstring::createDup(Template->getNameAsString());
4152*67e74705SXin Li }
4153*67e74705SXin Li
4154*67e74705SXin Li case CXCursor_NamespaceRef: {
4155*67e74705SXin Li const NamedDecl *NS = getCursorNamespaceRef(C).first;
4156*67e74705SXin Li assert(NS && "Missing namespace decl");
4157*67e74705SXin Li
4158*67e74705SXin Li return cxstring::createDup(NS->getNameAsString());
4159*67e74705SXin Li }
4160*67e74705SXin Li
4161*67e74705SXin Li case CXCursor_MemberRef: {
4162*67e74705SXin Li const FieldDecl *Field = getCursorMemberRef(C).first;
4163*67e74705SXin Li assert(Field && "Missing member decl");
4164*67e74705SXin Li
4165*67e74705SXin Li return cxstring::createDup(Field->getNameAsString());
4166*67e74705SXin Li }
4167*67e74705SXin Li
4168*67e74705SXin Li case CXCursor_LabelRef: {
4169*67e74705SXin Li const LabelStmt *Label = getCursorLabelRef(C).first;
4170*67e74705SXin Li assert(Label && "Missing label");
4171*67e74705SXin Li
4172*67e74705SXin Li return cxstring::createRef(Label->getName());
4173*67e74705SXin Li }
4174*67e74705SXin Li
4175*67e74705SXin Li case CXCursor_OverloadedDeclRef: {
4176*67e74705SXin Li OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
4177*67e74705SXin Li if (const Decl *D = Storage.dyn_cast<const Decl *>()) {
4178*67e74705SXin Li if (const NamedDecl *ND = dyn_cast<NamedDecl>(D))
4179*67e74705SXin Li return cxstring::createDup(ND->getNameAsString());
4180*67e74705SXin Li return cxstring::createEmpty();
4181*67e74705SXin Li }
4182*67e74705SXin Li if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
4183*67e74705SXin Li return cxstring::createDup(E->getName().getAsString());
4184*67e74705SXin Li OverloadedTemplateStorage *Ovl
4185*67e74705SXin Li = Storage.get<OverloadedTemplateStorage*>();
4186*67e74705SXin Li if (Ovl->size() == 0)
4187*67e74705SXin Li return cxstring::createEmpty();
4188*67e74705SXin Li return cxstring::createDup((*Ovl->begin())->getNameAsString());
4189*67e74705SXin Li }
4190*67e74705SXin Li
4191*67e74705SXin Li case CXCursor_VariableRef: {
4192*67e74705SXin Li const VarDecl *Var = getCursorVariableRef(C).first;
4193*67e74705SXin Li assert(Var && "Missing variable decl");
4194*67e74705SXin Li
4195*67e74705SXin Li return cxstring::createDup(Var->getNameAsString());
4196*67e74705SXin Li }
4197*67e74705SXin Li
4198*67e74705SXin Li default:
4199*67e74705SXin Li return cxstring::createRef("<not implemented>");
4200*67e74705SXin Li }
4201*67e74705SXin Li }
4202*67e74705SXin Li
4203*67e74705SXin Li if (clang_isExpression(C.kind)) {
4204*67e74705SXin Li const Expr *E = getCursorExpr(C);
4205*67e74705SXin Li
4206*67e74705SXin Li if (C.kind == CXCursor_ObjCStringLiteral ||
4207*67e74705SXin Li C.kind == CXCursor_StringLiteral) {
4208*67e74705SXin Li const StringLiteral *SLit;
4209*67e74705SXin Li if (const ObjCStringLiteral *OSL = dyn_cast<ObjCStringLiteral>(E)) {
4210*67e74705SXin Li SLit = OSL->getString();
4211*67e74705SXin Li } else {
4212*67e74705SXin Li SLit = cast<StringLiteral>(E);
4213*67e74705SXin Li }
4214*67e74705SXin Li SmallString<256> Buf;
4215*67e74705SXin Li llvm::raw_svector_ostream OS(Buf);
4216*67e74705SXin Li SLit->outputString(OS);
4217*67e74705SXin Li return cxstring::createDup(OS.str());
4218*67e74705SXin Li }
4219*67e74705SXin Li
4220*67e74705SXin Li const Decl *D = getDeclFromExpr(getCursorExpr(C));
4221*67e74705SXin Li if (D)
4222*67e74705SXin Li return getDeclSpelling(D);
4223*67e74705SXin Li return cxstring::createEmpty();
4224*67e74705SXin Li }
4225*67e74705SXin Li
4226*67e74705SXin Li if (clang_isStatement(C.kind)) {
4227*67e74705SXin Li const Stmt *S = getCursorStmt(C);
4228*67e74705SXin Li if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S))
4229*67e74705SXin Li return cxstring::createRef(Label->getName());
4230*67e74705SXin Li
4231*67e74705SXin Li return cxstring::createEmpty();
4232*67e74705SXin Li }
4233*67e74705SXin Li
4234*67e74705SXin Li if (C.kind == CXCursor_MacroExpansion)
4235*67e74705SXin Li return cxstring::createRef(getCursorMacroExpansion(C).getName()
4236*67e74705SXin Li ->getNameStart());
4237*67e74705SXin Li
4238*67e74705SXin Li if (C.kind == CXCursor_MacroDefinition)
4239*67e74705SXin Li return cxstring::createRef(getCursorMacroDefinition(C)->getName()
4240*67e74705SXin Li ->getNameStart());
4241*67e74705SXin Li
4242*67e74705SXin Li if (C.kind == CXCursor_InclusionDirective)
4243*67e74705SXin Li return cxstring::createDup(getCursorInclusionDirective(C)->getFileName());
4244*67e74705SXin Li
4245*67e74705SXin Li if (clang_isDeclaration(C.kind))
4246*67e74705SXin Li return getDeclSpelling(getCursorDecl(C));
4247*67e74705SXin Li
4248*67e74705SXin Li if (C.kind == CXCursor_AnnotateAttr) {
4249*67e74705SXin Li const AnnotateAttr *AA = cast<AnnotateAttr>(cxcursor::getCursorAttr(C));
4250*67e74705SXin Li return cxstring::createDup(AA->getAnnotation());
4251*67e74705SXin Li }
4252*67e74705SXin Li
4253*67e74705SXin Li if (C.kind == CXCursor_AsmLabelAttr) {
4254*67e74705SXin Li const AsmLabelAttr *AA = cast<AsmLabelAttr>(cxcursor::getCursorAttr(C));
4255*67e74705SXin Li return cxstring::createDup(AA->getLabel());
4256*67e74705SXin Li }
4257*67e74705SXin Li
4258*67e74705SXin Li if (C.kind == CXCursor_PackedAttr) {
4259*67e74705SXin Li return cxstring::createRef("packed");
4260*67e74705SXin Li }
4261*67e74705SXin Li
4262*67e74705SXin Li if (C.kind == CXCursor_VisibilityAttr) {
4263*67e74705SXin Li const VisibilityAttr *AA = cast<VisibilityAttr>(cxcursor::getCursorAttr(C));
4264*67e74705SXin Li switch (AA->getVisibility()) {
4265*67e74705SXin Li case VisibilityAttr::VisibilityType::Default:
4266*67e74705SXin Li return cxstring::createRef("default");
4267*67e74705SXin Li case VisibilityAttr::VisibilityType::Hidden:
4268*67e74705SXin Li return cxstring::createRef("hidden");
4269*67e74705SXin Li case VisibilityAttr::VisibilityType::Protected:
4270*67e74705SXin Li return cxstring::createRef("protected");
4271*67e74705SXin Li }
4272*67e74705SXin Li llvm_unreachable("unknown visibility type");
4273*67e74705SXin Li }
4274*67e74705SXin Li
4275*67e74705SXin Li return cxstring::createEmpty();
4276*67e74705SXin Li }
4277*67e74705SXin Li
clang_Cursor_getSpellingNameRange(CXCursor C,unsigned pieceIndex,unsigned options)4278*67e74705SXin Li CXSourceRange clang_Cursor_getSpellingNameRange(CXCursor C,
4279*67e74705SXin Li unsigned pieceIndex,
4280*67e74705SXin Li unsigned options) {
4281*67e74705SXin Li if (clang_Cursor_isNull(C))
4282*67e74705SXin Li return clang_getNullRange();
4283*67e74705SXin Li
4284*67e74705SXin Li ASTContext &Ctx = getCursorContext(C);
4285*67e74705SXin Li
4286*67e74705SXin Li if (clang_isStatement(C.kind)) {
4287*67e74705SXin Li const Stmt *S = getCursorStmt(C);
4288*67e74705SXin Li if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S)) {
4289*67e74705SXin Li if (pieceIndex > 0)
4290*67e74705SXin Li return clang_getNullRange();
4291*67e74705SXin Li return cxloc::translateSourceRange(Ctx, Label->getIdentLoc());
4292*67e74705SXin Li }
4293*67e74705SXin Li
4294*67e74705SXin Li return clang_getNullRange();
4295*67e74705SXin Li }
4296*67e74705SXin Li
4297*67e74705SXin Li if (C.kind == CXCursor_ObjCMessageExpr) {
4298*67e74705SXin Li if (const ObjCMessageExpr *
4299*67e74705SXin Li ME = dyn_cast_or_null<ObjCMessageExpr>(getCursorExpr(C))) {
4300*67e74705SXin Li if (pieceIndex >= ME->getNumSelectorLocs())
4301*67e74705SXin Li return clang_getNullRange();
4302*67e74705SXin Li return cxloc::translateSourceRange(Ctx, ME->getSelectorLoc(pieceIndex));
4303*67e74705SXin Li }
4304*67e74705SXin Li }
4305*67e74705SXin Li
4306*67e74705SXin Li if (C.kind == CXCursor_ObjCInstanceMethodDecl ||
4307*67e74705SXin Li C.kind == CXCursor_ObjCClassMethodDecl) {
4308*67e74705SXin Li if (const ObjCMethodDecl *
4309*67e74705SXin Li MD = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(C))) {
4310*67e74705SXin Li if (pieceIndex >= MD->getNumSelectorLocs())
4311*67e74705SXin Li return clang_getNullRange();
4312*67e74705SXin Li return cxloc::translateSourceRange(Ctx, MD->getSelectorLoc(pieceIndex));
4313*67e74705SXin Li }
4314*67e74705SXin Li }
4315*67e74705SXin Li
4316*67e74705SXin Li if (C.kind == CXCursor_ObjCCategoryDecl ||
4317*67e74705SXin Li C.kind == CXCursor_ObjCCategoryImplDecl) {
4318*67e74705SXin Li if (pieceIndex > 0)
4319*67e74705SXin Li return clang_getNullRange();
4320*67e74705SXin Li if (const ObjCCategoryDecl *
4321*67e74705SXin Li CD = dyn_cast_or_null<ObjCCategoryDecl>(getCursorDecl(C)))
4322*67e74705SXin Li return cxloc::translateSourceRange(Ctx, CD->getCategoryNameLoc());
4323*67e74705SXin Li if (const ObjCCategoryImplDecl *
4324*67e74705SXin Li CID = dyn_cast_or_null<ObjCCategoryImplDecl>(getCursorDecl(C)))
4325*67e74705SXin Li return cxloc::translateSourceRange(Ctx, CID->getCategoryNameLoc());
4326*67e74705SXin Li }
4327*67e74705SXin Li
4328*67e74705SXin Li if (C.kind == CXCursor_ModuleImportDecl) {
4329*67e74705SXin Li if (pieceIndex > 0)
4330*67e74705SXin Li return clang_getNullRange();
4331*67e74705SXin Li if (const ImportDecl *ImportD =
4332*67e74705SXin Li dyn_cast_or_null<ImportDecl>(getCursorDecl(C))) {
4333*67e74705SXin Li ArrayRef<SourceLocation> Locs = ImportD->getIdentifierLocs();
4334*67e74705SXin Li if (!Locs.empty())
4335*67e74705SXin Li return cxloc::translateSourceRange(Ctx,
4336*67e74705SXin Li SourceRange(Locs.front(), Locs.back()));
4337*67e74705SXin Li }
4338*67e74705SXin Li return clang_getNullRange();
4339*67e74705SXin Li }
4340*67e74705SXin Li
4341*67e74705SXin Li if (C.kind == CXCursor_CXXMethod || C.kind == CXCursor_Destructor ||
4342*67e74705SXin Li C.kind == CXCursor_ConversionFunction) {
4343*67e74705SXin Li if (pieceIndex > 0)
4344*67e74705SXin Li return clang_getNullRange();
4345*67e74705SXin Li if (const FunctionDecl *FD =
4346*67e74705SXin Li dyn_cast_or_null<FunctionDecl>(getCursorDecl(C))) {
4347*67e74705SXin Li DeclarationNameInfo FunctionName = FD->getNameInfo();
4348*67e74705SXin Li return cxloc::translateSourceRange(Ctx, FunctionName.getSourceRange());
4349*67e74705SXin Li }
4350*67e74705SXin Li return clang_getNullRange();
4351*67e74705SXin Li }
4352*67e74705SXin Li
4353*67e74705SXin Li // FIXME: A CXCursor_InclusionDirective should give the location of the
4354*67e74705SXin Li // filename, but we don't keep track of this.
4355*67e74705SXin Li
4356*67e74705SXin Li // FIXME: A CXCursor_AnnotateAttr should give the location of the annotation
4357*67e74705SXin Li // but we don't keep track of this.
4358*67e74705SXin Li
4359*67e74705SXin Li // FIXME: A CXCursor_AsmLabelAttr should give the location of the label
4360*67e74705SXin Li // but we don't keep track of this.
4361*67e74705SXin Li
4362*67e74705SXin Li // Default handling, give the location of the cursor.
4363*67e74705SXin Li
4364*67e74705SXin Li if (pieceIndex > 0)
4365*67e74705SXin Li return clang_getNullRange();
4366*67e74705SXin Li
4367*67e74705SXin Li CXSourceLocation CXLoc = clang_getCursorLocation(C);
4368*67e74705SXin Li SourceLocation Loc = cxloc::translateSourceLocation(CXLoc);
4369*67e74705SXin Li return cxloc::translateSourceRange(Ctx, Loc);
4370*67e74705SXin Li }
4371*67e74705SXin Li
clang_Cursor_getMangling(CXCursor C)4372*67e74705SXin Li CXString clang_Cursor_getMangling(CXCursor C) {
4373*67e74705SXin Li if (clang_isInvalid(C.kind) || !clang_isDeclaration(C.kind))
4374*67e74705SXin Li return cxstring::createEmpty();
4375*67e74705SXin Li
4376*67e74705SXin Li // Mangling only works for functions and variables.
4377*67e74705SXin Li const Decl *D = getCursorDecl(C);
4378*67e74705SXin Li if (!D || !(isa<FunctionDecl>(D) || isa<VarDecl>(D)))
4379*67e74705SXin Li return cxstring::createEmpty();
4380*67e74705SXin Li
4381*67e74705SXin Li ASTContext &Ctx = D->getASTContext();
4382*67e74705SXin Li index::CodegenNameGenerator CGNameGen(Ctx);
4383*67e74705SXin Li return cxstring::createDup(CGNameGen.getName(D));
4384*67e74705SXin Li }
4385*67e74705SXin Li
clang_Cursor_getCXXManglings(CXCursor C)4386*67e74705SXin Li CXStringSet *clang_Cursor_getCXXManglings(CXCursor C) {
4387*67e74705SXin Li if (clang_isInvalid(C.kind) || !clang_isDeclaration(C.kind))
4388*67e74705SXin Li return nullptr;
4389*67e74705SXin Li
4390*67e74705SXin Li const Decl *D = getCursorDecl(C);
4391*67e74705SXin Li if (!(isa<CXXRecordDecl>(D) || isa<CXXMethodDecl>(D)))
4392*67e74705SXin Li return nullptr;
4393*67e74705SXin Li
4394*67e74705SXin Li ASTContext &Ctx = D->getASTContext();
4395*67e74705SXin Li index::CodegenNameGenerator CGNameGen(Ctx);
4396*67e74705SXin Li std::vector<std::string> Manglings = CGNameGen.getAllManglings(D);
4397*67e74705SXin Li return cxstring::createSet(Manglings);
4398*67e74705SXin Li }
4399*67e74705SXin Li
clang_getCursorDisplayName(CXCursor C)4400*67e74705SXin Li CXString clang_getCursorDisplayName(CXCursor C) {
4401*67e74705SXin Li if (!clang_isDeclaration(C.kind))
4402*67e74705SXin Li return clang_getCursorSpelling(C);
4403*67e74705SXin Li
4404*67e74705SXin Li const Decl *D = getCursorDecl(C);
4405*67e74705SXin Li if (!D)
4406*67e74705SXin Li return cxstring::createEmpty();
4407*67e74705SXin Li
4408*67e74705SXin Li PrintingPolicy Policy = getCursorContext(C).getPrintingPolicy();
4409*67e74705SXin Li if (const FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(D))
4410*67e74705SXin Li D = FunTmpl->getTemplatedDecl();
4411*67e74705SXin Li
4412*67e74705SXin Li if (const FunctionDecl *Function = dyn_cast<FunctionDecl>(D)) {
4413*67e74705SXin Li SmallString<64> Str;
4414*67e74705SXin Li llvm::raw_svector_ostream OS(Str);
4415*67e74705SXin Li OS << *Function;
4416*67e74705SXin Li if (Function->getPrimaryTemplate())
4417*67e74705SXin Li OS << "<>";
4418*67e74705SXin Li OS << "(";
4419*67e74705SXin Li for (unsigned I = 0, N = Function->getNumParams(); I != N; ++I) {
4420*67e74705SXin Li if (I)
4421*67e74705SXin Li OS << ", ";
4422*67e74705SXin Li OS << Function->getParamDecl(I)->getType().getAsString(Policy);
4423*67e74705SXin Li }
4424*67e74705SXin Li
4425*67e74705SXin Li if (Function->isVariadic()) {
4426*67e74705SXin Li if (Function->getNumParams())
4427*67e74705SXin Li OS << ", ";
4428*67e74705SXin Li OS << "...";
4429*67e74705SXin Li }
4430*67e74705SXin Li OS << ")";
4431*67e74705SXin Li return cxstring::createDup(OS.str());
4432*67e74705SXin Li }
4433*67e74705SXin Li
4434*67e74705SXin Li if (const ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(D)) {
4435*67e74705SXin Li SmallString<64> Str;
4436*67e74705SXin Li llvm::raw_svector_ostream OS(Str);
4437*67e74705SXin Li OS << *ClassTemplate;
4438*67e74705SXin Li OS << "<";
4439*67e74705SXin Li TemplateParameterList *Params = ClassTemplate->getTemplateParameters();
4440*67e74705SXin Li for (unsigned I = 0, N = Params->size(); I != N; ++I) {
4441*67e74705SXin Li if (I)
4442*67e74705SXin Li OS << ", ";
4443*67e74705SXin Li
4444*67e74705SXin Li NamedDecl *Param = Params->getParam(I);
4445*67e74705SXin Li if (Param->getIdentifier()) {
4446*67e74705SXin Li OS << Param->getIdentifier()->getName();
4447*67e74705SXin Li continue;
4448*67e74705SXin Li }
4449*67e74705SXin Li
4450*67e74705SXin Li // There is no parameter name, which makes this tricky. Try to come up
4451*67e74705SXin Li // with something useful that isn't too long.
4452*67e74705SXin Li if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(Param))
4453*67e74705SXin Li OS << (TTP->wasDeclaredWithTypename()? "typename" : "class");
4454*67e74705SXin Li else if (NonTypeTemplateParmDecl *NTTP
4455*67e74705SXin Li = dyn_cast<NonTypeTemplateParmDecl>(Param))
4456*67e74705SXin Li OS << NTTP->getType().getAsString(Policy);
4457*67e74705SXin Li else
4458*67e74705SXin Li OS << "template<...> class";
4459*67e74705SXin Li }
4460*67e74705SXin Li
4461*67e74705SXin Li OS << ">";
4462*67e74705SXin Li return cxstring::createDup(OS.str());
4463*67e74705SXin Li }
4464*67e74705SXin Li
4465*67e74705SXin Li if (const ClassTemplateSpecializationDecl *ClassSpec
4466*67e74705SXin Li = dyn_cast<ClassTemplateSpecializationDecl>(D)) {
4467*67e74705SXin Li // If the type was explicitly written, use that.
4468*67e74705SXin Li if (TypeSourceInfo *TSInfo = ClassSpec->getTypeAsWritten())
4469*67e74705SXin Li return cxstring::createDup(TSInfo->getType().getAsString(Policy));
4470*67e74705SXin Li
4471*67e74705SXin Li SmallString<128> Str;
4472*67e74705SXin Li llvm::raw_svector_ostream OS(Str);
4473*67e74705SXin Li OS << *ClassSpec;
4474*67e74705SXin Li TemplateSpecializationType::PrintTemplateArgumentList(
4475*67e74705SXin Li OS, ClassSpec->getTemplateArgs().asArray(), Policy);
4476*67e74705SXin Li return cxstring::createDup(OS.str());
4477*67e74705SXin Li }
4478*67e74705SXin Li
4479*67e74705SXin Li return clang_getCursorSpelling(C);
4480*67e74705SXin Li }
4481*67e74705SXin Li
clang_getCursorKindSpelling(enum CXCursorKind Kind)4482*67e74705SXin Li CXString clang_getCursorKindSpelling(enum CXCursorKind Kind) {
4483*67e74705SXin Li switch (Kind) {
4484*67e74705SXin Li case CXCursor_FunctionDecl:
4485*67e74705SXin Li return cxstring::createRef("FunctionDecl");
4486*67e74705SXin Li case CXCursor_TypedefDecl:
4487*67e74705SXin Li return cxstring::createRef("TypedefDecl");
4488*67e74705SXin Li case CXCursor_EnumDecl:
4489*67e74705SXin Li return cxstring::createRef("EnumDecl");
4490*67e74705SXin Li case CXCursor_EnumConstantDecl:
4491*67e74705SXin Li return cxstring::createRef("EnumConstantDecl");
4492*67e74705SXin Li case CXCursor_StructDecl:
4493*67e74705SXin Li return cxstring::createRef("StructDecl");
4494*67e74705SXin Li case CXCursor_UnionDecl:
4495*67e74705SXin Li return cxstring::createRef("UnionDecl");
4496*67e74705SXin Li case CXCursor_ClassDecl:
4497*67e74705SXin Li return cxstring::createRef("ClassDecl");
4498*67e74705SXin Li case CXCursor_FieldDecl:
4499*67e74705SXin Li return cxstring::createRef("FieldDecl");
4500*67e74705SXin Li case CXCursor_VarDecl:
4501*67e74705SXin Li return cxstring::createRef("VarDecl");
4502*67e74705SXin Li case CXCursor_ParmDecl:
4503*67e74705SXin Li return cxstring::createRef("ParmDecl");
4504*67e74705SXin Li case CXCursor_ObjCInterfaceDecl:
4505*67e74705SXin Li return cxstring::createRef("ObjCInterfaceDecl");
4506*67e74705SXin Li case CXCursor_ObjCCategoryDecl:
4507*67e74705SXin Li return cxstring::createRef("ObjCCategoryDecl");
4508*67e74705SXin Li case CXCursor_ObjCProtocolDecl:
4509*67e74705SXin Li return cxstring::createRef("ObjCProtocolDecl");
4510*67e74705SXin Li case CXCursor_ObjCPropertyDecl:
4511*67e74705SXin Li return cxstring::createRef("ObjCPropertyDecl");
4512*67e74705SXin Li case CXCursor_ObjCIvarDecl:
4513*67e74705SXin Li return cxstring::createRef("ObjCIvarDecl");
4514*67e74705SXin Li case CXCursor_ObjCInstanceMethodDecl:
4515*67e74705SXin Li return cxstring::createRef("ObjCInstanceMethodDecl");
4516*67e74705SXin Li case CXCursor_ObjCClassMethodDecl:
4517*67e74705SXin Li return cxstring::createRef("ObjCClassMethodDecl");
4518*67e74705SXin Li case CXCursor_ObjCImplementationDecl:
4519*67e74705SXin Li return cxstring::createRef("ObjCImplementationDecl");
4520*67e74705SXin Li case CXCursor_ObjCCategoryImplDecl:
4521*67e74705SXin Li return cxstring::createRef("ObjCCategoryImplDecl");
4522*67e74705SXin Li case CXCursor_CXXMethod:
4523*67e74705SXin Li return cxstring::createRef("CXXMethod");
4524*67e74705SXin Li case CXCursor_UnexposedDecl:
4525*67e74705SXin Li return cxstring::createRef("UnexposedDecl");
4526*67e74705SXin Li case CXCursor_ObjCSuperClassRef:
4527*67e74705SXin Li return cxstring::createRef("ObjCSuperClassRef");
4528*67e74705SXin Li case CXCursor_ObjCProtocolRef:
4529*67e74705SXin Li return cxstring::createRef("ObjCProtocolRef");
4530*67e74705SXin Li case CXCursor_ObjCClassRef:
4531*67e74705SXin Li return cxstring::createRef("ObjCClassRef");
4532*67e74705SXin Li case CXCursor_TypeRef:
4533*67e74705SXin Li return cxstring::createRef("TypeRef");
4534*67e74705SXin Li case CXCursor_TemplateRef:
4535*67e74705SXin Li return cxstring::createRef("TemplateRef");
4536*67e74705SXin Li case CXCursor_NamespaceRef:
4537*67e74705SXin Li return cxstring::createRef("NamespaceRef");
4538*67e74705SXin Li case CXCursor_MemberRef:
4539*67e74705SXin Li return cxstring::createRef("MemberRef");
4540*67e74705SXin Li case CXCursor_LabelRef:
4541*67e74705SXin Li return cxstring::createRef("LabelRef");
4542*67e74705SXin Li case CXCursor_OverloadedDeclRef:
4543*67e74705SXin Li return cxstring::createRef("OverloadedDeclRef");
4544*67e74705SXin Li case CXCursor_VariableRef:
4545*67e74705SXin Li return cxstring::createRef("VariableRef");
4546*67e74705SXin Li case CXCursor_IntegerLiteral:
4547*67e74705SXin Li return cxstring::createRef("IntegerLiteral");
4548*67e74705SXin Li case CXCursor_FloatingLiteral:
4549*67e74705SXin Li return cxstring::createRef("FloatingLiteral");
4550*67e74705SXin Li case CXCursor_ImaginaryLiteral:
4551*67e74705SXin Li return cxstring::createRef("ImaginaryLiteral");
4552*67e74705SXin Li case CXCursor_StringLiteral:
4553*67e74705SXin Li return cxstring::createRef("StringLiteral");
4554*67e74705SXin Li case CXCursor_CharacterLiteral:
4555*67e74705SXin Li return cxstring::createRef("CharacterLiteral");
4556*67e74705SXin Li case CXCursor_ParenExpr:
4557*67e74705SXin Li return cxstring::createRef("ParenExpr");
4558*67e74705SXin Li case CXCursor_UnaryOperator:
4559*67e74705SXin Li return cxstring::createRef("UnaryOperator");
4560*67e74705SXin Li case CXCursor_ArraySubscriptExpr:
4561*67e74705SXin Li return cxstring::createRef("ArraySubscriptExpr");
4562*67e74705SXin Li case CXCursor_OMPArraySectionExpr:
4563*67e74705SXin Li return cxstring::createRef("OMPArraySectionExpr");
4564*67e74705SXin Li case CXCursor_BinaryOperator:
4565*67e74705SXin Li return cxstring::createRef("BinaryOperator");
4566*67e74705SXin Li case CXCursor_CompoundAssignOperator:
4567*67e74705SXin Li return cxstring::createRef("CompoundAssignOperator");
4568*67e74705SXin Li case CXCursor_ConditionalOperator:
4569*67e74705SXin Li return cxstring::createRef("ConditionalOperator");
4570*67e74705SXin Li case CXCursor_CStyleCastExpr:
4571*67e74705SXin Li return cxstring::createRef("CStyleCastExpr");
4572*67e74705SXin Li case CXCursor_CompoundLiteralExpr:
4573*67e74705SXin Li return cxstring::createRef("CompoundLiteralExpr");
4574*67e74705SXin Li case CXCursor_InitListExpr:
4575*67e74705SXin Li return cxstring::createRef("InitListExpr");
4576*67e74705SXin Li case CXCursor_AddrLabelExpr:
4577*67e74705SXin Li return cxstring::createRef("AddrLabelExpr");
4578*67e74705SXin Li case CXCursor_StmtExpr:
4579*67e74705SXin Li return cxstring::createRef("StmtExpr");
4580*67e74705SXin Li case CXCursor_GenericSelectionExpr:
4581*67e74705SXin Li return cxstring::createRef("GenericSelectionExpr");
4582*67e74705SXin Li case CXCursor_GNUNullExpr:
4583*67e74705SXin Li return cxstring::createRef("GNUNullExpr");
4584*67e74705SXin Li case CXCursor_CXXStaticCastExpr:
4585*67e74705SXin Li return cxstring::createRef("CXXStaticCastExpr");
4586*67e74705SXin Li case CXCursor_CXXDynamicCastExpr:
4587*67e74705SXin Li return cxstring::createRef("CXXDynamicCastExpr");
4588*67e74705SXin Li case CXCursor_CXXReinterpretCastExpr:
4589*67e74705SXin Li return cxstring::createRef("CXXReinterpretCastExpr");
4590*67e74705SXin Li case CXCursor_CXXConstCastExpr:
4591*67e74705SXin Li return cxstring::createRef("CXXConstCastExpr");
4592*67e74705SXin Li case CXCursor_CXXFunctionalCastExpr:
4593*67e74705SXin Li return cxstring::createRef("CXXFunctionalCastExpr");
4594*67e74705SXin Li case CXCursor_CXXTypeidExpr:
4595*67e74705SXin Li return cxstring::createRef("CXXTypeidExpr");
4596*67e74705SXin Li case CXCursor_CXXBoolLiteralExpr:
4597*67e74705SXin Li return cxstring::createRef("CXXBoolLiteralExpr");
4598*67e74705SXin Li case CXCursor_CXXNullPtrLiteralExpr:
4599*67e74705SXin Li return cxstring::createRef("CXXNullPtrLiteralExpr");
4600*67e74705SXin Li case CXCursor_CXXThisExpr:
4601*67e74705SXin Li return cxstring::createRef("CXXThisExpr");
4602*67e74705SXin Li case CXCursor_CXXThrowExpr:
4603*67e74705SXin Li return cxstring::createRef("CXXThrowExpr");
4604*67e74705SXin Li case CXCursor_CXXNewExpr:
4605*67e74705SXin Li return cxstring::createRef("CXXNewExpr");
4606*67e74705SXin Li case CXCursor_CXXDeleteExpr:
4607*67e74705SXin Li return cxstring::createRef("CXXDeleteExpr");
4608*67e74705SXin Li case CXCursor_UnaryExpr:
4609*67e74705SXin Li return cxstring::createRef("UnaryExpr");
4610*67e74705SXin Li case CXCursor_ObjCStringLiteral:
4611*67e74705SXin Li return cxstring::createRef("ObjCStringLiteral");
4612*67e74705SXin Li case CXCursor_ObjCBoolLiteralExpr:
4613*67e74705SXin Li return cxstring::createRef("ObjCBoolLiteralExpr");
4614*67e74705SXin Li case CXCursor_ObjCSelfExpr:
4615*67e74705SXin Li return cxstring::createRef("ObjCSelfExpr");
4616*67e74705SXin Li case CXCursor_ObjCEncodeExpr:
4617*67e74705SXin Li return cxstring::createRef("ObjCEncodeExpr");
4618*67e74705SXin Li case CXCursor_ObjCSelectorExpr:
4619*67e74705SXin Li return cxstring::createRef("ObjCSelectorExpr");
4620*67e74705SXin Li case CXCursor_ObjCProtocolExpr:
4621*67e74705SXin Li return cxstring::createRef("ObjCProtocolExpr");
4622*67e74705SXin Li case CXCursor_ObjCBridgedCastExpr:
4623*67e74705SXin Li return cxstring::createRef("ObjCBridgedCastExpr");
4624*67e74705SXin Li case CXCursor_BlockExpr:
4625*67e74705SXin Li return cxstring::createRef("BlockExpr");
4626*67e74705SXin Li case CXCursor_PackExpansionExpr:
4627*67e74705SXin Li return cxstring::createRef("PackExpansionExpr");
4628*67e74705SXin Li case CXCursor_SizeOfPackExpr:
4629*67e74705SXin Li return cxstring::createRef("SizeOfPackExpr");
4630*67e74705SXin Li case CXCursor_LambdaExpr:
4631*67e74705SXin Li return cxstring::createRef("LambdaExpr");
4632*67e74705SXin Li case CXCursor_UnexposedExpr:
4633*67e74705SXin Li return cxstring::createRef("UnexposedExpr");
4634*67e74705SXin Li case CXCursor_DeclRefExpr:
4635*67e74705SXin Li return cxstring::createRef("DeclRefExpr");
4636*67e74705SXin Li case CXCursor_MemberRefExpr:
4637*67e74705SXin Li return cxstring::createRef("MemberRefExpr");
4638*67e74705SXin Li case CXCursor_CallExpr:
4639*67e74705SXin Li return cxstring::createRef("CallExpr");
4640*67e74705SXin Li case CXCursor_ObjCMessageExpr:
4641*67e74705SXin Li return cxstring::createRef("ObjCMessageExpr");
4642*67e74705SXin Li case CXCursor_UnexposedStmt:
4643*67e74705SXin Li return cxstring::createRef("UnexposedStmt");
4644*67e74705SXin Li case CXCursor_DeclStmt:
4645*67e74705SXin Li return cxstring::createRef("DeclStmt");
4646*67e74705SXin Li case CXCursor_LabelStmt:
4647*67e74705SXin Li return cxstring::createRef("LabelStmt");
4648*67e74705SXin Li case CXCursor_CompoundStmt:
4649*67e74705SXin Li return cxstring::createRef("CompoundStmt");
4650*67e74705SXin Li case CXCursor_CaseStmt:
4651*67e74705SXin Li return cxstring::createRef("CaseStmt");
4652*67e74705SXin Li case CXCursor_DefaultStmt:
4653*67e74705SXin Li return cxstring::createRef("DefaultStmt");
4654*67e74705SXin Li case CXCursor_IfStmt:
4655*67e74705SXin Li return cxstring::createRef("IfStmt");
4656*67e74705SXin Li case CXCursor_SwitchStmt:
4657*67e74705SXin Li return cxstring::createRef("SwitchStmt");
4658*67e74705SXin Li case CXCursor_WhileStmt:
4659*67e74705SXin Li return cxstring::createRef("WhileStmt");
4660*67e74705SXin Li case CXCursor_DoStmt:
4661*67e74705SXin Li return cxstring::createRef("DoStmt");
4662*67e74705SXin Li case CXCursor_ForStmt:
4663*67e74705SXin Li return cxstring::createRef("ForStmt");
4664*67e74705SXin Li case CXCursor_GotoStmt:
4665*67e74705SXin Li return cxstring::createRef("GotoStmt");
4666*67e74705SXin Li case CXCursor_IndirectGotoStmt:
4667*67e74705SXin Li return cxstring::createRef("IndirectGotoStmt");
4668*67e74705SXin Li case CXCursor_ContinueStmt:
4669*67e74705SXin Li return cxstring::createRef("ContinueStmt");
4670*67e74705SXin Li case CXCursor_BreakStmt:
4671*67e74705SXin Li return cxstring::createRef("BreakStmt");
4672*67e74705SXin Li case CXCursor_ReturnStmt:
4673*67e74705SXin Li return cxstring::createRef("ReturnStmt");
4674*67e74705SXin Li case CXCursor_GCCAsmStmt:
4675*67e74705SXin Li return cxstring::createRef("GCCAsmStmt");
4676*67e74705SXin Li case CXCursor_MSAsmStmt:
4677*67e74705SXin Li return cxstring::createRef("MSAsmStmt");
4678*67e74705SXin Li case CXCursor_ObjCAtTryStmt:
4679*67e74705SXin Li return cxstring::createRef("ObjCAtTryStmt");
4680*67e74705SXin Li case CXCursor_ObjCAtCatchStmt:
4681*67e74705SXin Li return cxstring::createRef("ObjCAtCatchStmt");
4682*67e74705SXin Li case CXCursor_ObjCAtFinallyStmt:
4683*67e74705SXin Li return cxstring::createRef("ObjCAtFinallyStmt");
4684*67e74705SXin Li case CXCursor_ObjCAtThrowStmt:
4685*67e74705SXin Li return cxstring::createRef("ObjCAtThrowStmt");
4686*67e74705SXin Li case CXCursor_ObjCAtSynchronizedStmt:
4687*67e74705SXin Li return cxstring::createRef("ObjCAtSynchronizedStmt");
4688*67e74705SXin Li case CXCursor_ObjCAutoreleasePoolStmt:
4689*67e74705SXin Li return cxstring::createRef("ObjCAutoreleasePoolStmt");
4690*67e74705SXin Li case CXCursor_ObjCForCollectionStmt:
4691*67e74705SXin Li return cxstring::createRef("ObjCForCollectionStmt");
4692*67e74705SXin Li case CXCursor_CXXCatchStmt:
4693*67e74705SXin Li return cxstring::createRef("CXXCatchStmt");
4694*67e74705SXin Li case CXCursor_CXXTryStmt:
4695*67e74705SXin Li return cxstring::createRef("CXXTryStmt");
4696*67e74705SXin Li case CXCursor_CXXForRangeStmt:
4697*67e74705SXin Li return cxstring::createRef("CXXForRangeStmt");
4698*67e74705SXin Li case CXCursor_SEHTryStmt:
4699*67e74705SXin Li return cxstring::createRef("SEHTryStmt");
4700*67e74705SXin Li case CXCursor_SEHExceptStmt:
4701*67e74705SXin Li return cxstring::createRef("SEHExceptStmt");
4702*67e74705SXin Li case CXCursor_SEHFinallyStmt:
4703*67e74705SXin Li return cxstring::createRef("SEHFinallyStmt");
4704*67e74705SXin Li case CXCursor_SEHLeaveStmt:
4705*67e74705SXin Li return cxstring::createRef("SEHLeaveStmt");
4706*67e74705SXin Li case CXCursor_NullStmt:
4707*67e74705SXin Li return cxstring::createRef("NullStmt");
4708*67e74705SXin Li case CXCursor_InvalidFile:
4709*67e74705SXin Li return cxstring::createRef("InvalidFile");
4710*67e74705SXin Li case CXCursor_InvalidCode:
4711*67e74705SXin Li return cxstring::createRef("InvalidCode");
4712*67e74705SXin Li case CXCursor_NoDeclFound:
4713*67e74705SXin Li return cxstring::createRef("NoDeclFound");
4714*67e74705SXin Li case CXCursor_NotImplemented:
4715*67e74705SXin Li return cxstring::createRef("NotImplemented");
4716*67e74705SXin Li case CXCursor_TranslationUnit:
4717*67e74705SXin Li return cxstring::createRef("TranslationUnit");
4718*67e74705SXin Li case CXCursor_UnexposedAttr:
4719*67e74705SXin Li return cxstring::createRef("UnexposedAttr");
4720*67e74705SXin Li case CXCursor_IBActionAttr:
4721*67e74705SXin Li return cxstring::createRef("attribute(ibaction)");
4722*67e74705SXin Li case CXCursor_IBOutletAttr:
4723*67e74705SXin Li return cxstring::createRef("attribute(iboutlet)");
4724*67e74705SXin Li case CXCursor_IBOutletCollectionAttr:
4725*67e74705SXin Li return cxstring::createRef("attribute(iboutletcollection)");
4726*67e74705SXin Li case CXCursor_CXXFinalAttr:
4727*67e74705SXin Li return cxstring::createRef("attribute(final)");
4728*67e74705SXin Li case CXCursor_CXXOverrideAttr:
4729*67e74705SXin Li return cxstring::createRef("attribute(override)");
4730*67e74705SXin Li case CXCursor_AnnotateAttr:
4731*67e74705SXin Li return cxstring::createRef("attribute(annotate)");
4732*67e74705SXin Li case CXCursor_AsmLabelAttr:
4733*67e74705SXin Li return cxstring::createRef("asm label");
4734*67e74705SXin Li case CXCursor_PackedAttr:
4735*67e74705SXin Li return cxstring::createRef("attribute(packed)");
4736*67e74705SXin Li case CXCursor_PureAttr:
4737*67e74705SXin Li return cxstring::createRef("attribute(pure)");
4738*67e74705SXin Li case CXCursor_ConstAttr:
4739*67e74705SXin Li return cxstring::createRef("attribute(const)");
4740*67e74705SXin Li case CXCursor_NoDuplicateAttr:
4741*67e74705SXin Li return cxstring::createRef("attribute(noduplicate)");
4742*67e74705SXin Li case CXCursor_CUDAConstantAttr:
4743*67e74705SXin Li return cxstring::createRef("attribute(constant)");
4744*67e74705SXin Li case CXCursor_CUDADeviceAttr:
4745*67e74705SXin Li return cxstring::createRef("attribute(device)");
4746*67e74705SXin Li case CXCursor_CUDAGlobalAttr:
4747*67e74705SXin Li return cxstring::createRef("attribute(global)");
4748*67e74705SXin Li case CXCursor_CUDAHostAttr:
4749*67e74705SXin Li return cxstring::createRef("attribute(host)");
4750*67e74705SXin Li case CXCursor_CUDASharedAttr:
4751*67e74705SXin Li return cxstring::createRef("attribute(shared)");
4752*67e74705SXin Li case CXCursor_VisibilityAttr:
4753*67e74705SXin Li return cxstring::createRef("attribute(visibility)");
4754*67e74705SXin Li case CXCursor_DLLExport:
4755*67e74705SXin Li return cxstring::createRef("attribute(dllexport)");
4756*67e74705SXin Li case CXCursor_DLLImport:
4757*67e74705SXin Li return cxstring::createRef("attribute(dllimport)");
4758*67e74705SXin Li case CXCursor_PreprocessingDirective:
4759*67e74705SXin Li return cxstring::createRef("preprocessing directive");
4760*67e74705SXin Li case CXCursor_MacroDefinition:
4761*67e74705SXin Li return cxstring::createRef("macro definition");
4762*67e74705SXin Li case CXCursor_MacroExpansion:
4763*67e74705SXin Li return cxstring::createRef("macro expansion");
4764*67e74705SXin Li case CXCursor_InclusionDirective:
4765*67e74705SXin Li return cxstring::createRef("inclusion directive");
4766*67e74705SXin Li case CXCursor_Namespace:
4767*67e74705SXin Li return cxstring::createRef("Namespace");
4768*67e74705SXin Li case CXCursor_LinkageSpec:
4769*67e74705SXin Li return cxstring::createRef("LinkageSpec");
4770*67e74705SXin Li case CXCursor_CXXBaseSpecifier:
4771*67e74705SXin Li return cxstring::createRef("C++ base class specifier");
4772*67e74705SXin Li case CXCursor_Constructor:
4773*67e74705SXin Li return cxstring::createRef("CXXConstructor");
4774*67e74705SXin Li case CXCursor_Destructor:
4775*67e74705SXin Li return cxstring::createRef("CXXDestructor");
4776*67e74705SXin Li case CXCursor_ConversionFunction:
4777*67e74705SXin Li return cxstring::createRef("CXXConversion");
4778*67e74705SXin Li case CXCursor_TemplateTypeParameter:
4779*67e74705SXin Li return cxstring::createRef("TemplateTypeParameter");
4780*67e74705SXin Li case CXCursor_NonTypeTemplateParameter:
4781*67e74705SXin Li return cxstring::createRef("NonTypeTemplateParameter");
4782*67e74705SXin Li case CXCursor_TemplateTemplateParameter:
4783*67e74705SXin Li return cxstring::createRef("TemplateTemplateParameter");
4784*67e74705SXin Li case CXCursor_FunctionTemplate:
4785*67e74705SXin Li return cxstring::createRef("FunctionTemplate");
4786*67e74705SXin Li case CXCursor_ClassTemplate:
4787*67e74705SXin Li return cxstring::createRef("ClassTemplate");
4788*67e74705SXin Li case CXCursor_ClassTemplatePartialSpecialization:
4789*67e74705SXin Li return cxstring::createRef("ClassTemplatePartialSpecialization");
4790*67e74705SXin Li case CXCursor_NamespaceAlias:
4791*67e74705SXin Li return cxstring::createRef("NamespaceAlias");
4792*67e74705SXin Li case CXCursor_UsingDirective:
4793*67e74705SXin Li return cxstring::createRef("UsingDirective");
4794*67e74705SXin Li case CXCursor_UsingDeclaration:
4795*67e74705SXin Li return cxstring::createRef("UsingDeclaration");
4796*67e74705SXin Li case CXCursor_TypeAliasDecl:
4797*67e74705SXin Li return cxstring::createRef("TypeAliasDecl");
4798*67e74705SXin Li case CXCursor_ObjCSynthesizeDecl:
4799*67e74705SXin Li return cxstring::createRef("ObjCSynthesizeDecl");
4800*67e74705SXin Li case CXCursor_ObjCDynamicDecl:
4801*67e74705SXin Li return cxstring::createRef("ObjCDynamicDecl");
4802*67e74705SXin Li case CXCursor_CXXAccessSpecifier:
4803*67e74705SXin Li return cxstring::createRef("CXXAccessSpecifier");
4804*67e74705SXin Li case CXCursor_ModuleImportDecl:
4805*67e74705SXin Li return cxstring::createRef("ModuleImport");
4806*67e74705SXin Li case CXCursor_OMPParallelDirective:
4807*67e74705SXin Li return cxstring::createRef("OMPParallelDirective");
4808*67e74705SXin Li case CXCursor_OMPSimdDirective:
4809*67e74705SXin Li return cxstring::createRef("OMPSimdDirective");
4810*67e74705SXin Li case CXCursor_OMPForDirective:
4811*67e74705SXin Li return cxstring::createRef("OMPForDirective");
4812*67e74705SXin Li case CXCursor_OMPForSimdDirective:
4813*67e74705SXin Li return cxstring::createRef("OMPForSimdDirective");
4814*67e74705SXin Li case CXCursor_OMPSectionsDirective:
4815*67e74705SXin Li return cxstring::createRef("OMPSectionsDirective");
4816*67e74705SXin Li case CXCursor_OMPSectionDirective:
4817*67e74705SXin Li return cxstring::createRef("OMPSectionDirective");
4818*67e74705SXin Li case CXCursor_OMPSingleDirective:
4819*67e74705SXin Li return cxstring::createRef("OMPSingleDirective");
4820*67e74705SXin Li case CXCursor_OMPMasterDirective:
4821*67e74705SXin Li return cxstring::createRef("OMPMasterDirective");
4822*67e74705SXin Li case CXCursor_OMPCriticalDirective:
4823*67e74705SXin Li return cxstring::createRef("OMPCriticalDirective");
4824*67e74705SXin Li case CXCursor_OMPParallelForDirective:
4825*67e74705SXin Li return cxstring::createRef("OMPParallelForDirective");
4826*67e74705SXin Li case CXCursor_OMPParallelForSimdDirective:
4827*67e74705SXin Li return cxstring::createRef("OMPParallelForSimdDirective");
4828*67e74705SXin Li case CXCursor_OMPParallelSectionsDirective:
4829*67e74705SXin Li return cxstring::createRef("OMPParallelSectionsDirective");
4830*67e74705SXin Li case CXCursor_OMPTaskDirective:
4831*67e74705SXin Li return cxstring::createRef("OMPTaskDirective");
4832*67e74705SXin Li case CXCursor_OMPTaskyieldDirective:
4833*67e74705SXin Li return cxstring::createRef("OMPTaskyieldDirective");
4834*67e74705SXin Li case CXCursor_OMPBarrierDirective:
4835*67e74705SXin Li return cxstring::createRef("OMPBarrierDirective");
4836*67e74705SXin Li case CXCursor_OMPTaskwaitDirective:
4837*67e74705SXin Li return cxstring::createRef("OMPTaskwaitDirective");
4838*67e74705SXin Li case CXCursor_OMPTaskgroupDirective:
4839*67e74705SXin Li return cxstring::createRef("OMPTaskgroupDirective");
4840*67e74705SXin Li case CXCursor_OMPFlushDirective:
4841*67e74705SXin Li return cxstring::createRef("OMPFlushDirective");
4842*67e74705SXin Li case CXCursor_OMPOrderedDirective:
4843*67e74705SXin Li return cxstring::createRef("OMPOrderedDirective");
4844*67e74705SXin Li case CXCursor_OMPAtomicDirective:
4845*67e74705SXin Li return cxstring::createRef("OMPAtomicDirective");
4846*67e74705SXin Li case CXCursor_OMPTargetDirective:
4847*67e74705SXin Li return cxstring::createRef("OMPTargetDirective");
4848*67e74705SXin Li case CXCursor_OMPTargetDataDirective:
4849*67e74705SXin Li return cxstring::createRef("OMPTargetDataDirective");
4850*67e74705SXin Li case CXCursor_OMPTargetEnterDataDirective:
4851*67e74705SXin Li return cxstring::createRef("OMPTargetEnterDataDirective");
4852*67e74705SXin Li case CXCursor_OMPTargetExitDataDirective:
4853*67e74705SXin Li return cxstring::createRef("OMPTargetExitDataDirective");
4854*67e74705SXin Li case CXCursor_OMPTargetParallelDirective:
4855*67e74705SXin Li return cxstring::createRef("OMPTargetParallelDirective");
4856*67e74705SXin Li case CXCursor_OMPTargetParallelForDirective:
4857*67e74705SXin Li return cxstring::createRef("OMPTargetParallelForDirective");
4858*67e74705SXin Li case CXCursor_OMPTargetUpdateDirective:
4859*67e74705SXin Li return cxstring::createRef("OMPTargetUpdateDirective");
4860*67e74705SXin Li case CXCursor_OMPTeamsDirective:
4861*67e74705SXin Li return cxstring::createRef("OMPTeamsDirective");
4862*67e74705SXin Li case CXCursor_OMPCancellationPointDirective:
4863*67e74705SXin Li return cxstring::createRef("OMPCancellationPointDirective");
4864*67e74705SXin Li case CXCursor_OMPCancelDirective:
4865*67e74705SXin Li return cxstring::createRef("OMPCancelDirective");
4866*67e74705SXin Li case CXCursor_OMPTaskLoopDirective:
4867*67e74705SXin Li return cxstring::createRef("OMPTaskLoopDirective");
4868*67e74705SXin Li case CXCursor_OMPTaskLoopSimdDirective:
4869*67e74705SXin Li return cxstring::createRef("OMPTaskLoopSimdDirective");
4870*67e74705SXin Li case CXCursor_OMPDistributeDirective:
4871*67e74705SXin Li return cxstring::createRef("OMPDistributeDirective");
4872*67e74705SXin Li case CXCursor_OMPDistributeParallelForDirective:
4873*67e74705SXin Li return cxstring::createRef("OMPDistributeParallelForDirective");
4874*67e74705SXin Li case CXCursor_OMPDistributeParallelForSimdDirective:
4875*67e74705SXin Li return cxstring::createRef("OMPDistributeParallelForSimdDirective");
4876*67e74705SXin Li case CXCursor_OMPDistributeSimdDirective:
4877*67e74705SXin Li return cxstring::createRef("OMPDistributeSimdDirective");
4878*67e74705SXin Li case CXCursor_OMPTargetParallelForSimdDirective:
4879*67e74705SXin Li return cxstring::createRef("OMPTargetParallelForSimdDirective");
4880*67e74705SXin Li case CXCursor_OverloadCandidate:
4881*67e74705SXin Li return cxstring::createRef("OverloadCandidate");
4882*67e74705SXin Li case CXCursor_TypeAliasTemplateDecl:
4883*67e74705SXin Li return cxstring::createRef("TypeAliasTemplateDecl");
4884*67e74705SXin Li case CXCursor_StaticAssert:
4885*67e74705SXin Li return cxstring::createRef("StaticAssert");
4886*67e74705SXin Li }
4887*67e74705SXin Li
4888*67e74705SXin Li llvm_unreachable("Unhandled CXCursorKind");
4889*67e74705SXin Li }
4890*67e74705SXin Li
4891*67e74705SXin Li struct GetCursorData {
4892*67e74705SXin Li SourceLocation TokenBeginLoc;
4893*67e74705SXin Li bool PointsAtMacroArgExpansion;
4894*67e74705SXin Li bool VisitedObjCPropertyImplDecl;
4895*67e74705SXin Li SourceLocation VisitedDeclaratorDeclStartLoc;
4896*67e74705SXin Li CXCursor &BestCursor;
4897*67e74705SXin Li
GetCursorDataGetCursorData4898*67e74705SXin Li GetCursorData(SourceManager &SM,
4899*67e74705SXin Li SourceLocation tokenBegin, CXCursor &outputCursor)
4900*67e74705SXin Li : TokenBeginLoc(tokenBegin), BestCursor(outputCursor) {
4901*67e74705SXin Li PointsAtMacroArgExpansion = SM.isMacroArgExpansion(tokenBegin);
4902*67e74705SXin Li VisitedObjCPropertyImplDecl = false;
4903*67e74705SXin Li }
4904*67e74705SXin Li };
4905*67e74705SXin Li
GetCursorVisitor(CXCursor cursor,CXCursor parent,CXClientData client_data)4906*67e74705SXin Li static enum CXChildVisitResult GetCursorVisitor(CXCursor cursor,
4907*67e74705SXin Li CXCursor parent,
4908*67e74705SXin Li CXClientData client_data) {
4909*67e74705SXin Li GetCursorData *Data = static_cast<GetCursorData *>(client_data);
4910*67e74705SXin Li CXCursor *BestCursor = &Data->BestCursor;
4911*67e74705SXin Li
4912*67e74705SXin Li // If we point inside a macro argument we should provide info of what the
4913*67e74705SXin Li // token is so use the actual cursor, don't replace it with a macro expansion
4914*67e74705SXin Li // cursor.
4915*67e74705SXin Li if (cursor.kind == CXCursor_MacroExpansion && Data->PointsAtMacroArgExpansion)
4916*67e74705SXin Li return CXChildVisit_Recurse;
4917*67e74705SXin Li
4918*67e74705SXin Li if (clang_isDeclaration(cursor.kind)) {
4919*67e74705SXin Li // Avoid having the implicit methods override the property decls.
4920*67e74705SXin Li if (const ObjCMethodDecl *MD
4921*67e74705SXin Li = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
4922*67e74705SXin Li if (MD->isImplicit())
4923*67e74705SXin Li return CXChildVisit_Break;
4924*67e74705SXin Li
4925*67e74705SXin Li } else if (const ObjCInterfaceDecl *ID
4926*67e74705SXin Li = dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(cursor))) {
4927*67e74705SXin Li // Check that when we have multiple @class references in the same line,
4928*67e74705SXin Li // that later ones do not override the previous ones.
4929*67e74705SXin Li // If we have:
4930*67e74705SXin Li // @class Foo, Bar;
4931*67e74705SXin Li // source ranges for both start at '@', so 'Bar' will end up overriding
4932*67e74705SXin Li // 'Foo' even though the cursor location was at 'Foo'.
4933*67e74705SXin Li if (BestCursor->kind == CXCursor_ObjCInterfaceDecl ||
4934*67e74705SXin Li BestCursor->kind == CXCursor_ObjCClassRef)
4935*67e74705SXin Li if (const ObjCInterfaceDecl *PrevID
4936*67e74705SXin Li = dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(*BestCursor))){
4937*67e74705SXin Li if (PrevID != ID &&
4938*67e74705SXin Li !PrevID->isThisDeclarationADefinition() &&
4939*67e74705SXin Li !ID->isThisDeclarationADefinition())
4940*67e74705SXin Li return CXChildVisit_Break;
4941*67e74705SXin Li }
4942*67e74705SXin Li
4943*67e74705SXin Li } else if (const DeclaratorDecl *DD
4944*67e74705SXin Li = dyn_cast_or_null<DeclaratorDecl>(getCursorDecl(cursor))) {
4945*67e74705SXin Li SourceLocation StartLoc = DD->getSourceRange().getBegin();
4946*67e74705SXin Li // Check that when we have multiple declarators in the same line,
4947*67e74705SXin Li // that later ones do not override the previous ones.
4948*67e74705SXin Li // If we have:
4949*67e74705SXin Li // int Foo, Bar;
4950*67e74705SXin Li // source ranges for both start at 'int', so 'Bar' will end up overriding
4951*67e74705SXin Li // 'Foo' even though the cursor location was at 'Foo'.
4952*67e74705SXin Li if (Data->VisitedDeclaratorDeclStartLoc == StartLoc)
4953*67e74705SXin Li return CXChildVisit_Break;
4954*67e74705SXin Li Data->VisitedDeclaratorDeclStartLoc = StartLoc;
4955*67e74705SXin Li
4956*67e74705SXin Li } else if (const ObjCPropertyImplDecl *PropImp
4957*67e74705SXin Li = dyn_cast_or_null<ObjCPropertyImplDecl>(getCursorDecl(cursor))) {
4958*67e74705SXin Li (void)PropImp;
4959*67e74705SXin Li // Check that when we have multiple @synthesize in the same line,
4960*67e74705SXin Li // that later ones do not override the previous ones.
4961*67e74705SXin Li // If we have:
4962*67e74705SXin Li // @synthesize Foo, Bar;
4963*67e74705SXin Li // source ranges for both start at '@', so 'Bar' will end up overriding
4964*67e74705SXin Li // 'Foo' even though the cursor location was at 'Foo'.
4965*67e74705SXin Li if (Data->VisitedObjCPropertyImplDecl)
4966*67e74705SXin Li return CXChildVisit_Break;
4967*67e74705SXin Li Data->VisitedObjCPropertyImplDecl = true;
4968*67e74705SXin Li }
4969*67e74705SXin Li }
4970*67e74705SXin Li
4971*67e74705SXin Li if (clang_isExpression(cursor.kind) &&
4972*67e74705SXin Li clang_isDeclaration(BestCursor->kind)) {
4973*67e74705SXin Li if (const Decl *D = getCursorDecl(*BestCursor)) {
4974*67e74705SXin Li // Avoid having the cursor of an expression replace the declaration cursor
4975*67e74705SXin Li // when the expression source range overlaps the declaration range.
4976*67e74705SXin Li // This can happen for C++ constructor expressions whose range generally
4977*67e74705SXin Li // include the variable declaration, e.g.:
4978*67e74705SXin Li // MyCXXClass foo; // Make sure pointing at 'foo' returns a VarDecl cursor.
4979*67e74705SXin Li if (D->getLocation().isValid() && Data->TokenBeginLoc.isValid() &&
4980*67e74705SXin Li D->getLocation() == Data->TokenBeginLoc)
4981*67e74705SXin Li return CXChildVisit_Break;
4982*67e74705SXin Li }
4983*67e74705SXin Li }
4984*67e74705SXin Li
4985*67e74705SXin Li // If our current best cursor is the construction of a temporary object,
4986*67e74705SXin Li // don't replace that cursor with a type reference, because we want
4987*67e74705SXin Li // clang_getCursor() to point at the constructor.
4988*67e74705SXin Li if (clang_isExpression(BestCursor->kind) &&
4989*67e74705SXin Li isa<CXXTemporaryObjectExpr>(getCursorExpr(*BestCursor)) &&
4990*67e74705SXin Li cursor.kind == CXCursor_TypeRef) {
4991*67e74705SXin Li // Keep the cursor pointing at CXXTemporaryObjectExpr but also mark it
4992*67e74705SXin Li // as having the actual point on the type reference.
4993*67e74705SXin Li *BestCursor = getTypeRefedCallExprCursor(*BestCursor);
4994*67e74705SXin Li return CXChildVisit_Recurse;
4995*67e74705SXin Li }
4996*67e74705SXin Li
4997*67e74705SXin Li // If we already have an Objective-C superclass reference, don't
4998*67e74705SXin Li // update it further.
4999*67e74705SXin Li if (BestCursor->kind == CXCursor_ObjCSuperClassRef)
5000*67e74705SXin Li return CXChildVisit_Break;
5001*67e74705SXin Li
5002*67e74705SXin Li *BestCursor = cursor;
5003*67e74705SXin Li return CXChildVisit_Recurse;
5004*67e74705SXin Li }
5005*67e74705SXin Li
clang_getCursor(CXTranslationUnit TU,CXSourceLocation Loc)5006*67e74705SXin Li CXCursor clang_getCursor(CXTranslationUnit TU, CXSourceLocation Loc) {
5007*67e74705SXin Li if (isNotUsableTU(TU)) {
5008*67e74705SXin Li LOG_BAD_TU(TU);
5009*67e74705SXin Li return clang_getNullCursor();
5010*67e74705SXin Li }
5011*67e74705SXin Li
5012*67e74705SXin Li ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
5013*67e74705SXin Li ASTUnit::ConcurrencyCheck Check(*CXXUnit);
5014*67e74705SXin Li
5015*67e74705SXin Li SourceLocation SLoc = cxloc::translateSourceLocation(Loc);
5016*67e74705SXin Li CXCursor Result = cxcursor::getCursor(TU, SLoc);
5017*67e74705SXin Li
5018*67e74705SXin Li LOG_FUNC_SECTION {
5019*67e74705SXin Li CXFile SearchFile;
5020*67e74705SXin Li unsigned SearchLine, SearchColumn;
5021*67e74705SXin Li CXFile ResultFile;
5022*67e74705SXin Li unsigned ResultLine, ResultColumn;
5023*67e74705SXin Li CXString SearchFileName, ResultFileName, KindSpelling, USR;
5024*67e74705SXin Li const char *IsDef = clang_isCursorDefinition(Result)? " (Definition)" : "";
5025*67e74705SXin Li CXSourceLocation ResultLoc = clang_getCursorLocation(Result);
5026*67e74705SXin Li
5027*67e74705SXin Li clang_getFileLocation(Loc, &SearchFile, &SearchLine, &SearchColumn,
5028*67e74705SXin Li nullptr);
5029*67e74705SXin Li clang_getFileLocation(ResultLoc, &ResultFile, &ResultLine,
5030*67e74705SXin Li &ResultColumn, nullptr);
5031*67e74705SXin Li SearchFileName = clang_getFileName(SearchFile);
5032*67e74705SXin Li ResultFileName = clang_getFileName(ResultFile);
5033*67e74705SXin Li KindSpelling = clang_getCursorKindSpelling(Result.kind);
5034*67e74705SXin Li USR = clang_getCursorUSR(Result);
5035*67e74705SXin Li *Log << llvm::format("(%s:%d:%d) = %s",
5036*67e74705SXin Li clang_getCString(SearchFileName), SearchLine, SearchColumn,
5037*67e74705SXin Li clang_getCString(KindSpelling))
5038*67e74705SXin Li << llvm::format("(%s:%d:%d):%s%s",
5039*67e74705SXin Li clang_getCString(ResultFileName), ResultLine, ResultColumn,
5040*67e74705SXin Li clang_getCString(USR), IsDef);
5041*67e74705SXin Li clang_disposeString(SearchFileName);
5042*67e74705SXin Li clang_disposeString(ResultFileName);
5043*67e74705SXin Li clang_disposeString(KindSpelling);
5044*67e74705SXin Li clang_disposeString(USR);
5045*67e74705SXin Li
5046*67e74705SXin Li CXCursor Definition = clang_getCursorDefinition(Result);
5047*67e74705SXin Li if (!clang_equalCursors(Definition, clang_getNullCursor())) {
5048*67e74705SXin Li CXSourceLocation DefinitionLoc = clang_getCursorLocation(Definition);
5049*67e74705SXin Li CXString DefinitionKindSpelling
5050*67e74705SXin Li = clang_getCursorKindSpelling(Definition.kind);
5051*67e74705SXin Li CXFile DefinitionFile;
5052*67e74705SXin Li unsigned DefinitionLine, DefinitionColumn;
5053*67e74705SXin Li clang_getFileLocation(DefinitionLoc, &DefinitionFile,
5054*67e74705SXin Li &DefinitionLine, &DefinitionColumn, nullptr);
5055*67e74705SXin Li CXString DefinitionFileName = clang_getFileName(DefinitionFile);
5056*67e74705SXin Li *Log << llvm::format(" -> %s(%s:%d:%d)",
5057*67e74705SXin Li clang_getCString(DefinitionKindSpelling),
5058*67e74705SXin Li clang_getCString(DefinitionFileName),
5059*67e74705SXin Li DefinitionLine, DefinitionColumn);
5060*67e74705SXin Li clang_disposeString(DefinitionFileName);
5061*67e74705SXin Li clang_disposeString(DefinitionKindSpelling);
5062*67e74705SXin Li }
5063*67e74705SXin Li }
5064*67e74705SXin Li
5065*67e74705SXin Li return Result;
5066*67e74705SXin Li }
5067*67e74705SXin Li
clang_getNullCursor(void)5068*67e74705SXin Li CXCursor clang_getNullCursor(void) {
5069*67e74705SXin Li return MakeCXCursorInvalid(CXCursor_InvalidFile);
5070*67e74705SXin Li }
5071*67e74705SXin Li
clang_equalCursors(CXCursor X,CXCursor Y)5072*67e74705SXin Li unsigned clang_equalCursors(CXCursor X, CXCursor Y) {
5073*67e74705SXin Li // Clear out the "FirstInDeclGroup" part in a declaration cursor, since we
5074*67e74705SXin Li // can't set consistently. For example, when visiting a DeclStmt we will set
5075*67e74705SXin Li // it but we don't set it on the result of clang_getCursorDefinition for
5076*67e74705SXin Li // a reference of the same declaration.
5077*67e74705SXin Li // FIXME: Setting "FirstInDeclGroup" in CXCursors is a hack that only works
5078*67e74705SXin Li // when visiting a DeclStmt currently, the AST should be enhanced to be able
5079*67e74705SXin Li // to provide that kind of info.
5080*67e74705SXin Li if (clang_isDeclaration(X.kind))
5081*67e74705SXin Li X.data[1] = nullptr;
5082*67e74705SXin Li if (clang_isDeclaration(Y.kind))
5083*67e74705SXin Li Y.data[1] = nullptr;
5084*67e74705SXin Li
5085*67e74705SXin Li return X == Y;
5086*67e74705SXin Li }
5087*67e74705SXin Li
clang_hashCursor(CXCursor C)5088*67e74705SXin Li unsigned clang_hashCursor(CXCursor C) {
5089*67e74705SXin Li unsigned Index = 0;
5090*67e74705SXin Li if (clang_isExpression(C.kind) || clang_isStatement(C.kind))
5091*67e74705SXin Li Index = 1;
5092*67e74705SXin Li
5093*67e74705SXin Li return llvm::DenseMapInfo<std::pair<unsigned, const void*> >::getHashValue(
5094*67e74705SXin Li std::make_pair(C.kind, C.data[Index]));
5095*67e74705SXin Li }
5096*67e74705SXin Li
clang_isInvalid(enum CXCursorKind K)5097*67e74705SXin Li unsigned clang_isInvalid(enum CXCursorKind K) {
5098*67e74705SXin Li return K >= CXCursor_FirstInvalid && K <= CXCursor_LastInvalid;
5099*67e74705SXin Li }
5100*67e74705SXin Li
clang_isDeclaration(enum CXCursorKind K)5101*67e74705SXin Li unsigned clang_isDeclaration(enum CXCursorKind K) {
5102*67e74705SXin Li return (K >= CXCursor_FirstDecl && K <= CXCursor_LastDecl) ||
5103*67e74705SXin Li (K >= CXCursor_FirstExtraDecl && K <= CXCursor_LastExtraDecl);
5104*67e74705SXin Li }
5105*67e74705SXin Li
clang_isReference(enum CXCursorKind K)5106*67e74705SXin Li unsigned clang_isReference(enum CXCursorKind K) {
5107*67e74705SXin Li return K >= CXCursor_FirstRef && K <= CXCursor_LastRef;
5108*67e74705SXin Li }
5109*67e74705SXin Li
clang_isExpression(enum CXCursorKind K)5110*67e74705SXin Li unsigned clang_isExpression(enum CXCursorKind K) {
5111*67e74705SXin Li return K >= CXCursor_FirstExpr && K <= CXCursor_LastExpr;
5112*67e74705SXin Li }
5113*67e74705SXin Li
clang_isStatement(enum CXCursorKind K)5114*67e74705SXin Li unsigned clang_isStatement(enum CXCursorKind K) {
5115*67e74705SXin Li return K >= CXCursor_FirstStmt && K <= CXCursor_LastStmt;
5116*67e74705SXin Li }
5117*67e74705SXin Li
clang_isAttribute(enum CXCursorKind K)5118*67e74705SXin Li unsigned clang_isAttribute(enum CXCursorKind K) {
5119*67e74705SXin Li return K >= CXCursor_FirstAttr && K <= CXCursor_LastAttr;
5120*67e74705SXin Li }
5121*67e74705SXin Li
clang_isTranslationUnit(enum CXCursorKind K)5122*67e74705SXin Li unsigned clang_isTranslationUnit(enum CXCursorKind K) {
5123*67e74705SXin Li return K == CXCursor_TranslationUnit;
5124*67e74705SXin Li }
5125*67e74705SXin Li
clang_isPreprocessing(enum CXCursorKind K)5126*67e74705SXin Li unsigned clang_isPreprocessing(enum CXCursorKind K) {
5127*67e74705SXin Li return K >= CXCursor_FirstPreprocessing && K <= CXCursor_LastPreprocessing;
5128*67e74705SXin Li }
5129*67e74705SXin Li
clang_isUnexposed(enum CXCursorKind K)5130*67e74705SXin Li unsigned clang_isUnexposed(enum CXCursorKind K) {
5131*67e74705SXin Li switch (K) {
5132*67e74705SXin Li case CXCursor_UnexposedDecl:
5133*67e74705SXin Li case CXCursor_UnexposedExpr:
5134*67e74705SXin Li case CXCursor_UnexposedStmt:
5135*67e74705SXin Li case CXCursor_UnexposedAttr:
5136*67e74705SXin Li return true;
5137*67e74705SXin Li default:
5138*67e74705SXin Li return false;
5139*67e74705SXin Li }
5140*67e74705SXin Li }
5141*67e74705SXin Li
clang_getCursorKind(CXCursor C)5142*67e74705SXin Li CXCursorKind clang_getCursorKind(CXCursor C) {
5143*67e74705SXin Li return C.kind;
5144*67e74705SXin Li }
5145*67e74705SXin Li
clang_getCursorLocation(CXCursor C)5146*67e74705SXin Li CXSourceLocation clang_getCursorLocation(CXCursor C) {
5147*67e74705SXin Li if (clang_isReference(C.kind)) {
5148*67e74705SXin Li switch (C.kind) {
5149*67e74705SXin Li case CXCursor_ObjCSuperClassRef: {
5150*67e74705SXin Li std::pair<const ObjCInterfaceDecl *, SourceLocation> P
5151*67e74705SXin Li = getCursorObjCSuperClassRef(C);
5152*67e74705SXin Li return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
5153*67e74705SXin Li }
5154*67e74705SXin Li
5155*67e74705SXin Li case CXCursor_ObjCProtocolRef: {
5156*67e74705SXin Li std::pair<const ObjCProtocolDecl *, SourceLocation> P
5157*67e74705SXin Li = getCursorObjCProtocolRef(C);
5158*67e74705SXin Li return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
5159*67e74705SXin Li }
5160*67e74705SXin Li
5161*67e74705SXin Li case CXCursor_ObjCClassRef: {
5162*67e74705SXin Li std::pair<const ObjCInterfaceDecl *, SourceLocation> P
5163*67e74705SXin Li = getCursorObjCClassRef(C);
5164*67e74705SXin Li return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
5165*67e74705SXin Li }
5166*67e74705SXin Li
5167*67e74705SXin Li case CXCursor_TypeRef: {
5168*67e74705SXin Li std::pair<const TypeDecl *, SourceLocation> P = getCursorTypeRef(C);
5169*67e74705SXin Li return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
5170*67e74705SXin Li }
5171*67e74705SXin Li
5172*67e74705SXin Li case CXCursor_TemplateRef: {
5173*67e74705SXin Li std::pair<const TemplateDecl *, SourceLocation> P =
5174*67e74705SXin Li getCursorTemplateRef(C);
5175*67e74705SXin Li return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
5176*67e74705SXin Li }
5177*67e74705SXin Li
5178*67e74705SXin Li case CXCursor_NamespaceRef: {
5179*67e74705SXin Li std::pair<const NamedDecl *, SourceLocation> P = getCursorNamespaceRef(C);
5180*67e74705SXin Li return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
5181*67e74705SXin Li }
5182*67e74705SXin Li
5183*67e74705SXin Li case CXCursor_MemberRef: {
5184*67e74705SXin Li std::pair<const FieldDecl *, SourceLocation> P = getCursorMemberRef(C);
5185*67e74705SXin Li return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
5186*67e74705SXin Li }
5187*67e74705SXin Li
5188*67e74705SXin Li case CXCursor_VariableRef: {
5189*67e74705SXin Li std::pair<const VarDecl *, SourceLocation> P = getCursorVariableRef(C);
5190*67e74705SXin Li return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
5191*67e74705SXin Li }
5192*67e74705SXin Li
5193*67e74705SXin Li case CXCursor_CXXBaseSpecifier: {
5194*67e74705SXin Li const CXXBaseSpecifier *BaseSpec = getCursorCXXBaseSpecifier(C);
5195*67e74705SXin Li if (!BaseSpec)
5196*67e74705SXin Li return clang_getNullLocation();
5197*67e74705SXin Li
5198*67e74705SXin Li if (TypeSourceInfo *TSInfo = BaseSpec->getTypeSourceInfo())
5199*67e74705SXin Li return cxloc::translateSourceLocation(getCursorContext(C),
5200*67e74705SXin Li TSInfo->getTypeLoc().getBeginLoc());
5201*67e74705SXin Li
5202*67e74705SXin Li return cxloc::translateSourceLocation(getCursorContext(C),
5203*67e74705SXin Li BaseSpec->getLocStart());
5204*67e74705SXin Li }
5205*67e74705SXin Li
5206*67e74705SXin Li case CXCursor_LabelRef: {
5207*67e74705SXin Li std::pair<const LabelStmt *, SourceLocation> P = getCursorLabelRef(C);
5208*67e74705SXin Li return cxloc::translateSourceLocation(getCursorContext(C), P.second);
5209*67e74705SXin Li }
5210*67e74705SXin Li
5211*67e74705SXin Li case CXCursor_OverloadedDeclRef:
5212*67e74705SXin Li return cxloc::translateSourceLocation(getCursorContext(C),
5213*67e74705SXin Li getCursorOverloadedDeclRef(C).second);
5214*67e74705SXin Li
5215*67e74705SXin Li default:
5216*67e74705SXin Li // FIXME: Need a way to enumerate all non-reference cases.
5217*67e74705SXin Li llvm_unreachable("Missed a reference kind");
5218*67e74705SXin Li }
5219*67e74705SXin Li }
5220*67e74705SXin Li
5221*67e74705SXin Li if (clang_isExpression(C.kind))
5222*67e74705SXin Li return cxloc::translateSourceLocation(getCursorContext(C),
5223*67e74705SXin Li getLocationFromExpr(getCursorExpr(C)));
5224*67e74705SXin Li
5225*67e74705SXin Li if (clang_isStatement(C.kind))
5226*67e74705SXin Li return cxloc::translateSourceLocation(getCursorContext(C),
5227*67e74705SXin Li getCursorStmt(C)->getLocStart());
5228*67e74705SXin Li
5229*67e74705SXin Li if (C.kind == CXCursor_PreprocessingDirective) {
5230*67e74705SXin Li SourceLocation L = cxcursor::getCursorPreprocessingDirective(C).getBegin();
5231*67e74705SXin Li return cxloc::translateSourceLocation(getCursorContext(C), L);
5232*67e74705SXin Li }
5233*67e74705SXin Li
5234*67e74705SXin Li if (C.kind == CXCursor_MacroExpansion) {
5235*67e74705SXin Li SourceLocation L
5236*67e74705SXin Li = cxcursor::getCursorMacroExpansion(C).getSourceRange().getBegin();
5237*67e74705SXin Li return cxloc::translateSourceLocation(getCursorContext(C), L);
5238*67e74705SXin Li }
5239*67e74705SXin Li
5240*67e74705SXin Li if (C.kind == CXCursor_MacroDefinition) {
5241*67e74705SXin Li SourceLocation L = cxcursor::getCursorMacroDefinition(C)->getLocation();
5242*67e74705SXin Li return cxloc::translateSourceLocation(getCursorContext(C), L);
5243*67e74705SXin Li }
5244*67e74705SXin Li
5245*67e74705SXin Li if (C.kind == CXCursor_InclusionDirective) {
5246*67e74705SXin Li SourceLocation L
5247*67e74705SXin Li = cxcursor::getCursorInclusionDirective(C)->getSourceRange().getBegin();
5248*67e74705SXin Li return cxloc::translateSourceLocation(getCursorContext(C), L);
5249*67e74705SXin Li }
5250*67e74705SXin Li
5251*67e74705SXin Li if (clang_isAttribute(C.kind)) {
5252*67e74705SXin Li SourceLocation L
5253*67e74705SXin Li = cxcursor::getCursorAttr(C)->getLocation();
5254*67e74705SXin Li return cxloc::translateSourceLocation(getCursorContext(C), L);
5255*67e74705SXin Li }
5256*67e74705SXin Li
5257*67e74705SXin Li if (!clang_isDeclaration(C.kind))
5258*67e74705SXin Li return clang_getNullLocation();
5259*67e74705SXin Li
5260*67e74705SXin Li const Decl *D = getCursorDecl(C);
5261*67e74705SXin Li if (!D)
5262*67e74705SXin Li return clang_getNullLocation();
5263*67e74705SXin Li
5264*67e74705SXin Li SourceLocation Loc = D->getLocation();
5265*67e74705SXin Li // FIXME: Multiple variables declared in a single declaration
5266*67e74705SXin Li // currently lack the information needed to correctly determine their
5267*67e74705SXin Li // ranges when accounting for the type-specifier. We use context
5268*67e74705SXin Li // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
5269*67e74705SXin Li // and if so, whether it is the first decl.
5270*67e74705SXin Li if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
5271*67e74705SXin Li if (!cxcursor::isFirstInDeclGroup(C))
5272*67e74705SXin Li Loc = VD->getLocation();
5273*67e74705SXin Li }
5274*67e74705SXin Li
5275*67e74705SXin Li // For ObjC methods, give the start location of the method name.
5276*67e74705SXin Li if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
5277*67e74705SXin Li Loc = MD->getSelectorStartLoc();
5278*67e74705SXin Li
5279*67e74705SXin Li return cxloc::translateSourceLocation(getCursorContext(C), Loc);
5280*67e74705SXin Li }
5281*67e74705SXin Li
5282*67e74705SXin Li } // end extern "C"
5283*67e74705SXin Li
getCursor(CXTranslationUnit TU,SourceLocation SLoc)5284*67e74705SXin Li CXCursor cxcursor::getCursor(CXTranslationUnit TU, SourceLocation SLoc) {
5285*67e74705SXin Li assert(TU);
5286*67e74705SXin Li
5287*67e74705SXin Li // Guard against an invalid SourceLocation, or we may assert in one
5288*67e74705SXin Li // of the following calls.
5289*67e74705SXin Li if (SLoc.isInvalid())
5290*67e74705SXin Li return clang_getNullCursor();
5291*67e74705SXin Li
5292*67e74705SXin Li ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
5293*67e74705SXin Li
5294*67e74705SXin Li // Translate the given source location to make it point at the beginning of
5295*67e74705SXin Li // the token under the cursor.
5296*67e74705SXin Li SLoc = Lexer::GetBeginningOfToken(SLoc, CXXUnit->getSourceManager(),
5297*67e74705SXin Li CXXUnit->getASTContext().getLangOpts());
5298*67e74705SXin Li
5299*67e74705SXin Li CXCursor Result = MakeCXCursorInvalid(CXCursor_NoDeclFound);
5300*67e74705SXin Li if (SLoc.isValid()) {
5301*67e74705SXin Li GetCursorData ResultData(CXXUnit->getSourceManager(), SLoc, Result);
5302*67e74705SXin Li CursorVisitor CursorVis(TU, GetCursorVisitor, &ResultData,
5303*67e74705SXin Li /*VisitPreprocessorLast=*/true,
5304*67e74705SXin Li /*VisitIncludedEntities=*/false,
5305*67e74705SXin Li SourceLocation(SLoc));
5306*67e74705SXin Li CursorVis.visitFileRegion();
5307*67e74705SXin Li }
5308*67e74705SXin Li
5309*67e74705SXin Li return Result;
5310*67e74705SXin Li }
5311*67e74705SXin Li
getRawCursorExtent(CXCursor C)5312*67e74705SXin Li static SourceRange getRawCursorExtent(CXCursor C) {
5313*67e74705SXin Li if (clang_isReference(C.kind)) {
5314*67e74705SXin Li switch (C.kind) {
5315*67e74705SXin Li case CXCursor_ObjCSuperClassRef:
5316*67e74705SXin Li return getCursorObjCSuperClassRef(C).second;
5317*67e74705SXin Li
5318*67e74705SXin Li case CXCursor_ObjCProtocolRef:
5319*67e74705SXin Li return getCursorObjCProtocolRef(C).second;
5320*67e74705SXin Li
5321*67e74705SXin Li case CXCursor_ObjCClassRef:
5322*67e74705SXin Li return getCursorObjCClassRef(C).second;
5323*67e74705SXin Li
5324*67e74705SXin Li case CXCursor_TypeRef:
5325*67e74705SXin Li return getCursorTypeRef(C).second;
5326*67e74705SXin Li
5327*67e74705SXin Li case CXCursor_TemplateRef:
5328*67e74705SXin Li return getCursorTemplateRef(C).second;
5329*67e74705SXin Li
5330*67e74705SXin Li case CXCursor_NamespaceRef:
5331*67e74705SXin Li return getCursorNamespaceRef(C).second;
5332*67e74705SXin Li
5333*67e74705SXin Li case CXCursor_MemberRef:
5334*67e74705SXin Li return getCursorMemberRef(C).second;
5335*67e74705SXin Li
5336*67e74705SXin Li case CXCursor_CXXBaseSpecifier:
5337*67e74705SXin Li return getCursorCXXBaseSpecifier(C)->getSourceRange();
5338*67e74705SXin Li
5339*67e74705SXin Li case CXCursor_LabelRef:
5340*67e74705SXin Li return getCursorLabelRef(C).second;
5341*67e74705SXin Li
5342*67e74705SXin Li case CXCursor_OverloadedDeclRef:
5343*67e74705SXin Li return getCursorOverloadedDeclRef(C).second;
5344*67e74705SXin Li
5345*67e74705SXin Li case CXCursor_VariableRef:
5346*67e74705SXin Li return getCursorVariableRef(C).second;
5347*67e74705SXin Li
5348*67e74705SXin Li default:
5349*67e74705SXin Li // FIXME: Need a way to enumerate all non-reference cases.
5350*67e74705SXin Li llvm_unreachable("Missed a reference kind");
5351*67e74705SXin Li }
5352*67e74705SXin Li }
5353*67e74705SXin Li
5354*67e74705SXin Li if (clang_isExpression(C.kind))
5355*67e74705SXin Li return getCursorExpr(C)->getSourceRange();
5356*67e74705SXin Li
5357*67e74705SXin Li if (clang_isStatement(C.kind))
5358*67e74705SXin Li return getCursorStmt(C)->getSourceRange();
5359*67e74705SXin Li
5360*67e74705SXin Li if (clang_isAttribute(C.kind))
5361*67e74705SXin Li return getCursorAttr(C)->getRange();
5362*67e74705SXin Li
5363*67e74705SXin Li if (C.kind == CXCursor_PreprocessingDirective)
5364*67e74705SXin Li return cxcursor::getCursorPreprocessingDirective(C);
5365*67e74705SXin Li
5366*67e74705SXin Li if (C.kind == CXCursor_MacroExpansion) {
5367*67e74705SXin Li ASTUnit *TU = getCursorASTUnit(C);
5368*67e74705SXin Li SourceRange Range = cxcursor::getCursorMacroExpansion(C).getSourceRange();
5369*67e74705SXin Li return TU->mapRangeFromPreamble(Range);
5370*67e74705SXin Li }
5371*67e74705SXin Li
5372*67e74705SXin Li if (C.kind == CXCursor_MacroDefinition) {
5373*67e74705SXin Li ASTUnit *TU = getCursorASTUnit(C);
5374*67e74705SXin Li SourceRange Range = cxcursor::getCursorMacroDefinition(C)->getSourceRange();
5375*67e74705SXin Li return TU->mapRangeFromPreamble(Range);
5376*67e74705SXin Li }
5377*67e74705SXin Li
5378*67e74705SXin Li if (C.kind == CXCursor_InclusionDirective) {
5379*67e74705SXin Li ASTUnit *TU = getCursorASTUnit(C);
5380*67e74705SXin Li SourceRange Range = cxcursor::getCursorInclusionDirective(C)->getSourceRange();
5381*67e74705SXin Li return TU->mapRangeFromPreamble(Range);
5382*67e74705SXin Li }
5383*67e74705SXin Li
5384*67e74705SXin Li if (C.kind == CXCursor_TranslationUnit) {
5385*67e74705SXin Li ASTUnit *TU = getCursorASTUnit(C);
5386*67e74705SXin Li FileID MainID = TU->getSourceManager().getMainFileID();
5387*67e74705SXin Li SourceLocation Start = TU->getSourceManager().getLocForStartOfFile(MainID);
5388*67e74705SXin Li SourceLocation End = TU->getSourceManager().getLocForEndOfFile(MainID);
5389*67e74705SXin Li return SourceRange(Start, End);
5390*67e74705SXin Li }
5391*67e74705SXin Li
5392*67e74705SXin Li if (clang_isDeclaration(C.kind)) {
5393*67e74705SXin Li const Decl *D = cxcursor::getCursorDecl(C);
5394*67e74705SXin Li if (!D)
5395*67e74705SXin Li return SourceRange();
5396*67e74705SXin Li
5397*67e74705SXin Li SourceRange R = D->getSourceRange();
5398*67e74705SXin Li // FIXME: Multiple variables declared in a single declaration
5399*67e74705SXin Li // currently lack the information needed to correctly determine their
5400*67e74705SXin Li // ranges when accounting for the type-specifier. We use context
5401*67e74705SXin Li // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
5402*67e74705SXin Li // and if so, whether it is the first decl.
5403*67e74705SXin Li if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
5404*67e74705SXin Li if (!cxcursor::isFirstInDeclGroup(C))
5405*67e74705SXin Li R.setBegin(VD->getLocation());
5406*67e74705SXin Li }
5407*67e74705SXin Li return R;
5408*67e74705SXin Li }
5409*67e74705SXin Li return SourceRange();
5410*67e74705SXin Li }
5411*67e74705SXin Li
5412*67e74705SXin Li /// \brief Retrieves the "raw" cursor extent, which is then extended to include
5413*67e74705SXin Li /// the decl-specifier-seq for declarations.
getFullCursorExtent(CXCursor C,SourceManager & SrcMgr)5414*67e74705SXin Li static SourceRange getFullCursorExtent(CXCursor C, SourceManager &SrcMgr) {
5415*67e74705SXin Li if (clang_isDeclaration(C.kind)) {
5416*67e74705SXin Li const Decl *D = cxcursor::getCursorDecl(C);
5417*67e74705SXin Li if (!D)
5418*67e74705SXin Li return SourceRange();
5419*67e74705SXin Li
5420*67e74705SXin Li SourceRange R = D->getSourceRange();
5421*67e74705SXin Li
5422*67e74705SXin Li // Adjust the start of the location for declarations preceded by
5423*67e74705SXin Li // declaration specifiers.
5424*67e74705SXin Li SourceLocation StartLoc;
5425*67e74705SXin Li if (const DeclaratorDecl *DD = dyn_cast<DeclaratorDecl>(D)) {
5426*67e74705SXin Li if (TypeSourceInfo *TI = DD->getTypeSourceInfo())
5427*67e74705SXin Li StartLoc = TI->getTypeLoc().getLocStart();
5428*67e74705SXin Li } else if (const TypedefDecl *Typedef = dyn_cast<TypedefDecl>(D)) {
5429*67e74705SXin Li if (TypeSourceInfo *TI = Typedef->getTypeSourceInfo())
5430*67e74705SXin Li StartLoc = TI->getTypeLoc().getLocStart();
5431*67e74705SXin Li }
5432*67e74705SXin Li
5433*67e74705SXin Li if (StartLoc.isValid() && R.getBegin().isValid() &&
5434*67e74705SXin Li SrcMgr.isBeforeInTranslationUnit(StartLoc, R.getBegin()))
5435*67e74705SXin Li R.setBegin(StartLoc);
5436*67e74705SXin Li
5437*67e74705SXin Li // FIXME: Multiple variables declared in a single declaration
5438*67e74705SXin Li // currently lack the information needed to correctly determine their
5439*67e74705SXin Li // ranges when accounting for the type-specifier. We use context
5440*67e74705SXin Li // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
5441*67e74705SXin Li // and if so, whether it is the first decl.
5442*67e74705SXin Li if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
5443*67e74705SXin Li if (!cxcursor::isFirstInDeclGroup(C))
5444*67e74705SXin Li R.setBegin(VD->getLocation());
5445*67e74705SXin Li }
5446*67e74705SXin Li
5447*67e74705SXin Li return R;
5448*67e74705SXin Li }
5449*67e74705SXin Li
5450*67e74705SXin Li return getRawCursorExtent(C);
5451*67e74705SXin Li }
5452*67e74705SXin Li
5453*67e74705SXin Li extern "C" {
5454*67e74705SXin Li
clang_getCursorExtent(CXCursor C)5455*67e74705SXin Li CXSourceRange clang_getCursorExtent(CXCursor C) {
5456*67e74705SXin Li SourceRange R = getRawCursorExtent(C);
5457*67e74705SXin Li if (R.isInvalid())
5458*67e74705SXin Li return clang_getNullRange();
5459*67e74705SXin Li
5460*67e74705SXin Li return cxloc::translateSourceRange(getCursorContext(C), R);
5461*67e74705SXin Li }
5462*67e74705SXin Li
clang_getCursorReferenced(CXCursor C)5463*67e74705SXin Li CXCursor clang_getCursorReferenced(CXCursor C) {
5464*67e74705SXin Li if (clang_isInvalid(C.kind))
5465*67e74705SXin Li return clang_getNullCursor();
5466*67e74705SXin Li
5467*67e74705SXin Li CXTranslationUnit tu = getCursorTU(C);
5468*67e74705SXin Li if (clang_isDeclaration(C.kind)) {
5469*67e74705SXin Li const Decl *D = getCursorDecl(C);
5470*67e74705SXin Li if (!D)
5471*67e74705SXin Li return clang_getNullCursor();
5472*67e74705SXin Li if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
5473*67e74705SXin Li return MakeCursorOverloadedDeclRef(Using, D->getLocation(), tu);
5474*67e74705SXin Li if (const ObjCPropertyImplDecl *PropImpl =
5475*67e74705SXin Li dyn_cast<ObjCPropertyImplDecl>(D))
5476*67e74705SXin Li if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
5477*67e74705SXin Li return MakeCXCursor(Property, tu);
5478*67e74705SXin Li
5479*67e74705SXin Li return C;
5480*67e74705SXin Li }
5481*67e74705SXin Li
5482*67e74705SXin Li if (clang_isExpression(C.kind)) {
5483*67e74705SXin Li const Expr *E = getCursorExpr(C);
5484*67e74705SXin Li const Decl *D = getDeclFromExpr(E);
5485*67e74705SXin Li if (D) {
5486*67e74705SXin Li CXCursor declCursor = MakeCXCursor(D, tu);
5487*67e74705SXin Li declCursor = getSelectorIdentifierCursor(getSelectorIdentifierIndex(C),
5488*67e74705SXin Li declCursor);
5489*67e74705SXin Li return declCursor;
5490*67e74705SXin Li }
5491*67e74705SXin Li
5492*67e74705SXin Li if (const OverloadExpr *Ovl = dyn_cast_or_null<OverloadExpr>(E))
5493*67e74705SXin Li return MakeCursorOverloadedDeclRef(Ovl, tu);
5494*67e74705SXin Li
5495*67e74705SXin Li return clang_getNullCursor();
5496*67e74705SXin Li }
5497*67e74705SXin Li
5498*67e74705SXin Li if (clang_isStatement(C.kind)) {
5499*67e74705SXin Li const Stmt *S = getCursorStmt(C);
5500*67e74705SXin Li if (const GotoStmt *Goto = dyn_cast_or_null<GotoStmt>(S))
5501*67e74705SXin Li if (LabelDecl *label = Goto->getLabel())
5502*67e74705SXin Li if (LabelStmt *labelS = label->getStmt())
5503*67e74705SXin Li return MakeCXCursor(labelS, getCursorDecl(C), tu);
5504*67e74705SXin Li
5505*67e74705SXin Li return clang_getNullCursor();
5506*67e74705SXin Li }
5507*67e74705SXin Li
5508*67e74705SXin Li if (C.kind == CXCursor_MacroExpansion) {
5509*67e74705SXin Li if (const MacroDefinitionRecord *Def =
5510*67e74705SXin Li getCursorMacroExpansion(C).getDefinition())
5511*67e74705SXin Li return MakeMacroDefinitionCursor(Def, tu);
5512*67e74705SXin Li }
5513*67e74705SXin Li
5514*67e74705SXin Li if (!clang_isReference(C.kind))
5515*67e74705SXin Li return clang_getNullCursor();
5516*67e74705SXin Li
5517*67e74705SXin Li switch (C.kind) {
5518*67e74705SXin Li case CXCursor_ObjCSuperClassRef:
5519*67e74705SXin Li return MakeCXCursor(getCursorObjCSuperClassRef(C).first, tu);
5520*67e74705SXin Li
5521*67e74705SXin Li case CXCursor_ObjCProtocolRef: {
5522*67e74705SXin Li const ObjCProtocolDecl *Prot = getCursorObjCProtocolRef(C).first;
5523*67e74705SXin Li if (const ObjCProtocolDecl *Def = Prot->getDefinition())
5524*67e74705SXin Li return MakeCXCursor(Def, tu);
5525*67e74705SXin Li
5526*67e74705SXin Li return MakeCXCursor(Prot, tu);
5527*67e74705SXin Li }
5528*67e74705SXin Li
5529*67e74705SXin Li case CXCursor_ObjCClassRef: {
5530*67e74705SXin Li const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
5531*67e74705SXin Li if (const ObjCInterfaceDecl *Def = Class->getDefinition())
5532*67e74705SXin Li return MakeCXCursor(Def, tu);
5533*67e74705SXin Li
5534*67e74705SXin Li return MakeCXCursor(Class, tu);
5535*67e74705SXin Li }
5536*67e74705SXin Li
5537*67e74705SXin Li case CXCursor_TypeRef:
5538*67e74705SXin Li return MakeCXCursor(getCursorTypeRef(C).first, tu );
5539*67e74705SXin Li
5540*67e74705SXin Li case CXCursor_TemplateRef:
5541*67e74705SXin Li return MakeCXCursor(getCursorTemplateRef(C).first, tu );
5542*67e74705SXin Li
5543*67e74705SXin Li case CXCursor_NamespaceRef:
5544*67e74705SXin Li return MakeCXCursor(getCursorNamespaceRef(C).first, tu );
5545*67e74705SXin Li
5546*67e74705SXin Li case CXCursor_MemberRef:
5547*67e74705SXin Li return MakeCXCursor(getCursorMemberRef(C).first, tu );
5548*67e74705SXin Li
5549*67e74705SXin Li case CXCursor_CXXBaseSpecifier: {
5550*67e74705SXin Li const CXXBaseSpecifier *B = cxcursor::getCursorCXXBaseSpecifier(C);
5551*67e74705SXin Li return clang_getTypeDeclaration(cxtype::MakeCXType(B->getType(),
5552*67e74705SXin Li tu ));
5553*67e74705SXin Li }
5554*67e74705SXin Li
5555*67e74705SXin Li case CXCursor_LabelRef:
5556*67e74705SXin Li // FIXME: We end up faking the "parent" declaration here because we
5557*67e74705SXin Li // don't want to make CXCursor larger.
5558*67e74705SXin Li return MakeCXCursor(getCursorLabelRef(C).first,
5559*67e74705SXin Li cxtu::getASTUnit(tu)->getASTContext()
5560*67e74705SXin Li .getTranslationUnitDecl(),
5561*67e74705SXin Li tu);
5562*67e74705SXin Li
5563*67e74705SXin Li case CXCursor_OverloadedDeclRef:
5564*67e74705SXin Li return C;
5565*67e74705SXin Li
5566*67e74705SXin Li case CXCursor_VariableRef:
5567*67e74705SXin Li return MakeCXCursor(getCursorVariableRef(C).first, tu);
5568*67e74705SXin Li
5569*67e74705SXin Li default:
5570*67e74705SXin Li // We would prefer to enumerate all non-reference cursor kinds here.
5571*67e74705SXin Li llvm_unreachable("Unhandled reference cursor kind");
5572*67e74705SXin Li }
5573*67e74705SXin Li }
5574*67e74705SXin Li
clang_getCursorDefinition(CXCursor C)5575*67e74705SXin Li CXCursor clang_getCursorDefinition(CXCursor C) {
5576*67e74705SXin Li if (clang_isInvalid(C.kind))
5577*67e74705SXin Li return clang_getNullCursor();
5578*67e74705SXin Li
5579*67e74705SXin Li CXTranslationUnit TU = getCursorTU(C);
5580*67e74705SXin Li
5581*67e74705SXin Li bool WasReference = false;
5582*67e74705SXin Li if (clang_isReference(C.kind) || clang_isExpression(C.kind)) {
5583*67e74705SXin Li C = clang_getCursorReferenced(C);
5584*67e74705SXin Li WasReference = true;
5585*67e74705SXin Li }
5586*67e74705SXin Li
5587*67e74705SXin Li if (C.kind == CXCursor_MacroExpansion)
5588*67e74705SXin Li return clang_getCursorReferenced(C);
5589*67e74705SXin Li
5590*67e74705SXin Li if (!clang_isDeclaration(C.kind))
5591*67e74705SXin Li return clang_getNullCursor();
5592*67e74705SXin Li
5593*67e74705SXin Li const Decl *D = getCursorDecl(C);
5594*67e74705SXin Li if (!D)
5595*67e74705SXin Li return clang_getNullCursor();
5596*67e74705SXin Li
5597*67e74705SXin Li switch (D->getKind()) {
5598*67e74705SXin Li // Declaration kinds that don't really separate the notions of
5599*67e74705SXin Li // declaration and definition.
5600*67e74705SXin Li case Decl::Namespace:
5601*67e74705SXin Li case Decl::Typedef:
5602*67e74705SXin Li case Decl::TypeAlias:
5603*67e74705SXin Li case Decl::TypeAliasTemplate:
5604*67e74705SXin Li case Decl::TemplateTypeParm:
5605*67e74705SXin Li case Decl::EnumConstant:
5606*67e74705SXin Li case Decl::Field:
5607*67e74705SXin Li case Decl::MSProperty:
5608*67e74705SXin Li case Decl::IndirectField:
5609*67e74705SXin Li case Decl::ObjCIvar:
5610*67e74705SXin Li case Decl::ObjCAtDefsField:
5611*67e74705SXin Li case Decl::ImplicitParam:
5612*67e74705SXin Li case Decl::ParmVar:
5613*67e74705SXin Li case Decl::NonTypeTemplateParm:
5614*67e74705SXin Li case Decl::TemplateTemplateParm:
5615*67e74705SXin Li case Decl::ObjCCategoryImpl:
5616*67e74705SXin Li case Decl::ObjCImplementation:
5617*67e74705SXin Li case Decl::AccessSpec:
5618*67e74705SXin Li case Decl::LinkageSpec:
5619*67e74705SXin Li case Decl::ObjCPropertyImpl:
5620*67e74705SXin Li case Decl::FileScopeAsm:
5621*67e74705SXin Li case Decl::StaticAssert:
5622*67e74705SXin Li case Decl::Block:
5623*67e74705SXin Li case Decl::Captured:
5624*67e74705SXin Li case Decl::OMPCapturedExpr:
5625*67e74705SXin Li case Decl::Label: // FIXME: Is this right??
5626*67e74705SXin Li case Decl::ClassScopeFunctionSpecialization:
5627*67e74705SXin Li case Decl::Import:
5628*67e74705SXin Li case Decl::OMPThreadPrivate:
5629*67e74705SXin Li case Decl::OMPDeclareReduction:
5630*67e74705SXin Li case Decl::ObjCTypeParam:
5631*67e74705SXin Li case Decl::BuiltinTemplate:
5632*67e74705SXin Li case Decl::PragmaComment:
5633*67e74705SXin Li case Decl::PragmaDetectMismatch:
5634*67e74705SXin Li return C;
5635*67e74705SXin Li
5636*67e74705SXin Li // Declaration kinds that don't make any sense here, but are
5637*67e74705SXin Li // nonetheless harmless.
5638*67e74705SXin Li case Decl::Empty:
5639*67e74705SXin Li case Decl::TranslationUnit:
5640*67e74705SXin Li case Decl::ExternCContext:
5641*67e74705SXin Li break;
5642*67e74705SXin Li
5643*67e74705SXin Li // Declaration kinds for which the definition is not resolvable.
5644*67e74705SXin Li case Decl::UnresolvedUsingTypename:
5645*67e74705SXin Li case Decl::UnresolvedUsingValue:
5646*67e74705SXin Li break;
5647*67e74705SXin Li
5648*67e74705SXin Li case Decl::UsingDirective:
5649*67e74705SXin Li return MakeCXCursor(cast<UsingDirectiveDecl>(D)->getNominatedNamespace(),
5650*67e74705SXin Li TU);
5651*67e74705SXin Li
5652*67e74705SXin Li case Decl::NamespaceAlias:
5653*67e74705SXin Li return MakeCXCursor(cast<NamespaceAliasDecl>(D)->getNamespace(), TU);
5654*67e74705SXin Li
5655*67e74705SXin Li case Decl::Enum:
5656*67e74705SXin Li case Decl::Record:
5657*67e74705SXin Li case Decl::CXXRecord:
5658*67e74705SXin Li case Decl::ClassTemplateSpecialization:
5659*67e74705SXin Li case Decl::ClassTemplatePartialSpecialization:
5660*67e74705SXin Li if (TagDecl *Def = cast<TagDecl>(D)->getDefinition())
5661*67e74705SXin Li return MakeCXCursor(Def, TU);
5662*67e74705SXin Li return clang_getNullCursor();
5663*67e74705SXin Li
5664*67e74705SXin Li case Decl::Function:
5665*67e74705SXin Li case Decl::CXXMethod:
5666*67e74705SXin Li case Decl::CXXConstructor:
5667*67e74705SXin Li case Decl::CXXDestructor:
5668*67e74705SXin Li case Decl::CXXConversion: {
5669*67e74705SXin Li const FunctionDecl *Def = nullptr;
5670*67e74705SXin Li if (cast<FunctionDecl>(D)->getBody(Def))
5671*67e74705SXin Li return MakeCXCursor(Def, TU);
5672*67e74705SXin Li return clang_getNullCursor();
5673*67e74705SXin Li }
5674*67e74705SXin Li
5675*67e74705SXin Li case Decl::Var:
5676*67e74705SXin Li case Decl::VarTemplateSpecialization:
5677*67e74705SXin Li case Decl::VarTemplatePartialSpecialization: {
5678*67e74705SXin Li // Ask the variable if it has a definition.
5679*67e74705SXin Li if (const VarDecl *Def = cast<VarDecl>(D)->getDefinition())
5680*67e74705SXin Li return MakeCXCursor(Def, TU);
5681*67e74705SXin Li return clang_getNullCursor();
5682*67e74705SXin Li }
5683*67e74705SXin Li
5684*67e74705SXin Li case Decl::FunctionTemplate: {
5685*67e74705SXin Li const FunctionDecl *Def = nullptr;
5686*67e74705SXin Li if (cast<FunctionTemplateDecl>(D)->getTemplatedDecl()->getBody(Def))
5687*67e74705SXin Li return MakeCXCursor(Def->getDescribedFunctionTemplate(), TU);
5688*67e74705SXin Li return clang_getNullCursor();
5689*67e74705SXin Li }
5690*67e74705SXin Li
5691*67e74705SXin Li case Decl::ClassTemplate: {
5692*67e74705SXin Li if (RecordDecl *Def = cast<ClassTemplateDecl>(D)->getTemplatedDecl()
5693*67e74705SXin Li ->getDefinition())
5694*67e74705SXin Li return MakeCXCursor(cast<CXXRecordDecl>(Def)->getDescribedClassTemplate(),
5695*67e74705SXin Li TU);
5696*67e74705SXin Li return clang_getNullCursor();
5697*67e74705SXin Li }
5698*67e74705SXin Li
5699*67e74705SXin Li case Decl::VarTemplate: {
5700*67e74705SXin Li if (VarDecl *Def =
5701*67e74705SXin Li cast<VarTemplateDecl>(D)->getTemplatedDecl()->getDefinition())
5702*67e74705SXin Li return MakeCXCursor(cast<VarDecl>(Def)->getDescribedVarTemplate(), TU);
5703*67e74705SXin Li return clang_getNullCursor();
5704*67e74705SXin Li }
5705*67e74705SXin Li
5706*67e74705SXin Li case Decl::Using:
5707*67e74705SXin Li return MakeCursorOverloadedDeclRef(cast<UsingDecl>(D),
5708*67e74705SXin Li D->getLocation(), TU);
5709*67e74705SXin Li
5710*67e74705SXin Li case Decl::UsingShadow:
5711*67e74705SXin Li case Decl::ConstructorUsingShadow:
5712*67e74705SXin Li return clang_getCursorDefinition(
5713*67e74705SXin Li MakeCXCursor(cast<UsingShadowDecl>(D)->getTargetDecl(),
5714*67e74705SXin Li TU));
5715*67e74705SXin Li
5716*67e74705SXin Li case Decl::ObjCMethod: {
5717*67e74705SXin Li const ObjCMethodDecl *Method = cast<ObjCMethodDecl>(D);
5718*67e74705SXin Li if (Method->isThisDeclarationADefinition())
5719*67e74705SXin Li return C;
5720*67e74705SXin Li
5721*67e74705SXin Li // Dig out the method definition in the associated
5722*67e74705SXin Li // @implementation, if we have it.
5723*67e74705SXin Li // FIXME: The ASTs should make finding the definition easier.
5724*67e74705SXin Li if (const ObjCInterfaceDecl *Class
5725*67e74705SXin Li = dyn_cast<ObjCInterfaceDecl>(Method->getDeclContext()))
5726*67e74705SXin Li if (ObjCImplementationDecl *ClassImpl = Class->getImplementation())
5727*67e74705SXin Li if (ObjCMethodDecl *Def = ClassImpl->getMethod(Method->getSelector(),
5728*67e74705SXin Li Method->isInstanceMethod()))
5729*67e74705SXin Li if (Def->isThisDeclarationADefinition())
5730*67e74705SXin Li return MakeCXCursor(Def, TU);
5731*67e74705SXin Li
5732*67e74705SXin Li return clang_getNullCursor();
5733*67e74705SXin Li }
5734*67e74705SXin Li
5735*67e74705SXin Li case Decl::ObjCCategory:
5736*67e74705SXin Li if (ObjCCategoryImplDecl *Impl
5737*67e74705SXin Li = cast<ObjCCategoryDecl>(D)->getImplementation())
5738*67e74705SXin Li return MakeCXCursor(Impl, TU);
5739*67e74705SXin Li return clang_getNullCursor();
5740*67e74705SXin Li
5741*67e74705SXin Li case Decl::ObjCProtocol:
5742*67e74705SXin Li if (const ObjCProtocolDecl *Def = cast<ObjCProtocolDecl>(D)->getDefinition())
5743*67e74705SXin Li return MakeCXCursor(Def, TU);
5744*67e74705SXin Li return clang_getNullCursor();
5745*67e74705SXin Li
5746*67e74705SXin Li case Decl::ObjCInterface: {
5747*67e74705SXin Li // There are two notions of a "definition" for an Objective-C
5748*67e74705SXin Li // class: the interface and its implementation. When we resolved a
5749*67e74705SXin Li // reference to an Objective-C class, produce the @interface as
5750*67e74705SXin Li // the definition; when we were provided with the interface,
5751*67e74705SXin Li // produce the @implementation as the definition.
5752*67e74705SXin Li const ObjCInterfaceDecl *IFace = cast<ObjCInterfaceDecl>(D);
5753*67e74705SXin Li if (WasReference) {
5754*67e74705SXin Li if (const ObjCInterfaceDecl *Def = IFace->getDefinition())
5755*67e74705SXin Li return MakeCXCursor(Def, TU);
5756*67e74705SXin Li } else if (ObjCImplementationDecl *Impl = IFace->getImplementation())
5757*67e74705SXin Li return MakeCXCursor(Impl, TU);
5758*67e74705SXin Li return clang_getNullCursor();
5759*67e74705SXin Li }
5760*67e74705SXin Li
5761*67e74705SXin Li case Decl::ObjCProperty:
5762*67e74705SXin Li // FIXME: We don't really know where to find the
5763*67e74705SXin Li // ObjCPropertyImplDecls that implement this property.
5764*67e74705SXin Li return clang_getNullCursor();
5765*67e74705SXin Li
5766*67e74705SXin Li case Decl::ObjCCompatibleAlias:
5767*67e74705SXin Li if (const ObjCInterfaceDecl *Class
5768*67e74705SXin Li = cast<ObjCCompatibleAliasDecl>(D)->getClassInterface())
5769*67e74705SXin Li if (const ObjCInterfaceDecl *Def = Class->getDefinition())
5770*67e74705SXin Li return MakeCXCursor(Def, TU);
5771*67e74705SXin Li
5772*67e74705SXin Li return clang_getNullCursor();
5773*67e74705SXin Li
5774*67e74705SXin Li case Decl::Friend:
5775*67e74705SXin Li if (NamedDecl *Friend = cast<FriendDecl>(D)->getFriendDecl())
5776*67e74705SXin Li return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
5777*67e74705SXin Li return clang_getNullCursor();
5778*67e74705SXin Li
5779*67e74705SXin Li case Decl::FriendTemplate:
5780*67e74705SXin Li if (NamedDecl *Friend = cast<FriendTemplateDecl>(D)->getFriendDecl())
5781*67e74705SXin Li return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
5782*67e74705SXin Li return clang_getNullCursor();
5783*67e74705SXin Li }
5784*67e74705SXin Li
5785*67e74705SXin Li return clang_getNullCursor();
5786*67e74705SXin Li }
5787*67e74705SXin Li
clang_isCursorDefinition(CXCursor C)5788*67e74705SXin Li unsigned clang_isCursorDefinition(CXCursor C) {
5789*67e74705SXin Li if (!clang_isDeclaration(C.kind))
5790*67e74705SXin Li return 0;
5791*67e74705SXin Li
5792*67e74705SXin Li return clang_getCursorDefinition(C) == C;
5793*67e74705SXin Li }
5794*67e74705SXin Li
clang_getCanonicalCursor(CXCursor C)5795*67e74705SXin Li CXCursor clang_getCanonicalCursor(CXCursor C) {
5796*67e74705SXin Li if (!clang_isDeclaration(C.kind))
5797*67e74705SXin Li return C;
5798*67e74705SXin Li
5799*67e74705SXin Li if (const Decl *D = getCursorDecl(C)) {
5800*67e74705SXin Li if (const ObjCCategoryImplDecl *CatImplD = dyn_cast<ObjCCategoryImplDecl>(D))
5801*67e74705SXin Li if (ObjCCategoryDecl *CatD = CatImplD->getCategoryDecl())
5802*67e74705SXin Li return MakeCXCursor(CatD, getCursorTU(C));
5803*67e74705SXin Li
5804*67e74705SXin Li if (const ObjCImplDecl *ImplD = dyn_cast<ObjCImplDecl>(D))
5805*67e74705SXin Li if (const ObjCInterfaceDecl *IFD = ImplD->getClassInterface())
5806*67e74705SXin Li return MakeCXCursor(IFD, getCursorTU(C));
5807*67e74705SXin Li
5808*67e74705SXin Li return MakeCXCursor(D->getCanonicalDecl(), getCursorTU(C));
5809*67e74705SXin Li }
5810*67e74705SXin Li
5811*67e74705SXin Li return C;
5812*67e74705SXin Li }
5813*67e74705SXin Li
clang_Cursor_getObjCSelectorIndex(CXCursor cursor)5814*67e74705SXin Li int clang_Cursor_getObjCSelectorIndex(CXCursor cursor) {
5815*67e74705SXin Li return cxcursor::getSelectorIdentifierIndexAndLoc(cursor).first;
5816*67e74705SXin Li }
5817*67e74705SXin Li
clang_getNumOverloadedDecls(CXCursor C)5818*67e74705SXin Li unsigned clang_getNumOverloadedDecls(CXCursor C) {
5819*67e74705SXin Li if (C.kind != CXCursor_OverloadedDeclRef)
5820*67e74705SXin Li return 0;
5821*67e74705SXin Li
5822*67e74705SXin Li OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
5823*67e74705SXin Li if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
5824*67e74705SXin Li return E->getNumDecls();
5825*67e74705SXin Li
5826*67e74705SXin Li if (OverloadedTemplateStorage *S
5827*67e74705SXin Li = Storage.dyn_cast<OverloadedTemplateStorage*>())
5828*67e74705SXin Li return S->size();
5829*67e74705SXin Li
5830*67e74705SXin Li const Decl *D = Storage.get<const Decl *>();
5831*67e74705SXin Li if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
5832*67e74705SXin Li return Using->shadow_size();
5833*67e74705SXin Li
5834*67e74705SXin Li return 0;
5835*67e74705SXin Li }
5836*67e74705SXin Li
clang_getOverloadedDecl(CXCursor cursor,unsigned index)5837*67e74705SXin Li CXCursor clang_getOverloadedDecl(CXCursor cursor, unsigned index) {
5838*67e74705SXin Li if (cursor.kind != CXCursor_OverloadedDeclRef)
5839*67e74705SXin Li return clang_getNullCursor();
5840*67e74705SXin Li
5841*67e74705SXin Li if (index >= clang_getNumOverloadedDecls(cursor))
5842*67e74705SXin Li return clang_getNullCursor();
5843*67e74705SXin Li
5844*67e74705SXin Li CXTranslationUnit TU = getCursorTU(cursor);
5845*67e74705SXin Li OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(cursor).first;
5846*67e74705SXin Li if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
5847*67e74705SXin Li return MakeCXCursor(E->decls_begin()[index], TU);
5848*67e74705SXin Li
5849*67e74705SXin Li if (OverloadedTemplateStorage *S
5850*67e74705SXin Li = Storage.dyn_cast<OverloadedTemplateStorage*>())
5851*67e74705SXin Li return MakeCXCursor(S->begin()[index], TU);
5852*67e74705SXin Li
5853*67e74705SXin Li const Decl *D = Storage.get<const Decl *>();
5854*67e74705SXin Li if (const UsingDecl *Using = dyn_cast<UsingDecl>(D)) {
5855*67e74705SXin Li // FIXME: This is, unfortunately, linear time.
5856*67e74705SXin Li UsingDecl::shadow_iterator Pos = Using->shadow_begin();
5857*67e74705SXin Li std::advance(Pos, index);
5858*67e74705SXin Li return MakeCXCursor(cast<UsingShadowDecl>(*Pos)->getTargetDecl(), TU);
5859*67e74705SXin Li }
5860*67e74705SXin Li
5861*67e74705SXin Li return clang_getNullCursor();
5862*67e74705SXin Li }
5863*67e74705SXin Li
clang_getDefinitionSpellingAndExtent(CXCursor C,const char ** startBuf,const char ** endBuf,unsigned * startLine,unsigned * startColumn,unsigned * endLine,unsigned * endColumn)5864*67e74705SXin Li void clang_getDefinitionSpellingAndExtent(CXCursor C,
5865*67e74705SXin Li const char **startBuf,
5866*67e74705SXin Li const char **endBuf,
5867*67e74705SXin Li unsigned *startLine,
5868*67e74705SXin Li unsigned *startColumn,
5869*67e74705SXin Li unsigned *endLine,
5870*67e74705SXin Li unsigned *endColumn) {
5871*67e74705SXin Li assert(getCursorDecl(C) && "CXCursor has null decl");
5872*67e74705SXin Li const FunctionDecl *FD = dyn_cast<FunctionDecl>(getCursorDecl(C));
5873*67e74705SXin Li CompoundStmt *Body = dyn_cast<CompoundStmt>(FD->getBody());
5874*67e74705SXin Li
5875*67e74705SXin Li SourceManager &SM = FD->getASTContext().getSourceManager();
5876*67e74705SXin Li *startBuf = SM.getCharacterData(Body->getLBracLoc());
5877*67e74705SXin Li *endBuf = SM.getCharacterData(Body->getRBracLoc());
5878*67e74705SXin Li *startLine = SM.getSpellingLineNumber(Body->getLBracLoc());
5879*67e74705SXin Li *startColumn = SM.getSpellingColumnNumber(Body->getLBracLoc());
5880*67e74705SXin Li *endLine = SM.getSpellingLineNumber(Body->getRBracLoc());
5881*67e74705SXin Li *endColumn = SM.getSpellingColumnNumber(Body->getRBracLoc());
5882*67e74705SXin Li }
5883*67e74705SXin Li
5884*67e74705SXin Li
clang_getCursorReferenceNameRange(CXCursor C,unsigned NameFlags,unsigned PieceIndex)5885*67e74705SXin Li CXSourceRange clang_getCursorReferenceNameRange(CXCursor C, unsigned NameFlags,
5886*67e74705SXin Li unsigned PieceIndex) {
5887*67e74705SXin Li RefNamePieces Pieces;
5888*67e74705SXin Li
5889*67e74705SXin Li switch (C.kind) {
5890*67e74705SXin Li case CXCursor_MemberRefExpr:
5891*67e74705SXin Li if (const MemberExpr *E = dyn_cast<MemberExpr>(getCursorExpr(C)))
5892*67e74705SXin Li Pieces = buildPieces(NameFlags, true, E->getMemberNameInfo(),
5893*67e74705SXin Li E->getQualifierLoc().getSourceRange());
5894*67e74705SXin Li break;
5895*67e74705SXin Li
5896*67e74705SXin Li case CXCursor_DeclRefExpr:
5897*67e74705SXin Li if (const DeclRefExpr *E = dyn_cast<DeclRefExpr>(getCursorExpr(C))) {
5898*67e74705SXin Li SourceRange TemplateArgLoc(E->getLAngleLoc(), E->getRAngleLoc());
5899*67e74705SXin Li Pieces =
5900*67e74705SXin Li buildPieces(NameFlags, false, E->getNameInfo(),
5901*67e74705SXin Li E->getQualifierLoc().getSourceRange(), &TemplateArgLoc);
5902*67e74705SXin Li }
5903*67e74705SXin Li break;
5904*67e74705SXin Li
5905*67e74705SXin Li case CXCursor_CallExpr:
5906*67e74705SXin Li if (const CXXOperatorCallExpr *OCE =
5907*67e74705SXin Li dyn_cast<CXXOperatorCallExpr>(getCursorExpr(C))) {
5908*67e74705SXin Li const Expr *Callee = OCE->getCallee();
5909*67e74705SXin Li if (const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Callee))
5910*67e74705SXin Li Callee = ICE->getSubExpr();
5911*67e74705SXin Li
5912*67e74705SXin Li if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(Callee))
5913*67e74705SXin Li Pieces = buildPieces(NameFlags, false, DRE->getNameInfo(),
5914*67e74705SXin Li DRE->getQualifierLoc().getSourceRange());
5915*67e74705SXin Li }
5916*67e74705SXin Li break;
5917*67e74705SXin Li
5918*67e74705SXin Li default:
5919*67e74705SXin Li break;
5920*67e74705SXin Li }
5921*67e74705SXin Li
5922*67e74705SXin Li if (Pieces.empty()) {
5923*67e74705SXin Li if (PieceIndex == 0)
5924*67e74705SXin Li return clang_getCursorExtent(C);
5925*67e74705SXin Li } else if (PieceIndex < Pieces.size()) {
5926*67e74705SXin Li SourceRange R = Pieces[PieceIndex];
5927*67e74705SXin Li if (R.isValid())
5928*67e74705SXin Li return cxloc::translateSourceRange(getCursorContext(C), R);
5929*67e74705SXin Li }
5930*67e74705SXin Li
5931*67e74705SXin Li return clang_getNullRange();
5932*67e74705SXin Li }
5933*67e74705SXin Li
clang_enableStackTraces(void)5934*67e74705SXin Li void clang_enableStackTraces(void) {
5935*67e74705SXin Li // FIXME: Provide an argv0 here so we can find llvm-symbolizer.
5936*67e74705SXin Li llvm::sys::PrintStackTraceOnErrorSignal(StringRef());
5937*67e74705SXin Li }
5938*67e74705SXin Li
clang_executeOnThread(void (* fn)(void *),void * user_data,unsigned stack_size)5939*67e74705SXin Li void clang_executeOnThread(void (*fn)(void*), void *user_data,
5940*67e74705SXin Li unsigned stack_size) {
5941*67e74705SXin Li llvm::llvm_execute_on_thread(fn, user_data, stack_size);
5942*67e74705SXin Li }
5943*67e74705SXin Li
5944*67e74705SXin Li } // end: extern "C"
5945*67e74705SXin Li
5946*67e74705SXin Li //===----------------------------------------------------------------------===//
5947*67e74705SXin Li // Token-based Operations.
5948*67e74705SXin Li //===----------------------------------------------------------------------===//
5949*67e74705SXin Li
5950*67e74705SXin Li /* CXToken layout:
5951*67e74705SXin Li * int_data[0]: a CXTokenKind
5952*67e74705SXin Li * int_data[1]: starting token location
5953*67e74705SXin Li * int_data[2]: token length
5954*67e74705SXin Li * int_data[3]: reserved
5955*67e74705SXin Li * ptr_data: for identifiers and keywords, an IdentifierInfo*.
5956*67e74705SXin Li * otherwise unused.
5957*67e74705SXin Li */
5958*67e74705SXin Li extern "C" {
5959*67e74705SXin Li
clang_getTokenKind(CXToken CXTok)5960*67e74705SXin Li CXTokenKind clang_getTokenKind(CXToken CXTok) {
5961*67e74705SXin Li return static_cast<CXTokenKind>(CXTok.int_data[0]);
5962*67e74705SXin Li }
5963*67e74705SXin Li
clang_getTokenSpelling(CXTranslationUnit TU,CXToken CXTok)5964*67e74705SXin Li CXString clang_getTokenSpelling(CXTranslationUnit TU, CXToken CXTok) {
5965*67e74705SXin Li switch (clang_getTokenKind(CXTok)) {
5966*67e74705SXin Li case CXToken_Identifier:
5967*67e74705SXin Li case CXToken_Keyword:
5968*67e74705SXin Li // We know we have an IdentifierInfo*, so use that.
5969*67e74705SXin Li return cxstring::createRef(static_cast<IdentifierInfo *>(CXTok.ptr_data)
5970*67e74705SXin Li ->getNameStart());
5971*67e74705SXin Li
5972*67e74705SXin Li case CXToken_Literal: {
5973*67e74705SXin Li // We have stashed the starting pointer in the ptr_data field. Use it.
5974*67e74705SXin Li const char *Text = static_cast<const char *>(CXTok.ptr_data);
5975*67e74705SXin Li return cxstring::createDup(StringRef(Text, CXTok.int_data[2]));
5976*67e74705SXin Li }
5977*67e74705SXin Li
5978*67e74705SXin Li case CXToken_Punctuation:
5979*67e74705SXin Li case CXToken_Comment:
5980*67e74705SXin Li break;
5981*67e74705SXin Li }
5982*67e74705SXin Li
5983*67e74705SXin Li if (isNotUsableTU(TU)) {
5984*67e74705SXin Li LOG_BAD_TU(TU);
5985*67e74705SXin Li return cxstring::createEmpty();
5986*67e74705SXin Li }
5987*67e74705SXin Li
5988*67e74705SXin Li // We have to find the starting buffer pointer the hard way, by
5989*67e74705SXin Li // deconstructing the source location.
5990*67e74705SXin Li ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
5991*67e74705SXin Li if (!CXXUnit)
5992*67e74705SXin Li return cxstring::createEmpty();
5993*67e74705SXin Li
5994*67e74705SXin Li SourceLocation Loc = SourceLocation::getFromRawEncoding(CXTok.int_data[1]);
5995*67e74705SXin Li std::pair<FileID, unsigned> LocInfo
5996*67e74705SXin Li = CXXUnit->getSourceManager().getDecomposedSpellingLoc(Loc);
5997*67e74705SXin Li bool Invalid = false;
5998*67e74705SXin Li StringRef Buffer
5999*67e74705SXin Li = CXXUnit->getSourceManager().getBufferData(LocInfo.first, &Invalid);
6000*67e74705SXin Li if (Invalid)
6001*67e74705SXin Li return cxstring::createEmpty();
6002*67e74705SXin Li
6003*67e74705SXin Li return cxstring::createDup(Buffer.substr(LocInfo.second, CXTok.int_data[2]));
6004*67e74705SXin Li }
6005*67e74705SXin Li
clang_getTokenLocation(CXTranslationUnit TU,CXToken CXTok)6006*67e74705SXin Li CXSourceLocation clang_getTokenLocation(CXTranslationUnit TU, CXToken CXTok) {
6007*67e74705SXin Li if (isNotUsableTU(TU)) {
6008*67e74705SXin Li LOG_BAD_TU(TU);
6009*67e74705SXin Li return clang_getNullLocation();
6010*67e74705SXin Li }
6011*67e74705SXin Li
6012*67e74705SXin Li ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
6013*67e74705SXin Li if (!CXXUnit)
6014*67e74705SXin Li return clang_getNullLocation();
6015*67e74705SXin Li
6016*67e74705SXin Li return cxloc::translateSourceLocation(CXXUnit->getASTContext(),
6017*67e74705SXin Li SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
6018*67e74705SXin Li }
6019*67e74705SXin Li
clang_getTokenExtent(CXTranslationUnit TU,CXToken CXTok)6020*67e74705SXin Li CXSourceRange clang_getTokenExtent(CXTranslationUnit TU, CXToken CXTok) {
6021*67e74705SXin Li if (isNotUsableTU(TU)) {
6022*67e74705SXin Li LOG_BAD_TU(TU);
6023*67e74705SXin Li return clang_getNullRange();
6024*67e74705SXin Li }
6025*67e74705SXin Li
6026*67e74705SXin Li ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
6027*67e74705SXin Li if (!CXXUnit)
6028*67e74705SXin Li return clang_getNullRange();
6029*67e74705SXin Li
6030*67e74705SXin Li return cxloc::translateSourceRange(CXXUnit->getASTContext(),
6031*67e74705SXin Li SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
6032*67e74705SXin Li }
6033*67e74705SXin Li
getTokens(ASTUnit * CXXUnit,SourceRange Range,SmallVectorImpl<CXToken> & CXTokens)6034*67e74705SXin Li static void getTokens(ASTUnit *CXXUnit, SourceRange Range,
6035*67e74705SXin Li SmallVectorImpl<CXToken> &CXTokens) {
6036*67e74705SXin Li SourceManager &SourceMgr = CXXUnit->getSourceManager();
6037*67e74705SXin Li std::pair<FileID, unsigned> BeginLocInfo
6038*67e74705SXin Li = SourceMgr.getDecomposedSpellingLoc(Range.getBegin());
6039*67e74705SXin Li std::pair<FileID, unsigned> EndLocInfo
6040*67e74705SXin Li = SourceMgr.getDecomposedSpellingLoc(Range.getEnd());
6041*67e74705SXin Li
6042*67e74705SXin Li // Cannot tokenize across files.
6043*67e74705SXin Li if (BeginLocInfo.first != EndLocInfo.first)
6044*67e74705SXin Li return;
6045*67e74705SXin Li
6046*67e74705SXin Li // Create a lexer
6047*67e74705SXin Li bool Invalid = false;
6048*67e74705SXin Li StringRef Buffer
6049*67e74705SXin Li = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
6050*67e74705SXin Li if (Invalid)
6051*67e74705SXin Li return;
6052*67e74705SXin Li
6053*67e74705SXin Li Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
6054*67e74705SXin Li CXXUnit->getASTContext().getLangOpts(),
6055*67e74705SXin Li Buffer.begin(), Buffer.data() + BeginLocInfo.second, Buffer.end());
6056*67e74705SXin Li Lex.SetCommentRetentionState(true);
6057*67e74705SXin Li
6058*67e74705SXin Li // Lex tokens until we hit the end of the range.
6059*67e74705SXin Li const char *EffectiveBufferEnd = Buffer.data() + EndLocInfo.second;
6060*67e74705SXin Li Token Tok;
6061*67e74705SXin Li bool previousWasAt = false;
6062*67e74705SXin Li do {
6063*67e74705SXin Li // Lex the next token
6064*67e74705SXin Li Lex.LexFromRawLexer(Tok);
6065*67e74705SXin Li if (Tok.is(tok::eof))
6066*67e74705SXin Li break;
6067*67e74705SXin Li
6068*67e74705SXin Li // Initialize the CXToken.
6069*67e74705SXin Li CXToken CXTok;
6070*67e74705SXin Li
6071*67e74705SXin Li // - Common fields
6072*67e74705SXin Li CXTok.int_data[1] = Tok.getLocation().getRawEncoding();
6073*67e74705SXin Li CXTok.int_data[2] = Tok.getLength();
6074*67e74705SXin Li CXTok.int_data[3] = 0;
6075*67e74705SXin Li
6076*67e74705SXin Li // - Kind-specific fields
6077*67e74705SXin Li if (Tok.isLiteral()) {
6078*67e74705SXin Li CXTok.int_data[0] = CXToken_Literal;
6079*67e74705SXin Li CXTok.ptr_data = const_cast<char *>(Tok.getLiteralData());
6080*67e74705SXin Li } else if (Tok.is(tok::raw_identifier)) {
6081*67e74705SXin Li // Lookup the identifier to determine whether we have a keyword.
6082*67e74705SXin Li IdentifierInfo *II
6083*67e74705SXin Li = CXXUnit->getPreprocessor().LookUpIdentifierInfo(Tok);
6084*67e74705SXin Li
6085*67e74705SXin Li if ((II->getObjCKeywordID() != tok::objc_not_keyword) && previousWasAt) {
6086*67e74705SXin Li CXTok.int_data[0] = CXToken_Keyword;
6087*67e74705SXin Li }
6088*67e74705SXin Li else {
6089*67e74705SXin Li CXTok.int_data[0] = Tok.is(tok::identifier)
6090*67e74705SXin Li ? CXToken_Identifier
6091*67e74705SXin Li : CXToken_Keyword;
6092*67e74705SXin Li }
6093*67e74705SXin Li CXTok.ptr_data = II;
6094*67e74705SXin Li } else if (Tok.is(tok::comment)) {
6095*67e74705SXin Li CXTok.int_data[0] = CXToken_Comment;
6096*67e74705SXin Li CXTok.ptr_data = nullptr;
6097*67e74705SXin Li } else {
6098*67e74705SXin Li CXTok.int_data[0] = CXToken_Punctuation;
6099*67e74705SXin Li CXTok.ptr_data = nullptr;
6100*67e74705SXin Li }
6101*67e74705SXin Li CXTokens.push_back(CXTok);
6102*67e74705SXin Li previousWasAt = Tok.is(tok::at);
6103*67e74705SXin Li } while (Lex.getBufferLocation() <= EffectiveBufferEnd);
6104*67e74705SXin Li }
6105*67e74705SXin Li
clang_tokenize(CXTranslationUnit TU,CXSourceRange Range,CXToken ** Tokens,unsigned * NumTokens)6106*67e74705SXin Li void clang_tokenize(CXTranslationUnit TU, CXSourceRange Range,
6107*67e74705SXin Li CXToken **Tokens, unsigned *NumTokens) {
6108*67e74705SXin Li LOG_FUNC_SECTION {
6109*67e74705SXin Li *Log << TU << ' ' << Range;
6110*67e74705SXin Li }
6111*67e74705SXin Li
6112*67e74705SXin Li if (Tokens)
6113*67e74705SXin Li *Tokens = nullptr;
6114*67e74705SXin Li if (NumTokens)
6115*67e74705SXin Li *NumTokens = 0;
6116*67e74705SXin Li
6117*67e74705SXin Li if (isNotUsableTU(TU)) {
6118*67e74705SXin Li LOG_BAD_TU(TU);
6119*67e74705SXin Li return;
6120*67e74705SXin Li }
6121*67e74705SXin Li
6122*67e74705SXin Li ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
6123*67e74705SXin Li if (!CXXUnit || !Tokens || !NumTokens)
6124*67e74705SXin Li return;
6125*67e74705SXin Li
6126*67e74705SXin Li ASTUnit::ConcurrencyCheck Check(*CXXUnit);
6127*67e74705SXin Li
6128*67e74705SXin Li SourceRange R = cxloc::translateCXSourceRange(Range);
6129*67e74705SXin Li if (R.isInvalid())
6130*67e74705SXin Li return;
6131*67e74705SXin Li
6132*67e74705SXin Li SmallVector<CXToken, 32> CXTokens;
6133*67e74705SXin Li getTokens(CXXUnit, R, CXTokens);
6134*67e74705SXin Li
6135*67e74705SXin Li if (CXTokens.empty())
6136*67e74705SXin Li return;
6137*67e74705SXin Li
6138*67e74705SXin Li *Tokens = (CXToken *)malloc(sizeof(CXToken) * CXTokens.size());
6139*67e74705SXin Li memmove(*Tokens, CXTokens.data(), sizeof(CXToken) * CXTokens.size());
6140*67e74705SXin Li *NumTokens = CXTokens.size();
6141*67e74705SXin Li }
6142*67e74705SXin Li
clang_disposeTokens(CXTranslationUnit TU,CXToken * Tokens,unsigned NumTokens)6143*67e74705SXin Li void clang_disposeTokens(CXTranslationUnit TU,
6144*67e74705SXin Li CXToken *Tokens, unsigned NumTokens) {
6145*67e74705SXin Li free(Tokens);
6146*67e74705SXin Li }
6147*67e74705SXin Li
6148*67e74705SXin Li } // end: extern "C"
6149*67e74705SXin Li
6150*67e74705SXin Li //===----------------------------------------------------------------------===//
6151*67e74705SXin Li // Token annotation APIs.
6152*67e74705SXin Li //===----------------------------------------------------------------------===//
6153*67e74705SXin Li
6154*67e74705SXin Li static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
6155*67e74705SXin Li CXCursor parent,
6156*67e74705SXin Li CXClientData client_data);
6157*67e74705SXin Li static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
6158*67e74705SXin Li CXClientData client_data);
6159*67e74705SXin Li
6160*67e74705SXin Li namespace {
6161*67e74705SXin Li class AnnotateTokensWorker {
6162*67e74705SXin Li CXToken *Tokens;
6163*67e74705SXin Li CXCursor *Cursors;
6164*67e74705SXin Li unsigned NumTokens;
6165*67e74705SXin Li unsigned TokIdx;
6166*67e74705SXin Li unsigned PreprocessingTokIdx;
6167*67e74705SXin Li CursorVisitor AnnotateVis;
6168*67e74705SXin Li SourceManager &SrcMgr;
6169*67e74705SXin Li bool HasContextSensitiveKeywords;
6170*67e74705SXin Li
6171*67e74705SXin Li struct PostChildrenInfo {
6172*67e74705SXin Li CXCursor Cursor;
6173*67e74705SXin Li SourceRange CursorRange;
6174*67e74705SXin Li unsigned BeforeReachingCursorIdx;
6175*67e74705SXin Li unsigned BeforeChildrenTokenIdx;
6176*67e74705SXin Li };
6177*67e74705SXin Li SmallVector<PostChildrenInfo, 8> PostChildrenInfos;
6178*67e74705SXin Li
getTok(unsigned Idx)6179*67e74705SXin Li CXToken &getTok(unsigned Idx) {
6180*67e74705SXin Li assert(Idx < NumTokens);
6181*67e74705SXin Li return Tokens[Idx];
6182*67e74705SXin Li }
getTok(unsigned Idx) const6183*67e74705SXin Li const CXToken &getTok(unsigned Idx) const {
6184*67e74705SXin Li assert(Idx < NumTokens);
6185*67e74705SXin Li return Tokens[Idx];
6186*67e74705SXin Li }
MoreTokens() const6187*67e74705SXin Li bool MoreTokens() const { return TokIdx < NumTokens; }
NextToken() const6188*67e74705SXin Li unsigned NextToken() const { return TokIdx; }
AdvanceToken()6189*67e74705SXin Li void AdvanceToken() { ++TokIdx; }
GetTokenLoc(unsigned tokI)6190*67e74705SXin Li SourceLocation GetTokenLoc(unsigned tokI) {
6191*67e74705SXin Li return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[1]);
6192*67e74705SXin Li }
isFunctionMacroToken(unsigned tokI) const6193*67e74705SXin Li bool isFunctionMacroToken(unsigned tokI) const {
6194*67e74705SXin Li return getTok(tokI).int_data[3] != 0;
6195*67e74705SXin Li }
getFunctionMacroTokenLoc(unsigned tokI) const6196*67e74705SXin Li SourceLocation getFunctionMacroTokenLoc(unsigned tokI) const {
6197*67e74705SXin Li return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[3]);
6198*67e74705SXin Li }
6199*67e74705SXin Li
6200*67e74705SXin Li void annotateAndAdvanceTokens(CXCursor, RangeComparisonResult, SourceRange);
6201*67e74705SXin Li bool annotateAndAdvanceFunctionMacroTokens(CXCursor, RangeComparisonResult,
6202*67e74705SXin Li SourceRange);
6203*67e74705SXin Li
6204*67e74705SXin Li public:
AnnotateTokensWorker(CXToken * tokens,CXCursor * cursors,unsigned numTokens,CXTranslationUnit TU,SourceRange RegionOfInterest)6205*67e74705SXin Li AnnotateTokensWorker(CXToken *tokens, CXCursor *cursors, unsigned numTokens,
6206*67e74705SXin Li CXTranslationUnit TU, SourceRange RegionOfInterest)
6207*67e74705SXin Li : Tokens(tokens), Cursors(cursors),
6208*67e74705SXin Li NumTokens(numTokens), TokIdx(0), PreprocessingTokIdx(0),
6209*67e74705SXin Li AnnotateVis(TU,
6210*67e74705SXin Li AnnotateTokensVisitor, this,
6211*67e74705SXin Li /*VisitPreprocessorLast=*/true,
6212*67e74705SXin Li /*VisitIncludedEntities=*/false,
6213*67e74705SXin Li RegionOfInterest,
6214*67e74705SXin Li /*VisitDeclsOnly=*/false,
6215*67e74705SXin Li AnnotateTokensPostChildrenVisitor),
6216*67e74705SXin Li SrcMgr(cxtu::getASTUnit(TU)->getSourceManager()),
6217*67e74705SXin Li HasContextSensitiveKeywords(false) { }
6218*67e74705SXin Li
VisitChildren(CXCursor C)6219*67e74705SXin Li void VisitChildren(CXCursor C) { AnnotateVis.VisitChildren(C); }
6220*67e74705SXin Li enum CXChildVisitResult Visit(CXCursor cursor, CXCursor parent);
6221*67e74705SXin Li bool postVisitChildren(CXCursor cursor);
6222*67e74705SXin Li void AnnotateTokens();
6223*67e74705SXin Li
6224*67e74705SXin Li /// \brief Determine whether the annotator saw any cursors that have
6225*67e74705SXin Li /// context-sensitive keywords.
hasContextSensitiveKeywords() const6226*67e74705SXin Li bool hasContextSensitiveKeywords() const {
6227*67e74705SXin Li return HasContextSensitiveKeywords;
6228*67e74705SXin Li }
6229*67e74705SXin Li
~AnnotateTokensWorker()6230*67e74705SXin Li ~AnnotateTokensWorker() {
6231*67e74705SXin Li assert(PostChildrenInfos.empty());
6232*67e74705SXin Li }
6233*67e74705SXin Li };
6234*67e74705SXin Li }
6235*67e74705SXin Li
AnnotateTokens()6236*67e74705SXin Li void AnnotateTokensWorker::AnnotateTokens() {
6237*67e74705SXin Li // Walk the AST within the region of interest, annotating tokens
6238*67e74705SXin Li // along the way.
6239*67e74705SXin Li AnnotateVis.visitFileRegion();
6240*67e74705SXin Li }
6241*67e74705SXin Li
updateCursorAnnotation(CXCursor & Cursor,const CXCursor & updateC)6242*67e74705SXin Li static inline void updateCursorAnnotation(CXCursor &Cursor,
6243*67e74705SXin Li const CXCursor &updateC) {
6244*67e74705SXin Li if (clang_isInvalid(updateC.kind) || !clang_isInvalid(Cursor.kind))
6245*67e74705SXin Li return;
6246*67e74705SXin Li Cursor = updateC;
6247*67e74705SXin Li }
6248*67e74705SXin Li
6249*67e74705SXin Li /// \brief It annotates and advances tokens with a cursor until the comparison
6250*67e74705SXin Li //// between the cursor location and the source range is the same as
6251*67e74705SXin Li /// \arg compResult.
6252*67e74705SXin Li ///
6253*67e74705SXin Li /// Pass RangeBefore to annotate tokens with a cursor until a range is reached.
6254*67e74705SXin Li /// Pass RangeOverlap to annotate tokens inside a range.
annotateAndAdvanceTokens(CXCursor updateC,RangeComparisonResult compResult,SourceRange range)6255*67e74705SXin Li void AnnotateTokensWorker::annotateAndAdvanceTokens(CXCursor updateC,
6256*67e74705SXin Li RangeComparisonResult compResult,
6257*67e74705SXin Li SourceRange range) {
6258*67e74705SXin Li while (MoreTokens()) {
6259*67e74705SXin Li const unsigned I = NextToken();
6260*67e74705SXin Li if (isFunctionMacroToken(I))
6261*67e74705SXin Li if (!annotateAndAdvanceFunctionMacroTokens(updateC, compResult, range))
6262*67e74705SXin Li return;
6263*67e74705SXin Li
6264*67e74705SXin Li SourceLocation TokLoc = GetTokenLoc(I);
6265*67e74705SXin Li if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
6266*67e74705SXin Li updateCursorAnnotation(Cursors[I], updateC);
6267*67e74705SXin Li AdvanceToken();
6268*67e74705SXin Li continue;
6269*67e74705SXin Li }
6270*67e74705SXin Li break;
6271*67e74705SXin Li }
6272*67e74705SXin Li }
6273*67e74705SXin Li
6274*67e74705SXin Li /// \brief Special annotation handling for macro argument tokens.
6275*67e74705SXin Li /// \returns true if it advanced beyond all macro tokens, false otherwise.
annotateAndAdvanceFunctionMacroTokens(CXCursor updateC,RangeComparisonResult compResult,SourceRange range)6276*67e74705SXin Li bool AnnotateTokensWorker::annotateAndAdvanceFunctionMacroTokens(
6277*67e74705SXin Li CXCursor updateC,
6278*67e74705SXin Li RangeComparisonResult compResult,
6279*67e74705SXin Li SourceRange range) {
6280*67e74705SXin Li assert(MoreTokens());
6281*67e74705SXin Li assert(isFunctionMacroToken(NextToken()) &&
6282*67e74705SXin Li "Should be called only for macro arg tokens");
6283*67e74705SXin Li
6284*67e74705SXin Li // This works differently than annotateAndAdvanceTokens; because expanded
6285*67e74705SXin Li // macro arguments can have arbitrary translation-unit source order, we do not
6286*67e74705SXin Li // advance the token index one by one until a token fails the range test.
6287*67e74705SXin Li // We only advance once past all of the macro arg tokens if all of them
6288*67e74705SXin Li // pass the range test. If one of them fails we keep the token index pointing
6289*67e74705SXin Li // at the start of the macro arg tokens so that the failing token will be
6290*67e74705SXin Li // annotated by a subsequent annotation try.
6291*67e74705SXin Li
6292*67e74705SXin Li bool atLeastOneCompFail = false;
6293*67e74705SXin Li
6294*67e74705SXin Li unsigned I = NextToken();
6295*67e74705SXin Li for (; I < NumTokens && isFunctionMacroToken(I); ++I) {
6296*67e74705SXin Li SourceLocation TokLoc = getFunctionMacroTokenLoc(I);
6297*67e74705SXin Li if (TokLoc.isFileID())
6298*67e74705SXin Li continue; // not macro arg token, it's parens or comma.
6299*67e74705SXin Li if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
6300*67e74705SXin Li if (clang_isInvalid(clang_getCursorKind(Cursors[I])))
6301*67e74705SXin Li Cursors[I] = updateC;
6302*67e74705SXin Li } else
6303*67e74705SXin Li atLeastOneCompFail = true;
6304*67e74705SXin Li }
6305*67e74705SXin Li
6306*67e74705SXin Li if (atLeastOneCompFail)
6307*67e74705SXin Li return false;
6308*67e74705SXin Li
6309*67e74705SXin Li TokIdx = I; // All of the tokens were handled, advance beyond all of them.
6310*67e74705SXin Li return true;
6311*67e74705SXin Li }
6312*67e74705SXin Li
6313*67e74705SXin Li enum CXChildVisitResult
Visit(CXCursor cursor,CXCursor parent)6314*67e74705SXin Li AnnotateTokensWorker::Visit(CXCursor cursor, CXCursor parent) {
6315*67e74705SXin Li SourceRange cursorRange = getRawCursorExtent(cursor);
6316*67e74705SXin Li if (cursorRange.isInvalid())
6317*67e74705SXin Li return CXChildVisit_Recurse;
6318*67e74705SXin Li
6319*67e74705SXin Li if (!HasContextSensitiveKeywords) {
6320*67e74705SXin Li // Objective-C properties can have context-sensitive keywords.
6321*67e74705SXin Li if (cursor.kind == CXCursor_ObjCPropertyDecl) {
6322*67e74705SXin Li if (const ObjCPropertyDecl *Property
6323*67e74705SXin Li = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(cursor)))
6324*67e74705SXin Li HasContextSensitiveKeywords = Property->getPropertyAttributesAsWritten() != 0;
6325*67e74705SXin Li }
6326*67e74705SXin Li // Objective-C methods can have context-sensitive keywords.
6327*67e74705SXin Li else if (cursor.kind == CXCursor_ObjCInstanceMethodDecl ||
6328*67e74705SXin Li cursor.kind == CXCursor_ObjCClassMethodDecl) {
6329*67e74705SXin Li if (const ObjCMethodDecl *Method
6330*67e74705SXin Li = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
6331*67e74705SXin Li if (Method->getObjCDeclQualifier())
6332*67e74705SXin Li HasContextSensitiveKeywords = true;
6333*67e74705SXin Li else {
6334*67e74705SXin Li for (const auto *P : Method->parameters()) {
6335*67e74705SXin Li if (P->getObjCDeclQualifier()) {
6336*67e74705SXin Li HasContextSensitiveKeywords = true;
6337*67e74705SXin Li break;
6338*67e74705SXin Li }
6339*67e74705SXin Li }
6340*67e74705SXin Li }
6341*67e74705SXin Li }
6342*67e74705SXin Li }
6343*67e74705SXin Li // C++ methods can have context-sensitive keywords.
6344*67e74705SXin Li else if (cursor.kind == CXCursor_CXXMethod) {
6345*67e74705SXin Li if (const CXXMethodDecl *Method
6346*67e74705SXin Li = dyn_cast_or_null<CXXMethodDecl>(getCursorDecl(cursor))) {
6347*67e74705SXin Li if (Method->hasAttr<FinalAttr>() || Method->hasAttr<OverrideAttr>())
6348*67e74705SXin Li HasContextSensitiveKeywords = true;
6349*67e74705SXin Li }
6350*67e74705SXin Li }
6351*67e74705SXin Li // C++ classes can have context-sensitive keywords.
6352*67e74705SXin Li else if (cursor.kind == CXCursor_StructDecl ||
6353*67e74705SXin Li cursor.kind == CXCursor_ClassDecl ||
6354*67e74705SXin Li cursor.kind == CXCursor_ClassTemplate ||
6355*67e74705SXin Li cursor.kind == CXCursor_ClassTemplatePartialSpecialization) {
6356*67e74705SXin Li if (const Decl *D = getCursorDecl(cursor))
6357*67e74705SXin Li if (D->hasAttr<FinalAttr>())
6358*67e74705SXin Li HasContextSensitiveKeywords = true;
6359*67e74705SXin Li }
6360*67e74705SXin Li }
6361*67e74705SXin Li
6362*67e74705SXin Li // Don't override a property annotation with its getter/setter method.
6363*67e74705SXin Li if (cursor.kind == CXCursor_ObjCInstanceMethodDecl &&
6364*67e74705SXin Li parent.kind == CXCursor_ObjCPropertyDecl)
6365*67e74705SXin Li return CXChildVisit_Continue;
6366*67e74705SXin Li
6367*67e74705SXin Li if (clang_isPreprocessing(cursor.kind)) {
6368*67e74705SXin Li // Items in the preprocessing record are kept separate from items in
6369*67e74705SXin Li // declarations, so we keep a separate token index.
6370*67e74705SXin Li unsigned SavedTokIdx = TokIdx;
6371*67e74705SXin Li TokIdx = PreprocessingTokIdx;
6372*67e74705SXin Li
6373*67e74705SXin Li // Skip tokens up until we catch up to the beginning of the preprocessing
6374*67e74705SXin Li // entry.
6375*67e74705SXin Li while (MoreTokens()) {
6376*67e74705SXin Li const unsigned I = NextToken();
6377*67e74705SXin Li SourceLocation TokLoc = GetTokenLoc(I);
6378*67e74705SXin Li switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
6379*67e74705SXin Li case RangeBefore:
6380*67e74705SXin Li AdvanceToken();
6381*67e74705SXin Li continue;
6382*67e74705SXin Li case RangeAfter:
6383*67e74705SXin Li case RangeOverlap:
6384*67e74705SXin Li break;
6385*67e74705SXin Li }
6386*67e74705SXin Li break;
6387*67e74705SXin Li }
6388*67e74705SXin Li
6389*67e74705SXin Li // Look at all of the tokens within this range.
6390*67e74705SXin Li while (MoreTokens()) {
6391*67e74705SXin Li const unsigned I = NextToken();
6392*67e74705SXin Li SourceLocation TokLoc = GetTokenLoc(I);
6393*67e74705SXin Li switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
6394*67e74705SXin Li case RangeBefore:
6395*67e74705SXin Li llvm_unreachable("Infeasible");
6396*67e74705SXin Li case RangeAfter:
6397*67e74705SXin Li break;
6398*67e74705SXin Li case RangeOverlap:
6399*67e74705SXin Li // For macro expansions, just note where the beginning of the macro
6400*67e74705SXin Li // expansion occurs.
6401*67e74705SXin Li if (cursor.kind == CXCursor_MacroExpansion) {
6402*67e74705SXin Li if (TokLoc == cursorRange.getBegin())
6403*67e74705SXin Li Cursors[I] = cursor;
6404*67e74705SXin Li AdvanceToken();
6405*67e74705SXin Li break;
6406*67e74705SXin Li }
6407*67e74705SXin Li // We may have already annotated macro names inside macro definitions.
6408*67e74705SXin Li if (Cursors[I].kind != CXCursor_MacroExpansion)
6409*67e74705SXin Li Cursors[I] = cursor;
6410*67e74705SXin Li AdvanceToken();
6411*67e74705SXin Li continue;
6412*67e74705SXin Li }
6413*67e74705SXin Li break;
6414*67e74705SXin Li }
6415*67e74705SXin Li
6416*67e74705SXin Li // Save the preprocessing token index; restore the non-preprocessing
6417*67e74705SXin Li // token index.
6418*67e74705SXin Li PreprocessingTokIdx = TokIdx;
6419*67e74705SXin Li TokIdx = SavedTokIdx;
6420*67e74705SXin Li return CXChildVisit_Recurse;
6421*67e74705SXin Li }
6422*67e74705SXin Li
6423*67e74705SXin Li if (cursorRange.isInvalid())
6424*67e74705SXin Li return CXChildVisit_Continue;
6425*67e74705SXin Li
6426*67e74705SXin Li unsigned BeforeReachingCursorIdx = NextToken();
6427*67e74705SXin Li const enum CXCursorKind cursorK = clang_getCursorKind(cursor);
6428*67e74705SXin Li const enum CXCursorKind K = clang_getCursorKind(parent);
6429*67e74705SXin Li const CXCursor updateC =
6430*67e74705SXin Li (clang_isInvalid(K) || K == CXCursor_TranslationUnit ||
6431*67e74705SXin Li // Attributes are annotated out-of-order, skip tokens until we reach it.
6432*67e74705SXin Li clang_isAttribute(cursor.kind))
6433*67e74705SXin Li ? clang_getNullCursor() : parent;
6434*67e74705SXin Li
6435*67e74705SXin Li annotateAndAdvanceTokens(updateC, RangeBefore, cursorRange);
6436*67e74705SXin Li
6437*67e74705SXin Li // Avoid having the cursor of an expression "overwrite" the annotation of the
6438*67e74705SXin Li // variable declaration that it belongs to.
6439*67e74705SXin Li // This can happen for C++ constructor expressions whose range generally
6440*67e74705SXin Li // include the variable declaration, e.g.:
6441*67e74705SXin Li // MyCXXClass foo; // Make sure we don't annotate 'foo' as a CallExpr cursor.
6442*67e74705SXin Li if (clang_isExpression(cursorK) && MoreTokens()) {
6443*67e74705SXin Li const Expr *E = getCursorExpr(cursor);
6444*67e74705SXin Li if (const Decl *D = getCursorParentDecl(cursor)) {
6445*67e74705SXin Li const unsigned I = NextToken();
6446*67e74705SXin Li if (E->getLocStart().isValid() && D->getLocation().isValid() &&
6447*67e74705SXin Li E->getLocStart() == D->getLocation() &&
6448*67e74705SXin Li E->getLocStart() == GetTokenLoc(I)) {
6449*67e74705SXin Li updateCursorAnnotation(Cursors[I], updateC);
6450*67e74705SXin Li AdvanceToken();
6451*67e74705SXin Li }
6452*67e74705SXin Li }
6453*67e74705SXin Li }
6454*67e74705SXin Li
6455*67e74705SXin Li // Before recursing into the children keep some state that we are going
6456*67e74705SXin Li // to use in the AnnotateTokensWorker::postVisitChildren callback to do some
6457*67e74705SXin Li // extra work after the child nodes are visited.
6458*67e74705SXin Li // Note that we don't call VisitChildren here to avoid traversing statements
6459*67e74705SXin Li // code-recursively which can blow the stack.
6460*67e74705SXin Li
6461*67e74705SXin Li PostChildrenInfo Info;
6462*67e74705SXin Li Info.Cursor = cursor;
6463*67e74705SXin Li Info.CursorRange = cursorRange;
6464*67e74705SXin Li Info.BeforeReachingCursorIdx = BeforeReachingCursorIdx;
6465*67e74705SXin Li Info.BeforeChildrenTokenIdx = NextToken();
6466*67e74705SXin Li PostChildrenInfos.push_back(Info);
6467*67e74705SXin Li
6468*67e74705SXin Li return CXChildVisit_Recurse;
6469*67e74705SXin Li }
6470*67e74705SXin Li
postVisitChildren(CXCursor cursor)6471*67e74705SXin Li bool AnnotateTokensWorker::postVisitChildren(CXCursor cursor) {
6472*67e74705SXin Li if (PostChildrenInfos.empty())
6473*67e74705SXin Li return false;
6474*67e74705SXin Li const PostChildrenInfo &Info = PostChildrenInfos.back();
6475*67e74705SXin Li if (!clang_equalCursors(Info.Cursor, cursor))
6476*67e74705SXin Li return false;
6477*67e74705SXin Li
6478*67e74705SXin Li const unsigned BeforeChildren = Info.BeforeChildrenTokenIdx;
6479*67e74705SXin Li const unsigned AfterChildren = NextToken();
6480*67e74705SXin Li SourceRange cursorRange = Info.CursorRange;
6481*67e74705SXin Li
6482*67e74705SXin Li // Scan the tokens that are at the end of the cursor, but are not captured
6483*67e74705SXin Li // but the child cursors.
6484*67e74705SXin Li annotateAndAdvanceTokens(cursor, RangeOverlap, cursorRange);
6485*67e74705SXin Li
6486*67e74705SXin Li // Scan the tokens that are at the beginning of the cursor, but are not
6487*67e74705SXin Li // capture by the child cursors.
6488*67e74705SXin Li for (unsigned I = BeforeChildren; I != AfterChildren; ++I) {
6489*67e74705SXin Li if (!clang_isInvalid(clang_getCursorKind(Cursors[I])))
6490*67e74705SXin Li break;
6491*67e74705SXin Li
6492*67e74705SXin Li Cursors[I] = cursor;
6493*67e74705SXin Li }
6494*67e74705SXin Li
6495*67e74705SXin Li // Attributes are annotated out-of-order, rewind TokIdx to when we first
6496*67e74705SXin Li // encountered the attribute cursor.
6497*67e74705SXin Li if (clang_isAttribute(cursor.kind))
6498*67e74705SXin Li TokIdx = Info.BeforeReachingCursorIdx;
6499*67e74705SXin Li
6500*67e74705SXin Li PostChildrenInfos.pop_back();
6501*67e74705SXin Li return false;
6502*67e74705SXin Li }
6503*67e74705SXin Li
AnnotateTokensVisitor(CXCursor cursor,CXCursor parent,CXClientData client_data)6504*67e74705SXin Li static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
6505*67e74705SXin Li CXCursor parent,
6506*67e74705SXin Li CXClientData client_data) {
6507*67e74705SXin Li return static_cast<AnnotateTokensWorker*>(client_data)->Visit(cursor, parent);
6508*67e74705SXin Li }
6509*67e74705SXin Li
AnnotateTokensPostChildrenVisitor(CXCursor cursor,CXClientData client_data)6510*67e74705SXin Li static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
6511*67e74705SXin Li CXClientData client_data) {
6512*67e74705SXin Li return static_cast<AnnotateTokensWorker*>(client_data)->
6513*67e74705SXin Li postVisitChildren(cursor);
6514*67e74705SXin Li }
6515*67e74705SXin Li
6516*67e74705SXin Li namespace {
6517*67e74705SXin Li
6518*67e74705SXin Li /// \brief Uses the macro expansions in the preprocessing record to find
6519*67e74705SXin Li /// and mark tokens that are macro arguments. This info is used by the
6520*67e74705SXin Li /// AnnotateTokensWorker.
6521*67e74705SXin Li class MarkMacroArgTokensVisitor {
6522*67e74705SXin Li SourceManager &SM;
6523*67e74705SXin Li CXToken *Tokens;
6524*67e74705SXin Li unsigned NumTokens;
6525*67e74705SXin Li unsigned CurIdx;
6526*67e74705SXin Li
6527*67e74705SXin Li public:
MarkMacroArgTokensVisitor(SourceManager & SM,CXToken * tokens,unsigned numTokens)6528*67e74705SXin Li MarkMacroArgTokensVisitor(SourceManager &SM,
6529*67e74705SXin Li CXToken *tokens, unsigned numTokens)
6530*67e74705SXin Li : SM(SM), Tokens(tokens), NumTokens(numTokens), CurIdx(0) { }
6531*67e74705SXin Li
visit(CXCursor cursor,CXCursor parent)6532*67e74705SXin Li CXChildVisitResult visit(CXCursor cursor, CXCursor parent) {
6533*67e74705SXin Li if (cursor.kind != CXCursor_MacroExpansion)
6534*67e74705SXin Li return CXChildVisit_Continue;
6535*67e74705SXin Li
6536*67e74705SXin Li SourceRange macroRange = getCursorMacroExpansion(cursor).getSourceRange();
6537*67e74705SXin Li if (macroRange.getBegin() == macroRange.getEnd())
6538*67e74705SXin Li return CXChildVisit_Continue; // it's not a function macro.
6539*67e74705SXin Li
6540*67e74705SXin Li for (; CurIdx < NumTokens; ++CurIdx) {
6541*67e74705SXin Li if (!SM.isBeforeInTranslationUnit(getTokenLoc(CurIdx),
6542*67e74705SXin Li macroRange.getBegin()))
6543*67e74705SXin Li break;
6544*67e74705SXin Li }
6545*67e74705SXin Li
6546*67e74705SXin Li if (CurIdx == NumTokens)
6547*67e74705SXin Li return CXChildVisit_Break;
6548*67e74705SXin Li
6549*67e74705SXin Li for (; CurIdx < NumTokens; ++CurIdx) {
6550*67e74705SXin Li SourceLocation tokLoc = getTokenLoc(CurIdx);
6551*67e74705SXin Li if (!SM.isBeforeInTranslationUnit(tokLoc, macroRange.getEnd()))
6552*67e74705SXin Li break;
6553*67e74705SXin Li
6554*67e74705SXin Li setFunctionMacroTokenLoc(CurIdx, SM.getMacroArgExpandedLocation(tokLoc));
6555*67e74705SXin Li }
6556*67e74705SXin Li
6557*67e74705SXin Li if (CurIdx == NumTokens)
6558*67e74705SXin Li return CXChildVisit_Break;
6559*67e74705SXin Li
6560*67e74705SXin Li return CXChildVisit_Continue;
6561*67e74705SXin Li }
6562*67e74705SXin Li
6563*67e74705SXin Li private:
getTok(unsigned Idx)6564*67e74705SXin Li CXToken &getTok(unsigned Idx) {
6565*67e74705SXin Li assert(Idx < NumTokens);
6566*67e74705SXin Li return Tokens[Idx];
6567*67e74705SXin Li }
getTok(unsigned Idx) const6568*67e74705SXin Li const CXToken &getTok(unsigned Idx) const {
6569*67e74705SXin Li assert(Idx < NumTokens);
6570*67e74705SXin Li return Tokens[Idx];
6571*67e74705SXin Li }
6572*67e74705SXin Li
getTokenLoc(unsigned tokI)6573*67e74705SXin Li SourceLocation getTokenLoc(unsigned tokI) {
6574*67e74705SXin Li return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[1]);
6575*67e74705SXin Li }
6576*67e74705SXin Li
setFunctionMacroTokenLoc(unsigned tokI,SourceLocation loc)6577*67e74705SXin Li void setFunctionMacroTokenLoc(unsigned tokI, SourceLocation loc) {
6578*67e74705SXin Li // The third field is reserved and currently not used. Use it here
6579*67e74705SXin Li // to mark macro arg expanded tokens with their expanded locations.
6580*67e74705SXin Li getTok(tokI).int_data[3] = loc.getRawEncoding();
6581*67e74705SXin Li }
6582*67e74705SXin Li };
6583*67e74705SXin Li
6584*67e74705SXin Li } // end anonymous namespace
6585*67e74705SXin Li
6586*67e74705SXin Li static CXChildVisitResult
MarkMacroArgTokensVisitorDelegate(CXCursor cursor,CXCursor parent,CXClientData client_data)6587*67e74705SXin Li MarkMacroArgTokensVisitorDelegate(CXCursor cursor, CXCursor parent,
6588*67e74705SXin Li CXClientData client_data) {
6589*67e74705SXin Li return static_cast<MarkMacroArgTokensVisitor*>(client_data)->visit(cursor,
6590*67e74705SXin Li parent);
6591*67e74705SXin Li }
6592*67e74705SXin Li
6593*67e74705SXin Li /// \brief Used by \c annotatePreprocessorTokens.
6594*67e74705SXin Li /// \returns true if lexing was finished, false otherwise.
lexNext(Lexer & Lex,Token & Tok,unsigned & NextIdx,unsigned NumTokens)6595*67e74705SXin Li static bool lexNext(Lexer &Lex, Token &Tok,
6596*67e74705SXin Li unsigned &NextIdx, unsigned NumTokens) {
6597*67e74705SXin Li if (NextIdx >= NumTokens)
6598*67e74705SXin Li return true;
6599*67e74705SXin Li
6600*67e74705SXin Li ++NextIdx;
6601*67e74705SXin Li Lex.LexFromRawLexer(Tok);
6602*67e74705SXin Li return Tok.is(tok::eof);
6603*67e74705SXin Li }
6604*67e74705SXin Li
annotatePreprocessorTokens(CXTranslationUnit TU,SourceRange RegionOfInterest,CXCursor * Cursors,CXToken * Tokens,unsigned NumTokens)6605*67e74705SXin Li static void annotatePreprocessorTokens(CXTranslationUnit TU,
6606*67e74705SXin Li SourceRange RegionOfInterest,
6607*67e74705SXin Li CXCursor *Cursors,
6608*67e74705SXin Li CXToken *Tokens,
6609*67e74705SXin Li unsigned NumTokens) {
6610*67e74705SXin Li ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
6611*67e74705SXin Li
6612*67e74705SXin Li Preprocessor &PP = CXXUnit->getPreprocessor();
6613*67e74705SXin Li SourceManager &SourceMgr = CXXUnit->getSourceManager();
6614*67e74705SXin Li std::pair<FileID, unsigned> BeginLocInfo
6615*67e74705SXin Li = SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getBegin());
6616*67e74705SXin Li std::pair<FileID, unsigned> EndLocInfo
6617*67e74705SXin Li = SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getEnd());
6618*67e74705SXin Li
6619*67e74705SXin Li if (BeginLocInfo.first != EndLocInfo.first)
6620*67e74705SXin Li return;
6621*67e74705SXin Li
6622*67e74705SXin Li StringRef Buffer;
6623*67e74705SXin Li bool Invalid = false;
6624*67e74705SXin Li Buffer = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
6625*67e74705SXin Li if (Buffer.empty() || Invalid)
6626*67e74705SXin Li return;
6627*67e74705SXin Li
6628*67e74705SXin Li Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
6629*67e74705SXin Li CXXUnit->getASTContext().getLangOpts(),
6630*67e74705SXin Li Buffer.begin(), Buffer.data() + BeginLocInfo.second,
6631*67e74705SXin Li Buffer.end());
6632*67e74705SXin Li Lex.SetCommentRetentionState(true);
6633*67e74705SXin Li
6634*67e74705SXin Li unsigned NextIdx = 0;
6635*67e74705SXin Li // Lex tokens in raw mode until we hit the end of the range, to avoid
6636*67e74705SXin Li // entering #includes or expanding macros.
6637*67e74705SXin Li while (true) {
6638*67e74705SXin Li Token Tok;
6639*67e74705SXin Li if (lexNext(Lex, Tok, NextIdx, NumTokens))
6640*67e74705SXin Li break;
6641*67e74705SXin Li unsigned TokIdx = NextIdx-1;
6642*67e74705SXin Li assert(Tok.getLocation() ==
6643*67e74705SXin Li SourceLocation::getFromRawEncoding(Tokens[TokIdx].int_data[1]));
6644*67e74705SXin Li
6645*67e74705SXin Li reprocess:
6646*67e74705SXin Li if (Tok.is(tok::hash) && Tok.isAtStartOfLine()) {
6647*67e74705SXin Li // We have found a preprocessing directive. Annotate the tokens
6648*67e74705SXin Li // appropriately.
6649*67e74705SXin Li //
6650*67e74705SXin Li // FIXME: Some simple tests here could identify macro definitions and
6651*67e74705SXin Li // #undefs, to provide specific cursor kinds for those.
6652*67e74705SXin Li
6653*67e74705SXin Li SourceLocation BeginLoc = Tok.getLocation();
6654*67e74705SXin Li if (lexNext(Lex, Tok, NextIdx, NumTokens))
6655*67e74705SXin Li break;
6656*67e74705SXin Li
6657*67e74705SXin Li MacroInfo *MI = nullptr;
6658*67e74705SXin Li if (Tok.is(tok::raw_identifier) && Tok.getRawIdentifier() == "define") {
6659*67e74705SXin Li if (lexNext(Lex, Tok, NextIdx, NumTokens))
6660*67e74705SXin Li break;
6661*67e74705SXin Li
6662*67e74705SXin Li if (Tok.is(tok::raw_identifier)) {
6663*67e74705SXin Li IdentifierInfo &II =
6664*67e74705SXin Li PP.getIdentifierTable().get(Tok.getRawIdentifier());
6665*67e74705SXin Li SourceLocation MappedTokLoc =
6666*67e74705SXin Li CXXUnit->mapLocationToPreamble(Tok.getLocation());
6667*67e74705SXin Li MI = getMacroInfo(II, MappedTokLoc, TU);
6668*67e74705SXin Li }
6669*67e74705SXin Li }
6670*67e74705SXin Li
6671*67e74705SXin Li bool finished = false;
6672*67e74705SXin Li do {
6673*67e74705SXin Li if (lexNext(Lex, Tok, NextIdx, NumTokens)) {
6674*67e74705SXin Li finished = true;
6675*67e74705SXin Li break;
6676*67e74705SXin Li }
6677*67e74705SXin Li // If we are in a macro definition, check if the token was ever a
6678*67e74705SXin Li // macro name and annotate it if that's the case.
6679*67e74705SXin Li if (MI) {
6680*67e74705SXin Li SourceLocation SaveLoc = Tok.getLocation();
6681*67e74705SXin Li Tok.setLocation(CXXUnit->mapLocationToPreamble(SaveLoc));
6682*67e74705SXin Li MacroDefinitionRecord *MacroDef =
6683*67e74705SXin Li checkForMacroInMacroDefinition(MI, Tok, TU);
6684*67e74705SXin Li Tok.setLocation(SaveLoc);
6685*67e74705SXin Li if (MacroDef)
6686*67e74705SXin Li Cursors[NextIdx - 1] =
6687*67e74705SXin Li MakeMacroExpansionCursor(MacroDef, Tok.getLocation(), TU);
6688*67e74705SXin Li }
6689*67e74705SXin Li } while (!Tok.isAtStartOfLine());
6690*67e74705SXin Li
6691*67e74705SXin Li unsigned LastIdx = finished ? NextIdx-1 : NextIdx-2;
6692*67e74705SXin Li assert(TokIdx <= LastIdx);
6693*67e74705SXin Li SourceLocation EndLoc =
6694*67e74705SXin Li SourceLocation::getFromRawEncoding(Tokens[LastIdx].int_data[1]);
6695*67e74705SXin Li CXCursor Cursor =
6696*67e74705SXin Li MakePreprocessingDirectiveCursor(SourceRange(BeginLoc, EndLoc), TU);
6697*67e74705SXin Li
6698*67e74705SXin Li for (; TokIdx <= LastIdx; ++TokIdx)
6699*67e74705SXin Li updateCursorAnnotation(Cursors[TokIdx], Cursor);
6700*67e74705SXin Li
6701*67e74705SXin Li if (finished)
6702*67e74705SXin Li break;
6703*67e74705SXin Li goto reprocess;
6704*67e74705SXin Li }
6705*67e74705SXin Li }
6706*67e74705SXin Li }
6707*67e74705SXin Li
6708*67e74705SXin Li // This gets run a separate thread to avoid stack blowout.
clang_annotateTokensImpl(CXTranslationUnit TU,ASTUnit * CXXUnit,CXToken * Tokens,unsigned NumTokens,CXCursor * Cursors)6709*67e74705SXin Li static void clang_annotateTokensImpl(CXTranslationUnit TU, ASTUnit *CXXUnit,
6710*67e74705SXin Li CXToken *Tokens, unsigned NumTokens,
6711*67e74705SXin Li CXCursor *Cursors) {
6712*67e74705SXin Li CIndexer *CXXIdx = TU->CIdx;
6713*67e74705SXin Li if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
6714*67e74705SXin Li setThreadBackgroundPriority();
6715*67e74705SXin Li
6716*67e74705SXin Li // Determine the region of interest, which contains all of the tokens.
6717*67e74705SXin Li SourceRange RegionOfInterest;
6718*67e74705SXin Li RegionOfInterest.setBegin(
6719*67e74705SXin Li cxloc::translateSourceLocation(clang_getTokenLocation(TU, Tokens[0])));
6720*67e74705SXin Li RegionOfInterest.setEnd(
6721*67e74705SXin Li cxloc::translateSourceLocation(clang_getTokenLocation(TU,
6722*67e74705SXin Li Tokens[NumTokens-1])));
6723*67e74705SXin Li
6724*67e74705SXin Li // Relex the tokens within the source range to look for preprocessing
6725*67e74705SXin Li // directives.
6726*67e74705SXin Li annotatePreprocessorTokens(TU, RegionOfInterest, Cursors, Tokens, NumTokens);
6727*67e74705SXin Li
6728*67e74705SXin Li // If begin location points inside a macro argument, set it to the expansion
6729*67e74705SXin Li // location so we can have the full context when annotating semantically.
6730*67e74705SXin Li {
6731*67e74705SXin Li SourceManager &SM = CXXUnit->getSourceManager();
6732*67e74705SXin Li SourceLocation Loc =
6733*67e74705SXin Li SM.getMacroArgExpandedLocation(RegionOfInterest.getBegin());
6734*67e74705SXin Li if (Loc.isMacroID())
6735*67e74705SXin Li RegionOfInterest.setBegin(SM.getExpansionLoc(Loc));
6736*67e74705SXin Li }
6737*67e74705SXin Li
6738*67e74705SXin Li if (CXXUnit->getPreprocessor().getPreprocessingRecord()) {
6739*67e74705SXin Li // Search and mark tokens that are macro argument expansions.
6740*67e74705SXin Li MarkMacroArgTokensVisitor Visitor(CXXUnit->getSourceManager(),
6741*67e74705SXin Li Tokens, NumTokens);
6742*67e74705SXin Li CursorVisitor MacroArgMarker(TU,
6743*67e74705SXin Li MarkMacroArgTokensVisitorDelegate, &Visitor,
6744*67e74705SXin Li /*VisitPreprocessorLast=*/true,
6745*67e74705SXin Li /*VisitIncludedEntities=*/false,
6746*67e74705SXin Li RegionOfInterest);
6747*67e74705SXin Li MacroArgMarker.visitPreprocessedEntitiesInRegion();
6748*67e74705SXin Li }
6749*67e74705SXin Li
6750*67e74705SXin Li // Annotate all of the source locations in the region of interest that map to
6751*67e74705SXin Li // a specific cursor.
6752*67e74705SXin Li AnnotateTokensWorker W(Tokens, Cursors, NumTokens, TU, RegionOfInterest);
6753*67e74705SXin Li
6754*67e74705SXin Li // FIXME: We use a ridiculous stack size here because the data-recursion
6755*67e74705SXin Li // algorithm uses a large stack frame than the non-data recursive version,
6756*67e74705SXin Li // and AnnotationTokensWorker currently transforms the data-recursion
6757*67e74705SXin Li // algorithm back into a traditional recursion by explicitly calling
6758*67e74705SXin Li // VisitChildren(). We will need to remove this explicit recursive call.
6759*67e74705SXin Li W.AnnotateTokens();
6760*67e74705SXin Li
6761*67e74705SXin Li // If we ran into any entities that involve context-sensitive keywords,
6762*67e74705SXin Li // take another pass through the tokens to mark them as such.
6763*67e74705SXin Li if (W.hasContextSensitiveKeywords()) {
6764*67e74705SXin Li for (unsigned I = 0; I != NumTokens; ++I) {
6765*67e74705SXin Li if (clang_getTokenKind(Tokens[I]) != CXToken_Identifier)
6766*67e74705SXin Li continue;
6767*67e74705SXin Li
6768*67e74705SXin Li if (Cursors[I].kind == CXCursor_ObjCPropertyDecl) {
6769*67e74705SXin Li IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
6770*67e74705SXin Li if (const ObjCPropertyDecl *Property
6771*67e74705SXin Li = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(Cursors[I]))) {
6772*67e74705SXin Li if (Property->getPropertyAttributesAsWritten() != 0 &&
6773*67e74705SXin Li llvm::StringSwitch<bool>(II->getName())
6774*67e74705SXin Li .Case("readonly", true)
6775*67e74705SXin Li .Case("assign", true)
6776*67e74705SXin Li .Case("unsafe_unretained", true)
6777*67e74705SXin Li .Case("readwrite", true)
6778*67e74705SXin Li .Case("retain", true)
6779*67e74705SXin Li .Case("copy", true)
6780*67e74705SXin Li .Case("nonatomic", true)
6781*67e74705SXin Li .Case("atomic", true)
6782*67e74705SXin Li .Case("getter", true)
6783*67e74705SXin Li .Case("setter", true)
6784*67e74705SXin Li .Case("strong", true)
6785*67e74705SXin Li .Case("weak", true)
6786*67e74705SXin Li .Case("class", true)
6787*67e74705SXin Li .Default(false))
6788*67e74705SXin Li Tokens[I].int_data[0] = CXToken_Keyword;
6789*67e74705SXin Li }
6790*67e74705SXin Li continue;
6791*67e74705SXin Li }
6792*67e74705SXin Li
6793*67e74705SXin Li if (Cursors[I].kind == CXCursor_ObjCInstanceMethodDecl ||
6794*67e74705SXin Li Cursors[I].kind == CXCursor_ObjCClassMethodDecl) {
6795*67e74705SXin Li IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
6796*67e74705SXin Li if (llvm::StringSwitch<bool>(II->getName())
6797*67e74705SXin Li .Case("in", true)
6798*67e74705SXin Li .Case("out", true)
6799*67e74705SXin Li .Case("inout", true)
6800*67e74705SXin Li .Case("oneway", true)
6801*67e74705SXin Li .Case("bycopy", true)
6802*67e74705SXin Li .Case("byref", true)
6803*67e74705SXin Li .Default(false))
6804*67e74705SXin Li Tokens[I].int_data[0] = CXToken_Keyword;
6805*67e74705SXin Li continue;
6806*67e74705SXin Li }
6807*67e74705SXin Li
6808*67e74705SXin Li if (Cursors[I].kind == CXCursor_CXXFinalAttr ||
6809*67e74705SXin Li Cursors[I].kind == CXCursor_CXXOverrideAttr) {
6810*67e74705SXin Li Tokens[I].int_data[0] = CXToken_Keyword;
6811*67e74705SXin Li continue;
6812*67e74705SXin Li }
6813*67e74705SXin Li }
6814*67e74705SXin Li }
6815*67e74705SXin Li }
6816*67e74705SXin Li
6817*67e74705SXin Li extern "C" {
6818*67e74705SXin Li
clang_annotateTokens(CXTranslationUnit TU,CXToken * Tokens,unsigned NumTokens,CXCursor * Cursors)6819*67e74705SXin Li void clang_annotateTokens(CXTranslationUnit TU,
6820*67e74705SXin Li CXToken *Tokens, unsigned NumTokens,
6821*67e74705SXin Li CXCursor *Cursors) {
6822*67e74705SXin Li if (isNotUsableTU(TU)) {
6823*67e74705SXin Li LOG_BAD_TU(TU);
6824*67e74705SXin Li return;
6825*67e74705SXin Li }
6826*67e74705SXin Li if (NumTokens == 0 || !Tokens || !Cursors) {
6827*67e74705SXin Li LOG_FUNC_SECTION { *Log << "<null input>"; }
6828*67e74705SXin Li return;
6829*67e74705SXin Li }
6830*67e74705SXin Li
6831*67e74705SXin Li LOG_FUNC_SECTION {
6832*67e74705SXin Li *Log << TU << ' ';
6833*67e74705SXin Li CXSourceLocation bloc = clang_getTokenLocation(TU, Tokens[0]);
6834*67e74705SXin Li CXSourceLocation eloc = clang_getTokenLocation(TU, Tokens[NumTokens-1]);
6835*67e74705SXin Li *Log << clang_getRange(bloc, eloc);
6836*67e74705SXin Li }
6837*67e74705SXin Li
6838*67e74705SXin Li // Any token we don't specifically annotate will have a NULL cursor.
6839*67e74705SXin Li CXCursor C = clang_getNullCursor();
6840*67e74705SXin Li for (unsigned I = 0; I != NumTokens; ++I)
6841*67e74705SXin Li Cursors[I] = C;
6842*67e74705SXin Li
6843*67e74705SXin Li ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
6844*67e74705SXin Li if (!CXXUnit)
6845*67e74705SXin Li return;
6846*67e74705SXin Li
6847*67e74705SXin Li ASTUnit::ConcurrencyCheck Check(*CXXUnit);
6848*67e74705SXin Li
6849*67e74705SXin Li auto AnnotateTokensImpl = [=]() {
6850*67e74705SXin Li clang_annotateTokensImpl(TU, CXXUnit, Tokens, NumTokens, Cursors);
6851*67e74705SXin Li };
6852*67e74705SXin Li llvm::CrashRecoveryContext CRC;
6853*67e74705SXin Li if (!RunSafely(CRC, AnnotateTokensImpl, GetSafetyThreadStackSize() * 2)) {
6854*67e74705SXin Li fprintf(stderr, "libclang: crash detected while annotating tokens\n");
6855*67e74705SXin Li }
6856*67e74705SXin Li }
6857*67e74705SXin Li
6858*67e74705SXin Li } // end: extern "C"
6859*67e74705SXin Li
6860*67e74705SXin Li //===----------------------------------------------------------------------===//
6861*67e74705SXin Li // Operations for querying linkage of a cursor.
6862*67e74705SXin Li //===----------------------------------------------------------------------===//
6863*67e74705SXin Li
6864*67e74705SXin Li extern "C" {
clang_getCursorLinkage(CXCursor cursor)6865*67e74705SXin Li CXLinkageKind clang_getCursorLinkage(CXCursor cursor) {
6866*67e74705SXin Li if (!clang_isDeclaration(cursor.kind))
6867*67e74705SXin Li return CXLinkage_Invalid;
6868*67e74705SXin Li
6869*67e74705SXin Li const Decl *D = cxcursor::getCursorDecl(cursor);
6870*67e74705SXin Li if (const NamedDecl *ND = dyn_cast_or_null<NamedDecl>(D))
6871*67e74705SXin Li switch (ND->getLinkageInternal()) {
6872*67e74705SXin Li case NoLinkage:
6873*67e74705SXin Li case VisibleNoLinkage: return CXLinkage_NoLinkage;
6874*67e74705SXin Li case InternalLinkage: return CXLinkage_Internal;
6875*67e74705SXin Li case UniqueExternalLinkage: return CXLinkage_UniqueExternal;
6876*67e74705SXin Li case ExternalLinkage: return CXLinkage_External;
6877*67e74705SXin Li };
6878*67e74705SXin Li
6879*67e74705SXin Li return CXLinkage_Invalid;
6880*67e74705SXin Li }
6881*67e74705SXin Li } // end: extern "C"
6882*67e74705SXin Li
6883*67e74705SXin Li //===----------------------------------------------------------------------===//
6884*67e74705SXin Li // Operations for querying visibility of a cursor.
6885*67e74705SXin Li //===----------------------------------------------------------------------===//
6886*67e74705SXin Li
6887*67e74705SXin Li extern "C" {
clang_getCursorVisibility(CXCursor cursor)6888*67e74705SXin Li CXVisibilityKind clang_getCursorVisibility(CXCursor cursor) {
6889*67e74705SXin Li if (!clang_isDeclaration(cursor.kind))
6890*67e74705SXin Li return CXVisibility_Invalid;
6891*67e74705SXin Li
6892*67e74705SXin Li const Decl *D = cxcursor::getCursorDecl(cursor);
6893*67e74705SXin Li if (const NamedDecl *ND = dyn_cast_or_null<NamedDecl>(D))
6894*67e74705SXin Li switch (ND->getVisibility()) {
6895*67e74705SXin Li case HiddenVisibility: return CXVisibility_Hidden;
6896*67e74705SXin Li case ProtectedVisibility: return CXVisibility_Protected;
6897*67e74705SXin Li case DefaultVisibility: return CXVisibility_Default;
6898*67e74705SXin Li };
6899*67e74705SXin Li
6900*67e74705SXin Li return CXVisibility_Invalid;
6901*67e74705SXin Li }
6902*67e74705SXin Li } // end: extern "C"
6903*67e74705SXin Li
6904*67e74705SXin Li //===----------------------------------------------------------------------===//
6905*67e74705SXin Li // Operations for querying language of a cursor.
6906*67e74705SXin Li //===----------------------------------------------------------------------===//
6907*67e74705SXin Li
getDeclLanguage(const Decl * D)6908*67e74705SXin Li static CXLanguageKind getDeclLanguage(const Decl *D) {
6909*67e74705SXin Li if (!D)
6910*67e74705SXin Li return CXLanguage_C;
6911*67e74705SXin Li
6912*67e74705SXin Li switch (D->getKind()) {
6913*67e74705SXin Li default:
6914*67e74705SXin Li break;
6915*67e74705SXin Li case Decl::ImplicitParam:
6916*67e74705SXin Li case Decl::ObjCAtDefsField:
6917*67e74705SXin Li case Decl::ObjCCategory:
6918*67e74705SXin Li case Decl::ObjCCategoryImpl:
6919*67e74705SXin Li case Decl::ObjCCompatibleAlias:
6920*67e74705SXin Li case Decl::ObjCImplementation:
6921*67e74705SXin Li case Decl::ObjCInterface:
6922*67e74705SXin Li case Decl::ObjCIvar:
6923*67e74705SXin Li case Decl::ObjCMethod:
6924*67e74705SXin Li case Decl::ObjCProperty:
6925*67e74705SXin Li case Decl::ObjCPropertyImpl:
6926*67e74705SXin Li case Decl::ObjCProtocol:
6927*67e74705SXin Li case Decl::ObjCTypeParam:
6928*67e74705SXin Li return CXLanguage_ObjC;
6929*67e74705SXin Li case Decl::CXXConstructor:
6930*67e74705SXin Li case Decl::CXXConversion:
6931*67e74705SXin Li case Decl::CXXDestructor:
6932*67e74705SXin Li case Decl::CXXMethod:
6933*67e74705SXin Li case Decl::CXXRecord:
6934*67e74705SXin Li case Decl::ClassTemplate:
6935*67e74705SXin Li case Decl::ClassTemplatePartialSpecialization:
6936*67e74705SXin Li case Decl::ClassTemplateSpecialization:
6937*67e74705SXin Li case Decl::Friend:
6938*67e74705SXin Li case Decl::FriendTemplate:
6939*67e74705SXin Li case Decl::FunctionTemplate:
6940*67e74705SXin Li case Decl::LinkageSpec:
6941*67e74705SXin Li case Decl::Namespace:
6942*67e74705SXin Li case Decl::NamespaceAlias:
6943*67e74705SXin Li case Decl::NonTypeTemplateParm:
6944*67e74705SXin Li case Decl::StaticAssert:
6945*67e74705SXin Li case Decl::TemplateTemplateParm:
6946*67e74705SXin Li case Decl::TemplateTypeParm:
6947*67e74705SXin Li case Decl::UnresolvedUsingTypename:
6948*67e74705SXin Li case Decl::UnresolvedUsingValue:
6949*67e74705SXin Li case Decl::Using:
6950*67e74705SXin Li case Decl::UsingDirective:
6951*67e74705SXin Li case Decl::UsingShadow:
6952*67e74705SXin Li return CXLanguage_CPlusPlus;
6953*67e74705SXin Li }
6954*67e74705SXin Li
6955*67e74705SXin Li return CXLanguage_C;
6956*67e74705SXin Li }
6957*67e74705SXin Li
6958*67e74705SXin Li extern "C" {
6959*67e74705SXin Li
getCursorAvailabilityForDecl(const Decl * D)6960*67e74705SXin Li static CXAvailabilityKind getCursorAvailabilityForDecl(const Decl *D) {
6961*67e74705SXin Li if (isa<FunctionDecl>(D) && cast<FunctionDecl>(D)->isDeleted())
6962*67e74705SXin Li return CXAvailability_NotAvailable;
6963*67e74705SXin Li
6964*67e74705SXin Li switch (D->getAvailability()) {
6965*67e74705SXin Li case AR_Available:
6966*67e74705SXin Li case AR_NotYetIntroduced:
6967*67e74705SXin Li if (const EnumConstantDecl *EnumConst = dyn_cast<EnumConstantDecl>(D))
6968*67e74705SXin Li return getCursorAvailabilityForDecl(
6969*67e74705SXin Li cast<Decl>(EnumConst->getDeclContext()));
6970*67e74705SXin Li return CXAvailability_Available;
6971*67e74705SXin Li
6972*67e74705SXin Li case AR_Deprecated:
6973*67e74705SXin Li return CXAvailability_Deprecated;
6974*67e74705SXin Li
6975*67e74705SXin Li case AR_Unavailable:
6976*67e74705SXin Li return CXAvailability_NotAvailable;
6977*67e74705SXin Li }
6978*67e74705SXin Li
6979*67e74705SXin Li llvm_unreachable("Unknown availability kind!");
6980*67e74705SXin Li }
6981*67e74705SXin Li
clang_getCursorAvailability(CXCursor cursor)6982*67e74705SXin Li enum CXAvailabilityKind clang_getCursorAvailability(CXCursor cursor) {
6983*67e74705SXin Li if (clang_isDeclaration(cursor.kind))
6984*67e74705SXin Li if (const Decl *D = cxcursor::getCursorDecl(cursor))
6985*67e74705SXin Li return getCursorAvailabilityForDecl(D);
6986*67e74705SXin Li
6987*67e74705SXin Li return CXAvailability_Available;
6988*67e74705SXin Li }
6989*67e74705SXin Li
convertVersion(VersionTuple In)6990*67e74705SXin Li static CXVersion convertVersion(VersionTuple In) {
6991*67e74705SXin Li CXVersion Out = { -1, -1, -1 };
6992*67e74705SXin Li if (In.empty())
6993*67e74705SXin Li return Out;
6994*67e74705SXin Li
6995*67e74705SXin Li Out.Major = In.getMajor();
6996*67e74705SXin Li
6997*67e74705SXin Li Optional<unsigned> Minor = In.getMinor();
6998*67e74705SXin Li if (Minor.hasValue())
6999*67e74705SXin Li Out.Minor = *Minor;
7000*67e74705SXin Li else
7001*67e74705SXin Li return Out;
7002*67e74705SXin Li
7003*67e74705SXin Li Optional<unsigned> Subminor = In.getSubminor();
7004*67e74705SXin Li if (Subminor.hasValue())
7005*67e74705SXin Li Out.Subminor = *Subminor;
7006*67e74705SXin Li
7007*67e74705SXin Li return Out;
7008*67e74705SXin Li }
7009*67e74705SXin Li
getCursorPlatformAvailabilityForDecl(const Decl * D,int * always_deprecated,CXString * deprecated_message,int * always_unavailable,CXString * unavailable_message,CXPlatformAvailability * availability,int availability_size)7010*67e74705SXin Li static int getCursorPlatformAvailabilityForDecl(const Decl *D,
7011*67e74705SXin Li int *always_deprecated,
7012*67e74705SXin Li CXString *deprecated_message,
7013*67e74705SXin Li int *always_unavailable,
7014*67e74705SXin Li CXString *unavailable_message,
7015*67e74705SXin Li CXPlatformAvailability *availability,
7016*67e74705SXin Li int availability_size) {
7017*67e74705SXin Li bool HadAvailAttr = false;
7018*67e74705SXin Li int N = 0;
7019*67e74705SXin Li for (auto A : D->attrs()) {
7020*67e74705SXin Li if (DeprecatedAttr *Deprecated = dyn_cast<DeprecatedAttr>(A)) {
7021*67e74705SXin Li HadAvailAttr = true;
7022*67e74705SXin Li if (always_deprecated)
7023*67e74705SXin Li *always_deprecated = 1;
7024*67e74705SXin Li if (deprecated_message) {
7025*67e74705SXin Li clang_disposeString(*deprecated_message);
7026*67e74705SXin Li *deprecated_message = cxstring::createDup(Deprecated->getMessage());
7027*67e74705SXin Li }
7028*67e74705SXin Li continue;
7029*67e74705SXin Li }
7030*67e74705SXin Li
7031*67e74705SXin Li if (UnavailableAttr *Unavailable = dyn_cast<UnavailableAttr>(A)) {
7032*67e74705SXin Li HadAvailAttr = true;
7033*67e74705SXin Li if (always_unavailable)
7034*67e74705SXin Li *always_unavailable = 1;
7035*67e74705SXin Li if (unavailable_message) {
7036*67e74705SXin Li clang_disposeString(*unavailable_message);
7037*67e74705SXin Li *unavailable_message = cxstring::createDup(Unavailable->getMessage());
7038*67e74705SXin Li }
7039*67e74705SXin Li continue;
7040*67e74705SXin Li }
7041*67e74705SXin Li
7042*67e74705SXin Li if (AvailabilityAttr *Avail = dyn_cast<AvailabilityAttr>(A)) {
7043*67e74705SXin Li HadAvailAttr = true;
7044*67e74705SXin Li if (N < availability_size) {
7045*67e74705SXin Li availability[N].Platform
7046*67e74705SXin Li = cxstring::createDup(Avail->getPlatform()->getName());
7047*67e74705SXin Li availability[N].Introduced = convertVersion(Avail->getIntroduced());
7048*67e74705SXin Li availability[N].Deprecated = convertVersion(Avail->getDeprecated());
7049*67e74705SXin Li availability[N].Obsoleted = convertVersion(Avail->getObsoleted());
7050*67e74705SXin Li availability[N].Unavailable = Avail->getUnavailable();
7051*67e74705SXin Li availability[N].Message = cxstring::createDup(Avail->getMessage());
7052*67e74705SXin Li }
7053*67e74705SXin Li ++N;
7054*67e74705SXin Li }
7055*67e74705SXin Li }
7056*67e74705SXin Li
7057*67e74705SXin Li if (!HadAvailAttr)
7058*67e74705SXin Li if (const EnumConstantDecl *EnumConst = dyn_cast<EnumConstantDecl>(D))
7059*67e74705SXin Li return getCursorPlatformAvailabilityForDecl(
7060*67e74705SXin Li cast<Decl>(EnumConst->getDeclContext()),
7061*67e74705SXin Li always_deprecated,
7062*67e74705SXin Li deprecated_message,
7063*67e74705SXin Li always_unavailable,
7064*67e74705SXin Li unavailable_message,
7065*67e74705SXin Li availability,
7066*67e74705SXin Li availability_size);
7067*67e74705SXin Li
7068*67e74705SXin Li return N;
7069*67e74705SXin Li }
7070*67e74705SXin Li
clang_getCursorPlatformAvailability(CXCursor cursor,int * always_deprecated,CXString * deprecated_message,int * always_unavailable,CXString * unavailable_message,CXPlatformAvailability * availability,int availability_size)7071*67e74705SXin Li int clang_getCursorPlatformAvailability(CXCursor cursor,
7072*67e74705SXin Li int *always_deprecated,
7073*67e74705SXin Li CXString *deprecated_message,
7074*67e74705SXin Li int *always_unavailable,
7075*67e74705SXin Li CXString *unavailable_message,
7076*67e74705SXin Li CXPlatformAvailability *availability,
7077*67e74705SXin Li int availability_size) {
7078*67e74705SXin Li if (always_deprecated)
7079*67e74705SXin Li *always_deprecated = 0;
7080*67e74705SXin Li if (deprecated_message)
7081*67e74705SXin Li *deprecated_message = cxstring::createEmpty();
7082*67e74705SXin Li if (always_unavailable)
7083*67e74705SXin Li *always_unavailable = 0;
7084*67e74705SXin Li if (unavailable_message)
7085*67e74705SXin Li *unavailable_message = cxstring::createEmpty();
7086*67e74705SXin Li
7087*67e74705SXin Li if (!clang_isDeclaration(cursor.kind))
7088*67e74705SXin Li return 0;
7089*67e74705SXin Li
7090*67e74705SXin Li const Decl *D = cxcursor::getCursorDecl(cursor);
7091*67e74705SXin Li if (!D)
7092*67e74705SXin Li return 0;
7093*67e74705SXin Li
7094*67e74705SXin Li return getCursorPlatformAvailabilityForDecl(D, always_deprecated,
7095*67e74705SXin Li deprecated_message,
7096*67e74705SXin Li always_unavailable,
7097*67e74705SXin Li unavailable_message,
7098*67e74705SXin Li availability,
7099*67e74705SXin Li availability_size);
7100*67e74705SXin Li }
7101*67e74705SXin Li
clang_disposeCXPlatformAvailability(CXPlatformAvailability * availability)7102*67e74705SXin Li void clang_disposeCXPlatformAvailability(CXPlatformAvailability *availability) {
7103*67e74705SXin Li clang_disposeString(availability->Platform);
7104*67e74705SXin Li clang_disposeString(availability->Message);
7105*67e74705SXin Li }
7106*67e74705SXin Li
clang_getCursorLanguage(CXCursor cursor)7107*67e74705SXin Li CXLanguageKind clang_getCursorLanguage(CXCursor cursor) {
7108*67e74705SXin Li if (clang_isDeclaration(cursor.kind))
7109*67e74705SXin Li return getDeclLanguage(cxcursor::getCursorDecl(cursor));
7110*67e74705SXin Li
7111*67e74705SXin Li return CXLanguage_Invalid;
7112*67e74705SXin Li }
7113*67e74705SXin Li
7114*67e74705SXin Li /// \brief If the given cursor is the "templated" declaration
7115*67e74705SXin Li /// descibing a class or function template, return the class or
7116*67e74705SXin Li /// function template.
maybeGetTemplateCursor(const Decl * D)7117*67e74705SXin Li static const Decl *maybeGetTemplateCursor(const Decl *D) {
7118*67e74705SXin Li if (!D)
7119*67e74705SXin Li return nullptr;
7120*67e74705SXin Li
7121*67e74705SXin Li if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
7122*67e74705SXin Li if (FunctionTemplateDecl *FunTmpl = FD->getDescribedFunctionTemplate())
7123*67e74705SXin Li return FunTmpl;
7124*67e74705SXin Li
7125*67e74705SXin Li if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(D))
7126*67e74705SXin Li if (ClassTemplateDecl *ClassTmpl = RD->getDescribedClassTemplate())
7127*67e74705SXin Li return ClassTmpl;
7128*67e74705SXin Li
7129*67e74705SXin Li return D;
7130*67e74705SXin Li }
7131*67e74705SXin Li
7132*67e74705SXin Li
clang_Cursor_getStorageClass(CXCursor C)7133*67e74705SXin Li enum CX_StorageClass clang_Cursor_getStorageClass(CXCursor C) {
7134*67e74705SXin Li StorageClass sc = SC_None;
7135*67e74705SXin Li const Decl *D = getCursorDecl(C);
7136*67e74705SXin Li if (D) {
7137*67e74705SXin Li if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
7138*67e74705SXin Li sc = FD->getStorageClass();
7139*67e74705SXin Li } else if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
7140*67e74705SXin Li sc = VD->getStorageClass();
7141*67e74705SXin Li } else {
7142*67e74705SXin Li return CX_SC_Invalid;
7143*67e74705SXin Li }
7144*67e74705SXin Li } else {
7145*67e74705SXin Li return CX_SC_Invalid;
7146*67e74705SXin Li }
7147*67e74705SXin Li switch (sc) {
7148*67e74705SXin Li case SC_None:
7149*67e74705SXin Li return CX_SC_None;
7150*67e74705SXin Li case SC_Extern:
7151*67e74705SXin Li return CX_SC_Extern;
7152*67e74705SXin Li case SC_Static:
7153*67e74705SXin Li return CX_SC_Static;
7154*67e74705SXin Li case SC_PrivateExtern:
7155*67e74705SXin Li return CX_SC_PrivateExtern;
7156*67e74705SXin Li case SC_Auto:
7157*67e74705SXin Li return CX_SC_Auto;
7158*67e74705SXin Li case SC_Register:
7159*67e74705SXin Li return CX_SC_Register;
7160*67e74705SXin Li }
7161*67e74705SXin Li llvm_unreachable("Unhandled storage class!");
7162*67e74705SXin Li }
7163*67e74705SXin Li
clang_getCursorSemanticParent(CXCursor cursor)7164*67e74705SXin Li CXCursor clang_getCursorSemanticParent(CXCursor cursor) {
7165*67e74705SXin Li if (clang_isDeclaration(cursor.kind)) {
7166*67e74705SXin Li if (const Decl *D = getCursorDecl(cursor)) {
7167*67e74705SXin Li const DeclContext *DC = D->getDeclContext();
7168*67e74705SXin Li if (!DC)
7169*67e74705SXin Li return clang_getNullCursor();
7170*67e74705SXin Li
7171*67e74705SXin Li return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
7172*67e74705SXin Li getCursorTU(cursor));
7173*67e74705SXin Li }
7174*67e74705SXin Li }
7175*67e74705SXin Li
7176*67e74705SXin Li if (clang_isStatement(cursor.kind) || clang_isExpression(cursor.kind)) {
7177*67e74705SXin Li if (const Decl *D = getCursorDecl(cursor))
7178*67e74705SXin Li return MakeCXCursor(D, getCursorTU(cursor));
7179*67e74705SXin Li }
7180*67e74705SXin Li
7181*67e74705SXin Li return clang_getNullCursor();
7182*67e74705SXin Li }
7183*67e74705SXin Li
clang_getCursorLexicalParent(CXCursor cursor)7184*67e74705SXin Li CXCursor clang_getCursorLexicalParent(CXCursor cursor) {
7185*67e74705SXin Li if (clang_isDeclaration(cursor.kind)) {
7186*67e74705SXin Li if (const Decl *D = getCursorDecl(cursor)) {
7187*67e74705SXin Li const DeclContext *DC = D->getLexicalDeclContext();
7188*67e74705SXin Li if (!DC)
7189*67e74705SXin Li return clang_getNullCursor();
7190*67e74705SXin Li
7191*67e74705SXin Li return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
7192*67e74705SXin Li getCursorTU(cursor));
7193*67e74705SXin Li }
7194*67e74705SXin Li }
7195*67e74705SXin Li
7196*67e74705SXin Li // FIXME: Note that we can't easily compute the lexical context of a
7197*67e74705SXin Li // statement or expression, so we return nothing.
7198*67e74705SXin Li return clang_getNullCursor();
7199*67e74705SXin Li }
7200*67e74705SXin Li
clang_getIncludedFile(CXCursor cursor)7201*67e74705SXin Li CXFile clang_getIncludedFile(CXCursor cursor) {
7202*67e74705SXin Li if (cursor.kind != CXCursor_InclusionDirective)
7203*67e74705SXin Li return nullptr;
7204*67e74705SXin Li
7205*67e74705SXin Li const InclusionDirective *ID = getCursorInclusionDirective(cursor);
7206*67e74705SXin Li return const_cast<FileEntry *>(ID->getFile());
7207*67e74705SXin Li }
7208*67e74705SXin Li
clang_Cursor_getObjCPropertyAttributes(CXCursor C,unsigned reserved)7209*67e74705SXin Li unsigned clang_Cursor_getObjCPropertyAttributes(CXCursor C, unsigned reserved) {
7210*67e74705SXin Li if (C.kind != CXCursor_ObjCPropertyDecl)
7211*67e74705SXin Li return CXObjCPropertyAttr_noattr;
7212*67e74705SXin Li
7213*67e74705SXin Li unsigned Result = CXObjCPropertyAttr_noattr;
7214*67e74705SXin Li const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(getCursorDecl(C));
7215*67e74705SXin Li ObjCPropertyDecl::PropertyAttributeKind Attr =
7216*67e74705SXin Li PD->getPropertyAttributesAsWritten();
7217*67e74705SXin Li
7218*67e74705SXin Li #define SET_CXOBJCPROP_ATTR(A) \
7219*67e74705SXin Li if (Attr & ObjCPropertyDecl::OBJC_PR_##A) \
7220*67e74705SXin Li Result |= CXObjCPropertyAttr_##A
7221*67e74705SXin Li SET_CXOBJCPROP_ATTR(readonly);
7222*67e74705SXin Li SET_CXOBJCPROP_ATTR(getter);
7223*67e74705SXin Li SET_CXOBJCPROP_ATTR(assign);
7224*67e74705SXin Li SET_CXOBJCPROP_ATTR(readwrite);
7225*67e74705SXin Li SET_CXOBJCPROP_ATTR(retain);
7226*67e74705SXin Li SET_CXOBJCPROP_ATTR(copy);
7227*67e74705SXin Li SET_CXOBJCPROP_ATTR(nonatomic);
7228*67e74705SXin Li SET_CXOBJCPROP_ATTR(setter);
7229*67e74705SXin Li SET_CXOBJCPROP_ATTR(atomic);
7230*67e74705SXin Li SET_CXOBJCPROP_ATTR(weak);
7231*67e74705SXin Li SET_CXOBJCPROP_ATTR(strong);
7232*67e74705SXin Li SET_CXOBJCPROP_ATTR(unsafe_unretained);
7233*67e74705SXin Li SET_CXOBJCPROP_ATTR(class);
7234*67e74705SXin Li #undef SET_CXOBJCPROP_ATTR
7235*67e74705SXin Li
7236*67e74705SXin Li return Result;
7237*67e74705SXin Li }
7238*67e74705SXin Li
clang_Cursor_getObjCDeclQualifiers(CXCursor C)7239*67e74705SXin Li unsigned clang_Cursor_getObjCDeclQualifiers(CXCursor C) {
7240*67e74705SXin Li if (!clang_isDeclaration(C.kind))
7241*67e74705SXin Li return CXObjCDeclQualifier_None;
7242*67e74705SXin Li
7243*67e74705SXin Li Decl::ObjCDeclQualifier QT = Decl::OBJC_TQ_None;
7244*67e74705SXin Li const Decl *D = getCursorDecl(C);
7245*67e74705SXin Li if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
7246*67e74705SXin Li QT = MD->getObjCDeclQualifier();
7247*67e74705SXin Li else if (const ParmVarDecl *PD = dyn_cast<ParmVarDecl>(D))
7248*67e74705SXin Li QT = PD->getObjCDeclQualifier();
7249*67e74705SXin Li if (QT == Decl::OBJC_TQ_None)
7250*67e74705SXin Li return CXObjCDeclQualifier_None;
7251*67e74705SXin Li
7252*67e74705SXin Li unsigned Result = CXObjCDeclQualifier_None;
7253*67e74705SXin Li if (QT & Decl::OBJC_TQ_In) Result |= CXObjCDeclQualifier_In;
7254*67e74705SXin Li if (QT & Decl::OBJC_TQ_Inout) Result |= CXObjCDeclQualifier_Inout;
7255*67e74705SXin Li if (QT & Decl::OBJC_TQ_Out) Result |= CXObjCDeclQualifier_Out;
7256*67e74705SXin Li if (QT & Decl::OBJC_TQ_Bycopy) Result |= CXObjCDeclQualifier_Bycopy;
7257*67e74705SXin Li if (QT & Decl::OBJC_TQ_Byref) Result |= CXObjCDeclQualifier_Byref;
7258*67e74705SXin Li if (QT & Decl::OBJC_TQ_Oneway) Result |= CXObjCDeclQualifier_Oneway;
7259*67e74705SXin Li
7260*67e74705SXin Li return Result;
7261*67e74705SXin Li }
7262*67e74705SXin Li
clang_Cursor_isObjCOptional(CXCursor C)7263*67e74705SXin Li unsigned clang_Cursor_isObjCOptional(CXCursor C) {
7264*67e74705SXin Li if (!clang_isDeclaration(C.kind))
7265*67e74705SXin Li return 0;
7266*67e74705SXin Li
7267*67e74705SXin Li const Decl *D = getCursorDecl(C);
7268*67e74705SXin Li if (const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(D))
7269*67e74705SXin Li return PD->getPropertyImplementation() == ObjCPropertyDecl::Optional;
7270*67e74705SXin Li if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
7271*67e74705SXin Li return MD->getImplementationControl() == ObjCMethodDecl::Optional;
7272*67e74705SXin Li
7273*67e74705SXin Li return 0;
7274*67e74705SXin Li }
7275*67e74705SXin Li
clang_Cursor_isVariadic(CXCursor C)7276*67e74705SXin Li unsigned clang_Cursor_isVariadic(CXCursor C) {
7277*67e74705SXin Li if (!clang_isDeclaration(C.kind))
7278*67e74705SXin Li return 0;
7279*67e74705SXin Li
7280*67e74705SXin Li const Decl *D = getCursorDecl(C);
7281*67e74705SXin Li if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
7282*67e74705SXin Li return FD->isVariadic();
7283*67e74705SXin Li if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
7284*67e74705SXin Li return MD->isVariadic();
7285*67e74705SXin Li
7286*67e74705SXin Li return 0;
7287*67e74705SXin Li }
7288*67e74705SXin Li
clang_Cursor_getCommentRange(CXCursor C)7289*67e74705SXin Li CXSourceRange clang_Cursor_getCommentRange(CXCursor C) {
7290*67e74705SXin Li if (!clang_isDeclaration(C.kind))
7291*67e74705SXin Li return clang_getNullRange();
7292*67e74705SXin Li
7293*67e74705SXin Li const Decl *D = getCursorDecl(C);
7294*67e74705SXin Li ASTContext &Context = getCursorContext(C);
7295*67e74705SXin Li const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
7296*67e74705SXin Li if (!RC)
7297*67e74705SXin Li return clang_getNullRange();
7298*67e74705SXin Li
7299*67e74705SXin Li return cxloc::translateSourceRange(Context, RC->getSourceRange());
7300*67e74705SXin Li }
7301*67e74705SXin Li
clang_Cursor_getRawCommentText(CXCursor C)7302*67e74705SXin Li CXString clang_Cursor_getRawCommentText(CXCursor C) {
7303*67e74705SXin Li if (!clang_isDeclaration(C.kind))
7304*67e74705SXin Li return cxstring::createNull();
7305*67e74705SXin Li
7306*67e74705SXin Li const Decl *D = getCursorDecl(C);
7307*67e74705SXin Li ASTContext &Context = getCursorContext(C);
7308*67e74705SXin Li const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
7309*67e74705SXin Li StringRef RawText = RC ? RC->getRawText(Context.getSourceManager()) :
7310*67e74705SXin Li StringRef();
7311*67e74705SXin Li
7312*67e74705SXin Li // Don't duplicate the string because RawText points directly into source
7313*67e74705SXin Li // code.
7314*67e74705SXin Li return cxstring::createRef(RawText);
7315*67e74705SXin Li }
7316*67e74705SXin Li
clang_Cursor_getBriefCommentText(CXCursor C)7317*67e74705SXin Li CXString clang_Cursor_getBriefCommentText(CXCursor C) {
7318*67e74705SXin Li if (!clang_isDeclaration(C.kind))
7319*67e74705SXin Li return cxstring::createNull();
7320*67e74705SXin Li
7321*67e74705SXin Li const Decl *D = getCursorDecl(C);
7322*67e74705SXin Li const ASTContext &Context = getCursorContext(C);
7323*67e74705SXin Li const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
7324*67e74705SXin Li
7325*67e74705SXin Li if (RC) {
7326*67e74705SXin Li StringRef BriefText = RC->getBriefText(Context);
7327*67e74705SXin Li
7328*67e74705SXin Li // Don't duplicate the string because RawComment ensures that this memory
7329*67e74705SXin Li // will not go away.
7330*67e74705SXin Li return cxstring::createRef(BriefText);
7331*67e74705SXin Li }
7332*67e74705SXin Li
7333*67e74705SXin Li return cxstring::createNull();
7334*67e74705SXin Li }
7335*67e74705SXin Li
clang_Cursor_getModule(CXCursor C)7336*67e74705SXin Li CXModule clang_Cursor_getModule(CXCursor C) {
7337*67e74705SXin Li if (C.kind == CXCursor_ModuleImportDecl) {
7338*67e74705SXin Li if (const ImportDecl *ImportD =
7339*67e74705SXin Li dyn_cast_or_null<ImportDecl>(getCursorDecl(C)))
7340*67e74705SXin Li return ImportD->getImportedModule();
7341*67e74705SXin Li }
7342*67e74705SXin Li
7343*67e74705SXin Li return nullptr;
7344*67e74705SXin Li }
7345*67e74705SXin Li
clang_getModuleForFile(CXTranslationUnit TU,CXFile File)7346*67e74705SXin Li CXModule clang_getModuleForFile(CXTranslationUnit TU, CXFile File) {
7347*67e74705SXin Li if (isNotUsableTU(TU)) {
7348*67e74705SXin Li LOG_BAD_TU(TU);
7349*67e74705SXin Li return nullptr;
7350*67e74705SXin Li }
7351*67e74705SXin Li if (!File)
7352*67e74705SXin Li return nullptr;
7353*67e74705SXin Li FileEntry *FE = static_cast<FileEntry *>(File);
7354*67e74705SXin Li
7355*67e74705SXin Li ASTUnit &Unit = *cxtu::getASTUnit(TU);
7356*67e74705SXin Li HeaderSearch &HS = Unit.getPreprocessor().getHeaderSearchInfo();
7357*67e74705SXin Li ModuleMap::KnownHeader Header = HS.findModuleForHeader(FE);
7358*67e74705SXin Li
7359*67e74705SXin Li return Header.getModule();
7360*67e74705SXin Li }
7361*67e74705SXin Li
clang_Module_getASTFile(CXModule CXMod)7362*67e74705SXin Li CXFile clang_Module_getASTFile(CXModule CXMod) {
7363*67e74705SXin Li if (!CXMod)
7364*67e74705SXin Li return nullptr;
7365*67e74705SXin Li Module *Mod = static_cast<Module*>(CXMod);
7366*67e74705SXin Li return const_cast<FileEntry *>(Mod->getASTFile());
7367*67e74705SXin Li }
7368*67e74705SXin Li
clang_Module_getParent(CXModule CXMod)7369*67e74705SXin Li CXModule clang_Module_getParent(CXModule CXMod) {
7370*67e74705SXin Li if (!CXMod)
7371*67e74705SXin Li return nullptr;
7372*67e74705SXin Li Module *Mod = static_cast<Module*>(CXMod);
7373*67e74705SXin Li return Mod->Parent;
7374*67e74705SXin Li }
7375*67e74705SXin Li
clang_Module_getName(CXModule CXMod)7376*67e74705SXin Li CXString clang_Module_getName(CXModule CXMod) {
7377*67e74705SXin Li if (!CXMod)
7378*67e74705SXin Li return cxstring::createEmpty();
7379*67e74705SXin Li Module *Mod = static_cast<Module*>(CXMod);
7380*67e74705SXin Li return cxstring::createDup(Mod->Name);
7381*67e74705SXin Li }
7382*67e74705SXin Li
clang_Module_getFullName(CXModule CXMod)7383*67e74705SXin Li CXString clang_Module_getFullName(CXModule CXMod) {
7384*67e74705SXin Li if (!CXMod)
7385*67e74705SXin Li return cxstring::createEmpty();
7386*67e74705SXin Li Module *Mod = static_cast<Module*>(CXMod);
7387*67e74705SXin Li return cxstring::createDup(Mod->getFullModuleName());
7388*67e74705SXin Li }
7389*67e74705SXin Li
clang_Module_isSystem(CXModule CXMod)7390*67e74705SXin Li int clang_Module_isSystem(CXModule CXMod) {
7391*67e74705SXin Li if (!CXMod)
7392*67e74705SXin Li return 0;
7393*67e74705SXin Li Module *Mod = static_cast<Module*>(CXMod);
7394*67e74705SXin Li return Mod->IsSystem;
7395*67e74705SXin Li }
7396*67e74705SXin Li
clang_Module_getNumTopLevelHeaders(CXTranslationUnit TU,CXModule CXMod)7397*67e74705SXin Li unsigned clang_Module_getNumTopLevelHeaders(CXTranslationUnit TU,
7398*67e74705SXin Li CXModule CXMod) {
7399*67e74705SXin Li if (isNotUsableTU(TU)) {
7400*67e74705SXin Li LOG_BAD_TU(TU);
7401*67e74705SXin Li return 0;
7402*67e74705SXin Li }
7403*67e74705SXin Li if (!CXMod)
7404*67e74705SXin Li return 0;
7405*67e74705SXin Li Module *Mod = static_cast<Module*>(CXMod);
7406*67e74705SXin Li FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
7407*67e74705SXin Li ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
7408*67e74705SXin Li return TopHeaders.size();
7409*67e74705SXin Li }
7410*67e74705SXin Li
clang_Module_getTopLevelHeader(CXTranslationUnit TU,CXModule CXMod,unsigned Index)7411*67e74705SXin Li CXFile clang_Module_getTopLevelHeader(CXTranslationUnit TU,
7412*67e74705SXin Li CXModule CXMod, unsigned Index) {
7413*67e74705SXin Li if (isNotUsableTU(TU)) {
7414*67e74705SXin Li LOG_BAD_TU(TU);
7415*67e74705SXin Li return nullptr;
7416*67e74705SXin Li }
7417*67e74705SXin Li if (!CXMod)
7418*67e74705SXin Li return nullptr;
7419*67e74705SXin Li Module *Mod = static_cast<Module*>(CXMod);
7420*67e74705SXin Li FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
7421*67e74705SXin Li
7422*67e74705SXin Li ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
7423*67e74705SXin Li if (Index < TopHeaders.size())
7424*67e74705SXin Li return const_cast<FileEntry *>(TopHeaders[Index]);
7425*67e74705SXin Li
7426*67e74705SXin Li return nullptr;
7427*67e74705SXin Li }
7428*67e74705SXin Li
7429*67e74705SXin Li } // end: extern "C"
7430*67e74705SXin Li
7431*67e74705SXin Li //===----------------------------------------------------------------------===//
7432*67e74705SXin Li // C++ AST instrospection.
7433*67e74705SXin Li //===----------------------------------------------------------------------===//
7434*67e74705SXin Li
7435*67e74705SXin Li extern "C" {
7436*67e74705SXin Li
clang_CXXConstructor_isDefaultConstructor(CXCursor C)7437*67e74705SXin Li unsigned clang_CXXConstructor_isDefaultConstructor(CXCursor C) {
7438*67e74705SXin Li if (!clang_isDeclaration(C.kind))
7439*67e74705SXin Li return 0;
7440*67e74705SXin Li
7441*67e74705SXin Li const Decl *D = cxcursor::getCursorDecl(C);
7442*67e74705SXin Li const CXXConstructorDecl *Constructor =
7443*67e74705SXin Li D ? dyn_cast_or_null<CXXConstructorDecl>(D->getAsFunction()) : nullptr;
7444*67e74705SXin Li return (Constructor && Constructor->isDefaultConstructor()) ? 1 : 0;
7445*67e74705SXin Li }
7446*67e74705SXin Li
clang_CXXConstructor_isCopyConstructor(CXCursor C)7447*67e74705SXin Li unsigned clang_CXXConstructor_isCopyConstructor(CXCursor C) {
7448*67e74705SXin Li if (!clang_isDeclaration(C.kind))
7449*67e74705SXin Li return 0;
7450*67e74705SXin Li
7451*67e74705SXin Li const Decl *D = cxcursor::getCursorDecl(C);
7452*67e74705SXin Li const CXXConstructorDecl *Constructor =
7453*67e74705SXin Li D ? dyn_cast_or_null<CXXConstructorDecl>(D->getAsFunction()) : nullptr;
7454*67e74705SXin Li return (Constructor && Constructor->isCopyConstructor()) ? 1 : 0;
7455*67e74705SXin Li }
7456*67e74705SXin Li
clang_CXXConstructor_isMoveConstructor(CXCursor C)7457*67e74705SXin Li unsigned clang_CXXConstructor_isMoveConstructor(CXCursor C) {
7458*67e74705SXin Li if (!clang_isDeclaration(C.kind))
7459*67e74705SXin Li return 0;
7460*67e74705SXin Li
7461*67e74705SXin Li const Decl *D = cxcursor::getCursorDecl(C);
7462*67e74705SXin Li const CXXConstructorDecl *Constructor =
7463*67e74705SXin Li D ? dyn_cast_or_null<CXXConstructorDecl>(D->getAsFunction()) : nullptr;
7464*67e74705SXin Li return (Constructor && Constructor->isMoveConstructor()) ? 1 : 0;
7465*67e74705SXin Li }
7466*67e74705SXin Li
clang_CXXConstructor_isConvertingConstructor(CXCursor C)7467*67e74705SXin Li unsigned clang_CXXConstructor_isConvertingConstructor(CXCursor C) {
7468*67e74705SXin Li if (!clang_isDeclaration(C.kind))
7469*67e74705SXin Li return 0;
7470*67e74705SXin Li
7471*67e74705SXin Li const Decl *D = cxcursor::getCursorDecl(C);
7472*67e74705SXin Li const CXXConstructorDecl *Constructor =
7473*67e74705SXin Li D ? dyn_cast_or_null<CXXConstructorDecl>(D->getAsFunction()) : nullptr;
7474*67e74705SXin Li // Passing 'false' excludes constructors marked 'explicit'.
7475*67e74705SXin Li return (Constructor && Constructor->isConvertingConstructor(false)) ? 1 : 0;
7476*67e74705SXin Li }
7477*67e74705SXin Li
clang_CXXField_isMutable(CXCursor C)7478*67e74705SXin Li unsigned clang_CXXField_isMutable(CXCursor C) {
7479*67e74705SXin Li if (!clang_isDeclaration(C.kind))
7480*67e74705SXin Li return 0;
7481*67e74705SXin Li
7482*67e74705SXin Li if (const auto D = cxcursor::getCursorDecl(C))
7483*67e74705SXin Li if (const auto FD = dyn_cast_or_null<FieldDecl>(D))
7484*67e74705SXin Li return FD->isMutable() ? 1 : 0;
7485*67e74705SXin Li return 0;
7486*67e74705SXin Li }
7487*67e74705SXin Li
clang_CXXMethod_isPureVirtual(CXCursor C)7488*67e74705SXin Li unsigned clang_CXXMethod_isPureVirtual(CXCursor C) {
7489*67e74705SXin Li if (!clang_isDeclaration(C.kind))
7490*67e74705SXin Li return 0;
7491*67e74705SXin Li
7492*67e74705SXin Li const Decl *D = cxcursor::getCursorDecl(C);
7493*67e74705SXin Li const CXXMethodDecl *Method =
7494*67e74705SXin Li D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
7495*67e74705SXin Li return (Method && Method->isVirtual() && Method->isPure()) ? 1 : 0;
7496*67e74705SXin Li }
7497*67e74705SXin Li
clang_CXXMethod_isConst(CXCursor C)7498*67e74705SXin Li unsigned clang_CXXMethod_isConst(CXCursor C) {
7499*67e74705SXin Li if (!clang_isDeclaration(C.kind))
7500*67e74705SXin Li return 0;
7501*67e74705SXin Li
7502*67e74705SXin Li const Decl *D = cxcursor::getCursorDecl(C);
7503*67e74705SXin Li const CXXMethodDecl *Method =
7504*67e74705SXin Li D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
7505*67e74705SXin Li return (Method && (Method->getTypeQualifiers() & Qualifiers::Const)) ? 1 : 0;
7506*67e74705SXin Li }
7507*67e74705SXin Li
clang_CXXMethod_isDefaulted(CXCursor C)7508*67e74705SXin Li unsigned clang_CXXMethod_isDefaulted(CXCursor C) {
7509*67e74705SXin Li if (!clang_isDeclaration(C.kind))
7510*67e74705SXin Li return 0;
7511*67e74705SXin Li
7512*67e74705SXin Li const Decl *D = cxcursor::getCursorDecl(C);
7513*67e74705SXin Li const CXXMethodDecl *Method =
7514*67e74705SXin Li D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
7515*67e74705SXin Li return (Method && Method->isDefaulted()) ? 1 : 0;
7516*67e74705SXin Li }
7517*67e74705SXin Li
clang_CXXMethod_isStatic(CXCursor C)7518*67e74705SXin Li unsigned clang_CXXMethod_isStatic(CXCursor C) {
7519*67e74705SXin Li if (!clang_isDeclaration(C.kind))
7520*67e74705SXin Li return 0;
7521*67e74705SXin Li
7522*67e74705SXin Li const Decl *D = cxcursor::getCursorDecl(C);
7523*67e74705SXin Li const CXXMethodDecl *Method =
7524*67e74705SXin Li D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
7525*67e74705SXin Li return (Method && Method->isStatic()) ? 1 : 0;
7526*67e74705SXin Li }
7527*67e74705SXin Li
clang_CXXMethod_isVirtual(CXCursor C)7528*67e74705SXin Li unsigned clang_CXXMethod_isVirtual(CXCursor C) {
7529*67e74705SXin Li if (!clang_isDeclaration(C.kind))
7530*67e74705SXin Li return 0;
7531*67e74705SXin Li
7532*67e74705SXin Li const Decl *D = cxcursor::getCursorDecl(C);
7533*67e74705SXin Li const CXXMethodDecl *Method =
7534*67e74705SXin Li D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
7535*67e74705SXin Li return (Method && Method->isVirtual()) ? 1 : 0;
7536*67e74705SXin Li }
7537*67e74705SXin Li } // end: extern "C"
7538*67e74705SXin Li
7539*67e74705SXin Li //===----------------------------------------------------------------------===//
7540*67e74705SXin Li // Attribute introspection.
7541*67e74705SXin Li //===----------------------------------------------------------------------===//
7542*67e74705SXin Li
7543*67e74705SXin Li extern "C" {
clang_getIBOutletCollectionType(CXCursor C)7544*67e74705SXin Li CXType clang_getIBOutletCollectionType(CXCursor C) {
7545*67e74705SXin Li if (C.kind != CXCursor_IBOutletCollectionAttr)
7546*67e74705SXin Li return cxtype::MakeCXType(QualType(), cxcursor::getCursorTU(C));
7547*67e74705SXin Li
7548*67e74705SXin Li const IBOutletCollectionAttr *A =
7549*67e74705SXin Li cast<IBOutletCollectionAttr>(cxcursor::getCursorAttr(C));
7550*67e74705SXin Li
7551*67e74705SXin Li return cxtype::MakeCXType(A->getInterface(), cxcursor::getCursorTU(C));
7552*67e74705SXin Li }
7553*67e74705SXin Li } // end: extern "C"
7554*67e74705SXin Li
7555*67e74705SXin Li //===----------------------------------------------------------------------===//
7556*67e74705SXin Li // Inspecting memory usage.
7557*67e74705SXin Li //===----------------------------------------------------------------------===//
7558*67e74705SXin Li
7559*67e74705SXin Li typedef std::vector<CXTUResourceUsageEntry> MemUsageEntries;
7560*67e74705SXin Li
createCXTUResourceUsageEntry(MemUsageEntries & entries,enum CXTUResourceUsageKind k,unsigned long amount)7561*67e74705SXin Li static inline void createCXTUResourceUsageEntry(MemUsageEntries &entries,
7562*67e74705SXin Li enum CXTUResourceUsageKind k,
7563*67e74705SXin Li unsigned long amount) {
7564*67e74705SXin Li CXTUResourceUsageEntry entry = { k, amount };
7565*67e74705SXin Li entries.push_back(entry);
7566*67e74705SXin Li }
7567*67e74705SXin Li
7568*67e74705SXin Li extern "C" {
7569*67e74705SXin Li
clang_getTUResourceUsageName(CXTUResourceUsageKind kind)7570*67e74705SXin Li const char *clang_getTUResourceUsageName(CXTUResourceUsageKind kind) {
7571*67e74705SXin Li const char *str = "";
7572*67e74705SXin Li switch (kind) {
7573*67e74705SXin Li case CXTUResourceUsage_AST:
7574*67e74705SXin Li str = "ASTContext: expressions, declarations, and types";
7575*67e74705SXin Li break;
7576*67e74705SXin Li case CXTUResourceUsage_Identifiers:
7577*67e74705SXin Li str = "ASTContext: identifiers";
7578*67e74705SXin Li break;
7579*67e74705SXin Li case CXTUResourceUsage_Selectors:
7580*67e74705SXin Li str = "ASTContext: selectors";
7581*67e74705SXin Li break;
7582*67e74705SXin Li case CXTUResourceUsage_GlobalCompletionResults:
7583*67e74705SXin Li str = "Code completion: cached global results";
7584*67e74705SXin Li break;
7585*67e74705SXin Li case CXTUResourceUsage_SourceManagerContentCache:
7586*67e74705SXin Li str = "SourceManager: content cache allocator";
7587*67e74705SXin Li break;
7588*67e74705SXin Li case CXTUResourceUsage_AST_SideTables:
7589*67e74705SXin Li str = "ASTContext: side tables";
7590*67e74705SXin Li break;
7591*67e74705SXin Li case CXTUResourceUsage_SourceManager_Membuffer_Malloc:
7592*67e74705SXin Li str = "SourceManager: malloc'ed memory buffers";
7593*67e74705SXin Li break;
7594*67e74705SXin Li case CXTUResourceUsage_SourceManager_Membuffer_MMap:
7595*67e74705SXin Li str = "SourceManager: mmap'ed memory buffers";
7596*67e74705SXin Li break;
7597*67e74705SXin Li case CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc:
7598*67e74705SXin Li str = "ExternalASTSource: malloc'ed memory buffers";
7599*67e74705SXin Li break;
7600*67e74705SXin Li case CXTUResourceUsage_ExternalASTSource_Membuffer_MMap:
7601*67e74705SXin Li str = "ExternalASTSource: mmap'ed memory buffers";
7602*67e74705SXin Li break;
7603*67e74705SXin Li case CXTUResourceUsage_Preprocessor:
7604*67e74705SXin Li str = "Preprocessor: malloc'ed memory";
7605*67e74705SXin Li break;
7606*67e74705SXin Li case CXTUResourceUsage_PreprocessingRecord:
7607*67e74705SXin Li str = "Preprocessor: PreprocessingRecord";
7608*67e74705SXin Li break;
7609*67e74705SXin Li case CXTUResourceUsage_SourceManager_DataStructures:
7610*67e74705SXin Li str = "SourceManager: data structures and tables";
7611*67e74705SXin Li break;
7612*67e74705SXin Li case CXTUResourceUsage_Preprocessor_HeaderSearch:
7613*67e74705SXin Li str = "Preprocessor: header search tables";
7614*67e74705SXin Li break;
7615*67e74705SXin Li }
7616*67e74705SXin Li return str;
7617*67e74705SXin Li }
7618*67e74705SXin Li
clang_getCXTUResourceUsage(CXTranslationUnit TU)7619*67e74705SXin Li CXTUResourceUsage clang_getCXTUResourceUsage(CXTranslationUnit TU) {
7620*67e74705SXin Li if (isNotUsableTU(TU)) {
7621*67e74705SXin Li LOG_BAD_TU(TU);
7622*67e74705SXin Li CXTUResourceUsage usage = { (void*) nullptr, 0, nullptr };
7623*67e74705SXin Li return usage;
7624*67e74705SXin Li }
7625*67e74705SXin Li
7626*67e74705SXin Li ASTUnit *astUnit = cxtu::getASTUnit(TU);
7627*67e74705SXin Li std::unique_ptr<MemUsageEntries> entries(new MemUsageEntries());
7628*67e74705SXin Li ASTContext &astContext = astUnit->getASTContext();
7629*67e74705SXin Li
7630*67e74705SXin Li // How much memory is used by AST nodes and types?
7631*67e74705SXin Li createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST,
7632*67e74705SXin Li (unsigned long) astContext.getASTAllocatedMemory());
7633*67e74705SXin Li
7634*67e74705SXin Li // How much memory is used by identifiers?
7635*67e74705SXin Li createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Identifiers,
7636*67e74705SXin Li (unsigned long) astContext.Idents.getAllocator().getTotalMemory());
7637*67e74705SXin Li
7638*67e74705SXin Li // How much memory is used for selectors?
7639*67e74705SXin Li createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Selectors,
7640*67e74705SXin Li (unsigned long) astContext.Selectors.getTotalMemory());
7641*67e74705SXin Li
7642*67e74705SXin Li // How much memory is used by ASTContext's side tables?
7643*67e74705SXin Li createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST_SideTables,
7644*67e74705SXin Li (unsigned long) astContext.getSideTableAllocatedMemory());
7645*67e74705SXin Li
7646*67e74705SXin Li // How much memory is used for caching global code completion results?
7647*67e74705SXin Li unsigned long completionBytes = 0;
7648*67e74705SXin Li if (GlobalCodeCompletionAllocator *completionAllocator =
7649*67e74705SXin Li astUnit->getCachedCompletionAllocator().get()) {
7650*67e74705SXin Li completionBytes = completionAllocator->getTotalMemory();
7651*67e74705SXin Li }
7652*67e74705SXin Li createCXTUResourceUsageEntry(*entries,
7653*67e74705SXin Li CXTUResourceUsage_GlobalCompletionResults,
7654*67e74705SXin Li completionBytes);
7655*67e74705SXin Li
7656*67e74705SXin Li // How much memory is being used by SourceManager's content cache?
7657*67e74705SXin Li createCXTUResourceUsageEntry(*entries,
7658*67e74705SXin Li CXTUResourceUsage_SourceManagerContentCache,
7659*67e74705SXin Li (unsigned long) astContext.getSourceManager().getContentCacheSize());
7660*67e74705SXin Li
7661*67e74705SXin Li // How much memory is being used by the MemoryBuffer's in SourceManager?
7662*67e74705SXin Li const SourceManager::MemoryBufferSizes &srcBufs =
7663*67e74705SXin Li astUnit->getSourceManager().getMemoryBufferSizes();
7664*67e74705SXin Li
7665*67e74705SXin Li createCXTUResourceUsageEntry(*entries,
7666*67e74705SXin Li CXTUResourceUsage_SourceManager_Membuffer_Malloc,
7667*67e74705SXin Li (unsigned long) srcBufs.malloc_bytes);
7668*67e74705SXin Li createCXTUResourceUsageEntry(*entries,
7669*67e74705SXin Li CXTUResourceUsage_SourceManager_Membuffer_MMap,
7670*67e74705SXin Li (unsigned long) srcBufs.mmap_bytes);
7671*67e74705SXin Li createCXTUResourceUsageEntry(*entries,
7672*67e74705SXin Li CXTUResourceUsage_SourceManager_DataStructures,
7673*67e74705SXin Li (unsigned long) astContext.getSourceManager()
7674*67e74705SXin Li .getDataStructureSizes());
7675*67e74705SXin Li
7676*67e74705SXin Li // How much memory is being used by the ExternalASTSource?
7677*67e74705SXin Li if (ExternalASTSource *esrc = astContext.getExternalSource()) {
7678*67e74705SXin Li const ExternalASTSource::MemoryBufferSizes &sizes =
7679*67e74705SXin Li esrc->getMemoryBufferSizes();
7680*67e74705SXin Li
7681*67e74705SXin Li createCXTUResourceUsageEntry(*entries,
7682*67e74705SXin Li CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc,
7683*67e74705SXin Li (unsigned long) sizes.malloc_bytes);
7684*67e74705SXin Li createCXTUResourceUsageEntry(*entries,
7685*67e74705SXin Li CXTUResourceUsage_ExternalASTSource_Membuffer_MMap,
7686*67e74705SXin Li (unsigned long) sizes.mmap_bytes);
7687*67e74705SXin Li }
7688*67e74705SXin Li
7689*67e74705SXin Li // How much memory is being used by the Preprocessor?
7690*67e74705SXin Li Preprocessor &pp = astUnit->getPreprocessor();
7691*67e74705SXin Li createCXTUResourceUsageEntry(*entries,
7692*67e74705SXin Li CXTUResourceUsage_Preprocessor,
7693*67e74705SXin Li pp.getTotalMemory());
7694*67e74705SXin Li
7695*67e74705SXin Li if (PreprocessingRecord *pRec = pp.getPreprocessingRecord()) {
7696*67e74705SXin Li createCXTUResourceUsageEntry(*entries,
7697*67e74705SXin Li CXTUResourceUsage_PreprocessingRecord,
7698*67e74705SXin Li pRec->getTotalMemory());
7699*67e74705SXin Li }
7700*67e74705SXin Li
7701*67e74705SXin Li createCXTUResourceUsageEntry(*entries,
7702*67e74705SXin Li CXTUResourceUsage_Preprocessor_HeaderSearch,
7703*67e74705SXin Li pp.getHeaderSearchInfo().getTotalMemory());
7704*67e74705SXin Li
7705*67e74705SXin Li CXTUResourceUsage usage = { (void*) entries.get(),
7706*67e74705SXin Li (unsigned) entries->size(),
7707*67e74705SXin Li !entries->empty() ? &(*entries)[0] : nullptr };
7708*67e74705SXin Li entries.release();
7709*67e74705SXin Li return usage;
7710*67e74705SXin Li }
7711*67e74705SXin Li
clang_disposeCXTUResourceUsage(CXTUResourceUsage usage)7712*67e74705SXin Li void clang_disposeCXTUResourceUsage(CXTUResourceUsage usage) {
7713*67e74705SXin Li if (usage.data)
7714*67e74705SXin Li delete (MemUsageEntries*) usage.data;
7715*67e74705SXin Li }
7716*67e74705SXin Li
clang_getSkippedRanges(CXTranslationUnit TU,CXFile file)7717*67e74705SXin Li CXSourceRangeList *clang_getSkippedRanges(CXTranslationUnit TU, CXFile file) {
7718*67e74705SXin Li CXSourceRangeList *skipped = new CXSourceRangeList;
7719*67e74705SXin Li skipped->count = 0;
7720*67e74705SXin Li skipped->ranges = nullptr;
7721*67e74705SXin Li
7722*67e74705SXin Li if (isNotUsableTU(TU)) {
7723*67e74705SXin Li LOG_BAD_TU(TU);
7724*67e74705SXin Li return skipped;
7725*67e74705SXin Li }
7726*67e74705SXin Li
7727*67e74705SXin Li if (!file)
7728*67e74705SXin Li return skipped;
7729*67e74705SXin Li
7730*67e74705SXin Li ASTUnit *astUnit = cxtu::getASTUnit(TU);
7731*67e74705SXin Li PreprocessingRecord *ppRec = astUnit->getPreprocessor().getPreprocessingRecord();
7732*67e74705SXin Li if (!ppRec)
7733*67e74705SXin Li return skipped;
7734*67e74705SXin Li
7735*67e74705SXin Li ASTContext &Ctx = astUnit->getASTContext();
7736*67e74705SXin Li SourceManager &sm = Ctx.getSourceManager();
7737*67e74705SXin Li FileEntry *fileEntry = static_cast<FileEntry *>(file);
7738*67e74705SXin Li FileID wantedFileID = sm.translateFile(fileEntry);
7739*67e74705SXin Li
7740*67e74705SXin Li const std::vector<SourceRange> &SkippedRanges = ppRec->getSkippedRanges();
7741*67e74705SXin Li std::vector<SourceRange> wantedRanges;
7742*67e74705SXin Li for (std::vector<SourceRange>::const_iterator i = SkippedRanges.begin(), ei = SkippedRanges.end();
7743*67e74705SXin Li i != ei; ++i) {
7744*67e74705SXin Li if (sm.getFileID(i->getBegin()) == wantedFileID || sm.getFileID(i->getEnd()) == wantedFileID)
7745*67e74705SXin Li wantedRanges.push_back(*i);
7746*67e74705SXin Li }
7747*67e74705SXin Li
7748*67e74705SXin Li skipped->count = wantedRanges.size();
7749*67e74705SXin Li skipped->ranges = new CXSourceRange[skipped->count];
7750*67e74705SXin Li for (unsigned i = 0, ei = skipped->count; i != ei; ++i)
7751*67e74705SXin Li skipped->ranges[i] = cxloc::translateSourceRange(Ctx, wantedRanges[i]);
7752*67e74705SXin Li
7753*67e74705SXin Li return skipped;
7754*67e74705SXin Li }
7755*67e74705SXin Li
clang_disposeSourceRangeList(CXSourceRangeList * ranges)7756*67e74705SXin Li void clang_disposeSourceRangeList(CXSourceRangeList *ranges) {
7757*67e74705SXin Li if (ranges) {
7758*67e74705SXin Li delete[] ranges->ranges;
7759*67e74705SXin Li delete ranges;
7760*67e74705SXin Li }
7761*67e74705SXin Li }
7762*67e74705SXin Li
7763*67e74705SXin Li } // end extern "C"
7764*67e74705SXin Li
PrintLibclangResourceUsage(CXTranslationUnit TU)7765*67e74705SXin Li void clang::PrintLibclangResourceUsage(CXTranslationUnit TU) {
7766*67e74705SXin Li CXTUResourceUsage Usage = clang_getCXTUResourceUsage(TU);
7767*67e74705SXin Li for (unsigned I = 0; I != Usage.numEntries; ++I)
7768*67e74705SXin Li fprintf(stderr, " %s: %lu\n",
7769*67e74705SXin Li clang_getTUResourceUsageName(Usage.entries[I].kind),
7770*67e74705SXin Li Usage.entries[I].amount);
7771*67e74705SXin Li
7772*67e74705SXin Li clang_disposeCXTUResourceUsage(Usage);
7773*67e74705SXin Li }
7774*67e74705SXin Li
7775*67e74705SXin Li //===----------------------------------------------------------------------===//
7776*67e74705SXin Li // Misc. utility functions.
7777*67e74705SXin Li //===----------------------------------------------------------------------===//
7778*67e74705SXin Li
7779*67e74705SXin Li /// Default to using an 8 MB stack size on "safety" threads.
7780*67e74705SXin Li static unsigned SafetyStackThreadSize = 8 << 20;
7781*67e74705SXin Li
7782*67e74705SXin Li namespace clang {
7783*67e74705SXin Li
RunSafely(llvm::CrashRecoveryContext & CRC,llvm::function_ref<void ()> Fn,unsigned Size)7784*67e74705SXin Li bool RunSafely(llvm::CrashRecoveryContext &CRC, llvm::function_ref<void()> Fn,
7785*67e74705SXin Li unsigned Size) {
7786*67e74705SXin Li if (!Size)
7787*67e74705SXin Li Size = GetSafetyThreadStackSize();
7788*67e74705SXin Li if (Size)
7789*67e74705SXin Li return CRC.RunSafelyOnThread(Fn, Size);
7790*67e74705SXin Li return CRC.RunSafely(Fn);
7791*67e74705SXin Li }
7792*67e74705SXin Li
GetSafetyThreadStackSize()7793*67e74705SXin Li unsigned GetSafetyThreadStackSize() {
7794*67e74705SXin Li return SafetyStackThreadSize;
7795*67e74705SXin Li }
7796*67e74705SXin Li
SetSafetyThreadStackSize(unsigned Value)7797*67e74705SXin Li void SetSafetyThreadStackSize(unsigned Value) {
7798*67e74705SXin Li SafetyStackThreadSize = Value;
7799*67e74705SXin Li }
7800*67e74705SXin Li
7801*67e74705SXin Li }
7802*67e74705SXin Li
setThreadBackgroundPriority()7803*67e74705SXin Li void clang::setThreadBackgroundPriority() {
7804*67e74705SXin Li if (getenv("LIBCLANG_BGPRIO_DISABLE"))
7805*67e74705SXin Li return;
7806*67e74705SXin Li
7807*67e74705SXin Li #ifdef USE_DARWIN_THREADS
7808*67e74705SXin Li setpriority(PRIO_DARWIN_THREAD, 0, PRIO_DARWIN_BG);
7809*67e74705SXin Li #endif
7810*67e74705SXin Li }
7811*67e74705SXin Li
printDiagsToStderr(ASTUnit * Unit)7812*67e74705SXin Li void cxindex::printDiagsToStderr(ASTUnit *Unit) {
7813*67e74705SXin Li if (!Unit)
7814*67e74705SXin Li return;
7815*67e74705SXin Li
7816*67e74705SXin Li for (ASTUnit::stored_diag_iterator D = Unit->stored_diag_begin(),
7817*67e74705SXin Li DEnd = Unit->stored_diag_end();
7818*67e74705SXin Li D != DEnd; ++D) {
7819*67e74705SXin Li CXStoredDiagnostic Diag(*D, Unit->getLangOpts());
7820*67e74705SXin Li CXString Msg = clang_formatDiagnostic(&Diag,
7821*67e74705SXin Li clang_defaultDiagnosticDisplayOptions());
7822*67e74705SXin Li fprintf(stderr, "%s\n", clang_getCString(Msg));
7823*67e74705SXin Li clang_disposeString(Msg);
7824*67e74705SXin Li }
7825*67e74705SXin Li #ifdef LLVM_ON_WIN32
7826*67e74705SXin Li // On Windows, force a flush, since there may be multiple copies of
7827*67e74705SXin Li // stderr and stdout in the file system, all with different buffers
7828*67e74705SXin Li // but writing to the same device.
7829*67e74705SXin Li fflush(stderr);
7830*67e74705SXin Li #endif
7831*67e74705SXin Li }
7832*67e74705SXin Li
getMacroInfo(const IdentifierInfo & II,SourceLocation MacroDefLoc,CXTranslationUnit TU)7833*67e74705SXin Li MacroInfo *cxindex::getMacroInfo(const IdentifierInfo &II,
7834*67e74705SXin Li SourceLocation MacroDefLoc,
7835*67e74705SXin Li CXTranslationUnit TU){
7836*67e74705SXin Li if (MacroDefLoc.isInvalid() || !TU)
7837*67e74705SXin Li return nullptr;
7838*67e74705SXin Li if (!II.hadMacroDefinition())
7839*67e74705SXin Li return nullptr;
7840*67e74705SXin Li
7841*67e74705SXin Li ASTUnit *Unit = cxtu::getASTUnit(TU);
7842*67e74705SXin Li Preprocessor &PP = Unit->getPreprocessor();
7843*67e74705SXin Li MacroDirective *MD = PP.getLocalMacroDirectiveHistory(&II);
7844*67e74705SXin Li if (MD) {
7845*67e74705SXin Li for (MacroDirective::DefInfo
7846*67e74705SXin Li Def = MD->getDefinition(); Def; Def = Def.getPreviousDefinition()) {
7847*67e74705SXin Li if (MacroDefLoc == Def.getMacroInfo()->getDefinitionLoc())
7848*67e74705SXin Li return Def.getMacroInfo();
7849*67e74705SXin Li }
7850*67e74705SXin Li }
7851*67e74705SXin Li
7852*67e74705SXin Li return nullptr;
7853*67e74705SXin Li }
7854*67e74705SXin Li
getMacroInfo(const MacroDefinitionRecord * MacroDef,CXTranslationUnit TU)7855*67e74705SXin Li const MacroInfo *cxindex::getMacroInfo(const MacroDefinitionRecord *MacroDef,
7856*67e74705SXin Li CXTranslationUnit TU) {
7857*67e74705SXin Li if (!MacroDef || !TU)
7858*67e74705SXin Li return nullptr;
7859*67e74705SXin Li const IdentifierInfo *II = MacroDef->getName();
7860*67e74705SXin Li if (!II)
7861*67e74705SXin Li return nullptr;
7862*67e74705SXin Li
7863*67e74705SXin Li return getMacroInfo(*II, MacroDef->getLocation(), TU);
7864*67e74705SXin Li }
7865*67e74705SXin Li
7866*67e74705SXin Li MacroDefinitionRecord *
checkForMacroInMacroDefinition(const MacroInfo * MI,const Token & Tok,CXTranslationUnit TU)7867*67e74705SXin Li cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI, const Token &Tok,
7868*67e74705SXin Li CXTranslationUnit TU) {
7869*67e74705SXin Li if (!MI || !TU)
7870*67e74705SXin Li return nullptr;
7871*67e74705SXin Li if (Tok.isNot(tok::raw_identifier))
7872*67e74705SXin Li return nullptr;
7873*67e74705SXin Li
7874*67e74705SXin Li if (MI->getNumTokens() == 0)
7875*67e74705SXin Li return nullptr;
7876*67e74705SXin Li SourceRange DefRange(MI->getReplacementToken(0).getLocation(),
7877*67e74705SXin Li MI->getDefinitionEndLoc());
7878*67e74705SXin Li ASTUnit *Unit = cxtu::getASTUnit(TU);
7879*67e74705SXin Li
7880*67e74705SXin Li // Check that the token is inside the definition and not its argument list.
7881*67e74705SXin Li SourceManager &SM = Unit->getSourceManager();
7882*67e74705SXin Li if (SM.isBeforeInTranslationUnit(Tok.getLocation(), DefRange.getBegin()))
7883*67e74705SXin Li return nullptr;
7884*67e74705SXin Li if (SM.isBeforeInTranslationUnit(DefRange.getEnd(), Tok.getLocation()))
7885*67e74705SXin Li return nullptr;
7886*67e74705SXin Li
7887*67e74705SXin Li Preprocessor &PP = Unit->getPreprocessor();
7888*67e74705SXin Li PreprocessingRecord *PPRec = PP.getPreprocessingRecord();
7889*67e74705SXin Li if (!PPRec)
7890*67e74705SXin Li return nullptr;
7891*67e74705SXin Li
7892*67e74705SXin Li IdentifierInfo &II = PP.getIdentifierTable().get(Tok.getRawIdentifier());
7893*67e74705SXin Li if (!II.hadMacroDefinition())
7894*67e74705SXin Li return nullptr;
7895*67e74705SXin Li
7896*67e74705SXin Li // Check that the identifier is not one of the macro arguments.
7897*67e74705SXin Li if (std::find(MI->arg_begin(), MI->arg_end(), &II) != MI->arg_end())
7898*67e74705SXin Li return nullptr;
7899*67e74705SXin Li
7900*67e74705SXin Li MacroDirective *InnerMD = PP.getLocalMacroDirectiveHistory(&II);
7901*67e74705SXin Li if (!InnerMD)
7902*67e74705SXin Li return nullptr;
7903*67e74705SXin Li
7904*67e74705SXin Li return PPRec->findMacroDefinition(InnerMD->getMacroInfo());
7905*67e74705SXin Li }
7906*67e74705SXin Li
7907*67e74705SXin Li MacroDefinitionRecord *
checkForMacroInMacroDefinition(const MacroInfo * MI,SourceLocation Loc,CXTranslationUnit TU)7908*67e74705SXin Li cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI, SourceLocation Loc,
7909*67e74705SXin Li CXTranslationUnit TU) {
7910*67e74705SXin Li if (Loc.isInvalid() || !MI || !TU)
7911*67e74705SXin Li return nullptr;
7912*67e74705SXin Li
7913*67e74705SXin Li if (MI->getNumTokens() == 0)
7914*67e74705SXin Li return nullptr;
7915*67e74705SXin Li ASTUnit *Unit = cxtu::getASTUnit(TU);
7916*67e74705SXin Li Preprocessor &PP = Unit->getPreprocessor();
7917*67e74705SXin Li if (!PP.getPreprocessingRecord())
7918*67e74705SXin Li return nullptr;
7919*67e74705SXin Li Loc = Unit->getSourceManager().getSpellingLoc(Loc);
7920*67e74705SXin Li Token Tok;
7921*67e74705SXin Li if (PP.getRawToken(Loc, Tok))
7922*67e74705SXin Li return nullptr;
7923*67e74705SXin Li
7924*67e74705SXin Li return checkForMacroInMacroDefinition(MI, Tok, TU);
7925*67e74705SXin Li }
7926*67e74705SXin Li
7927*67e74705SXin Li extern "C" {
7928*67e74705SXin Li
clang_getClangVersion()7929*67e74705SXin Li CXString clang_getClangVersion() {
7930*67e74705SXin Li return cxstring::createDup(getClangFullVersion());
7931*67e74705SXin Li }
7932*67e74705SXin Li
7933*67e74705SXin Li } // end: extern "C"
7934*67e74705SXin Li
operator <<(CXTranslationUnit TU)7935*67e74705SXin Li Logger &cxindex::Logger::operator<<(CXTranslationUnit TU) {
7936*67e74705SXin Li if (TU) {
7937*67e74705SXin Li if (ASTUnit *Unit = cxtu::getASTUnit(TU)) {
7938*67e74705SXin Li LogOS << '<' << Unit->getMainFileName() << '>';
7939*67e74705SXin Li if (Unit->isMainFileAST())
7940*67e74705SXin Li LogOS << " (" << Unit->getASTFileName() << ')';
7941*67e74705SXin Li return *this;
7942*67e74705SXin Li }
7943*67e74705SXin Li } else {
7944*67e74705SXin Li LogOS << "<NULL TU>";
7945*67e74705SXin Li }
7946*67e74705SXin Li return *this;
7947*67e74705SXin Li }
7948*67e74705SXin Li
operator <<(const FileEntry * FE)7949*67e74705SXin Li Logger &cxindex::Logger::operator<<(const FileEntry *FE) {
7950*67e74705SXin Li *this << FE->getName();
7951*67e74705SXin Li return *this;
7952*67e74705SXin Li }
7953*67e74705SXin Li
operator <<(CXCursor cursor)7954*67e74705SXin Li Logger &cxindex::Logger::operator<<(CXCursor cursor) {
7955*67e74705SXin Li CXString cursorName = clang_getCursorDisplayName(cursor);
7956*67e74705SXin Li *this << cursorName << "@" << clang_getCursorLocation(cursor);
7957*67e74705SXin Li clang_disposeString(cursorName);
7958*67e74705SXin Li return *this;
7959*67e74705SXin Li }
7960*67e74705SXin Li
operator <<(CXSourceLocation Loc)7961*67e74705SXin Li Logger &cxindex::Logger::operator<<(CXSourceLocation Loc) {
7962*67e74705SXin Li CXFile File;
7963*67e74705SXin Li unsigned Line, Column;
7964*67e74705SXin Li clang_getFileLocation(Loc, &File, &Line, &Column, nullptr);
7965*67e74705SXin Li CXString FileName = clang_getFileName(File);
7966*67e74705SXin Li *this << llvm::format("(%s:%d:%d)", clang_getCString(FileName), Line, Column);
7967*67e74705SXin Li clang_disposeString(FileName);
7968*67e74705SXin Li return *this;
7969*67e74705SXin Li }
7970*67e74705SXin Li
operator <<(CXSourceRange range)7971*67e74705SXin Li Logger &cxindex::Logger::operator<<(CXSourceRange range) {
7972*67e74705SXin Li CXSourceLocation BLoc = clang_getRangeStart(range);
7973*67e74705SXin Li CXSourceLocation ELoc = clang_getRangeEnd(range);
7974*67e74705SXin Li
7975*67e74705SXin Li CXFile BFile;
7976*67e74705SXin Li unsigned BLine, BColumn;
7977*67e74705SXin Li clang_getFileLocation(BLoc, &BFile, &BLine, &BColumn, nullptr);
7978*67e74705SXin Li
7979*67e74705SXin Li CXFile EFile;
7980*67e74705SXin Li unsigned ELine, EColumn;
7981*67e74705SXin Li clang_getFileLocation(ELoc, &EFile, &ELine, &EColumn, nullptr);
7982*67e74705SXin Li
7983*67e74705SXin Li CXString BFileName = clang_getFileName(BFile);
7984*67e74705SXin Li if (BFile == EFile) {
7985*67e74705SXin Li *this << llvm::format("[%s %d:%d-%d:%d]", clang_getCString(BFileName),
7986*67e74705SXin Li BLine, BColumn, ELine, EColumn);
7987*67e74705SXin Li } else {
7988*67e74705SXin Li CXString EFileName = clang_getFileName(EFile);
7989*67e74705SXin Li *this << llvm::format("[%s:%d:%d - ", clang_getCString(BFileName),
7990*67e74705SXin Li BLine, BColumn)
7991*67e74705SXin Li << llvm::format("%s:%d:%d]", clang_getCString(EFileName),
7992*67e74705SXin Li ELine, EColumn);
7993*67e74705SXin Li clang_disposeString(EFileName);
7994*67e74705SXin Li }
7995*67e74705SXin Li clang_disposeString(BFileName);
7996*67e74705SXin Li return *this;
7997*67e74705SXin Li }
7998*67e74705SXin Li
operator <<(CXString Str)7999*67e74705SXin Li Logger &cxindex::Logger::operator<<(CXString Str) {
8000*67e74705SXin Li *this << clang_getCString(Str);
8001*67e74705SXin Li return *this;
8002*67e74705SXin Li }
8003*67e74705SXin Li
operator <<(const llvm::format_object_base & Fmt)8004*67e74705SXin Li Logger &cxindex::Logger::operator<<(const llvm::format_object_base &Fmt) {
8005*67e74705SXin Li LogOS << Fmt;
8006*67e74705SXin Li return *this;
8007*67e74705SXin Li }
8008*67e74705SXin Li
8009*67e74705SXin Li static llvm::ManagedStatic<llvm::sys::Mutex> LoggingMutex;
8010*67e74705SXin Li
~Logger()8011*67e74705SXin Li cxindex::Logger::~Logger() {
8012*67e74705SXin Li llvm::sys::ScopedLock L(*LoggingMutex);
8013*67e74705SXin Li
8014*67e74705SXin Li static llvm::TimeRecord sBeginTR = llvm::TimeRecord::getCurrentTime();
8015*67e74705SXin Li
8016*67e74705SXin Li raw_ostream &OS = llvm::errs();
8017*67e74705SXin Li OS << "[libclang:" << Name << ':';
8018*67e74705SXin Li
8019*67e74705SXin Li #ifdef USE_DARWIN_THREADS
8020*67e74705SXin Li // TODO: Portability.
8021*67e74705SXin Li mach_port_t tid = pthread_mach_thread_np(pthread_self());
8022*67e74705SXin Li OS << tid << ':';
8023*67e74705SXin Li #endif
8024*67e74705SXin Li
8025*67e74705SXin Li llvm::TimeRecord TR = llvm::TimeRecord::getCurrentTime();
8026*67e74705SXin Li OS << llvm::format("%7.4f] ", TR.getWallTime() - sBeginTR.getWallTime());
8027*67e74705SXin Li OS << Msg << '\n';
8028*67e74705SXin Li
8029*67e74705SXin Li if (Trace) {
8030*67e74705SXin Li llvm::sys::PrintStackTrace(OS);
8031*67e74705SXin Li OS << "--------------------------------------------------\n";
8032*67e74705SXin Li }
8033*67e74705SXin Li }
8034*67e74705SXin Li
8035*67e74705SXin Li #ifdef CLANG_TOOL_EXTRA_BUILD
8036*67e74705SXin Li // This anchor is used to force the linker to link the clang-tidy plugin.
8037*67e74705SXin Li extern volatile int ClangTidyPluginAnchorSource;
8038*67e74705SXin Li static int LLVM_ATTRIBUTE_UNUSED ClangTidyPluginAnchorDestination =
8039*67e74705SXin Li ClangTidyPluginAnchorSource;
8040*67e74705SXin Li #endif
8041