blob: c4caed1e00ffd9bf4a18c46558a95cf100854af6 [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 Kremenek788ef0a2009-01-08 20:49:27 +000076 for (method_iterator I=meth_begin(), E=meth_end(); I!=E; ++I)
77 if (*I) const_cast<ObjCMethodDecl*>((*I))->Destroy(C);
Ted Kremenek22db1602008-06-06 17:21:42 +000078
79 // FIXME: Because there is no clear ownership
80 // role between ObjCInterfaceDecls and the ObjCPropertyDecls that they
81 // reference, we destroy ObjCPropertyDecls in ~TranslationUnit.
82
Ted Kremenek8c945b12008-06-06 16:45:15 +000083 Decl::Destroy(C);
84}
85
86
Chris Lattnerf3874bc2008-04-06 04:47:34 +000087ObjCIvarDecl *ObjCIvarDecl::Create(ASTContext &C, SourceLocation L,
Ted Kremenek173dd312008-07-23 18:04:17 +000088 IdentifierInfo *Id, QualType T,
89 AccessControl ac, Expr *BW) {
Chris Lattner0db541b2008-03-16 01:15:50 +000090 void *Mem = C.getAllocator().Allocate<ObjCIvarDecl>();
Ted Kremenek173dd312008-07-23 18:04:17 +000091 return new (Mem) ObjCIvarDecl(L, Id, T, ac, BW);
Chris Lattner114add62008-03-16 00:49:28 +000092}
93
Ted Kremeneke5bedfe2008-08-20 03:26:33 +000094
95ObjCAtDefsFieldDecl
Douglas Gregor8acb7272008-12-11 16:49:14 +000096*ObjCAtDefsFieldDecl::Create(ASTContext &C, DeclContext *DC, SourceLocation L,
Ted Kremeneke5bedfe2008-08-20 03:26:33 +000097 IdentifierInfo *Id, QualType T, Expr *BW) {
98 void *Mem = C.getAllocator().Allocate<ObjCAtDefsFieldDecl>();
Douglas Gregor8acb7272008-12-11 16:49:14 +000099 return new (Mem) ObjCAtDefsFieldDecl(DC, L, Id, T, BW);
Ted Kremeneke5bedfe2008-08-20 03:26:33 +0000100}
101
102void ObjCAtDefsFieldDecl::Destroy(ASTContext& C) {
103 this->~ObjCAtDefsFieldDecl();
104 C.getAllocator().Deallocate((void *)this);
105}
106
Douglas Gregor6e4fa2c2009-01-09 00:49:46 +0000107ObjCProtocolDecl *ObjCProtocolDecl::Create(ASTContext &C, DeclContext *DC,
Chris Lattnereee57c02008-04-04 06:12:32 +0000108 SourceLocation L,
Chris Lattner7afba9c2008-03-16 20:19:15 +0000109 IdentifierInfo *Id) {
Chris Lattner180f7e22008-03-16 01:23:04 +0000110 void *Mem = C.getAllocator().Allocate<ObjCProtocolDecl>();
Douglas Gregor6e4fa2c2009-01-09 00:49:46 +0000111 return new (Mem) ObjCProtocolDecl(DC, L, Id);
Chris Lattner180f7e22008-03-16 01:23:04 +0000112}
113
Ted Kremenekc906e5e2008-06-06 19:48:57 +0000114ObjCProtocolDecl::~ObjCProtocolDecl() {
Ted Kremenekc906e5e2008-06-06 19:48:57 +0000115 delete [] PropertyDecl;
116}
117
118void ObjCProtocolDecl::Destroy(ASTContext& C) {
119
120 // Referenced Protocols are not owned, so don't Destroy them.
121
Ted Kremenek788ef0a2009-01-08 20:49:27 +0000122 for (method_iterator I=meth_begin(), E=meth_end(); I!=E; ++I)
123 if (*I) const_cast<ObjCMethodDecl*>((*I))->Destroy(C);
Ted Kremenekc906e5e2008-06-06 19:48:57 +0000124
125 // FIXME: Because there is no clear ownership
126 // role between ObjCProtocolDecls and the ObjCPropertyDecls that they
127 // reference, we destroy ObjCPropertyDecls in ~TranslationUnit.
128
129 Decl::Destroy(C);
130}
131
132
Douglas Gregor6e4fa2c2009-01-09 00:49:46 +0000133ObjCClassDecl *ObjCClassDecl::Create(ASTContext &C, DeclContext *DC,
Chris Lattnereee57c02008-04-04 06:12:32 +0000134 SourceLocation L,
Chris Lattnere29dc832008-03-16 20:34:23 +0000135 ObjCInterfaceDecl **Elts, unsigned nElts) {
136 void *Mem = C.getAllocator().Allocate<ObjCClassDecl>();
Douglas Gregor6e4fa2c2009-01-09 00:49:46 +0000137 return new (Mem) ObjCClassDecl(DC, L, Elts, nElts);
Chris Lattnere29dc832008-03-16 20:34:23 +0000138}
139
Ted Kremenekff291622008-06-06 20:11:53 +0000140ObjCClassDecl::~ObjCClassDecl() {
141 delete [] ForwardDecls;
142}
143
144void ObjCClassDecl::Destroy(ASTContext& C) {
145
146 // FIXME: There is no clear ownership policy now for referenced
147 // ObjCInterfaceDecls. Some of them can be forward declarations that
148 // are never later defined (in which case the ObjCClassDecl owns them)
149 // or the ObjCInterfaceDecl later becomes a real definition later. Ideally
150 // we should have separate objects for forward declarations and definitions,
151 // obviating this problem. Because of this situation, referenced
152 // ObjCInterfaceDecls are destroyed in ~TranslationUnit.
153
154 Decl::Destroy(C);
155}
156
Chris Lattnere29dc832008-03-16 20:34:23 +0000157ObjCForwardProtocolDecl *
Douglas Gregor6e4fa2c2009-01-09 00:49:46 +0000158ObjCForwardProtocolDecl::Create(ASTContext &C, DeclContext *DC,
Chris Lattnereee57c02008-04-04 06:12:32 +0000159 SourceLocation L,
Chris Lattnere29dc832008-03-16 20:34:23 +0000160 ObjCProtocolDecl **Elts, unsigned NumElts) {
161 void *Mem = C.getAllocator().Allocate<ObjCForwardProtocolDecl>();
Douglas Gregor6e4fa2c2009-01-09 00:49:46 +0000162 return new (Mem) ObjCForwardProtocolDecl(DC, L, Elts, NumElts);
Chris Lattnere29dc832008-03-16 20:34:23 +0000163}
164
Ted Kremenek1e5e0bf2008-06-06 21:05:33 +0000165ObjCForwardProtocolDecl::~ObjCForwardProtocolDecl() {
166 delete [] ReferencedProtocols;
167}
168
Douglas Gregor6e4fa2c2009-01-09 00:49:46 +0000169ObjCCategoryDecl *ObjCCategoryDecl::Create(ASTContext &C, DeclContext *DC,
Chris Lattnereee57c02008-04-04 06:12:32 +0000170 SourceLocation L,
Chris Lattnere29dc832008-03-16 20:34:23 +0000171 IdentifierInfo *Id) {
172 void *Mem = C.getAllocator().Allocate<ObjCCategoryDecl>();
Douglas Gregor6e4fa2c2009-01-09 00:49:46 +0000173 return new (Mem) ObjCCategoryDecl(DC, L, Id);
Chris Lattnere29dc832008-03-16 20:34:23 +0000174}
175
Chris Lattner1b6de332008-03-16 20:53:07 +0000176ObjCCategoryImplDecl *
Douglas Gregor6e4fa2c2009-01-09 00:49:46 +0000177ObjCCategoryImplDecl::Create(ASTContext &C, DeclContext *DC,
Chris Lattnereee57c02008-04-04 06:12:32 +0000178 SourceLocation L,IdentifierInfo *Id,
Chris Lattner1b6de332008-03-16 20:53:07 +0000179 ObjCInterfaceDecl *ClassInterface) {
180 void *Mem = C.getAllocator().Allocate<ObjCCategoryImplDecl>();
Douglas Gregor6e4fa2c2009-01-09 00:49:46 +0000181 return new (Mem) ObjCCategoryImplDecl(DC, L, Id, ClassInterface);
Chris Lattner1b6de332008-03-16 20:53:07 +0000182}
183
184ObjCImplementationDecl *
Douglas Gregor6e4fa2c2009-01-09 00:49:46 +0000185ObjCImplementationDecl::Create(ASTContext &C, DeclContext *DC,
Chris Lattnereee57c02008-04-04 06:12:32 +0000186 SourceLocation L,
Chris Lattner1b6de332008-03-16 20:53:07 +0000187 IdentifierInfo *Id,
188 ObjCInterfaceDecl *ClassInterface,
189 ObjCInterfaceDecl *SuperDecl) {
190 void *Mem = C.getAllocator().Allocate<ObjCImplementationDecl>();
Douglas Gregor6e4fa2c2009-01-09 00:49:46 +0000191 return new (Mem) ObjCImplementationDecl(DC, L, Id, ClassInterface, SuperDecl);
Chris Lattner1b6de332008-03-16 20:53:07 +0000192}
Chris Lattner10318b82008-03-16 00:19:01 +0000193
Chris Lattner2d1c4312008-03-16 21:17:37 +0000194ObjCCompatibleAliasDecl *
Douglas Gregor6e4fa2c2009-01-09 00:49:46 +0000195ObjCCompatibleAliasDecl::Create(ASTContext &C, DeclContext *DC,
Chris Lattnereee57c02008-04-04 06:12:32 +0000196 SourceLocation L,
Chris Lattner2d1c4312008-03-16 21:17:37 +0000197 IdentifierInfo *Id,
198 ObjCInterfaceDecl* AliasedClass) {
199 void *Mem = C.getAllocator().Allocate<ObjCCompatibleAliasDecl>();
Douglas Gregor6e4fa2c2009-01-09 00:49:46 +0000200 return new (Mem) ObjCCompatibleAliasDecl(DC, L, Id, AliasedClass);
Chris Lattner2d1c4312008-03-16 21:17:37 +0000201}
202
Douglas Gregor6e4fa2c2009-01-09 00:49:46 +0000203ObjCPropertyDecl *ObjCPropertyDecl::Create(ASTContext &C, DeclContext *DC,
Fariborz Jahaniane7071722008-04-11 23:40:25 +0000204 SourceLocation L,
Fariborz Jahanian0ceb4be2008-04-14 23:36:35 +0000205 IdentifierInfo *Id,
Fariborz Jahanian4aa72a72008-05-05 18:51:55 +0000206 QualType T,
207 PropertyControl propControl) {
Chris Lattner2d1c4312008-03-16 21:17:37 +0000208 void *Mem = C.getAllocator().Allocate<ObjCPropertyDecl>();
Douglas Gregor6e4fa2c2009-01-09 00:49:46 +0000209 return new (Mem) ObjCPropertyDecl(DC, L, Id, T);
Chris Lattner2d1c4312008-03-16 21:17:37 +0000210}
211
Chris Lattner10318b82008-03-16 00:19:01 +0000212//===----------------------------------------------------------------------===//
213// Objective-C Decl Implementation
214//===----------------------------------------------------------------------===//
215
Fariborz Jahanian91dd9d32008-12-09 20:23:04 +0000216void ObjCMethodDecl::createImplicitParams(ASTContext &Context,
217 const ObjCInterfaceDecl *OID) {
Daniel Dunbar88116372008-08-26 06:08:30 +0000218 QualType selfTy;
Douglas Gregor5d764842009-01-09 17:18:27 +0000219 if (isInstanceMethod()) {
Daniel Dunbar88116372008-08-26 06:08:30 +0000220 // There may be no interface context due to error in declaration
221 // of the interface (which has been reported). Recover gracefully.
Fariborz Jahanian91dd9d32008-12-09 20:23:04 +0000222 if (OID) {
223 selfTy = Context.getObjCInterfaceType(const_cast<ObjCInterfaceDecl *>(OID));
Daniel Dunbar88116372008-08-26 06:08:30 +0000224 selfTy = Context.getPointerType(selfTy);
225 } else {
226 selfTy = Context.getObjCIdType();
227 }
228 } else // we have a factory method.
229 selfTy = Context.getObjCClassType();
230
231 SelfDecl = ImplicitParamDecl::Create(Context, this,
232 SourceLocation(),
233 &Context.Idents.get("self"),
234 selfTy, 0);
235
236 CmdDecl = ImplicitParamDecl::Create(Context, this,
237 SourceLocation(),
238 &Context.Idents.get("_cmd"),
239 Context.getObjCSelType(), 0);
240}
241
Chris Lattner10318b82008-03-16 00:19:01 +0000242void ObjCMethodDecl::setMethodParams(ParmVarDecl **NewParamInfo,
243 unsigned NumParams) {
244 assert(ParamInfo == 0 && "Already has param info!");
245
246 // Zero params -> null pointer.
247 if (NumParams) {
248 ParamInfo = new ParmVarDecl*[NumParams];
249 memcpy(ParamInfo, NewParamInfo, sizeof(ParmVarDecl*)*NumParams);
250 NumMethodParams = NumParams;
251 }
252}
253
Daniel Dunbar0a576d52009-01-09 01:04:21 +0000254/// isPropertyReadonly - Return true if property is readonly, by searching
Fariborz Jahanian4739da12008-11-25 21:48:26 +0000255/// for the property in the class and in its categories.
256///
257bool ObjCInterfaceDecl::isPropertyReadonly(ObjCPropertyDecl *PDecl) const
258{
Fariborz Jahaniane008c142009-01-10 18:43:55 +0000259 // Even if property is ready only, if interface has a user defined setter,
260 // it is not considered read only.
261 if (!PDecl->isReadOnly() || getInstanceMethod(PDecl->getSetterName()))
Daniel Dunbar0a576d52009-01-09 01:04:21 +0000262 return false;
263
264 // Main class has the property as 'readonly'. Must search
265 // through the category list to see if the property's
266 // attribute has been over-ridden to 'readwrite'.
267 for (ObjCCategoryDecl *Category = getCategoryList();
268 Category; Category = Category->getNextClassCategory()) {
Fariborz Jahaniane008c142009-01-10 18:43:55 +0000269 // Even if property is ready only, if a category has a user defined setter,
270 // it is not considered read only.
271 if (Category->getInstanceMethod(PDecl->getSetterName()))
272 return false;
Daniel Dunbar0a576d52009-01-09 01:04:21 +0000273 ObjCPropertyDecl *P =
274 Category->FindPropertyDeclaration(PDecl->getIdentifier());
275 if (P && !P->isReadOnly())
276 return false;
Fariborz Jahanian4739da12008-11-25 21:48:26 +0000277 }
Daniel Dunbar0a576d52009-01-09 01:04:21 +0000278
279 return true;
Fariborz Jahanian4739da12008-11-25 21:48:26 +0000280}
281
Fariborz Jahanianef8a3df2008-04-21 19:04:53 +0000282/// FindCategoryDeclaration - Finds category declaration in the list of
283/// categories for this class and returns it. Name of the category is passed
284/// in 'CategoryId'. If category not found, return 0;
285///
286ObjCCategoryDecl *
287 ObjCInterfaceDecl::FindCategoryDeclaration(IdentifierInfo *CategoryId) const {
288 for (ObjCCategoryDecl *Category = getCategoryList();
289 Category; Category = Category->getNextClassCategory())
290 if (Category->getIdentifier() == CategoryId)
291 return Category;
292 return 0;
293}
294
295/// FindIvarDeclaration - Find an Ivar declaration in this class given its
296/// name in 'IvarId'. On failure to find, return 0;
297///
298ObjCIvarDecl *
299 ObjCInterfaceDecl::FindIvarDeclaration(IdentifierInfo *IvarId) const {
300 for (ObjCInterfaceDecl::ivar_iterator IVI = ivar_begin(),
301 IVE = ivar_end(); IVI != IVE; ++IVI) {
302 ObjCIvarDecl* Ivar = (*IVI);
303 if (Ivar->getIdentifier() == IvarId)
304 return Ivar;
305 }
Fariborz Jahanian8acf3352008-04-21 23:57:08 +0000306 if (getSuperClass())
307 return getSuperClass()->FindIvarDeclaration(IvarId);
Fariborz Jahanianef8a3df2008-04-21 19:04:53 +0000308 return 0;
309}
310
Chris Lattner10318b82008-03-16 00:19:01 +0000311/// ObjCAddInstanceVariablesToClass - Inserts instance variables
312/// into ObjCInterfaceDecl's fields.
313///
314void ObjCInterfaceDecl::addInstanceVariablesToClass(ObjCIvarDecl **ivars,
315 unsigned numIvars,
316 SourceLocation RBrac) {
317 NumIvars = numIvars;
318 if (numIvars) {
319 Ivars = new ObjCIvarDecl*[numIvars];
320 memcpy(Ivars, ivars, numIvars*sizeof(ObjCIvarDecl*));
321 }
322 setLocEnd(RBrac);
323}
324
Fariborz Jahanian09772392008-12-13 22:20:28 +0000325/// lookupFieldDeclForIvar - looks up a field decl' in the laid out
326/// storage which matches this 'ivar'.
327///
328FieldDecl *ObjCInterfaceDecl::lookupFieldDeclForIvar(ASTContext &Context,
Fariborz Jahanian86008c02008-12-15 20:35:07 +0000329 const ObjCIvarDecl *ivar) {
Fariborz Jahanian0556b152008-12-17 21:40:49 +0000330 const RecordDecl *RecordForDecl = Context.addRecordToClass(this);
Fariborz Jahanian09772392008-12-13 22:20:28 +0000331 assert(RecordForDecl && "lookupFieldDeclForIvar no storage for class");
332 DeclarationName Member = ivar->getDeclName();
Fariborz Jahanian0556b152008-12-17 21:40:49 +0000333 DeclContext::lookup_result Lookup = (const_cast< RecordDecl *>(RecordForDecl))
Steve Naroffab63fd62009-01-08 17:28:14 +0000334 ->lookup(Member);
Fariborz Jahanian09772392008-12-13 22:20:28 +0000335 assert((Lookup.first != Lookup.second) && "field decl not found");
336 FieldDecl *MemberDecl = dyn_cast<FieldDecl>(*Lookup.first);
337 assert(MemberDecl && "field decl not found");
338 return MemberDecl;
339}
340
Chris Lattner10318b82008-03-16 00:19:01 +0000341/// ObjCAddInstanceVariablesToClassImpl - Checks for correctness of Instance
342/// Variables (Ivars) relative to what declared in @implementation;s class.
343/// Ivars into ObjCImplementationDecl's fields.
344///
345void ObjCImplementationDecl::ObjCAddInstanceVariablesToClassImpl(
346 ObjCIvarDecl **ivars, unsigned numIvars) {
347 NumIvars = numIvars;
348 if (numIvars) {
349 Ivars = new ObjCIvarDecl*[numIvars];
350 memcpy(Ivars, ivars, numIvars*sizeof(ObjCIvarDecl*));
351 }
352}
353
Steve Naroffab63fd62009-01-08 17:28:14 +0000354// Get the local instance method declared in this interface.
355// FIXME: handle overloading, instance & class methods can have the same name.
356ObjCMethodDecl *ObjCContainerDecl::getInstanceMethod(Selector Sel) const {
357 lookup_const_result MethodResult = lookup(Sel);
358 if (MethodResult.first)
359 return const_cast<ObjCMethodDecl*>(
360 dyn_cast<ObjCMethodDecl>(*MethodResult.first));
361 return 0;
362}
363
364// Get the local class method declared in this interface.
365ObjCMethodDecl *ObjCContainerDecl::getClassMethod(Selector Sel) const {
366 lookup_const_result MethodResult = lookup(Sel);
367 if (MethodResult.first)
368 return const_cast<ObjCMethodDecl*>(
369 dyn_cast<ObjCMethodDecl>(*MethodResult.first));
370 return 0;
371}
372
373unsigned ObjCContainerDecl::getNumInstanceMethods() const {
374 unsigned sum = 0;
375 for (instmeth_iterator I=instmeth_begin(), E=instmeth_end(); I != E; ++I)
376 sum++;
377 return sum;
378}
379unsigned ObjCContainerDecl::getNumClassMethods() const {
380 unsigned sum = 0;
381 for (classmeth_iterator I=classmeth_begin(), E=classmeth_end(); I != E; ++I)
382 sum++;
383 return sum;
384}
Steve Naroff56af2002009-01-11 01:06:09 +0000385unsigned ObjCContainerDecl::getNumProperties() const {
386 unsigned sum = 0;
387 for (prop_iterator I=prop_begin(), E=prop_end(); I != E; ++I)
388 sum++;
389 return sum;
390}
Steve Naroffab63fd62009-01-08 17:28:14 +0000391
Fariborz Jahanianef8a3df2008-04-21 19:04:53 +0000392/// FindPropertyDeclaration - Finds declaration of the property given its name
393/// in 'PropertyId' and returns it. It returns 0, if not found.
Steve Naroffdcf1e842009-01-11 12:47:58 +0000394/// FIXME: Convert to DeclContext lookup...
Fariborz Jahanianef8a3df2008-04-21 19:04:53 +0000395///
396ObjCPropertyDecl *
Steve Naroff451f83c2009-01-09 15:36:25 +0000397ObjCContainerDecl::FindPropertyDeclaration(IdentifierInfo *PropertyId) const {
398 for (prop_iterator I = prop_begin(), E = prop_end(); I != E; ++I) {
Fariborz Jahanianef8a3df2008-04-21 19:04:53 +0000399 ObjCPropertyDecl *property = *I;
400 if (property->getIdentifier() == PropertyId)
401 return property;
402 }
Fariborz Jahanianfaca5e22009-01-09 21:04:52 +0000403 const ObjCProtocolDecl *PID = dyn_cast<ObjCProtocolDecl>(this);
404 if (PID) {
405 for (ObjCProtocolDecl::protocol_iterator P = PID->protocol_begin(),
406 E = PID->protocol_end();
407 P != E; ++P)
408 if (ObjCPropertyDecl *property =
409 (*P)->FindPropertyDeclaration(PropertyId))
410 return property;
411 }
412
Steve Naroff451f83c2009-01-09 15:36:25 +0000413 const ObjCInterfaceDecl *OID = dyn_cast<ObjCInterfaceDecl>(this);
414 if (OID) {
415 // Look through categories.
416 for (ObjCCategoryDecl *Category = OID->getCategoryList();
417 Category; Category = Category->getNextClassCategory()) {
418 ObjCPropertyDecl *property = Category->FindPropertyDeclaration(PropertyId);
419 if (property)
420 return property;
421 }
422 // Look through protocols.
423 for (ObjCInterfaceDecl::protocol_iterator I = OID->protocol_begin(),
424 E = OID->protocol_end(); I != E; ++I) {
425 ObjCProtocolDecl *Protocol = *I;
426 ObjCPropertyDecl *property = Protocol->FindPropertyDeclaration(PropertyId);
427 if (property)
428 return property;
429 }
430 if (OID->getSuperClass())
431 return OID->getSuperClass()->FindPropertyDeclaration(PropertyId);
Steve Naroffd1f0eb42008-06-05 13:55:23 +0000432 }
433 return 0;
434}
435
Chris Lattner10318b82008-03-16 00:19:01 +0000436ObjCIvarDecl *ObjCInterfaceDecl::lookupInstanceVariable(
437 IdentifierInfo *ID, ObjCInterfaceDecl *&clsDeclared) {
438 ObjCInterfaceDecl* ClassDecl = this;
439 while (ClassDecl != NULL) {
440 for (ivar_iterator I = ClassDecl->ivar_begin(), E = ClassDecl->ivar_end();
441 I != E; ++I) {
442 if ((*I)->getIdentifier() == ID) {
443 clsDeclared = ClassDecl;
444 return *I;
445 }
446 }
447 ClassDecl = ClassDecl->getSuperClass();
448 }
449 return NULL;
450}
451
452/// lookupInstanceMethod - This method returns an instance method by looking in
453/// the class, its categories, and its super classes (using a linear search).
454ObjCMethodDecl *ObjCInterfaceDecl::lookupInstanceMethod(Selector Sel) {
455 ObjCInterfaceDecl* ClassDecl = this;
456 ObjCMethodDecl *MethodDecl = 0;
457
458 while (ClassDecl != NULL) {
459 if ((MethodDecl = ClassDecl->getInstanceMethod(Sel)))
460 return MethodDecl;
461
462 // Didn't find one yet - look through protocols.
Chris Lattner8bcb5252008-07-21 18:19:38 +0000463 const ObjCList<ObjCProtocolDecl> &Protocols =
464 ClassDecl->getReferencedProtocols();
465 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
466 E = Protocols.end(); I != E; ++I)
467 if ((MethodDecl = (*I)->getInstanceMethod(Sel)))
Chris Lattner10318b82008-03-16 00:19:01 +0000468 return MethodDecl;
Chris Lattner8bcb5252008-07-21 18:19:38 +0000469
Chris Lattner10318b82008-03-16 00:19:01 +0000470 // Didn't find one yet - now look through categories.
471 ObjCCategoryDecl *CatDecl = ClassDecl->getCategoryList();
472 while (CatDecl) {
473 if ((MethodDecl = CatDecl->getInstanceMethod(Sel)))
474 return MethodDecl;
Steve Naroffaf151802008-12-08 20:57:28 +0000475
476 // Didn't find one yet - look through protocols.
477 const ObjCList<ObjCProtocolDecl> &Protocols =
478 CatDecl->getReferencedProtocols();
479 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
480 E = Protocols.end(); I != E; ++I)
481 if ((MethodDecl = (*I)->getInstanceMethod(Sel)))
482 return MethodDecl;
Chris Lattner10318b82008-03-16 00:19:01 +0000483 CatDecl = CatDecl->getNextClassCategory();
484 }
485 ClassDecl = ClassDecl->getSuperClass();
486 }
487 return NULL;
488}
489
490// lookupClassMethod - This method returns a class method by looking in the
491// class, its categories, and its super classes (using a linear search).
492ObjCMethodDecl *ObjCInterfaceDecl::lookupClassMethod(Selector Sel) {
493 ObjCInterfaceDecl* ClassDecl = this;
494 ObjCMethodDecl *MethodDecl = 0;
495
496 while (ClassDecl != NULL) {
497 if ((MethodDecl = ClassDecl->getClassMethod(Sel)))
498 return MethodDecl;
499
500 // Didn't find one yet - look through protocols.
Chris Lattner0be08822008-07-21 21:32:27 +0000501 for (ObjCInterfaceDecl::protocol_iterator I = ClassDecl->protocol_begin(),
502 E = ClassDecl->protocol_end(); I != E; ++I)
Chris Lattner8bcb5252008-07-21 18:19:38 +0000503 if ((MethodDecl = (*I)->getClassMethod(Sel)))
Chris Lattner10318b82008-03-16 00:19:01 +0000504 return MethodDecl;
Chris Lattner0be08822008-07-21 21:32:27 +0000505
Chris Lattner10318b82008-03-16 00:19:01 +0000506 // Didn't find one yet - now look through categories.
507 ObjCCategoryDecl *CatDecl = ClassDecl->getCategoryList();
508 while (CatDecl) {
509 if ((MethodDecl = CatDecl->getClassMethod(Sel)))
510 return MethodDecl;
511 CatDecl = CatDecl->getNextClassCategory();
512 }
513 ClassDecl = ClassDecl->getSuperClass();
514 }
515 return NULL;
516}
517
Daniel Dunbardd24b9a2008-08-26 06:53:45 +0000518/// getInstanceMethod - This method returns an instance method by
519/// looking in the class implementation. Unlike interfaces, we don't
520/// look outside the implementation.
521ObjCMethodDecl *ObjCImplementationDecl::getInstanceMethod(Selector Sel) const {
Chris Lattner10318b82008-03-16 00:19:01 +0000522 for (instmeth_iterator I = instmeth_begin(), E = instmeth_end(); I != E; ++I)
523 if ((*I)->getSelector() == Sel)
524 return *I;
525 return NULL;
526}
527
Daniel Dunbardd24b9a2008-08-26 06:53:45 +0000528/// getClassMethod - This method returns a class method by looking in
529/// the class implementation. Unlike interfaces, we don't look outside
530/// the implementation.
531ObjCMethodDecl *ObjCImplementationDecl::getClassMethod(Selector Sel) const {
Chris Lattner10318b82008-03-16 00:19:01 +0000532 for (classmeth_iterator I = classmeth_begin(), E = classmeth_end();
533 I != E; ++I)
534 if ((*I)->getSelector() == Sel)
535 return *I;
536 return NULL;
537}
538
Fariborz Jahanian68342282008-12-05 22:32:48 +0000539/// FindPropertyImplDecl - This method looks up a previous ObjCPropertyImplDecl
540/// added to the list of those properties @synthesized/@dynamic in this
541/// @implementation block.
542///
543ObjCPropertyImplDecl *ObjCImplementationDecl::FindPropertyImplDecl(IdentifierInfo *Id) const {
544 for (propimpl_iterator i = propimpl_begin(), e = propimpl_end(); i != e; ++i) {
545 ObjCPropertyImplDecl *PID = *i;
546 if (PID->getPropertyDecl()->getIdentifier() == Id)
547 return PID;
548 }
549 return 0;
550}
551
552/// FindPropertyImplIvarDecl - This method lookup the ivar in the list of
Fariborz Jahanian17eb8882008-12-05 22:36:19 +0000553/// properties implemented in this @implementation block and returns the
554/// implemented property that uses it.
Fariborz Jahanian68342282008-12-05 22:32:48 +0000555///
556ObjCPropertyImplDecl *ObjCImplementationDecl::FindPropertyImplIvarDecl(IdentifierInfo *ivarId) const {
557 for (propimpl_iterator i = propimpl_begin(), e = propimpl_end(); i != e; ++i) {
558 ObjCPropertyImplDecl *PID = *i;
559 if (PID->getPropertyIvarDecl() &&
560 PID->getPropertyIvarDecl()->getIdentifier() == ivarId)
561 return PID;
562 }
563 return 0;
564}
565
566/// FindPropertyImplIvarDecl - This method lookup the ivar in the list of
Fariborz Jahanian17eb8882008-12-05 22:36:19 +0000567/// properties implemented in this category @implementation block and returns the
568/// implemented property that uses it.
Fariborz Jahanian68342282008-12-05 22:32:48 +0000569///
570ObjCPropertyImplDecl *ObjCCategoryImplDecl::FindPropertyImplIvarDecl(IdentifierInfo *ivarId) const {
571 for (propimpl_iterator i = propimpl_begin(), e = propimpl_end(); i != e; ++i) {
572 ObjCPropertyImplDecl *PID = *i;
573 if (PID->getPropertyIvarDecl() &&
574 PID->getPropertyIvarDecl()->getIdentifier() == ivarId)
575 return PID;
576 }
577 return 0;
578}
579
580/// FindPropertyImplDecl - This method looks up a previous ObjCPropertyImplDecl
581/// added to the list of those properties @synthesized/@dynamic in this
582/// category @implementation block.
583///
584ObjCPropertyImplDecl *ObjCCategoryImplDecl::FindPropertyImplDecl(IdentifierInfo *Id) const {
585 for (propimpl_iterator i = propimpl_begin(), e = propimpl_end(); i != e; ++i) {
586 ObjCPropertyImplDecl *PID = *i;
587 if (PID->getPropertyDecl()->getIdentifier() == Id)
588 return PID;
589 }
590 return 0;
591}
592
Chris Lattner10318b82008-03-16 00:19:01 +0000593// lookupInstanceMethod - This method returns an instance method by looking in
594// the class implementation. Unlike interfaces, we don't look outside the
595// implementation.
Daniel Dunbardd24b9a2008-08-26 06:53:45 +0000596ObjCMethodDecl *ObjCCategoryImplDecl::getInstanceMethod(Selector Sel) const {
Chris Lattner10318b82008-03-16 00:19:01 +0000597 for (instmeth_iterator I = instmeth_begin(), E = instmeth_end(); I != E; ++I)
598 if ((*I)->getSelector() == Sel)
599 return *I;
600 return NULL;
601}
602
603// lookupClassMethod - This method returns an instance method by looking in
604// the class implementation. Unlike interfaces, we don't look outside the
605// implementation.
Daniel Dunbardd24b9a2008-08-26 06:53:45 +0000606ObjCMethodDecl *ObjCCategoryImplDecl::getClassMethod(Selector Sel) const {
Chris Lattner10318b82008-03-16 00:19:01 +0000607 for (classmeth_iterator I = classmeth_begin(), E = classmeth_end();
608 I != E; ++I)
609 if ((*I)->getSelector() == Sel)
610 return *I;
611 return NULL;
612}
613
614// lookupInstanceMethod - Lookup a instance method in the protocol and protocols
615// it inherited.
616ObjCMethodDecl *ObjCProtocolDecl::lookupInstanceMethod(Selector Sel) {
617 ObjCMethodDecl *MethodDecl = NULL;
618
619 if ((MethodDecl = getInstanceMethod(Sel)))
620 return MethodDecl;
621
Chris Lattner0be08822008-07-21 21:32:27 +0000622 for (protocol_iterator I = protocol_begin(), E = protocol_end(); I != E; ++I)
Steve Naroff30fb1da2008-12-18 15:50:41 +0000623 if ((MethodDecl = (*I)->lookupInstanceMethod(Sel)))
Chris Lattner0be08822008-07-21 21:32:27 +0000624 return MethodDecl;
Chris Lattner10318b82008-03-16 00:19:01 +0000625 return NULL;
626}
627
628// lookupInstanceMethod - Lookup a class method in the protocol and protocols
629// it inherited.
630ObjCMethodDecl *ObjCProtocolDecl::lookupClassMethod(Selector Sel) {
631 ObjCMethodDecl *MethodDecl = NULL;
632
633 if ((MethodDecl = getClassMethod(Sel)))
634 return MethodDecl;
635
Chris Lattner0be08822008-07-21 21:32:27 +0000636 for (protocol_iterator I = protocol_begin(), E = protocol_end(); I != E; ++I)
Steve Naroff30fb1da2008-12-18 15:50:41 +0000637 if ((MethodDecl = (*I)->lookupClassMethod(Sel)))
Chris Lattner0be08822008-07-21 21:32:27 +0000638 return MethodDecl;
Chris Lattner10318b82008-03-16 00:19:01 +0000639 return NULL;
640}
641
642/// getSynthesizedMethodSize - Compute size of synthesized method name
643/// as done be the rewrite.
644///
645unsigned ObjCMethodDecl::getSynthesizedMethodSize() const {
646 // syntesized method name is a concatenation of -/+[class-name selector]
647 // Get length of this name.
648 unsigned length = 3; // _I_ or _C_
Chris Lattnerd120b9e2008-11-24 03:54:41 +0000649 length += getClassInterface()->getNameAsString().size()+1; // extra for _
Steve Naroff438be772009-01-08 19:41:02 +0000650 if (const ObjCCategoryImplDecl *CID =
651 dyn_cast<ObjCCategoryImplDecl>(getDeclContext()))
Chris Lattnerd120b9e2008-11-24 03:54:41 +0000652 length += CID->getNameAsString().size()+1;
Chris Lattner3a8f2942008-11-24 03:33:13 +0000653 length += getSelector().getAsString().size(); // selector name
Chris Lattner10318b82008-03-16 00:19:01 +0000654 return length;
655}
656
Chris Lattner052fbcd2008-04-06 05:25:03 +0000657ObjCInterfaceDecl *ObjCMethodDecl::getClassInterface() {
Steve Naroff438be772009-01-08 19:41:02 +0000658 if (ObjCInterfaceDecl *ID = dyn_cast<ObjCInterfaceDecl>(getDeclContext()))
Chris Lattner10318b82008-03-16 00:19:01 +0000659 return ID;
Steve Naroff438be772009-01-08 19:41:02 +0000660 if (ObjCCategoryDecl *CD = dyn_cast<ObjCCategoryDecl>(getDeclContext()))
Chris Lattner10318b82008-03-16 00:19:01 +0000661 return CD->getClassInterface();
662 if (ObjCImplementationDecl *IMD =
Steve Naroff438be772009-01-08 19:41:02 +0000663 dyn_cast<ObjCImplementationDecl>(getDeclContext()))
Chris Lattner10318b82008-03-16 00:19:01 +0000664 return IMD->getClassInterface();
Steve Naroff438be772009-01-08 19:41:02 +0000665 if (ObjCCategoryImplDecl *CID =
666 dyn_cast<ObjCCategoryImplDecl>(getDeclContext()))
Chris Lattner10318b82008-03-16 00:19:01 +0000667 return CID->getClassInterface();
668 assert(false && "unknown method context");
669 return 0;
670}
Chris Lattner44859612008-03-17 01:19:02 +0000671
Fariborz Jahaniandc0569e2008-04-23 00:06:01 +0000672ObjCPropertyImplDecl *ObjCPropertyImplDecl::Create(ASTContext &C,
Douglas Gregor6e4fa2c2009-01-09 00:49:46 +0000673 DeclContext *DC,
Fariborz Jahaniandc0569e2008-04-23 00:06:01 +0000674 SourceLocation atLoc,
675 SourceLocation L,
676 ObjCPropertyDecl *property,
Daniel Dunbar14117fc2008-08-26 04:47:31 +0000677 Kind PK,
Fariborz Jahaniandc0569e2008-04-23 00:06:01 +0000678 ObjCIvarDecl *ivar) {
679 void *Mem = C.getAllocator().Allocate<ObjCPropertyImplDecl>();
Douglas Gregor6e4fa2c2009-01-09 00:49:46 +0000680 return new (Mem) ObjCPropertyImplDecl(DC, atLoc, L, property, PK, ivar);
Fariborz Jahaniandc0569e2008-04-23 00:06:01 +0000681}
Chris Lattner44859612008-03-17 01:19:02 +0000682
Chris Lattnereee57c02008-04-04 06:12:32 +0000683