blob: 701ad353a3e92e67834f33d7db13223fc1365568 [file] [log] [blame]
Chris Lattner1e03a562008-03-16 00:19:01 +00001//===--- DeclObjC.cpp - ObjC Declaration AST Node Implementation ----------===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file implements the Objective-C related Decl classes.
11//
12//===----------------------------------------------------------------------===//
13
14#include "clang/AST/DeclObjC.h"
15#include "clang/AST/ASTContext.h"
16using namespace clang;
17
Chris Lattner6c4ae5d2008-03-16 00:49:28 +000018//===----------------------------------------------------------------------===//
19// ObjC Decl Allocation/Deallocation Method Implementations
20//===----------------------------------------------------------------------===//
21
Chris Lattner0ed844b2008-04-04 06:12:32 +000022ObjCMethodDecl *ObjCMethodDecl::Create(ASTContext &C,
23 SourceLocation beginLoc,
Chris Lattner6c4ae5d2008-03-16 00:49:28 +000024 SourceLocation endLoc,
25 Selector SelInfo, QualType T,
26 Decl *contextDecl,
Chris Lattner6c4ae5d2008-03-16 00:49:28 +000027 AttributeList *M, bool isInstance,
28 bool isVariadic,
Fariborz Jahanian46070342008-05-07 20:53:44 +000029 bool isSynthesized,
Chris Lattnerb06fa3b2008-03-16 00:58:16 +000030 ImplementationControl impControl) {
Chris Lattner6c4ae5d2008-03-16 00:49:28 +000031 void *Mem = C.getAllocator().Allocate<ObjCMethodDecl>();
Chris Lattner0ed844b2008-04-04 06:12:32 +000032 return new (Mem) ObjCMethodDecl(beginLoc, endLoc,
33 SelInfo, T, contextDecl,
Chris Lattnerb06fa3b2008-03-16 00:58:16 +000034 M, isInstance,
Fariborz Jahanian46070342008-05-07 20:53:44 +000035 isVariadic, isSynthesized, impControl);
Chris Lattner0e77ba02008-03-16 01:15:50 +000036}
Chris Lattner6c4ae5d2008-03-16 00:49:28 +000037
Chris Lattner0ed844b2008-04-04 06:12:32 +000038ObjCInterfaceDecl *ObjCInterfaceDecl::Create(ASTContext &C,
39 SourceLocation atLoc,
Chris Lattner0e77ba02008-03-16 01:15:50 +000040 unsigned numRefProtos,
Steve Naroffd6a07aa2008-04-11 19:35:35 +000041 IdentifierInfo *Id,
42 SourceLocation ClassLoc,
Chris Lattner0e77ba02008-03-16 01:15:50 +000043 bool ForwardDecl, bool isInternal){
44 void *Mem = C.getAllocator().Allocate<ObjCInterfaceDecl>();
Chris Lattner0ed844b2008-04-04 06:12:32 +000045 return new (Mem) ObjCInterfaceDecl(atLoc, numRefProtos,
Steve Naroffd6a07aa2008-04-11 19:35:35 +000046 Id, ClassLoc, ForwardDecl,
Chris Lattner0e77ba02008-03-16 01:15:50 +000047 isInternal);
48}
49
Chris Lattnerb048c982008-04-06 04:47:34 +000050ObjCIvarDecl *ObjCIvarDecl::Create(ASTContext &C, SourceLocation L,
Chris Lattner0e77ba02008-03-16 01:15:50 +000051 IdentifierInfo *Id, QualType T) {
52 void *Mem = C.getAllocator().Allocate<ObjCIvarDecl>();
Chris Lattnerb048c982008-04-06 04:47:34 +000053 return new (Mem) ObjCIvarDecl(L, Id, T);
Chris Lattner6c4ae5d2008-03-16 00:49:28 +000054}
55
Chris Lattner0ed844b2008-04-04 06:12:32 +000056ObjCProtocolDecl *ObjCProtocolDecl::Create(ASTContext &C,
57 SourceLocation L,
Chris Lattnercca59d72008-03-16 01:23:04 +000058 unsigned numRefProtos,
Chris Lattnerc8581052008-03-16 20:19:15 +000059 IdentifierInfo *Id) {
Chris Lattnercca59d72008-03-16 01:23:04 +000060 void *Mem = C.getAllocator().Allocate<ObjCProtocolDecl>();
Chris Lattnerc8581052008-03-16 20:19:15 +000061 return new (Mem) ObjCProtocolDecl(L, numRefProtos, Id);
Chris Lattnercca59d72008-03-16 01:23:04 +000062}
63
Chris Lattner0ed844b2008-04-04 06:12:32 +000064ObjCClassDecl *ObjCClassDecl::Create(ASTContext &C,
65 SourceLocation L,
Chris Lattner61f9d412008-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 Lattner0ed844b2008-04-04 06:12:32 +000072ObjCForwardProtocolDecl::Create(ASTContext &C,
73 SourceLocation L,
Chris Lattner61f9d412008-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 Lattner0ed844b2008-04-04 06:12:32 +000079ObjCCategoryDecl *ObjCCategoryDecl::Create(ASTContext &C,
80 SourceLocation L,
Chris Lattner61f9d412008-03-16 20:34:23 +000081 IdentifierInfo *Id) {
82 void *Mem = C.getAllocator().Allocate<ObjCCategoryDecl>();
Chris Lattner68c82cf2008-03-16 20:47:45 +000083 return new (Mem) ObjCCategoryDecl(L, Id);
Chris Lattner61f9d412008-03-16 20:34:23 +000084}
85
Chris Lattner75c9cae2008-03-16 20:53:07 +000086ObjCCategoryImplDecl *
Chris Lattner0ed844b2008-04-04 06:12:32 +000087ObjCCategoryImplDecl::Create(ASTContext &C,
88 SourceLocation L,IdentifierInfo *Id,
Chris Lattner75c9cae2008-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 Lattner0ed844b2008-04-04 06:12:32 +000095ObjCImplementationDecl::Create(ASTContext &C,
96 SourceLocation L,
Chris Lattner75c9cae2008-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 Lattner1e03a562008-03-16 00:19:01 +0000103
Chris Lattnerf8d17a52008-03-16 21:17:37 +0000104ObjCCompatibleAliasDecl *
Chris Lattner0ed844b2008-04-04 06:12:32 +0000105ObjCCompatibleAliasDecl::Create(ASTContext &C,
106 SourceLocation L,
Chris Lattnerf8d17a52008-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 Lattner0ed844b2008-04-04 06:12:32 +0000113ObjCPropertyDecl *ObjCPropertyDecl::Create(ASTContext &C,
Fariborz Jahaniandae1a1a2008-04-11 23:40:25 +0000114 SourceLocation L,
Fariborz Jahanian1de1e742008-04-14 23:36:35 +0000115 IdentifierInfo *Id,
Fariborz Jahanian46b55e52008-05-05 18:51:55 +0000116 QualType T,
117 PropertyControl propControl) {
Chris Lattnerf8d17a52008-03-16 21:17:37 +0000118 void *Mem = C.getAllocator().Allocate<ObjCPropertyDecl>();
Fariborz Jahanian1de1e742008-04-14 23:36:35 +0000119 return new (Mem) ObjCPropertyDecl(L, Id, T);
Chris Lattnerf8d17a52008-03-16 21:17:37 +0000120}
121
Chris Lattner1e03a562008-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 Jahanian559c0c42008-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 Jahanianc70bee82008-04-21 23:57:08 +0000153 if (getSuperClass())
154 return getSuperClass()->FindPropertyDeclaration(PropertyId);
Fariborz Jahanian559c0c42008-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 Jahanianc70bee82008-04-21 23:57:08 +0000182 if (getSuperClass())
183 return getSuperClass()->FindIvarDeclaration(IvarId);
Fariborz Jahanian559c0c42008-04-21 19:04:53 +0000184 return 0;
185}
186
Chris Lattner1e03a562008-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 Jahanian7e7e3872008-04-16 21:08:45 +0000235/// addProperties - Insert property declaration AST nodes into
236/// ObjCInterfaceDecl's PropertyDecl field.
Chris Lattner55d13b42008-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 Jahanianaebf0cb2008-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*));
Nuno Lopes6b3502c2008-05-10 10:31:54 +0000263 delete[] PropertyDecl;
Fariborz Jahanianaebf0cb2008-05-02 19:17:30 +0000264 PropertyDecl = newPropertyDecl;
265 NumPropertyDecl += NumNewProperties;
266 }
267 else {
Nuno Lopes6b3502c2008-05-10 10:31:54 +0000268 addProperties(Properties, NumNewProperties);
Fariborz Jahanianaebf0cb2008-05-02 19:17:30 +0000269 }
270}
271
Fariborz Jahanian33de3f02008-05-07 17:43:59 +0000272/// addPropertyMethods - Goes through list of properties declared in this class
273/// and builds setter/getter method declartions depending on the setter/getter
274/// attributes of the property.
275///
276void ObjCInterfaceDecl::addPropertyMethods(
277 ASTContext &Context,
278 ObjCPropertyDecl *property,
279 llvm::SmallVector<ObjCMethodDecl*, 32> &insMethods) {
280 // Find the default getter and if one not found, add one.
281 ObjCMethodDecl *GetterDecl = getInstanceMethod(property->getGetterName());
282 if (GetterDecl) {
283 // An instance method with same name as property getter name found.
284 property->setGetterMethodDecl(GetterDecl);
285 }
286 else {
287 // No instance method of same name as property getter name was found.
288 // Declare a getter method and add it to the list of methods
289 // for this class.
290 QualType resultDeclType = property->getType();
291 ObjCMethodDecl* ObjCMethod =
292 ObjCMethodDecl::Create(Context, property->getLocation(),
293 property->getLocation(),
294 property->getGetterName(), resultDeclType,
295 this, 0,
Fariborz Jahanian46070342008-05-07 20:53:44 +0000296 true, false, true, ObjCMethodDecl::Required);
Fariborz Jahanian33de3f02008-05-07 17:43:59 +0000297 property->setGetterMethodDecl(ObjCMethod);
298 insMethods.push_back(ObjCMethod);
299 }
300}
301
Fariborz Jahanian7e7e3872008-04-16 21:08:45 +0000302/// addProperties - Insert property declaration AST nodes into
Fariborz Jahanian3dd4ba42008-04-17 18:25:18 +0000303/// ObjCProtocolDecl's PropertyDecl field.
304///
305void ObjCProtocolDecl::addProperties(ObjCPropertyDecl **Properties,
306 unsigned NumProperties) {
307 if (NumProperties == 0) return;
308
309 NumPropertyDecl = NumProperties;
310 PropertyDecl = new ObjCPropertyDecl*[NumProperties];
311 memcpy(PropertyDecl, Properties, NumProperties*sizeof(ObjCPropertyDecl*));
312}
313
314/// addProperties - Insert property declaration AST nodes into
Fariborz Jahaniand9a3c332008-04-16 21:11:25 +0000315/// ObjCCategoryDecl's PropertyDecl field.
Fariborz Jahanian7e7e3872008-04-16 21:08:45 +0000316///
317void ObjCCategoryDecl::addProperties(ObjCPropertyDecl **Properties,
318 unsigned NumProperties) {
319 if (NumProperties == 0) return;
320
321 NumPropertyDecl = NumProperties;
322 PropertyDecl = new ObjCPropertyDecl*[NumProperties];
323 memcpy(PropertyDecl, Properties, NumProperties*sizeof(ObjCPropertyDecl*));
324}
325
Chris Lattner55d13b42008-03-16 21:23:50 +0000326/// addMethods - Insert instance and methods declarations into
Chris Lattner1e03a562008-03-16 00:19:01 +0000327/// ObjCProtocolDecl's ProtoInsMethods and ProtoClsMethods fields.
328///
329void ObjCProtocolDecl::addMethods(ObjCMethodDecl **insMethods,
330 unsigned numInsMembers,
331 ObjCMethodDecl **clsMethods,
332 unsigned numClsMembers,
333 SourceLocation endLoc) {
334 NumInstanceMethods = numInsMembers;
335 if (numInsMembers) {
336 InstanceMethods = new ObjCMethodDecl*[numInsMembers];
337 memcpy(InstanceMethods, insMethods, numInsMembers*sizeof(ObjCMethodDecl*));
338 }
339 NumClassMethods = numClsMembers;
340 if (numClsMembers) {
341 ClassMethods = new ObjCMethodDecl*[numClsMembers];
342 memcpy(ClassMethods, clsMethods, numClsMembers*sizeof(ObjCMethodDecl*));
343 }
344 AtEndLoc = endLoc;
345}
346
Chris Lattner68c82cf2008-03-16 20:47:45 +0000347void ObjCCategoryDecl::setReferencedProtocolList(ObjCProtocolDecl **List,
348 unsigned NumRPs) {
349 assert(NumReferencedProtocols == 0 && "Protocol list already set");
350 if (NumRPs == 0) return;
351
352 ReferencedProtocols = new ObjCProtocolDecl*[NumRPs];
353 memcpy(ReferencedProtocols, List, NumRPs*sizeof(ObjCProtocolDecl*));
354 NumReferencedProtocols = NumRPs;
355}
356
357
Chris Lattner1e03a562008-03-16 00:19:01 +0000358/// addMethods - Insert instance and methods declarations into
359/// ObjCCategoryDecl's CatInsMethods and CatClsMethods fields.
360///
361void ObjCCategoryDecl::addMethods(ObjCMethodDecl **insMethods,
362 unsigned numInsMembers,
363 ObjCMethodDecl **clsMethods,
364 unsigned numClsMembers,
365 SourceLocation endLoc) {
366 NumInstanceMethods = numInsMembers;
367 if (numInsMembers) {
368 InstanceMethods = new ObjCMethodDecl*[numInsMembers];
369 memcpy(InstanceMethods, insMethods, numInsMembers*sizeof(ObjCMethodDecl*));
370 }
371 NumClassMethods = numClsMembers;
372 if (numClsMembers) {
373 ClassMethods = new ObjCMethodDecl*[numClsMembers];
374 memcpy(ClassMethods, clsMethods, numClsMembers*sizeof(ObjCMethodDecl*));
375 }
376 AtEndLoc = endLoc;
377}
378
Fariborz Jahanian559c0c42008-04-21 19:04:53 +0000379/// FindPropertyDeclaration - Finds declaration of the property given its name
380/// in 'PropertyId' and returns it. It returns 0, if not found.
381///
382ObjCPropertyDecl *
383ObjCCategoryDecl::FindPropertyDeclaration(IdentifierInfo *PropertyId) const {
384 for (ObjCCategoryDecl::classprop_iterator I = classprop_begin(),
385 E = classprop_end(); I != E; ++I) {
386 ObjCPropertyDecl *property = *I;
387 if (property->getIdentifier() == PropertyId)
388 return property;
389 }
390 return 0;
391}
392
Chris Lattner1e03a562008-03-16 00:19:01 +0000393ObjCIvarDecl *ObjCInterfaceDecl::lookupInstanceVariable(
394 IdentifierInfo *ID, ObjCInterfaceDecl *&clsDeclared) {
395 ObjCInterfaceDecl* ClassDecl = this;
396 while (ClassDecl != NULL) {
397 for (ivar_iterator I = ClassDecl->ivar_begin(), E = ClassDecl->ivar_end();
398 I != E; ++I) {
399 if ((*I)->getIdentifier() == ID) {
400 clsDeclared = ClassDecl;
401 return *I;
402 }
403 }
404 ClassDecl = ClassDecl->getSuperClass();
405 }
406 return NULL;
407}
408
409/// lookupInstanceMethod - This method returns an instance method by looking in
410/// the class, its categories, and its super classes (using a linear search).
411ObjCMethodDecl *ObjCInterfaceDecl::lookupInstanceMethod(Selector Sel) {
412 ObjCInterfaceDecl* ClassDecl = this;
413 ObjCMethodDecl *MethodDecl = 0;
414
415 while (ClassDecl != NULL) {
416 if ((MethodDecl = ClassDecl->getInstanceMethod(Sel)))
417 return MethodDecl;
418
419 // Didn't find one yet - look through protocols.
420 ObjCProtocolDecl **protocols = ClassDecl->getReferencedProtocols();
421 int numProtocols = ClassDecl->getNumIntfRefProtocols();
422 for (int pIdx = 0; pIdx < numProtocols; pIdx++) {
423 if ((MethodDecl = protocols[pIdx]->getInstanceMethod(Sel)))
424 return MethodDecl;
425 }
426 // Didn't find one yet - now look through categories.
427 ObjCCategoryDecl *CatDecl = ClassDecl->getCategoryList();
428 while (CatDecl) {
429 if ((MethodDecl = CatDecl->getInstanceMethod(Sel)))
430 return MethodDecl;
431 CatDecl = CatDecl->getNextClassCategory();
432 }
433 ClassDecl = ClassDecl->getSuperClass();
434 }
435 return NULL;
436}
437
438// lookupClassMethod - This method returns a class method by looking in the
439// class, its categories, and its super classes (using a linear search).
440ObjCMethodDecl *ObjCInterfaceDecl::lookupClassMethod(Selector Sel) {
441 ObjCInterfaceDecl* ClassDecl = this;
442 ObjCMethodDecl *MethodDecl = 0;
443
444 while (ClassDecl != NULL) {
445 if ((MethodDecl = ClassDecl->getClassMethod(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]->getClassMethod(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->getClassMethod(Sel)))
459 return MethodDecl;
460 CatDecl = CatDecl->getNextClassCategory();
461 }
462 ClassDecl = ClassDecl->getSuperClass();
463 }
464 return NULL;
465}
466
467/// lookupInstanceMethod - This method returns an instance method by looking in
468/// the class implementation. Unlike interfaces, we don't look outside the
469/// implementation.
470ObjCMethodDecl *ObjCImplementationDecl::getInstanceMethod(Selector Sel) {
471 for (instmeth_iterator I = instmeth_begin(), E = instmeth_end(); I != E; ++I)
472 if ((*I)->getSelector() == Sel)
473 return *I;
474 return NULL;
475}
476
477/// lookupClassMethod - This method returns a class method by looking in
478/// the class implementation. Unlike interfaces, we don't look outside the
479/// implementation.
480ObjCMethodDecl *ObjCImplementationDecl::getClassMethod(Selector Sel) {
481 for (classmeth_iterator I = classmeth_begin(), E = classmeth_end();
482 I != E; ++I)
483 if ((*I)->getSelector() == Sel)
484 return *I;
485 return NULL;
486}
487
488// lookupInstanceMethod - This method returns an instance method by looking in
489// the class implementation. Unlike interfaces, we don't look outside the
490// implementation.
491ObjCMethodDecl *ObjCCategoryImplDecl::getInstanceMethod(Selector Sel) {
492 for (instmeth_iterator I = instmeth_begin(), E = instmeth_end(); I != E; ++I)
493 if ((*I)->getSelector() == Sel)
494 return *I;
495 return NULL;
496}
497
498// lookupClassMethod - This method returns an instance method by looking in
499// the class implementation. Unlike interfaces, we don't look outside the
500// implementation.
501ObjCMethodDecl *ObjCCategoryImplDecl::getClassMethod(Selector Sel) {
502 for (classmeth_iterator I = classmeth_begin(), E = classmeth_end();
503 I != E; ++I)
504 if ((*I)->getSelector() == Sel)
505 return *I;
506 return NULL;
507}
508
509// lookupInstanceMethod - Lookup a instance method in the protocol and protocols
510// it inherited.
511ObjCMethodDecl *ObjCProtocolDecl::lookupInstanceMethod(Selector Sel) {
512 ObjCMethodDecl *MethodDecl = NULL;
513
514 if ((MethodDecl = getInstanceMethod(Sel)))
515 return MethodDecl;
516
517 if (getNumReferencedProtocols() > 0) {
518 ObjCProtocolDecl **RefPDecl = getReferencedProtocols();
519
520 for (unsigned i = 0; i < getNumReferencedProtocols(); i++) {
521 if ((MethodDecl = RefPDecl[i]->getInstanceMethod(Sel)))
522 return MethodDecl;
523 }
524 }
525 return NULL;
526}
527
528// lookupInstanceMethod - Lookup a class method in the protocol and protocols
529// it inherited.
530ObjCMethodDecl *ObjCProtocolDecl::lookupClassMethod(Selector Sel) {
531 ObjCMethodDecl *MethodDecl = NULL;
532
533 if ((MethodDecl = getClassMethod(Sel)))
534 return MethodDecl;
535
536 if (getNumReferencedProtocols() > 0) {
537 ObjCProtocolDecl **RefPDecl = getReferencedProtocols();
538
539 for(unsigned i = 0; i < getNumReferencedProtocols(); i++) {
540 if ((MethodDecl = RefPDecl[i]->getClassMethod(Sel)))
541 return MethodDecl;
542 }
543 }
544 return NULL;
545}
546
547/// getSynthesizedMethodSize - Compute size of synthesized method name
548/// as done be the rewrite.
549///
550unsigned ObjCMethodDecl::getSynthesizedMethodSize() const {
551 // syntesized method name is a concatenation of -/+[class-name selector]
552 // Get length of this name.
553 unsigned length = 3; // _I_ or _C_
554 length += strlen(getClassInterface()->getName()) +1; // extra for _
555 NamedDecl *MethodContext = getMethodContext();
556 if (ObjCCategoryImplDecl *CID =
557 dyn_cast<ObjCCategoryImplDecl>(MethodContext))
558 length += strlen(CID->getName()) +1;
559 length += getSelector().getName().size(); // selector name
560 return length;
561}
562
Chris Lattner56196882008-04-06 05:25:03 +0000563ObjCInterfaceDecl *ObjCMethodDecl::getClassInterface() {
Chris Lattner1e03a562008-03-16 00:19:01 +0000564 if (ObjCInterfaceDecl *ID = dyn_cast<ObjCInterfaceDecl>(MethodContext))
565 return ID;
566 if (ObjCCategoryDecl *CD = dyn_cast<ObjCCategoryDecl>(MethodContext))
567 return CD->getClassInterface();
568 if (ObjCImplementationDecl *IMD =
Chris Lattner56196882008-04-06 05:25:03 +0000569 dyn_cast<ObjCImplementationDecl>(MethodContext))
Chris Lattner1e03a562008-03-16 00:19:01 +0000570 return IMD->getClassInterface();
Chris Lattner56196882008-04-06 05:25:03 +0000571 if (ObjCCategoryImplDecl *CID = dyn_cast<ObjCCategoryImplDecl>(MethodContext))
Chris Lattner1e03a562008-03-16 00:19:01 +0000572 return CID->getClassInterface();
573 assert(false && "unknown method context");
574 return 0;
575}
Chris Lattnerf4af5152008-03-17 01:19:02 +0000576
Fariborz Jahanian628b96f2008-04-23 00:06:01 +0000577ObjCPropertyImplDecl *ObjCPropertyImplDecl::Create(ASTContext &C,
578 SourceLocation atLoc,
579 SourceLocation L,
580 ObjCPropertyDecl *property,
581 PropertyImplKind kind,
582 ObjCIvarDecl *ivar) {
583 void *Mem = C.getAllocator().Allocate<ObjCPropertyImplDecl>();
584 return new (Mem) ObjCPropertyImplDecl(atLoc, L, property, kind, ivar);
585}
Chris Lattnerf4af5152008-03-17 01:19:02 +0000586
Chris Lattner0ed844b2008-04-04 06:12:32 +0000587