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