blob: 6536df6e1e10bf39bda0ea04a8590bbc75848e1f [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 }
Steve Naroff30faf472008-06-04 04:46:04 +0000153 // Look through categories.
154 for (ObjCCategoryDecl *Category = getCategoryList();
155 Category; Category = Category->getNextClassCategory()) {
156 ObjCPropertyDecl *property = Category->FindPropertyDeclaration(PropertyId);
157 if (property)
158 return property;
159 }
Steve Naroffd1f0eb42008-06-05 13:55:23 +0000160 // Look through protocols.
161 for (ObjCInterfaceDecl::protocol_iterator I = protocol_begin(),
162 E = protocol_end(); I != E; ++I) {
163 ObjCProtocolDecl *Protocol = *I;
164 ObjCPropertyDecl *property = Protocol->FindPropertyDeclaration(PropertyId);
165 if (property)
166 return property;
167 }
Fariborz Jahanian8acf3352008-04-21 23:57:08 +0000168 if (getSuperClass())
169 return getSuperClass()->FindPropertyDeclaration(PropertyId);
Fariborz Jahanianef8a3df2008-04-21 19:04:53 +0000170 return 0;
171}
172
173/// FindCategoryDeclaration - Finds category declaration in the list of
174/// categories for this class and returns it. Name of the category is passed
175/// in 'CategoryId'. If category not found, return 0;
176///
177ObjCCategoryDecl *
178 ObjCInterfaceDecl::FindCategoryDeclaration(IdentifierInfo *CategoryId) const {
179 for (ObjCCategoryDecl *Category = getCategoryList();
180 Category; Category = Category->getNextClassCategory())
181 if (Category->getIdentifier() == CategoryId)
182 return Category;
183 return 0;
184}
185
186/// FindIvarDeclaration - Find an Ivar declaration in this class given its
187/// name in 'IvarId'. On failure to find, return 0;
188///
189ObjCIvarDecl *
190 ObjCInterfaceDecl::FindIvarDeclaration(IdentifierInfo *IvarId) const {
191 for (ObjCInterfaceDecl::ivar_iterator IVI = ivar_begin(),
192 IVE = ivar_end(); IVI != IVE; ++IVI) {
193 ObjCIvarDecl* Ivar = (*IVI);
194 if (Ivar->getIdentifier() == IvarId)
195 return Ivar;
196 }
Fariborz Jahanian8acf3352008-04-21 23:57:08 +0000197 if (getSuperClass())
198 return getSuperClass()->FindIvarDeclaration(IvarId);
Fariborz Jahanianef8a3df2008-04-21 19:04:53 +0000199 return 0;
200}
201
Chris Lattner10318b82008-03-16 00:19:01 +0000202/// ObjCAddInstanceVariablesToClass - Inserts instance variables
203/// into ObjCInterfaceDecl's fields.
204///
205void ObjCInterfaceDecl::addInstanceVariablesToClass(ObjCIvarDecl **ivars,
206 unsigned numIvars,
207 SourceLocation RBrac) {
208 NumIvars = numIvars;
209 if (numIvars) {
210 Ivars = new ObjCIvarDecl*[numIvars];
211 memcpy(Ivars, ivars, numIvars*sizeof(ObjCIvarDecl*));
212 }
213 setLocEnd(RBrac);
214}
215
216/// ObjCAddInstanceVariablesToClassImpl - Checks for correctness of Instance
217/// Variables (Ivars) relative to what declared in @implementation;s class.
218/// Ivars into ObjCImplementationDecl's fields.
219///
220void ObjCImplementationDecl::ObjCAddInstanceVariablesToClassImpl(
221 ObjCIvarDecl **ivars, unsigned numIvars) {
222 NumIvars = numIvars;
223 if (numIvars) {
224 Ivars = new ObjCIvarDecl*[numIvars];
225 memcpy(Ivars, ivars, numIvars*sizeof(ObjCIvarDecl*));
226 }
227}
228
229/// addMethods - Insert instance and methods declarations into
230/// ObjCInterfaceDecl's InsMethods and ClsMethods fields.
231///
232void ObjCInterfaceDecl::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
Fariborz Jahanian52ff8442008-04-16 21:08:45 +0000250/// addProperties - Insert property declaration AST nodes into
251/// ObjCInterfaceDecl's PropertyDecl field.
Chris Lattnercffe3662008-03-16 21:23:50 +0000252///
253void ObjCInterfaceDecl::addProperties(ObjCPropertyDecl **Properties,
254 unsigned NumProperties) {
255 if (NumProperties == 0) return;
256
257 NumPropertyDecl = NumProperties;
258 PropertyDecl = new ObjCPropertyDecl*[NumProperties];
259 memcpy(PropertyDecl, Properties, NumProperties*sizeof(ObjCPropertyDecl*));
260}
261
Fariborz Jahanian33973a22008-05-02 19:17:30 +0000262/// mergeProperties - Adds properties to the end of list of current properties
263/// for this class.
264
265void ObjCInterfaceDecl::mergeProperties(ObjCPropertyDecl **Properties,
266 unsigned NumNewProperties) {
267 if (NumNewProperties == 0) return;
268
269 if (PropertyDecl) {
270 ObjCPropertyDecl **newPropertyDecl =
271 new ObjCPropertyDecl*[NumNewProperties + NumPropertyDecl];
272 ObjCPropertyDecl **buf = newPropertyDecl;
273 // put back original properties in buffer.
274 memcpy(buf, PropertyDecl, NumPropertyDecl*sizeof(ObjCPropertyDecl*));
275 // Add new properties to this buffer.
276 memcpy(buf+NumPropertyDecl, Properties,
277 NumNewProperties*sizeof(ObjCPropertyDecl*));
Nuno Lopes1ee78042008-05-10 10:31:54 +0000278 delete[] PropertyDecl;
Fariborz Jahanian33973a22008-05-02 19:17:30 +0000279 PropertyDecl = newPropertyDecl;
280 NumPropertyDecl += NumNewProperties;
281 }
282 else {
Nuno Lopes1ee78042008-05-10 10:31:54 +0000283 addProperties(Properties, NumNewProperties);
Fariborz Jahanian33973a22008-05-02 19:17:30 +0000284 }
285}
286
Fariborz Jahaniane4534e72008-05-07 17:43:59 +0000287/// addPropertyMethods - Goes through list of properties declared in this class
288/// and builds setter/getter method declartions depending on the setter/getter
289/// attributes of the property.
290///
291void ObjCInterfaceDecl::addPropertyMethods(
292 ASTContext &Context,
293 ObjCPropertyDecl *property,
294 llvm::SmallVector<ObjCMethodDecl*, 32> &insMethods) {
295 // Find the default getter and if one not found, add one.
296 ObjCMethodDecl *GetterDecl = getInstanceMethod(property->getGetterName());
297 if (GetterDecl) {
298 // An instance method with same name as property getter name found.
299 property->setGetterMethodDecl(GetterDecl);
300 }
301 else {
302 // No instance method of same name as property getter name was found.
303 // Declare a getter method and add it to the list of methods
304 // for this class.
305 QualType resultDeclType = property->getType();
306 ObjCMethodDecl* ObjCMethod =
307 ObjCMethodDecl::Create(Context, property->getLocation(),
308 property->getLocation(),
309 property->getGetterName(), resultDeclType,
310 this, 0,
Fariborz Jahanian5f2e2242008-05-07 20:53:44 +0000311 true, false, true, ObjCMethodDecl::Required);
Fariborz Jahaniane4534e72008-05-07 17:43:59 +0000312 property->setGetterMethodDecl(ObjCMethod);
313 insMethods.push_back(ObjCMethod);
314 }
315}
316
Fariborz Jahanian52ff8442008-04-16 21:08:45 +0000317/// addProperties - Insert property declaration AST nodes into
Fariborz Jahanian8516e9a2008-04-17 18:25:18 +0000318/// ObjCProtocolDecl's PropertyDecl field.
319///
320void ObjCProtocolDecl::addProperties(ObjCPropertyDecl **Properties,
321 unsigned NumProperties) {
322 if (NumProperties == 0) return;
323
324 NumPropertyDecl = NumProperties;
325 PropertyDecl = new ObjCPropertyDecl*[NumProperties];
326 memcpy(PropertyDecl, Properties, NumProperties*sizeof(ObjCPropertyDecl*));
327}
328
329/// addProperties - Insert property declaration AST nodes into
Fariborz Jahanian5742a0f2008-04-16 21:11:25 +0000330/// ObjCCategoryDecl's PropertyDecl field.
Fariborz Jahanian52ff8442008-04-16 21:08:45 +0000331///
332void ObjCCategoryDecl::addProperties(ObjCPropertyDecl **Properties,
333 unsigned NumProperties) {
334 if (NumProperties == 0) return;
335
336 NumPropertyDecl = NumProperties;
337 PropertyDecl = new ObjCPropertyDecl*[NumProperties];
338 memcpy(PropertyDecl, Properties, NumProperties*sizeof(ObjCPropertyDecl*));
339}
340
Chris Lattnercffe3662008-03-16 21:23:50 +0000341/// addMethods - Insert instance and methods declarations into
Chris Lattner10318b82008-03-16 00:19:01 +0000342/// ObjCProtocolDecl's ProtoInsMethods and ProtoClsMethods fields.
343///
344void ObjCProtocolDecl::addMethods(ObjCMethodDecl **insMethods,
345 unsigned numInsMembers,
346 ObjCMethodDecl **clsMethods,
347 unsigned numClsMembers,
348 SourceLocation endLoc) {
349 NumInstanceMethods = numInsMembers;
350 if (numInsMembers) {
351 InstanceMethods = new ObjCMethodDecl*[numInsMembers];
352 memcpy(InstanceMethods, insMethods, numInsMembers*sizeof(ObjCMethodDecl*));
353 }
354 NumClassMethods = numClsMembers;
355 if (numClsMembers) {
356 ClassMethods = new ObjCMethodDecl*[numClsMembers];
357 memcpy(ClassMethods, clsMethods, numClsMembers*sizeof(ObjCMethodDecl*));
358 }
359 AtEndLoc = endLoc;
360}
361
Chris Lattner321b5d12008-03-16 20:47:45 +0000362void ObjCCategoryDecl::setReferencedProtocolList(ObjCProtocolDecl **List,
363 unsigned NumRPs) {
364 assert(NumReferencedProtocols == 0 && "Protocol list already set");
365 if (NumRPs == 0) return;
366
367 ReferencedProtocols = new ObjCProtocolDecl*[NumRPs];
368 memcpy(ReferencedProtocols, List, NumRPs*sizeof(ObjCProtocolDecl*));
369 NumReferencedProtocols = NumRPs;
370}
371
372
Chris Lattner10318b82008-03-16 00:19:01 +0000373/// addMethods - Insert instance and methods declarations into
374/// ObjCCategoryDecl's CatInsMethods and CatClsMethods fields.
375///
376void ObjCCategoryDecl::addMethods(ObjCMethodDecl **insMethods,
377 unsigned numInsMembers,
378 ObjCMethodDecl **clsMethods,
379 unsigned numClsMembers,
380 SourceLocation endLoc) {
381 NumInstanceMethods = numInsMembers;
382 if (numInsMembers) {
383 InstanceMethods = new ObjCMethodDecl*[numInsMembers];
384 memcpy(InstanceMethods, insMethods, numInsMembers*sizeof(ObjCMethodDecl*));
385 }
386 NumClassMethods = numClsMembers;
387 if (numClsMembers) {
388 ClassMethods = new ObjCMethodDecl*[numClsMembers];
389 memcpy(ClassMethods, clsMethods, numClsMembers*sizeof(ObjCMethodDecl*));
390 }
391 AtEndLoc = endLoc;
392}
393
Fariborz Jahanianef8a3df2008-04-21 19:04:53 +0000394/// FindPropertyDeclaration - Finds declaration of the property given its name
395/// in 'PropertyId' and returns it. It returns 0, if not found.
396///
397ObjCPropertyDecl *
398ObjCCategoryDecl::FindPropertyDeclaration(IdentifierInfo *PropertyId) const {
399 for (ObjCCategoryDecl::classprop_iterator I = classprop_begin(),
400 E = classprop_end(); I != E; ++I) {
401 ObjCPropertyDecl *property = *I;
402 if (property->getIdentifier() == PropertyId)
403 return property;
404 }
405 return 0;
406}
407
Steve Naroffd1f0eb42008-06-05 13:55:23 +0000408/// FindPropertyDeclaration - Finds declaration of the property given its name
409/// in 'PropertyId' and returns it. It returns 0, if not found.
410///
411ObjCPropertyDecl *
412ObjCProtocolDecl::FindPropertyDeclaration(IdentifierInfo *PropertyId) const {
413 for (ObjCProtocolDecl::classprop_iterator I = classprop_begin(),
414 E = classprop_end(); I != E; ++I) {
415 ObjCPropertyDecl *property = *I;
416 if (property->getIdentifier() == PropertyId)
417 return property;
418 }
419 return 0;
420}
421
Chris Lattner10318b82008-03-16 00:19:01 +0000422ObjCIvarDecl *ObjCInterfaceDecl::lookupInstanceVariable(
423 IdentifierInfo *ID, ObjCInterfaceDecl *&clsDeclared) {
424 ObjCInterfaceDecl* ClassDecl = this;
425 while (ClassDecl != NULL) {
426 for (ivar_iterator I = ClassDecl->ivar_begin(), E = ClassDecl->ivar_end();
427 I != E; ++I) {
428 if ((*I)->getIdentifier() == ID) {
429 clsDeclared = ClassDecl;
430 return *I;
431 }
432 }
433 ClassDecl = ClassDecl->getSuperClass();
434 }
435 return NULL;
436}
437
438/// lookupInstanceMethod - This method returns an instance method by looking in
439/// the class, its categories, and its super classes (using a linear search).
440ObjCMethodDecl *ObjCInterfaceDecl::lookupInstanceMethod(Selector Sel) {
441 ObjCInterfaceDecl* ClassDecl = this;
442 ObjCMethodDecl *MethodDecl = 0;
443
444 while (ClassDecl != NULL) {
445 if ((MethodDecl = ClassDecl->getInstanceMethod(Sel)))
446 return MethodDecl;
447
448 // Didn't find one yet - look through protocols.
449 ObjCProtocolDecl **protocols = ClassDecl->getReferencedProtocols();
450 int numProtocols = ClassDecl->getNumIntfRefProtocols();
451 for (int pIdx = 0; pIdx < numProtocols; pIdx++) {
452 if ((MethodDecl = protocols[pIdx]->getInstanceMethod(Sel)))
453 return MethodDecl;
454 }
455 // Didn't find one yet - now look through categories.
456 ObjCCategoryDecl *CatDecl = ClassDecl->getCategoryList();
457 while (CatDecl) {
458 if ((MethodDecl = CatDecl->getInstanceMethod(Sel)))
459 return MethodDecl;
460 CatDecl = CatDecl->getNextClassCategory();
461 }
462 ClassDecl = ClassDecl->getSuperClass();
463 }
464 return NULL;
465}
466
467// lookupClassMethod - This method returns a class method by looking in the
468// class, its categories, and its super classes (using a linear search).
469ObjCMethodDecl *ObjCInterfaceDecl::lookupClassMethod(Selector Sel) {
470 ObjCInterfaceDecl* ClassDecl = this;
471 ObjCMethodDecl *MethodDecl = 0;
472
473 while (ClassDecl != NULL) {
474 if ((MethodDecl = ClassDecl->getClassMethod(Sel)))
475 return MethodDecl;
476
477 // Didn't find one yet - look through protocols.
478 ObjCProtocolDecl **protocols = ClassDecl->getReferencedProtocols();
479 int numProtocols = ClassDecl->getNumIntfRefProtocols();
480 for (int pIdx = 0; pIdx < numProtocols; pIdx++) {
481 if ((MethodDecl = protocols[pIdx]->getClassMethod(Sel)))
482 return MethodDecl;
483 }
484 // Didn't find one yet - now look through categories.
485 ObjCCategoryDecl *CatDecl = ClassDecl->getCategoryList();
486 while (CatDecl) {
487 if ((MethodDecl = CatDecl->getClassMethod(Sel)))
488 return MethodDecl;
489 CatDecl = CatDecl->getNextClassCategory();
490 }
491 ClassDecl = ClassDecl->getSuperClass();
492 }
493 return NULL;
494}
495
496/// lookupInstanceMethod - This method returns an instance method by looking in
497/// the class implementation. Unlike interfaces, we don't look outside the
498/// implementation.
499ObjCMethodDecl *ObjCImplementationDecl::getInstanceMethod(Selector Sel) {
500 for (instmeth_iterator I = instmeth_begin(), E = instmeth_end(); I != E; ++I)
501 if ((*I)->getSelector() == Sel)
502 return *I;
503 return NULL;
504}
505
506/// lookupClassMethod - This method returns a class method by looking in
507/// the class implementation. Unlike interfaces, we don't look outside the
508/// implementation.
509ObjCMethodDecl *ObjCImplementationDecl::getClassMethod(Selector Sel) {
510 for (classmeth_iterator I = classmeth_begin(), E = classmeth_end();
511 I != E; ++I)
512 if ((*I)->getSelector() == Sel)
513 return *I;
514 return NULL;
515}
516
517// lookupInstanceMethod - This method returns an instance method by looking in
518// the class implementation. Unlike interfaces, we don't look outside the
519// implementation.
520ObjCMethodDecl *ObjCCategoryImplDecl::getInstanceMethod(Selector Sel) {
521 for (instmeth_iterator I = instmeth_begin(), E = instmeth_end(); I != E; ++I)
522 if ((*I)->getSelector() == Sel)
523 return *I;
524 return NULL;
525}
526
527// lookupClassMethod - This method returns an instance method by looking in
528// the class implementation. Unlike interfaces, we don't look outside the
529// implementation.
530ObjCMethodDecl *ObjCCategoryImplDecl::getClassMethod(Selector Sel) {
531 for (classmeth_iterator I = classmeth_begin(), E = classmeth_end();
532 I != E; ++I)
533 if ((*I)->getSelector() == Sel)
534 return *I;
535 return NULL;
536}
537
538// lookupInstanceMethod - Lookup a instance method in the protocol and protocols
539// it inherited.
540ObjCMethodDecl *ObjCProtocolDecl::lookupInstanceMethod(Selector Sel) {
541 ObjCMethodDecl *MethodDecl = NULL;
542
543 if ((MethodDecl = getInstanceMethod(Sel)))
544 return MethodDecl;
545
546 if (getNumReferencedProtocols() > 0) {
547 ObjCProtocolDecl **RefPDecl = getReferencedProtocols();
548
549 for (unsigned i = 0; i < getNumReferencedProtocols(); i++) {
550 if ((MethodDecl = RefPDecl[i]->getInstanceMethod(Sel)))
551 return MethodDecl;
552 }
553 }
554 return NULL;
555}
556
557// lookupInstanceMethod - Lookup a class method in the protocol and protocols
558// it inherited.
559ObjCMethodDecl *ObjCProtocolDecl::lookupClassMethod(Selector Sel) {
560 ObjCMethodDecl *MethodDecl = NULL;
561
562 if ((MethodDecl = getClassMethod(Sel)))
563 return MethodDecl;
564
565 if (getNumReferencedProtocols() > 0) {
566 ObjCProtocolDecl **RefPDecl = getReferencedProtocols();
567
568 for(unsigned i = 0; i < getNumReferencedProtocols(); i++) {
569 if ((MethodDecl = RefPDecl[i]->getClassMethod(Sel)))
570 return MethodDecl;
571 }
572 }
573 return NULL;
574}
575
576/// getSynthesizedMethodSize - Compute size of synthesized method name
577/// as done be the rewrite.
578///
579unsigned ObjCMethodDecl::getSynthesizedMethodSize() const {
580 // syntesized method name is a concatenation of -/+[class-name selector]
581 // Get length of this name.
582 unsigned length = 3; // _I_ or _C_
583 length += strlen(getClassInterface()->getName()) +1; // extra for _
584 NamedDecl *MethodContext = getMethodContext();
585 if (ObjCCategoryImplDecl *CID =
586 dyn_cast<ObjCCategoryImplDecl>(MethodContext))
587 length += strlen(CID->getName()) +1;
588 length += getSelector().getName().size(); // selector name
589 return length;
590}
591
Chris Lattner052fbcd2008-04-06 05:25:03 +0000592ObjCInterfaceDecl *ObjCMethodDecl::getClassInterface() {
Chris Lattner10318b82008-03-16 00:19:01 +0000593 if (ObjCInterfaceDecl *ID = dyn_cast<ObjCInterfaceDecl>(MethodContext))
594 return ID;
595 if (ObjCCategoryDecl *CD = dyn_cast<ObjCCategoryDecl>(MethodContext))
596 return CD->getClassInterface();
597 if (ObjCImplementationDecl *IMD =
Chris Lattner052fbcd2008-04-06 05:25:03 +0000598 dyn_cast<ObjCImplementationDecl>(MethodContext))
Chris Lattner10318b82008-03-16 00:19:01 +0000599 return IMD->getClassInterface();
Chris Lattner052fbcd2008-04-06 05:25:03 +0000600 if (ObjCCategoryImplDecl *CID = dyn_cast<ObjCCategoryImplDecl>(MethodContext))
Chris Lattner10318b82008-03-16 00:19:01 +0000601 return CID->getClassInterface();
602 assert(false && "unknown method context");
603 return 0;
604}
Chris Lattner44859612008-03-17 01:19:02 +0000605
Fariborz Jahaniandc0569e2008-04-23 00:06:01 +0000606ObjCPropertyImplDecl *ObjCPropertyImplDecl::Create(ASTContext &C,
607 SourceLocation atLoc,
608 SourceLocation L,
609 ObjCPropertyDecl *property,
610 PropertyImplKind kind,
611 ObjCIvarDecl *ivar) {
612 void *Mem = C.getAllocator().Allocate<ObjCPropertyImplDecl>();
613 return new (Mem) ObjCPropertyImplDecl(atLoc, L, property, kind, ivar);
614}
Chris Lattner44859612008-03-17 01:19:02 +0000615
Chris Lattnereee57c02008-04-04 06:12:32 +0000616