blob: 68fba7e3cd7e92e025ae9b5594d127c59e0af1a5 [file] [log] [blame]
Ted Kremenek16c440a2010-01-15 20:35:54 +00001//===- 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//
Douglas Gregor2e331b92010-01-16 14:00:32 +000010// 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.
Ted Kremenek16c440a2010-01-15 20:35:54 +000013//
14//===----------------------------------------------------------------------===//
15
16#include "CXCursor.h"
17#include "clang/AST/Decl.h"
Douglas Gregor283cae32010-01-15 21:56:13 +000018#include "clang/AST/DeclObjC.h"
19#include "clang/AST/Expr.h"
Ted Kremenekedc8aa62010-01-16 00:36:30 +000020#include "llvm/Support/ErrorHandling.h"
Ted Kremenek16c440a2010-01-15 20:35:54 +000021
22using namespace clang;
23
24CXCursor cxcursor::MakeCXCursor(CXCursorKind K, Decl *D) {
Douglas Gregor283cae32010-01-15 21:56:13 +000025 CXCursor C = { K, { D, 0, 0 } };
Ted Kremenek16c440a2010-01-15 20:35:54 +000026 return C;
27}
28
Douglas Gregorf46034a2010-01-18 23:41:10 +000029CXCursor cxcursor::MakeCXCursor(CXCursorKind K, Decl *D, Stmt *S,
30 ASTContext &Context) {
Ted Kremenek16c440a2010-01-15 20:35:54 +000031 assert(clang_isReference(K));
Douglas Gregorf46034a2010-01-18 23:41:10 +000032 CXCursor C = { K, { D, S, &Context } };
Ted Kremenek16c440a2010-01-15 20:35:54 +000033 return C;
34}
35
Ted Kremenekedc8aa62010-01-16 00:36:30 +000036static CXCursorKind GetCursorKind(Decl *D) {
37 switch (D->getKind()) {
Ted Kremenek70ee5422010-01-16 01:44:12 +000038 case Decl::Enum: return CXCursor_EnumDecl;
39 case Decl::EnumConstant: return CXCursor_EnumConstantDecl;
40 case Decl::Field: return CXCursor_FieldDecl;
Ted Kremenekedc8aa62010-01-16 00:36:30 +000041 case Decl::Function:
Douglas Gregorb6998662010-01-19 19:34:47 +000042 return CXCursor_FunctionDecl;
Ted Kremenekedc8aa62010-01-16 00:36:30 +000043 case Decl::ObjCCategory: return CXCursor_ObjCCategoryDecl;
Douglas Gregorb6998662010-01-19 19:34:47 +000044 case Decl::ObjCCategoryImpl: return CXCursor_ObjCCategoryImplDecl;
Ted Kremenek70ee5422010-01-16 01:44:12 +000045 case Decl::ObjCClass:
46 // FIXME
Douglas Gregor30122132010-01-19 22:07:56 +000047 return CXCursor_UnexposedDecl;
Ted Kremenek6483a772010-01-18 22:07:45 +000048 case Decl::ObjCForwardProtocol:
49 // FIXME
Douglas Gregor30122132010-01-19 22:07:56 +000050 return CXCursor_UnexposedDecl;
Douglas Gregorb6998662010-01-19 19:34:47 +000051 case Decl::ObjCImplementation: return CXCursor_ObjCImplementationDecl;
Ted Kremenekedc8aa62010-01-16 00:36:30 +000052 case Decl::ObjCInterface: return CXCursor_ObjCInterfaceDecl;
Ted Kremenek70ee5422010-01-16 01:44:12 +000053 case Decl::ObjCIvar: return CXCursor_ObjCIvarDecl;
54 case Decl::ObjCMethod:
55 return cast<ObjCMethodDecl>(D)->isInstanceMethod()
56 ? CXCursor_ObjCInstanceMethodDecl : CXCursor_ObjCClassMethodDecl;
Ted Kremenek10fa3cc2010-01-16 02:08:29 +000057 case Decl::ObjCProperty: return CXCursor_ObjCPropertyDecl;
Ted Kremenekedc8aa62010-01-16 00:36:30 +000058 case Decl::ObjCProtocol: return CXCursor_ObjCProtocolDecl;
Ted Kremenek70ee5422010-01-16 01:44:12 +000059 case Decl::ParmVar: return CXCursor_ParmDecl;
Ted Kremenekedc8aa62010-01-16 00:36:30 +000060 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 }
Douglas Gregor30122132010-01-19 22:07:56 +000071
72 return CXCursor_UnexposedDecl;
Ted Kremenekedc8aa62010-01-16 00:36:30 +000073 }
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
Douglas Gregor97b98722010-01-19 23:20:36 +000083CXCursor 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
Douglas Gregor2e331b92010-01-16 14:00:32 +0000218CXCursor 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
Douglas Gregor78db0cd2010-01-16 15:44:18 +0000233CXCursor 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
Douglas Gregor1adb0822010-01-16 17:14:40 +0000248CXCursor 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
Douglas Gregor283cae32010-01-15 21:56:13 +0000263Decl *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) {
Douglas Gregor78db0cd2010-01-16 15:44:18 +0000272 if (Cursor.kind == CXCursor_ObjCSuperClassRef ||
Douglas Gregor1adb0822010-01-16 17:14:40 +0000273 Cursor.kind == CXCursor_ObjCProtocolRef ||
274 Cursor.kind == CXCursor_ObjCClassRef)
Douglas Gregor2e331b92010-01-16 14:00:32 +0000275 return 0;
276
Douglas Gregor283cae32010-01-15 21:56:13 +0000277 return (Stmt *)Cursor.data[1];
278}
279
Douglas Gregorf46034a2010-01-18 23:41:10 +0000280ASTContext &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:
Douglas Gregorb6998662010-01-19 19:34:47 +0000299 case CXCursor_ObjCImplementationDecl:
300 case CXCursor_ObjCCategoryImplDecl:
Douglas Gregor30122132010-01-19 22:07:56 +0000301 case CXCursor_UnexposedDecl:
Douglas Gregorf46034a2010-01-18 23:41:10 +0000302 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:
Douglas Gregorf46034a2010-01-18 23:41:10 +0000310 case CXCursor_VarRef:
311 case CXCursor_FunctionRef:
312 case CXCursor_EnumConstantRef:
Douglas Gregorf46034a2010-01-18 23:41:10 +0000313 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");
Douglas Gregor97b98722010-01-19 23:20:36 +0000319 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
Douglas Gregorf46034a2010-01-18 23:41:10 +0000329 }
330
331 llvm_unreachable("No context available");
Douglas Gregor283cae32010-01-15 21:56:13 +0000332}
333
Douglas Gregor283cae32010-01-15 21:56:13 +0000334bool 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];
Douglas Gregor2e331b92010-01-16 14:00:32 +0000337}