blob: f7f3ada90716ae466191868f1bbed52005a25e18 [file] [log] [blame]
Chris Lattner10318b82008-03-16 00:19:01 +00001//===--- DeclObjC.cpp - ObjC Declaration AST Node Implementation ----------===//
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 implements the Objective-C related Decl classes.
11//
12//===----------------------------------------------------------------------===//
13
14#include "clang/AST/DeclObjC.h"
15#include "clang/AST/ASTContext.h"
16using namespace clang;
17
18
19//===----------------------------------------------------------------------===//
20// Objective-C Decl Implementation
21//===----------------------------------------------------------------------===//
22
23void ObjCMethodDecl::setMethodParams(ParmVarDecl **NewParamInfo,
24 unsigned NumParams) {
25 assert(ParamInfo == 0 && "Already has param info!");
26
27 // Zero params -> null pointer.
28 if (NumParams) {
29 ParamInfo = new ParmVarDecl*[NumParams];
30 memcpy(ParamInfo, NewParamInfo, sizeof(ParmVarDecl*)*NumParams);
31 NumMethodParams = NumParams;
32 }
33}
34
35ObjCMethodDecl::~ObjCMethodDecl() {
36 delete[] ParamInfo;
37}
38
39/// ObjCAddInstanceVariablesToClass - Inserts instance variables
40/// into ObjCInterfaceDecl's fields.
41///
42void ObjCInterfaceDecl::addInstanceVariablesToClass(ObjCIvarDecl **ivars,
43 unsigned numIvars,
44 SourceLocation RBrac) {
45 NumIvars = numIvars;
46 if (numIvars) {
47 Ivars = new ObjCIvarDecl*[numIvars];
48 memcpy(Ivars, ivars, numIvars*sizeof(ObjCIvarDecl*));
49 }
50 setLocEnd(RBrac);
51}
52
53/// ObjCAddInstanceVariablesToClassImpl - Checks for correctness of Instance
54/// Variables (Ivars) relative to what declared in @implementation;s class.
55/// Ivars into ObjCImplementationDecl's fields.
56///
57void ObjCImplementationDecl::ObjCAddInstanceVariablesToClassImpl(
58 ObjCIvarDecl **ivars, unsigned numIvars) {
59 NumIvars = numIvars;
60 if (numIvars) {
61 Ivars = new ObjCIvarDecl*[numIvars];
62 memcpy(Ivars, ivars, numIvars*sizeof(ObjCIvarDecl*));
63 }
64}
65
66/// addMethods - Insert instance and methods declarations into
67/// ObjCInterfaceDecl's InsMethods and ClsMethods fields.
68///
69void ObjCInterfaceDecl::addMethods(ObjCMethodDecl **insMethods,
70 unsigned numInsMembers,
71 ObjCMethodDecl **clsMethods,
72 unsigned numClsMembers,
73 SourceLocation endLoc) {
74 NumInstanceMethods = numInsMembers;
75 if (numInsMembers) {
76 InstanceMethods = new ObjCMethodDecl*[numInsMembers];
77 memcpy(InstanceMethods, insMethods, numInsMembers*sizeof(ObjCMethodDecl*));
78 }
79 NumClassMethods = numClsMembers;
80 if (numClsMembers) {
81 ClassMethods = new ObjCMethodDecl*[numClsMembers];
82 memcpy(ClassMethods, clsMethods, numClsMembers*sizeof(ObjCMethodDecl*));
83 }
84 AtEndLoc = endLoc;
85}
86
87/// addMethods - Insert instance and methods declarations into
88/// ObjCProtocolDecl's ProtoInsMethods and ProtoClsMethods fields.
89///
90void ObjCProtocolDecl::addMethods(ObjCMethodDecl **insMethods,
91 unsigned numInsMembers,
92 ObjCMethodDecl **clsMethods,
93 unsigned numClsMembers,
94 SourceLocation endLoc) {
95 NumInstanceMethods = numInsMembers;
96 if (numInsMembers) {
97 InstanceMethods = new ObjCMethodDecl*[numInsMembers];
98 memcpy(InstanceMethods, insMethods, numInsMembers*sizeof(ObjCMethodDecl*));
99 }
100 NumClassMethods = numClsMembers;
101 if (numClsMembers) {
102 ClassMethods = new ObjCMethodDecl*[numClsMembers];
103 memcpy(ClassMethods, clsMethods, numClsMembers*sizeof(ObjCMethodDecl*));
104 }
105 AtEndLoc = endLoc;
106}
107
108/// addMethods - Insert instance and methods declarations into
109/// ObjCCategoryDecl's CatInsMethods and CatClsMethods fields.
110///
111void ObjCCategoryDecl::addMethods(ObjCMethodDecl **insMethods,
112 unsigned numInsMembers,
113 ObjCMethodDecl **clsMethods,
114 unsigned numClsMembers,
115 SourceLocation endLoc) {
116 NumInstanceMethods = numInsMembers;
117 if (numInsMembers) {
118 InstanceMethods = new ObjCMethodDecl*[numInsMembers];
119 memcpy(InstanceMethods, insMethods, numInsMembers*sizeof(ObjCMethodDecl*));
120 }
121 NumClassMethods = numClsMembers;
122 if (numClsMembers) {
123 ClassMethods = new ObjCMethodDecl*[numClsMembers];
124 memcpy(ClassMethods, clsMethods, numClsMembers*sizeof(ObjCMethodDecl*));
125 }
126 AtEndLoc = endLoc;
127}
128
129ObjCIvarDecl *ObjCInterfaceDecl::lookupInstanceVariable(
130 IdentifierInfo *ID, ObjCInterfaceDecl *&clsDeclared) {
131 ObjCInterfaceDecl* ClassDecl = this;
132 while (ClassDecl != NULL) {
133 for (ivar_iterator I = ClassDecl->ivar_begin(), E = ClassDecl->ivar_end();
134 I != E; ++I) {
135 if ((*I)->getIdentifier() == ID) {
136 clsDeclared = ClassDecl;
137 return *I;
138 }
139 }
140 ClassDecl = ClassDecl->getSuperClass();
141 }
142 return NULL;
143}
144
145/// lookupInstanceMethod - This method returns an instance method by looking in
146/// the class, its categories, and its super classes (using a linear search).
147ObjCMethodDecl *ObjCInterfaceDecl::lookupInstanceMethod(Selector Sel) {
148 ObjCInterfaceDecl* ClassDecl = this;
149 ObjCMethodDecl *MethodDecl = 0;
150
151 while (ClassDecl != NULL) {
152 if ((MethodDecl = ClassDecl->getInstanceMethod(Sel)))
153 return MethodDecl;
154
155 // Didn't find one yet - look through protocols.
156 ObjCProtocolDecl **protocols = ClassDecl->getReferencedProtocols();
157 int numProtocols = ClassDecl->getNumIntfRefProtocols();
158 for (int pIdx = 0; pIdx < numProtocols; pIdx++) {
159 if ((MethodDecl = protocols[pIdx]->getInstanceMethod(Sel)))
160 return MethodDecl;
161 }
162 // Didn't find one yet - now look through categories.
163 ObjCCategoryDecl *CatDecl = ClassDecl->getCategoryList();
164 while (CatDecl) {
165 if ((MethodDecl = CatDecl->getInstanceMethod(Sel)))
166 return MethodDecl;
167 CatDecl = CatDecl->getNextClassCategory();
168 }
169 ClassDecl = ClassDecl->getSuperClass();
170 }
171 return NULL;
172}
173
174// lookupClassMethod - This method returns a class method by looking in the
175// class, its categories, and its super classes (using a linear search).
176ObjCMethodDecl *ObjCInterfaceDecl::lookupClassMethod(Selector Sel) {
177 ObjCInterfaceDecl* ClassDecl = this;
178 ObjCMethodDecl *MethodDecl = 0;
179
180 while (ClassDecl != NULL) {
181 if ((MethodDecl = ClassDecl->getClassMethod(Sel)))
182 return MethodDecl;
183
184 // Didn't find one yet - look through protocols.
185 ObjCProtocolDecl **protocols = ClassDecl->getReferencedProtocols();
186 int numProtocols = ClassDecl->getNumIntfRefProtocols();
187 for (int pIdx = 0; pIdx < numProtocols; pIdx++) {
188 if ((MethodDecl = protocols[pIdx]->getClassMethod(Sel)))
189 return MethodDecl;
190 }
191 // Didn't find one yet - now look through categories.
192 ObjCCategoryDecl *CatDecl = ClassDecl->getCategoryList();
193 while (CatDecl) {
194 if ((MethodDecl = CatDecl->getClassMethod(Sel)))
195 return MethodDecl;
196 CatDecl = CatDecl->getNextClassCategory();
197 }
198 ClassDecl = ClassDecl->getSuperClass();
199 }
200 return NULL;
201}
202
203/// lookupInstanceMethod - This method returns an instance method by looking in
204/// the class implementation. Unlike interfaces, we don't look outside the
205/// implementation.
206ObjCMethodDecl *ObjCImplementationDecl::getInstanceMethod(Selector Sel) {
207 for (instmeth_iterator I = instmeth_begin(), E = instmeth_end(); I != E; ++I)
208 if ((*I)->getSelector() == Sel)
209 return *I;
210 return NULL;
211}
212
213/// lookupClassMethod - This method returns a class method by looking in
214/// the class implementation. Unlike interfaces, we don't look outside the
215/// implementation.
216ObjCMethodDecl *ObjCImplementationDecl::getClassMethod(Selector Sel) {
217 for (classmeth_iterator I = classmeth_begin(), E = classmeth_end();
218 I != E; ++I)
219 if ((*I)->getSelector() == Sel)
220 return *I;
221 return NULL;
222}
223
224// lookupInstanceMethod - This method returns an instance method by looking in
225// the class implementation. Unlike interfaces, we don't look outside the
226// implementation.
227ObjCMethodDecl *ObjCCategoryImplDecl::getInstanceMethod(Selector Sel) {
228 for (instmeth_iterator I = instmeth_begin(), E = instmeth_end(); I != E; ++I)
229 if ((*I)->getSelector() == Sel)
230 return *I;
231 return NULL;
232}
233
234// lookupClassMethod - This method returns an instance method by looking in
235// the class implementation. Unlike interfaces, we don't look outside the
236// implementation.
237ObjCMethodDecl *ObjCCategoryImplDecl::getClassMethod(Selector Sel) {
238 for (classmeth_iterator I = classmeth_begin(), E = classmeth_end();
239 I != E; ++I)
240 if ((*I)->getSelector() == Sel)
241 return *I;
242 return NULL;
243}
244
245// lookupInstanceMethod - Lookup a instance method in the protocol and protocols
246// it inherited.
247ObjCMethodDecl *ObjCProtocolDecl::lookupInstanceMethod(Selector Sel) {
248 ObjCMethodDecl *MethodDecl = NULL;
249
250 if ((MethodDecl = getInstanceMethod(Sel)))
251 return MethodDecl;
252
253 if (getNumReferencedProtocols() > 0) {
254 ObjCProtocolDecl **RefPDecl = getReferencedProtocols();
255
256 for (unsigned i = 0; i < getNumReferencedProtocols(); i++) {
257 if ((MethodDecl = RefPDecl[i]->getInstanceMethod(Sel)))
258 return MethodDecl;
259 }
260 }
261 return NULL;
262}
263
264// lookupInstanceMethod - Lookup a class method in the protocol and protocols
265// it inherited.
266ObjCMethodDecl *ObjCProtocolDecl::lookupClassMethod(Selector Sel) {
267 ObjCMethodDecl *MethodDecl = NULL;
268
269 if ((MethodDecl = getClassMethod(Sel)))
270 return MethodDecl;
271
272 if (getNumReferencedProtocols() > 0) {
273 ObjCProtocolDecl **RefPDecl = getReferencedProtocols();
274
275 for(unsigned i = 0; i < getNumReferencedProtocols(); i++) {
276 if ((MethodDecl = RefPDecl[i]->getClassMethod(Sel)))
277 return MethodDecl;
278 }
279 }
280 return NULL;
281}
282
283/// getSynthesizedMethodSize - Compute size of synthesized method name
284/// as done be the rewrite.
285///
286unsigned ObjCMethodDecl::getSynthesizedMethodSize() const {
287 // syntesized method name is a concatenation of -/+[class-name selector]
288 // Get length of this name.
289 unsigned length = 3; // _I_ or _C_
290 length += strlen(getClassInterface()->getName()) +1; // extra for _
291 NamedDecl *MethodContext = getMethodContext();
292 if (ObjCCategoryImplDecl *CID =
293 dyn_cast<ObjCCategoryImplDecl>(MethodContext))
294 length += strlen(CID->getName()) +1;
295 length += getSelector().getName().size(); // selector name
296 return length;
297}
298
299ObjCInterfaceDecl *const ObjCMethodDecl::getClassInterface() const {
300 if (ObjCInterfaceDecl *ID = dyn_cast<ObjCInterfaceDecl>(MethodContext))
301 return ID;
302 if (ObjCCategoryDecl *CD = dyn_cast<ObjCCategoryDecl>(MethodContext))
303 return CD->getClassInterface();
304 if (ObjCImplementationDecl *IMD =
305 dyn_cast<ObjCImplementationDecl>(MethodContext))
306 return IMD->getClassInterface();
307 if (ObjCCategoryImplDecl *CID =
308 dyn_cast<ObjCCategoryImplDecl>(MethodContext))
309 return CID->getClassInterface();
310 assert(false && "unknown method context");
311 return 0;
312}