blob: 2e3a06a956faee7944e09add2d8f12e66daeffe0 [file] [log] [blame]
Chris Lattner1e03a562008-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 Lattner6c4ae5d2008-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 Lattner6c4ae5d2008-03-16 00:49:28 +000026 AttributeList *M, bool isInstance,
27 bool isVariadic,
Chris Lattnerb06fa3b2008-03-16 00:58:16 +000028 ImplementationControl impControl) {
Chris Lattner6c4ae5d2008-03-16 00:49:28 +000029 void *Mem = C.getAllocator().Allocate<ObjCMethodDecl>();
30 return new (Mem) ObjCMethodDecl(beginLoc, endLoc, SelInfo, T, contextDecl,
Chris Lattnerb06fa3b2008-03-16 00:58:16 +000031 M, isInstance,
32 isVariadic, impControl);
Chris Lattner0e77ba02008-03-16 01:15:50 +000033}
Chris Lattner6c4ae5d2008-03-16 00:49:28 +000034
Chris Lattner0e77ba02008-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 Lattner6c4ae5d2008-03-16 00:49:28 +000048}
49
Chris Lattnercca59d72008-03-16 01:23:04 +000050ObjCProtocolDecl *ObjCProtocolDecl::Create(ASTContext &C, SourceLocation L,
51 unsigned numRefProtos,
Chris Lattnerc8581052008-03-16 20:19:15 +000052 IdentifierInfo *Id) {
Chris Lattnercca59d72008-03-16 01:23:04 +000053 void *Mem = C.getAllocator().Allocate<ObjCProtocolDecl>();
Chris Lattnerc8581052008-03-16 20:19:15 +000054 return new (Mem) ObjCProtocolDecl(L, numRefProtos, Id);
Chris Lattnercca59d72008-03-16 01:23:04 +000055}
56
Chris Lattner61f9d412008-03-16 20:34:23 +000057ObjCClassDecl *ObjCClassDecl::Create(ASTContext &C, SourceLocation L,
58 ObjCInterfaceDecl **Elts, unsigned nElts) {
59 void *Mem = C.getAllocator().Allocate<ObjCClassDecl>();
60 return new (Mem) ObjCClassDecl(L, Elts, nElts);
61}
62
63ObjCForwardProtocolDecl *
64ObjCForwardProtocolDecl::Create(ASTContext &C, SourceLocation L,
65 ObjCProtocolDecl **Elts, unsigned NumElts) {
66 void *Mem = C.getAllocator().Allocate<ObjCForwardProtocolDecl>();
67 return new (Mem) ObjCForwardProtocolDecl(L, Elts, NumElts);
68}
69
70ObjCCategoryDecl *ObjCCategoryDecl::Create(ASTContext &C, SourceLocation L,
Chris Lattner61f9d412008-03-16 20:34:23 +000071 IdentifierInfo *Id) {
72 void *Mem = C.getAllocator().Allocate<ObjCCategoryDecl>();
Chris Lattner68c82cf2008-03-16 20:47:45 +000073 return new (Mem) ObjCCategoryDecl(L, Id);
Chris Lattner61f9d412008-03-16 20:34:23 +000074}
75
Chris Lattner75c9cae2008-03-16 20:53:07 +000076ObjCCategoryImplDecl *
77ObjCCategoryImplDecl::Create(ASTContext &C, SourceLocation L,IdentifierInfo *Id,
78 ObjCInterfaceDecl *ClassInterface) {
79 void *Mem = C.getAllocator().Allocate<ObjCCategoryImplDecl>();
80 return new (Mem) ObjCCategoryImplDecl(L, Id, ClassInterface);
81}
82
83ObjCImplementationDecl *
84ObjCImplementationDecl::Create(ASTContext &C, SourceLocation L,
85 IdentifierInfo *Id,
86 ObjCInterfaceDecl *ClassInterface,
87 ObjCInterfaceDecl *SuperDecl) {
88 void *Mem = C.getAllocator().Allocate<ObjCImplementationDecl>();
89 return new (Mem) ObjCImplementationDecl(L, Id, ClassInterface, SuperDecl);
90}
Chris Lattner1e03a562008-03-16 00:19:01 +000091
Chris Lattnerf8d17a52008-03-16 21:17:37 +000092ObjCCompatibleAliasDecl *
93ObjCCompatibleAliasDecl::Create(ASTContext &C, SourceLocation L,
94 IdentifierInfo *Id,
95 ObjCInterfaceDecl* AliasedClass) {
96 void *Mem = C.getAllocator().Allocate<ObjCCompatibleAliasDecl>();
97 return new (Mem) ObjCCompatibleAliasDecl(L, Id, AliasedClass);
98}
99
100ObjCPropertyDecl *ObjCPropertyDecl::Create(ASTContext &C, SourceLocation L) {
101 void *Mem = C.getAllocator().Allocate<ObjCPropertyDecl>();
102 return new (Mem) ObjCPropertyDecl(L);
103}
104
Chris Lattner1e03a562008-03-16 00:19:01 +0000105//===----------------------------------------------------------------------===//
106// Objective-C Decl Implementation
107//===----------------------------------------------------------------------===//
108
109void ObjCMethodDecl::setMethodParams(ParmVarDecl **NewParamInfo,
110 unsigned NumParams) {
111 assert(ParamInfo == 0 && "Already has param info!");
112
113 // Zero params -> null pointer.
114 if (NumParams) {
115 ParamInfo = new ParmVarDecl*[NumParams];
116 memcpy(ParamInfo, NewParamInfo, sizeof(ParmVarDecl*)*NumParams);
117 NumMethodParams = NumParams;
118 }
119}
120
121ObjCMethodDecl::~ObjCMethodDecl() {
122 delete[] ParamInfo;
123}
124
125/// ObjCAddInstanceVariablesToClass - Inserts instance variables
126/// into ObjCInterfaceDecl's fields.
127///
128void ObjCInterfaceDecl::addInstanceVariablesToClass(ObjCIvarDecl **ivars,
129 unsigned numIvars,
130 SourceLocation RBrac) {
131 NumIvars = numIvars;
132 if (numIvars) {
133 Ivars = new ObjCIvarDecl*[numIvars];
134 memcpy(Ivars, ivars, numIvars*sizeof(ObjCIvarDecl*));
135 }
136 setLocEnd(RBrac);
137}
138
139/// ObjCAddInstanceVariablesToClassImpl - Checks for correctness of Instance
140/// Variables (Ivars) relative to what declared in @implementation;s class.
141/// Ivars into ObjCImplementationDecl's fields.
142///
143void ObjCImplementationDecl::ObjCAddInstanceVariablesToClassImpl(
144 ObjCIvarDecl **ivars, unsigned numIvars) {
145 NumIvars = numIvars;
146 if (numIvars) {
147 Ivars = new ObjCIvarDecl*[numIvars];
148 memcpy(Ivars, ivars, numIvars*sizeof(ObjCIvarDecl*));
149 }
150}
151
152/// addMethods - Insert instance and methods declarations into
153/// ObjCInterfaceDecl's InsMethods and ClsMethods fields.
154///
155void ObjCInterfaceDecl::addMethods(ObjCMethodDecl **insMethods,
156 unsigned numInsMembers,
157 ObjCMethodDecl **clsMethods,
158 unsigned numClsMembers,
159 SourceLocation endLoc) {
160 NumInstanceMethods = numInsMembers;
161 if (numInsMembers) {
162 InstanceMethods = new ObjCMethodDecl*[numInsMembers];
163 memcpy(InstanceMethods, insMethods, numInsMembers*sizeof(ObjCMethodDecl*));
164 }
165 NumClassMethods = numClsMembers;
166 if (numClsMembers) {
167 ClassMethods = new ObjCMethodDecl*[numClsMembers];
168 memcpy(ClassMethods, clsMethods, numClsMembers*sizeof(ObjCMethodDecl*));
169 }
170 AtEndLoc = endLoc;
171}
172
173/// addMethods - Insert instance and methods declarations into
Chris Lattner55d13b42008-03-16 21:23:50 +0000174/// ObjCInterfaceDecl's InsMethods and ClsMethods fields.
175///
176void ObjCInterfaceDecl::addProperties(ObjCPropertyDecl **Properties,
177 unsigned NumProperties) {
178 if (NumProperties == 0) return;
179
180 NumPropertyDecl = NumProperties;
181 PropertyDecl = new ObjCPropertyDecl*[NumProperties];
182 memcpy(PropertyDecl, Properties, NumProperties*sizeof(ObjCPropertyDecl*));
183}
184
185/// addMethods - Insert instance and methods declarations into
Chris Lattner1e03a562008-03-16 00:19:01 +0000186/// ObjCProtocolDecl's ProtoInsMethods and ProtoClsMethods fields.
187///
188void ObjCProtocolDecl::addMethods(ObjCMethodDecl **insMethods,
189 unsigned numInsMembers,
190 ObjCMethodDecl **clsMethods,
191 unsigned numClsMembers,
192 SourceLocation endLoc) {
193 NumInstanceMethods = numInsMembers;
194 if (numInsMembers) {
195 InstanceMethods = new ObjCMethodDecl*[numInsMembers];
196 memcpy(InstanceMethods, insMethods, numInsMembers*sizeof(ObjCMethodDecl*));
197 }
198 NumClassMethods = numClsMembers;
199 if (numClsMembers) {
200 ClassMethods = new ObjCMethodDecl*[numClsMembers];
201 memcpy(ClassMethods, clsMethods, numClsMembers*sizeof(ObjCMethodDecl*));
202 }
203 AtEndLoc = endLoc;
204}
205
Chris Lattner68c82cf2008-03-16 20:47:45 +0000206void ObjCCategoryDecl::setReferencedProtocolList(ObjCProtocolDecl **List,
207 unsigned NumRPs) {
208 assert(NumReferencedProtocols == 0 && "Protocol list already set");
209 if (NumRPs == 0) return;
210
211 ReferencedProtocols = new ObjCProtocolDecl*[NumRPs];
212 memcpy(ReferencedProtocols, List, NumRPs*sizeof(ObjCProtocolDecl*));
213 NumReferencedProtocols = NumRPs;
214}
215
216
Chris Lattner1e03a562008-03-16 00:19:01 +0000217/// addMethods - Insert instance and methods declarations into
218/// ObjCCategoryDecl's CatInsMethods and CatClsMethods fields.
219///
220void ObjCCategoryDecl::addMethods(ObjCMethodDecl **insMethods,
221 unsigned numInsMembers,
222 ObjCMethodDecl **clsMethods,
223 unsigned numClsMembers,
224 SourceLocation endLoc) {
225 NumInstanceMethods = numInsMembers;
226 if (numInsMembers) {
227 InstanceMethods = new ObjCMethodDecl*[numInsMembers];
228 memcpy(InstanceMethods, insMethods, numInsMembers*sizeof(ObjCMethodDecl*));
229 }
230 NumClassMethods = numClsMembers;
231 if (numClsMembers) {
232 ClassMethods = new ObjCMethodDecl*[numClsMembers];
233 memcpy(ClassMethods, clsMethods, numClsMembers*sizeof(ObjCMethodDecl*));
234 }
235 AtEndLoc = endLoc;
236}
237
238ObjCIvarDecl *ObjCInterfaceDecl::lookupInstanceVariable(
239 IdentifierInfo *ID, ObjCInterfaceDecl *&clsDeclared) {
240 ObjCInterfaceDecl* ClassDecl = this;
241 while (ClassDecl != NULL) {
242 for (ivar_iterator I = ClassDecl->ivar_begin(), E = ClassDecl->ivar_end();
243 I != E; ++I) {
244 if ((*I)->getIdentifier() == ID) {
245 clsDeclared = ClassDecl;
246 return *I;
247 }
248 }
249 ClassDecl = ClassDecl->getSuperClass();
250 }
251 return NULL;
252}
253
254/// lookupInstanceMethod - This method returns an instance method by looking in
255/// the class, its categories, and its super classes (using a linear search).
256ObjCMethodDecl *ObjCInterfaceDecl::lookupInstanceMethod(Selector Sel) {
257 ObjCInterfaceDecl* ClassDecl = this;
258 ObjCMethodDecl *MethodDecl = 0;
259
260 while (ClassDecl != NULL) {
261 if ((MethodDecl = ClassDecl->getInstanceMethod(Sel)))
262 return MethodDecl;
263
264 // Didn't find one yet - look through protocols.
265 ObjCProtocolDecl **protocols = ClassDecl->getReferencedProtocols();
266 int numProtocols = ClassDecl->getNumIntfRefProtocols();
267 for (int pIdx = 0; pIdx < numProtocols; pIdx++) {
268 if ((MethodDecl = protocols[pIdx]->getInstanceMethod(Sel)))
269 return MethodDecl;
270 }
271 // Didn't find one yet - now look through categories.
272 ObjCCategoryDecl *CatDecl = ClassDecl->getCategoryList();
273 while (CatDecl) {
274 if ((MethodDecl = CatDecl->getInstanceMethod(Sel)))
275 return MethodDecl;
276 CatDecl = CatDecl->getNextClassCategory();
277 }
278 ClassDecl = ClassDecl->getSuperClass();
279 }
280 return NULL;
281}
282
283// lookupClassMethod - This method returns a class method by looking in the
284// class, its categories, and its super classes (using a linear search).
285ObjCMethodDecl *ObjCInterfaceDecl::lookupClassMethod(Selector Sel) {
286 ObjCInterfaceDecl* ClassDecl = this;
287 ObjCMethodDecl *MethodDecl = 0;
288
289 while (ClassDecl != NULL) {
290 if ((MethodDecl = ClassDecl->getClassMethod(Sel)))
291 return MethodDecl;
292
293 // Didn't find one yet - look through protocols.
294 ObjCProtocolDecl **protocols = ClassDecl->getReferencedProtocols();
295 int numProtocols = ClassDecl->getNumIntfRefProtocols();
296 for (int pIdx = 0; pIdx < numProtocols; pIdx++) {
297 if ((MethodDecl = protocols[pIdx]->getClassMethod(Sel)))
298 return MethodDecl;
299 }
300 // Didn't find one yet - now look through categories.
301 ObjCCategoryDecl *CatDecl = ClassDecl->getCategoryList();
302 while (CatDecl) {
303 if ((MethodDecl = CatDecl->getClassMethod(Sel)))
304 return MethodDecl;
305 CatDecl = CatDecl->getNextClassCategory();
306 }
307 ClassDecl = ClassDecl->getSuperClass();
308 }
309 return NULL;
310}
311
312/// lookupInstanceMethod - This method returns an instance method by looking in
313/// the class implementation. Unlike interfaces, we don't look outside the
314/// implementation.
315ObjCMethodDecl *ObjCImplementationDecl::getInstanceMethod(Selector Sel) {
316 for (instmeth_iterator I = instmeth_begin(), E = instmeth_end(); I != E; ++I)
317 if ((*I)->getSelector() == Sel)
318 return *I;
319 return NULL;
320}
321
322/// lookupClassMethod - This method returns a class method by looking in
323/// the class implementation. Unlike interfaces, we don't look outside the
324/// implementation.
325ObjCMethodDecl *ObjCImplementationDecl::getClassMethod(Selector Sel) {
326 for (classmeth_iterator I = classmeth_begin(), E = classmeth_end();
327 I != E; ++I)
328 if ((*I)->getSelector() == Sel)
329 return *I;
330 return NULL;
331}
332
333// lookupInstanceMethod - This method returns an instance method by looking in
334// the class implementation. Unlike interfaces, we don't look outside the
335// implementation.
336ObjCMethodDecl *ObjCCategoryImplDecl::getInstanceMethod(Selector Sel) {
337 for (instmeth_iterator I = instmeth_begin(), E = instmeth_end(); I != E; ++I)
338 if ((*I)->getSelector() == Sel)
339 return *I;
340 return NULL;
341}
342
343// lookupClassMethod - This method returns an instance method by looking in
344// the class implementation. Unlike interfaces, we don't look outside the
345// implementation.
346ObjCMethodDecl *ObjCCategoryImplDecl::getClassMethod(Selector Sel) {
347 for (classmeth_iterator I = classmeth_begin(), E = classmeth_end();
348 I != E; ++I)
349 if ((*I)->getSelector() == Sel)
350 return *I;
351 return NULL;
352}
353
354// lookupInstanceMethod - Lookup a instance method in the protocol and protocols
355// it inherited.
356ObjCMethodDecl *ObjCProtocolDecl::lookupInstanceMethod(Selector Sel) {
357 ObjCMethodDecl *MethodDecl = NULL;
358
359 if ((MethodDecl = getInstanceMethod(Sel)))
360 return MethodDecl;
361
362 if (getNumReferencedProtocols() > 0) {
363 ObjCProtocolDecl **RefPDecl = getReferencedProtocols();
364
365 for (unsigned i = 0; i < getNumReferencedProtocols(); i++) {
366 if ((MethodDecl = RefPDecl[i]->getInstanceMethod(Sel)))
367 return MethodDecl;
368 }
369 }
370 return NULL;
371}
372
373// lookupInstanceMethod - Lookup a class method in the protocol and protocols
374// it inherited.
375ObjCMethodDecl *ObjCProtocolDecl::lookupClassMethod(Selector Sel) {
376 ObjCMethodDecl *MethodDecl = NULL;
377
378 if ((MethodDecl = getClassMethod(Sel)))
379 return MethodDecl;
380
381 if (getNumReferencedProtocols() > 0) {
382 ObjCProtocolDecl **RefPDecl = getReferencedProtocols();
383
384 for(unsigned i = 0; i < getNumReferencedProtocols(); i++) {
385 if ((MethodDecl = RefPDecl[i]->getClassMethod(Sel)))
386 return MethodDecl;
387 }
388 }
389 return NULL;
390}
391
392/// getSynthesizedMethodSize - Compute size of synthesized method name
393/// as done be the rewrite.
394///
395unsigned ObjCMethodDecl::getSynthesizedMethodSize() const {
396 // syntesized method name is a concatenation of -/+[class-name selector]
397 // Get length of this name.
398 unsigned length = 3; // _I_ or _C_
399 length += strlen(getClassInterface()->getName()) +1; // extra for _
400 NamedDecl *MethodContext = getMethodContext();
401 if (ObjCCategoryImplDecl *CID =
402 dyn_cast<ObjCCategoryImplDecl>(MethodContext))
403 length += strlen(CID->getName()) +1;
404 length += getSelector().getName().size(); // selector name
405 return length;
406}
407
408ObjCInterfaceDecl *const ObjCMethodDecl::getClassInterface() const {
409 if (ObjCInterfaceDecl *ID = dyn_cast<ObjCInterfaceDecl>(MethodContext))
410 return ID;
411 if (ObjCCategoryDecl *CD = dyn_cast<ObjCCategoryDecl>(MethodContext))
412 return CD->getClassInterface();
413 if (ObjCImplementationDecl *IMD =
414 dyn_cast<ObjCImplementationDecl>(MethodContext))
415 return IMD->getClassInterface();
416 if (ObjCCategoryImplDecl *CID =
417 dyn_cast<ObjCCategoryImplDecl>(MethodContext))
418 return CID->getClassInterface();
419 assert(false && "unknown method context");
420 return 0;
421}
Chris Lattnerf4af5152008-03-17 01:19:02 +0000422
423void ObjCPropertyDecl::setPropertyDeclLists(ObjCIvarDecl **Properties,
424 unsigned NumProp) {
425 assert(PropertyDecls == 0 && "Properties already set");
426 if (NumProp == 0) return;
427 NumPropertyDecls = NumProp;
428
429 PropertyDecls = new ObjCIvarDecl*[NumProp];
430 memcpy(PropertyDecls, Properties, NumProp*sizeof(ObjCIvarDecl*));
431}
432
433