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