blob: ea7a047780c8e88b75bfa26a76fad2957d66b00b [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"
Daniel Dunbare91593e2008-08-11 04:54:23 +000016#include "clang/AST/Stmt.h"
Chris Lattner1e03a562008-03-16 00:19:01 +000017using namespace clang;
18
Chris Lattner6c4ae5d2008-03-16 00:49:28 +000019//===----------------------------------------------------------------------===//
20// ObjC Decl Allocation/Deallocation Method Implementations
21//===----------------------------------------------------------------------===//
22
Chris Lattner0ed844b2008-04-04 06:12:32 +000023ObjCMethodDecl *ObjCMethodDecl::Create(ASTContext &C,
24 SourceLocation beginLoc,
Chris Lattner6c4ae5d2008-03-16 00:49:28 +000025 SourceLocation endLoc,
26 Selector SelInfo, QualType T,
Steve Naroff0701bbb2009-01-08 17:28:14 +000027 DeclContext *contextDecl,
Daniel Dunbarf6414922008-08-20 18:02:42 +000028 bool isInstance,
Chris Lattner6c4ae5d2008-03-16 00:49:28 +000029 bool isVariadic,
Fariborz Jahanian46070342008-05-07 20:53:44 +000030 bool isSynthesized,
Chris Lattnerb06fa3b2008-03-16 00:58:16 +000031 ImplementationControl impControl) {
Chris Lattner6c4ae5d2008-03-16 00:49:28 +000032 void *Mem = C.getAllocator().Allocate<ObjCMethodDecl>();
Chris Lattner0ed844b2008-04-04 06:12:32 +000033 return new (Mem) ObjCMethodDecl(beginLoc, endLoc,
34 SelInfo, T, contextDecl,
Daniel Dunbarf6414922008-08-20 18:02:42 +000035 isInstance,
Fariborz Jahanian46070342008-05-07 20:53:44 +000036 isVariadic, isSynthesized, impControl);
Chris Lattner0e77ba02008-03-16 01:15:50 +000037}
Chris Lattner6c4ae5d2008-03-16 00:49:28 +000038
Ted Kremenek8a779312008-06-06 16:45:15 +000039ObjCMethodDecl::~ObjCMethodDecl() {
40 delete [] ParamInfo;
Ted Kremenek8a779312008-06-06 16:45:15 +000041}
42
43void ObjCMethodDecl::Destroy(ASTContext& C) {
44 if (Body) Body->Destroy(C);
45 if (SelfDecl) SelfDecl->Destroy(C);
46
47 for (param_iterator I=param_begin(), E=param_end(); I!=E; ++I)
48 if (*I) (*I)->Destroy(C);
49
50 Decl::Destroy(C);
51}
52
Chris Lattner0ed844b2008-04-04 06:12:32 +000053ObjCInterfaceDecl *ObjCInterfaceDecl::Create(ASTContext &C,
Douglas Gregord0434102009-01-09 00:49:46 +000054 DeclContext *DC,
Chris Lattner0ed844b2008-04-04 06:12:32 +000055 SourceLocation atLoc,
Steve Naroffd6a07aa2008-04-11 19:35:35 +000056 IdentifierInfo *Id,
57 SourceLocation ClassLoc,
Chris Lattner0e77ba02008-03-16 01:15:50 +000058 bool ForwardDecl, bool isInternal){
59 void *Mem = C.getAllocator().Allocate<ObjCInterfaceDecl>();
Douglas Gregord0434102009-01-09 00:49:46 +000060 return new (Mem) ObjCInterfaceDecl(DC, atLoc, Id, ClassLoc, ForwardDecl,
Chris Lattner0e77ba02008-03-16 01:15:50 +000061 isInternal);
62}
63
Steve Naroffe4f039e2009-01-07 17:57:40 +000064ObjCContainerDecl::~ObjCContainerDecl() {
Steve Naroffe4f039e2009-01-07 17:57:40 +000065}
66
67ObjCInterfaceDecl::~ObjCInterfaceDecl() {
68 delete [] Ivars;
Ted Kremenek8a779312008-06-06 16:45:15 +000069 // FIXME: CategoryList?
70}
71
72void ObjCInterfaceDecl::Destroy(ASTContext& C) {
73 for (ivar_iterator I=ivar_begin(), E=ivar_end(); I!=E; ++I)
74 if (*I) (*I)->Destroy(C);
75
Ted Kremenek1a726d72008-06-06 17:21:42 +000076 // FIXME: Because there is no clear ownership
77 // role between ObjCInterfaceDecls and the ObjCPropertyDecls that they
78 // reference, we destroy ObjCPropertyDecls in ~TranslationUnit.
Ted Kremenek8a779312008-06-06 16:45:15 +000079 Decl::Destroy(C);
80}
81
82
Chris Lattnerb048c982008-04-06 04:47:34 +000083ObjCIvarDecl *ObjCIvarDecl::Create(ASTContext &C, SourceLocation L,
Ted Kremenekb8db21d2008-07-23 18:04:17 +000084 IdentifierInfo *Id, QualType T,
85 AccessControl ac, Expr *BW) {
Chris Lattner0e77ba02008-03-16 01:15:50 +000086 void *Mem = C.getAllocator().Allocate<ObjCIvarDecl>();
Ted Kremenekb8db21d2008-07-23 18:04:17 +000087 return new (Mem) ObjCIvarDecl(L, Id, T, ac, BW);
Chris Lattner6c4ae5d2008-03-16 00:49:28 +000088}
89
Ted Kremenek01e67792008-08-20 03:26:33 +000090
91ObjCAtDefsFieldDecl
Douglas Gregor44b43212008-12-11 16:49:14 +000092*ObjCAtDefsFieldDecl::Create(ASTContext &C, DeclContext *DC, SourceLocation L,
Ted Kremenek01e67792008-08-20 03:26:33 +000093 IdentifierInfo *Id, QualType T, Expr *BW) {
94 void *Mem = C.getAllocator().Allocate<ObjCAtDefsFieldDecl>();
Douglas Gregor44b43212008-12-11 16:49:14 +000095 return new (Mem) ObjCAtDefsFieldDecl(DC, L, Id, T, BW);
Ted Kremenek01e67792008-08-20 03:26:33 +000096}
97
98void ObjCAtDefsFieldDecl::Destroy(ASTContext& C) {
99 this->~ObjCAtDefsFieldDecl();
100 C.getAllocator().Deallocate((void *)this);
101}
102
Douglas Gregord0434102009-01-09 00:49:46 +0000103ObjCProtocolDecl *ObjCProtocolDecl::Create(ASTContext &C, DeclContext *DC,
Chris Lattner0ed844b2008-04-04 06:12:32 +0000104 SourceLocation L,
Chris Lattnerc8581052008-03-16 20:19:15 +0000105 IdentifierInfo *Id) {
Chris Lattnercca59d72008-03-16 01:23:04 +0000106 void *Mem = C.getAllocator().Allocate<ObjCProtocolDecl>();
Douglas Gregord0434102009-01-09 00:49:46 +0000107 return new (Mem) ObjCProtocolDecl(DC, L, Id);
Chris Lattnercca59d72008-03-16 01:23:04 +0000108}
109
Ted Kremenek1c8a4132008-06-06 19:48:57 +0000110ObjCProtocolDecl::~ObjCProtocolDecl() {
Ted Kremenek1c8a4132008-06-06 19:48:57 +0000111 delete [] PropertyDecl;
112}
113
Ted Kremenek1c8a4132008-06-06 19:48:57 +0000114
Douglas Gregord0434102009-01-09 00:49:46 +0000115ObjCClassDecl *ObjCClassDecl::Create(ASTContext &C, DeclContext *DC,
Chris Lattner0ed844b2008-04-04 06:12:32 +0000116 SourceLocation L,
Chris Lattner61f9d412008-03-16 20:34:23 +0000117 ObjCInterfaceDecl **Elts, unsigned nElts) {
118 void *Mem = C.getAllocator().Allocate<ObjCClassDecl>();
Douglas Gregord0434102009-01-09 00:49:46 +0000119 return new (Mem) ObjCClassDecl(DC, L, Elts, nElts);
Chris Lattner61f9d412008-03-16 20:34:23 +0000120}
121
Ted Kremenek400d95f2008-06-06 20:11:53 +0000122ObjCClassDecl::~ObjCClassDecl() {
123 delete [] ForwardDecls;
124}
125
126void ObjCClassDecl::Destroy(ASTContext& C) {
127
128 // FIXME: There is no clear ownership policy now for referenced
129 // ObjCInterfaceDecls. Some of them can be forward declarations that
130 // are never later defined (in which case the ObjCClassDecl owns them)
131 // or the ObjCInterfaceDecl later becomes a real definition later. Ideally
132 // we should have separate objects for forward declarations and definitions,
133 // obviating this problem. Because of this situation, referenced
134 // ObjCInterfaceDecls are destroyed in ~TranslationUnit.
135
136 Decl::Destroy(C);
137}
138
Chris Lattner61f9d412008-03-16 20:34:23 +0000139ObjCForwardProtocolDecl *
Douglas Gregord0434102009-01-09 00:49:46 +0000140ObjCForwardProtocolDecl::Create(ASTContext &C, DeclContext *DC,
Chris Lattner0ed844b2008-04-04 06:12:32 +0000141 SourceLocation L,
Chris Lattner61f9d412008-03-16 20:34:23 +0000142 ObjCProtocolDecl **Elts, unsigned NumElts) {
143 void *Mem = C.getAllocator().Allocate<ObjCForwardProtocolDecl>();
Douglas Gregord0434102009-01-09 00:49:46 +0000144 return new (Mem) ObjCForwardProtocolDecl(DC, L, Elts, NumElts);
Chris Lattner61f9d412008-03-16 20:34:23 +0000145}
146
Ted Kremenek05ac3ef2008-06-06 21:05:33 +0000147ObjCForwardProtocolDecl::~ObjCForwardProtocolDecl() {
148 delete [] ReferencedProtocols;
149}
150
Douglas Gregord0434102009-01-09 00:49:46 +0000151ObjCCategoryDecl *ObjCCategoryDecl::Create(ASTContext &C, DeclContext *DC,
Chris Lattner0ed844b2008-04-04 06:12:32 +0000152 SourceLocation L,
Chris Lattner61f9d412008-03-16 20:34:23 +0000153 IdentifierInfo *Id) {
154 void *Mem = C.getAllocator().Allocate<ObjCCategoryDecl>();
Douglas Gregord0434102009-01-09 00:49:46 +0000155 return new (Mem) ObjCCategoryDecl(DC, L, Id);
Chris Lattner61f9d412008-03-16 20:34:23 +0000156}
157
Chris Lattner75c9cae2008-03-16 20:53:07 +0000158ObjCCategoryImplDecl *
Douglas Gregord0434102009-01-09 00:49:46 +0000159ObjCCategoryImplDecl::Create(ASTContext &C, DeclContext *DC,
Chris Lattner0ed844b2008-04-04 06:12:32 +0000160 SourceLocation L,IdentifierInfo *Id,
Chris Lattner75c9cae2008-03-16 20:53:07 +0000161 ObjCInterfaceDecl *ClassInterface) {
162 void *Mem = C.getAllocator().Allocate<ObjCCategoryImplDecl>();
Douglas Gregord0434102009-01-09 00:49:46 +0000163 return new (Mem) ObjCCategoryImplDecl(DC, L, Id, ClassInterface);
Chris Lattner75c9cae2008-03-16 20:53:07 +0000164}
165
166ObjCImplementationDecl *
Douglas Gregord0434102009-01-09 00:49:46 +0000167ObjCImplementationDecl::Create(ASTContext &C, DeclContext *DC,
Chris Lattner0ed844b2008-04-04 06:12:32 +0000168 SourceLocation L,
Chris Lattner75c9cae2008-03-16 20:53:07 +0000169 IdentifierInfo *Id,
170 ObjCInterfaceDecl *ClassInterface,
171 ObjCInterfaceDecl *SuperDecl) {
172 void *Mem = C.getAllocator().Allocate<ObjCImplementationDecl>();
Douglas Gregord0434102009-01-09 00:49:46 +0000173 return new (Mem) ObjCImplementationDecl(DC, L, Id, ClassInterface, SuperDecl);
Chris Lattner75c9cae2008-03-16 20:53:07 +0000174}
Chris Lattner1e03a562008-03-16 00:19:01 +0000175
Chris Lattnerf8d17a52008-03-16 21:17:37 +0000176ObjCCompatibleAliasDecl *
Douglas Gregord0434102009-01-09 00:49:46 +0000177ObjCCompatibleAliasDecl::Create(ASTContext &C, DeclContext *DC,
Chris Lattner0ed844b2008-04-04 06:12:32 +0000178 SourceLocation L,
Chris Lattnerf8d17a52008-03-16 21:17:37 +0000179 IdentifierInfo *Id,
180 ObjCInterfaceDecl* AliasedClass) {
181 void *Mem = C.getAllocator().Allocate<ObjCCompatibleAliasDecl>();
Douglas Gregord0434102009-01-09 00:49:46 +0000182 return new (Mem) ObjCCompatibleAliasDecl(DC, L, Id, AliasedClass);
Chris Lattnerf8d17a52008-03-16 21:17:37 +0000183}
184
Douglas Gregord0434102009-01-09 00:49:46 +0000185ObjCPropertyDecl *ObjCPropertyDecl::Create(ASTContext &C, DeclContext *DC,
Fariborz Jahaniandae1a1a2008-04-11 23:40:25 +0000186 SourceLocation L,
Fariborz Jahanian1de1e742008-04-14 23:36:35 +0000187 IdentifierInfo *Id,
Fariborz Jahanian46b55e52008-05-05 18:51:55 +0000188 QualType T,
189 PropertyControl propControl) {
Chris Lattnerf8d17a52008-03-16 21:17:37 +0000190 void *Mem = C.getAllocator().Allocate<ObjCPropertyDecl>();
Douglas Gregord0434102009-01-09 00:49:46 +0000191 return new (Mem) ObjCPropertyDecl(DC, L, Id, T);
Chris Lattnerf8d17a52008-03-16 21:17:37 +0000192}
193
Chris Lattner1e03a562008-03-16 00:19:01 +0000194//===----------------------------------------------------------------------===//
195// Objective-C Decl Implementation
196//===----------------------------------------------------------------------===//
197
Fariborz Jahanianfef30b52008-12-09 20:23:04 +0000198void ObjCMethodDecl::createImplicitParams(ASTContext &Context,
199 const ObjCInterfaceDecl *OID) {
Daniel Dunbar08a356c2008-08-26 06:08:30 +0000200 QualType selfTy;
Douglas Gregorf8d49f62009-01-09 17:18:27 +0000201 if (isInstanceMethod()) {
Daniel Dunbar08a356c2008-08-26 06:08:30 +0000202 // There may be no interface context due to error in declaration
203 // of the interface (which has been reported). Recover gracefully.
Fariborz Jahanianfef30b52008-12-09 20:23:04 +0000204 if (OID) {
205 selfTy = Context.getObjCInterfaceType(const_cast<ObjCInterfaceDecl *>(OID));
Daniel Dunbar08a356c2008-08-26 06:08:30 +0000206 selfTy = Context.getPointerType(selfTy);
207 } else {
208 selfTy = Context.getObjCIdType();
209 }
210 } else // we have a factory method.
211 selfTy = Context.getObjCClassType();
212
213 SelfDecl = ImplicitParamDecl::Create(Context, this,
214 SourceLocation(),
215 &Context.Idents.get("self"),
216 selfTy, 0);
217
218 CmdDecl = ImplicitParamDecl::Create(Context, this,
219 SourceLocation(),
220 &Context.Idents.get("_cmd"),
221 Context.getObjCSelType(), 0);
222}
223
Chris Lattner1e03a562008-03-16 00:19:01 +0000224void ObjCMethodDecl::setMethodParams(ParmVarDecl **NewParamInfo,
225 unsigned NumParams) {
226 assert(ParamInfo == 0 && "Already has param info!");
227
228 // Zero params -> null pointer.
229 if (NumParams) {
230 ParamInfo = new ParmVarDecl*[NumParams];
231 memcpy(ParamInfo, NewParamInfo, sizeof(ParmVarDecl*)*NumParams);
232 NumMethodParams = NumParams;
233 }
234}
235
Fariborz Jahanian559c0c42008-04-21 19:04:53 +0000236/// FindCategoryDeclaration - Finds category declaration in the list of
237/// categories for this class and returns it. Name of the category is passed
238/// in 'CategoryId'. If category not found, return 0;
239///
240ObjCCategoryDecl *
241 ObjCInterfaceDecl::FindCategoryDeclaration(IdentifierInfo *CategoryId) const {
242 for (ObjCCategoryDecl *Category = getCategoryList();
243 Category; Category = Category->getNextClassCategory())
244 if (Category->getIdentifier() == CategoryId)
245 return Category;
246 return 0;
247}
248
249/// FindIvarDeclaration - Find an Ivar declaration in this class given its
250/// name in 'IvarId'. On failure to find, return 0;
251///
252ObjCIvarDecl *
253 ObjCInterfaceDecl::FindIvarDeclaration(IdentifierInfo *IvarId) const {
254 for (ObjCInterfaceDecl::ivar_iterator IVI = ivar_begin(),
255 IVE = ivar_end(); IVI != IVE; ++IVI) {
256 ObjCIvarDecl* Ivar = (*IVI);
257 if (Ivar->getIdentifier() == IvarId)
258 return Ivar;
259 }
Fariborz Jahanianc70bee82008-04-21 23:57:08 +0000260 if (getSuperClass())
261 return getSuperClass()->FindIvarDeclaration(IvarId);
Fariborz Jahanian559c0c42008-04-21 19:04:53 +0000262 return 0;
263}
264
Chris Lattner1e03a562008-03-16 00:19:01 +0000265/// ObjCAddInstanceVariablesToClass - Inserts instance variables
266/// into ObjCInterfaceDecl's fields.
267///
268void ObjCInterfaceDecl::addInstanceVariablesToClass(ObjCIvarDecl **ivars,
269 unsigned numIvars,
270 SourceLocation RBrac) {
271 NumIvars = numIvars;
272 if (numIvars) {
273 Ivars = new ObjCIvarDecl*[numIvars];
274 memcpy(Ivars, ivars, numIvars*sizeof(ObjCIvarDecl*));
275 }
276 setLocEnd(RBrac);
277}
278
Fariborz Jahanianaaa63a72008-12-13 22:20:28 +0000279/// lookupFieldDeclForIvar - looks up a field decl' in the laid out
280/// storage which matches this 'ivar'.
281///
282FieldDecl *ObjCInterfaceDecl::lookupFieldDeclForIvar(ASTContext &Context,
Fariborz Jahanianfd64bb62008-12-15 20:35:07 +0000283 const ObjCIvarDecl *ivar) {
Fariborz Jahaniana769c002008-12-17 21:40:49 +0000284 const RecordDecl *RecordForDecl = Context.addRecordToClass(this);
Fariborz Jahanianaaa63a72008-12-13 22:20:28 +0000285 assert(RecordForDecl && "lookupFieldDeclForIvar no storage for class");
286 DeclarationName Member = ivar->getDeclName();
Fariborz Jahaniana769c002008-12-17 21:40:49 +0000287 DeclContext::lookup_result Lookup = (const_cast< RecordDecl *>(RecordForDecl))
Steve Naroff0701bbb2009-01-08 17:28:14 +0000288 ->lookup(Member);
Fariborz Jahanianaaa63a72008-12-13 22:20:28 +0000289 assert((Lookup.first != Lookup.second) && "field decl not found");
290 FieldDecl *MemberDecl = dyn_cast<FieldDecl>(*Lookup.first);
291 assert(MemberDecl && "field decl not found");
292 return MemberDecl;
293}
294
Chris Lattner1e03a562008-03-16 00:19:01 +0000295/// ObjCAddInstanceVariablesToClassImpl - Checks for correctness of Instance
296/// Variables (Ivars) relative to what declared in @implementation;s class.
297/// Ivars into ObjCImplementationDecl's fields.
298///
299void ObjCImplementationDecl::ObjCAddInstanceVariablesToClassImpl(
300 ObjCIvarDecl **ivars, unsigned numIvars) {
301 NumIvars = numIvars;
302 if (numIvars) {
303 Ivars = new ObjCIvarDecl*[numIvars];
304 memcpy(Ivars, ivars, numIvars*sizeof(ObjCIvarDecl*));
305 }
306}
307
Steve Naroff0701bbb2009-01-08 17:28:14 +0000308// Get the local instance method declared in this interface.
309// FIXME: handle overloading, instance & class methods can have the same name.
310ObjCMethodDecl *ObjCContainerDecl::getInstanceMethod(Selector Sel) const {
311 lookup_const_result MethodResult = lookup(Sel);
312 if (MethodResult.first)
313 return const_cast<ObjCMethodDecl*>(
314 dyn_cast<ObjCMethodDecl>(*MethodResult.first));
315 return 0;
316}
317
318// Get the local class method declared in this interface.
319ObjCMethodDecl *ObjCContainerDecl::getClassMethod(Selector Sel) const {
320 lookup_const_result MethodResult = lookup(Sel);
321 if (MethodResult.first)
322 return const_cast<ObjCMethodDecl*>(
323 dyn_cast<ObjCMethodDecl>(*MethodResult.first));
324 return 0;
325}
326
327unsigned ObjCContainerDecl::getNumInstanceMethods() const {
328 unsigned sum = 0;
329 for (instmeth_iterator I=instmeth_begin(), E=instmeth_end(); I != E; ++I)
330 sum++;
331 return sum;
332}
333unsigned ObjCContainerDecl::getNumClassMethods() const {
334 unsigned sum = 0;
335 for (classmeth_iterator I=classmeth_begin(), E=classmeth_end(); I != E; ++I)
336 sum++;
337 return sum;
338}
Steve Naroff6327e0d2009-01-11 01:06:09 +0000339unsigned ObjCContainerDecl::getNumProperties() const {
340 unsigned sum = 0;
341 for (prop_iterator I=prop_begin(), E=prop_end(); I != E; ++I)
342 sum++;
343 return sum;
344}
Steve Naroff0701bbb2009-01-08 17:28:14 +0000345
Fariborz Jahanian559c0c42008-04-21 19:04:53 +0000346/// FindPropertyDeclaration - Finds declaration of the property given its name
347/// in 'PropertyId' and returns it. It returns 0, if not found.
Steve Naroff93983f82009-01-11 12:47:58 +0000348/// FIXME: Convert to DeclContext lookup...
Fariborz Jahanian559c0c42008-04-21 19:04:53 +0000349///
350ObjCPropertyDecl *
Steve Naroff09c47192009-01-09 15:36:25 +0000351ObjCContainerDecl::FindPropertyDeclaration(IdentifierInfo *PropertyId) const {
352 for (prop_iterator I = prop_begin(), E = prop_end(); I != E; ++I) {
Fariborz Jahanian559c0c42008-04-21 19:04:53 +0000353 ObjCPropertyDecl *property = *I;
354 if (property->getIdentifier() == PropertyId)
355 return property;
356 }
Fariborz Jahaniana66793e2009-01-09 21:04:52 +0000357 const ObjCProtocolDecl *PID = dyn_cast<ObjCProtocolDecl>(this);
358 if (PID) {
359 for (ObjCProtocolDecl::protocol_iterator P = PID->protocol_begin(),
360 E = PID->protocol_end();
361 P != E; ++P)
362 if (ObjCPropertyDecl *property =
363 (*P)->FindPropertyDeclaration(PropertyId))
364 return property;
365 }
366
Steve Naroff09c47192009-01-09 15:36:25 +0000367 const ObjCInterfaceDecl *OID = dyn_cast<ObjCInterfaceDecl>(this);
368 if (OID) {
369 // Look through categories.
370 for (ObjCCategoryDecl *Category = OID->getCategoryList();
371 Category; Category = Category->getNextClassCategory()) {
372 ObjCPropertyDecl *property = Category->FindPropertyDeclaration(PropertyId);
373 if (property)
374 return property;
375 }
376 // Look through protocols.
377 for (ObjCInterfaceDecl::protocol_iterator I = OID->protocol_begin(),
378 E = OID->protocol_end(); I != E; ++I) {
379 ObjCProtocolDecl *Protocol = *I;
380 ObjCPropertyDecl *property = Protocol->FindPropertyDeclaration(PropertyId);
381 if (property)
382 return property;
383 }
384 if (OID->getSuperClass())
385 return OID->getSuperClass()->FindPropertyDeclaration(PropertyId);
Steve Naroff3d2c22b2008-06-05 13:55:23 +0000386 }
387 return 0;
388}
389
Chris Lattner1e03a562008-03-16 00:19:01 +0000390ObjCIvarDecl *ObjCInterfaceDecl::lookupInstanceVariable(
391 IdentifierInfo *ID, ObjCInterfaceDecl *&clsDeclared) {
392 ObjCInterfaceDecl* ClassDecl = this;
393 while (ClassDecl != NULL) {
394 for (ivar_iterator I = ClassDecl->ivar_begin(), E = ClassDecl->ivar_end();
395 I != E; ++I) {
396 if ((*I)->getIdentifier() == ID) {
397 clsDeclared = ClassDecl;
398 return *I;
399 }
400 }
401 ClassDecl = ClassDecl->getSuperClass();
402 }
403 return NULL;
404}
405
406/// lookupInstanceMethod - This method returns an instance method by looking in
407/// the class, its categories, and its super classes (using a linear search).
408ObjCMethodDecl *ObjCInterfaceDecl::lookupInstanceMethod(Selector Sel) {
409 ObjCInterfaceDecl* ClassDecl = this;
410 ObjCMethodDecl *MethodDecl = 0;
411
412 while (ClassDecl != NULL) {
413 if ((MethodDecl = ClassDecl->getInstanceMethod(Sel)))
414 return MethodDecl;
415
416 // Didn't find one yet - look through protocols.
Chris Lattner3db6cae2008-07-21 18:19:38 +0000417 const ObjCList<ObjCProtocolDecl> &Protocols =
418 ClassDecl->getReferencedProtocols();
419 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
420 E = Protocols.end(); I != E; ++I)
421 if ((MethodDecl = (*I)->getInstanceMethod(Sel)))
Chris Lattner1e03a562008-03-16 00:19:01 +0000422 return MethodDecl;
Chris Lattner3db6cae2008-07-21 18:19:38 +0000423
Chris Lattner1e03a562008-03-16 00:19:01 +0000424 // Didn't find one yet - now look through categories.
425 ObjCCategoryDecl *CatDecl = ClassDecl->getCategoryList();
426 while (CatDecl) {
427 if ((MethodDecl = CatDecl->getInstanceMethod(Sel)))
428 return MethodDecl;
Steve Naroffb79c01e2008-12-08 20:57:28 +0000429
430 // Didn't find one yet - look through protocols.
431 const ObjCList<ObjCProtocolDecl> &Protocols =
432 CatDecl->getReferencedProtocols();
433 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
434 E = Protocols.end(); I != E; ++I)
435 if ((MethodDecl = (*I)->getInstanceMethod(Sel)))
436 return MethodDecl;
Chris Lattner1e03a562008-03-16 00:19:01 +0000437 CatDecl = CatDecl->getNextClassCategory();
438 }
439 ClassDecl = ClassDecl->getSuperClass();
440 }
441 return NULL;
442}
443
444// lookupClassMethod - This method returns a class method by looking in the
445// class, its categories, and its super classes (using a linear search).
446ObjCMethodDecl *ObjCInterfaceDecl::lookupClassMethod(Selector Sel) {
447 ObjCInterfaceDecl* ClassDecl = this;
448 ObjCMethodDecl *MethodDecl = 0;
449
450 while (ClassDecl != NULL) {
451 if ((MethodDecl = ClassDecl->getClassMethod(Sel)))
452 return MethodDecl;
453
454 // Didn't find one yet - look through protocols.
Chris Lattner780f3292008-07-21 21:32:27 +0000455 for (ObjCInterfaceDecl::protocol_iterator I = ClassDecl->protocol_begin(),
456 E = ClassDecl->protocol_end(); I != E; ++I)
Chris Lattner3db6cae2008-07-21 18:19:38 +0000457 if ((MethodDecl = (*I)->getClassMethod(Sel)))
Chris Lattner1e03a562008-03-16 00:19:01 +0000458 return MethodDecl;
Chris Lattner780f3292008-07-21 21:32:27 +0000459
Chris Lattner1e03a562008-03-16 00:19:01 +0000460 // Didn't find one yet - now look through categories.
461 ObjCCategoryDecl *CatDecl = ClassDecl->getCategoryList();
462 while (CatDecl) {
463 if ((MethodDecl = CatDecl->getClassMethod(Sel)))
464 return MethodDecl;
465 CatDecl = CatDecl->getNextClassCategory();
466 }
467 ClassDecl = ClassDecl->getSuperClass();
468 }
469 return NULL;
470}
471
Daniel Dunbar3216dcd2008-08-26 06:53:45 +0000472/// getInstanceMethod - This method returns an instance method by
473/// looking in the class implementation. Unlike interfaces, we don't
474/// look outside the implementation.
475ObjCMethodDecl *ObjCImplementationDecl::getInstanceMethod(Selector Sel) const {
Chris Lattner1e03a562008-03-16 00:19:01 +0000476 for (instmeth_iterator I = instmeth_begin(), E = instmeth_end(); I != E; ++I)
477 if ((*I)->getSelector() == Sel)
478 return *I;
479 return NULL;
480}
481
Daniel Dunbar3216dcd2008-08-26 06:53:45 +0000482/// getClassMethod - This method returns a class method by looking in
483/// the class implementation. Unlike interfaces, we don't look outside
484/// the implementation.
485ObjCMethodDecl *ObjCImplementationDecl::getClassMethod(Selector Sel) const {
Chris Lattner1e03a562008-03-16 00:19:01 +0000486 for (classmeth_iterator I = classmeth_begin(), E = classmeth_end();
487 I != E; ++I)
488 if ((*I)->getSelector() == Sel)
489 return *I;
490 return NULL;
491}
492
Fariborz Jahanianae6f6fd2008-12-05 22:32:48 +0000493/// FindPropertyImplDecl - This method looks up a previous ObjCPropertyImplDecl
494/// added to the list of those properties @synthesized/@dynamic in this
495/// @implementation block.
496///
497ObjCPropertyImplDecl *ObjCImplementationDecl::FindPropertyImplDecl(IdentifierInfo *Id) const {
498 for (propimpl_iterator i = propimpl_begin(), e = propimpl_end(); i != e; ++i) {
499 ObjCPropertyImplDecl *PID = *i;
500 if (PID->getPropertyDecl()->getIdentifier() == Id)
501 return PID;
502 }
503 return 0;
504}
505
506/// FindPropertyImplIvarDecl - This method lookup the ivar in the list of
Fariborz Jahanian9482a4f2008-12-05 22:36:19 +0000507/// properties implemented in this @implementation block and returns the
508/// implemented property that uses it.
Fariborz Jahanianae6f6fd2008-12-05 22:32:48 +0000509///
510ObjCPropertyImplDecl *ObjCImplementationDecl::FindPropertyImplIvarDecl(IdentifierInfo *ivarId) const {
511 for (propimpl_iterator i = propimpl_begin(), e = propimpl_end(); i != e; ++i) {
512 ObjCPropertyImplDecl *PID = *i;
513 if (PID->getPropertyIvarDecl() &&
514 PID->getPropertyIvarDecl()->getIdentifier() == ivarId)
515 return PID;
516 }
517 return 0;
518}
519
520/// FindPropertyImplIvarDecl - This method lookup the ivar in the list of
Fariborz Jahanian9482a4f2008-12-05 22:36:19 +0000521/// properties implemented in this category @implementation block and returns the
522/// implemented property that uses it.
Fariborz Jahanianae6f6fd2008-12-05 22:32:48 +0000523///
524ObjCPropertyImplDecl *ObjCCategoryImplDecl::FindPropertyImplIvarDecl(IdentifierInfo *ivarId) const {
525 for (propimpl_iterator i = propimpl_begin(), e = propimpl_end(); i != e; ++i) {
526 ObjCPropertyImplDecl *PID = *i;
527 if (PID->getPropertyIvarDecl() &&
528 PID->getPropertyIvarDecl()->getIdentifier() == ivarId)
529 return PID;
530 }
531 return 0;
532}
533
534/// FindPropertyImplDecl - This method looks up a previous ObjCPropertyImplDecl
535/// added to the list of those properties @synthesized/@dynamic in this
536/// category @implementation block.
537///
538ObjCPropertyImplDecl *ObjCCategoryImplDecl::FindPropertyImplDecl(IdentifierInfo *Id) const {
539 for (propimpl_iterator i = propimpl_begin(), e = propimpl_end(); i != e; ++i) {
540 ObjCPropertyImplDecl *PID = *i;
541 if (PID->getPropertyDecl()->getIdentifier() == Id)
542 return PID;
543 }
544 return 0;
545}
546
Chris Lattner1e03a562008-03-16 00:19:01 +0000547// lookupInstanceMethod - This method returns an instance method by looking in
548// the class implementation. Unlike interfaces, we don't look outside the
549// implementation.
Daniel Dunbar3216dcd2008-08-26 06:53:45 +0000550ObjCMethodDecl *ObjCCategoryImplDecl::getInstanceMethod(Selector Sel) const {
Chris Lattner1e03a562008-03-16 00:19:01 +0000551 for (instmeth_iterator I = instmeth_begin(), E = instmeth_end(); I != E; ++I)
552 if ((*I)->getSelector() == Sel)
553 return *I;
554 return NULL;
555}
556
557// lookupClassMethod - This method returns an instance method by looking in
558// the class implementation. Unlike interfaces, we don't look outside the
559// implementation.
Daniel Dunbar3216dcd2008-08-26 06:53:45 +0000560ObjCMethodDecl *ObjCCategoryImplDecl::getClassMethod(Selector Sel) const {
Chris Lattner1e03a562008-03-16 00:19:01 +0000561 for (classmeth_iterator I = classmeth_begin(), E = classmeth_end();
562 I != E; ++I)
563 if ((*I)->getSelector() == Sel)
564 return *I;
565 return NULL;
566}
567
568// lookupInstanceMethod - Lookup a instance method in the protocol and protocols
569// it inherited.
570ObjCMethodDecl *ObjCProtocolDecl::lookupInstanceMethod(Selector Sel) {
571 ObjCMethodDecl *MethodDecl = NULL;
572
573 if ((MethodDecl = getInstanceMethod(Sel)))
574 return MethodDecl;
575
Chris Lattner780f3292008-07-21 21:32:27 +0000576 for (protocol_iterator I = protocol_begin(), E = protocol_end(); I != E; ++I)
Steve Naroffd8df6822008-12-18 15:50:41 +0000577 if ((MethodDecl = (*I)->lookupInstanceMethod(Sel)))
Chris Lattner780f3292008-07-21 21:32:27 +0000578 return MethodDecl;
Chris Lattner1e03a562008-03-16 00:19:01 +0000579 return NULL;
580}
581
582// lookupInstanceMethod - Lookup a class method in the protocol and protocols
583// it inherited.
584ObjCMethodDecl *ObjCProtocolDecl::lookupClassMethod(Selector Sel) {
585 ObjCMethodDecl *MethodDecl = NULL;
586
587 if ((MethodDecl = getClassMethod(Sel)))
588 return MethodDecl;
589
Chris Lattner780f3292008-07-21 21:32:27 +0000590 for (protocol_iterator I = protocol_begin(), E = protocol_end(); I != E; ++I)
Steve Naroffd8df6822008-12-18 15:50:41 +0000591 if ((MethodDecl = (*I)->lookupClassMethod(Sel)))
Chris Lattner780f3292008-07-21 21:32:27 +0000592 return MethodDecl;
Chris Lattner1e03a562008-03-16 00:19:01 +0000593 return NULL;
594}
595
596/// getSynthesizedMethodSize - Compute size of synthesized method name
597/// as done be the rewrite.
598///
599unsigned ObjCMethodDecl::getSynthesizedMethodSize() const {
600 // syntesized method name is a concatenation of -/+[class-name selector]
601 // Get length of this name.
602 unsigned length = 3; // _I_ or _C_
Chris Lattner8ec03f52008-11-24 03:54:41 +0000603 length += getClassInterface()->getNameAsString().size()+1; // extra for _
Steve Naroff3e0a5402009-01-08 19:41:02 +0000604 if (const ObjCCategoryImplDecl *CID =
605 dyn_cast<ObjCCategoryImplDecl>(getDeclContext()))
Chris Lattner8ec03f52008-11-24 03:54:41 +0000606 length += CID->getNameAsString().size()+1;
Chris Lattner077bf5e2008-11-24 03:33:13 +0000607 length += getSelector().getAsString().size(); // selector name
Chris Lattner1e03a562008-03-16 00:19:01 +0000608 return length;
609}
610
Chris Lattner56196882008-04-06 05:25:03 +0000611ObjCInterfaceDecl *ObjCMethodDecl::getClassInterface() {
Steve Naroff3e0a5402009-01-08 19:41:02 +0000612 if (ObjCInterfaceDecl *ID = dyn_cast<ObjCInterfaceDecl>(getDeclContext()))
Chris Lattner1e03a562008-03-16 00:19:01 +0000613 return ID;
Steve Naroff3e0a5402009-01-08 19:41:02 +0000614 if (ObjCCategoryDecl *CD = dyn_cast<ObjCCategoryDecl>(getDeclContext()))
Chris Lattner1e03a562008-03-16 00:19:01 +0000615 return CD->getClassInterface();
616 if (ObjCImplementationDecl *IMD =
Steve Naroff3e0a5402009-01-08 19:41:02 +0000617 dyn_cast<ObjCImplementationDecl>(getDeclContext()))
Chris Lattner1e03a562008-03-16 00:19:01 +0000618 return IMD->getClassInterface();
Steve Naroff3e0a5402009-01-08 19:41:02 +0000619 if (ObjCCategoryImplDecl *CID =
620 dyn_cast<ObjCCategoryImplDecl>(getDeclContext()))
Chris Lattner1e03a562008-03-16 00:19:01 +0000621 return CID->getClassInterface();
622 assert(false && "unknown method context");
623 return 0;
624}
Chris Lattnerf4af5152008-03-17 01:19:02 +0000625
Fariborz Jahanian628b96f2008-04-23 00:06:01 +0000626ObjCPropertyImplDecl *ObjCPropertyImplDecl::Create(ASTContext &C,
Douglas Gregord0434102009-01-09 00:49:46 +0000627 DeclContext *DC,
Fariborz Jahanian628b96f2008-04-23 00:06:01 +0000628 SourceLocation atLoc,
629 SourceLocation L,
630 ObjCPropertyDecl *property,
Daniel Dunbar9f0afd42008-08-26 04:47:31 +0000631 Kind PK,
Fariborz Jahanian628b96f2008-04-23 00:06:01 +0000632 ObjCIvarDecl *ivar) {
633 void *Mem = C.getAllocator().Allocate<ObjCPropertyImplDecl>();
Douglas Gregord0434102009-01-09 00:49:46 +0000634 return new (Mem) ObjCPropertyImplDecl(DC, atLoc, L, property, PK, ivar);
Fariborz Jahanian628b96f2008-04-23 00:06:01 +0000635}
Chris Lattnerf4af5152008-03-17 01:19:02 +0000636
Chris Lattner0ed844b2008-04-04 06:12:32 +0000637