blob: bbbcc5f6714f5a18f809dde0ac160c3796ec1845 [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) {
Chris Lattner114add62008-03-16 00:49:28 +000032 void *Mem = C.getAllocator().Allocate<ObjCMethodDecl>();
Chris Lattnereee57c02008-04-04 06:12:32 +000033 return new (Mem) ObjCMethodDecl(beginLoc, endLoc,
34 SelInfo, T, contextDecl,
Daniel Dunbard8bd6822008-08-20 18:02:42 +000035 isInstance,
Fariborz Jahanian5f2e2242008-05-07 20:53:44 +000036 isVariadic, isSynthesized, impControl);
Chris Lattner0db541b2008-03-16 01:15:50 +000037}
Chris Lattner114add62008-03-16 00:49:28 +000038
Ted Kremenek8c945b12008-06-06 16:45:15 +000039ObjCMethodDecl::~ObjCMethodDecl() {
40 delete [] ParamInfo;
Ted Kremenek8c945b12008-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 Lattnereee57c02008-04-04 06:12:32 +000053ObjCInterfaceDecl *ObjCInterfaceDecl::Create(ASTContext &C,
Douglas Gregor6e4fa2c2009-01-09 00:49:46 +000054 DeclContext *DC,
Chris Lattnereee57c02008-04-04 06:12:32 +000055 SourceLocation atLoc,
Steve Naroff7c371742008-04-11 19:35:35 +000056 IdentifierInfo *Id,
57 SourceLocation ClassLoc,
Chris Lattner0db541b2008-03-16 01:15:50 +000058 bool ForwardDecl, bool isInternal){
59 void *Mem = C.getAllocator().Allocate<ObjCInterfaceDecl>();
Douglas Gregor6e4fa2c2009-01-09 00:49:46 +000060 return new (Mem) ObjCInterfaceDecl(DC, atLoc, Id, ClassLoc, ForwardDecl,
Chris Lattner0db541b2008-03-16 01:15:50 +000061 isInternal);
62}
63
Steve Naroffd9d4d502009-01-07 17:57:40 +000064ObjCContainerDecl::~ObjCContainerDecl() {
Steve Naroffd9d4d502009-01-07 17:57:40 +000065}
66
67ObjCInterfaceDecl::~ObjCInterfaceDecl() {
68 delete [] Ivars;
Ted Kremenek8c945b12008-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 Kremenek22db1602008-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 Kremenek8c945b12008-06-06 16:45:15 +000079 Decl::Destroy(C);
80}
81
82
Chris Lattnerf3874bc2008-04-06 04:47:34 +000083ObjCIvarDecl *ObjCIvarDecl::Create(ASTContext &C, SourceLocation L,
Ted Kremenek173dd312008-07-23 18:04:17 +000084 IdentifierInfo *Id, QualType T,
85 AccessControl ac, Expr *BW) {
Chris Lattner0db541b2008-03-16 01:15:50 +000086 void *Mem = C.getAllocator().Allocate<ObjCIvarDecl>();
Ted Kremenek173dd312008-07-23 18:04:17 +000087 return new (Mem) ObjCIvarDecl(L, Id, T, ac, BW);
Chris Lattner114add62008-03-16 00:49:28 +000088}
89
Ted Kremeneke5bedfe2008-08-20 03:26:33 +000090
91ObjCAtDefsFieldDecl
Douglas Gregor8acb7272008-12-11 16:49:14 +000092*ObjCAtDefsFieldDecl::Create(ASTContext &C, DeclContext *DC, SourceLocation L,
Ted Kremeneke5bedfe2008-08-20 03:26:33 +000093 IdentifierInfo *Id, QualType T, Expr *BW) {
94 void *Mem = C.getAllocator().Allocate<ObjCAtDefsFieldDecl>();
Douglas Gregor8acb7272008-12-11 16:49:14 +000095 return new (Mem) ObjCAtDefsFieldDecl(DC, L, Id, T, BW);
Ted Kremeneke5bedfe2008-08-20 03:26:33 +000096}
97
98void ObjCAtDefsFieldDecl::Destroy(ASTContext& C) {
99 this->~ObjCAtDefsFieldDecl();
100 C.getAllocator().Deallocate((void *)this);
101}
102
Douglas Gregor6e4fa2c2009-01-09 00:49:46 +0000103ObjCProtocolDecl *ObjCProtocolDecl::Create(ASTContext &C, DeclContext *DC,
Chris Lattnereee57c02008-04-04 06:12:32 +0000104 SourceLocation L,
Chris Lattner7afba9c2008-03-16 20:19:15 +0000105 IdentifierInfo *Id) {
Chris Lattner180f7e22008-03-16 01:23:04 +0000106 void *Mem = C.getAllocator().Allocate<ObjCProtocolDecl>();
Douglas Gregor6e4fa2c2009-01-09 00:49:46 +0000107 return new (Mem) ObjCProtocolDecl(DC, L, Id);
Chris Lattner180f7e22008-03-16 01:23:04 +0000108}
109
Ted Kremenekc906e5e2008-06-06 19:48:57 +0000110ObjCProtocolDecl::~ObjCProtocolDecl() {
Ted Kremenekc906e5e2008-06-06 19:48:57 +0000111 delete [] PropertyDecl;
112}
113
Ted Kremenekc906e5e2008-06-06 19:48:57 +0000114
Douglas Gregor6e4fa2c2009-01-09 00:49:46 +0000115ObjCClassDecl *ObjCClassDecl::Create(ASTContext &C, DeclContext *DC,
Chris Lattnereee57c02008-04-04 06:12:32 +0000116 SourceLocation L,
Chris Lattnere29dc832008-03-16 20:34:23 +0000117 ObjCInterfaceDecl **Elts, unsigned nElts) {
118 void *Mem = C.getAllocator().Allocate<ObjCClassDecl>();
Douglas Gregor6e4fa2c2009-01-09 00:49:46 +0000119 return new (Mem) ObjCClassDecl(DC, L, Elts, nElts);
Chris Lattnere29dc832008-03-16 20:34:23 +0000120}
121
Ted Kremenekff291622008-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 Lattnere29dc832008-03-16 20:34:23 +0000139ObjCForwardProtocolDecl *
Douglas Gregor6e4fa2c2009-01-09 00:49:46 +0000140ObjCForwardProtocolDecl::Create(ASTContext &C, DeclContext *DC,
Chris Lattnereee57c02008-04-04 06:12:32 +0000141 SourceLocation L,
Chris Lattnere29dc832008-03-16 20:34:23 +0000142 ObjCProtocolDecl **Elts, unsigned NumElts) {
143 void *Mem = C.getAllocator().Allocate<ObjCForwardProtocolDecl>();
Douglas Gregor6e4fa2c2009-01-09 00:49:46 +0000144 return new (Mem) ObjCForwardProtocolDecl(DC, L, Elts, NumElts);
Chris Lattnere29dc832008-03-16 20:34:23 +0000145}
146
Ted Kremenek1e5e0bf2008-06-06 21:05:33 +0000147ObjCForwardProtocolDecl::~ObjCForwardProtocolDecl() {
148 delete [] ReferencedProtocols;
149}
150
Douglas Gregor6e4fa2c2009-01-09 00:49:46 +0000151ObjCCategoryDecl *ObjCCategoryDecl::Create(ASTContext &C, DeclContext *DC,
Chris Lattnereee57c02008-04-04 06:12:32 +0000152 SourceLocation L,
Chris Lattnere29dc832008-03-16 20:34:23 +0000153 IdentifierInfo *Id) {
154 void *Mem = C.getAllocator().Allocate<ObjCCategoryDecl>();
Douglas Gregor6e4fa2c2009-01-09 00:49:46 +0000155 return new (Mem) ObjCCategoryDecl(DC, L, Id);
Chris Lattnere29dc832008-03-16 20:34:23 +0000156}
157
Chris Lattner1b6de332008-03-16 20:53:07 +0000158ObjCCategoryImplDecl *
Douglas Gregor6e4fa2c2009-01-09 00:49:46 +0000159ObjCCategoryImplDecl::Create(ASTContext &C, DeclContext *DC,
Chris Lattnereee57c02008-04-04 06:12:32 +0000160 SourceLocation L,IdentifierInfo *Id,
Chris Lattner1b6de332008-03-16 20:53:07 +0000161 ObjCInterfaceDecl *ClassInterface) {
162 void *Mem = C.getAllocator().Allocate<ObjCCategoryImplDecl>();
Douglas Gregor6e4fa2c2009-01-09 00:49:46 +0000163 return new (Mem) ObjCCategoryImplDecl(DC, L, Id, ClassInterface);
Chris Lattner1b6de332008-03-16 20:53:07 +0000164}
165
166ObjCImplementationDecl *
Douglas Gregor6e4fa2c2009-01-09 00:49:46 +0000167ObjCImplementationDecl::Create(ASTContext &C, DeclContext *DC,
Chris Lattnereee57c02008-04-04 06:12:32 +0000168 SourceLocation L,
Chris Lattner1b6de332008-03-16 20:53:07 +0000169 ObjCInterfaceDecl *ClassInterface,
170 ObjCInterfaceDecl *SuperDecl) {
171 void *Mem = C.getAllocator().Allocate<ObjCImplementationDecl>();
Douglas Gregoraf8ad2b2009-01-20 01:17:11 +0000172 return new (Mem) ObjCImplementationDecl(DC, L, ClassInterface, SuperDecl);
Chris Lattner1b6de332008-03-16 20:53:07 +0000173}
Chris Lattner10318b82008-03-16 00:19:01 +0000174
Chris Lattner2d1c4312008-03-16 21:17:37 +0000175ObjCCompatibleAliasDecl *
Douglas Gregor6e4fa2c2009-01-09 00:49:46 +0000176ObjCCompatibleAliasDecl::Create(ASTContext &C, DeclContext *DC,
Chris Lattnereee57c02008-04-04 06:12:32 +0000177 SourceLocation L,
Chris Lattner2d1c4312008-03-16 21:17:37 +0000178 IdentifierInfo *Id,
179 ObjCInterfaceDecl* AliasedClass) {
180 void *Mem = C.getAllocator().Allocate<ObjCCompatibleAliasDecl>();
Douglas Gregor6e4fa2c2009-01-09 00:49:46 +0000181 return new (Mem) ObjCCompatibleAliasDecl(DC, L, Id, AliasedClass);
Chris Lattner2d1c4312008-03-16 21:17:37 +0000182}
183
Douglas Gregor6e4fa2c2009-01-09 00:49:46 +0000184ObjCPropertyDecl *ObjCPropertyDecl::Create(ASTContext &C, DeclContext *DC,
Fariborz Jahaniane7071722008-04-11 23:40:25 +0000185 SourceLocation L,
Fariborz Jahanian0ceb4be2008-04-14 23:36:35 +0000186 IdentifierInfo *Id,
Fariborz Jahanian4aa72a72008-05-05 18:51:55 +0000187 QualType T,
188 PropertyControl propControl) {
Chris Lattner2d1c4312008-03-16 21:17:37 +0000189 void *Mem = C.getAllocator().Allocate<ObjCPropertyDecl>();
Douglas Gregor6e4fa2c2009-01-09 00:49:46 +0000190 return new (Mem) ObjCPropertyDecl(DC, L, Id, T);
Chris Lattner2d1c4312008-03-16 21:17:37 +0000191}
192
Chris Lattner10318b82008-03-16 00:19:01 +0000193//===----------------------------------------------------------------------===//
194// Objective-C Decl Implementation
195//===----------------------------------------------------------------------===//
196
Fariborz Jahanian91dd9d32008-12-09 20:23:04 +0000197void ObjCMethodDecl::createImplicitParams(ASTContext &Context,
198 const ObjCInterfaceDecl *OID) {
Daniel Dunbar88116372008-08-26 06:08:30 +0000199 QualType selfTy;
Douglas Gregor5d764842009-01-09 17:18:27 +0000200 if (isInstanceMethod()) {
Daniel Dunbar88116372008-08-26 06:08:30 +0000201 // There may be no interface context due to error in declaration
202 // of the interface (which has been reported). Recover gracefully.
Fariborz Jahanian91dd9d32008-12-09 20:23:04 +0000203 if (OID) {
204 selfTy = Context.getObjCInterfaceType(const_cast<ObjCInterfaceDecl *>(OID));
Daniel Dunbar88116372008-08-26 06:08:30 +0000205 selfTy = Context.getPointerType(selfTy);
206 } else {
207 selfTy = Context.getObjCIdType();
208 }
209 } else // we have a factory method.
210 selfTy = Context.getObjCClassType();
211
212 SelfDecl = ImplicitParamDecl::Create(Context, this,
213 SourceLocation(),
214 &Context.Idents.get("self"),
Douglas Gregoraf8ad2b2009-01-20 01:17:11 +0000215 selfTy);
Daniel Dunbar88116372008-08-26 06:08:30 +0000216
217 CmdDecl = ImplicitParamDecl::Create(Context, this,
218 SourceLocation(),
219 &Context.Idents.get("_cmd"),
Douglas Gregoraf8ad2b2009-01-20 01:17:11 +0000220 Context.getObjCSelType());
Daniel Dunbar88116372008-08-26 06:08:30 +0000221}
222
Chris Lattner10318b82008-03-16 00:19:01 +0000223void ObjCMethodDecl::setMethodParams(ParmVarDecl **NewParamInfo,
224 unsigned NumParams) {
225 assert(ParamInfo == 0 && "Already has param info!");
226
227 // Zero params -> null pointer.
228 if (NumParams) {
229 ParamInfo = new ParmVarDecl*[NumParams];
230 memcpy(ParamInfo, NewParamInfo, sizeof(ParmVarDecl*)*NumParams);
231 NumMethodParams = NumParams;
232 }
233}
234
Fariborz Jahanianef8a3df2008-04-21 19:04:53 +0000235/// FindCategoryDeclaration - Finds category declaration in the list of
236/// categories for this class and returns it. Name of the category is passed
237/// in 'CategoryId'. If category not found, return 0;
238///
239ObjCCategoryDecl *
240 ObjCInterfaceDecl::FindCategoryDeclaration(IdentifierInfo *CategoryId) const {
241 for (ObjCCategoryDecl *Category = getCategoryList();
242 Category; Category = Category->getNextClassCategory())
243 if (Category->getIdentifier() == CategoryId)
244 return Category;
245 return 0;
246}
247
248/// FindIvarDeclaration - Find an Ivar declaration in this class given its
249/// name in 'IvarId'. On failure to find, return 0;
250///
251ObjCIvarDecl *
252 ObjCInterfaceDecl::FindIvarDeclaration(IdentifierInfo *IvarId) const {
253 for (ObjCInterfaceDecl::ivar_iterator IVI = ivar_begin(),
254 IVE = ivar_end(); IVI != IVE; ++IVI) {
255 ObjCIvarDecl* Ivar = (*IVI);
256 if (Ivar->getIdentifier() == IvarId)
257 return Ivar;
258 }
Fariborz Jahanian8acf3352008-04-21 23:57:08 +0000259 if (getSuperClass())
260 return getSuperClass()->FindIvarDeclaration(IvarId);
Fariborz Jahanianef8a3df2008-04-21 19:04:53 +0000261 return 0;
262}
263
Chris Lattner10318b82008-03-16 00:19:01 +0000264/// ObjCAddInstanceVariablesToClass - Inserts instance variables
265/// into ObjCInterfaceDecl's fields.
266///
267void ObjCInterfaceDecl::addInstanceVariablesToClass(ObjCIvarDecl **ivars,
268 unsigned numIvars,
269 SourceLocation RBrac) {
270 NumIvars = numIvars;
271 if (numIvars) {
272 Ivars = new ObjCIvarDecl*[numIvars];
273 memcpy(Ivars, ivars, numIvars*sizeof(ObjCIvarDecl*));
274 }
275 setLocEnd(RBrac);
276}
277
Fariborz Jahanian09772392008-12-13 22:20:28 +0000278/// lookupFieldDeclForIvar - looks up a field decl' in the laid out
279/// storage which matches this 'ivar'.
280///
281FieldDecl *ObjCInterfaceDecl::lookupFieldDeclForIvar(ASTContext &Context,
Fariborz Jahanian86008c02008-12-15 20:35:07 +0000282 const ObjCIvarDecl *ivar) {
Fariborz Jahanian0556b152008-12-17 21:40:49 +0000283 const RecordDecl *RecordForDecl = Context.addRecordToClass(this);
Fariborz Jahanian09772392008-12-13 22:20:28 +0000284 assert(RecordForDecl && "lookupFieldDeclForIvar no storage for class");
285 DeclarationName Member = ivar->getDeclName();
Fariborz Jahanian0556b152008-12-17 21:40:49 +0000286 DeclContext::lookup_result Lookup = (const_cast< RecordDecl *>(RecordForDecl))
Steve Naroffab63fd62009-01-08 17:28:14 +0000287 ->lookup(Member);
Fariborz Jahanian09772392008-12-13 22:20:28 +0000288 assert((Lookup.first != Lookup.second) && "field decl not found");
289 FieldDecl *MemberDecl = dyn_cast<FieldDecl>(*Lookup.first);
290 assert(MemberDecl && "field decl not found");
291 return MemberDecl;
292}
293
Chris Lattner10318b82008-03-16 00:19:01 +0000294/// ObjCAddInstanceVariablesToClassImpl - Checks for correctness of Instance
295/// Variables (Ivars) relative to what declared in @implementation;s class.
296/// Ivars into ObjCImplementationDecl's fields.
297///
298void ObjCImplementationDecl::ObjCAddInstanceVariablesToClassImpl(
299 ObjCIvarDecl **ivars, unsigned numIvars) {
300 NumIvars = numIvars;
301 if (numIvars) {
302 Ivars = new ObjCIvarDecl*[numIvars];
303 memcpy(Ivars, ivars, numIvars*sizeof(ObjCIvarDecl*));
304 }
305}
306
Steve Naroffab63fd62009-01-08 17:28:14 +0000307// Get the local instance method declared in this interface.
308// FIXME: handle overloading, instance & class methods can have the same name.
309ObjCMethodDecl *ObjCContainerDecl::getInstanceMethod(Selector Sel) const {
310 lookup_const_result MethodResult = lookup(Sel);
311 if (MethodResult.first)
312 return const_cast<ObjCMethodDecl*>(
313 dyn_cast<ObjCMethodDecl>(*MethodResult.first));
314 return 0;
315}
316
317// Get the local class method declared in this interface.
318ObjCMethodDecl *ObjCContainerDecl::getClassMethod(Selector Sel) const {
319 lookup_const_result MethodResult = lookup(Sel);
320 if (MethodResult.first)
321 return const_cast<ObjCMethodDecl*>(
322 dyn_cast<ObjCMethodDecl>(*MethodResult.first));
323 return 0;
324}
325
326unsigned ObjCContainerDecl::getNumInstanceMethods() const {
327 unsigned sum = 0;
328 for (instmeth_iterator I=instmeth_begin(), E=instmeth_end(); I != E; ++I)
329 sum++;
330 return sum;
331}
332unsigned ObjCContainerDecl::getNumClassMethods() const {
333 unsigned sum = 0;
334 for (classmeth_iterator I=classmeth_begin(), E=classmeth_end(); I != E; ++I)
335 sum++;
336 return sum;
337}
Steve Naroff56af2002009-01-11 01:06:09 +0000338unsigned ObjCContainerDecl::getNumProperties() const {
339 unsigned sum = 0;
340 for (prop_iterator I=prop_begin(), E=prop_end(); I != E; ++I)
341 sum++;
342 return sum;
343}
Steve Naroffab63fd62009-01-08 17:28:14 +0000344
Fariborz Jahanianef8a3df2008-04-21 19:04:53 +0000345/// FindPropertyDeclaration - Finds declaration of the property given its name
346/// in 'PropertyId' and returns it. It returns 0, if not found.
Steve Naroffdcf1e842009-01-11 12:47:58 +0000347/// FIXME: Convert to DeclContext lookup...
Fariborz Jahanianef8a3df2008-04-21 19:04:53 +0000348///
349ObjCPropertyDecl *
Steve Naroff451f83c2009-01-09 15:36:25 +0000350ObjCContainerDecl::FindPropertyDeclaration(IdentifierInfo *PropertyId) const {
351 for (prop_iterator I = prop_begin(), E = prop_end(); I != E; ++I) {
Fariborz Jahanianef8a3df2008-04-21 19:04:53 +0000352 ObjCPropertyDecl *property = *I;
353 if (property->getIdentifier() == PropertyId)
354 return property;
355 }
Fariborz Jahanianfaca5e22009-01-09 21:04:52 +0000356 const ObjCProtocolDecl *PID = dyn_cast<ObjCProtocolDecl>(this);
357 if (PID) {
358 for (ObjCProtocolDecl::protocol_iterator P = PID->protocol_begin(),
359 E = PID->protocol_end();
360 P != E; ++P)
361 if (ObjCPropertyDecl *property =
362 (*P)->FindPropertyDeclaration(PropertyId))
363 return property;
364 }
365
Fariborz Jahanian6b0ed6f2009-01-19 18:16:19 +0000366 if (const ObjCInterfaceDecl *OID = dyn_cast<ObjCInterfaceDecl>(this)) {
Steve Naroff451f83c2009-01-09 15:36:25 +0000367 // Look through categories.
368 for (ObjCCategoryDecl *Category = OID->getCategoryList();
369 Category; Category = Category->getNextClassCategory()) {
370 ObjCPropertyDecl *property = Category->FindPropertyDeclaration(PropertyId);
371 if (property)
372 return property;
373 }
374 // Look through protocols.
375 for (ObjCInterfaceDecl::protocol_iterator I = OID->protocol_begin(),
376 E = OID->protocol_end(); I != E; ++I) {
377 ObjCProtocolDecl *Protocol = *I;
378 ObjCPropertyDecl *property = Protocol->FindPropertyDeclaration(PropertyId);
379 if (property)
380 return property;
381 }
382 if (OID->getSuperClass())
383 return OID->getSuperClass()->FindPropertyDeclaration(PropertyId);
Steve Naroffd1f0eb42008-06-05 13:55:23 +0000384 }
Fariborz Jahanian6b0ed6f2009-01-19 18:16:19 +0000385 else if (const ObjCCategoryDecl *OCD = dyn_cast<ObjCCategoryDecl>(this)) {
386 // Look through protocols.
387 for (ObjCInterfaceDecl::protocol_iterator I = OCD->protocol_begin(),
388 E = OCD->protocol_end(); I != E; ++I) {
389 ObjCProtocolDecl *Protocol = *I;
390 ObjCPropertyDecl *property = Protocol->FindPropertyDeclaration(PropertyId);
391 if (property)
392 return property;
393 }
394 }
Steve Naroffd1f0eb42008-06-05 13:55:23 +0000395 return 0;
396}
397
Chris Lattner10318b82008-03-16 00:19:01 +0000398ObjCIvarDecl *ObjCInterfaceDecl::lookupInstanceVariable(
399 IdentifierInfo *ID, ObjCInterfaceDecl *&clsDeclared) {
400 ObjCInterfaceDecl* ClassDecl = this;
401 while (ClassDecl != NULL) {
402 for (ivar_iterator I = ClassDecl->ivar_begin(), E = ClassDecl->ivar_end();
403 I != E; ++I) {
404 if ((*I)->getIdentifier() == ID) {
405 clsDeclared = ClassDecl;
406 return *I;
407 }
408 }
409 ClassDecl = ClassDecl->getSuperClass();
410 }
411 return NULL;
412}
413
414/// lookupInstanceMethod - This method returns an instance method by looking in
415/// the class, its categories, and its super classes (using a linear search).
416ObjCMethodDecl *ObjCInterfaceDecl::lookupInstanceMethod(Selector Sel) {
417 ObjCInterfaceDecl* ClassDecl = this;
418 ObjCMethodDecl *MethodDecl = 0;
419
420 while (ClassDecl != NULL) {
421 if ((MethodDecl = ClassDecl->getInstanceMethod(Sel)))
422 return MethodDecl;
423
424 // Didn't find one yet - look through protocols.
Chris Lattner8bcb5252008-07-21 18:19:38 +0000425 const ObjCList<ObjCProtocolDecl> &Protocols =
426 ClassDecl->getReferencedProtocols();
427 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
428 E = Protocols.end(); I != E; ++I)
429 if ((MethodDecl = (*I)->getInstanceMethod(Sel)))
Chris Lattner10318b82008-03-16 00:19:01 +0000430 return MethodDecl;
Chris Lattner8bcb5252008-07-21 18:19:38 +0000431
Chris Lattner10318b82008-03-16 00:19:01 +0000432 // Didn't find one yet - now look through categories.
433 ObjCCategoryDecl *CatDecl = ClassDecl->getCategoryList();
434 while (CatDecl) {
435 if ((MethodDecl = CatDecl->getInstanceMethod(Sel)))
436 return MethodDecl;
Steve Naroffaf151802008-12-08 20:57:28 +0000437
438 // Didn't find one yet - look through protocols.
439 const ObjCList<ObjCProtocolDecl> &Protocols =
440 CatDecl->getReferencedProtocols();
441 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
442 E = Protocols.end(); I != E; ++I)
443 if ((MethodDecl = (*I)->getInstanceMethod(Sel)))
444 return MethodDecl;
Chris Lattner10318b82008-03-16 00:19:01 +0000445 CatDecl = CatDecl->getNextClassCategory();
446 }
447 ClassDecl = ClassDecl->getSuperClass();
448 }
449 return NULL;
450}
451
452// lookupClassMethod - This method returns a class method by looking in the
453// class, its categories, and its super classes (using a linear search).
454ObjCMethodDecl *ObjCInterfaceDecl::lookupClassMethod(Selector Sel) {
455 ObjCInterfaceDecl* ClassDecl = this;
456 ObjCMethodDecl *MethodDecl = 0;
457
458 while (ClassDecl != NULL) {
459 if ((MethodDecl = ClassDecl->getClassMethod(Sel)))
460 return MethodDecl;
461
462 // Didn't find one yet - look through protocols.
Chris Lattner0be08822008-07-21 21:32:27 +0000463 for (ObjCInterfaceDecl::protocol_iterator I = ClassDecl->protocol_begin(),
464 E = ClassDecl->protocol_end(); I != E; ++I)
Chris Lattner8bcb5252008-07-21 18:19:38 +0000465 if ((MethodDecl = (*I)->getClassMethod(Sel)))
Chris Lattner10318b82008-03-16 00:19:01 +0000466 return MethodDecl;
Chris Lattner0be08822008-07-21 21:32:27 +0000467
Chris Lattner10318b82008-03-16 00:19:01 +0000468 // Didn't find one yet - now look through categories.
469 ObjCCategoryDecl *CatDecl = ClassDecl->getCategoryList();
470 while (CatDecl) {
471 if ((MethodDecl = CatDecl->getClassMethod(Sel)))
472 return MethodDecl;
473 CatDecl = CatDecl->getNextClassCategory();
474 }
475 ClassDecl = ClassDecl->getSuperClass();
476 }
477 return NULL;
478}
479
Daniel Dunbardd24b9a2008-08-26 06:53:45 +0000480/// getInstanceMethod - This method returns an instance method by
481/// looking in the class implementation. Unlike interfaces, we don't
482/// look outside the implementation.
483ObjCMethodDecl *ObjCImplementationDecl::getInstanceMethod(Selector Sel) const {
Chris Lattner10318b82008-03-16 00:19:01 +0000484 for (instmeth_iterator I = instmeth_begin(), E = instmeth_end(); I != E; ++I)
485 if ((*I)->getSelector() == Sel)
486 return *I;
487 return NULL;
488}
489
Daniel Dunbardd24b9a2008-08-26 06:53:45 +0000490/// getClassMethod - This method returns a class method by looking in
491/// the class implementation. Unlike interfaces, we don't look outside
492/// the implementation.
493ObjCMethodDecl *ObjCImplementationDecl::getClassMethod(Selector Sel) const {
Chris Lattner10318b82008-03-16 00:19:01 +0000494 for (classmeth_iterator I = classmeth_begin(), E = classmeth_end();
495 I != E; ++I)
496 if ((*I)->getSelector() == Sel)
497 return *I;
498 return NULL;
499}
500
Fariborz Jahanian68342282008-12-05 22:32:48 +0000501/// FindPropertyImplDecl - This method looks up a previous ObjCPropertyImplDecl
502/// added to the list of those properties @synthesized/@dynamic in this
503/// @implementation block.
504///
505ObjCPropertyImplDecl *ObjCImplementationDecl::FindPropertyImplDecl(IdentifierInfo *Id) const {
506 for (propimpl_iterator i = propimpl_begin(), e = propimpl_end(); i != e; ++i) {
507 ObjCPropertyImplDecl *PID = *i;
508 if (PID->getPropertyDecl()->getIdentifier() == Id)
509 return PID;
510 }
511 return 0;
512}
513
514/// FindPropertyImplIvarDecl - This method lookup the ivar in the list of
Fariborz Jahanian17eb8882008-12-05 22:36:19 +0000515/// properties implemented in this @implementation block and returns the
516/// implemented property that uses it.
Fariborz Jahanian68342282008-12-05 22:32:48 +0000517///
518ObjCPropertyImplDecl *ObjCImplementationDecl::FindPropertyImplIvarDecl(IdentifierInfo *ivarId) const {
519 for (propimpl_iterator i = propimpl_begin(), e = propimpl_end(); i != e; ++i) {
520 ObjCPropertyImplDecl *PID = *i;
521 if (PID->getPropertyIvarDecl() &&
522 PID->getPropertyIvarDecl()->getIdentifier() == ivarId)
523 return PID;
524 }
525 return 0;
526}
527
528/// FindPropertyImplIvarDecl - This method lookup the ivar in the list of
Fariborz Jahanian17eb8882008-12-05 22:36:19 +0000529/// properties implemented in this category @implementation block and returns the
530/// implemented property that uses it.
Fariborz Jahanian68342282008-12-05 22:32:48 +0000531///
532ObjCPropertyImplDecl *ObjCCategoryImplDecl::FindPropertyImplIvarDecl(IdentifierInfo *ivarId) const {
533 for (propimpl_iterator i = propimpl_begin(), e = propimpl_end(); i != e; ++i) {
534 ObjCPropertyImplDecl *PID = *i;
535 if (PID->getPropertyIvarDecl() &&
536 PID->getPropertyIvarDecl()->getIdentifier() == ivarId)
537 return PID;
538 }
539 return 0;
540}
541
542/// FindPropertyImplDecl - This method looks up a previous ObjCPropertyImplDecl
543/// added to the list of those properties @synthesized/@dynamic in this
544/// category @implementation block.
545///
546ObjCPropertyImplDecl *ObjCCategoryImplDecl::FindPropertyImplDecl(IdentifierInfo *Id) const {
547 for (propimpl_iterator i = propimpl_begin(), e = propimpl_end(); i != e; ++i) {
548 ObjCPropertyImplDecl *PID = *i;
549 if (PID->getPropertyDecl()->getIdentifier() == Id)
550 return PID;
551 }
552 return 0;
553}
554
Chris Lattner10318b82008-03-16 00:19:01 +0000555// lookupInstanceMethod - This method returns an instance method by looking in
556// the class implementation. Unlike interfaces, we don't look outside the
557// implementation.
Daniel Dunbardd24b9a2008-08-26 06:53:45 +0000558ObjCMethodDecl *ObjCCategoryImplDecl::getInstanceMethod(Selector Sel) const {
Chris Lattner10318b82008-03-16 00:19:01 +0000559 for (instmeth_iterator I = instmeth_begin(), E = instmeth_end(); I != E; ++I)
560 if ((*I)->getSelector() == Sel)
561 return *I;
562 return NULL;
563}
564
565// lookupClassMethod - This method returns an instance method by looking in
566// the class implementation. Unlike interfaces, we don't look outside the
567// implementation.
Daniel Dunbardd24b9a2008-08-26 06:53:45 +0000568ObjCMethodDecl *ObjCCategoryImplDecl::getClassMethod(Selector Sel) const {
Chris Lattner10318b82008-03-16 00:19:01 +0000569 for (classmeth_iterator I = classmeth_begin(), E = classmeth_end();
570 I != E; ++I)
571 if ((*I)->getSelector() == Sel)
572 return *I;
573 return NULL;
574}
575
576// lookupInstanceMethod - Lookup a instance method in the protocol and protocols
577// it inherited.
578ObjCMethodDecl *ObjCProtocolDecl::lookupInstanceMethod(Selector Sel) {
579 ObjCMethodDecl *MethodDecl = NULL;
580
581 if ((MethodDecl = getInstanceMethod(Sel)))
582 return MethodDecl;
583
Chris Lattner0be08822008-07-21 21:32:27 +0000584 for (protocol_iterator I = protocol_begin(), E = protocol_end(); I != E; ++I)
Steve Naroff30fb1da2008-12-18 15:50:41 +0000585 if ((MethodDecl = (*I)->lookupInstanceMethod(Sel)))
Chris Lattner0be08822008-07-21 21:32:27 +0000586 return MethodDecl;
Chris Lattner10318b82008-03-16 00:19:01 +0000587 return NULL;
588}
589
590// lookupInstanceMethod - Lookup a class method in the protocol and protocols
591// it inherited.
592ObjCMethodDecl *ObjCProtocolDecl::lookupClassMethod(Selector Sel) {
593 ObjCMethodDecl *MethodDecl = NULL;
594
595 if ((MethodDecl = getClassMethod(Sel)))
596 return MethodDecl;
597
Chris Lattner0be08822008-07-21 21:32:27 +0000598 for (protocol_iterator I = protocol_begin(), E = protocol_end(); I != E; ++I)
Steve Naroff30fb1da2008-12-18 15:50:41 +0000599 if ((MethodDecl = (*I)->lookupClassMethod(Sel)))
Chris Lattner0be08822008-07-21 21:32:27 +0000600 return MethodDecl;
Chris Lattner10318b82008-03-16 00:19:01 +0000601 return NULL;
602}
603
604/// getSynthesizedMethodSize - Compute size of synthesized method name
605/// as done be the rewrite.
606///
607unsigned ObjCMethodDecl::getSynthesizedMethodSize() const {
608 // syntesized method name is a concatenation of -/+[class-name selector]
609 // Get length of this name.
610 unsigned length = 3; // _I_ or _C_
Chris Lattnerd120b9e2008-11-24 03:54:41 +0000611 length += getClassInterface()->getNameAsString().size()+1; // extra for _
Steve Naroff438be772009-01-08 19:41:02 +0000612 if (const ObjCCategoryImplDecl *CID =
613 dyn_cast<ObjCCategoryImplDecl>(getDeclContext()))
Chris Lattnerd120b9e2008-11-24 03:54:41 +0000614 length += CID->getNameAsString().size()+1;
Chris Lattner3a8f2942008-11-24 03:33:13 +0000615 length += getSelector().getAsString().size(); // selector name
Chris Lattner10318b82008-03-16 00:19:01 +0000616 return length;
617}
618
Chris Lattner052fbcd2008-04-06 05:25:03 +0000619ObjCInterfaceDecl *ObjCMethodDecl::getClassInterface() {
Steve Naroff438be772009-01-08 19:41:02 +0000620 if (ObjCInterfaceDecl *ID = dyn_cast<ObjCInterfaceDecl>(getDeclContext()))
Chris Lattner10318b82008-03-16 00:19:01 +0000621 return ID;
Steve Naroff438be772009-01-08 19:41:02 +0000622 if (ObjCCategoryDecl *CD = dyn_cast<ObjCCategoryDecl>(getDeclContext()))
Chris Lattner10318b82008-03-16 00:19:01 +0000623 return CD->getClassInterface();
624 if (ObjCImplementationDecl *IMD =
Steve Naroff438be772009-01-08 19:41:02 +0000625 dyn_cast<ObjCImplementationDecl>(getDeclContext()))
Chris Lattner10318b82008-03-16 00:19:01 +0000626 return IMD->getClassInterface();
Steve Naroff438be772009-01-08 19:41:02 +0000627 if (ObjCCategoryImplDecl *CID =
628 dyn_cast<ObjCCategoryImplDecl>(getDeclContext()))
Chris Lattner10318b82008-03-16 00:19:01 +0000629 return CID->getClassInterface();
630 assert(false && "unknown method context");
631 return 0;
632}
Chris Lattner44859612008-03-17 01:19:02 +0000633
Fariborz Jahaniandc0569e2008-04-23 00:06:01 +0000634ObjCPropertyImplDecl *ObjCPropertyImplDecl::Create(ASTContext &C,
Douglas Gregor6e4fa2c2009-01-09 00:49:46 +0000635 DeclContext *DC,
Fariborz Jahaniandc0569e2008-04-23 00:06:01 +0000636 SourceLocation atLoc,
637 SourceLocation L,
638 ObjCPropertyDecl *property,
Daniel Dunbar14117fc2008-08-26 04:47:31 +0000639 Kind PK,
Fariborz Jahaniandc0569e2008-04-23 00:06:01 +0000640 ObjCIvarDecl *ivar) {
641 void *Mem = C.getAllocator().Allocate<ObjCPropertyImplDecl>();
Douglas Gregor6e4fa2c2009-01-09 00:49:46 +0000642 return new (Mem) ObjCPropertyImplDecl(DC, atLoc, L, property, PK, ivar);
Fariborz Jahaniandc0569e2008-04-23 00:06:01 +0000643}
Chris Lattner44859612008-03-17 01:19:02 +0000644
Chris Lattnereee57c02008-04-04 06:12:32 +0000645