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