blob: b36da643ecf87a03653cc6514fa2669fd126452f [file] [log] [blame]
Chris Lattner10318b82008-03-16 00:19:01 +00001//===--- DeclObjC.cpp - ObjC Declaration AST Node Implementation ----------===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file implements the Objective-C related Decl classes.
11//
12//===----------------------------------------------------------------------===//
13
14#include "clang/AST/DeclObjC.h"
15#include "clang/AST/ASTContext.h"
Daniel Dunbarde300732008-08-11 04:54:23 +000016#include "clang/AST/Stmt.h"
Chris Lattner10318b82008-03-16 00:19:01 +000017using namespace clang;
18
Chris Lattner114add62008-03-16 00:49:28 +000019//===----------------------------------------------------------------------===//
20// ObjC Decl Allocation/Deallocation Method Implementations
21//===----------------------------------------------------------------------===//
22
Chris Lattnereee57c02008-04-04 06:12:32 +000023ObjCMethodDecl *ObjCMethodDecl::Create(ASTContext &C,
24 SourceLocation beginLoc,
Chris Lattner114add62008-03-16 00:49:28 +000025 SourceLocation endLoc,
26 Selector SelInfo, QualType T,
Steve Naroffab63fd62009-01-08 17:28:14 +000027 DeclContext *contextDecl,
Daniel Dunbard8bd6822008-08-20 18:02:42 +000028 bool isInstance,
Chris Lattner114add62008-03-16 00:49:28 +000029 bool isVariadic,
Fariborz Jahanian5f2e2242008-05-07 20:53:44 +000030 bool isSynthesized,
Chris Lattnerf7355832008-03-16 00:58:16 +000031 ImplementationControl impControl) {
Steve Naroff5abb0282009-01-27 21:25:57 +000032 return new (C) ObjCMethodDecl(beginLoc, endLoc,
Chris Lattnereee57c02008-04-04 06:12:32 +000033 SelInfo, T, contextDecl,
Daniel Dunbard8bd6822008-08-20 18:02:42 +000034 isInstance,
Fariborz Jahanian5f2e2242008-05-07 20:53:44 +000035 isVariadic, isSynthesized, impControl);
Chris Lattner0db541b2008-03-16 01:15:50 +000036}
Chris Lattner114add62008-03-16 00:49:28 +000037
Ted Kremenek8c945b12008-06-06 16:45:15 +000038ObjCMethodDecl::~ObjCMethodDecl() {
39 delete [] ParamInfo;
Ted Kremenek8c945b12008-06-06 16:45:15 +000040}
41
42void ObjCMethodDecl::Destroy(ASTContext& C) {
43 if (Body) Body->Destroy(C);
44 if (SelfDecl) SelfDecl->Destroy(C);
45
46 for (param_iterator I=param_begin(), E=param_end(); I!=E; ++I)
47 if (*I) (*I)->Destroy(C);
48
49 Decl::Destroy(C);
50}
51
Chris Lattnereee57c02008-04-04 06:12:32 +000052ObjCInterfaceDecl *ObjCInterfaceDecl::Create(ASTContext &C,
Douglas Gregor6e4fa2c2009-01-09 00:49:46 +000053 DeclContext *DC,
Chris Lattnereee57c02008-04-04 06:12:32 +000054 SourceLocation atLoc,
Steve Naroff7c371742008-04-11 19:35:35 +000055 IdentifierInfo *Id,
56 SourceLocation ClassLoc,
Chris Lattner0db541b2008-03-16 01:15:50 +000057 bool ForwardDecl, bool isInternal){
Steve Naroff5abb0282009-01-27 21:25:57 +000058 return new (C) ObjCInterfaceDecl(DC, atLoc, Id, ClassLoc, ForwardDecl,
Chris Lattner0db541b2008-03-16 01:15:50 +000059 isInternal);
60}
61
Steve Naroffd9d4d502009-01-07 17:57:40 +000062ObjCContainerDecl::~ObjCContainerDecl() {
Steve Naroffd9d4d502009-01-07 17:57:40 +000063}
64
65ObjCInterfaceDecl::~ObjCInterfaceDecl() {
66 delete [] Ivars;
Ted Kremenek8c945b12008-06-06 16:45:15 +000067 // FIXME: CategoryList?
68}
69
70void ObjCInterfaceDecl::Destroy(ASTContext& C) {
71 for (ivar_iterator I=ivar_begin(), E=ivar_end(); I!=E; ++I)
72 if (*I) (*I)->Destroy(C);
73
Ted Kremenek22db1602008-06-06 17:21:42 +000074 // FIXME: Because there is no clear ownership
75 // role between ObjCInterfaceDecls and the ObjCPropertyDecls that they
76 // reference, we destroy ObjCPropertyDecls in ~TranslationUnit.
Ted Kremenek8c945b12008-06-06 16:45:15 +000077 Decl::Destroy(C);
78}
79
80
Chris Lattnerf3874bc2008-04-06 04:47:34 +000081ObjCIvarDecl *ObjCIvarDecl::Create(ASTContext &C, SourceLocation L,
Ted Kremenek173dd312008-07-23 18:04:17 +000082 IdentifierInfo *Id, QualType T,
83 AccessControl ac, Expr *BW) {
Steve Naroff5abb0282009-01-27 21:25:57 +000084 return new (C) ObjCIvarDecl(L, Id, T, ac, BW);
Chris Lattner114add62008-03-16 00:49:28 +000085}
86
Ted Kremeneke5bedfe2008-08-20 03:26:33 +000087
88ObjCAtDefsFieldDecl
Douglas Gregor8acb7272008-12-11 16:49:14 +000089*ObjCAtDefsFieldDecl::Create(ASTContext &C, DeclContext *DC, SourceLocation L,
Ted Kremeneke5bedfe2008-08-20 03:26:33 +000090 IdentifierInfo *Id, QualType T, Expr *BW) {
Steve Naroff5abb0282009-01-27 21:25:57 +000091 return new (C) ObjCAtDefsFieldDecl(DC, L, Id, T, BW);
Ted Kremeneke5bedfe2008-08-20 03:26:33 +000092}
93
94void ObjCAtDefsFieldDecl::Destroy(ASTContext& C) {
95 this->~ObjCAtDefsFieldDecl();
Steve Naroff5abb0282009-01-27 21:25:57 +000096 C.Deallocate((void *)this);
Ted Kremeneke5bedfe2008-08-20 03:26:33 +000097}
98
Douglas Gregor6e4fa2c2009-01-09 00:49:46 +000099ObjCProtocolDecl *ObjCProtocolDecl::Create(ASTContext &C, DeclContext *DC,
Chris Lattnereee57c02008-04-04 06:12:32 +0000100 SourceLocation L,
Chris Lattner7afba9c2008-03-16 20:19:15 +0000101 IdentifierInfo *Id) {
Steve Naroff5abb0282009-01-27 21:25:57 +0000102 return new (C) ObjCProtocolDecl(DC, L, Id);
Chris Lattner180f7e22008-03-16 01:23:04 +0000103}
104
Ted Kremenekc906e5e2008-06-06 19:48:57 +0000105ObjCProtocolDecl::~ObjCProtocolDecl() {
Ted Kremenekc906e5e2008-06-06 19:48:57 +0000106 delete [] PropertyDecl;
107}
108
Ted Kremenekc906e5e2008-06-06 19:48:57 +0000109
Douglas Gregor6e4fa2c2009-01-09 00:49:46 +0000110ObjCClassDecl *ObjCClassDecl::Create(ASTContext &C, DeclContext *DC,
Chris Lattnereee57c02008-04-04 06:12:32 +0000111 SourceLocation L,
Chris Lattnere29dc832008-03-16 20:34:23 +0000112 ObjCInterfaceDecl **Elts, unsigned nElts) {
Steve Naroff5abb0282009-01-27 21:25:57 +0000113 return new (C) ObjCClassDecl(DC, L, Elts, nElts);
Chris Lattnere29dc832008-03-16 20:34:23 +0000114}
115
Ted Kremenekff291622008-06-06 20:11:53 +0000116ObjCClassDecl::~ObjCClassDecl() {
117 delete [] ForwardDecls;
118}
119
120void ObjCClassDecl::Destroy(ASTContext& C) {
121
122 // FIXME: There is no clear ownership policy now for referenced
123 // ObjCInterfaceDecls. Some of them can be forward declarations that
124 // are never later defined (in which case the ObjCClassDecl owns them)
125 // or the ObjCInterfaceDecl later becomes a real definition later. Ideally
126 // we should have separate objects for forward declarations and definitions,
127 // obviating this problem. Because of this situation, referenced
128 // ObjCInterfaceDecls are destroyed in ~TranslationUnit.
129
130 Decl::Destroy(C);
131}
132
Chris Lattnere29dc832008-03-16 20:34:23 +0000133ObjCForwardProtocolDecl *
Douglas Gregor6e4fa2c2009-01-09 00:49:46 +0000134ObjCForwardProtocolDecl::Create(ASTContext &C, DeclContext *DC,
Chris Lattnereee57c02008-04-04 06:12:32 +0000135 SourceLocation L,
Chris Lattnere29dc832008-03-16 20:34:23 +0000136 ObjCProtocolDecl **Elts, unsigned NumElts) {
Steve Naroff5abb0282009-01-27 21:25:57 +0000137 return new (C) ObjCForwardProtocolDecl(DC, L, Elts, NumElts);
Chris Lattnere29dc832008-03-16 20:34:23 +0000138}
139
Ted Kremenek1e5e0bf2008-06-06 21:05:33 +0000140ObjCForwardProtocolDecl::~ObjCForwardProtocolDecl() {
141 delete [] ReferencedProtocols;
142}
143
Douglas Gregor6e4fa2c2009-01-09 00:49:46 +0000144ObjCCategoryDecl *ObjCCategoryDecl::Create(ASTContext &C, DeclContext *DC,
Chris Lattnereee57c02008-04-04 06:12:32 +0000145 SourceLocation L,
Chris Lattnere29dc832008-03-16 20:34:23 +0000146 IdentifierInfo *Id) {
Steve Naroff5abb0282009-01-27 21:25:57 +0000147 return new (C) ObjCCategoryDecl(DC, L, Id);
Chris Lattnere29dc832008-03-16 20:34:23 +0000148}
149
Chris Lattner1b6de332008-03-16 20:53:07 +0000150ObjCCategoryImplDecl *
Douglas Gregor6e4fa2c2009-01-09 00:49:46 +0000151ObjCCategoryImplDecl::Create(ASTContext &C, DeclContext *DC,
Chris Lattnereee57c02008-04-04 06:12:32 +0000152 SourceLocation L,IdentifierInfo *Id,
Chris Lattner1b6de332008-03-16 20:53:07 +0000153 ObjCInterfaceDecl *ClassInterface) {
Steve Naroff5abb0282009-01-27 21:25:57 +0000154 return new (C) ObjCCategoryImplDecl(DC, L, Id, ClassInterface);
Chris Lattner1b6de332008-03-16 20:53:07 +0000155}
156
157ObjCImplementationDecl *
Douglas Gregor6e4fa2c2009-01-09 00:49:46 +0000158ObjCImplementationDecl::Create(ASTContext &C, DeclContext *DC,
Chris Lattnereee57c02008-04-04 06:12:32 +0000159 SourceLocation L,
Chris Lattner1b6de332008-03-16 20:53:07 +0000160 ObjCInterfaceDecl *ClassInterface,
161 ObjCInterfaceDecl *SuperDecl) {
Steve Naroff5abb0282009-01-27 21:25:57 +0000162 return new (C) ObjCImplementationDecl(DC, L, ClassInterface, SuperDecl);
Chris Lattner1b6de332008-03-16 20:53:07 +0000163}
Chris Lattner10318b82008-03-16 00:19:01 +0000164
Chris Lattner2d1c4312008-03-16 21:17:37 +0000165ObjCCompatibleAliasDecl *
Douglas Gregor6e4fa2c2009-01-09 00:49:46 +0000166ObjCCompatibleAliasDecl::Create(ASTContext &C, DeclContext *DC,
Chris Lattnereee57c02008-04-04 06:12:32 +0000167 SourceLocation L,
Chris Lattner2d1c4312008-03-16 21:17:37 +0000168 IdentifierInfo *Id,
169 ObjCInterfaceDecl* AliasedClass) {
Steve Naroff5abb0282009-01-27 21:25:57 +0000170 return new (C) ObjCCompatibleAliasDecl(DC, L, Id, AliasedClass);
Chris Lattner2d1c4312008-03-16 21:17:37 +0000171}
172
Douglas Gregor6e4fa2c2009-01-09 00:49:46 +0000173ObjCPropertyDecl *ObjCPropertyDecl::Create(ASTContext &C, DeclContext *DC,
Fariborz Jahaniane7071722008-04-11 23:40:25 +0000174 SourceLocation L,
Fariborz Jahanian0ceb4be2008-04-14 23:36:35 +0000175 IdentifierInfo *Id,
Fariborz Jahanian4aa72a72008-05-05 18:51:55 +0000176 QualType T,
177 PropertyControl propControl) {
Steve Naroff5abb0282009-01-27 21:25:57 +0000178 return new (C) ObjCPropertyDecl(DC, L, Id, T);
Chris Lattner2d1c4312008-03-16 21:17:37 +0000179}
180
Chris Lattner10318b82008-03-16 00:19:01 +0000181//===----------------------------------------------------------------------===//
182// Objective-C Decl Implementation
183//===----------------------------------------------------------------------===//
184
Fariborz Jahanian91dd9d32008-12-09 20:23:04 +0000185void ObjCMethodDecl::createImplicitParams(ASTContext &Context,
186 const ObjCInterfaceDecl *OID) {
Daniel Dunbar88116372008-08-26 06:08:30 +0000187 QualType selfTy;
Douglas Gregor5d764842009-01-09 17:18:27 +0000188 if (isInstanceMethod()) {
Daniel Dunbar88116372008-08-26 06:08:30 +0000189 // There may be no interface context due to error in declaration
190 // of the interface (which has been reported). Recover gracefully.
Fariborz Jahanian91dd9d32008-12-09 20:23:04 +0000191 if (OID) {
192 selfTy = Context.getObjCInterfaceType(const_cast<ObjCInterfaceDecl *>(OID));
Daniel Dunbar88116372008-08-26 06:08:30 +0000193 selfTy = Context.getPointerType(selfTy);
194 } else {
195 selfTy = Context.getObjCIdType();
196 }
197 } else // we have a factory method.
198 selfTy = Context.getObjCClassType();
199
200 SelfDecl = ImplicitParamDecl::Create(Context, this,
201 SourceLocation(),
202 &Context.Idents.get("self"),
Douglas Gregoraf8ad2b2009-01-20 01:17:11 +0000203 selfTy);
Daniel Dunbar88116372008-08-26 06:08:30 +0000204
205 CmdDecl = ImplicitParamDecl::Create(Context, this,
206 SourceLocation(),
207 &Context.Idents.get("_cmd"),
Douglas Gregoraf8ad2b2009-01-20 01:17:11 +0000208 Context.getObjCSelType());
Daniel Dunbar88116372008-08-26 06:08:30 +0000209}
210
Chris Lattner10318b82008-03-16 00:19:01 +0000211void ObjCMethodDecl::setMethodParams(ParmVarDecl **NewParamInfo,
212 unsigned NumParams) {
213 assert(ParamInfo == 0 && "Already has param info!");
214
215 // Zero params -> null pointer.
216 if (NumParams) {
217 ParamInfo = new ParmVarDecl*[NumParams];
218 memcpy(ParamInfo, NewParamInfo, sizeof(ParmVarDecl*)*NumParams);
219 NumMethodParams = NumParams;
220 }
221}
222
Fariborz Jahanianef8a3df2008-04-21 19:04:53 +0000223/// FindCategoryDeclaration - Finds category declaration in the list of
224/// categories for this class and returns it. Name of the category is passed
225/// in 'CategoryId'. If category not found, return 0;
226///
227ObjCCategoryDecl *
228 ObjCInterfaceDecl::FindCategoryDeclaration(IdentifierInfo *CategoryId) const {
229 for (ObjCCategoryDecl *Category = getCategoryList();
230 Category; Category = Category->getNextClassCategory())
231 if (Category->getIdentifier() == CategoryId)
232 return Category;
233 return 0;
234}
235
236/// FindIvarDeclaration - Find an Ivar declaration in this class given its
237/// name in 'IvarId'. On failure to find, return 0;
238///
239ObjCIvarDecl *
240 ObjCInterfaceDecl::FindIvarDeclaration(IdentifierInfo *IvarId) const {
241 for (ObjCInterfaceDecl::ivar_iterator IVI = ivar_begin(),
242 IVE = ivar_end(); IVI != IVE; ++IVI) {
243 ObjCIvarDecl* Ivar = (*IVI);
244 if (Ivar->getIdentifier() == IvarId)
245 return Ivar;
246 }
Fariborz Jahanian8acf3352008-04-21 23:57:08 +0000247 if (getSuperClass())
248 return getSuperClass()->FindIvarDeclaration(IvarId);
Fariborz Jahanianef8a3df2008-04-21 19:04:53 +0000249 return 0;
250}
251
Chris Lattner10318b82008-03-16 00:19:01 +0000252/// ObjCAddInstanceVariablesToClass - Inserts instance variables
253/// into ObjCInterfaceDecl's fields.
254///
255void ObjCInterfaceDecl::addInstanceVariablesToClass(ObjCIvarDecl **ivars,
256 unsigned numIvars,
257 SourceLocation RBrac) {
258 NumIvars = numIvars;
259 if (numIvars) {
260 Ivars = new ObjCIvarDecl*[numIvars];
261 memcpy(Ivars, ivars, numIvars*sizeof(ObjCIvarDecl*));
262 }
263 setLocEnd(RBrac);
264}
265
Fariborz Jahanian09772392008-12-13 22:20:28 +0000266/// lookupFieldDeclForIvar - looks up a field decl' in the laid out
267/// storage which matches this 'ivar'.
268///
269FieldDecl *ObjCInterfaceDecl::lookupFieldDeclForIvar(ASTContext &Context,
Fariborz Jahanian86008c02008-12-15 20:35:07 +0000270 const ObjCIvarDecl *ivar) {
Fariborz Jahanian0556b152008-12-17 21:40:49 +0000271 const RecordDecl *RecordForDecl = Context.addRecordToClass(this);
Fariborz Jahanian09772392008-12-13 22:20:28 +0000272 assert(RecordForDecl && "lookupFieldDeclForIvar no storage for class");
273 DeclarationName Member = ivar->getDeclName();
Fariborz Jahanian0556b152008-12-17 21:40:49 +0000274 DeclContext::lookup_result Lookup = (const_cast< RecordDecl *>(RecordForDecl))
Steve Naroffab63fd62009-01-08 17:28:14 +0000275 ->lookup(Member);
Fariborz Jahanian09772392008-12-13 22:20:28 +0000276 assert((Lookup.first != Lookup.second) && "field decl not found");
277 FieldDecl *MemberDecl = dyn_cast<FieldDecl>(*Lookup.first);
278 assert(MemberDecl && "field decl not found");
279 return MemberDecl;
280}
281
Chris Lattner10318b82008-03-16 00:19:01 +0000282/// ObjCAddInstanceVariablesToClassImpl - Checks for correctness of Instance
283/// Variables (Ivars) relative to what declared in @implementation;s class.
284/// Ivars into ObjCImplementationDecl's fields.
285///
286void ObjCImplementationDecl::ObjCAddInstanceVariablesToClassImpl(
287 ObjCIvarDecl **ivars, unsigned numIvars) {
288 NumIvars = numIvars;
289 if (numIvars) {
290 Ivars = new ObjCIvarDecl*[numIvars];
291 memcpy(Ivars, ivars, numIvars*sizeof(ObjCIvarDecl*));
292 }
293}
294
Steve Naroffab63fd62009-01-08 17:28:14 +0000295// Get the local instance method declared in this interface.
296// FIXME: handle overloading, instance & class methods can have the same name.
297ObjCMethodDecl *ObjCContainerDecl::getInstanceMethod(Selector Sel) const {
298 lookup_const_result MethodResult = lookup(Sel);
299 if (MethodResult.first)
300 return const_cast<ObjCMethodDecl*>(
301 dyn_cast<ObjCMethodDecl>(*MethodResult.first));
302 return 0;
303}
304
305// Get the local class method declared in this interface.
306ObjCMethodDecl *ObjCContainerDecl::getClassMethod(Selector Sel) const {
307 lookup_const_result MethodResult = lookup(Sel);
308 if (MethodResult.first)
309 return const_cast<ObjCMethodDecl*>(
310 dyn_cast<ObjCMethodDecl>(*MethodResult.first));
311 return 0;
312}
313
314unsigned ObjCContainerDecl::getNumInstanceMethods() const {
315 unsigned sum = 0;
316 for (instmeth_iterator I=instmeth_begin(), E=instmeth_end(); I != E; ++I)
317 sum++;
318 return sum;
319}
320unsigned ObjCContainerDecl::getNumClassMethods() const {
321 unsigned sum = 0;
322 for (classmeth_iterator I=classmeth_begin(), E=classmeth_end(); I != E; ++I)
323 sum++;
324 return sum;
325}
Steve Naroff56af2002009-01-11 01:06:09 +0000326unsigned ObjCContainerDecl::getNumProperties() const {
327 unsigned sum = 0;
328 for (prop_iterator I=prop_begin(), E=prop_end(); I != E; ++I)
329 sum++;
330 return sum;
331}
Steve Naroffab63fd62009-01-08 17:28:14 +0000332
Fariborz Jahanianef8a3df2008-04-21 19:04:53 +0000333/// FindPropertyDeclaration - Finds declaration of the property given its name
334/// in 'PropertyId' and returns it. It returns 0, if not found.
Steve Naroffdcf1e842009-01-11 12:47:58 +0000335/// FIXME: Convert to DeclContext lookup...
Fariborz Jahanianef8a3df2008-04-21 19:04:53 +0000336///
337ObjCPropertyDecl *
Steve Naroff451f83c2009-01-09 15:36:25 +0000338ObjCContainerDecl::FindPropertyDeclaration(IdentifierInfo *PropertyId) const {
339 for (prop_iterator I = prop_begin(), E = prop_end(); I != E; ++I) {
Fariborz Jahanianef8a3df2008-04-21 19:04:53 +0000340 ObjCPropertyDecl *property = *I;
341 if (property->getIdentifier() == PropertyId)
342 return property;
343 }
Fariborz Jahanianfaca5e22009-01-09 21:04:52 +0000344 const ObjCProtocolDecl *PID = dyn_cast<ObjCProtocolDecl>(this);
345 if (PID) {
346 for (ObjCProtocolDecl::protocol_iterator P = PID->protocol_begin(),
347 E = PID->protocol_end();
348 P != E; ++P)
349 if (ObjCPropertyDecl *property =
350 (*P)->FindPropertyDeclaration(PropertyId))
351 return property;
352 }
353
Fariborz Jahanian6b0ed6f2009-01-19 18:16:19 +0000354 if (const ObjCInterfaceDecl *OID = dyn_cast<ObjCInterfaceDecl>(this)) {
Steve Naroff451f83c2009-01-09 15:36:25 +0000355 // Look through categories.
356 for (ObjCCategoryDecl *Category = OID->getCategoryList();
357 Category; Category = Category->getNextClassCategory()) {
358 ObjCPropertyDecl *property = Category->FindPropertyDeclaration(PropertyId);
359 if (property)
360 return property;
361 }
362 // Look through protocols.
363 for (ObjCInterfaceDecl::protocol_iterator I = OID->protocol_begin(),
364 E = OID->protocol_end(); I != E; ++I) {
365 ObjCProtocolDecl *Protocol = *I;
366 ObjCPropertyDecl *property = Protocol->FindPropertyDeclaration(PropertyId);
367 if (property)
368 return property;
369 }
370 if (OID->getSuperClass())
371 return OID->getSuperClass()->FindPropertyDeclaration(PropertyId);
Steve Naroffd1f0eb42008-06-05 13:55:23 +0000372 }
Fariborz Jahanian6b0ed6f2009-01-19 18:16:19 +0000373 else if (const ObjCCategoryDecl *OCD = dyn_cast<ObjCCategoryDecl>(this)) {
374 // Look through protocols.
375 for (ObjCInterfaceDecl::protocol_iterator I = OCD->protocol_begin(),
376 E = OCD->protocol_end(); I != E; ++I) {
377 ObjCProtocolDecl *Protocol = *I;
378 ObjCPropertyDecl *property = Protocol->FindPropertyDeclaration(PropertyId);
379 if (property)
380 return property;
381 }
382 }
Steve Naroffd1f0eb42008-06-05 13:55:23 +0000383 return 0;
384}
385
Chris Lattner10318b82008-03-16 00:19:01 +0000386ObjCIvarDecl *ObjCInterfaceDecl::lookupInstanceVariable(
387 IdentifierInfo *ID, ObjCInterfaceDecl *&clsDeclared) {
388 ObjCInterfaceDecl* ClassDecl = this;
389 while (ClassDecl != NULL) {
390 for (ivar_iterator I = ClassDecl->ivar_begin(), E = ClassDecl->ivar_end();
391 I != E; ++I) {
392 if ((*I)->getIdentifier() == ID) {
393 clsDeclared = ClassDecl;
394 return *I;
395 }
396 }
397 ClassDecl = ClassDecl->getSuperClass();
398 }
399 return NULL;
400}
401
402/// lookupInstanceMethod - This method returns an instance method by looking in
403/// the class, its categories, and its super classes (using a linear search).
404ObjCMethodDecl *ObjCInterfaceDecl::lookupInstanceMethod(Selector Sel) {
405 ObjCInterfaceDecl* ClassDecl = this;
406 ObjCMethodDecl *MethodDecl = 0;
407
408 while (ClassDecl != NULL) {
409 if ((MethodDecl = ClassDecl->getInstanceMethod(Sel)))
410 return MethodDecl;
411
412 // Didn't find one yet - look through protocols.
Chris Lattner8bcb5252008-07-21 18:19:38 +0000413 const ObjCList<ObjCProtocolDecl> &Protocols =
414 ClassDecl->getReferencedProtocols();
415 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
416 E = Protocols.end(); I != E; ++I)
417 if ((MethodDecl = (*I)->getInstanceMethod(Sel)))
Chris Lattner10318b82008-03-16 00:19:01 +0000418 return MethodDecl;
Chris Lattner8bcb5252008-07-21 18:19:38 +0000419
Chris Lattner10318b82008-03-16 00:19:01 +0000420 // Didn't find one yet - now look through categories.
421 ObjCCategoryDecl *CatDecl = ClassDecl->getCategoryList();
422 while (CatDecl) {
423 if ((MethodDecl = CatDecl->getInstanceMethod(Sel)))
424 return MethodDecl;
Steve Naroffaf151802008-12-08 20:57:28 +0000425
426 // Didn't find one yet - look through protocols.
427 const ObjCList<ObjCProtocolDecl> &Protocols =
428 CatDecl->getReferencedProtocols();
429 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
430 E = Protocols.end(); I != E; ++I)
431 if ((MethodDecl = (*I)->getInstanceMethod(Sel)))
432 return MethodDecl;
Chris Lattner10318b82008-03-16 00:19:01 +0000433 CatDecl = CatDecl->getNextClassCategory();
434 }
435 ClassDecl = ClassDecl->getSuperClass();
436 }
437 return NULL;
438}
439
440// lookupClassMethod - This method returns a class method by looking in the
441// class, its categories, and its super classes (using a linear search).
442ObjCMethodDecl *ObjCInterfaceDecl::lookupClassMethod(Selector Sel) {
443 ObjCInterfaceDecl* ClassDecl = this;
444 ObjCMethodDecl *MethodDecl = 0;
445
446 while (ClassDecl != NULL) {
447 if ((MethodDecl = ClassDecl->getClassMethod(Sel)))
448 return MethodDecl;
449
450 // Didn't find one yet - look through protocols.
Chris Lattner0be08822008-07-21 21:32:27 +0000451 for (ObjCInterfaceDecl::protocol_iterator I = ClassDecl->protocol_begin(),
452 E = ClassDecl->protocol_end(); I != E; ++I)
Chris Lattner8bcb5252008-07-21 18:19:38 +0000453 if ((MethodDecl = (*I)->getClassMethod(Sel)))
Chris Lattner10318b82008-03-16 00:19:01 +0000454 return MethodDecl;
Chris Lattner0be08822008-07-21 21:32:27 +0000455
Chris Lattner10318b82008-03-16 00:19:01 +0000456 // Didn't find one yet - now look through categories.
457 ObjCCategoryDecl *CatDecl = ClassDecl->getCategoryList();
458 while (CatDecl) {
459 if ((MethodDecl = CatDecl->getClassMethod(Sel)))
460 return MethodDecl;
461 CatDecl = CatDecl->getNextClassCategory();
462 }
463 ClassDecl = ClassDecl->getSuperClass();
464 }
465 return NULL;
466}
467
Daniel Dunbardd24b9a2008-08-26 06:53:45 +0000468/// getInstanceMethod - This method returns an instance method by
469/// looking in the class implementation. Unlike interfaces, we don't
470/// look outside the implementation.
471ObjCMethodDecl *ObjCImplementationDecl::getInstanceMethod(Selector Sel) const {
Chris Lattner10318b82008-03-16 00:19:01 +0000472 for (instmeth_iterator I = instmeth_begin(), E = instmeth_end(); I != E; ++I)
473 if ((*I)->getSelector() == Sel)
474 return *I;
475 return NULL;
476}
477
Daniel Dunbardd24b9a2008-08-26 06:53:45 +0000478/// getClassMethod - This method returns a class method by looking in
479/// the class implementation. Unlike interfaces, we don't look outside
480/// the implementation.
481ObjCMethodDecl *ObjCImplementationDecl::getClassMethod(Selector Sel) const {
Chris Lattner10318b82008-03-16 00:19:01 +0000482 for (classmeth_iterator I = classmeth_begin(), E = classmeth_end();
483 I != E; ++I)
484 if ((*I)->getSelector() == Sel)
485 return *I;
486 return NULL;
487}
488
Fariborz Jahanian68342282008-12-05 22:32:48 +0000489/// FindPropertyImplDecl - This method looks up a previous ObjCPropertyImplDecl
490/// added to the list of those properties @synthesized/@dynamic in this
491/// @implementation block.
492///
493ObjCPropertyImplDecl *ObjCImplementationDecl::FindPropertyImplDecl(IdentifierInfo *Id) const {
494 for (propimpl_iterator i = propimpl_begin(), e = propimpl_end(); i != e; ++i) {
495 ObjCPropertyImplDecl *PID = *i;
496 if (PID->getPropertyDecl()->getIdentifier() == Id)
497 return PID;
498 }
499 return 0;
500}
501
502/// FindPropertyImplIvarDecl - This method lookup the ivar in the list of
Fariborz Jahanian17eb8882008-12-05 22:36:19 +0000503/// properties implemented in this @implementation block and returns the
504/// implemented property that uses it.
Fariborz Jahanian68342282008-12-05 22:32:48 +0000505///
506ObjCPropertyImplDecl *ObjCImplementationDecl::FindPropertyImplIvarDecl(IdentifierInfo *ivarId) const {
507 for (propimpl_iterator i = propimpl_begin(), e = propimpl_end(); i != e; ++i) {
508 ObjCPropertyImplDecl *PID = *i;
509 if (PID->getPropertyIvarDecl() &&
510 PID->getPropertyIvarDecl()->getIdentifier() == ivarId)
511 return PID;
512 }
513 return 0;
514}
515
516/// FindPropertyImplIvarDecl - This method lookup the ivar in the list of
Fariborz Jahanian17eb8882008-12-05 22:36:19 +0000517/// properties implemented in this category @implementation block and returns the
518/// implemented property that uses it.
Fariborz Jahanian68342282008-12-05 22:32:48 +0000519///
520ObjCPropertyImplDecl *ObjCCategoryImplDecl::FindPropertyImplIvarDecl(IdentifierInfo *ivarId) const {
521 for (propimpl_iterator i = propimpl_begin(), e = propimpl_end(); i != e; ++i) {
522 ObjCPropertyImplDecl *PID = *i;
523 if (PID->getPropertyIvarDecl() &&
524 PID->getPropertyIvarDecl()->getIdentifier() == ivarId)
525 return PID;
526 }
527 return 0;
528}
529
530/// FindPropertyImplDecl - This method looks up a previous ObjCPropertyImplDecl
531/// added to the list of those properties @synthesized/@dynamic in this
532/// category @implementation block.
533///
534ObjCPropertyImplDecl *ObjCCategoryImplDecl::FindPropertyImplDecl(IdentifierInfo *Id) const {
535 for (propimpl_iterator i = propimpl_begin(), e = propimpl_end(); i != e; ++i) {
536 ObjCPropertyImplDecl *PID = *i;
537 if (PID->getPropertyDecl()->getIdentifier() == Id)
538 return PID;
539 }
540 return 0;
541}
542
Chris Lattner10318b82008-03-16 00:19:01 +0000543// lookupInstanceMethod - This method returns an instance method by looking in
544// the class implementation. Unlike interfaces, we don't look outside the
545// implementation.
Daniel Dunbardd24b9a2008-08-26 06:53:45 +0000546ObjCMethodDecl *ObjCCategoryImplDecl::getInstanceMethod(Selector Sel) const {
Chris Lattner10318b82008-03-16 00:19:01 +0000547 for (instmeth_iterator I = instmeth_begin(), E = instmeth_end(); I != E; ++I)
548 if ((*I)->getSelector() == Sel)
549 return *I;
550 return NULL;
551}
552
553// lookupClassMethod - This method returns an instance method by looking in
554// the class implementation. Unlike interfaces, we don't look outside the
555// implementation.
Daniel Dunbardd24b9a2008-08-26 06:53:45 +0000556ObjCMethodDecl *ObjCCategoryImplDecl::getClassMethod(Selector Sel) const {
Chris Lattner10318b82008-03-16 00:19:01 +0000557 for (classmeth_iterator I = classmeth_begin(), E = classmeth_end();
558 I != E; ++I)
559 if ((*I)->getSelector() == Sel)
560 return *I;
561 return NULL;
562}
563
564// lookupInstanceMethod - Lookup a instance method in the protocol and protocols
565// it inherited.
566ObjCMethodDecl *ObjCProtocolDecl::lookupInstanceMethod(Selector Sel) {
567 ObjCMethodDecl *MethodDecl = NULL;
568
569 if ((MethodDecl = getInstanceMethod(Sel)))
570 return MethodDecl;
571
Chris Lattner0be08822008-07-21 21:32:27 +0000572 for (protocol_iterator I = protocol_begin(), E = protocol_end(); I != E; ++I)
Steve Naroff30fb1da2008-12-18 15:50:41 +0000573 if ((MethodDecl = (*I)->lookupInstanceMethod(Sel)))
Chris Lattner0be08822008-07-21 21:32:27 +0000574 return MethodDecl;
Chris Lattner10318b82008-03-16 00:19:01 +0000575 return NULL;
576}
577
578// lookupInstanceMethod - Lookup a class method in the protocol and protocols
579// it inherited.
580ObjCMethodDecl *ObjCProtocolDecl::lookupClassMethod(Selector Sel) {
581 ObjCMethodDecl *MethodDecl = NULL;
582
583 if ((MethodDecl = getClassMethod(Sel)))
584 return MethodDecl;
585
Chris Lattner0be08822008-07-21 21:32:27 +0000586 for (protocol_iterator I = protocol_begin(), E = protocol_end(); I != E; ++I)
Steve Naroff30fb1da2008-12-18 15:50:41 +0000587 if ((MethodDecl = (*I)->lookupClassMethod(Sel)))
Chris Lattner0be08822008-07-21 21:32:27 +0000588 return MethodDecl;
Chris Lattner10318b82008-03-16 00:19:01 +0000589 return NULL;
590}
591
592/// getSynthesizedMethodSize - Compute size of synthesized method name
593/// as done be the rewrite.
594///
595unsigned ObjCMethodDecl::getSynthesizedMethodSize() const {
596 // syntesized method name is a concatenation of -/+[class-name selector]
597 // Get length of this name.
598 unsigned length = 3; // _I_ or _C_
Chris Lattnerd120b9e2008-11-24 03:54:41 +0000599 length += getClassInterface()->getNameAsString().size()+1; // extra for _
Steve Naroff438be772009-01-08 19:41:02 +0000600 if (const ObjCCategoryImplDecl *CID =
601 dyn_cast<ObjCCategoryImplDecl>(getDeclContext()))
Chris Lattnerd120b9e2008-11-24 03:54:41 +0000602 length += CID->getNameAsString().size()+1;
Chris Lattner3a8f2942008-11-24 03:33:13 +0000603 length += getSelector().getAsString().size(); // selector name
Chris Lattner10318b82008-03-16 00:19:01 +0000604 return length;
605}
606
Chris Lattner052fbcd2008-04-06 05:25:03 +0000607ObjCInterfaceDecl *ObjCMethodDecl::getClassInterface() {
Steve Naroff438be772009-01-08 19:41:02 +0000608 if (ObjCInterfaceDecl *ID = dyn_cast<ObjCInterfaceDecl>(getDeclContext()))
Chris Lattner10318b82008-03-16 00:19:01 +0000609 return ID;
Steve Naroff438be772009-01-08 19:41:02 +0000610 if (ObjCCategoryDecl *CD = dyn_cast<ObjCCategoryDecl>(getDeclContext()))
Chris Lattner10318b82008-03-16 00:19:01 +0000611 return CD->getClassInterface();
612 if (ObjCImplementationDecl *IMD =
Steve Naroff438be772009-01-08 19:41:02 +0000613 dyn_cast<ObjCImplementationDecl>(getDeclContext()))
Chris Lattner10318b82008-03-16 00:19:01 +0000614 return IMD->getClassInterface();
Steve Naroff438be772009-01-08 19:41:02 +0000615 if (ObjCCategoryImplDecl *CID =
616 dyn_cast<ObjCCategoryImplDecl>(getDeclContext()))
Chris Lattner10318b82008-03-16 00:19:01 +0000617 return CID->getClassInterface();
618 assert(false && "unknown method context");
619 return 0;
620}
Chris Lattner44859612008-03-17 01:19:02 +0000621
Fariborz Jahaniandc0569e2008-04-23 00:06:01 +0000622ObjCPropertyImplDecl *ObjCPropertyImplDecl::Create(ASTContext &C,
Douglas Gregor6e4fa2c2009-01-09 00:49:46 +0000623 DeclContext *DC,
Fariborz Jahaniandc0569e2008-04-23 00:06:01 +0000624 SourceLocation atLoc,
625 SourceLocation L,
626 ObjCPropertyDecl *property,
Daniel Dunbar14117fc2008-08-26 04:47:31 +0000627 Kind PK,
Fariborz Jahaniandc0569e2008-04-23 00:06:01 +0000628 ObjCIvarDecl *ivar) {
Steve Naroff5abb0282009-01-27 21:25:57 +0000629 return new (C) ObjCPropertyImplDecl(DC, atLoc, L, property, PK, ivar);
Fariborz Jahaniandc0569e2008-04-23 00:06:01 +0000630}
Chris Lattner44859612008-03-17 01:19:02 +0000631
Chris Lattnereee57c02008-04-04 06:12:32 +0000632