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