blob: 6e348cab08b310374d30c4280ce06dd380559711 [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
Chris Lattnereee57c02008-04-04 06:12:32 +000022ObjCMethodDecl *ObjCMethodDecl::Create(ASTContext &C,
23 SourceLocation beginLoc,
Chris Lattner114add62008-03-16 00:49:28 +000024 SourceLocation endLoc,
25 Selector SelInfo, QualType T,
26 Decl *contextDecl,
Chris Lattner114add62008-03-16 00:49:28 +000027 AttributeList *M, bool isInstance,
28 bool isVariadic,
Chris Lattnerf7355832008-03-16 00:58:16 +000029 ImplementationControl impControl) {
Chris Lattner114add62008-03-16 00:49:28 +000030 void *Mem = C.getAllocator().Allocate<ObjCMethodDecl>();
Chris Lattnereee57c02008-04-04 06:12:32 +000031 return new (Mem) ObjCMethodDecl(beginLoc, endLoc,
32 SelInfo, T, contextDecl,
Chris Lattnerf7355832008-03-16 00:58:16 +000033 M, isInstance,
34 isVariadic, impControl);
Chris Lattner0db541b2008-03-16 01:15:50 +000035}
Chris Lattner114add62008-03-16 00:49:28 +000036
Chris Lattnereee57c02008-04-04 06:12:32 +000037ObjCInterfaceDecl *ObjCInterfaceDecl::Create(ASTContext &C,
38 SourceLocation atLoc,
Chris Lattner0db541b2008-03-16 01:15:50 +000039 unsigned numRefProtos,
Steve Naroff7c371742008-04-11 19:35:35 +000040 IdentifierInfo *Id,
41 SourceLocation ClassLoc,
Chris Lattner0db541b2008-03-16 01:15:50 +000042 bool ForwardDecl, bool isInternal){
43 void *Mem = C.getAllocator().Allocate<ObjCInterfaceDecl>();
Chris Lattnereee57c02008-04-04 06:12:32 +000044 return new (Mem) ObjCInterfaceDecl(atLoc, numRefProtos,
Steve Naroff7c371742008-04-11 19:35:35 +000045 Id, ClassLoc, ForwardDecl,
Chris Lattner0db541b2008-03-16 01:15:50 +000046 isInternal);
47}
48
Chris Lattnerf3874bc2008-04-06 04:47:34 +000049ObjCIvarDecl *ObjCIvarDecl::Create(ASTContext &C, SourceLocation L,
Chris Lattner0db541b2008-03-16 01:15:50 +000050 IdentifierInfo *Id, QualType T) {
51 void *Mem = C.getAllocator().Allocate<ObjCIvarDecl>();
Chris Lattnerf3874bc2008-04-06 04:47:34 +000052 return new (Mem) ObjCIvarDecl(L, Id, T);
Chris Lattner114add62008-03-16 00:49:28 +000053}
54
Chris Lattnereee57c02008-04-04 06:12:32 +000055ObjCProtocolDecl *ObjCProtocolDecl::Create(ASTContext &C,
56 SourceLocation L,
Chris Lattner180f7e22008-03-16 01:23:04 +000057 unsigned numRefProtos,
Chris Lattner7afba9c2008-03-16 20:19:15 +000058 IdentifierInfo *Id) {
Chris Lattner180f7e22008-03-16 01:23:04 +000059 void *Mem = C.getAllocator().Allocate<ObjCProtocolDecl>();
Chris Lattner7afba9c2008-03-16 20:19:15 +000060 return new (Mem) ObjCProtocolDecl(L, numRefProtos, Id);
Chris Lattner180f7e22008-03-16 01:23:04 +000061}
62
Chris Lattnereee57c02008-04-04 06:12:32 +000063ObjCClassDecl *ObjCClassDecl::Create(ASTContext &C,
64 SourceLocation L,
Chris Lattnere29dc832008-03-16 20:34:23 +000065 ObjCInterfaceDecl **Elts, unsigned nElts) {
66 void *Mem = C.getAllocator().Allocate<ObjCClassDecl>();
67 return new (Mem) ObjCClassDecl(L, Elts, nElts);
68}
69
70ObjCForwardProtocolDecl *
Chris Lattnereee57c02008-04-04 06:12:32 +000071ObjCForwardProtocolDecl::Create(ASTContext &C,
72 SourceLocation L,
Chris Lattnere29dc832008-03-16 20:34:23 +000073 ObjCProtocolDecl **Elts, unsigned NumElts) {
74 void *Mem = C.getAllocator().Allocate<ObjCForwardProtocolDecl>();
75 return new (Mem) ObjCForwardProtocolDecl(L, Elts, NumElts);
76}
77
Chris Lattnereee57c02008-04-04 06:12:32 +000078ObjCCategoryDecl *ObjCCategoryDecl::Create(ASTContext &C,
79 SourceLocation L,
Chris Lattnere29dc832008-03-16 20:34:23 +000080 IdentifierInfo *Id) {
81 void *Mem = C.getAllocator().Allocate<ObjCCategoryDecl>();
Chris Lattner321b5d12008-03-16 20:47:45 +000082 return new (Mem) ObjCCategoryDecl(L, Id);
Chris Lattnere29dc832008-03-16 20:34:23 +000083}
84
Chris Lattner1b6de332008-03-16 20:53:07 +000085ObjCCategoryImplDecl *
Chris Lattnereee57c02008-04-04 06:12:32 +000086ObjCCategoryImplDecl::Create(ASTContext &C,
87 SourceLocation L,IdentifierInfo *Id,
Chris Lattner1b6de332008-03-16 20:53:07 +000088 ObjCInterfaceDecl *ClassInterface) {
89 void *Mem = C.getAllocator().Allocate<ObjCCategoryImplDecl>();
90 return new (Mem) ObjCCategoryImplDecl(L, Id, ClassInterface);
91}
92
93ObjCImplementationDecl *
Chris Lattnereee57c02008-04-04 06:12:32 +000094ObjCImplementationDecl::Create(ASTContext &C,
95 SourceLocation L,
Chris Lattner1b6de332008-03-16 20:53:07 +000096 IdentifierInfo *Id,
97 ObjCInterfaceDecl *ClassInterface,
98 ObjCInterfaceDecl *SuperDecl) {
99 void *Mem = C.getAllocator().Allocate<ObjCImplementationDecl>();
100 return new (Mem) ObjCImplementationDecl(L, Id, ClassInterface, SuperDecl);
101}
Chris Lattner10318b82008-03-16 00:19:01 +0000102
Chris Lattner2d1c4312008-03-16 21:17:37 +0000103ObjCCompatibleAliasDecl *
Chris Lattnereee57c02008-04-04 06:12:32 +0000104ObjCCompatibleAliasDecl::Create(ASTContext &C,
105 SourceLocation L,
Chris Lattner2d1c4312008-03-16 21:17:37 +0000106 IdentifierInfo *Id,
107 ObjCInterfaceDecl* AliasedClass) {
108 void *Mem = C.getAllocator().Allocate<ObjCCompatibleAliasDecl>();
109 return new (Mem) ObjCCompatibleAliasDecl(L, Id, AliasedClass);
110}
111
Chris Lattnereee57c02008-04-04 06:12:32 +0000112ObjCPropertyDecl *ObjCPropertyDecl::Create(ASTContext &C,
Fariborz Jahaniane7071722008-04-11 23:40:25 +0000113 SourceLocation L,
114 QualType T) {
Chris Lattner2d1c4312008-03-16 21:17:37 +0000115 void *Mem = C.getAllocator().Allocate<ObjCPropertyDecl>();
Fariborz Jahaniane7071722008-04-11 23:40:25 +0000116 return new (Mem) ObjCPropertyDecl(L, T);
Chris Lattner2d1c4312008-03-16 21:17:37 +0000117}
118
Chris Lattner10318b82008-03-16 00:19:01 +0000119//===----------------------------------------------------------------------===//
120// Objective-C Decl Implementation
121//===----------------------------------------------------------------------===//
122
123void ObjCMethodDecl::setMethodParams(ParmVarDecl **NewParamInfo,
124 unsigned NumParams) {
125 assert(ParamInfo == 0 && "Already has param info!");
126
127 // Zero params -> null pointer.
128 if (NumParams) {
129 ParamInfo = new ParmVarDecl*[NumParams];
130 memcpy(ParamInfo, NewParamInfo, sizeof(ParmVarDecl*)*NumParams);
131 NumMethodParams = NumParams;
132 }
133}
134
135ObjCMethodDecl::~ObjCMethodDecl() {
136 delete[] ParamInfo;
137}
138
139/// ObjCAddInstanceVariablesToClass - Inserts instance variables
140/// into ObjCInterfaceDecl's fields.
141///
142void ObjCInterfaceDecl::addInstanceVariablesToClass(ObjCIvarDecl **ivars,
143 unsigned numIvars,
144 SourceLocation RBrac) {
145 NumIvars = numIvars;
146 if (numIvars) {
147 Ivars = new ObjCIvarDecl*[numIvars];
148 memcpy(Ivars, ivars, numIvars*sizeof(ObjCIvarDecl*));
149 }
150 setLocEnd(RBrac);
151}
152
153/// ObjCAddInstanceVariablesToClassImpl - Checks for correctness of Instance
154/// Variables (Ivars) relative to what declared in @implementation;s class.
155/// Ivars into ObjCImplementationDecl's fields.
156///
157void ObjCImplementationDecl::ObjCAddInstanceVariablesToClassImpl(
158 ObjCIvarDecl **ivars, unsigned numIvars) {
159 NumIvars = numIvars;
160 if (numIvars) {
161 Ivars = new ObjCIvarDecl*[numIvars];
162 memcpy(Ivars, ivars, numIvars*sizeof(ObjCIvarDecl*));
163 }
164}
165
166/// addMethods - Insert instance and methods declarations into
167/// ObjCInterfaceDecl's InsMethods and ClsMethods fields.
168///
169void ObjCInterfaceDecl::addMethods(ObjCMethodDecl **insMethods,
170 unsigned numInsMembers,
171 ObjCMethodDecl **clsMethods,
172 unsigned numClsMembers,
173 SourceLocation endLoc) {
174 NumInstanceMethods = numInsMembers;
175 if (numInsMembers) {
176 InstanceMethods = new ObjCMethodDecl*[numInsMembers];
177 memcpy(InstanceMethods, insMethods, numInsMembers*sizeof(ObjCMethodDecl*));
178 }
179 NumClassMethods = numClsMembers;
180 if (numClsMembers) {
181 ClassMethods = new ObjCMethodDecl*[numClsMembers];
182 memcpy(ClassMethods, clsMethods, numClsMembers*sizeof(ObjCMethodDecl*));
183 }
184 AtEndLoc = endLoc;
185}
186
187/// addMethods - Insert instance and methods declarations into
Chris Lattnercffe3662008-03-16 21:23:50 +0000188/// ObjCInterfaceDecl's InsMethods and ClsMethods fields.
189///
190void ObjCInterfaceDecl::addProperties(ObjCPropertyDecl **Properties,
191 unsigned NumProperties) {
192 if (NumProperties == 0) return;
193
194 NumPropertyDecl = NumProperties;
195 PropertyDecl = new ObjCPropertyDecl*[NumProperties];
196 memcpy(PropertyDecl, Properties, NumProperties*sizeof(ObjCPropertyDecl*));
197}
198
199/// addMethods - Insert instance and methods declarations into
Chris Lattner10318b82008-03-16 00:19:01 +0000200/// ObjCProtocolDecl's ProtoInsMethods and ProtoClsMethods fields.
201///
202void ObjCProtocolDecl::addMethods(ObjCMethodDecl **insMethods,
203 unsigned numInsMembers,
204 ObjCMethodDecl **clsMethods,
205 unsigned numClsMembers,
206 SourceLocation endLoc) {
207 NumInstanceMethods = numInsMembers;
208 if (numInsMembers) {
209 InstanceMethods = new ObjCMethodDecl*[numInsMembers];
210 memcpy(InstanceMethods, insMethods, numInsMembers*sizeof(ObjCMethodDecl*));
211 }
212 NumClassMethods = numClsMembers;
213 if (numClsMembers) {
214 ClassMethods = new ObjCMethodDecl*[numClsMembers];
215 memcpy(ClassMethods, clsMethods, numClsMembers*sizeof(ObjCMethodDecl*));
216 }
217 AtEndLoc = endLoc;
218}
219
Chris Lattner321b5d12008-03-16 20:47:45 +0000220void ObjCCategoryDecl::setReferencedProtocolList(ObjCProtocolDecl **List,
221 unsigned NumRPs) {
222 assert(NumReferencedProtocols == 0 && "Protocol list already set");
223 if (NumRPs == 0) return;
224
225 ReferencedProtocols = new ObjCProtocolDecl*[NumRPs];
226 memcpy(ReferencedProtocols, List, NumRPs*sizeof(ObjCProtocolDecl*));
227 NumReferencedProtocols = NumRPs;
228}
229
230
Chris Lattner10318b82008-03-16 00:19:01 +0000231/// addMethods - Insert instance and methods declarations into
232/// ObjCCategoryDecl's CatInsMethods and CatClsMethods fields.
233///
234void ObjCCategoryDecl::addMethods(ObjCMethodDecl **insMethods,
235 unsigned numInsMembers,
236 ObjCMethodDecl **clsMethods,
237 unsigned numClsMembers,
238 SourceLocation endLoc) {
239 NumInstanceMethods = numInsMembers;
240 if (numInsMembers) {
241 InstanceMethods = new ObjCMethodDecl*[numInsMembers];
242 memcpy(InstanceMethods, insMethods, numInsMembers*sizeof(ObjCMethodDecl*));
243 }
244 NumClassMethods = numClsMembers;
245 if (numClsMembers) {
246 ClassMethods = new ObjCMethodDecl*[numClsMembers];
247 memcpy(ClassMethods, clsMethods, numClsMembers*sizeof(ObjCMethodDecl*));
248 }
249 AtEndLoc = endLoc;
250}
251
252ObjCIvarDecl *ObjCInterfaceDecl::lookupInstanceVariable(
253 IdentifierInfo *ID, ObjCInterfaceDecl *&clsDeclared) {
254 ObjCInterfaceDecl* ClassDecl = this;
255 while (ClassDecl != NULL) {
256 for (ivar_iterator I = ClassDecl->ivar_begin(), E = ClassDecl->ivar_end();
257 I != E; ++I) {
258 if ((*I)->getIdentifier() == ID) {
259 clsDeclared = ClassDecl;
260 return *I;
261 }
262 }
263 ClassDecl = ClassDecl->getSuperClass();
264 }
265 return NULL;
266}
267
268/// lookupInstanceMethod - This method returns an instance method by looking in
269/// the class, its categories, and its super classes (using a linear search).
270ObjCMethodDecl *ObjCInterfaceDecl::lookupInstanceMethod(Selector Sel) {
271 ObjCInterfaceDecl* ClassDecl = this;
272 ObjCMethodDecl *MethodDecl = 0;
273
274 while (ClassDecl != NULL) {
275 if ((MethodDecl = ClassDecl->getInstanceMethod(Sel)))
276 return MethodDecl;
277
278 // Didn't find one yet - look through protocols.
279 ObjCProtocolDecl **protocols = ClassDecl->getReferencedProtocols();
280 int numProtocols = ClassDecl->getNumIntfRefProtocols();
281 for (int pIdx = 0; pIdx < numProtocols; pIdx++) {
282 if ((MethodDecl = protocols[pIdx]->getInstanceMethod(Sel)))
283 return MethodDecl;
284 }
285 // Didn't find one yet - now look through categories.
286 ObjCCategoryDecl *CatDecl = ClassDecl->getCategoryList();
287 while (CatDecl) {
288 if ((MethodDecl = CatDecl->getInstanceMethod(Sel)))
289 return MethodDecl;
290 CatDecl = CatDecl->getNextClassCategory();
291 }
292 ClassDecl = ClassDecl->getSuperClass();
293 }
294 return NULL;
295}
296
297// lookupClassMethod - This method returns a class method by looking in the
298// class, its categories, and its super classes (using a linear search).
299ObjCMethodDecl *ObjCInterfaceDecl::lookupClassMethod(Selector Sel) {
300 ObjCInterfaceDecl* ClassDecl = this;
301 ObjCMethodDecl *MethodDecl = 0;
302
303 while (ClassDecl != NULL) {
304 if ((MethodDecl = ClassDecl->getClassMethod(Sel)))
305 return MethodDecl;
306
307 // Didn't find one yet - look through protocols.
308 ObjCProtocolDecl **protocols = ClassDecl->getReferencedProtocols();
309 int numProtocols = ClassDecl->getNumIntfRefProtocols();
310 for (int pIdx = 0; pIdx < numProtocols; pIdx++) {
311 if ((MethodDecl = protocols[pIdx]->getClassMethod(Sel)))
312 return MethodDecl;
313 }
314 // Didn't find one yet - now look through categories.
315 ObjCCategoryDecl *CatDecl = ClassDecl->getCategoryList();
316 while (CatDecl) {
317 if ((MethodDecl = CatDecl->getClassMethod(Sel)))
318 return MethodDecl;
319 CatDecl = CatDecl->getNextClassCategory();
320 }
321 ClassDecl = ClassDecl->getSuperClass();
322 }
323 return NULL;
324}
325
326/// lookupInstanceMethod - This method returns an instance method by looking in
327/// the class implementation. Unlike interfaces, we don't look outside the
328/// implementation.
329ObjCMethodDecl *ObjCImplementationDecl::getInstanceMethod(Selector Sel) {
330 for (instmeth_iterator I = instmeth_begin(), E = instmeth_end(); I != E; ++I)
331 if ((*I)->getSelector() == Sel)
332 return *I;
333 return NULL;
334}
335
336/// lookupClassMethod - This method returns a class method by looking in
337/// the class implementation. Unlike interfaces, we don't look outside the
338/// implementation.
339ObjCMethodDecl *ObjCImplementationDecl::getClassMethod(Selector Sel) {
340 for (classmeth_iterator I = classmeth_begin(), E = classmeth_end();
341 I != E; ++I)
342 if ((*I)->getSelector() == Sel)
343 return *I;
344 return NULL;
345}
346
347// lookupInstanceMethod - This method returns an instance method by looking in
348// the class implementation. Unlike interfaces, we don't look outside the
349// implementation.
350ObjCMethodDecl *ObjCCategoryImplDecl::getInstanceMethod(Selector Sel) {
351 for (instmeth_iterator I = instmeth_begin(), E = instmeth_end(); I != E; ++I)
352 if ((*I)->getSelector() == Sel)
353 return *I;
354 return NULL;
355}
356
357// lookupClassMethod - This method returns an instance method by looking in
358// the class implementation. Unlike interfaces, we don't look outside the
359// implementation.
360ObjCMethodDecl *ObjCCategoryImplDecl::getClassMethod(Selector Sel) {
361 for (classmeth_iterator I = classmeth_begin(), E = classmeth_end();
362 I != E; ++I)
363 if ((*I)->getSelector() == Sel)
364 return *I;
365 return NULL;
366}
367
368// lookupInstanceMethod - Lookup a instance method in the protocol and protocols
369// it inherited.
370ObjCMethodDecl *ObjCProtocolDecl::lookupInstanceMethod(Selector Sel) {
371 ObjCMethodDecl *MethodDecl = NULL;
372
373 if ((MethodDecl = getInstanceMethod(Sel)))
374 return MethodDecl;
375
376 if (getNumReferencedProtocols() > 0) {
377 ObjCProtocolDecl **RefPDecl = getReferencedProtocols();
378
379 for (unsigned i = 0; i < getNumReferencedProtocols(); i++) {
380 if ((MethodDecl = RefPDecl[i]->getInstanceMethod(Sel)))
381 return MethodDecl;
382 }
383 }
384 return NULL;
385}
386
387// lookupInstanceMethod - Lookup a class method in the protocol and protocols
388// it inherited.
389ObjCMethodDecl *ObjCProtocolDecl::lookupClassMethod(Selector Sel) {
390 ObjCMethodDecl *MethodDecl = NULL;
391
392 if ((MethodDecl = getClassMethod(Sel)))
393 return MethodDecl;
394
395 if (getNumReferencedProtocols() > 0) {
396 ObjCProtocolDecl **RefPDecl = getReferencedProtocols();
397
398 for(unsigned i = 0; i < getNumReferencedProtocols(); i++) {
399 if ((MethodDecl = RefPDecl[i]->getClassMethod(Sel)))
400 return MethodDecl;
401 }
402 }
403 return NULL;
404}
405
406/// getSynthesizedMethodSize - Compute size of synthesized method name
407/// as done be the rewrite.
408///
409unsigned ObjCMethodDecl::getSynthesizedMethodSize() const {
410 // syntesized method name is a concatenation of -/+[class-name selector]
411 // Get length of this name.
412 unsigned length = 3; // _I_ or _C_
413 length += strlen(getClassInterface()->getName()) +1; // extra for _
414 NamedDecl *MethodContext = getMethodContext();
415 if (ObjCCategoryImplDecl *CID =
416 dyn_cast<ObjCCategoryImplDecl>(MethodContext))
417 length += strlen(CID->getName()) +1;
418 length += getSelector().getName().size(); // selector name
419 return length;
420}
421
Chris Lattner052fbcd2008-04-06 05:25:03 +0000422ObjCInterfaceDecl *ObjCMethodDecl::getClassInterface() {
Chris Lattner10318b82008-03-16 00:19:01 +0000423 if (ObjCInterfaceDecl *ID = dyn_cast<ObjCInterfaceDecl>(MethodContext))
424 return ID;
425 if (ObjCCategoryDecl *CD = dyn_cast<ObjCCategoryDecl>(MethodContext))
426 return CD->getClassInterface();
427 if (ObjCImplementationDecl *IMD =
Chris Lattner052fbcd2008-04-06 05:25:03 +0000428 dyn_cast<ObjCImplementationDecl>(MethodContext))
Chris Lattner10318b82008-03-16 00:19:01 +0000429 return IMD->getClassInterface();
Chris Lattner052fbcd2008-04-06 05:25:03 +0000430 if (ObjCCategoryImplDecl *CID = dyn_cast<ObjCCategoryImplDecl>(MethodContext))
Chris Lattner10318b82008-03-16 00:19:01 +0000431 return CID->getClassInterface();
432 assert(false && "unknown method context");
433 return 0;
434}
Chris Lattner44859612008-03-17 01:19:02 +0000435
Chris Lattner44859612008-03-17 01:19:02 +0000436
Chris Lattnereee57c02008-04-04 06:12:32 +0000437