blob: 95ba2e0c5831b9cbef54888e60b4b1a857bba926 [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"
Daniel Dunbarde300732008-08-11 04:54:23 +000016#include "clang/AST/Stmt.h"
Chris Lattner10318b82008-03-16 00:19:01 +000017using namespace clang;
18
Chris Lattner114add62008-03-16 00:49:28 +000019//===----------------------------------------------------------------------===//
20// ObjC Decl Allocation/Deallocation Method Implementations
21//===----------------------------------------------------------------------===//
22
Chris Lattnereee57c02008-04-04 06:12:32 +000023ObjCMethodDecl *ObjCMethodDecl::Create(ASTContext &C,
24 SourceLocation beginLoc,
Chris Lattner114add62008-03-16 00:49:28 +000025 SourceLocation endLoc,
26 Selector SelInfo, QualType T,
Steve Naroffab63fd62009-01-08 17:28:14 +000027 DeclContext *contextDecl,
Daniel Dunbard8bd6822008-08-20 18:02:42 +000028 bool isInstance,
Chris Lattner114add62008-03-16 00:49:28 +000029 bool isVariadic,
Fariborz Jahanian5f2e2242008-05-07 20:53:44 +000030 bool isSynthesized,
Chris Lattnerf7355832008-03-16 00:58:16 +000031 ImplementationControl impControl) {
Steve Naroff5abb0282009-01-27 21:25:57 +000032 return new (C) ObjCMethodDecl(beginLoc, endLoc,
Chris Lattnereee57c02008-04-04 06:12:32 +000033 SelInfo, T, contextDecl,
Daniel Dunbard8bd6822008-08-20 18:02:42 +000034 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
Ted Kremenek8c945b12008-06-06 16:45:15 +000038void ObjCMethodDecl::Destroy(ASTContext& C) {
39 if (Body) Body->Destroy(C);
40 if (SelfDecl) SelfDecl->Destroy(C);
41
42 for (param_iterator I=param_begin(), E=param_end(); I!=E; ++I)
43 if (*I) (*I)->Destroy(C);
Chris Lattnerae538882009-02-20 05:54:35 +000044
45 delete [] ParamInfo;
46 ParamInfo = 0;
47
Ted Kremenek8c945b12008-06-06 16:45:15 +000048 Decl::Destroy(C);
49}
50
Chris Lattnereee57c02008-04-04 06:12:32 +000051ObjCInterfaceDecl *ObjCInterfaceDecl::Create(ASTContext &C,
Douglas Gregor6e4fa2c2009-01-09 00:49:46 +000052 DeclContext *DC,
Chris Lattnereee57c02008-04-04 06:12:32 +000053 SourceLocation atLoc,
Steve Naroff7c371742008-04-11 19:35:35 +000054 IdentifierInfo *Id,
55 SourceLocation ClassLoc,
Chris Lattner0db541b2008-03-16 01:15:50 +000056 bool ForwardDecl, bool isInternal){
Steve Naroff5abb0282009-01-27 21:25:57 +000057 return new (C) ObjCInterfaceDecl(DC, atLoc, Id, ClassLoc, ForwardDecl,
Chris Lattner0db541b2008-03-16 01:15:50 +000058 isInternal);
59}
60
Steve Naroffd9d4d502009-01-07 17:57:40 +000061ObjCContainerDecl::~ObjCContainerDecl() {
Steve Naroffd9d4d502009-01-07 17:57:40 +000062}
63
64ObjCInterfaceDecl::~ObjCInterfaceDecl() {
65 delete [] Ivars;
Ted Kremenek8c945b12008-06-06 16:45:15 +000066 // FIXME: CategoryList?
67}
68
69void ObjCInterfaceDecl::Destroy(ASTContext& C) {
70 for (ivar_iterator I=ivar_begin(), E=ivar_end(); I!=E; ++I)
71 if (*I) (*I)->Destroy(C);
72
Ted Kremenek22db1602008-06-06 17:21:42 +000073 // FIXME: Because there is no clear ownership
74 // role between ObjCInterfaceDecls and the ObjCPropertyDecls that they
75 // reference, we destroy ObjCPropertyDecls in ~TranslationUnit.
Ted Kremenek8c945b12008-06-06 16:45:15 +000076 Decl::Destroy(C);
77}
78
79
Argiris Kirtzidis96e79bf2009-02-17 20:20:37 +000080ObjCIvarDecl *ObjCIvarDecl::Create(ASTContext &C, DeclContext *DC,
81 SourceLocation L, IdentifierInfo *Id,
82 QualType T, AccessControl ac, Expr *BW) {
83 return new (C) ObjCIvarDecl(DC, L, Id, T, ac, BW);
Chris Lattner114add62008-03-16 00:49:28 +000084}
85
Ted Kremeneke5bedfe2008-08-20 03:26:33 +000086
87ObjCAtDefsFieldDecl
Douglas Gregor8acb7272008-12-11 16:49:14 +000088*ObjCAtDefsFieldDecl::Create(ASTContext &C, DeclContext *DC, SourceLocation L,
Ted Kremeneke5bedfe2008-08-20 03:26:33 +000089 IdentifierInfo *Id, QualType T, Expr *BW) {
Steve Naroff5abb0282009-01-27 21:25:57 +000090 return new (C) ObjCAtDefsFieldDecl(DC, L, Id, T, BW);
Ted Kremeneke5bedfe2008-08-20 03:26:33 +000091}
92
93void ObjCAtDefsFieldDecl::Destroy(ASTContext& C) {
94 this->~ObjCAtDefsFieldDecl();
Steve Naroff5abb0282009-01-27 21:25:57 +000095 C.Deallocate((void *)this);
Ted Kremeneke5bedfe2008-08-20 03:26:33 +000096}
97
Douglas Gregor6e4fa2c2009-01-09 00:49:46 +000098ObjCProtocolDecl *ObjCProtocolDecl::Create(ASTContext &C, DeclContext *DC,
Chris Lattnereee57c02008-04-04 06:12:32 +000099 SourceLocation L,
Chris Lattner7afba9c2008-03-16 20:19:15 +0000100 IdentifierInfo *Id) {
Steve Naroff5abb0282009-01-27 21:25:57 +0000101 return new (C) ObjCProtocolDecl(DC, L, Id);
Chris Lattner180f7e22008-03-16 01:23:04 +0000102}
103
Chris Lattnerae538882009-02-20 05:54:35 +0000104void ObjCProtocolDecl::Destroy(ASTContext &C) {
Ted Kremenekc906e5e2008-06-06 19:48:57 +0000105 delete [] PropertyDecl;
Chris Lattnerae538882009-02-20 05:54:35 +0000106 PropertyDecl = 0;
107 ObjCContainerDecl::Destroy(C);
Ted Kremenekc906e5e2008-06-06 19:48:57 +0000108}
109
Ted Kremenekc906e5e2008-06-06 19:48:57 +0000110
Chris Lattnerae538882009-02-20 05:54:35 +0000111
112
Douglas Gregor6e4fa2c2009-01-09 00:49:46 +0000113ObjCClassDecl *ObjCClassDecl::Create(ASTContext &C, DeclContext *DC,
Chris Lattnereee57c02008-04-04 06:12:32 +0000114 SourceLocation L,
Chris Lattnere29dc832008-03-16 20:34:23 +0000115 ObjCInterfaceDecl **Elts, unsigned nElts) {
Steve Naroff5abb0282009-01-27 21:25:57 +0000116 return new (C) ObjCClassDecl(DC, L, Elts, nElts);
Chris Lattnere29dc832008-03-16 20:34:23 +0000117}
118
Ted Kremenekff291622008-06-06 20:11:53 +0000119ObjCClassDecl::~ObjCClassDecl() {
120 delete [] ForwardDecls;
121}
122
123void ObjCClassDecl::Destroy(ASTContext& C) {
124
125 // FIXME: There is no clear ownership policy now for referenced
126 // ObjCInterfaceDecls. Some of them can be forward declarations that
127 // are never later defined (in which case the ObjCClassDecl owns them)
128 // or the ObjCInterfaceDecl later becomes a real definition later. Ideally
129 // we should have separate objects for forward declarations and definitions,
130 // obviating this problem. Because of this situation, referenced
131 // ObjCInterfaceDecls are destroyed in ~TranslationUnit.
132
133 Decl::Destroy(C);
134}
135
Chris Lattnere29dc832008-03-16 20:34:23 +0000136ObjCForwardProtocolDecl *
Douglas Gregor6e4fa2c2009-01-09 00:49:46 +0000137ObjCForwardProtocolDecl::Create(ASTContext &C, DeclContext *DC,
Chris Lattnereee57c02008-04-04 06:12:32 +0000138 SourceLocation L,
Chris Lattnere29dc832008-03-16 20:34:23 +0000139 ObjCProtocolDecl **Elts, unsigned NumElts) {
Steve Naroff5abb0282009-01-27 21:25:57 +0000140 return new (C) ObjCForwardProtocolDecl(DC, L, Elts, NumElts);
Chris Lattnere29dc832008-03-16 20:34:23 +0000141}
142
Ted Kremenek1e5e0bf2008-06-06 21:05:33 +0000143ObjCForwardProtocolDecl::~ObjCForwardProtocolDecl() {
144 delete [] ReferencedProtocols;
145}
146
Douglas Gregor6e4fa2c2009-01-09 00:49:46 +0000147ObjCCategoryDecl *ObjCCategoryDecl::Create(ASTContext &C, DeclContext *DC,
Chris Lattnereee57c02008-04-04 06:12:32 +0000148 SourceLocation L,
Chris Lattnere29dc832008-03-16 20:34:23 +0000149 IdentifierInfo *Id) {
Steve Naroff5abb0282009-01-27 21:25:57 +0000150 return new (C) ObjCCategoryDecl(DC, L, Id);
Chris Lattnere29dc832008-03-16 20:34:23 +0000151}
152
Chris Lattner1b6de332008-03-16 20:53:07 +0000153ObjCCategoryImplDecl *
Douglas Gregor6e4fa2c2009-01-09 00:49:46 +0000154ObjCCategoryImplDecl::Create(ASTContext &C, DeclContext *DC,
Chris Lattnereee57c02008-04-04 06:12:32 +0000155 SourceLocation L,IdentifierInfo *Id,
Chris Lattner1b6de332008-03-16 20:53:07 +0000156 ObjCInterfaceDecl *ClassInterface) {
Steve Naroff5abb0282009-01-27 21:25:57 +0000157 return new (C) ObjCCategoryImplDecl(DC, L, Id, ClassInterface);
Chris Lattner1b6de332008-03-16 20:53:07 +0000158}
159
160ObjCImplementationDecl *
Douglas Gregor6e4fa2c2009-01-09 00:49:46 +0000161ObjCImplementationDecl::Create(ASTContext &C, DeclContext *DC,
Chris Lattnereee57c02008-04-04 06:12:32 +0000162 SourceLocation L,
Chris Lattner1b6de332008-03-16 20:53:07 +0000163 ObjCInterfaceDecl *ClassInterface,
164 ObjCInterfaceDecl *SuperDecl) {
Steve Naroff5abb0282009-01-27 21:25:57 +0000165 return new (C) ObjCImplementationDecl(DC, L, ClassInterface, SuperDecl);
Chris Lattner1b6de332008-03-16 20:53:07 +0000166}
Chris Lattner10318b82008-03-16 00:19:01 +0000167
Chris Lattner2d1c4312008-03-16 21:17:37 +0000168ObjCCompatibleAliasDecl *
Douglas Gregor6e4fa2c2009-01-09 00:49:46 +0000169ObjCCompatibleAliasDecl::Create(ASTContext &C, DeclContext *DC,
Chris Lattnereee57c02008-04-04 06:12:32 +0000170 SourceLocation L,
Chris Lattner2d1c4312008-03-16 21:17:37 +0000171 IdentifierInfo *Id,
172 ObjCInterfaceDecl* AliasedClass) {
Steve Naroff5abb0282009-01-27 21:25:57 +0000173 return new (C) ObjCCompatibleAliasDecl(DC, L, Id, AliasedClass);
Chris Lattner2d1c4312008-03-16 21:17:37 +0000174}
175
Douglas Gregor6e4fa2c2009-01-09 00:49:46 +0000176ObjCPropertyDecl *ObjCPropertyDecl::Create(ASTContext &C, DeclContext *DC,
Fariborz Jahaniane7071722008-04-11 23:40:25 +0000177 SourceLocation L,
Fariborz Jahanian0ceb4be2008-04-14 23:36:35 +0000178 IdentifierInfo *Id,
Fariborz Jahanian4aa72a72008-05-05 18:51:55 +0000179 QualType T,
180 PropertyControl propControl) {
Steve Naroff5abb0282009-01-27 21:25:57 +0000181 return new (C) ObjCPropertyDecl(DC, L, Id, T);
Chris Lattner2d1c4312008-03-16 21:17:37 +0000182}
183
Chris Lattner10318b82008-03-16 00:19:01 +0000184//===----------------------------------------------------------------------===//
185// Objective-C Decl Implementation
186//===----------------------------------------------------------------------===//
187
Fariborz Jahanian91dd9d32008-12-09 20:23:04 +0000188void ObjCMethodDecl::createImplicitParams(ASTContext &Context,
189 const ObjCInterfaceDecl *OID) {
Daniel Dunbar88116372008-08-26 06:08:30 +0000190 QualType selfTy;
Douglas Gregor5d764842009-01-09 17:18:27 +0000191 if (isInstanceMethod()) {
Daniel Dunbar88116372008-08-26 06:08:30 +0000192 // There may be no interface context due to error in declaration
193 // of the interface (which has been reported). Recover gracefully.
Fariborz Jahanian91dd9d32008-12-09 20:23:04 +0000194 if (OID) {
195 selfTy = Context.getObjCInterfaceType(const_cast<ObjCInterfaceDecl *>(OID));
Daniel Dunbar88116372008-08-26 06:08:30 +0000196 selfTy = Context.getPointerType(selfTy);
197 } else {
198 selfTy = Context.getObjCIdType();
199 }
200 } else // we have a factory method.
201 selfTy = Context.getObjCClassType();
202
203 SelfDecl = ImplicitParamDecl::Create(Context, this,
204 SourceLocation(),
205 &Context.Idents.get("self"),
Douglas Gregoraf8ad2b2009-01-20 01:17:11 +0000206 selfTy);
Daniel Dunbar88116372008-08-26 06:08:30 +0000207
208 CmdDecl = ImplicitParamDecl::Create(Context, this,
209 SourceLocation(),
210 &Context.Idents.get("_cmd"),
Douglas Gregoraf8ad2b2009-01-20 01:17:11 +0000211 Context.getObjCSelType());
Daniel Dunbar88116372008-08-26 06:08:30 +0000212}
213
Chris Lattner10318b82008-03-16 00:19:01 +0000214void ObjCMethodDecl::setMethodParams(ParmVarDecl **NewParamInfo,
215 unsigned NumParams) {
216 assert(ParamInfo == 0 && "Already has param info!");
217
218 // Zero params -> null pointer.
219 if (NumParams) {
220 ParamInfo = new ParmVarDecl*[NumParams];
221 memcpy(ParamInfo, NewParamInfo, sizeof(ParmVarDecl*)*NumParams);
222 NumMethodParams = NumParams;
223 }
224}
225
Fariborz Jahanianef8a3df2008-04-21 19:04:53 +0000226/// FindCategoryDeclaration - Finds category declaration in the list of
227/// categories for this class and returns it. Name of the category is passed
228/// in 'CategoryId'. If category not found, return 0;
229///
230ObjCCategoryDecl *
231 ObjCInterfaceDecl::FindCategoryDeclaration(IdentifierInfo *CategoryId) const {
232 for (ObjCCategoryDecl *Category = getCategoryList();
233 Category; Category = Category->getNextClassCategory())
234 if (Category->getIdentifier() == CategoryId)
235 return Category;
236 return 0;
237}
238
Chris Lattner10318b82008-03-16 00:19:01 +0000239/// ObjCAddInstanceVariablesToClass - Inserts instance variables
240/// into ObjCInterfaceDecl's fields.
241///
242void ObjCInterfaceDecl::addInstanceVariablesToClass(ObjCIvarDecl **ivars,
243 unsigned numIvars,
244 SourceLocation RBrac) {
245 NumIvars = numIvars;
246 if (numIvars) {
247 Ivars = new ObjCIvarDecl*[numIvars];
248 memcpy(Ivars, ivars, numIvars*sizeof(ObjCIvarDecl*));
249 }
250 setLocEnd(RBrac);
251}
252
Fariborz Jahanian09772392008-12-13 22:20:28 +0000253/// lookupFieldDeclForIvar - looks up a field decl' in the laid out
254/// storage which matches this 'ivar'.
255///
256FieldDecl *ObjCInterfaceDecl::lookupFieldDeclForIvar(ASTContext &Context,
Fariborz Jahanian86008c02008-12-15 20:35:07 +0000257 const ObjCIvarDecl *ivar) {
Fariborz Jahanian0556b152008-12-17 21:40:49 +0000258 const RecordDecl *RecordForDecl = Context.addRecordToClass(this);
Fariborz Jahanian09772392008-12-13 22:20:28 +0000259 assert(RecordForDecl && "lookupFieldDeclForIvar no storage for class");
260 DeclarationName Member = ivar->getDeclName();
Fariborz Jahanian0556b152008-12-17 21:40:49 +0000261 DeclContext::lookup_result Lookup = (const_cast< RecordDecl *>(RecordForDecl))
Steve Naroffab63fd62009-01-08 17:28:14 +0000262 ->lookup(Member);
Fariborz Jahanian09772392008-12-13 22:20:28 +0000263 assert((Lookup.first != Lookup.second) && "field decl not found");
264 FieldDecl *MemberDecl = dyn_cast<FieldDecl>(*Lookup.first);
265 assert(MemberDecl && "field decl not found");
266 return MemberDecl;
267}
268
Chris Lattner10318b82008-03-16 00:19:01 +0000269/// ObjCAddInstanceVariablesToClassImpl - Checks for correctness of Instance
270/// Variables (Ivars) relative to what declared in @implementation;s class.
271/// Ivars into ObjCImplementationDecl's fields.
272///
273void ObjCImplementationDecl::ObjCAddInstanceVariablesToClassImpl(
274 ObjCIvarDecl **ivars, unsigned numIvars) {
275 NumIvars = numIvars;
276 if (numIvars) {
277 Ivars = new ObjCIvarDecl*[numIvars];
278 memcpy(Ivars, ivars, numIvars*sizeof(ObjCIvarDecl*));
279 }
280}
281
Steve Naroffab63fd62009-01-08 17:28:14 +0000282// Get the local instance method declared in this interface.
283// FIXME: handle overloading, instance & class methods can have the same name.
284ObjCMethodDecl *ObjCContainerDecl::getInstanceMethod(Selector Sel) const {
285 lookup_const_result MethodResult = lookup(Sel);
286 if (MethodResult.first)
287 return const_cast<ObjCMethodDecl*>(
288 dyn_cast<ObjCMethodDecl>(*MethodResult.first));
289 return 0;
290}
291
292// Get the local class method declared in this interface.
293ObjCMethodDecl *ObjCContainerDecl::getClassMethod(Selector Sel) const {
294 lookup_const_result MethodResult = lookup(Sel);
295 if (MethodResult.first)
296 return const_cast<ObjCMethodDecl*>(
297 dyn_cast<ObjCMethodDecl>(*MethodResult.first));
298 return 0;
299}
300
301unsigned ObjCContainerDecl::getNumInstanceMethods() const {
302 unsigned sum = 0;
303 for (instmeth_iterator I=instmeth_begin(), E=instmeth_end(); I != E; ++I)
304 sum++;
305 return sum;
306}
307unsigned ObjCContainerDecl::getNumClassMethods() const {
308 unsigned sum = 0;
309 for (classmeth_iterator I=classmeth_begin(), E=classmeth_end(); I != E; ++I)
310 sum++;
311 return sum;
312}
Steve Naroff56af2002009-01-11 01:06:09 +0000313unsigned ObjCContainerDecl::getNumProperties() const {
314 unsigned sum = 0;
315 for (prop_iterator I=prop_begin(), E=prop_end(); I != E; ++I)
316 sum++;
317 return sum;
318}
Steve Naroffab63fd62009-01-08 17:28:14 +0000319
Fariborz Jahanianef8a3df2008-04-21 19:04:53 +0000320/// FindPropertyDeclaration - Finds declaration of the property given its name
321/// in 'PropertyId' and returns it. It returns 0, if not found.
Steve Naroffdcf1e842009-01-11 12:47:58 +0000322/// FIXME: Convert to DeclContext lookup...
Fariborz Jahanianef8a3df2008-04-21 19:04:53 +0000323///
324ObjCPropertyDecl *
Steve Naroff451f83c2009-01-09 15:36:25 +0000325ObjCContainerDecl::FindPropertyDeclaration(IdentifierInfo *PropertyId) const {
326 for (prop_iterator I = prop_begin(), E = prop_end(); I != E; ++I) {
Fariborz Jahanianef8a3df2008-04-21 19:04:53 +0000327 ObjCPropertyDecl *property = *I;
328 if (property->getIdentifier() == PropertyId)
329 return property;
330 }
Fariborz Jahanianfaca5e22009-01-09 21:04:52 +0000331 const ObjCProtocolDecl *PID = dyn_cast<ObjCProtocolDecl>(this);
332 if (PID) {
333 for (ObjCProtocolDecl::protocol_iterator P = PID->protocol_begin(),
334 E = PID->protocol_end();
335 P != E; ++P)
336 if (ObjCPropertyDecl *property =
337 (*P)->FindPropertyDeclaration(PropertyId))
338 return property;
339 }
340
Fariborz Jahanian6b0ed6f2009-01-19 18:16:19 +0000341 if (const ObjCInterfaceDecl *OID = dyn_cast<ObjCInterfaceDecl>(this)) {
Steve Naroff451f83c2009-01-09 15:36:25 +0000342 // Look through categories.
343 for (ObjCCategoryDecl *Category = OID->getCategoryList();
344 Category; Category = Category->getNextClassCategory()) {
345 ObjCPropertyDecl *property = Category->FindPropertyDeclaration(PropertyId);
346 if (property)
347 return property;
348 }
349 // Look through protocols.
350 for (ObjCInterfaceDecl::protocol_iterator I = OID->protocol_begin(),
351 E = OID->protocol_end(); I != E; ++I) {
352 ObjCProtocolDecl *Protocol = *I;
353 ObjCPropertyDecl *property = Protocol->FindPropertyDeclaration(PropertyId);
354 if (property)
355 return property;
356 }
357 if (OID->getSuperClass())
358 return OID->getSuperClass()->FindPropertyDeclaration(PropertyId);
Steve Naroffd1f0eb42008-06-05 13:55:23 +0000359 }
Fariborz Jahanian6b0ed6f2009-01-19 18:16:19 +0000360 else if (const ObjCCategoryDecl *OCD = dyn_cast<ObjCCategoryDecl>(this)) {
361 // Look through protocols.
362 for (ObjCInterfaceDecl::protocol_iterator I = OCD->protocol_begin(),
363 E = OCD->protocol_end(); I != E; ++I) {
364 ObjCProtocolDecl *Protocol = *I;
365 ObjCPropertyDecl *property = Protocol->FindPropertyDeclaration(PropertyId);
366 if (property)
367 return property;
368 }
369 }
Steve Naroffd1f0eb42008-06-05 13:55:23 +0000370 return 0;
371}
372
Chris Lattner10318b82008-03-16 00:19:01 +0000373ObjCIvarDecl *ObjCInterfaceDecl::lookupInstanceVariable(
374 IdentifierInfo *ID, ObjCInterfaceDecl *&clsDeclared) {
375 ObjCInterfaceDecl* ClassDecl = this;
376 while (ClassDecl != NULL) {
377 for (ivar_iterator I = ClassDecl->ivar_begin(), E = ClassDecl->ivar_end();
378 I != E; ++I) {
379 if ((*I)->getIdentifier() == ID) {
380 clsDeclared = ClassDecl;
381 return *I;
382 }
383 }
384 ClassDecl = ClassDecl->getSuperClass();
385 }
386 return NULL;
387}
388
389/// lookupInstanceMethod - This method returns an instance method by looking in
390/// the class, its categories, and its super classes (using a linear search).
391ObjCMethodDecl *ObjCInterfaceDecl::lookupInstanceMethod(Selector Sel) {
392 ObjCInterfaceDecl* ClassDecl = this;
393 ObjCMethodDecl *MethodDecl = 0;
394
395 while (ClassDecl != NULL) {
396 if ((MethodDecl = ClassDecl->getInstanceMethod(Sel)))
397 return MethodDecl;
398
399 // Didn't find one yet - look through protocols.
Chris Lattner8bcb5252008-07-21 18:19:38 +0000400 const ObjCList<ObjCProtocolDecl> &Protocols =
401 ClassDecl->getReferencedProtocols();
402 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
403 E = Protocols.end(); I != E; ++I)
404 if ((MethodDecl = (*I)->getInstanceMethod(Sel)))
Chris Lattner10318b82008-03-16 00:19:01 +0000405 return MethodDecl;
Chris Lattner8bcb5252008-07-21 18:19:38 +0000406
Chris Lattner10318b82008-03-16 00:19:01 +0000407 // Didn't find one yet - now look through categories.
408 ObjCCategoryDecl *CatDecl = ClassDecl->getCategoryList();
409 while (CatDecl) {
410 if ((MethodDecl = CatDecl->getInstanceMethod(Sel)))
411 return MethodDecl;
Steve Naroffaf151802008-12-08 20:57:28 +0000412
413 // Didn't find one yet - look through protocols.
414 const ObjCList<ObjCProtocolDecl> &Protocols =
415 CatDecl->getReferencedProtocols();
416 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
417 E = Protocols.end(); I != E; ++I)
418 if ((MethodDecl = (*I)->getInstanceMethod(Sel)))
419 return MethodDecl;
Chris Lattner10318b82008-03-16 00:19:01 +0000420 CatDecl = CatDecl->getNextClassCategory();
421 }
422 ClassDecl = ClassDecl->getSuperClass();
423 }
424 return NULL;
425}
426
427// lookupClassMethod - This method returns a class method by looking in the
428// class, its categories, and its super classes (using a linear search).
429ObjCMethodDecl *ObjCInterfaceDecl::lookupClassMethod(Selector Sel) {
430 ObjCInterfaceDecl* ClassDecl = this;
431 ObjCMethodDecl *MethodDecl = 0;
432
433 while (ClassDecl != NULL) {
434 if ((MethodDecl = ClassDecl->getClassMethod(Sel)))
435 return MethodDecl;
436
437 // Didn't find one yet - look through protocols.
Chris Lattner0be08822008-07-21 21:32:27 +0000438 for (ObjCInterfaceDecl::protocol_iterator I = ClassDecl->protocol_begin(),
439 E = ClassDecl->protocol_end(); I != E; ++I)
Chris Lattner8bcb5252008-07-21 18:19:38 +0000440 if ((MethodDecl = (*I)->getClassMethod(Sel)))
Chris Lattner10318b82008-03-16 00:19:01 +0000441 return MethodDecl;
Chris Lattner0be08822008-07-21 21:32:27 +0000442
Chris Lattner10318b82008-03-16 00:19:01 +0000443 // Didn't find one yet - now look through categories.
444 ObjCCategoryDecl *CatDecl = ClassDecl->getCategoryList();
445 while (CatDecl) {
446 if ((MethodDecl = CatDecl->getClassMethod(Sel)))
447 return MethodDecl;
448 CatDecl = CatDecl->getNextClassCategory();
449 }
450 ClassDecl = ClassDecl->getSuperClass();
451 }
452 return NULL;
453}
454
Daniel Dunbardd24b9a2008-08-26 06:53:45 +0000455/// getInstanceMethod - This method returns an instance method by
456/// looking in the class implementation. Unlike interfaces, we don't
457/// look outside the implementation.
458ObjCMethodDecl *ObjCImplementationDecl::getInstanceMethod(Selector Sel) const {
Chris Lattner10318b82008-03-16 00:19:01 +0000459 for (instmeth_iterator I = instmeth_begin(), E = instmeth_end(); I != E; ++I)
460 if ((*I)->getSelector() == Sel)
461 return *I;
462 return NULL;
463}
464
Daniel Dunbardd24b9a2008-08-26 06:53:45 +0000465/// getClassMethod - This method returns a class method by looking in
466/// the class implementation. Unlike interfaces, we don't look outside
467/// the implementation.
468ObjCMethodDecl *ObjCImplementationDecl::getClassMethod(Selector Sel) const {
Chris Lattner10318b82008-03-16 00:19:01 +0000469 for (classmeth_iterator I = classmeth_begin(), E = classmeth_end();
470 I != E; ++I)
471 if ((*I)->getSelector() == Sel)
472 return *I;
473 return NULL;
474}
475
Fariborz Jahanian68342282008-12-05 22:32:48 +0000476/// FindPropertyImplDecl - This method looks up a previous ObjCPropertyImplDecl
477/// added to the list of those properties @synthesized/@dynamic in this
478/// @implementation block.
479///
480ObjCPropertyImplDecl *ObjCImplementationDecl::FindPropertyImplDecl(IdentifierInfo *Id) const {
481 for (propimpl_iterator i = propimpl_begin(), e = propimpl_end(); i != e; ++i) {
482 ObjCPropertyImplDecl *PID = *i;
483 if (PID->getPropertyDecl()->getIdentifier() == Id)
484 return PID;
485 }
486 return 0;
487}
488
489/// FindPropertyImplIvarDecl - This method lookup the ivar in the list of
Fariborz Jahanian17eb8882008-12-05 22:36:19 +0000490/// properties implemented in this @implementation block and returns the
491/// implemented property that uses it.
Fariborz Jahanian68342282008-12-05 22:32:48 +0000492///
493ObjCPropertyImplDecl *ObjCImplementationDecl::FindPropertyImplIvarDecl(IdentifierInfo *ivarId) const {
494 for (propimpl_iterator i = propimpl_begin(), e = propimpl_end(); i != e; ++i) {
495 ObjCPropertyImplDecl *PID = *i;
496 if (PID->getPropertyIvarDecl() &&
497 PID->getPropertyIvarDecl()->getIdentifier() == ivarId)
498 return PID;
499 }
500 return 0;
501}
502
503/// FindPropertyImplIvarDecl - This method lookup the ivar in the list of
Chris Lattner715e8482009-02-16 19:24:31 +0000504/// properties implemented in this category @implementation block and returns
505/// the implemented property that uses it.
Fariborz Jahanian68342282008-12-05 22:32:48 +0000506///
Chris Lattner715e8482009-02-16 19:24:31 +0000507ObjCPropertyImplDecl *ObjCCategoryImplDecl::
508FindPropertyImplIvarDecl(IdentifierInfo *ivarId) const {
509 for (propimpl_iterator i = propimpl_begin(), e = propimpl_end(); i != e; ++i){
Fariborz Jahanian68342282008-12-05 22:32:48 +0000510 ObjCPropertyImplDecl *PID = *i;
511 if (PID->getPropertyIvarDecl() &&
512 PID->getPropertyIvarDecl()->getIdentifier() == ivarId)
513 return PID;
514 }
515 return 0;
516}
517
518/// FindPropertyImplDecl - This method looks up a previous ObjCPropertyImplDecl
519/// added to the list of those properties @synthesized/@dynamic in this
520/// category @implementation block.
521///
Chris Lattner715e8482009-02-16 19:24:31 +0000522ObjCPropertyImplDecl *ObjCCategoryImplDecl::
523FindPropertyImplDecl(IdentifierInfo *Id) const {
524 for (propimpl_iterator i = propimpl_begin(), e = propimpl_end(); i != e; ++i){
Fariborz Jahanian68342282008-12-05 22:32:48 +0000525 ObjCPropertyImplDecl *PID = *i;
526 if (PID->getPropertyDecl()->getIdentifier() == Id)
527 return PID;
528 }
529 return 0;
530}
531
Chris Lattner10318b82008-03-16 00:19:01 +0000532// lookupInstanceMethod - This method returns an instance method by looking in
533// the class implementation. Unlike interfaces, we don't look outside the
534// implementation.
Daniel Dunbardd24b9a2008-08-26 06:53:45 +0000535ObjCMethodDecl *ObjCCategoryImplDecl::getInstanceMethod(Selector Sel) const {
Chris Lattner10318b82008-03-16 00:19:01 +0000536 for (instmeth_iterator I = instmeth_begin(), E = instmeth_end(); I != E; ++I)
537 if ((*I)->getSelector() == Sel)
538 return *I;
539 return NULL;
540}
541
542// lookupClassMethod - This method returns an instance method by looking in
543// the class implementation. Unlike interfaces, we don't look outside the
544// implementation.
Daniel Dunbardd24b9a2008-08-26 06:53:45 +0000545ObjCMethodDecl *ObjCCategoryImplDecl::getClassMethod(Selector Sel) const {
Chris Lattner10318b82008-03-16 00:19:01 +0000546 for (classmeth_iterator I = classmeth_begin(), E = classmeth_end();
547 I != E; ++I)
548 if ((*I)->getSelector() == Sel)
549 return *I;
550 return NULL;
551}
552
553// lookupInstanceMethod - Lookup a instance method in the protocol and protocols
554// it inherited.
555ObjCMethodDecl *ObjCProtocolDecl::lookupInstanceMethod(Selector Sel) {
556 ObjCMethodDecl *MethodDecl = NULL;
557
558 if ((MethodDecl = getInstanceMethod(Sel)))
559 return MethodDecl;
560
Chris Lattner0be08822008-07-21 21:32:27 +0000561 for (protocol_iterator I = protocol_begin(), E = protocol_end(); I != E; ++I)
Steve Naroff30fb1da2008-12-18 15:50:41 +0000562 if ((MethodDecl = (*I)->lookupInstanceMethod(Sel)))
Chris Lattner0be08822008-07-21 21:32:27 +0000563 return MethodDecl;
Chris Lattner10318b82008-03-16 00:19:01 +0000564 return NULL;
565}
566
567// lookupInstanceMethod - Lookup a class method in the protocol and protocols
568// it inherited.
569ObjCMethodDecl *ObjCProtocolDecl::lookupClassMethod(Selector Sel) {
570 ObjCMethodDecl *MethodDecl = NULL;
571
572 if ((MethodDecl = getClassMethod(Sel)))
573 return MethodDecl;
574
Chris Lattner0be08822008-07-21 21:32:27 +0000575 for (protocol_iterator I = protocol_begin(), E = protocol_end(); I != E; ++I)
Steve Naroff30fb1da2008-12-18 15:50:41 +0000576 if ((MethodDecl = (*I)->lookupClassMethod(Sel)))
Chris Lattner0be08822008-07-21 21:32:27 +0000577 return MethodDecl;
Chris Lattner10318b82008-03-16 00:19:01 +0000578 return NULL;
579}
580
581/// getSynthesizedMethodSize - Compute size of synthesized method name
582/// as done be the rewrite.
583///
584unsigned ObjCMethodDecl::getSynthesizedMethodSize() const {
585 // syntesized method name is a concatenation of -/+[class-name selector]
586 // Get length of this name.
587 unsigned length = 3; // _I_ or _C_
Chris Lattnerd120b9e2008-11-24 03:54:41 +0000588 length += getClassInterface()->getNameAsString().size()+1; // extra for _
Steve Naroff438be772009-01-08 19:41:02 +0000589 if (const ObjCCategoryImplDecl *CID =
590 dyn_cast<ObjCCategoryImplDecl>(getDeclContext()))
Chris Lattnerd120b9e2008-11-24 03:54:41 +0000591 length += CID->getNameAsString().size()+1;
Chris Lattner3a8f2942008-11-24 03:33:13 +0000592 length += getSelector().getAsString().size(); // selector name
Chris Lattner10318b82008-03-16 00:19:01 +0000593 return length;
594}
595
Chris Lattner052fbcd2008-04-06 05:25:03 +0000596ObjCInterfaceDecl *ObjCMethodDecl::getClassInterface() {
Steve Naroff438be772009-01-08 19:41:02 +0000597 if (ObjCInterfaceDecl *ID = dyn_cast<ObjCInterfaceDecl>(getDeclContext()))
Chris Lattner10318b82008-03-16 00:19:01 +0000598 return ID;
Steve Naroff438be772009-01-08 19:41:02 +0000599 if (ObjCCategoryDecl *CD = dyn_cast<ObjCCategoryDecl>(getDeclContext()))
Chris Lattner10318b82008-03-16 00:19:01 +0000600 return CD->getClassInterface();
601 if (ObjCImplementationDecl *IMD =
Steve Naroff438be772009-01-08 19:41:02 +0000602 dyn_cast<ObjCImplementationDecl>(getDeclContext()))
Chris Lattner10318b82008-03-16 00:19:01 +0000603 return IMD->getClassInterface();
Steve Naroff438be772009-01-08 19:41:02 +0000604 if (ObjCCategoryImplDecl *CID =
605 dyn_cast<ObjCCategoryImplDecl>(getDeclContext()))
Chris Lattner10318b82008-03-16 00:19:01 +0000606 return CID->getClassInterface();
607 assert(false && "unknown method context");
608 return 0;
609}
Chris Lattner44859612008-03-17 01:19:02 +0000610
Fariborz Jahaniandc0569e2008-04-23 00:06:01 +0000611ObjCPropertyImplDecl *ObjCPropertyImplDecl::Create(ASTContext &C,
Douglas Gregor6e4fa2c2009-01-09 00:49:46 +0000612 DeclContext *DC,
Fariborz Jahaniandc0569e2008-04-23 00:06:01 +0000613 SourceLocation atLoc,
614 SourceLocation L,
615 ObjCPropertyDecl *property,
Daniel Dunbar14117fc2008-08-26 04:47:31 +0000616 Kind PK,
Fariborz Jahaniandc0569e2008-04-23 00:06:01 +0000617 ObjCIvarDecl *ivar) {
Steve Naroff5abb0282009-01-27 21:25:57 +0000618 return new (C) ObjCPropertyImplDecl(DC, atLoc, L, property, PK, ivar);
Fariborz Jahaniandc0569e2008-04-23 00:06:01 +0000619}
Chris Lattner44859612008-03-17 01:19:02 +0000620
Chris Lattnereee57c02008-04-04 06:12:32 +0000621