CXCursor.cpp revision 97b9872d5775446cb8aca1380e437649fe848d91
1//===- CXCursor.cpp - Routines for manipulating CXCursors -----------------===//
2//
3//                     The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file defines routines for manipulating CXCursors. It should be the
11// only file that has internal knowledge of the encoding of the data in
12// CXCursor.
13//
14//===----------------------------------------------------------------------===//
15
16#include "CXCursor.h"
17#include "clang/AST/Decl.h"
18#include "clang/AST/DeclObjC.h"
19#include "clang/AST/Expr.h"
20#include "llvm/Support/ErrorHandling.h"
21
22using namespace clang;
23
24CXCursor cxcursor::MakeCXCursor(CXCursorKind K, Decl *D) {
25  CXCursor C = { K, { D, 0, 0 } };
26  return C;
27}
28
29CXCursor cxcursor::MakeCXCursor(CXCursorKind K, Decl *D, Stmt *S,
30                                ASTContext &Context) {
31  assert(clang_isReference(K));
32  CXCursor C = { K, { D, S, &Context } };
33  return C;
34}
35
36static CXCursorKind GetCursorKind(Decl *D) {
37  switch (D->getKind()) {
38    case Decl::Enum:               return CXCursor_EnumDecl;
39    case Decl::EnumConstant:       return CXCursor_EnumConstantDecl;
40    case Decl::Field:              return CXCursor_FieldDecl;
41    case Decl::Function:
42      return CXCursor_FunctionDecl;
43    case Decl::ObjCCategory:       return CXCursor_ObjCCategoryDecl;
44    case Decl::ObjCCategoryImpl:   return CXCursor_ObjCCategoryImplDecl;
45    case Decl::ObjCClass:
46      // FIXME
47      return CXCursor_UnexposedDecl;
48    case Decl::ObjCForwardProtocol:
49      // FIXME
50      return CXCursor_UnexposedDecl;
51    case Decl::ObjCImplementation: return CXCursor_ObjCImplementationDecl;
52    case Decl::ObjCInterface:      return CXCursor_ObjCInterfaceDecl;
53    case Decl::ObjCIvar:           return CXCursor_ObjCIvarDecl;
54    case Decl::ObjCMethod:
55      return cast<ObjCMethodDecl>(D)->isInstanceMethod()
56              ? CXCursor_ObjCInstanceMethodDecl : CXCursor_ObjCClassMethodDecl;
57    case Decl::ObjCProperty:       return CXCursor_ObjCPropertyDecl;
58    case Decl::ObjCProtocol:       return CXCursor_ObjCProtocolDecl;
59    case Decl::ParmVar:            return CXCursor_ParmDecl;
60    case Decl::Typedef:            return CXCursor_TypedefDecl;
61    case Decl::Var:                return CXCursor_VarDecl;
62    default:
63      if (TagDecl *TD = dyn_cast<TagDecl>(D)) {
64        switch (TD->getTagKind()) {
65          case TagDecl::TK_struct: return CXCursor_StructDecl;
66          case TagDecl::TK_class:  return CXCursor_ClassDecl;
67          case TagDecl::TK_union:  return CXCursor_UnionDecl;
68          case TagDecl::TK_enum:   return CXCursor_EnumDecl;
69        }
70      }
71
72      return CXCursor_UnexposedDecl;
73  }
74
75  llvm_unreachable("Invalid Decl");
76  return CXCursor_NotImplemented;
77}
78
79CXCursor cxcursor::MakeCXCursor(Decl *D) {
80  return MakeCXCursor(GetCursorKind(D), D);
81}
82
83CXCursor cxcursor::MakeCXCursor(Stmt *S, Decl *Parent) {
84  CXCursorKind K = CXCursor_NotImplemented;
85
86  switch (S->getStmtClass()) {
87  case Stmt::NoStmtClass:
88    break;
89
90  case Stmt::NullStmtClass:
91  case Stmt::CompoundStmtClass:
92  case Stmt::CaseStmtClass:
93  case Stmt::DefaultStmtClass:
94  case Stmt::LabelStmtClass:
95  case Stmt::IfStmtClass:
96  case Stmt::SwitchStmtClass:
97  case Stmt::WhileStmtClass:
98  case Stmt::DoStmtClass:
99  case Stmt::ForStmtClass:
100  case Stmt::GotoStmtClass:
101  case Stmt::IndirectGotoStmtClass:
102  case Stmt::ContinueStmtClass:
103  case Stmt::BreakStmtClass:
104  case Stmt::ReturnStmtClass:
105  case Stmt::DeclStmtClass:
106  case Stmt::SwitchCaseClass:
107  case Stmt::AsmStmtClass:
108  case Stmt::ObjCAtTryStmtClass:
109  case Stmt::ObjCAtCatchStmtClass:
110  case Stmt::ObjCAtFinallyStmtClass:
111  case Stmt::ObjCAtThrowStmtClass:
112  case Stmt::ObjCAtSynchronizedStmtClass:
113  case Stmt::ObjCForCollectionStmtClass:
114  case Stmt::CXXCatchStmtClass:
115  case Stmt::CXXTryStmtClass:
116    K = CXCursor_UnexposedStmt;
117    break;
118
119  case Stmt::ExprClass:
120  case Stmt::PredefinedExprClass:
121  case Stmt::IntegerLiteralClass:
122  case Stmt::FloatingLiteralClass:
123  case Stmt::ImaginaryLiteralClass:
124  case Stmt::StringLiteralClass:
125  case Stmt::CharacterLiteralClass:
126  case Stmt::ParenExprClass:
127  case Stmt::UnaryOperatorClass:
128  case Stmt::SizeOfAlignOfExprClass:
129  case Stmt::ArraySubscriptExprClass:
130  case Stmt::CastExprClass:
131  case Stmt::BinaryOperatorClass:
132  case Stmt::CompoundAssignOperatorClass:
133  case Stmt::ConditionalOperatorClass:
134  case Stmt::ImplicitCastExprClass:
135  case Stmt::ExplicitCastExprClass:
136  case Stmt::CStyleCastExprClass:
137  case Stmt::CompoundLiteralExprClass:
138  case Stmt::ExtVectorElementExprClass:
139  case Stmt::InitListExprClass:
140  case Stmt::DesignatedInitExprClass:
141  case Stmt::ImplicitValueInitExprClass:
142  case Stmt::ParenListExprClass:
143  case Stmt::VAArgExprClass:
144  case Stmt::AddrLabelExprClass:
145  case Stmt::StmtExprClass:
146  case Stmt::TypesCompatibleExprClass:
147  case Stmt::ChooseExprClass:
148  case Stmt::GNUNullExprClass:
149  case Stmt::CXXNamedCastExprClass:
150  case Stmt::CXXStaticCastExprClass:
151  case Stmt::CXXDynamicCastExprClass:
152  case Stmt::CXXReinterpretCastExprClass:
153  case Stmt::CXXConstCastExprClass:
154  case Stmt::CXXFunctionalCastExprClass:
155  case Stmt::CXXTypeidExprClass:
156  case Stmt::CXXBoolLiteralExprClass:
157  case Stmt::CXXNullPtrLiteralExprClass:
158  case Stmt::CXXThisExprClass:
159  case Stmt::CXXThrowExprClass:
160  case Stmt::CXXDefaultArgExprClass:
161  case Stmt::CXXZeroInitValueExprClass:
162  case Stmt::CXXNewExprClass:
163  case Stmt::CXXDeleteExprClass:
164  case Stmt::CXXPseudoDestructorExprClass:
165  case Stmt::UnresolvedLookupExprClass:
166  case Stmt::UnaryTypeTraitExprClass:
167  case Stmt::DependentScopeDeclRefExprClass:
168  case Stmt::CXXBindTemporaryExprClass:
169  case Stmt::CXXExprWithTemporariesClass:
170  case Stmt::CXXUnresolvedConstructExprClass:
171  case Stmt::CXXDependentScopeMemberExprClass:
172  case Stmt::UnresolvedMemberExprClass:
173  case Stmt::ObjCStringLiteralClass:
174  case Stmt::ObjCEncodeExprClass:
175  case Stmt::ObjCSelectorExprClass:
176  case Stmt::ObjCProtocolExprClass:
177  case Stmt::ObjCImplicitSetterGetterRefExprClass:
178  case Stmt::ObjCSuperExprClass:
179  case Stmt::ObjCIsaExprClass:
180  case Stmt::ShuffleVectorExprClass:
181  case Stmt::BlockExprClass:
182    K = CXCursor_UnexposedExpr;
183    break;
184  case Stmt::DeclRefExprClass:
185  case Stmt::BlockDeclRefExprClass:
186    // FIXME: UnresolvedLookupExpr?
187    // FIXME: DependentScopeDeclRefExpr?
188    K = CXCursor_DeclRefExpr;
189    break;
190
191  case Stmt::MemberExprClass:
192  case Stmt::ObjCIvarRefExprClass:
193  case Stmt::ObjCPropertyRefExprClass:
194    // FIXME: UnresolvedMemberExpr?
195    // FIXME: CXXDependentScopeMemberExpr?
196    K = CXCursor_MemberRefExpr;
197    break;
198
199  case Stmt::CallExprClass:
200  case Stmt::CXXOperatorCallExprClass:
201  case Stmt::CXXMemberCallExprClass:
202  case Stmt::CXXConstructExprClass:
203  case Stmt::CXXTemporaryObjectExprClass:
204    // FIXME: CXXUnresolvedConstructExpr
205    // FIXME: ObjCImplicitSetterGetterRefExpr?
206    K = CXCursor_CallExpr;
207    break;
208
209  case Stmt::ObjCMessageExprClass:
210    K = CXCursor_ObjCMessageExpr;
211    break;
212  }
213
214  CXCursor C = { K, { Parent, S, 0 } };
215  return C;
216}
217
218CXCursor cxcursor::MakeCursorObjCSuperClassRef(ObjCInterfaceDecl *Super,
219                                         SourceLocation Loc) {
220  void *RawLoc = reinterpret_cast<void *>(Loc.getRawEncoding());
221  CXCursor C = { CXCursor_ObjCSuperClassRef, { Super, RawLoc, 0 } };
222  return C;
223}
224
225std::pair<ObjCInterfaceDecl *, SourceLocation>
226cxcursor::getCursorObjCSuperClassRef(CXCursor C) {
227  assert(C.kind == CXCursor_ObjCSuperClassRef);
228  return std::make_pair(static_cast<ObjCInterfaceDecl *>(C.data[0]),
229           SourceLocation::getFromRawEncoding(
230                                      reinterpret_cast<uintptr_t>(C.data[1])));
231}
232
233CXCursor cxcursor::MakeCursorObjCProtocolRef(ObjCProtocolDecl *Super,
234                                             SourceLocation Loc) {
235  void *RawLoc = reinterpret_cast<void *>(Loc.getRawEncoding());
236  CXCursor C = { CXCursor_ObjCProtocolRef, { Super, RawLoc, 0 } };
237  return C;
238}
239
240std::pair<ObjCProtocolDecl *, SourceLocation>
241cxcursor::getCursorObjCProtocolRef(CXCursor C) {
242  assert(C.kind == CXCursor_ObjCProtocolRef);
243  return std::make_pair(static_cast<ObjCProtocolDecl *>(C.data[0]),
244           SourceLocation::getFromRawEncoding(
245                                      reinterpret_cast<uintptr_t>(C.data[1])));
246}
247
248CXCursor cxcursor::MakeCursorObjCClassRef(ObjCInterfaceDecl *Class,
249                                         SourceLocation Loc) {
250  void *RawLoc = reinterpret_cast<void *>(Loc.getRawEncoding());
251  CXCursor C = { CXCursor_ObjCClassRef, { Class, RawLoc, 0 } };
252  return C;
253}
254
255std::pair<ObjCInterfaceDecl *, SourceLocation>
256cxcursor::getCursorObjCClassRef(CXCursor C) {
257  assert(C.kind == CXCursor_ObjCClassRef);
258  return std::make_pair(static_cast<ObjCInterfaceDecl *>(C.data[0]),
259           SourceLocation::getFromRawEncoding(
260                                      reinterpret_cast<uintptr_t>(C.data[1])));
261}
262
263Decl *cxcursor::getCursorDecl(CXCursor Cursor) {
264  return (Decl *)Cursor.data[0];
265}
266
267Expr *cxcursor::getCursorExpr(CXCursor Cursor) {
268  return dyn_cast_or_null<Expr>(getCursorStmt(Cursor));
269}
270
271Stmt *cxcursor::getCursorStmt(CXCursor Cursor) {
272  if (Cursor.kind == CXCursor_ObjCSuperClassRef ||
273      Cursor.kind == CXCursor_ObjCProtocolRef ||
274      Cursor.kind == CXCursor_ObjCClassRef)
275    return 0;
276
277  return (Stmt *)Cursor.data[1];
278}
279
280ASTContext &cxcursor::getCursorContext(CXCursor Cursor) {
281  switch (Cursor.kind) {
282  case CXCursor_TypedefDecl:
283  case CXCursor_StructDecl:
284  case CXCursor_UnionDecl:
285  case CXCursor_ClassDecl:
286  case CXCursor_EnumDecl:
287  case CXCursor_FieldDecl:
288  case CXCursor_EnumConstantDecl:
289  case CXCursor_FunctionDecl:
290  case CXCursor_VarDecl:
291  case CXCursor_ParmDecl:
292  case CXCursor_ObjCInterfaceDecl:
293  case CXCursor_ObjCCategoryDecl:
294  case CXCursor_ObjCProtocolDecl:
295  case CXCursor_ObjCPropertyDecl:
296  case CXCursor_ObjCIvarDecl:
297  case CXCursor_ObjCInstanceMethodDecl:
298  case CXCursor_ObjCClassMethodDecl:
299  case CXCursor_ObjCImplementationDecl:
300  case CXCursor_ObjCCategoryImplDecl:
301  case CXCursor_UnexposedDecl:
302    return static_cast<Decl *>(Cursor.data[0])->getASTContext();
303
304  case CXCursor_ObjCSuperClassRef:
305  case CXCursor_ObjCProtocolRef:
306  case CXCursor_ObjCClassRef:
307    return static_cast<Decl *>(Cursor.data[0])->getASTContext();
308
309  case CXCursor_ObjCSelectorRef:
310  case CXCursor_VarRef:
311  case CXCursor_FunctionRef:
312  case CXCursor_EnumConstantRef:
313    return *static_cast<ASTContext *>(Cursor.data[2]);
314
315  case CXCursor_InvalidFile:
316  case CXCursor_NoDeclFound:
317  case CXCursor_NotImplemented:
318    llvm_unreachable("No context in an invalid cursor");
319    break;
320
321  case CXCursor_UnexposedExpr:
322  case CXCursor_DeclRefExpr:
323  case CXCursor_MemberRefExpr:
324  case CXCursor_CallExpr:
325  case CXCursor_ObjCMessageExpr:
326  case CXCursor_UnexposedStmt:
327    return static_cast<Decl *>(Cursor.data[0])->getASTContext();
328
329  }
330
331  llvm_unreachable("No context available");
332}
333
334bool cxcursor::operator==(CXCursor X, CXCursor Y) {
335  return X.kind == Y.kind && X.data[0] == Y.data[0] && X.data[1] == Y.data[1] &&
336         X.data[2] == Y.data[2];
337}
338