1*67e74705SXin Li //===- CXCursor.cpp - Routines for manipulating CXCursors -----------------===//
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 defines routines for manipulating CXCursors. It should be the
11*67e74705SXin Li // only file that has internal knowledge of the encoding of the data in
12*67e74705SXin Li // CXCursor.
13*67e74705SXin Li //
14*67e74705SXin Li //===----------------------------------------------------------------------===//
15*67e74705SXin Li
16*67e74705SXin Li #include "CXTranslationUnit.h"
17*67e74705SXin Li #include "CXCursor.h"
18*67e74705SXin Li #include "CXString.h"
19*67e74705SXin Li #include "CXType.h"
20*67e74705SXin Li #include "clang-c/Index.h"
21*67e74705SXin Li #include "clang/AST/Attr.h"
22*67e74705SXin Li #include "clang/AST/Decl.h"
23*67e74705SXin Li #include "clang/AST/DeclCXX.h"
24*67e74705SXin Li #include "clang/AST/DeclObjC.h"
25*67e74705SXin Li #include "clang/AST/DeclTemplate.h"
26*67e74705SXin Li #include "clang/AST/Expr.h"
27*67e74705SXin Li #include "clang/AST/ExprCXX.h"
28*67e74705SXin Li #include "clang/AST/ExprObjC.h"
29*67e74705SXin Li #include "clang/Frontend/ASTUnit.h"
30*67e74705SXin Li #include "llvm/Support/ErrorHandling.h"
31*67e74705SXin Li
32*67e74705SXin Li using namespace clang;
33*67e74705SXin Li using namespace cxcursor;
34*67e74705SXin Li
MakeCXCursorInvalid(CXCursorKind K,CXTranslationUnit TU)35*67e74705SXin Li CXCursor cxcursor::MakeCXCursorInvalid(CXCursorKind K, CXTranslationUnit TU) {
36*67e74705SXin Li assert(K >= CXCursor_FirstInvalid && K <= CXCursor_LastInvalid);
37*67e74705SXin Li CXCursor C = { K, 0, { nullptr, nullptr, TU } };
38*67e74705SXin Li return C;
39*67e74705SXin Li }
40*67e74705SXin Li
GetCursorKind(const Attr * A)41*67e74705SXin Li static CXCursorKind GetCursorKind(const Attr *A) {
42*67e74705SXin Li assert(A && "Invalid arguments!");
43*67e74705SXin Li switch (A->getKind()) {
44*67e74705SXin Li default: break;
45*67e74705SXin Li case attr::IBAction: return CXCursor_IBActionAttr;
46*67e74705SXin Li case attr::IBOutlet: return CXCursor_IBOutletAttr;
47*67e74705SXin Li case attr::IBOutletCollection: return CXCursor_IBOutletCollectionAttr;
48*67e74705SXin Li case attr::Final: return CXCursor_CXXFinalAttr;
49*67e74705SXin Li case attr::Override: return CXCursor_CXXOverrideAttr;
50*67e74705SXin Li case attr::Annotate: return CXCursor_AnnotateAttr;
51*67e74705SXin Li case attr::AsmLabel: return CXCursor_AsmLabelAttr;
52*67e74705SXin Li case attr::Packed: return CXCursor_PackedAttr;
53*67e74705SXin Li case attr::Pure: return CXCursor_PureAttr;
54*67e74705SXin Li case attr::Const: return CXCursor_ConstAttr;
55*67e74705SXin Li case attr::NoDuplicate: return CXCursor_NoDuplicateAttr;
56*67e74705SXin Li case attr::CUDAConstant: return CXCursor_CUDAConstantAttr;
57*67e74705SXin Li case attr::CUDADevice: return CXCursor_CUDADeviceAttr;
58*67e74705SXin Li case attr::CUDAGlobal: return CXCursor_CUDAGlobalAttr;
59*67e74705SXin Li case attr::CUDAHost: return CXCursor_CUDAHostAttr;
60*67e74705SXin Li case attr::CUDAShared: return CXCursor_CUDASharedAttr;
61*67e74705SXin Li case attr::Visibility: return CXCursor_VisibilityAttr;
62*67e74705SXin Li case attr::DLLExport: return CXCursor_DLLExport;
63*67e74705SXin Li case attr::DLLImport: return CXCursor_DLLImport;
64*67e74705SXin Li }
65*67e74705SXin Li
66*67e74705SXin Li return CXCursor_UnexposedAttr;
67*67e74705SXin Li }
68*67e74705SXin Li
MakeCXCursor(const Attr * A,const Decl * Parent,CXTranslationUnit TU)69*67e74705SXin Li CXCursor cxcursor::MakeCXCursor(const Attr *A, const Decl *Parent,
70*67e74705SXin Li CXTranslationUnit TU) {
71*67e74705SXin Li assert(A && Parent && TU && "Invalid arguments!");
72*67e74705SXin Li CXCursor C = { GetCursorKind(A), 0, { Parent, A, TU } };
73*67e74705SXin Li return C;
74*67e74705SXin Li }
75*67e74705SXin Li
MakeCXCursor(const Decl * D,CXTranslationUnit TU,SourceRange RegionOfInterest,bool FirstInDeclGroup)76*67e74705SXin Li CXCursor cxcursor::MakeCXCursor(const Decl *D, CXTranslationUnit TU,
77*67e74705SXin Li SourceRange RegionOfInterest,
78*67e74705SXin Li bool FirstInDeclGroup) {
79*67e74705SXin Li assert(D && TU && "Invalid arguments!");
80*67e74705SXin Li
81*67e74705SXin Li CXCursorKind K = getCursorKindForDecl(D);
82*67e74705SXin Li
83*67e74705SXin Li if (K == CXCursor_ObjCClassMethodDecl ||
84*67e74705SXin Li K == CXCursor_ObjCInstanceMethodDecl) {
85*67e74705SXin Li int SelectorIdIndex = -1;
86*67e74705SXin Li // Check if cursor points to a selector id.
87*67e74705SXin Li if (RegionOfInterest.isValid() &&
88*67e74705SXin Li RegionOfInterest.getBegin() == RegionOfInterest.getEnd()) {
89*67e74705SXin Li SmallVector<SourceLocation, 16> SelLocs;
90*67e74705SXin Li cast<ObjCMethodDecl>(D)->getSelectorLocs(SelLocs);
91*67e74705SXin Li SmallVectorImpl<SourceLocation>::iterator
92*67e74705SXin Li I=std::find(SelLocs.begin(), SelLocs.end(),RegionOfInterest.getBegin());
93*67e74705SXin Li if (I != SelLocs.end())
94*67e74705SXin Li SelectorIdIndex = I - SelLocs.begin();
95*67e74705SXin Li }
96*67e74705SXin Li CXCursor C = { K, SelectorIdIndex,
97*67e74705SXin Li { D, (void*)(intptr_t) (FirstInDeclGroup ? 1 : 0), TU }};
98*67e74705SXin Li return C;
99*67e74705SXin Li }
100*67e74705SXin Li
101*67e74705SXin Li CXCursor C = { K, 0, { D, (void*)(intptr_t) (FirstInDeclGroup ? 1 : 0), TU }};
102*67e74705SXin Li return C;
103*67e74705SXin Li }
104*67e74705SXin Li
MakeCXCursor(const Stmt * S,const Decl * Parent,CXTranslationUnit TU,SourceRange RegionOfInterest)105*67e74705SXin Li CXCursor cxcursor::MakeCXCursor(const Stmt *S, const Decl *Parent,
106*67e74705SXin Li CXTranslationUnit TU,
107*67e74705SXin Li SourceRange RegionOfInterest) {
108*67e74705SXin Li assert(S && TU && "Invalid arguments!");
109*67e74705SXin Li CXCursorKind K = CXCursor_NotImplemented;
110*67e74705SXin Li
111*67e74705SXin Li switch (S->getStmtClass()) {
112*67e74705SXin Li case Stmt::NoStmtClass:
113*67e74705SXin Li break;
114*67e74705SXin Li
115*67e74705SXin Li case Stmt::CaseStmtClass:
116*67e74705SXin Li K = CXCursor_CaseStmt;
117*67e74705SXin Li break;
118*67e74705SXin Li
119*67e74705SXin Li case Stmt::DefaultStmtClass:
120*67e74705SXin Li K = CXCursor_DefaultStmt;
121*67e74705SXin Li break;
122*67e74705SXin Li
123*67e74705SXin Li case Stmt::IfStmtClass:
124*67e74705SXin Li K = CXCursor_IfStmt;
125*67e74705SXin Li break;
126*67e74705SXin Li
127*67e74705SXin Li case Stmt::SwitchStmtClass:
128*67e74705SXin Li K = CXCursor_SwitchStmt;
129*67e74705SXin Li break;
130*67e74705SXin Li
131*67e74705SXin Li case Stmt::WhileStmtClass:
132*67e74705SXin Li K = CXCursor_WhileStmt;
133*67e74705SXin Li break;
134*67e74705SXin Li
135*67e74705SXin Li case Stmt::DoStmtClass:
136*67e74705SXin Li K = CXCursor_DoStmt;
137*67e74705SXin Li break;
138*67e74705SXin Li
139*67e74705SXin Li case Stmt::ForStmtClass:
140*67e74705SXin Li K = CXCursor_ForStmt;
141*67e74705SXin Li break;
142*67e74705SXin Li
143*67e74705SXin Li case Stmt::GotoStmtClass:
144*67e74705SXin Li K = CXCursor_GotoStmt;
145*67e74705SXin Li break;
146*67e74705SXin Li
147*67e74705SXin Li case Stmt::IndirectGotoStmtClass:
148*67e74705SXin Li K = CXCursor_IndirectGotoStmt;
149*67e74705SXin Li break;
150*67e74705SXin Li
151*67e74705SXin Li case Stmt::ContinueStmtClass:
152*67e74705SXin Li K = CXCursor_ContinueStmt;
153*67e74705SXin Li break;
154*67e74705SXin Li
155*67e74705SXin Li case Stmt::BreakStmtClass:
156*67e74705SXin Li K = CXCursor_BreakStmt;
157*67e74705SXin Li break;
158*67e74705SXin Li
159*67e74705SXin Li case Stmt::ReturnStmtClass:
160*67e74705SXin Li K = CXCursor_ReturnStmt;
161*67e74705SXin Li break;
162*67e74705SXin Li
163*67e74705SXin Li case Stmt::GCCAsmStmtClass:
164*67e74705SXin Li K = CXCursor_GCCAsmStmt;
165*67e74705SXin Li break;
166*67e74705SXin Li
167*67e74705SXin Li case Stmt::MSAsmStmtClass:
168*67e74705SXin Li K = CXCursor_MSAsmStmt;
169*67e74705SXin Li break;
170*67e74705SXin Li
171*67e74705SXin Li case Stmt::ObjCAtTryStmtClass:
172*67e74705SXin Li K = CXCursor_ObjCAtTryStmt;
173*67e74705SXin Li break;
174*67e74705SXin Li
175*67e74705SXin Li case Stmt::ObjCAtCatchStmtClass:
176*67e74705SXin Li K = CXCursor_ObjCAtCatchStmt;
177*67e74705SXin Li break;
178*67e74705SXin Li
179*67e74705SXin Li case Stmt::ObjCAtFinallyStmtClass:
180*67e74705SXin Li K = CXCursor_ObjCAtFinallyStmt;
181*67e74705SXin Li break;
182*67e74705SXin Li
183*67e74705SXin Li case Stmt::ObjCAtThrowStmtClass:
184*67e74705SXin Li K = CXCursor_ObjCAtThrowStmt;
185*67e74705SXin Li break;
186*67e74705SXin Li
187*67e74705SXin Li case Stmt::ObjCAtSynchronizedStmtClass:
188*67e74705SXin Li K = CXCursor_ObjCAtSynchronizedStmt;
189*67e74705SXin Li break;
190*67e74705SXin Li
191*67e74705SXin Li case Stmt::ObjCAutoreleasePoolStmtClass:
192*67e74705SXin Li K = CXCursor_ObjCAutoreleasePoolStmt;
193*67e74705SXin Li break;
194*67e74705SXin Li
195*67e74705SXin Li case Stmt::ObjCForCollectionStmtClass:
196*67e74705SXin Li K = CXCursor_ObjCForCollectionStmt;
197*67e74705SXin Li break;
198*67e74705SXin Li
199*67e74705SXin Li case Stmt::CXXCatchStmtClass:
200*67e74705SXin Li K = CXCursor_CXXCatchStmt;
201*67e74705SXin Li break;
202*67e74705SXin Li
203*67e74705SXin Li case Stmt::CXXTryStmtClass:
204*67e74705SXin Li K = CXCursor_CXXTryStmt;
205*67e74705SXin Li break;
206*67e74705SXin Li
207*67e74705SXin Li case Stmt::CXXForRangeStmtClass:
208*67e74705SXin Li K = CXCursor_CXXForRangeStmt;
209*67e74705SXin Li break;
210*67e74705SXin Li
211*67e74705SXin Li case Stmt::SEHTryStmtClass:
212*67e74705SXin Li K = CXCursor_SEHTryStmt;
213*67e74705SXin Li break;
214*67e74705SXin Li
215*67e74705SXin Li case Stmt::SEHExceptStmtClass:
216*67e74705SXin Li K = CXCursor_SEHExceptStmt;
217*67e74705SXin Li break;
218*67e74705SXin Li
219*67e74705SXin Li case Stmt::SEHFinallyStmtClass:
220*67e74705SXin Li K = CXCursor_SEHFinallyStmt;
221*67e74705SXin Li break;
222*67e74705SXin Li
223*67e74705SXin Li case Stmt::SEHLeaveStmtClass:
224*67e74705SXin Li K = CXCursor_SEHLeaveStmt;
225*67e74705SXin Li break;
226*67e74705SXin Li
227*67e74705SXin Li case Stmt::ArrayTypeTraitExprClass:
228*67e74705SXin Li case Stmt::AsTypeExprClass:
229*67e74705SXin Li case Stmt::AtomicExprClass:
230*67e74705SXin Li case Stmt::BinaryConditionalOperatorClass:
231*67e74705SXin Li case Stmt::TypeTraitExprClass:
232*67e74705SXin Li case Stmt::CoroutineBodyStmtClass:
233*67e74705SXin Li case Stmt::CoawaitExprClass:
234*67e74705SXin Li case Stmt::CoreturnStmtClass:
235*67e74705SXin Li case Stmt::CoyieldExprClass:
236*67e74705SXin Li case Stmt::CXXBindTemporaryExprClass:
237*67e74705SXin Li case Stmt::CXXDefaultArgExprClass:
238*67e74705SXin Li case Stmt::CXXDefaultInitExprClass:
239*67e74705SXin Li case Stmt::CXXFoldExprClass:
240*67e74705SXin Li case Stmt::CXXStdInitializerListExprClass:
241*67e74705SXin Li case Stmt::CXXScalarValueInitExprClass:
242*67e74705SXin Li case Stmt::CXXUuidofExprClass:
243*67e74705SXin Li case Stmt::ChooseExprClass:
244*67e74705SXin Li case Stmt::DesignatedInitExprClass:
245*67e74705SXin Li case Stmt::DesignatedInitUpdateExprClass:
246*67e74705SXin Li case Stmt::ExprWithCleanupsClass:
247*67e74705SXin Li case Stmt::ExpressionTraitExprClass:
248*67e74705SXin Li case Stmt::ExtVectorElementExprClass:
249*67e74705SXin Li case Stmt::ImplicitCastExprClass:
250*67e74705SXin Li case Stmt::ImplicitValueInitExprClass:
251*67e74705SXin Li case Stmt::NoInitExprClass:
252*67e74705SXin Li case Stmt::MaterializeTemporaryExprClass:
253*67e74705SXin Li case Stmt::ObjCIndirectCopyRestoreExprClass:
254*67e74705SXin Li case Stmt::OffsetOfExprClass:
255*67e74705SXin Li case Stmt::ParenListExprClass:
256*67e74705SXin Li case Stmt::PredefinedExprClass:
257*67e74705SXin Li case Stmt::ShuffleVectorExprClass:
258*67e74705SXin Li case Stmt::ConvertVectorExprClass:
259*67e74705SXin Li case Stmt::VAArgExprClass:
260*67e74705SXin Li case Stmt::ObjCArrayLiteralClass:
261*67e74705SXin Li case Stmt::ObjCDictionaryLiteralClass:
262*67e74705SXin Li case Stmt::ObjCBoxedExprClass:
263*67e74705SXin Li case Stmt::ObjCSubscriptRefExprClass:
264*67e74705SXin Li K = CXCursor_UnexposedExpr;
265*67e74705SXin Li break;
266*67e74705SXin Li
267*67e74705SXin Li case Stmt::OpaqueValueExprClass:
268*67e74705SXin Li if (Expr *Src = cast<OpaqueValueExpr>(S)->getSourceExpr())
269*67e74705SXin Li return MakeCXCursor(Src, Parent, TU, RegionOfInterest);
270*67e74705SXin Li K = CXCursor_UnexposedExpr;
271*67e74705SXin Li break;
272*67e74705SXin Li
273*67e74705SXin Li case Stmt::PseudoObjectExprClass:
274*67e74705SXin Li return MakeCXCursor(cast<PseudoObjectExpr>(S)->getSyntacticForm(),
275*67e74705SXin Li Parent, TU, RegionOfInterest);
276*67e74705SXin Li
277*67e74705SXin Li case Stmt::CompoundStmtClass:
278*67e74705SXin Li K = CXCursor_CompoundStmt;
279*67e74705SXin Li break;
280*67e74705SXin Li
281*67e74705SXin Li case Stmt::NullStmtClass:
282*67e74705SXin Li K = CXCursor_NullStmt;
283*67e74705SXin Li break;
284*67e74705SXin Li
285*67e74705SXin Li case Stmt::LabelStmtClass:
286*67e74705SXin Li K = CXCursor_LabelStmt;
287*67e74705SXin Li break;
288*67e74705SXin Li
289*67e74705SXin Li case Stmt::AttributedStmtClass:
290*67e74705SXin Li K = CXCursor_UnexposedStmt;
291*67e74705SXin Li break;
292*67e74705SXin Li
293*67e74705SXin Li case Stmt::DeclStmtClass:
294*67e74705SXin Li K = CXCursor_DeclStmt;
295*67e74705SXin Li break;
296*67e74705SXin Li
297*67e74705SXin Li case Stmt::CapturedStmtClass:
298*67e74705SXin Li K = CXCursor_UnexposedStmt;
299*67e74705SXin Li break;
300*67e74705SXin Li
301*67e74705SXin Li case Stmt::IntegerLiteralClass:
302*67e74705SXin Li K = CXCursor_IntegerLiteral;
303*67e74705SXin Li break;
304*67e74705SXin Li
305*67e74705SXin Li case Stmt::FloatingLiteralClass:
306*67e74705SXin Li K = CXCursor_FloatingLiteral;
307*67e74705SXin Li break;
308*67e74705SXin Li
309*67e74705SXin Li case Stmt::ImaginaryLiteralClass:
310*67e74705SXin Li K = CXCursor_ImaginaryLiteral;
311*67e74705SXin Li break;
312*67e74705SXin Li
313*67e74705SXin Li case Stmt::StringLiteralClass:
314*67e74705SXin Li K = CXCursor_StringLiteral;
315*67e74705SXin Li break;
316*67e74705SXin Li
317*67e74705SXin Li case Stmt::CharacterLiteralClass:
318*67e74705SXin Li K = CXCursor_CharacterLiteral;
319*67e74705SXin Li break;
320*67e74705SXin Li
321*67e74705SXin Li case Stmt::ParenExprClass:
322*67e74705SXin Li K = CXCursor_ParenExpr;
323*67e74705SXin Li break;
324*67e74705SXin Li
325*67e74705SXin Li case Stmt::UnaryOperatorClass:
326*67e74705SXin Li K = CXCursor_UnaryOperator;
327*67e74705SXin Li break;
328*67e74705SXin Li
329*67e74705SXin Li case Stmt::UnaryExprOrTypeTraitExprClass:
330*67e74705SXin Li case Stmt::CXXNoexceptExprClass:
331*67e74705SXin Li K = CXCursor_UnaryExpr;
332*67e74705SXin Li break;
333*67e74705SXin Li
334*67e74705SXin Li case Stmt::MSPropertySubscriptExprClass:
335*67e74705SXin Li case Stmt::ArraySubscriptExprClass:
336*67e74705SXin Li K = CXCursor_ArraySubscriptExpr;
337*67e74705SXin Li break;
338*67e74705SXin Li
339*67e74705SXin Li case Stmt::OMPArraySectionExprClass:
340*67e74705SXin Li K = CXCursor_OMPArraySectionExpr;
341*67e74705SXin Li break;
342*67e74705SXin Li
343*67e74705SXin Li case Stmt::BinaryOperatorClass:
344*67e74705SXin Li K = CXCursor_BinaryOperator;
345*67e74705SXin Li break;
346*67e74705SXin Li
347*67e74705SXin Li case Stmt::CompoundAssignOperatorClass:
348*67e74705SXin Li K = CXCursor_CompoundAssignOperator;
349*67e74705SXin Li break;
350*67e74705SXin Li
351*67e74705SXin Li case Stmt::ConditionalOperatorClass:
352*67e74705SXin Li K = CXCursor_ConditionalOperator;
353*67e74705SXin Li break;
354*67e74705SXin Li
355*67e74705SXin Li case Stmt::CStyleCastExprClass:
356*67e74705SXin Li K = CXCursor_CStyleCastExpr;
357*67e74705SXin Li break;
358*67e74705SXin Li
359*67e74705SXin Li case Stmt::CompoundLiteralExprClass:
360*67e74705SXin Li K = CXCursor_CompoundLiteralExpr;
361*67e74705SXin Li break;
362*67e74705SXin Li
363*67e74705SXin Li case Stmt::InitListExprClass:
364*67e74705SXin Li K = CXCursor_InitListExpr;
365*67e74705SXin Li break;
366*67e74705SXin Li
367*67e74705SXin Li case Stmt::AddrLabelExprClass:
368*67e74705SXin Li K = CXCursor_AddrLabelExpr;
369*67e74705SXin Li break;
370*67e74705SXin Li
371*67e74705SXin Li case Stmt::StmtExprClass:
372*67e74705SXin Li K = CXCursor_StmtExpr;
373*67e74705SXin Li break;
374*67e74705SXin Li
375*67e74705SXin Li case Stmt::GenericSelectionExprClass:
376*67e74705SXin Li K = CXCursor_GenericSelectionExpr;
377*67e74705SXin Li break;
378*67e74705SXin Li
379*67e74705SXin Li case Stmt::GNUNullExprClass:
380*67e74705SXin Li K = CXCursor_GNUNullExpr;
381*67e74705SXin Li break;
382*67e74705SXin Li
383*67e74705SXin Li case Stmt::CXXStaticCastExprClass:
384*67e74705SXin Li K = CXCursor_CXXStaticCastExpr;
385*67e74705SXin Li break;
386*67e74705SXin Li
387*67e74705SXin Li case Stmt::CXXDynamicCastExprClass:
388*67e74705SXin Li K = CXCursor_CXXDynamicCastExpr;
389*67e74705SXin Li break;
390*67e74705SXin Li
391*67e74705SXin Li case Stmt::CXXReinterpretCastExprClass:
392*67e74705SXin Li K = CXCursor_CXXReinterpretCastExpr;
393*67e74705SXin Li break;
394*67e74705SXin Li
395*67e74705SXin Li case Stmt::CXXConstCastExprClass:
396*67e74705SXin Li K = CXCursor_CXXConstCastExpr;
397*67e74705SXin Li break;
398*67e74705SXin Li
399*67e74705SXin Li case Stmt::CXXFunctionalCastExprClass:
400*67e74705SXin Li K = CXCursor_CXXFunctionalCastExpr;
401*67e74705SXin Li break;
402*67e74705SXin Li
403*67e74705SXin Li case Stmt::CXXTypeidExprClass:
404*67e74705SXin Li K = CXCursor_CXXTypeidExpr;
405*67e74705SXin Li break;
406*67e74705SXin Li
407*67e74705SXin Li case Stmt::CXXBoolLiteralExprClass:
408*67e74705SXin Li K = CXCursor_CXXBoolLiteralExpr;
409*67e74705SXin Li break;
410*67e74705SXin Li
411*67e74705SXin Li case Stmt::CXXNullPtrLiteralExprClass:
412*67e74705SXin Li K = CXCursor_CXXNullPtrLiteralExpr;
413*67e74705SXin Li break;
414*67e74705SXin Li
415*67e74705SXin Li case Stmt::CXXThisExprClass:
416*67e74705SXin Li K = CXCursor_CXXThisExpr;
417*67e74705SXin Li break;
418*67e74705SXin Li
419*67e74705SXin Li case Stmt::CXXThrowExprClass:
420*67e74705SXin Li K = CXCursor_CXXThrowExpr;
421*67e74705SXin Li break;
422*67e74705SXin Li
423*67e74705SXin Li case Stmt::CXXNewExprClass:
424*67e74705SXin Li K = CXCursor_CXXNewExpr;
425*67e74705SXin Li break;
426*67e74705SXin Li
427*67e74705SXin Li case Stmt::CXXDeleteExprClass:
428*67e74705SXin Li K = CXCursor_CXXDeleteExpr;
429*67e74705SXin Li break;
430*67e74705SXin Li
431*67e74705SXin Li case Stmt::ObjCStringLiteralClass:
432*67e74705SXin Li K = CXCursor_ObjCStringLiteral;
433*67e74705SXin Li break;
434*67e74705SXin Li
435*67e74705SXin Li case Stmt::ObjCEncodeExprClass:
436*67e74705SXin Li K = CXCursor_ObjCEncodeExpr;
437*67e74705SXin Li break;
438*67e74705SXin Li
439*67e74705SXin Li case Stmt::ObjCSelectorExprClass:
440*67e74705SXin Li K = CXCursor_ObjCSelectorExpr;
441*67e74705SXin Li break;
442*67e74705SXin Li
443*67e74705SXin Li case Stmt::ObjCProtocolExprClass:
444*67e74705SXin Li K = CXCursor_ObjCProtocolExpr;
445*67e74705SXin Li break;
446*67e74705SXin Li
447*67e74705SXin Li case Stmt::ObjCBoolLiteralExprClass:
448*67e74705SXin Li K = CXCursor_ObjCBoolLiteralExpr;
449*67e74705SXin Li break;
450*67e74705SXin Li
451*67e74705SXin Li case Stmt::ObjCBridgedCastExprClass:
452*67e74705SXin Li K = CXCursor_ObjCBridgedCastExpr;
453*67e74705SXin Li break;
454*67e74705SXin Li
455*67e74705SXin Li case Stmt::BlockExprClass:
456*67e74705SXin Li K = CXCursor_BlockExpr;
457*67e74705SXin Li break;
458*67e74705SXin Li
459*67e74705SXin Li case Stmt::PackExpansionExprClass:
460*67e74705SXin Li K = CXCursor_PackExpansionExpr;
461*67e74705SXin Li break;
462*67e74705SXin Li
463*67e74705SXin Li case Stmt::SizeOfPackExprClass:
464*67e74705SXin Li K = CXCursor_SizeOfPackExpr;
465*67e74705SXin Li break;
466*67e74705SXin Li
467*67e74705SXin Li case Stmt::DeclRefExprClass:
468*67e74705SXin Li if (const ImplicitParamDecl *IPD =
469*67e74705SXin Li dyn_cast_or_null<ImplicitParamDecl>(cast<DeclRefExpr>(S)->getDecl())) {
470*67e74705SXin Li if (const ObjCMethodDecl *MD =
471*67e74705SXin Li dyn_cast<ObjCMethodDecl>(IPD->getDeclContext())) {
472*67e74705SXin Li if (MD->getSelfDecl() == IPD) {
473*67e74705SXin Li K = CXCursor_ObjCSelfExpr;
474*67e74705SXin Li break;
475*67e74705SXin Li }
476*67e74705SXin Li }
477*67e74705SXin Li }
478*67e74705SXin Li
479*67e74705SXin Li K = CXCursor_DeclRefExpr;
480*67e74705SXin Li break;
481*67e74705SXin Li
482*67e74705SXin Li case Stmt::DependentScopeDeclRefExprClass:
483*67e74705SXin Li case Stmt::SubstNonTypeTemplateParmExprClass:
484*67e74705SXin Li case Stmt::SubstNonTypeTemplateParmPackExprClass:
485*67e74705SXin Li case Stmt::FunctionParmPackExprClass:
486*67e74705SXin Li case Stmt::UnresolvedLookupExprClass:
487*67e74705SXin Li case Stmt::TypoExprClass: // A typo could actually be a DeclRef or a MemberRef
488*67e74705SXin Li K = CXCursor_DeclRefExpr;
489*67e74705SXin Li break;
490*67e74705SXin Li
491*67e74705SXin Li case Stmt::CXXDependentScopeMemberExprClass:
492*67e74705SXin Li case Stmt::CXXPseudoDestructorExprClass:
493*67e74705SXin Li case Stmt::MemberExprClass:
494*67e74705SXin Li case Stmt::MSPropertyRefExprClass:
495*67e74705SXin Li case Stmt::ObjCIsaExprClass:
496*67e74705SXin Li case Stmt::ObjCIvarRefExprClass:
497*67e74705SXin Li case Stmt::ObjCPropertyRefExprClass:
498*67e74705SXin Li case Stmt::UnresolvedMemberExprClass:
499*67e74705SXin Li K = CXCursor_MemberRefExpr;
500*67e74705SXin Li break;
501*67e74705SXin Li
502*67e74705SXin Li case Stmt::CallExprClass:
503*67e74705SXin Li case Stmt::CXXOperatorCallExprClass:
504*67e74705SXin Li case Stmt::CXXMemberCallExprClass:
505*67e74705SXin Li case Stmt::CUDAKernelCallExprClass:
506*67e74705SXin Li case Stmt::CXXConstructExprClass:
507*67e74705SXin Li case Stmt::CXXInheritedCtorInitExprClass:
508*67e74705SXin Li case Stmt::CXXTemporaryObjectExprClass:
509*67e74705SXin Li case Stmt::CXXUnresolvedConstructExprClass:
510*67e74705SXin Li case Stmt::UserDefinedLiteralClass:
511*67e74705SXin Li K = CXCursor_CallExpr;
512*67e74705SXin Li break;
513*67e74705SXin Li
514*67e74705SXin Li case Stmt::LambdaExprClass:
515*67e74705SXin Li K = CXCursor_LambdaExpr;
516*67e74705SXin Li break;
517*67e74705SXin Li
518*67e74705SXin Li case Stmt::ObjCMessageExprClass: {
519*67e74705SXin Li K = CXCursor_ObjCMessageExpr;
520*67e74705SXin Li int SelectorIdIndex = -1;
521*67e74705SXin Li // Check if cursor points to a selector id.
522*67e74705SXin Li if (RegionOfInterest.isValid() &&
523*67e74705SXin Li RegionOfInterest.getBegin() == RegionOfInterest.getEnd()) {
524*67e74705SXin Li SmallVector<SourceLocation, 16> SelLocs;
525*67e74705SXin Li cast<ObjCMessageExpr>(S)->getSelectorLocs(SelLocs);
526*67e74705SXin Li SmallVectorImpl<SourceLocation>::iterator
527*67e74705SXin Li I=std::find(SelLocs.begin(), SelLocs.end(),RegionOfInterest.getBegin());
528*67e74705SXin Li if (I != SelLocs.end())
529*67e74705SXin Li SelectorIdIndex = I - SelLocs.begin();
530*67e74705SXin Li }
531*67e74705SXin Li CXCursor C = { K, 0, { Parent, S, TU } };
532*67e74705SXin Li return getSelectorIdentifierCursor(SelectorIdIndex, C);
533*67e74705SXin Li }
534*67e74705SXin Li
535*67e74705SXin Li case Stmt::MSDependentExistsStmtClass:
536*67e74705SXin Li K = CXCursor_UnexposedStmt;
537*67e74705SXin Li break;
538*67e74705SXin Li case Stmt::OMPParallelDirectiveClass:
539*67e74705SXin Li K = CXCursor_OMPParallelDirective;
540*67e74705SXin Li break;
541*67e74705SXin Li case Stmt::OMPSimdDirectiveClass:
542*67e74705SXin Li K = CXCursor_OMPSimdDirective;
543*67e74705SXin Li break;
544*67e74705SXin Li case Stmt::OMPForDirectiveClass:
545*67e74705SXin Li K = CXCursor_OMPForDirective;
546*67e74705SXin Li break;
547*67e74705SXin Li case Stmt::OMPForSimdDirectiveClass:
548*67e74705SXin Li K = CXCursor_OMPForSimdDirective;
549*67e74705SXin Li break;
550*67e74705SXin Li case Stmt::OMPSectionsDirectiveClass:
551*67e74705SXin Li K = CXCursor_OMPSectionsDirective;
552*67e74705SXin Li break;
553*67e74705SXin Li case Stmt::OMPSectionDirectiveClass:
554*67e74705SXin Li K = CXCursor_OMPSectionDirective;
555*67e74705SXin Li break;
556*67e74705SXin Li case Stmt::OMPSingleDirectiveClass:
557*67e74705SXin Li K = CXCursor_OMPSingleDirective;
558*67e74705SXin Li break;
559*67e74705SXin Li case Stmt::OMPMasterDirectiveClass:
560*67e74705SXin Li K = CXCursor_OMPMasterDirective;
561*67e74705SXin Li break;
562*67e74705SXin Li case Stmt::OMPCriticalDirectiveClass:
563*67e74705SXin Li K = CXCursor_OMPCriticalDirective;
564*67e74705SXin Li break;
565*67e74705SXin Li case Stmt::OMPParallelForDirectiveClass:
566*67e74705SXin Li K = CXCursor_OMPParallelForDirective;
567*67e74705SXin Li break;
568*67e74705SXin Li case Stmt::OMPParallelForSimdDirectiveClass:
569*67e74705SXin Li K = CXCursor_OMPParallelForSimdDirective;
570*67e74705SXin Li break;
571*67e74705SXin Li case Stmt::OMPParallelSectionsDirectiveClass:
572*67e74705SXin Li K = CXCursor_OMPParallelSectionsDirective;
573*67e74705SXin Li break;
574*67e74705SXin Li case Stmt::OMPTaskDirectiveClass:
575*67e74705SXin Li K = CXCursor_OMPTaskDirective;
576*67e74705SXin Li break;
577*67e74705SXin Li case Stmt::OMPTaskyieldDirectiveClass:
578*67e74705SXin Li K = CXCursor_OMPTaskyieldDirective;
579*67e74705SXin Li break;
580*67e74705SXin Li case Stmt::OMPBarrierDirectiveClass:
581*67e74705SXin Li K = CXCursor_OMPBarrierDirective;
582*67e74705SXin Li break;
583*67e74705SXin Li case Stmt::OMPTaskwaitDirectiveClass:
584*67e74705SXin Li K = CXCursor_OMPTaskwaitDirective;
585*67e74705SXin Li break;
586*67e74705SXin Li case Stmt::OMPTaskgroupDirectiveClass:
587*67e74705SXin Li K = CXCursor_OMPTaskgroupDirective;
588*67e74705SXin Li break;
589*67e74705SXin Li case Stmt::OMPFlushDirectiveClass:
590*67e74705SXin Li K = CXCursor_OMPFlushDirective;
591*67e74705SXin Li break;
592*67e74705SXin Li case Stmt::OMPOrderedDirectiveClass:
593*67e74705SXin Li K = CXCursor_OMPOrderedDirective;
594*67e74705SXin Li break;
595*67e74705SXin Li case Stmt::OMPAtomicDirectiveClass:
596*67e74705SXin Li K = CXCursor_OMPAtomicDirective;
597*67e74705SXin Li break;
598*67e74705SXin Li case Stmt::OMPTargetDirectiveClass:
599*67e74705SXin Li K = CXCursor_OMPTargetDirective;
600*67e74705SXin Li break;
601*67e74705SXin Li case Stmt::OMPTargetDataDirectiveClass:
602*67e74705SXin Li K = CXCursor_OMPTargetDataDirective;
603*67e74705SXin Li break;
604*67e74705SXin Li case Stmt::OMPTargetEnterDataDirectiveClass:
605*67e74705SXin Li K = CXCursor_OMPTargetEnterDataDirective;
606*67e74705SXin Li break;
607*67e74705SXin Li case Stmt::OMPTargetExitDataDirectiveClass:
608*67e74705SXin Li K = CXCursor_OMPTargetExitDataDirective;
609*67e74705SXin Li break;
610*67e74705SXin Li case Stmt::OMPTargetParallelDirectiveClass:
611*67e74705SXin Li K = CXCursor_OMPTargetParallelDirective;
612*67e74705SXin Li break;
613*67e74705SXin Li case Stmt::OMPTargetParallelForDirectiveClass:
614*67e74705SXin Li K = CXCursor_OMPTargetParallelForDirective;
615*67e74705SXin Li break;
616*67e74705SXin Li case Stmt::OMPTargetUpdateDirectiveClass:
617*67e74705SXin Li K = CXCursor_OMPTargetUpdateDirective;
618*67e74705SXin Li break;
619*67e74705SXin Li case Stmt::OMPTeamsDirectiveClass:
620*67e74705SXin Li K = CXCursor_OMPTeamsDirective;
621*67e74705SXin Li break;
622*67e74705SXin Li case Stmt::OMPCancellationPointDirectiveClass:
623*67e74705SXin Li K = CXCursor_OMPCancellationPointDirective;
624*67e74705SXin Li break;
625*67e74705SXin Li case Stmt::OMPCancelDirectiveClass:
626*67e74705SXin Li K = CXCursor_OMPCancelDirective;
627*67e74705SXin Li break;
628*67e74705SXin Li case Stmt::OMPTaskLoopDirectiveClass:
629*67e74705SXin Li K = CXCursor_OMPTaskLoopDirective;
630*67e74705SXin Li break;
631*67e74705SXin Li case Stmt::OMPTaskLoopSimdDirectiveClass:
632*67e74705SXin Li K = CXCursor_OMPTaskLoopSimdDirective;
633*67e74705SXin Li break;
634*67e74705SXin Li case Stmt::OMPDistributeDirectiveClass:
635*67e74705SXin Li K = CXCursor_OMPDistributeDirective;
636*67e74705SXin Li break;
637*67e74705SXin Li case Stmt::OMPDistributeParallelForDirectiveClass:
638*67e74705SXin Li K = CXCursor_OMPDistributeParallelForDirective;
639*67e74705SXin Li break;
640*67e74705SXin Li case Stmt::OMPDistributeParallelForSimdDirectiveClass:
641*67e74705SXin Li K = CXCursor_OMPDistributeParallelForSimdDirective;
642*67e74705SXin Li break;
643*67e74705SXin Li case Stmt::OMPDistributeSimdDirectiveClass:
644*67e74705SXin Li K = CXCursor_OMPDistributeSimdDirective;
645*67e74705SXin Li break;
646*67e74705SXin Li case Stmt::OMPTargetParallelForSimdDirectiveClass:
647*67e74705SXin Li K = CXCursor_OMPTargetParallelForSimdDirective;
648*67e74705SXin Li break;
649*67e74705SXin Li }
650*67e74705SXin Li
651*67e74705SXin Li CXCursor C = { K, 0, { Parent, S, TU } };
652*67e74705SXin Li return C;
653*67e74705SXin Li }
654*67e74705SXin Li
MakeCursorObjCSuperClassRef(ObjCInterfaceDecl * Super,SourceLocation Loc,CXTranslationUnit TU)655*67e74705SXin Li CXCursor cxcursor::MakeCursorObjCSuperClassRef(ObjCInterfaceDecl *Super,
656*67e74705SXin Li SourceLocation Loc,
657*67e74705SXin Li CXTranslationUnit TU) {
658*67e74705SXin Li assert(Super && TU && "Invalid arguments!");
659*67e74705SXin Li void *RawLoc = Loc.getPtrEncoding();
660*67e74705SXin Li CXCursor C = { CXCursor_ObjCSuperClassRef, 0, { Super, RawLoc, TU } };
661*67e74705SXin Li return C;
662*67e74705SXin Li }
663*67e74705SXin Li
664*67e74705SXin Li std::pair<const ObjCInterfaceDecl *, SourceLocation>
getCursorObjCSuperClassRef(CXCursor C)665*67e74705SXin Li cxcursor::getCursorObjCSuperClassRef(CXCursor C) {
666*67e74705SXin Li assert(C.kind == CXCursor_ObjCSuperClassRef);
667*67e74705SXin Li return std::make_pair(static_cast<const ObjCInterfaceDecl *>(C.data[0]),
668*67e74705SXin Li SourceLocation::getFromPtrEncoding(C.data[1]));
669*67e74705SXin Li }
670*67e74705SXin Li
MakeCursorObjCProtocolRef(const ObjCProtocolDecl * Proto,SourceLocation Loc,CXTranslationUnit TU)671*67e74705SXin Li CXCursor cxcursor::MakeCursorObjCProtocolRef(const ObjCProtocolDecl *Proto,
672*67e74705SXin Li SourceLocation Loc,
673*67e74705SXin Li CXTranslationUnit TU) {
674*67e74705SXin Li assert(Proto && TU && "Invalid arguments!");
675*67e74705SXin Li void *RawLoc = Loc.getPtrEncoding();
676*67e74705SXin Li CXCursor C = { CXCursor_ObjCProtocolRef, 0, { Proto, RawLoc, TU } };
677*67e74705SXin Li return C;
678*67e74705SXin Li }
679*67e74705SXin Li
680*67e74705SXin Li std::pair<const ObjCProtocolDecl *, SourceLocation>
getCursorObjCProtocolRef(CXCursor C)681*67e74705SXin Li cxcursor::getCursorObjCProtocolRef(CXCursor C) {
682*67e74705SXin Li assert(C.kind == CXCursor_ObjCProtocolRef);
683*67e74705SXin Li return std::make_pair(static_cast<const ObjCProtocolDecl *>(C.data[0]),
684*67e74705SXin Li SourceLocation::getFromPtrEncoding(C.data[1]));
685*67e74705SXin Li }
686*67e74705SXin Li
MakeCursorObjCClassRef(const ObjCInterfaceDecl * Class,SourceLocation Loc,CXTranslationUnit TU)687*67e74705SXin Li CXCursor cxcursor::MakeCursorObjCClassRef(const ObjCInterfaceDecl *Class,
688*67e74705SXin Li SourceLocation Loc,
689*67e74705SXin Li CXTranslationUnit TU) {
690*67e74705SXin Li // 'Class' can be null for invalid code.
691*67e74705SXin Li if (!Class)
692*67e74705SXin Li return MakeCXCursorInvalid(CXCursor_InvalidCode);
693*67e74705SXin Li assert(TU && "Invalid arguments!");
694*67e74705SXin Li void *RawLoc = Loc.getPtrEncoding();
695*67e74705SXin Li CXCursor C = { CXCursor_ObjCClassRef, 0, { Class, RawLoc, TU } };
696*67e74705SXin Li return C;
697*67e74705SXin Li }
698*67e74705SXin Li
699*67e74705SXin Li std::pair<const ObjCInterfaceDecl *, SourceLocation>
getCursorObjCClassRef(CXCursor C)700*67e74705SXin Li cxcursor::getCursorObjCClassRef(CXCursor C) {
701*67e74705SXin Li assert(C.kind == CXCursor_ObjCClassRef);
702*67e74705SXin Li return std::make_pair(static_cast<const ObjCInterfaceDecl *>(C.data[0]),
703*67e74705SXin Li SourceLocation::getFromPtrEncoding(C.data[1]));
704*67e74705SXin Li }
705*67e74705SXin Li
MakeCursorTypeRef(const TypeDecl * Type,SourceLocation Loc,CXTranslationUnit TU)706*67e74705SXin Li CXCursor cxcursor::MakeCursorTypeRef(const TypeDecl *Type, SourceLocation Loc,
707*67e74705SXin Li CXTranslationUnit TU) {
708*67e74705SXin Li assert(Type && TU && "Invalid arguments!");
709*67e74705SXin Li void *RawLoc = Loc.getPtrEncoding();
710*67e74705SXin Li CXCursor C = { CXCursor_TypeRef, 0, { Type, RawLoc, TU } };
711*67e74705SXin Li return C;
712*67e74705SXin Li }
713*67e74705SXin Li
714*67e74705SXin Li std::pair<const TypeDecl *, SourceLocation>
getCursorTypeRef(CXCursor C)715*67e74705SXin Li cxcursor::getCursorTypeRef(CXCursor C) {
716*67e74705SXin Li assert(C.kind == CXCursor_TypeRef);
717*67e74705SXin Li return std::make_pair(static_cast<const TypeDecl *>(C.data[0]),
718*67e74705SXin Li SourceLocation::getFromPtrEncoding(C.data[1]));
719*67e74705SXin Li }
720*67e74705SXin Li
MakeCursorTemplateRef(const TemplateDecl * Template,SourceLocation Loc,CXTranslationUnit TU)721*67e74705SXin Li CXCursor cxcursor::MakeCursorTemplateRef(const TemplateDecl *Template,
722*67e74705SXin Li SourceLocation Loc,
723*67e74705SXin Li CXTranslationUnit TU) {
724*67e74705SXin Li assert(Template && TU && "Invalid arguments!");
725*67e74705SXin Li void *RawLoc = Loc.getPtrEncoding();
726*67e74705SXin Li CXCursor C = { CXCursor_TemplateRef, 0, { Template, RawLoc, TU } };
727*67e74705SXin Li return C;
728*67e74705SXin Li }
729*67e74705SXin Li
730*67e74705SXin Li std::pair<const TemplateDecl *, SourceLocation>
getCursorTemplateRef(CXCursor C)731*67e74705SXin Li cxcursor::getCursorTemplateRef(CXCursor C) {
732*67e74705SXin Li assert(C.kind == CXCursor_TemplateRef);
733*67e74705SXin Li return std::make_pair(static_cast<const TemplateDecl *>(C.data[0]),
734*67e74705SXin Li SourceLocation::getFromPtrEncoding(C.data[1]));
735*67e74705SXin Li }
736*67e74705SXin Li
MakeCursorNamespaceRef(const NamedDecl * NS,SourceLocation Loc,CXTranslationUnit TU)737*67e74705SXin Li CXCursor cxcursor::MakeCursorNamespaceRef(const NamedDecl *NS,
738*67e74705SXin Li SourceLocation Loc,
739*67e74705SXin Li CXTranslationUnit TU) {
740*67e74705SXin Li
741*67e74705SXin Li assert(NS && (isa<NamespaceDecl>(NS) || isa<NamespaceAliasDecl>(NS)) && TU &&
742*67e74705SXin Li "Invalid arguments!");
743*67e74705SXin Li void *RawLoc = Loc.getPtrEncoding();
744*67e74705SXin Li CXCursor C = { CXCursor_NamespaceRef, 0, { NS, RawLoc, TU } };
745*67e74705SXin Li return C;
746*67e74705SXin Li }
747*67e74705SXin Li
748*67e74705SXin Li std::pair<const NamedDecl *, SourceLocation>
getCursorNamespaceRef(CXCursor C)749*67e74705SXin Li cxcursor::getCursorNamespaceRef(CXCursor C) {
750*67e74705SXin Li assert(C.kind == CXCursor_NamespaceRef);
751*67e74705SXin Li return std::make_pair(static_cast<const NamedDecl *>(C.data[0]),
752*67e74705SXin Li SourceLocation::getFromPtrEncoding(C.data[1]));
753*67e74705SXin Li }
754*67e74705SXin Li
MakeCursorVariableRef(const VarDecl * Var,SourceLocation Loc,CXTranslationUnit TU)755*67e74705SXin Li CXCursor cxcursor::MakeCursorVariableRef(const VarDecl *Var, SourceLocation Loc,
756*67e74705SXin Li CXTranslationUnit TU) {
757*67e74705SXin Li
758*67e74705SXin Li assert(Var && TU && "Invalid arguments!");
759*67e74705SXin Li void *RawLoc = Loc.getPtrEncoding();
760*67e74705SXin Li CXCursor C = { CXCursor_VariableRef, 0, { Var, RawLoc, TU } };
761*67e74705SXin Li return C;
762*67e74705SXin Li }
763*67e74705SXin Li
764*67e74705SXin Li std::pair<const VarDecl *, SourceLocation>
getCursorVariableRef(CXCursor C)765*67e74705SXin Li cxcursor::getCursorVariableRef(CXCursor C) {
766*67e74705SXin Li assert(C.kind == CXCursor_VariableRef);
767*67e74705SXin Li return std::make_pair(static_cast<const VarDecl *>(C.data[0]),
768*67e74705SXin Li SourceLocation::getFromPtrEncoding(C.data[1]));
769*67e74705SXin Li }
770*67e74705SXin Li
MakeCursorMemberRef(const FieldDecl * Field,SourceLocation Loc,CXTranslationUnit TU)771*67e74705SXin Li CXCursor cxcursor::MakeCursorMemberRef(const FieldDecl *Field, SourceLocation Loc,
772*67e74705SXin Li CXTranslationUnit TU) {
773*67e74705SXin Li
774*67e74705SXin Li assert(Field && TU && "Invalid arguments!");
775*67e74705SXin Li void *RawLoc = Loc.getPtrEncoding();
776*67e74705SXin Li CXCursor C = { CXCursor_MemberRef, 0, { Field, RawLoc, TU } };
777*67e74705SXin Li return C;
778*67e74705SXin Li }
779*67e74705SXin Li
780*67e74705SXin Li std::pair<const FieldDecl *, SourceLocation>
getCursorMemberRef(CXCursor C)781*67e74705SXin Li cxcursor::getCursorMemberRef(CXCursor C) {
782*67e74705SXin Li assert(C.kind == CXCursor_MemberRef);
783*67e74705SXin Li return std::make_pair(static_cast<const FieldDecl *>(C.data[0]),
784*67e74705SXin Li SourceLocation::getFromPtrEncoding(C.data[1]));
785*67e74705SXin Li }
786*67e74705SXin Li
MakeCursorCXXBaseSpecifier(const CXXBaseSpecifier * B,CXTranslationUnit TU)787*67e74705SXin Li CXCursor cxcursor::MakeCursorCXXBaseSpecifier(const CXXBaseSpecifier *B,
788*67e74705SXin Li CXTranslationUnit TU){
789*67e74705SXin Li CXCursor C = { CXCursor_CXXBaseSpecifier, 0, { B, nullptr, TU } };
790*67e74705SXin Li return C;
791*67e74705SXin Li }
792*67e74705SXin Li
getCursorCXXBaseSpecifier(CXCursor C)793*67e74705SXin Li const CXXBaseSpecifier *cxcursor::getCursorCXXBaseSpecifier(CXCursor C) {
794*67e74705SXin Li assert(C.kind == CXCursor_CXXBaseSpecifier);
795*67e74705SXin Li return static_cast<const CXXBaseSpecifier*>(C.data[0]);
796*67e74705SXin Li }
797*67e74705SXin Li
MakePreprocessingDirectiveCursor(SourceRange Range,CXTranslationUnit TU)798*67e74705SXin Li CXCursor cxcursor::MakePreprocessingDirectiveCursor(SourceRange Range,
799*67e74705SXin Li CXTranslationUnit TU) {
800*67e74705SXin Li CXCursor C = { CXCursor_PreprocessingDirective, 0,
801*67e74705SXin Li { Range.getBegin().getPtrEncoding(),
802*67e74705SXin Li Range.getEnd().getPtrEncoding(),
803*67e74705SXin Li TU }
804*67e74705SXin Li };
805*67e74705SXin Li return C;
806*67e74705SXin Li }
807*67e74705SXin Li
getCursorPreprocessingDirective(CXCursor C)808*67e74705SXin Li SourceRange cxcursor::getCursorPreprocessingDirective(CXCursor C) {
809*67e74705SXin Li assert(C.kind == CXCursor_PreprocessingDirective);
810*67e74705SXin Li SourceRange Range(SourceLocation::getFromPtrEncoding(C.data[0]),
811*67e74705SXin Li SourceLocation::getFromPtrEncoding(C.data[1]));
812*67e74705SXin Li ASTUnit *TU = getCursorASTUnit(C);
813*67e74705SXin Li return TU->mapRangeFromPreamble(Range);
814*67e74705SXin Li }
815*67e74705SXin Li
MakeMacroDefinitionCursor(const MacroDefinitionRecord * MI,CXTranslationUnit TU)816*67e74705SXin Li CXCursor cxcursor::MakeMacroDefinitionCursor(const MacroDefinitionRecord *MI,
817*67e74705SXin Li CXTranslationUnit TU) {
818*67e74705SXin Li CXCursor C = {CXCursor_MacroDefinition, 0, {MI, nullptr, TU}};
819*67e74705SXin Li return C;
820*67e74705SXin Li }
821*67e74705SXin Li
getCursorMacroDefinition(CXCursor C)822*67e74705SXin Li const MacroDefinitionRecord *cxcursor::getCursorMacroDefinition(CXCursor C) {
823*67e74705SXin Li assert(C.kind == CXCursor_MacroDefinition);
824*67e74705SXin Li return static_cast<const MacroDefinitionRecord *>(C.data[0]);
825*67e74705SXin Li }
826*67e74705SXin Li
MakeMacroExpansionCursor(MacroExpansion * MI,CXTranslationUnit TU)827*67e74705SXin Li CXCursor cxcursor::MakeMacroExpansionCursor(MacroExpansion *MI,
828*67e74705SXin Li CXTranslationUnit TU) {
829*67e74705SXin Li CXCursor C = { CXCursor_MacroExpansion, 0, { MI, nullptr, TU } };
830*67e74705SXin Li return C;
831*67e74705SXin Li }
832*67e74705SXin Li
MakeMacroExpansionCursor(MacroDefinitionRecord * MI,SourceLocation Loc,CXTranslationUnit TU)833*67e74705SXin Li CXCursor cxcursor::MakeMacroExpansionCursor(MacroDefinitionRecord *MI,
834*67e74705SXin Li SourceLocation Loc,
835*67e74705SXin Li CXTranslationUnit TU) {
836*67e74705SXin Li assert(Loc.isValid());
837*67e74705SXin Li CXCursor C = {CXCursor_MacroExpansion, 0, {MI, Loc.getPtrEncoding(), TU}};
838*67e74705SXin Li return C;
839*67e74705SXin Li }
840*67e74705SXin Li
getName() const841*67e74705SXin Li const IdentifierInfo *cxcursor::MacroExpansionCursor::getName() const {
842*67e74705SXin Li if (isPseudo())
843*67e74705SXin Li return getAsMacroDefinition()->getName();
844*67e74705SXin Li return getAsMacroExpansion()->getName();
845*67e74705SXin Li }
846*67e74705SXin Li const MacroDefinitionRecord *
getDefinition() const847*67e74705SXin Li cxcursor::MacroExpansionCursor::getDefinition() const {
848*67e74705SXin Li if (isPseudo())
849*67e74705SXin Li return getAsMacroDefinition();
850*67e74705SXin Li return getAsMacroExpansion()->getDefinition();
851*67e74705SXin Li }
getSourceRange() const852*67e74705SXin Li SourceRange cxcursor::MacroExpansionCursor::getSourceRange() const {
853*67e74705SXin Li if (isPseudo())
854*67e74705SXin Li return getPseudoLoc();
855*67e74705SXin Li return getAsMacroExpansion()->getSourceRange();
856*67e74705SXin Li }
857*67e74705SXin Li
MakeInclusionDirectiveCursor(InclusionDirective * ID,CXTranslationUnit TU)858*67e74705SXin Li CXCursor cxcursor::MakeInclusionDirectiveCursor(InclusionDirective *ID,
859*67e74705SXin Li CXTranslationUnit TU) {
860*67e74705SXin Li CXCursor C = { CXCursor_InclusionDirective, 0, { ID, nullptr, TU } };
861*67e74705SXin Li return C;
862*67e74705SXin Li }
863*67e74705SXin Li
getCursorInclusionDirective(CXCursor C)864*67e74705SXin Li const InclusionDirective *cxcursor::getCursorInclusionDirective(CXCursor C) {
865*67e74705SXin Li assert(C.kind == CXCursor_InclusionDirective);
866*67e74705SXin Li return static_cast<const InclusionDirective *>(C.data[0]);
867*67e74705SXin Li }
868*67e74705SXin Li
MakeCursorLabelRef(LabelStmt * Label,SourceLocation Loc,CXTranslationUnit TU)869*67e74705SXin Li CXCursor cxcursor::MakeCursorLabelRef(LabelStmt *Label, SourceLocation Loc,
870*67e74705SXin Li CXTranslationUnit TU) {
871*67e74705SXin Li
872*67e74705SXin Li assert(Label && TU && "Invalid arguments!");
873*67e74705SXin Li void *RawLoc = Loc.getPtrEncoding();
874*67e74705SXin Li CXCursor C = { CXCursor_LabelRef, 0, { Label, RawLoc, TU } };
875*67e74705SXin Li return C;
876*67e74705SXin Li }
877*67e74705SXin Li
878*67e74705SXin Li std::pair<const LabelStmt *, SourceLocation>
getCursorLabelRef(CXCursor C)879*67e74705SXin Li cxcursor::getCursorLabelRef(CXCursor C) {
880*67e74705SXin Li assert(C.kind == CXCursor_LabelRef);
881*67e74705SXin Li return std::make_pair(static_cast<const LabelStmt *>(C.data[0]),
882*67e74705SXin Li SourceLocation::getFromPtrEncoding(C.data[1]));
883*67e74705SXin Li }
884*67e74705SXin Li
MakeCursorOverloadedDeclRef(const OverloadExpr * E,CXTranslationUnit TU)885*67e74705SXin Li CXCursor cxcursor::MakeCursorOverloadedDeclRef(const OverloadExpr *E,
886*67e74705SXin Li CXTranslationUnit TU) {
887*67e74705SXin Li assert(E && TU && "Invalid arguments!");
888*67e74705SXin Li OverloadedDeclRefStorage Storage(E);
889*67e74705SXin Li void *RawLoc = E->getNameLoc().getPtrEncoding();
890*67e74705SXin Li CXCursor C = {
891*67e74705SXin Li CXCursor_OverloadedDeclRef, 0,
892*67e74705SXin Li { Storage.getOpaqueValue(), RawLoc, TU }
893*67e74705SXin Li };
894*67e74705SXin Li return C;
895*67e74705SXin Li }
896*67e74705SXin Li
MakeCursorOverloadedDeclRef(const Decl * D,SourceLocation Loc,CXTranslationUnit TU)897*67e74705SXin Li CXCursor cxcursor::MakeCursorOverloadedDeclRef(const Decl *D,
898*67e74705SXin Li SourceLocation Loc,
899*67e74705SXin Li CXTranslationUnit TU) {
900*67e74705SXin Li assert(D && TU && "Invalid arguments!");
901*67e74705SXin Li void *RawLoc = Loc.getPtrEncoding();
902*67e74705SXin Li OverloadedDeclRefStorage Storage(D);
903*67e74705SXin Li CXCursor C = {
904*67e74705SXin Li CXCursor_OverloadedDeclRef, 0,
905*67e74705SXin Li { Storage.getOpaqueValue(), RawLoc, TU }
906*67e74705SXin Li };
907*67e74705SXin Li return C;
908*67e74705SXin Li }
909*67e74705SXin Li
MakeCursorOverloadedDeclRef(TemplateName Name,SourceLocation Loc,CXTranslationUnit TU)910*67e74705SXin Li CXCursor cxcursor::MakeCursorOverloadedDeclRef(TemplateName Name,
911*67e74705SXin Li SourceLocation Loc,
912*67e74705SXin Li CXTranslationUnit TU) {
913*67e74705SXin Li assert(Name.getAsOverloadedTemplate() && TU && "Invalid arguments!");
914*67e74705SXin Li void *RawLoc = Loc.getPtrEncoding();
915*67e74705SXin Li OverloadedDeclRefStorage Storage(Name.getAsOverloadedTemplate());
916*67e74705SXin Li CXCursor C = {
917*67e74705SXin Li CXCursor_OverloadedDeclRef, 0,
918*67e74705SXin Li { Storage.getOpaqueValue(), RawLoc, TU }
919*67e74705SXin Li };
920*67e74705SXin Li return C;
921*67e74705SXin Li }
922*67e74705SXin Li
923*67e74705SXin Li std::pair<cxcursor::OverloadedDeclRefStorage, SourceLocation>
getCursorOverloadedDeclRef(CXCursor C)924*67e74705SXin Li cxcursor::getCursorOverloadedDeclRef(CXCursor C) {
925*67e74705SXin Li assert(C.kind == CXCursor_OverloadedDeclRef);
926*67e74705SXin Li return std::make_pair(OverloadedDeclRefStorage::getFromOpaqueValue(
927*67e74705SXin Li const_cast<void *>(C.data[0])),
928*67e74705SXin Li SourceLocation::getFromPtrEncoding(C.data[1]));
929*67e74705SXin Li }
930*67e74705SXin Li
getCursorDecl(CXCursor Cursor)931*67e74705SXin Li const Decl *cxcursor::getCursorDecl(CXCursor Cursor) {
932*67e74705SXin Li return static_cast<const Decl *>(Cursor.data[0]);
933*67e74705SXin Li }
934*67e74705SXin Li
getCursorExpr(CXCursor Cursor)935*67e74705SXin Li const Expr *cxcursor::getCursorExpr(CXCursor Cursor) {
936*67e74705SXin Li return dyn_cast_or_null<Expr>(getCursorStmt(Cursor));
937*67e74705SXin Li }
938*67e74705SXin Li
getCursorStmt(CXCursor Cursor)939*67e74705SXin Li const Stmt *cxcursor::getCursorStmt(CXCursor Cursor) {
940*67e74705SXin Li if (Cursor.kind == CXCursor_ObjCSuperClassRef ||
941*67e74705SXin Li Cursor.kind == CXCursor_ObjCProtocolRef ||
942*67e74705SXin Li Cursor.kind == CXCursor_ObjCClassRef)
943*67e74705SXin Li return nullptr;
944*67e74705SXin Li
945*67e74705SXin Li return static_cast<const Stmt *>(Cursor.data[1]);
946*67e74705SXin Li }
947*67e74705SXin Li
getCursorAttr(CXCursor Cursor)948*67e74705SXin Li const Attr *cxcursor::getCursorAttr(CXCursor Cursor) {
949*67e74705SXin Li return static_cast<const Attr *>(Cursor.data[1]);
950*67e74705SXin Li }
951*67e74705SXin Li
getCursorParentDecl(CXCursor Cursor)952*67e74705SXin Li const Decl *cxcursor::getCursorParentDecl(CXCursor Cursor) {
953*67e74705SXin Li return static_cast<const Decl *>(Cursor.data[0]);
954*67e74705SXin Li }
955*67e74705SXin Li
getCursorContext(CXCursor Cursor)956*67e74705SXin Li ASTContext &cxcursor::getCursorContext(CXCursor Cursor) {
957*67e74705SXin Li return getCursorASTUnit(Cursor)->getASTContext();
958*67e74705SXin Li }
959*67e74705SXin Li
getCursorASTUnit(CXCursor Cursor)960*67e74705SXin Li ASTUnit *cxcursor::getCursorASTUnit(CXCursor Cursor) {
961*67e74705SXin Li CXTranslationUnit TU = getCursorTU(Cursor);
962*67e74705SXin Li if (!TU)
963*67e74705SXin Li return nullptr;
964*67e74705SXin Li return cxtu::getASTUnit(TU);
965*67e74705SXin Li }
966*67e74705SXin Li
getCursorTU(CXCursor Cursor)967*67e74705SXin Li CXTranslationUnit cxcursor::getCursorTU(CXCursor Cursor) {
968*67e74705SXin Li return static_cast<CXTranslationUnit>(const_cast<void*>(Cursor.data[2]));
969*67e74705SXin Li }
970*67e74705SXin Li
getOverriddenCursors(CXCursor cursor,SmallVectorImpl<CXCursor> & overridden)971*67e74705SXin Li void cxcursor::getOverriddenCursors(CXCursor cursor,
972*67e74705SXin Li SmallVectorImpl<CXCursor> &overridden) {
973*67e74705SXin Li assert(clang_isDeclaration(cursor.kind));
974*67e74705SXin Li const NamedDecl *D = dyn_cast_or_null<NamedDecl>(getCursorDecl(cursor));
975*67e74705SXin Li if (!D)
976*67e74705SXin Li return;
977*67e74705SXin Li
978*67e74705SXin Li CXTranslationUnit TU = getCursorTU(cursor);
979*67e74705SXin Li SmallVector<const NamedDecl *, 8> OverDecls;
980*67e74705SXin Li D->getASTContext().getOverriddenMethods(D, OverDecls);
981*67e74705SXin Li
982*67e74705SXin Li for (SmallVectorImpl<const NamedDecl *>::iterator
983*67e74705SXin Li I = OverDecls.begin(), E = OverDecls.end(); I != E; ++I) {
984*67e74705SXin Li overridden.push_back(MakeCXCursor(*I, TU));
985*67e74705SXin Li }
986*67e74705SXin Li }
987*67e74705SXin Li
988*67e74705SXin Li std::pair<int, SourceLocation>
getSelectorIdentifierIndexAndLoc(CXCursor cursor)989*67e74705SXin Li cxcursor::getSelectorIdentifierIndexAndLoc(CXCursor cursor) {
990*67e74705SXin Li if (cursor.kind == CXCursor_ObjCMessageExpr) {
991*67e74705SXin Li if (cursor.xdata != -1)
992*67e74705SXin Li return std::make_pair(cursor.xdata,
993*67e74705SXin Li cast<ObjCMessageExpr>(getCursorExpr(cursor))
994*67e74705SXin Li ->getSelectorLoc(cursor.xdata));
995*67e74705SXin Li } else if (cursor.kind == CXCursor_ObjCClassMethodDecl ||
996*67e74705SXin Li cursor.kind == CXCursor_ObjCInstanceMethodDecl) {
997*67e74705SXin Li if (cursor.xdata != -1)
998*67e74705SXin Li return std::make_pair(cursor.xdata,
999*67e74705SXin Li cast<ObjCMethodDecl>(getCursorDecl(cursor))
1000*67e74705SXin Li ->getSelectorLoc(cursor.xdata));
1001*67e74705SXin Li }
1002*67e74705SXin Li
1003*67e74705SXin Li return std::make_pair(-1, SourceLocation());
1004*67e74705SXin Li }
1005*67e74705SXin Li
getSelectorIdentifierCursor(int SelIdx,CXCursor cursor)1006*67e74705SXin Li CXCursor cxcursor::getSelectorIdentifierCursor(int SelIdx, CXCursor cursor) {
1007*67e74705SXin Li CXCursor newCursor = cursor;
1008*67e74705SXin Li
1009*67e74705SXin Li if (cursor.kind == CXCursor_ObjCMessageExpr) {
1010*67e74705SXin Li if (SelIdx == -1 ||
1011*67e74705SXin Li unsigned(SelIdx) >= cast<ObjCMessageExpr>(getCursorExpr(cursor))
1012*67e74705SXin Li ->getNumSelectorLocs())
1013*67e74705SXin Li newCursor.xdata = -1;
1014*67e74705SXin Li else
1015*67e74705SXin Li newCursor.xdata = SelIdx;
1016*67e74705SXin Li } else if (cursor.kind == CXCursor_ObjCClassMethodDecl ||
1017*67e74705SXin Li cursor.kind == CXCursor_ObjCInstanceMethodDecl) {
1018*67e74705SXin Li if (SelIdx == -1 ||
1019*67e74705SXin Li unsigned(SelIdx) >= cast<ObjCMethodDecl>(getCursorDecl(cursor))
1020*67e74705SXin Li ->getNumSelectorLocs())
1021*67e74705SXin Li newCursor.xdata = -1;
1022*67e74705SXin Li else
1023*67e74705SXin Li newCursor.xdata = SelIdx;
1024*67e74705SXin Li }
1025*67e74705SXin Li
1026*67e74705SXin Li return newCursor;
1027*67e74705SXin Li }
1028*67e74705SXin Li
getTypeRefCursor(CXCursor cursor)1029*67e74705SXin Li CXCursor cxcursor::getTypeRefCursor(CXCursor cursor) {
1030*67e74705SXin Li if (cursor.kind != CXCursor_CallExpr)
1031*67e74705SXin Li return cursor;
1032*67e74705SXin Li
1033*67e74705SXin Li if (cursor.xdata == 0)
1034*67e74705SXin Li return cursor;
1035*67e74705SXin Li
1036*67e74705SXin Li const Expr *E = getCursorExpr(cursor);
1037*67e74705SXin Li TypeSourceInfo *Type = nullptr;
1038*67e74705SXin Li if (const CXXUnresolvedConstructExpr *
1039*67e74705SXin Li UnCtor = dyn_cast<CXXUnresolvedConstructExpr>(E)) {
1040*67e74705SXin Li Type = UnCtor->getTypeSourceInfo();
1041*67e74705SXin Li } else if (const CXXTemporaryObjectExpr *Tmp =
1042*67e74705SXin Li dyn_cast<CXXTemporaryObjectExpr>(E)){
1043*67e74705SXin Li Type = Tmp->getTypeSourceInfo();
1044*67e74705SXin Li }
1045*67e74705SXin Li
1046*67e74705SXin Li if (!Type)
1047*67e74705SXin Li return cursor;
1048*67e74705SXin Li
1049*67e74705SXin Li CXTranslationUnit TU = getCursorTU(cursor);
1050*67e74705SXin Li QualType Ty = Type->getType();
1051*67e74705SXin Li TypeLoc TL = Type->getTypeLoc();
1052*67e74705SXin Li SourceLocation Loc = TL.getBeginLoc();
1053*67e74705SXin Li
1054*67e74705SXin Li if (const ElaboratedType *ElabT = Ty->getAs<ElaboratedType>()) {
1055*67e74705SXin Li Ty = ElabT->getNamedType();
1056*67e74705SXin Li ElaboratedTypeLoc ElabTL = TL.castAs<ElaboratedTypeLoc>();
1057*67e74705SXin Li Loc = ElabTL.getNamedTypeLoc().getBeginLoc();
1058*67e74705SXin Li }
1059*67e74705SXin Li
1060*67e74705SXin Li if (const TypedefType *Typedef = Ty->getAs<TypedefType>())
1061*67e74705SXin Li return MakeCursorTypeRef(Typedef->getDecl(), Loc, TU);
1062*67e74705SXin Li if (const TagType *Tag = Ty->getAs<TagType>())
1063*67e74705SXin Li return MakeCursorTypeRef(Tag->getDecl(), Loc, TU);
1064*67e74705SXin Li if (const TemplateTypeParmType *TemplP = Ty->getAs<TemplateTypeParmType>())
1065*67e74705SXin Li return MakeCursorTypeRef(TemplP->getDecl(), Loc, TU);
1066*67e74705SXin Li
1067*67e74705SXin Li return cursor;
1068*67e74705SXin Li }
1069*67e74705SXin Li
operator ==(CXCursor X,CXCursor Y)1070*67e74705SXin Li bool cxcursor::operator==(CXCursor X, CXCursor Y) {
1071*67e74705SXin Li return X.kind == Y.kind && X.data[0] == Y.data[0] && X.data[1] == Y.data[1] &&
1072*67e74705SXin Li X.data[2] == Y.data[2];
1073*67e74705SXin Li }
1074*67e74705SXin Li
1075*67e74705SXin Li // FIXME: Remove once we can model DeclGroups and their appropriate ranges
1076*67e74705SXin Li // properly in the ASTs.
isFirstInDeclGroup(CXCursor C)1077*67e74705SXin Li bool cxcursor::isFirstInDeclGroup(CXCursor C) {
1078*67e74705SXin Li assert(clang_isDeclaration(C.kind));
1079*67e74705SXin Li return ((uintptr_t) (C.data[1])) != 0;
1080*67e74705SXin Li }
1081*67e74705SXin Li
1082*67e74705SXin Li //===----------------------------------------------------------------------===//
1083*67e74705SXin Li // libclang CXCursor APIs
1084*67e74705SXin Li //===----------------------------------------------------------------------===//
1085*67e74705SXin Li
1086*67e74705SXin Li extern "C" {
1087*67e74705SXin Li
clang_Cursor_isNull(CXCursor cursor)1088*67e74705SXin Li int clang_Cursor_isNull(CXCursor cursor) {
1089*67e74705SXin Li return clang_equalCursors(cursor, clang_getNullCursor());
1090*67e74705SXin Li }
1091*67e74705SXin Li
clang_Cursor_getTranslationUnit(CXCursor cursor)1092*67e74705SXin Li CXTranslationUnit clang_Cursor_getTranslationUnit(CXCursor cursor) {
1093*67e74705SXin Li return getCursorTU(cursor);
1094*67e74705SXin Li }
1095*67e74705SXin Li
clang_Cursor_getNumArguments(CXCursor C)1096*67e74705SXin Li int clang_Cursor_getNumArguments(CXCursor C) {
1097*67e74705SXin Li if (clang_isDeclaration(C.kind)) {
1098*67e74705SXin Li const Decl *D = cxcursor::getCursorDecl(C);
1099*67e74705SXin Li if (const ObjCMethodDecl *MD = dyn_cast_or_null<ObjCMethodDecl>(D))
1100*67e74705SXin Li return MD->param_size();
1101*67e74705SXin Li if (const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(D))
1102*67e74705SXin Li return FD->param_size();
1103*67e74705SXin Li }
1104*67e74705SXin Li
1105*67e74705SXin Li if (clang_isExpression(C.kind)) {
1106*67e74705SXin Li const Expr *E = cxcursor::getCursorExpr(C);
1107*67e74705SXin Li if (const CallExpr *CE = dyn_cast<CallExpr>(E)) {
1108*67e74705SXin Li return CE->getNumArgs();
1109*67e74705SXin Li }
1110*67e74705SXin Li }
1111*67e74705SXin Li
1112*67e74705SXin Li return -1;
1113*67e74705SXin Li }
1114*67e74705SXin Li
clang_Cursor_getArgument(CXCursor C,unsigned i)1115*67e74705SXin Li CXCursor clang_Cursor_getArgument(CXCursor C, unsigned i) {
1116*67e74705SXin Li if (clang_isDeclaration(C.kind)) {
1117*67e74705SXin Li const Decl *D = cxcursor::getCursorDecl(C);
1118*67e74705SXin Li if (const ObjCMethodDecl *MD = dyn_cast_or_null<ObjCMethodDecl>(D)) {
1119*67e74705SXin Li if (i < MD->param_size())
1120*67e74705SXin Li return cxcursor::MakeCXCursor(MD->parameters()[i],
1121*67e74705SXin Li cxcursor::getCursorTU(C));
1122*67e74705SXin Li } else if (const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(D)) {
1123*67e74705SXin Li if (i < FD->param_size())
1124*67e74705SXin Li return cxcursor::MakeCXCursor(FD->parameters()[i],
1125*67e74705SXin Li cxcursor::getCursorTU(C));
1126*67e74705SXin Li }
1127*67e74705SXin Li }
1128*67e74705SXin Li
1129*67e74705SXin Li if (clang_isExpression(C.kind)) {
1130*67e74705SXin Li const Expr *E = cxcursor::getCursorExpr(C);
1131*67e74705SXin Li if (const CallExpr *CE = dyn_cast<CallExpr>(E)) {
1132*67e74705SXin Li if (i < CE->getNumArgs()) {
1133*67e74705SXin Li return cxcursor::MakeCXCursor(CE->getArg(i),
1134*67e74705SXin Li getCursorDecl(C),
1135*67e74705SXin Li cxcursor::getCursorTU(C));
1136*67e74705SXin Li }
1137*67e74705SXin Li }
1138*67e74705SXin Li }
1139*67e74705SXin Li
1140*67e74705SXin Li return clang_getNullCursor();
1141*67e74705SXin Li }
1142*67e74705SXin Li
clang_Cursor_getNumTemplateArguments(CXCursor C)1143*67e74705SXin Li int clang_Cursor_getNumTemplateArguments(CXCursor C) {
1144*67e74705SXin Li if (clang_getCursorKind(C) != CXCursor_FunctionDecl) {
1145*67e74705SXin Li return -1;
1146*67e74705SXin Li }
1147*67e74705SXin Li
1148*67e74705SXin Li const FunctionDecl *FD = llvm::dyn_cast_or_null<clang::FunctionDecl>(
1149*67e74705SXin Li getCursorDecl(C));
1150*67e74705SXin Li if (!FD) {
1151*67e74705SXin Li return -1;
1152*67e74705SXin Li }
1153*67e74705SXin Li
1154*67e74705SXin Li const FunctionTemplateSpecializationInfo* SpecInfo =
1155*67e74705SXin Li FD->getTemplateSpecializationInfo();
1156*67e74705SXin Li if (!SpecInfo) {
1157*67e74705SXin Li return -1;
1158*67e74705SXin Li }
1159*67e74705SXin Li
1160*67e74705SXin Li return SpecInfo->TemplateArguments->size();
1161*67e74705SXin Li }
1162*67e74705SXin Li
1163*67e74705SXin Li enum CXGetTemplateArgumentStatus {
1164*67e74705SXin Li /** \brief The operation completed successfully */
1165*67e74705SXin Li CXGetTemplateArgumentStatus_Success = 0,
1166*67e74705SXin Li
1167*67e74705SXin Li /** \brief The specified cursor did not represent a FunctionDecl. */
1168*67e74705SXin Li CXGetTemplateArgumentStatus_CursorNotFunctionDecl = -1,
1169*67e74705SXin Li
1170*67e74705SXin Li /** \brief The specified cursor was not castable to a FunctionDecl. */
1171*67e74705SXin Li CXGetTemplateArgumentStatus_BadFunctionDeclCast = -2,
1172*67e74705SXin Li
1173*67e74705SXin Li /** \brief A NULL FunctionTemplateSpecializationInfo was retrieved. */
1174*67e74705SXin Li CXGetTemplateArgumentStatus_NullTemplSpecInfo = -3,
1175*67e74705SXin Li
1176*67e74705SXin Li /** \brief An invalid (OOB) argument index was specified */
1177*67e74705SXin Li CXGetTemplateArgumentStatus_InvalidIndex = -4
1178*67e74705SXin Li };
1179*67e74705SXin Li
clang_Cursor_getTemplateArgument(CXCursor C,unsigned I,TemplateArgument * TA)1180*67e74705SXin Li static int clang_Cursor_getTemplateArgument(
1181*67e74705SXin Li CXCursor C, unsigned I, TemplateArgument *TA) {
1182*67e74705SXin Li if (clang_getCursorKind(C) != CXCursor_FunctionDecl) {
1183*67e74705SXin Li return CXGetTemplateArgumentStatus_CursorNotFunctionDecl;
1184*67e74705SXin Li }
1185*67e74705SXin Li
1186*67e74705SXin Li const FunctionDecl *FD = llvm::dyn_cast_or_null<clang::FunctionDecl>(
1187*67e74705SXin Li getCursorDecl(C));
1188*67e74705SXin Li if (!FD) {
1189*67e74705SXin Li return CXGetTemplateArgumentStatus_BadFunctionDeclCast;
1190*67e74705SXin Li }
1191*67e74705SXin Li
1192*67e74705SXin Li const FunctionTemplateSpecializationInfo* SpecInfo =
1193*67e74705SXin Li FD->getTemplateSpecializationInfo();
1194*67e74705SXin Li if (!SpecInfo) {
1195*67e74705SXin Li return CXGetTemplateArgumentStatus_NullTemplSpecInfo;
1196*67e74705SXin Li }
1197*67e74705SXin Li
1198*67e74705SXin Li if (I >= SpecInfo->TemplateArguments->size()) {
1199*67e74705SXin Li return CXGetTemplateArgumentStatus_InvalidIndex;
1200*67e74705SXin Li }
1201*67e74705SXin Li
1202*67e74705SXin Li *TA = SpecInfo->TemplateArguments->get(I);
1203*67e74705SXin Li return 0;
1204*67e74705SXin Li }
1205*67e74705SXin Li
clang_Cursor_getTemplateArgumentKind(CXCursor C,unsigned I)1206*67e74705SXin Li enum CXTemplateArgumentKind clang_Cursor_getTemplateArgumentKind(CXCursor C,
1207*67e74705SXin Li unsigned I) {
1208*67e74705SXin Li TemplateArgument TA;
1209*67e74705SXin Li if (clang_Cursor_getTemplateArgument(C, I, &TA)) {
1210*67e74705SXin Li return CXTemplateArgumentKind_Invalid;
1211*67e74705SXin Li }
1212*67e74705SXin Li
1213*67e74705SXin Li switch (TA.getKind()) {
1214*67e74705SXin Li case TemplateArgument::Null: return CXTemplateArgumentKind_Null;
1215*67e74705SXin Li case TemplateArgument::Type: return CXTemplateArgumentKind_Type;
1216*67e74705SXin Li case TemplateArgument::Declaration:
1217*67e74705SXin Li return CXTemplateArgumentKind_Declaration;
1218*67e74705SXin Li case TemplateArgument::NullPtr: return CXTemplateArgumentKind_NullPtr;
1219*67e74705SXin Li case TemplateArgument::Integral: return CXTemplateArgumentKind_Integral;
1220*67e74705SXin Li case TemplateArgument::Template: return CXTemplateArgumentKind_Template;
1221*67e74705SXin Li case TemplateArgument::TemplateExpansion:
1222*67e74705SXin Li return CXTemplateArgumentKind_TemplateExpansion;
1223*67e74705SXin Li case TemplateArgument::Expression: return CXTemplateArgumentKind_Expression;
1224*67e74705SXin Li case TemplateArgument::Pack: return CXTemplateArgumentKind_Pack;
1225*67e74705SXin Li }
1226*67e74705SXin Li
1227*67e74705SXin Li return CXTemplateArgumentKind_Invalid;
1228*67e74705SXin Li }
1229*67e74705SXin Li
clang_Cursor_getTemplateArgumentType(CXCursor C,unsigned I)1230*67e74705SXin Li CXType clang_Cursor_getTemplateArgumentType(CXCursor C, unsigned I) {
1231*67e74705SXin Li TemplateArgument TA;
1232*67e74705SXin Li if (clang_Cursor_getTemplateArgument(C, I, &TA) !=
1233*67e74705SXin Li CXGetTemplateArgumentStatus_Success) {
1234*67e74705SXin Li return cxtype::MakeCXType(QualType(), getCursorTU(C));
1235*67e74705SXin Li }
1236*67e74705SXin Li
1237*67e74705SXin Li if (TA.getKind() != TemplateArgument::Type) {
1238*67e74705SXin Li return cxtype::MakeCXType(QualType(), getCursorTU(C));
1239*67e74705SXin Li }
1240*67e74705SXin Li
1241*67e74705SXin Li return cxtype::MakeCXType(TA.getAsType(), getCursorTU(C));
1242*67e74705SXin Li }
1243*67e74705SXin Li
clang_Cursor_getTemplateArgumentValue(CXCursor C,unsigned I)1244*67e74705SXin Li long long clang_Cursor_getTemplateArgumentValue(CXCursor C, unsigned I) {
1245*67e74705SXin Li TemplateArgument TA;
1246*67e74705SXin Li if (clang_Cursor_getTemplateArgument(C, I, &TA) !=
1247*67e74705SXin Li CXGetTemplateArgumentStatus_Success) {
1248*67e74705SXin Li assert(0 && "Unable to retrieve TemplateArgument");
1249*67e74705SXin Li return 0;
1250*67e74705SXin Li }
1251*67e74705SXin Li
1252*67e74705SXin Li if (TA.getKind() != TemplateArgument::Integral) {
1253*67e74705SXin Li assert(0 && "Passed template argument is not Integral");
1254*67e74705SXin Li return 0;
1255*67e74705SXin Li }
1256*67e74705SXin Li
1257*67e74705SXin Li return TA.getAsIntegral().getSExtValue();
1258*67e74705SXin Li }
1259*67e74705SXin Li
clang_Cursor_getTemplateArgumentUnsignedValue(CXCursor C,unsigned I)1260*67e74705SXin Li unsigned long long clang_Cursor_getTemplateArgumentUnsignedValue(CXCursor C,
1261*67e74705SXin Li unsigned I) {
1262*67e74705SXin Li TemplateArgument TA;
1263*67e74705SXin Li if (clang_Cursor_getTemplateArgument(C, I, &TA) !=
1264*67e74705SXin Li CXGetTemplateArgumentStatus_Success) {
1265*67e74705SXin Li assert(0 && "Unable to retrieve TemplateArgument");
1266*67e74705SXin Li return 0;
1267*67e74705SXin Li }
1268*67e74705SXin Li
1269*67e74705SXin Li if (TA.getKind() != TemplateArgument::Integral) {
1270*67e74705SXin Li assert(0 && "Passed template argument is not Integral");
1271*67e74705SXin Li return 0;
1272*67e74705SXin Li }
1273*67e74705SXin Li
1274*67e74705SXin Li return TA.getAsIntegral().getZExtValue();
1275*67e74705SXin Li }
1276*67e74705SXin Li
1277*67e74705SXin Li } // end: extern "C"
1278*67e74705SXin Li
1279*67e74705SXin Li //===----------------------------------------------------------------------===//
1280*67e74705SXin Li // CXCursorSet.
1281*67e74705SXin Li //===----------------------------------------------------------------------===//
1282*67e74705SXin Li
1283*67e74705SXin Li typedef llvm::DenseMap<CXCursor, unsigned> CXCursorSet_Impl;
1284*67e74705SXin Li
packCXCursorSet(CXCursorSet_Impl * setImpl)1285*67e74705SXin Li static inline CXCursorSet packCXCursorSet(CXCursorSet_Impl *setImpl) {
1286*67e74705SXin Li return (CXCursorSet) setImpl;
1287*67e74705SXin Li }
unpackCXCursorSet(CXCursorSet set)1288*67e74705SXin Li static inline CXCursorSet_Impl *unpackCXCursorSet(CXCursorSet set) {
1289*67e74705SXin Li return (CXCursorSet_Impl*) set;
1290*67e74705SXin Li }
1291*67e74705SXin Li namespace llvm {
1292*67e74705SXin Li template<> struct DenseMapInfo<CXCursor> {
1293*67e74705SXin Li public:
getEmptyKeyllvm::DenseMapInfo1294*67e74705SXin Li static inline CXCursor getEmptyKey() {
1295*67e74705SXin Li return MakeCXCursorInvalid(CXCursor_InvalidFile);
1296*67e74705SXin Li }
getTombstoneKeyllvm::DenseMapInfo1297*67e74705SXin Li static inline CXCursor getTombstoneKey() {
1298*67e74705SXin Li return MakeCXCursorInvalid(CXCursor_NoDeclFound);
1299*67e74705SXin Li }
getHashValuellvm::DenseMapInfo1300*67e74705SXin Li static inline unsigned getHashValue(const CXCursor &cursor) {
1301*67e74705SXin Li return llvm::DenseMapInfo<std::pair<const void *, const void *> >
1302*67e74705SXin Li ::getHashValue(std::make_pair(cursor.data[0], cursor.data[1]));
1303*67e74705SXin Li }
isEqualllvm::DenseMapInfo1304*67e74705SXin Li static inline bool isEqual(const CXCursor &x, const CXCursor &y) {
1305*67e74705SXin Li return x.kind == y.kind &&
1306*67e74705SXin Li x.data[0] == y.data[0] &&
1307*67e74705SXin Li x.data[1] == y.data[1];
1308*67e74705SXin Li }
1309*67e74705SXin Li };
1310*67e74705SXin Li }
1311*67e74705SXin Li
1312*67e74705SXin Li extern "C" {
clang_createCXCursorSet()1313*67e74705SXin Li CXCursorSet clang_createCXCursorSet() {
1314*67e74705SXin Li return packCXCursorSet(new CXCursorSet_Impl());
1315*67e74705SXin Li }
1316*67e74705SXin Li
clang_disposeCXCursorSet(CXCursorSet set)1317*67e74705SXin Li void clang_disposeCXCursorSet(CXCursorSet set) {
1318*67e74705SXin Li delete unpackCXCursorSet(set);
1319*67e74705SXin Li }
1320*67e74705SXin Li
clang_CXCursorSet_contains(CXCursorSet set,CXCursor cursor)1321*67e74705SXin Li unsigned clang_CXCursorSet_contains(CXCursorSet set, CXCursor cursor) {
1322*67e74705SXin Li CXCursorSet_Impl *setImpl = unpackCXCursorSet(set);
1323*67e74705SXin Li if (!setImpl)
1324*67e74705SXin Li return 0;
1325*67e74705SXin Li return setImpl->find(cursor) != setImpl->end();
1326*67e74705SXin Li }
1327*67e74705SXin Li
clang_CXCursorSet_insert(CXCursorSet set,CXCursor cursor)1328*67e74705SXin Li unsigned clang_CXCursorSet_insert(CXCursorSet set, CXCursor cursor) {
1329*67e74705SXin Li // Do not insert invalid cursors into the set.
1330*67e74705SXin Li if (cursor.kind >= CXCursor_FirstInvalid &&
1331*67e74705SXin Li cursor.kind <= CXCursor_LastInvalid)
1332*67e74705SXin Li return 1;
1333*67e74705SXin Li
1334*67e74705SXin Li CXCursorSet_Impl *setImpl = unpackCXCursorSet(set);
1335*67e74705SXin Li if (!setImpl)
1336*67e74705SXin Li return 1;
1337*67e74705SXin Li unsigned &entry = (*setImpl)[cursor];
1338*67e74705SXin Li unsigned flag = entry == 0 ? 1 : 0;
1339*67e74705SXin Li entry = 1;
1340*67e74705SXin Li return flag;
1341*67e74705SXin Li }
1342*67e74705SXin Li
clang_getCursorCompletionString(CXCursor cursor)1343*67e74705SXin Li CXCompletionString clang_getCursorCompletionString(CXCursor cursor) {
1344*67e74705SXin Li enum CXCursorKind kind = clang_getCursorKind(cursor);
1345*67e74705SXin Li if (clang_isDeclaration(kind)) {
1346*67e74705SXin Li const Decl *decl = getCursorDecl(cursor);
1347*67e74705SXin Li if (const NamedDecl *namedDecl = dyn_cast_or_null<NamedDecl>(decl)) {
1348*67e74705SXin Li ASTUnit *unit = getCursorASTUnit(cursor);
1349*67e74705SXin Li CodeCompletionResult Result(namedDecl, CCP_Declaration);
1350*67e74705SXin Li CodeCompletionString *String
1351*67e74705SXin Li = Result.CreateCodeCompletionString(unit->getASTContext(),
1352*67e74705SXin Li unit->getPreprocessor(),
1353*67e74705SXin Li CodeCompletionContext::CCC_Other,
1354*67e74705SXin Li unit->getCodeCompletionTUInfo().getAllocator(),
1355*67e74705SXin Li unit->getCodeCompletionTUInfo(),
1356*67e74705SXin Li true);
1357*67e74705SXin Li return String;
1358*67e74705SXin Li }
1359*67e74705SXin Li } else if (kind == CXCursor_MacroDefinition) {
1360*67e74705SXin Li const MacroDefinitionRecord *definition = getCursorMacroDefinition(cursor);
1361*67e74705SXin Li const IdentifierInfo *MacroInfo = definition->getName();
1362*67e74705SXin Li ASTUnit *unit = getCursorASTUnit(cursor);
1363*67e74705SXin Li CodeCompletionResult Result(MacroInfo);
1364*67e74705SXin Li CodeCompletionString *String
1365*67e74705SXin Li = Result.CreateCodeCompletionString(unit->getASTContext(),
1366*67e74705SXin Li unit->getPreprocessor(),
1367*67e74705SXin Li CodeCompletionContext::CCC_Other,
1368*67e74705SXin Li unit->getCodeCompletionTUInfo().getAllocator(),
1369*67e74705SXin Li unit->getCodeCompletionTUInfo(),
1370*67e74705SXin Li false);
1371*67e74705SXin Li return String;
1372*67e74705SXin Li }
1373*67e74705SXin Li return nullptr;
1374*67e74705SXin Li }
1375*67e74705SXin Li } // end: extern C.
1376*67e74705SXin Li
1377*67e74705SXin Li namespace {
1378*67e74705SXin Li struct OverridenCursorsPool {
1379*67e74705SXin Li typedef SmallVector<CXCursor, 2> CursorVec;
1380*67e74705SXin Li std::vector<CursorVec*> AllCursors;
1381*67e74705SXin Li std::vector<CursorVec*> AvailableCursors;
1382*67e74705SXin Li
~OverridenCursorsPool__anon17938eb00111::OverridenCursorsPool1383*67e74705SXin Li ~OverridenCursorsPool() {
1384*67e74705SXin Li for (std::vector<CursorVec*>::iterator I = AllCursors.begin(),
1385*67e74705SXin Li E = AllCursors.end(); I != E; ++I) {
1386*67e74705SXin Li delete *I;
1387*67e74705SXin Li }
1388*67e74705SXin Li }
1389*67e74705SXin Li };
1390*67e74705SXin Li }
1391*67e74705SXin Li
createOverridenCXCursorsPool()1392*67e74705SXin Li void *cxcursor::createOverridenCXCursorsPool() {
1393*67e74705SXin Li return new OverridenCursorsPool();
1394*67e74705SXin Li }
1395*67e74705SXin Li
disposeOverridenCXCursorsPool(void * pool)1396*67e74705SXin Li void cxcursor::disposeOverridenCXCursorsPool(void *pool) {
1397*67e74705SXin Li delete static_cast<OverridenCursorsPool*>(pool);
1398*67e74705SXin Li }
1399*67e74705SXin Li
1400*67e74705SXin Li extern "C" {
clang_getOverriddenCursors(CXCursor cursor,CXCursor ** overridden,unsigned * num_overridden)1401*67e74705SXin Li void clang_getOverriddenCursors(CXCursor cursor,
1402*67e74705SXin Li CXCursor **overridden,
1403*67e74705SXin Li unsigned *num_overridden) {
1404*67e74705SXin Li if (overridden)
1405*67e74705SXin Li *overridden = nullptr;
1406*67e74705SXin Li if (num_overridden)
1407*67e74705SXin Li *num_overridden = 0;
1408*67e74705SXin Li
1409*67e74705SXin Li CXTranslationUnit TU = cxcursor::getCursorTU(cursor);
1410*67e74705SXin Li
1411*67e74705SXin Li if (!overridden || !num_overridden || !TU)
1412*67e74705SXin Li return;
1413*67e74705SXin Li
1414*67e74705SXin Li if (!clang_isDeclaration(cursor.kind))
1415*67e74705SXin Li return;
1416*67e74705SXin Li
1417*67e74705SXin Li OverridenCursorsPool &pool =
1418*67e74705SXin Li *static_cast<OverridenCursorsPool*>(TU->OverridenCursorsPool);
1419*67e74705SXin Li
1420*67e74705SXin Li OverridenCursorsPool::CursorVec *Vec = nullptr;
1421*67e74705SXin Li
1422*67e74705SXin Li if (!pool.AvailableCursors.empty()) {
1423*67e74705SXin Li Vec = pool.AvailableCursors.back();
1424*67e74705SXin Li pool.AvailableCursors.pop_back();
1425*67e74705SXin Li }
1426*67e74705SXin Li else {
1427*67e74705SXin Li Vec = new OverridenCursorsPool::CursorVec();
1428*67e74705SXin Li pool.AllCursors.push_back(Vec);
1429*67e74705SXin Li }
1430*67e74705SXin Li
1431*67e74705SXin Li // Clear out the vector, but don't free the memory contents. This
1432*67e74705SXin Li // reduces malloc() traffic.
1433*67e74705SXin Li Vec->clear();
1434*67e74705SXin Li
1435*67e74705SXin Li // Use the first entry to contain a back reference to the vector.
1436*67e74705SXin Li // This is a complete hack.
1437*67e74705SXin Li CXCursor backRefCursor = MakeCXCursorInvalid(CXCursor_InvalidFile, TU);
1438*67e74705SXin Li backRefCursor.data[0] = Vec;
1439*67e74705SXin Li assert(cxcursor::getCursorTU(backRefCursor) == TU);
1440*67e74705SXin Li Vec->push_back(backRefCursor);
1441*67e74705SXin Li
1442*67e74705SXin Li // Get the overriden cursors.
1443*67e74705SXin Li cxcursor::getOverriddenCursors(cursor, *Vec);
1444*67e74705SXin Li
1445*67e74705SXin Li // Did we get any overriden cursors? If not, return Vec to the pool
1446*67e74705SXin Li // of available cursor vectors.
1447*67e74705SXin Li if (Vec->size() == 1) {
1448*67e74705SXin Li pool.AvailableCursors.push_back(Vec);
1449*67e74705SXin Li return;
1450*67e74705SXin Li }
1451*67e74705SXin Li
1452*67e74705SXin Li // Now tell the caller about the overriden cursors.
1453*67e74705SXin Li assert(Vec->size() > 1);
1454*67e74705SXin Li *overridden = &((*Vec)[1]);
1455*67e74705SXin Li *num_overridden = Vec->size() - 1;
1456*67e74705SXin Li }
1457*67e74705SXin Li
clang_disposeOverriddenCursors(CXCursor * overridden)1458*67e74705SXin Li void clang_disposeOverriddenCursors(CXCursor *overridden) {
1459*67e74705SXin Li if (!overridden)
1460*67e74705SXin Li return;
1461*67e74705SXin Li
1462*67e74705SXin Li // Use pointer arithmetic to get back the first faux entry
1463*67e74705SXin Li // which has a back-reference to the TU and the vector.
1464*67e74705SXin Li --overridden;
1465*67e74705SXin Li OverridenCursorsPool::CursorVec *Vec =
1466*67e74705SXin Li static_cast<OverridenCursorsPool::CursorVec *>(
1467*67e74705SXin Li const_cast<void *>(overridden->data[0]));
1468*67e74705SXin Li CXTranslationUnit TU = getCursorTU(*overridden);
1469*67e74705SXin Li
1470*67e74705SXin Li assert(Vec && TU);
1471*67e74705SXin Li
1472*67e74705SXin Li OverridenCursorsPool &pool =
1473*67e74705SXin Li *static_cast<OverridenCursorsPool*>(TU->OverridenCursorsPool);
1474*67e74705SXin Li
1475*67e74705SXin Li pool.AvailableCursors.push_back(Vec);
1476*67e74705SXin Li }
1477*67e74705SXin Li
clang_Cursor_isDynamicCall(CXCursor C)1478*67e74705SXin Li int clang_Cursor_isDynamicCall(CXCursor C) {
1479*67e74705SXin Li const Expr *E = nullptr;
1480*67e74705SXin Li if (clang_isExpression(C.kind))
1481*67e74705SXin Li E = getCursorExpr(C);
1482*67e74705SXin Li if (!E)
1483*67e74705SXin Li return 0;
1484*67e74705SXin Li
1485*67e74705SXin Li if (const ObjCMessageExpr *MsgE = dyn_cast<ObjCMessageExpr>(E)) {
1486*67e74705SXin Li if (MsgE->getReceiverKind() != ObjCMessageExpr::Instance)
1487*67e74705SXin Li return false;
1488*67e74705SXin Li if (auto *RecE = dyn_cast<ObjCMessageExpr>(
1489*67e74705SXin Li MsgE->getInstanceReceiver()->IgnoreParenCasts())) {
1490*67e74705SXin Li if (RecE->getMethodFamily() == OMF_alloc)
1491*67e74705SXin Li return false;
1492*67e74705SXin Li }
1493*67e74705SXin Li return true;
1494*67e74705SXin Li }
1495*67e74705SXin Li
1496*67e74705SXin Li const MemberExpr *ME = nullptr;
1497*67e74705SXin Li if (isa<MemberExpr>(E))
1498*67e74705SXin Li ME = cast<MemberExpr>(E);
1499*67e74705SXin Li else if (const CallExpr *CE = dyn_cast<CallExpr>(E))
1500*67e74705SXin Li ME = dyn_cast_or_null<MemberExpr>(CE->getCallee());
1501*67e74705SXin Li
1502*67e74705SXin Li if (ME) {
1503*67e74705SXin Li if (const CXXMethodDecl *
1504*67e74705SXin Li MD = dyn_cast_or_null<CXXMethodDecl>(ME->getMemberDecl()))
1505*67e74705SXin Li return MD->isVirtual() && !ME->hasQualifier();
1506*67e74705SXin Li }
1507*67e74705SXin Li
1508*67e74705SXin Li return 0;
1509*67e74705SXin Li }
1510*67e74705SXin Li
clang_Cursor_getReceiverType(CXCursor C)1511*67e74705SXin Li CXType clang_Cursor_getReceiverType(CXCursor C) {
1512*67e74705SXin Li CXTranslationUnit TU = cxcursor::getCursorTU(C);
1513*67e74705SXin Li const Expr *E = nullptr;
1514*67e74705SXin Li if (clang_isExpression(C.kind))
1515*67e74705SXin Li E = getCursorExpr(C);
1516*67e74705SXin Li
1517*67e74705SXin Li if (const ObjCMessageExpr *MsgE = dyn_cast_or_null<ObjCMessageExpr>(E))
1518*67e74705SXin Li return cxtype::MakeCXType(MsgE->getReceiverType(), TU);
1519*67e74705SXin Li
1520*67e74705SXin Li return cxtype::MakeCXType(QualType(), TU);
1521*67e74705SXin Li }
1522*67e74705SXin Li
1523*67e74705SXin Li } // end: extern "C"
1524