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