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