blob: 747b1a1390880d8b6cb98dc58ce3a1c537bf4120 [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:
42 return cast<FunctionDecl>(D)->isThisDeclarationADefinition()
43 ? CXCursor_FunctionDefn : CXCursor_FunctionDecl;
44 case Decl::ObjCCategory: return CXCursor_ObjCCategoryDecl;
45 case Decl::ObjCCategoryImpl: return CXCursor_ObjCCategoryDefn;
Ted Kremenek70ee5422010-01-16 01:44:12 +000046 case Decl::ObjCClass:
47 // FIXME
48 return CXCursor_NotImplemented;
Ted Kremenek6483a772010-01-18 22:07:45 +000049 case Decl::ObjCForwardProtocol:
50 // FIXME
51 return CXCursor_NotImplemented;
Ted Kremenekedc8aa62010-01-16 00:36:30 +000052 case Decl::ObjCImplementation: return CXCursor_ObjCClassDefn;
53 case Decl::ObjCInterface: return CXCursor_ObjCInterfaceDecl;
Ted Kremenek70ee5422010-01-16 01:44:12 +000054 case Decl::ObjCIvar: return CXCursor_ObjCIvarDecl;
55 case Decl::ObjCMethod:
56 return cast<ObjCMethodDecl>(D)->isInstanceMethod()
57 ? CXCursor_ObjCInstanceMethodDecl : CXCursor_ObjCClassMethodDecl;
Ted Kremenek10fa3cc2010-01-16 02:08:29 +000058 case Decl::ObjCProperty: return CXCursor_ObjCPropertyDecl;
Ted Kremenekedc8aa62010-01-16 00:36:30 +000059 case Decl::ObjCProtocol: return CXCursor_ObjCProtocolDecl;
Ted Kremenek70ee5422010-01-16 01:44:12 +000060 case Decl::ParmVar: return CXCursor_ParmDecl;
Ted Kremenekedc8aa62010-01-16 00:36:30 +000061 case Decl::Typedef: return CXCursor_TypedefDecl;
62 case Decl::Var: return CXCursor_VarDecl;
63 default:
64 if (TagDecl *TD = dyn_cast<TagDecl>(D)) {
65 switch (TD->getTagKind()) {
66 case TagDecl::TK_struct: return CXCursor_StructDecl;
67 case TagDecl::TK_class: return CXCursor_ClassDecl;
68 case TagDecl::TK_union: return CXCursor_UnionDecl;
69 case TagDecl::TK_enum: return CXCursor_EnumDecl;
70 }
71 }
72 }
73
74 llvm_unreachable("Invalid Decl");
75 return CXCursor_NotImplemented;
76}
77
78CXCursor cxcursor::MakeCXCursor(Decl *D) {
79 return MakeCXCursor(GetCursorKind(D), D);
80}
81
Douglas Gregor2e331b92010-01-16 14:00:32 +000082CXCursor cxcursor::MakeCursorObjCSuperClassRef(ObjCInterfaceDecl *Super,
83 SourceLocation Loc) {
84 void *RawLoc = reinterpret_cast<void *>(Loc.getRawEncoding());
85 CXCursor C = { CXCursor_ObjCSuperClassRef, { Super, RawLoc, 0 } };
86 return C;
87}
88
89std::pair<ObjCInterfaceDecl *, SourceLocation>
90cxcursor::getCursorObjCSuperClassRef(CXCursor C) {
91 assert(C.kind == CXCursor_ObjCSuperClassRef);
92 return std::make_pair(static_cast<ObjCInterfaceDecl *>(C.data[0]),
93 SourceLocation::getFromRawEncoding(
94 reinterpret_cast<uintptr_t>(C.data[1])));
95}
96
Douglas Gregor78db0cd2010-01-16 15:44:18 +000097CXCursor cxcursor::MakeCursorObjCProtocolRef(ObjCProtocolDecl *Super,
98 SourceLocation Loc) {
99 void *RawLoc = reinterpret_cast<void *>(Loc.getRawEncoding());
100 CXCursor C = { CXCursor_ObjCProtocolRef, { Super, RawLoc, 0 } };
101 return C;
102}
103
104std::pair<ObjCProtocolDecl *, SourceLocation>
105cxcursor::getCursorObjCProtocolRef(CXCursor C) {
106 assert(C.kind == CXCursor_ObjCProtocolRef);
107 return std::make_pair(static_cast<ObjCProtocolDecl *>(C.data[0]),
108 SourceLocation::getFromRawEncoding(
109 reinterpret_cast<uintptr_t>(C.data[1])));
110}
111
Douglas Gregor1adb0822010-01-16 17:14:40 +0000112CXCursor cxcursor::MakeCursorObjCClassRef(ObjCInterfaceDecl *Class,
113 SourceLocation Loc) {
114 void *RawLoc = reinterpret_cast<void *>(Loc.getRawEncoding());
115 CXCursor C = { CXCursor_ObjCClassRef, { Class, RawLoc, 0 } };
116 return C;
117}
118
119std::pair<ObjCInterfaceDecl *, SourceLocation>
120cxcursor::getCursorObjCClassRef(CXCursor C) {
121 assert(C.kind == CXCursor_ObjCClassRef);
122 return std::make_pair(static_cast<ObjCInterfaceDecl *>(C.data[0]),
123 SourceLocation::getFromRawEncoding(
124 reinterpret_cast<uintptr_t>(C.data[1])));
125}
126
Douglas Gregor283cae32010-01-15 21:56:13 +0000127Decl *cxcursor::getCursorDecl(CXCursor Cursor) {
128 return (Decl *)Cursor.data[0];
129}
130
131Expr *cxcursor::getCursorExpr(CXCursor Cursor) {
132 return dyn_cast_or_null<Expr>(getCursorStmt(Cursor));
133}
134
135Stmt *cxcursor::getCursorStmt(CXCursor Cursor) {
Douglas Gregor78db0cd2010-01-16 15:44:18 +0000136 if (Cursor.kind == CXCursor_ObjCSuperClassRef ||
Douglas Gregor1adb0822010-01-16 17:14:40 +0000137 Cursor.kind == CXCursor_ObjCProtocolRef ||
138 Cursor.kind == CXCursor_ObjCClassRef)
Douglas Gregor2e331b92010-01-16 14:00:32 +0000139 return 0;
140
Douglas Gregor283cae32010-01-15 21:56:13 +0000141 return (Stmt *)Cursor.data[1];
142}
143
Douglas Gregorf46034a2010-01-18 23:41:10 +0000144ASTContext &cxcursor::getCursorContext(CXCursor Cursor) {
145 switch (Cursor.kind) {
146 case CXCursor_TypedefDecl:
147 case CXCursor_StructDecl:
148 case CXCursor_UnionDecl:
149 case CXCursor_ClassDecl:
150 case CXCursor_EnumDecl:
151 case CXCursor_FieldDecl:
152 case CXCursor_EnumConstantDecl:
153 case CXCursor_FunctionDecl:
154 case CXCursor_VarDecl:
155 case CXCursor_ParmDecl:
156 case CXCursor_ObjCInterfaceDecl:
157 case CXCursor_ObjCCategoryDecl:
158 case CXCursor_ObjCProtocolDecl:
159 case CXCursor_ObjCPropertyDecl:
160 case CXCursor_ObjCIvarDecl:
161 case CXCursor_ObjCInstanceMethodDecl:
162 case CXCursor_ObjCClassMethodDecl:
163 case CXCursor_FunctionDefn:
164 case CXCursor_ObjCClassDefn:
165 case CXCursor_ObjCCategoryDefn:
166 case CXCursor_ObjCInstanceMethodDefn:
167 case CXCursor_ObjCClassMethodDefn:
168 return static_cast<Decl *>(Cursor.data[0])->getASTContext();
169
170 case CXCursor_ObjCSuperClassRef:
171 case CXCursor_ObjCProtocolRef:
172 case CXCursor_ObjCClassRef:
173 return static_cast<Decl *>(Cursor.data[0])->getASTContext();
174
175 case CXCursor_ObjCSelectorRef:
176 case CXCursor_ObjCIvarRef:
177 case CXCursor_VarRef:
178 case CXCursor_FunctionRef:
179 case CXCursor_EnumConstantRef:
180 case CXCursor_MemberRef:
181 return *static_cast<ASTContext *>(Cursor.data[2]);
182
183 case CXCursor_InvalidFile:
184 case CXCursor_NoDeclFound:
185 case CXCursor_NotImplemented:
186 llvm_unreachable("No context in an invalid cursor");
187 }
188
189 llvm_unreachable("No context available");
Douglas Gregor283cae32010-01-15 21:56:13 +0000190}
191
Douglas Gregor283cae32010-01-15 21:56:13 +0000192bool cxcursor::operator==(CXCursor X, CXCursor Y) {
193 return X.kind == Y.kind && X.data[0] == Y.data[0] && X.data[1] == Y.data[1] &&
194 X.data[2] == Y.data[2];
Douglas Gregor2e331b92010-01-16 14:00:32 +0000195}