blob: cda73d2ff9cdb0c2c579225c4b662fb971274a77 [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,
Fariborz Jahanian5f2e2242008-05-07 20:53:44 +000029 bool isSynthesized,
Chris Lattnerf7355832008-03-16 00:58:16 +000030 ImplementationControl impControl) {
Chris Lattner114add62008-03-16 00:49:28 +000031 void *Mem = C.getAllocator().Allocate<ObjCMethodDecl>();
Chris Lattnereee57c02008-04-04 06:12:32 +000032 return new (Mem) ObjCMethodDecl(beginLoc, endLoc,
33 SelInfo, T, contextDecl,
Chris Lattnerf7355832008-03-16 00:58:16 +000034 M, isInstance,
Fariborz Jahanian5f2e2242008-05-07 20:53:44 +000035 isVariadic, isSynthesized, impControl);
Chris Lattner0db541b2008-03-16 01:15:50 +000036}
Chris Lattner114add62008-03-16 00:49:28 +000037
Chris Lattnereee57c02008-04-04 06:12:32 +000038ObjCInterfaceDecl *ObjCInterfaceDecl::Create(ASTContext &C,
39 SourceLocation atLoc,
Chris Lattner0db541b2008-03-16 01:15:50 +000040 unsigned numRefProtos,
Steve Naroff7c371742008-04-11 19:35:35 +000041 IdentifierInfo *Id,
42 SourceLocation ClassLoc,
Chris Lattner0db541b2008-03-16 01:15:50 +000043 bool ForwardDecl, bool isInternal){
44 void *Mem = C.getAllocator().Allocate<ObjCInterfaceDecl>();
Chris Lattnereee57c02008-04-04 06:12:32 +000045 return new (Mem) ObjCInterfaceDecl(atLoc, numRefProtos,
Steve Naroff7c371742008-04-11 19:35:35 +000046 Id, ClassLoc, ForwardDecl,
Chris Lattner0db541b2008-03-16 01:15:50 +000047 isInternal);
48}
49
Chris Lattnerf3874bc2008-04-06 04:47:34 +000050ObjCIvarDecl *ObjCIvarDecl::Create(ASTContext &C, SourceLocation L,
Chris Lattner0db541b2008-03-16 01:15:50 +000051 IdentifierInfo *Id, QualType T) {
52 void *Mem = C.getAllocator().Allocate<ObjCIvarDecl>();
Chris Lattnerf3874bc2008-04-06 04:47:34 +000053 return new (Mem) ObjCIvarDecl(L, Id, T);
Chris Lattner114add62008-03-16 00:49:28 +000054}
55
Chris Lattnereee57c02008-04-04 06:12:32 +000056ObjCProtocolDecl *ObjCProtocolDecl::Create(ASTContext &C,
57 SourceLocation L,
Chris Lattner180f7e22008-03-16 01:23:04 +000058 unsigned numRefProtos,
Chris Lattner7afba9c2008-03-16 20:19:15 +000059 IdentifierInfo *Id) {
Chris Lattner180f7e22008-03-16 01:23:04 +000060 void *Mem = C.getAllocator().Allocate<ObjCProtocolDecl>();
Chris Lattner7afba9c2008-03-16 20:19:15 +000061 return new (Mem) ObjCProtocolDecl(L, numRefProtos, Id);
Chris Lattner180f7e22008-03-16 01:23:04 +000062}
63
Chris Lattnereee57c02008-04-04 06:12:32 +000064ObjCClassDecl *ObjCClassDecl::Create(ASTContext &C,
65 SourceLocation L,
Chris Lattnere29dc832008-03-16 20:34:23 +000066 ObjCInterfaceDecl **Elts, unsigned nElts) {
67 void *Mem = C.getAllocator().Allocate<ObjCClassDecl>();
68 return new (Mem) ObjCClassDecl(L, Elts, nElts);
69}
70
71ObjCForwardProtocolDecl *
Chris Lattnereee57c02008-04-04 06:12:32 +000072ObjCForwardProtocolDecl::Create(ASTContext &C,
73 SourceLocation L,
Chris Lattnere29dc832008-03-16 20:34:23 +000074 ObjCProtocolDecl **Elts, unsigned NumElts) {
75 void *Mem = C.getAllocator().Allocate<ObjCForwardProtocolDecl>();
76 return new (Mem) ObjCForwardProtocolDecl(L, Elts, NumElts);
77}
78
Chris Lattnereee57c02008-04-04 06:12:32 +000079ObjCCategoryDecl *ObjCCategoryDecl::Create(ASTContext &C,
80 SourceLocation L,
Chris Lattnere29dc832008-03-16 20:34:23 +000081 IdentifierInfo *Id) {
82 void *Mem = C.getAllocator().Allocate<ObjCCategoryDecl>();
Chris Lattner321b5d12008-03-16 20:47:45 +000083 return new (Mem) ObjCCategoryDecl(L, Id);
Chris Lattnere29dc832008-03-16 20:34:23 +000084}
85
Chris Lattner1b6de332008-03-16 20:53:07 +000086ObjCCategoryImplDecl *
Chris Lattnereee57c02008-04-04 06:12:32 +000087ObjCCategoryImplDecl::Create(ASTContext &C,
88 SourceLocation L,IdentifierInfo *Id,
Chris Lattner1b6de332008-03-16 20:53:07 +000089 ObjCInterfaceDecl *ClassInterface) {
90 void *Mem = C.getAllocator().Allocate<ObjCCategoryImplDecl>();
91 return new (Mem) ObjCCategoryImplDecl(L, Id, ClassInterface);
92}
93
94ObjCImplementationDecl *
Chris Lattnereee57c02008-04-04 06:12:32 +000095ObjCImplementationDecl::Create(ASTContext &C,
96 SourceLocation L,
Chris Lattner1b6de332008-03-16 20:53:07 +000097 IdentifierInfo *Id,
98 ObjCInterfaceDecl *ClassInterface,
99 ObjCInterfaceDecl *SuperDecl) {
100 void *Mem = C.getAllocator().Allocate<ObjCImplementationDecl>();
101 return new (Mem) ObjCImplementationDecl(L, Id, ClassInterface, SuperDecl);
102}
Chris Lattner10318b82008-03-16 00:19:01 +0000103
Chris Lattner2d1c4312008-03-16 21:17:37 +0000104ObjCCompatibleAliasDecl *
Chris Lattnereee57c02008-04-04 06:12:32 +0000105ObjCCompatibleAliasDecl::Create(ASTContext &C,
106 SourceLocation L,
Chris Lattner2d1c4312008-03-16 21:17:37 +0000107 IdentifierInfo *Id,
108 ObjCInterfaceDecl* AliasedClass) {
109 void *Mem = C.getAllocator().Allocate<ObjCCompatibleAliasDecl>();
110 return new (Mem) ObjCCompatibleAliasDecl(L, Id, AliasedClass);
111}
112
Chris Lattnereee57c02008-04-04 06:12:32 +0000113ObjCPropertyDecl *ObjCPropertyDecl::Create(ASTContext &C,
Fariborz Jahaniane7071722008-04-11 23:40:25 +0000114 SourceLocation L,
Fariborz Jahanian0ceb4be2008-04-14 23:36:35 +0000115 IdentifierInfo *Id,
Fariborz Jahanian4aa72a72008-05-05 18:51:55 +0000116 QualType T,
117 PropertyControl propControl) {
Chris Lattner2d1c4312008-03-16 21:17:37 +0000118 void *Mem = C.getAllocator().Allocate<ObjCPropertyDecl>();
Fariborz Jahanian0ceb4be2008-04-14 23:36:35 +0000119 return new (Mem) ObjCPropertyDecl(L, Id, T);
Chris Lattner2d1c4312008-03-16 21:17:37 +0000120}
121
Chris Lattner10318b82008-03-16 00:19:01 +0000122//===----------------------------------------------------------------------===//
123// Objective-C Decl Implementation
124//===----------------------------------------------------------------------===//
125
126void ObjCMethodDecl::setMethodParams(ParmVarDecl **NewParamInfo,
127 unsigned NumParams) {
128 assert(ParamInfo == 0 && "Already has param info!");
129
130 // Zero params -> null pointer.
131 if (NumParams) {
132 ParamInfo = new ParmVarDecl*[NumParams];
133 memcpy(ParamInfo, NewParamInfo, sizeof(ParmVarDecl*)*NumParams);
134 NumMethodParams = NumParams;
135 }
136}
137
138ObjCMethodDecl::~ObjCMethodDecl() {
139 delete[] ParamInfo;
140}
141
Fariborz Jahanianef8a3df2008-04-21 19:04:53 +0000142/// FindPropertyDeclaration - Finds declaration of the property given its name
143/// in 'PropertyId' and returns it. It returns 0, if not found.
144///
145ObjCPropertyDecl *
146 ObjCInterfaceDecl::FindPropertyDeclaration(IdentifierInfo *PropertyId) const {
147 for (ObjCInterfaceDecl::classprop_iterator I = classprop_begin(),
148 E = classprop_end(); I != E; ++I) {
149 ObjCPropertyDecl *property = *I;
150 if (property->getIdentifier() == PropertyId)
151 return property;
152 }
Fariborz Jahanian8acf3352008-04-21 23:57:08 +0000153 if (getSuperClass())
154 return getSuperClass()->FindPropertyDeclaration(PropertyId);
Fariborz Jahanianef8a3df2008-04-21 19:04:53 +0000155 return 0;
156}
157
158/// FindCategoryDeclaration - Finds category declaration in the list of
159/// categories for this class and returns it. Name of the category is passed
160/// in 'CategoryId'. If category not found, return 0;
161///
162ObjCCategoryDecl *
163 ObjCInterfaceDecl::FindCategoryDeclaration(IdentifierInfo *CategoryId) const {
164 for (ObjCCategoryDecl *Category = getCategoryList();
165 Category; Category = Category->getNextClassCategory())
166 if (Category->getIdentifier() == CategoryId)
167 return Category;
168 return 0;
169}
170
171/// FindIvarDeclaration - Find an Ivar declaration in this class given its
172/// name in 'IvarId'. On failure to find, return 0;
173///
174ObjCIvarDecl *
175 ObjCInterfaceDecl::FindIvarDeclaration(IdentifierInfo *IvarId) const {
176 for (ObjCInterfaceDecl::ivar_iterator IVI = ivar_begin(),
177 IVE = ivar_end(); IVI != IVE; ++IVI) {
178 ObjCIvarDecl* Ivar = (*IVI);
179 if (Ivar->getIdentifier() == IvarId)
180 return Ivar;
181 }
Fariborz Jahanian8acf3352008-04-21 23:57:08 +0000182 if (getSuperClass())
183 return getSuperClass()->FindIvarDeclaration(IvarId);
Fariborz Jahanianef8a3df2008-04-21 19:04:53 +0000184 return 0;
185}
186
Chris Lattner10318b82008-03-16 00:19:01 +0000187/// ObjCAddInstanceVariablesToClass - Inserts instance variables
188/// into ObjCInterfaceDecl's fields.
189///
190void ObjCInterfaceDecl::addInstanceVariablesToClass(ObjCIvarDecl **ivars,
191 unsigned numIvars,
192 SourceLocation RBrac) {
193 NumIvars = numIvars;
194 if (numIvars) {
195 Ivars = new ObjCIvarDecl*[numIvars];
196 memcpy(Ivars, ivars, numIvars*sizeof(ObjCIvarDecl*));
197 }
198 setLocEnd(RBrac);
199}
200
201/// ObjCAddInstanceVariablesToClassImpl - Checks for correctness of Instance
202/// Variables (Ivars) relative to what declared in @implementation;s class.
203/// Ivars into ObjCImplementationDecl's fields.
204///
205void ObjCImplementationDecl::ObjCAddInstanceVariablesToClassImpl(
206 ObjCIvarDecl **ivars, unsigned numIvars) {
207 NumIvars = numIvars;
208 if (numIvars) {
209 Ivars = new ObjCIvarDecl*[numIvars];
210 memcpy(Ivars, ivars, numIvars*sizeof(ObjCIvarDecl*));
211 }
212}
213
214/// addMethods - Insert instance and methods declarations into
215/// ObjCInterfaceDecl's InsMethods and ClsMethods fields.
216///
217void ObjCInterfaceDecl::addMethods(ObjCMethodDecl **insMethods,
218 unsigned numInsMembers,
219 ObjCMethodDecl **clsMethods,
220 unsigned numClsMembers,
221 SourceLocation endLoc) {
222 NumInstanceMethods = numInsMembers;
223 if (numInsMembers) {
224 InstanceMethods = new ObjCMethodDecl*[numInsMembers];
225 memcpy(InstanceMethods, insMethods, numInsMembers*sizeof(ObjCMethodDecl*));
226 }
227 NumClassMethods = numClsMembers;
228 if (numClsMembers) {
229 ClassMethods = new ObjCMethodDecl*[numClsMembers];
230 memcpy(ClassMethods, clsMethods, numClsMembers*sizeof(ObjCMethodDecl*));
231 }
232 AtEndLoc = endLoc;
233}
234
Fariborz Jahanian52ff8442008-04-16 21:08:45 +0000235/// addProperties - Insert property declaration AST nodes into
236/// ObjCInterfaceDecl's PropertyDecl field.
Chris Lattnercffe3662008-03-16 21:23:50 +0000237///
238void ObjCInterfaceDecl::addProperties(ObjCPropertyDecl **Properties,
239 unsigned NumProperties) {
240 if (NumProperties == 0) return;
241
242 NumPropertyDecl = NumProperties;
243 PropertyDecl = new ObjCPropertyDecl*[NumProperties];
244 memcpy(PropertyDecl, Properties, NumProperties*sizeof(ObjCPropertyDecl*));
245}
246
Fariborz Jahanian33973a22008-05-02 19:17:30 +0000247/// mergeProperties - Adds properties to the end of list of current properties
248/// for this class.
249
250void ObjCInterfaceDecl::mergeProperties(ObjCPropertyDecl **Properties,
251 unsigned NumNewProperties) {
252 if (NumNewProperties == 0) return;
253
254 if (PropertyDecl) {
255 ObjCPropertyDecl **newPropertyDecl =
256 new ObjCPropertyDecl*[NumNewProperties + NumPropertyDecl];
257 ObjCPropertyDecl **buf = newPropertyDecl;
258 // put back original properties in buffer.
259 memcpy(buf, PropertyDecl, NumPropertyDecl*sizeof(ObjCPropertyDecl*));
260 // Add new properties to this buffer.
261 memcpy(buf+NumPropertyDecl, Properties,
262 NumNewProperties*sizeof(ObjCPropertyDecl*));
263 free(PropertyDecl);
264 PropertyDecl = newPropertyDecl;
265 NumPropertyDecl += NumNewProperties;
266 }
267 else {
268 PropertyDecl = new ObjCPropertyDecl*[NumNewProperties];
269 memcpy(PropertyDecl, Properties, NumNewProperties*sizeof(ObjCPropertyDecl*));
270 NumPropertyDecl = NumNewProperties;
271 }
272}
273
Fariborz Jahaniane4534e72008-05-07 17:43:59 +0000274/// addPropertyMethods - Goes through list of properties declared in this class
275/// and builds setter/getter method declartions depending on the setter/getter
276/// attributes of the property.
277///
278void ObjCInterfaceDecl::addPropertyMethods(
279 ASTContext &Context,
280 ObjCPropertyDecl *property,
281 llvm::SmallVector<ObjCMethodDecl*, 32> &insMethods) {
282 // Find the default getter and if one not found, add one.
283 ObjCMethodDecl *GetterDecl = getInstanceMethod(property->getGetterName());
284 if (GetterDecl) {
285 // An instance method with same name as property getter name found.
286 property->setGetterMethodDecl(GetterDecl);
287 }
288 else {
289 // No instance method of same name as property getter name was found.
290 // Declare a getter method and add it to the list of methods
291 // for this class.
292 QualType resultDeclType = property->getType();
293 ObjCMethodDecl* ObjCMethod =
294 ObjCMethodDecl::Create(Context, property->getLocation(),
295 property->getLocation(),
296 property->getGetterName(), resultDeclType,
297 this, 0,
Fariborz Jahanian5f2e2242008-05-07 20:53:44 +0000298 true, false, true, ObjCMethodDecl::Required);
Fariborz Jahaniane4534e72008-05-07 17:43:59 +0000299 property->setGetterMethodDecl(ObjCMethod);
300 insMethods.push_back(ObjCMethod);
301 }
302}
303
Fariborz Jahanian52ff8442008-04-16 21:08:45 +0000304/// addProperties - Insert property declaration AST nodes into
Fariborz Jahanian8516e9a2008-04-17 18:25:18 +0000305/// ObjCProtocolDecl's PropertyDecl field.
306///
307void ObjCProtocolDecl::addProperties(ObjCPropertyDecl **Properties,
308 unsigned NumProperties) {
309 if (NumProperties == 0) return;
310
311 NumPropertyDecl = NumProperties;
312 PropertyDecl = new ObjCPropertyDecl*[NumProperties];
313 memcpy(PropertyDecl, Properties, NumProperties*sizeof(ObjCPropertyDecl*));
314}
315
316/// addProperties - Insert property declaration AST nodes into
Fariborz Jahanian5742a0f2008-04-16 21:11:25 +0000317/// ObjCCategoryDecl's PropertyDecl field.
Fariborz Jahanian52ff8442008-04-16 21:08:45 +0000318///
319void ObjCCategoryDecl::addProperties(ObjCPropertyDecl **Properties,
320 unsigned NumProperties) {
321 if (NumProperties == 0) return;
322
323 NumPropertyDecl = NumProperties;
324 PropertyDecl = new ObjCPropertyDecl*[NumProperties];
325 memcpy(PropertyDecl, Properties, NumProperties*sizeof(ObjCPropertyDecl*));
326}
327
Chris Lattnercffe3662008-03-16 21:23:50 +0000328/// addMethods - Insert instance and methods declarations into
Chris Lattner10318b82008-03-16 00:19:01 +0000329/// ObjCProtocolDecl's ProtoInsMethods and ProtoClsMethods fields.
330///
331void ObjCProtocolDecl::addMethods(ObjCMethodDecl **insMethods,
332 unsigned numInsMembers,
333 ObjCMethodDecl **clsMethods,
334 unsigned numClsMembers,
335 SourceLocation endLoc) {
336 NumInstanceMethods = numInsMembers;
337 if (numInsMembers) {
338 InstanceMethods = new ObjCMethodDecl*[numInsMembers];
339 memcpy(InstanceMethods, insMethods, numInsMembers*sizeof(ObjCMethodDecl*));
340 }
341 NumClassMethods = numClsMembers;
342 if (numClsMembers) {
343 ClassMethods = new ObjCMethodDecl*[numClsMembers];
344 memcpy(ClassMethods, clsMethods, numClsMembers*sizeof(ObjCMethodDecl*));
345 }
346 AtEndLoc = endLoc;
347}
348
Chris Lattner321b5d12008-03-16 20:47:45 +0000349void ObjCCategoryDecl::setReferencedProtocolList(ObjCProtocolDecl **List,
350 unsigned NumRPs) {
351 assert(NumReferencedProtocols == 0 && "Protocol list already set");
352 if (NumRPs == 0) return;
353
354 ReferencedProtocols = new ObjCProtocolDecl*[NumRPs];
355 memcpy(ReferencedProtocols, List, NumRPs*sizeof(ObjCProtocolDecl*));
356 NumReferencedProtocols = NumRPs;
357}
358
359
Chris Lattner10318b82008-03-16 00:19:01 +0000360/// addMethods - Insert instance and methods declarations into
361/// ObjCCategoryDecl's CatInsMethods and CatClsMethods fields.
362///
363void ObjCCategoryDecl::addMethods(ObjCMethodDecl **insMethods,
364 unsigned numInsMembers,
365 ObjCMethodDecl **clsMethods,
366 unsigned numClsMembers,
367 SourceLocation endLoc) {
368 NumInstanceMethods = numInsMembers;
369 if (numInsMembers) {
370 InstanceMethods = new ObjCMethodDecl*[numInsMembers];
371 memcpy(InstanceMethods, insMethods, numInsMembers*sizeof(ObjCMethodDecl*));
372 }
373 NumClassMethods = numClsMembers;
374 if (numClsMembers) {
375 ClassMethods = new ObjCMethodDecl*[numClsMembers];
376 memcpy(ClassMethods, clsMethods, numClsMembers*sizeof(ObjCMethodDecl*));
377 }
378 AtEndLoc = endLoc;
379}
380
Fariborz Jahanianef8a3df2008-04-21 19:04:53 +0000381/// FindPropertyDeclaration - Finds declaration of the property given its name
382/// in 'PropertyId' and returns it. It returns 0, if not found.
383///
384ObjCPropertyDecl *
385ObjCCategoryDecl::FindPropertyDeclaration(IdentifierInfo *PropertyId) const {
386 for (ObjCCategoryDecl::classprop_iterator I = classprop_begin(),
387 E = classprop_end(); I != E; ++I) {
388 ObjCPropertyDecl *property = *I;
389 if (property->getIdentifier() == PropertyId)
390 return property;
391 }
392 return 0;
393}
394
Chris Lattner10318b82008-03-16 00:19:01 +0000395ObjCIvarDecl *ObjCInterfaceDecl::lookupInstanceVariable(
396 IdentifierInfo *ID, ObjCInterfaceDecl *&clsDeclared) {
397 ObjCInterfaceDecl* ClassDecl = this;
398 while (ClassDecl != NULL) {
399 for (ivar_iterator I = ClassDecl->ivar_begin(), E = ClassDecl->ivar_end();
400 I != E; ++I) {
401 if ((*I)->getIdentifier() == ID) {
402 clsDeclared = ClassDecl;
403 return *I;
404 }
405 }
406 ClassDecl = ClassDecl->getSuperClass();
407 }
408 return NULL;
409}
410
411/// lookupInstanceMethod - This method returns an instance method by looking in
412/// the class, its categories, and its super classes (using a linear search).
413ObjCMethodDecl *ObjCInterfaceDecl::lookupInstanceMethod(Selector Sel) {
414 ObjCInterfaceDecl* ClassDecl = this;
415 ObjCMethodDecl *MethodDecl = 0;
416
417 while (ClassDecl != NULL) {
418 if ((MethodDecl = ClassDecl->getInstanceMethod(Sel)))
419 return MethodDecl;
420
421 // Didn't find one yet - look through protocols.
422 ObjCProtocolDecl **protocols = ClassDecl->getReferencedProtocols();
423 int numProtocols = ClassDecl->getNumIntfRefProtocols();
424 for (int pIdx = 0; pIdx < numProtocols; pIdx++) {
425 if ((MethodDecl = protocols[pIdx]->getInstanceMethod(Sel)))
426 return MethodDecl;
427 }
428 // Didn't find one yet - now look through categories.
429 ObjCCategoryDecl *CatDecl = ClassDecl->getCategoryList();
430 while (CatDecl) {
431 if ((MethodDecl = CatDecl->getInstanceMethod(Sel)))
432 return MethodDecl;
433 CatDecl = CatDecl->getNextClassCategory();
434 }
435 ClassDecl = ClassDecl->getSuperClass();
436 }
437 return NULL;
438}
439
440// lookupClassMethod - This method returns a class method by looking in the
441// class, its categories, and its super classes (using a linear search).
442ObjCMethodDecl *ObjCInterfaceDecl::lookupClassMethod(Selector Sel) {
443 ObjCInterfaceDecl* ClassDecl = this;
444 ObjCMethodDecl *MethodDecl = 0;
445
446 while (ClassDecl != NULL) {
447 if ((MethodDecl = ClassDecl->getClassMethod(Sel)))
448 return MethodDecl;
449
450 // Didn't find one yet - look through protocols.
451 ObjCProtocolDecl **protocols = ClassDecl->getReferencedProtocols();
452 int numProtocols = ClassDecl->getNumIntfRefProtocols();
453 for (int pIdx = 0; pIdx < numProtocols; pIdx++) {
454 if ((MethodDecl = protocols[pIdx]->getClassMethod(Sel)))
455 return MethodDecl;
456 }
457 // Didn't find one yet - now look through categories.
458 ObjCCategoryDecl *CatDecl = ClassDecl->getCategoryList();
459 while (CatDecl) {
460 if ((MethodDecl = CatDecl->getClassMethod(Sel)))
461 return MethodDecl;
462 CatDecl = CatDecl->getNextClassCategory();
463 }
464 ClassDecl = ClassDecl->getSuperClass();
465 }
466 return NULL;
467}
468
469/// lookupInstanceMethod - This method returns an instance method by looking in
470/// the class implementation. Unlike interfaces, we don't look outside the
471/// implementation.
472ObjCMethodDecl *ObjCImplementationDecl::getInstanceMethod(Selector Sel) {
473 for (instmeth_iterator I = instmeth_begin(), E = instmeth_end(); I != E; ++I)
474 if ((*I)->getSelector() == Sel)
475 return *I;
476 return NULL;
477}
478
479/// lookupClassMethod - This method returns a class method by looking in
480/// the class implementation. Unlike interfaces, we don't look outside the
481/// implementation.
482ObjCMethodDecl *ObjCImplementationDecl::getClassMethod(Selector Sel) {
483 for (classmeth_iterator I = classmeth_begin(), E = classmeth_end();
484 I != E; ++I)
485 if ((*I)->getSelector() == Sel)
486 return *I;
487 return NULL;
488}
489
490// lookupInstanceMethod - This method returns an instance method by looking in
491// the class implementation. Unlike interfaces, we don't look outside the
492// implementation.
493ObjCMethodDecl *ObjCCategoryImplDecl::getInstanceMethod(Selector Sel) {
494 for (instmeth_iterator I = instmeth_begin(), E = instmeth_end(); I != E; ++I)
495 if ((*I)->getSelector() == Sel)
496 return *I;
497 return NULL;
498}
499
500// lookupClassMethod - This method returns an instance method by looking in
501// the class implementation. Unlike interfaces, we don't look outside the
502// implementation.
503ObjCMethodDecl *ObjCCategoryImplDecl::getClassMethod(Selector Sel) {
504 for (classmeth_iterator I = classmeth_begin(), E = classmeth_end();
505 I != E; ++I)
506 if ((*I)->getSelector() == Sel)
507 return *I;
508 return NULL;
509}
510
511// lookupInstanceMethod - Lookup a instance method in the protocol and protocols
512// it inherited.
513ObjCMethodDecl *ObjCProtocolDecl::lookupInstanceMethod(Selector Sel) {
514 ObjCMethodDecl *MethodDecl = NULL;
515
516 if ((MethodDecl = getInstanceMethod(Sel)))
517 return MethodDecl;
518
519 if (getNumReferencedProtocols() > 0) {
520 ObjCProtocolDecl **RefPDecl = getReferencedProtocols();
521
522 for (unsigned i = 0; i < getNumReferencedProtocols(); i++) {
523 if ((MethodDecl = RefPDecl[i]->getInstanceMethod(Sel)))
524 return MethodDecl;
525 }
526 }
527 return NULL;
528}
529
530// lookupInstanceMethod - Lookup a class method in the protocol and protocols
531// it inherited.
532ObjCMethodDecl *ObjCProtocolDecl::lookupClassMethod(Selector Sel) {
533 ObjCMethodDecl *MethodDecl = NULL;
534
535 if ((MethodDecl = getClassMethod(Sel)))
536 return MethodDecl;
537
538 if (getNumReferencedProtocols() > 0) {
539 ObjCProtocolDecl **RefPDecl = getReferencedProtocols();
540
541 for(unsigned i = 0; i < getNumReferencedProtocols(); i++) {
542 if ((MethodDecl = RefPDecl[i]->getClassMethod(Sel)))
543 return MethodDecl;
544 }
545 }
546 return NULL;
547}
548
549/// getSynthesizedMethodSize - Compute size of synthesized method name
550/// as done be the rewrite.
551///
552unsigned ObjCMethodDecl::getSynthesizedMethodSize() const {
553 // syntesized method name is a concatenation of -/+[class-name selector]
554 // Get length of this name.
555 unsigned length = 3; // _I_ or _C_
556 length += strlen(getClassInterface()->getName()) +1; // extra for _
557 NamedDecl *MethodContext = getMethodContext();
558 if (ObjCCategoryImplDecl *CID =
559 dyn_cast<ObjCCategoryImplDecl>(MethodContext))
560 length += strlen(CID->getName()) +1;
561 length += getSelector().getName().size(); // selector name
562 return length;
563}
564
Chris Lattner052fbcd2008-04-06 05:25:03 +0000565ObjCInterfaceDecl *ObjCMethodDecl::getClassInterface() {
Chris Lattner10318b82008-03-16 00:19:01 +0000566 if (ObjCInterfaceDecl *ID = dyn_cast<ObjCInterfaceDecl>(MethodContext))
567 return ID;
568 if (ObjCCategoryDecl *CD = dyn_cast<ObjCCategoryDecl>(MethodContext))
569 return CD->getClassInterface();
570 if (ObjCImplementationDecl *IMD =
Chris Lattner052fbcd2008-04-06 05:25:03 +0000571 dyn_cast<ObjCImplementationDecl>(MethodContext))
Chris Lattner10318b82008-03-16 00:19:01 +0000572 return IMD->getClassInterface();
Chris Lattner052fbcd2008-04-06 05:25:03 +0000573 if (ObjCCategoryImplDecl *CID = dyn_cast<ObjCCategoryImplDecl>(MethodContext))
Chris Lattner10318b82008-03-16 00:19:01 +0000574 return CID->getClassInterface();
575 assert(false && "unknown method context");
576 return 0;
577}
Chris Lattner44859612008-03-17 01:19:02 +0000578
Fariborz Jahaniandc0569e2008-04-23 00:06:01 +0000579ObjCPropertyImplDecl *ObjCPropertyImplDecl::Create(ASTContext &C,
580 SourceLocation atLoc,
581 SourceLocation L,
582 ObjCPropertyDecl *property,
583 PropertyImplKind kind,
584 ObjCIvarDecl *ivar) {
585 void *Mem = C.getAllocator().Allocate<ObjCPropertyImplDecl>();
586 return new (Mem) ObjCPropertyImplDecl(atLoc, L, property, kind, ivar);
587}
Chris Lattner44859612008-03-17 01:19:02 +0000588
Chris Lattnereee57c02008-04-04 06:12:32 +0000589