blob: 3417a302dcb78c2a13b35c9f9e89cc470b5432eb [file] [log] [blame]
Chris Lattner10318b82008-03-16 00:19:01 +00001//===--- DeclObjC.cpp - ObjC Declaration AST Node Implementation ----------===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file implements the Objective-C related Decl classes.
11//
12//===----------------------------------------------------------------------===//
13
14#include "clang/AST/DeclObjC.h"
15#include "clang/AST/ASTContext.h"
Daniel Dunbarde300732008-08-11 04:54:23 +000016#include "clang/AST/Stmt.h"
Chris Lattner10318b82008-03-16 00:19:01 +000017using namespace clang;
18
Chris Lattner114add62008-03-16 00:49:28 +000019//===----------------------------------------------------------------------===//
20// ObjC Decl Allocation/Deallocation Method Implementations
21//===----------------------------------------------------------------------===//
22
Chris Lattnereee57c02008-04-04 06:12:32 +000023ObjCMethodDecl *ObjCMethodDecl::Create(ASTContext &C,
24 SourceLocation beginLoc,
Chris Lattner114add62008-03-16 00:49:28 +000025 SourceLocation endLoc,
26 Selector SelInfo, QualType T,
Steve Naroffab63fd62009-01-08 17:28:14 +000027 DeclContext *contextDecl,
Daniel Dunbard8bd6822008-08-20 18:02:42 +000028 bool isInstance,
Chris Lattner114add62008-03-16 00:49:28 +000029 bool isVariadic,
Fariborz Jahanian5f2e2242008-05-07 20:53:44 +000030 bool isSynthesized,
Chris Lattnerf7355832008-03-16 00:58:16 +000031 ImplementationControl impControl) {
Steve Naroff5abb0282009-01-27 21:25:57 +000032 return new (C) ObjCMethodDecl(beginLoc, endLoc,
Chris Lattnereee57c02008-04-04 06:12:32 +000033 SelInfo, T, contextDecl,
Daniel Dunbard8bd6822008-08-20 18:02:42 +000034 isInstance,
Fariborz Jahanian5f2e2242008-05-07 20:53:44 +000035 isVariadic, isSynthesized, impControl);
Chris Lattner0db541b2008-03-16 01:15:50 +000036}
Chris Lattner114add62008-03-16 00:49:28 +000037
Ted Kremenek8c945b12008-06-06 16:45:15 +000038void ObjCMethodDecl::Destroy(ASTContext& C) {
39 if (Body) Body->Destroy(C);
40 if (SelfDecl) SelfDecl->Destroy(C);
41
42 for (param_iterator I=param_begin(), E=param_end(); I!=E; ++I)
43 if (*I) (*I)->Destroy(C);
Chris Lattnerae538882009-02-20 05:54:35 +000044
45 delete [] ParamInfo;
46 ParamInfo = 0;
47
Ted Kremenek8c945b12008-06-06 16:45:15 +000048 Decl::Destroy(C);
49}
50
Chris Lattner3e27e632009-02-20 06:03:09 +000051
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
Chris Lattner3e27e632009-02-20 06:03:09 +000062ObjCInterfaceDecl::
63ObjCInterfaceDecl(DeclContext *DC, SourceLocation atLoc, IdentifierInfo *Id,
64 SourceLocation CLoc, bool FD, bool isInternal)
65 : ObjCContainerDecl(ObjCInterface, DC, atLoc, Id),
66 TypeForDecl(0), SuperClass(0), Ivars(0), NumIvars(0),
67 CategoryList(0), ForwardDecl(FD), InternalInterface(isInternal),
68 ClassLoc(CLoc) {
Steve Naroffd9d4d502009-01-07 17:57:40 +000069}
70
Chris Lattner3e27e632009-02-20 06:03:09 +000071void ObjCInterfaceDecl::Destroy(ASTContext &C) {
Ted Kremenek8c945b12008-06-06 16:45:15 +000072 for (ivar_iterator I=ivar_begin(), E=ivar_end(); I!=E; ++I)
73 if (*I) (*I)->Destroy(C);
74
Chris Lattner3e27e632009-02-20 06:03:09 +000075 delete [] Ivars;
76 Ivars = 0;
77 // FIXME: CategoryList?
78
Ted Kremenek22db1602008-06-06 17:21:42 +000079 // FIXME: Because there is no clear ownership
80 // role between ObjCInterfaceDecls and the ObjCPropertyDecls that they
81 // reference, we destroy ObjCPropertyDecls in ~TranslationUnit.
Ted Kremenek8c945b12008-06-06 16:45:15 +000082 Decl::Destroy(C);
83}
84
85
Argiris Kirtzidis96e79bf2009-02-17 20:20:37 +000086ObjCIvarDecl *ObjCIvarDecl::Create(ASTContext &C, DeclContext *DC,
87 SourceLocation L, IdentifierInfo *Id,
88 QualType T, AccessControl ac, Expr *BW) {
89 return new (C) ObjCIvarDecl(DC, L, Id, T, ac, BW);
Chris Lattner114add62008-03-16 00:49:28 +000090}
91
Ted Kremeneke5bedfe2008-08-20 03:26:33 +000092
93ObjCAtDefsFieldDecl
Douglas Gregor8acb7272008-12-11 16:49:14 +000094*ObjCAtDefsFieldDecl::Create(ASTContext &C, DeclContext *DC, SourceLocation L,
Ted Kremeneke5bedfe2008-08-20 03:26:33 +000095 IdentifierInfo *Id, QualType T, Expr *BW) {
Steve Naroff5abb0282009-01-27 21:25:57 +000096 return new (C) ObjCAtDefsFieldDecl(DC, L, Id, T, BW);
Ted Kremeneke5bedfe2008-08-20 03:26:33 +000097}
98
99void ObjCAtDefsFieldDecl::Destroy(ASTContext& C) {
100 this->~ObjCAtDefsFieldDecl();
Steve Naroff5abb0282009-01-27 21:25:57 +0000101 C.Deallocate((void *)this);
Ted Kremeneke5bedfe2008-08-20 03:26:33 +0000102}
103
Douglas Gregor6e4fa2c2009-01-09 00:49:46 +0000104ObjCProtocolDecl *ObjCProtocolDecl::Create(ASTContext &C, DeclContext *DC,
Chris Lattnereee57c02008-04-04 06:12:32 +0000105 SourceLocation L,
Chris Lattner7afba9c2008-03-16 20:19:15 +0000106 IdentifierInfo *Id) {
Steve Naroff5abb0282009-01-27 21:25:57 +0000107 return new (C) ObjCProtocolDecl(DC, L, Id);
Chris Lattner180f7e22008-03-16 01:23:04 +0000108}
109
Chris Lattnerae538882009-02-20 05:54:35 +0000110void ObjCProtocolDecl::Destroy(ASTContext &C) {
Ted Kremenekc906e5e2008-06-06 19:48:57 +0000111 delete [] PropertyDecl;
Chris Lattnerae538882009-02-20 05:54:35 +0000112 PropertyDecl = 0;
113 ObjCContainerDecl::Destroy(C);
Ted Kremenekc906e5e2008-06-06 19:48:57 +0000114}
115
Ted Kremenekc906e5e2008-06-06 19:48:57 +0000116
Chris Lattnerae538882009-02-20 05:54:35 +0000117
118
Douglas Gregor6e4fa2c2009-01-09 00:49:46 +0000119ObjCClassDecl *ObjCClassDecl::Create(ASTContext &C, DeclContext *DC,
Chris Lattnereee57c02008-04-04 06:12:32 +0000120 SourceLocation L,
Chris Lattnere29dc832008-03-16 20:34:23 +0000121 ObjCInterfaceDecl **Elts, unsigned nElts) {
Steve Naroff5abb0282009-01-27 21:25:57 +0000122 return new (C) ObjCClassDecl(DC, L, Elts, nElts);
Chris Lattnere29dc832008-03-16 20:34:23 +0000123}
124
Chris Lattner3e27e632009-02-20 06:03:09 +0000125ObjCClassDecl::ObjCClassDecl(DeclContext *DC, SourceLocation L,
126 ObjCInterfaceDecl **Elts, unsigned nElts)
127 : Decl(ObjCClass, DC, L) {
128 if (nElts) {
129 ForwardDecls = new ObjCInterfaceDecl*[nElts];
130 memcpy(ForwardDecls, Elts, nElts*sizeof(ObjCInterfaceDecl*));
131 } else {
132 ForwardDecls = 0;
133 }
134 NumForwardDecls = nElts;
Ted Kremenekff291622008-06-06 20:11:53 +0000135}
136
Chris Lattner3e27e632009-02-20 06:03:09 +0000137void ObjCClassDecl::Destroy(ASTContext &C) {
Ted Kremenekff291622008-06-06 20:11:53 +0000138
139 // FIXME: There is no clear ownership policy now for referenced
140 // ObjCInterfaceDecls. Some of them can be forward declarations that
141 // are never later defined (in which case the ObjCClassDecl owns them)
142 // or the ObjCInterfaceDecl later becomes a real definition later. Ideally
143 // we should have separate objects for forward declarations and definitions,
144 // obviating this problem. Because of this situation, referenced
145 // ObjCInterfaceDecls are destroyed in ~TranslationUnit.
146
Chris Lattner3e27e632009-02-20 06:03:09 +0000147 delete [] ForwardDecls;
148 ForwardDecls = 0;
149
Ted Kremenekff291622008-06-06 20:11:53 +0000150 Decl::Destroy(C);
151}
152
Chris Lattnere29dc832008-03-16 20:34:23 +0000153ObjCForwardProtocolDecl *
Douglas Gregor6e4fa2c2009-01-09 00:49:46 +0000154ObjCForwardProtocolDecl::Create(ASTContext &C, DeclContext *DC,
Chris Lattnereee57c02008-04-04 06:12:32 +0000155 SourceLocation L,
Chris Lattnere29dc832008-03-16 20:34:23 +0000156 ObjCProtocolDecl **Elts, unsigned NumElts) {
Steve Naroff5abb0282009-01-27 21:25:57 +0000157 return new (C) ObjCForwardProtocolDecl(DC, L, Elts, NumElts);
Chris Lattnere29dc832008-03-16 20:34:23 +0000158}
159
Chris Lattner3e27e632009-02-20 06:03:09 +0000160ObjCForwardProtocolDecl::
161ObjCForwardProtocolDecl(DeclContext *DC, SourceLocation L,
162 ObjCProtocolDecl **Elts, unsigned nElts)
163 : Decl(ObjCForwardProtocol, DC, L) {
164 NumReferencedProtocols = nElts;
165 if (nElts) {
166 ReferencedProtocols = new ObjCProtocolDecl*[nElts];
167 memcpy(ReferencedProtocols, Elts, nElts*sizeof(ObjCProtocolDecl*));
168 } else {
169 ReferencedProtocols = 0;
170 }
171}
172
173void ObjCForwardProtocolDecl::Destroy(ASTContext &C) {
Ted Kremenek1e5e0bf2008-06-06 21:05:33 +0000174 delete [] ReferencedProtocols;
Chris Lattner3e27e632009-02-20 06:03:09 +0000175 ReferencedProtocols = 0;
Ted Kremenek1e5e0bf2008-06-06 21:05:33 +0000176}
177
Douglas Gregor6e4fa2c2009-01-09 00:49:46 +0000178ObjCCategoryDecl *ObjCCategoryDecl::Create(ASTContext &C, DeclContext *DC,
Chris Lattnereee57c02008-04-04 06:12:32 +0000179 SourceLocation L,
Chris Lattnere29dc832008-03-16 20:34:23 +0000180 IdentifierInfo *Id) {
Steve Naroff5abb0282009-01-27 21:25:57 +0000181 return new (C) ObjCCategoryDecl(DC, L, Id);
Chris Lattnere29dc832008-03-16 20:34:23 +0000182}
183
Chris Lattner1b6de332008-03-16 20:53:07 +0000184ObjCCategoryImplDecl *
Douglas Gregor6e4fa2c2009-01-09 00:49:46 +0000185ObjCCategoryImplDecl::Create(ASTContext &C, DeclContext *DC,
Chris Lattnereee57c02008-04-04 06:12:32 +0000186 SourceLocation L,IdentifierInfo *Id,
Chris Lattner1b6de332008-03-16 20:53:07 +0000187 ObjCInterfaceDecl *ClassInterface) {
Steve Naroff5abb0282009-01-27 21:25:57 +0000188 return new (C) ObjCCategoryImplDecl(DC, L, Id, ClassInterface);
Chris Lattner1b6de332008-03-16 20:53:07 +0000189}
190
191ObjCImplementationDecl *
Douglas Gregor6e4fa2c2009-01-09 00:49:46 +0000192ObjCImplementationDecl::Create(ASTContext &C, DeclContext *DC,
Chris Lattnereee57c02008-04-04 06:12:32 +0000193 SourceLocation L,
Chris Lattner1b6de332008-03-16 20:53:07 +0000194 ObjCInterfaceDecl *ClassInterface,
195 ObjCInterfaceDecl *SuperDecl) {
Steve Naroff5abb0282009-01-27 21:25:57 +0000196 return new (C) ObjCImplementationDecl(DC, L, ClassInterface, SuperDecl);
Chris Lattner1b6de332008-03-16 20:53:07 +0000197}
Chris Lattner10318b82008-03-16 00:19:01 +0000198
Chris Lattner2d1c4312008-03-16 21:17:37 +0000199ObjCCompatibleAliasDecl *
Douglas Gregor6e4fa2c2009-01-09 00:49:46 +0000200ObjCCompatibleAliasDecl::Create(ASTContext &C, DeclContext *DC,
Chris Lattnereee57c02008-04-04 06:12:32 +0000201 SourceLocation L,
Chris Lattner2d1c4312008-03-16 21:17:37 +0000202 IdentifierInfo *Id,
203 ObjCInterfaceDecl* AliasedClass) {
Steve Naroff5abb0282009-01-27 21:25:57 +0000204 return new (C) ObjCCompatibleAliasDecl(DC, L, Id, AliasedClass);
Chris Lattner2d1c4312008-03-16 21:17:37 +0000205}
206
Douglas Gregor6e4fa2c2009-01-09 00:49:46 +0000207ObjCPropertyDecl *ObjCPropertyDecl::Create(ASTContext &C, DeclContext *DC,
Fariborz Jahaniane7071722008-04-11 23:40:25 +0000208 SourceLocation L,
Fariborz Jahanian0ceb4be2008-04-14 23:36:35 +0000209 IdentifierInfo *Id,
Fariborz Jahanian4aa72a72008-05-05 18:51:55 +0000210 QualType T,
211 PropertyControl propControl) {
Steve Naroff5abb0282009-01-27 21:25:57 +0000212 return new (C) ObjCPropertyDecl(DC, L, Id, T);
Chris Lattner2d1c4312008-03-16 21:17:37 +0000213}
214
Chris Lattner10318b82008-03-16 00:19:01 +0000215//===----------------------------------------------------------------------===//
216// Objective-C Decl Implementation
217//===----------------------------------------------------------------------===//
218
Fariborz Jahanian91dd9d32008-12-09 20:23:04 +0000219void ObjCMethodDecl::createImplicitParams(ASTContext &Context,
220 const ObjCInterfaceDecl *OID) {
Daniel Dunbar88116372008-08-26 06:08:30 +0000221 QualType selfTy;
Douglas Gregor5d764842009-01-09 17:18:27 +0000222 if (isInstanceMethod()) {
Daniel Dunbar88116372008-08-26 06:08:30 +0000223 // There may be no interface context due to error in declaration
224 // of the interface (which has been reported). Recover gracefully.
Fariborz Jahanian91dd9d32008-12-09 20:23:04 +0000225 if (OID) {
226 selfTy = Context.getObjCInterfaceType(const_cast<ObjCInterfaceDecl *>(OID));
Daniel Dunbar88116372008-08-26 06:08:30 +0000227 selfTy = Context.getPointerType(selfTy);
228 } else {
229 selfTy = Context.getObjCIdType();
230 }
231 } else // we have a factory method.
232 selfTy = Context.getObjCClassType();
233
234 SelfDecl = ImplicitParamDecl::Create(Context, this,
235 SourceLocation(),
236 &Context.Idents.get("self"),
Douglas Gregoraf8ad2b2009-01-20 01:17:11 +0000237 selfTy);
Daniel Dunbar88116372008-08-26 06:08:30 +0000238
239 CmdDecl = ImplicitParamDecl::Create(Context, this,
240 SourceLocation(),
241 &Context.Idents.get("_cmd"),
Douglas Gregoraf8ad2b2009-01-20 01:17:11 +0000242 Context.getObjCSelType());
Daniel Dunbar88116372008-08-26 06:08:30 +0000243}
244
Chris Lattner10318b82008-03-16 00:19:01 +0000245void ObjCMethodDecl::setMethodParams(ParmVarDecl **NewParamInfo,
246 unsigned NumParams) {
247 assert(ParamInfo == 0 && "Already has param info!");
248
249 // Zero params -> null pointer.
250 if (NumParams) {
251 ParamInfo = new ParmVarDecl*[NumParams];
252 memcpy(ParamInfo, NewParamInfo, sizeof(ParmVarDecl*)*NumParams);
253 NumMethodParams = NumParams;
254 }
255}
256
Fariborz Jahanianef8a3df2008-04-21 19:04:53 +0000257/// FindCategoryDeclaration - Finds category declaration in the list of
258/// categories for this class and returns it. Name of the category is passed
259/// in 'CategoryId'. If category not found, return 0;
260///
261ObjCCategoryDecl *
262 ObjCInterfaceDecl::FindCategoryDeclaration(IdentifierInfo *CategoryId) const {
263 for (ObjCCategoryDecl *Category = getCategoryList();
264 Category; Category = Category->getNextClassCategory())
265 if (Category->getIdentifier() == CategoryId)
266 return Category;
267 return 0;
268}
269
Chris Lattner10318b82008-03-16 00:19:01 +0000270/// ObjCAddInstanceVariablesToClass - Inserts instance variables
271/// into ObjCInterfaceDecl's fields.
272///
273void ObjCInterfaceDecl::addInstanceVariablesToClass(ObjCIvarDecl **ivars,
274 unsigned numIvars,
275 SourceLocation RBrac) {
276 NumIvars = numIvars;
277 if (numIvars) {
278 Ivars = new ObjCIvarDecl*[numIvars];
279 memcpy(Ivars, ivars, numIvars*sizeof(ObjCIvarDecl*));
280 }
281 setLocEnd(RBrac);
282}
283
Fariborz Jahanian09772392008-12-13 22:20:28 +0000284/// lookupFieldDeclForIvar - looks up a field decl' in the laid out
285/// storage which matches this 'ivar'.
286///
287FieldDecl *ObjCInterfaceDecl::lookupFieldDeclForIvar(ASTContext &Context,
Fariborz Jahanian86008c02008-12-15 20:35:07 +0000288 const ObjCIvarDecl *ivar) {
Fariborz Jahanian0556b152008-12-17 21:40:49 +0000289 const RecordDecl *RecordForDecl = Context.addRecordToClass(this);
Fariborz Jahanian09772392008-12-13 22:20:28 +0000290 assert(RecordForDecl && "lookupFieldDeclForIvar no storage for class");
291 DeclarationName Member = ivar->getDeclName();
Fariborz Jahanian0556b152008-12-17 21:40:49 +0000292 DeclContext::lookup_result Lookup = (const_cast< RecordDecl *>(RecordForDecl))
Steve Naroffab63fd62009-01-08 17:28:14 +0000293 ->lookup(Member);
Fariborz Jahanian09772392008-12-13 22:20:28 +0000294 assert((Lookup.first != Lookup.second) && "field decl not found");
295 FieldDecl *MemberDecl = dyn_cast<FieldDecl>(*Lookup.first);
296 assert(MemberDecl && "field decl not found");
297 return MemberDecl;
298}
299
Chris Lattner10318b82008-03-16 00:19:01 +0000300/// ObjCAddInstanceVariablesToClassImpl - Checks for correctness of Instance
301/// Variables (Ivars) relative to what declared in @implementation;s class.
302/// Ivars into ObjCImplementationDecl's fields.
303///
304void ObjCImplementationDecl::ObjCAddInstanceVariablesToClassImpl(
305 ObjCIvarDecl **ivars, unsigned numIvars) {
306 NumIvars = numIvars;
307 if (numIvars) {
308 Ivars = new ObjCIvarDecl*[numIvars];
309 memcpy(Ivars, ivars, numIvars*sizeof(ObjCIvarDecl*));
310 }
311}
312
Steve Naroffab63fd62009-01-08 17:28:14 +0000313// Get the local instance method declared in this interface.
314// FIXME: handle overloading, instance & class methods can have the same name.
315ObjCMethodDecl *ObjCContainerDecl::getInstanceMethod(Selector Sel) const {
316 lookup_const_result MethodResult = lookup(Sel);
317 if (MethodResult.first)
318 return const_cast<ObjCMethodDecl*>(
319 dyn_cast<ObjCMethodDecl>(*MethodResult.first));
320 return 0;
321}
322
323// Get the local class method declared in this interface.
324ObjCMethodDecl *ObjCContainerDecl::getClassMethod(Selector Sel) const {
325 lookup_const_result MethodResult = lookup(Sel);
326 if (MethodResult.first)
327 return const_cast<ObjCMethodDecl*>(
328 dyn_cast<ObjCMethodDecl>(*MethodResult.first));
329 return 0;
330}
331
332unsigned ObjCContainerDecl::getNumInstanceMethods() const {
333 unsigned sum = 0;
334 for (instmeth_iterator I=instmeth_begin(), E=instmeth_end(); I != E; ++I)
335 sum++;
336 return sum;
337}
338unsigned ObjCContainerDecl::getNumClassMethods() const {
339 unsigned sum = 0;
340 for (classmeth_iterator I=classmeth_begin(), E=classmeth_end(); I != E; ++I)
341 sum++;
342 return sum;
343}
Steve Naroff56af2002009-01-11 01:06:09 +0000344unsigned ObjCContainerDecl::getNumProperties() const {
345 unsigned sum = 0;
346 for (prop_iterator I=prop_begin(), E=prop_end(); I != E; ++I)
347 sum++;
348 return sum;
349}
Steve Naroffab63fd62009-01-08 17:28:14 +0000350
Fariborz Jahanianef8a3df2008-04-21 19:04:53 +0000351/// FindPropertyDeclaration - Finds declaration of the property given its name
352/// in 'PropertyId' and returns it. It returns 0, if not found.
Steve Naroffdcf1e842009-01-11 12:47:58 +0000353/// FIXME: Convert to DeclContext lookup...
Fariborz Jahanianef8a3df2008-04-21 19:04:53 +0000354///
355ObjCPropertyDecl *
Steve Naroff451f83c2009-01-09 15:36:25 +0000356ObjCContainerDecl::FindPropertyDeclaration(IdentifierInfo *PropertyId) const {
357 for (prop_iterator I = prop_begin(), E = prop_end(); I != E; ++I) {
Fariborz Jahanianef8a3df2008-04-21 19:04:53 +0000358 ObjCPropertyDecl *property = *I;
359 if (property->getIdentifier() == PropertyId)
360 return property;
361 }
Fariborz Jahanianfaca5e22009-01-09 21:04:52 +0000362 const ObjCProtocolDecl *PID = dyn_cast<ObjCProtocolDecl>(this);
363 if (PID) {
364 for (ObjCProtocolDecl::protocol_iterator P = PID->protocol_begin(),
365 E = PID->protocol_end();
366 P != E; ++P)
367 if (ObjCPropertyDecl *property =
368 (*P)->FindPropertyDeclaration(PropertyId))
369 return property;
370 }
371
Fariborz Jahanian6b0ed6f2009-01-19 18:16:19 +0000372 if (const ObjCInterfaceDecl *OID = dyn_cast<ObjCInterfaceDecl>(this)) {
Steve Naroff451f83c2009-01-09 15:36:25 +0000373 // Look through categories.
374 for (ObjCCategoryDecl *Category = OID->getCategoryList();
375 Category; Category = Category->getNextClassCategory()) {
376 ObjCPropertyDecl *property = Category->FindPropertyDeclaration(PropertyId);
377 if (property)
378 return property;
379 }
380 // Look through protocols.
381 for (ObjCInterfaceDecl::protocol_iterator I = OID->protocol_begin(),
382 E = OID->protocol_end(); I != E; ++I) {
383 ObjCProtocolDecl *Protocol = *I;
384 ObjCPropertyDecl *property = Protocol->FindPropertyDeclaration(PropertyId);
385 if (property)
386 return property;
387 }
388 if (OID->getSuperClass())
389 return OID->getSuperClass()->FindPropertyDeclaration(PropertyId);
Steve Naroffd1f0eb42008-06-05 13:55:23 +0000390 }
Fariborz Jahanian6b0ed6f2009-01-19 18:16:19 +0000391 else if (const ObjCCategoryDecl *OCD = dyn_cast<ObjCCategoryDecl>(this)) {
392 // Look through protocols.
393 for (ObjCInterfaceDecl::protocol_iterator I = OCD->protocol_begin(),
394 E = OCD->protocol_end(); I != E; ++I) {
395 ObjCProtocolDecl *Protocol = *I;
396 ObjCPropertyDecl *property = Protocol->FindPropertyDeclaration(PropertyId);
397 if (property)
398 return property;
399 }
400 }
Steve Naroffd1f0eb42008-06-05 13:55:23 +0000401 return 0;
402}
403
Chris Lattner10318b82008-03-16 00:19:01 +0000404ObjCIvarDecl *ObjCInterfaceDecl::lookupInstanceVariable(
405 IdentifierInfo *ID, ObjCInterfaceDecl *&clsDeclared) {
406 ObjCInterfaceDecl* ClassDecl = this;
407 while (ClassDecl != NULL) {
408 for (ivar_iterator I = ClassDecl->ivar_begin(), E = ClassDecl->ivar_end();
409 I != E; ++I) {
410 if ((*I)->getIdentifier() == ID) {
411 clsDeclared = ClassDecl;
412 return *I;
413 }
414 }
415 ClassDecl = ClassDecl->getSuperClass();
416 }
417 return NULL;
418}
419
420/// lookupInstanceMethod - This method returns an instance method by looking in
421/// the class, its categories, and its super classes (using a linear search).
422ObjCMethodDecl *ObjCInterfaceDecl::lookupInstanceMethod(Selector Sel) {
423 ObjCInterfaceDecl* ClassDecl = this;
424 ObjCMethodDecl *MethodDecl = 0;
425
426 while (ClassDecl != NULL) {
427 if ((MethodDecl = ClassDecl->getInstanceMethod(Sel)))
428 return MethodDecl;
429
430 // Didn't find one yet - look through protocols.
Chris Lattner8bcb5252008-07-21 18:19:38 +0000431 const ObjCList<ObjCProtocolDecl> &Protocols =
432 ClassDecl->getReferencedProtocols();
433 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
434 E = Protocols.end(); I != E; ++I)
435 if ((MethodDecl = (*I)->getInstanceMethod(Sel)))
Chris Lattner10318b82008-03-16 00:19:01 +0000436 return MethodDecl;
Chris Lattner8bcb5252008-07-21 18:19:38 +0000437
Chris Lattner10318b82008-03-16 00:19:01 +0000438 // Didn't find one yet - now look through categories.
439 ObjCCategoryDecl *CatDecl = ClassDecl->getCategoryList();
440 while (CatDecl) {
441 if ((MethodDecl = CatDecl->getInstanceMethod(Sel)))
442 return MethodDecl;
Steve Naroffaf151802008-12-08 20:57:28 +0000443
444 // Didn't find one yet - look through protocols.
445 const ObjCList<ObjCProtocolDecl> &Protocols =
446 CatDecl->getReferencedProtocols();
447 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
448 E = Protocols.end(); I != E; ++I)
449 if ((MethodDecl = (*I)->getInstanceMethod(Sel)))
450 return MethodDecl;
Chris Lattner10318b82008-03-16 00:19:01 +0000451 CatDecl = CatDecl->getNextClassCategory();
452 }
453 ClassDecl = ClassDecl->getSuperClass();
454 }
455 return NULL;
456}
457
458// lookupClassMethod - This method returns a class method by looking in the
459// class, its categories, and its super classes (using a linear search).
460ObjCMethodDecl *ObjCInterfaceDecl::lookupClassMethod(Selector Sel) {
461 ObjCInterfaceDecl* ClassDecl = this;
462 ObjCMethodDecl *MethodDecl = 0;
463
464 while (ClassDecl != NULL) {
465 if ((MethodDecl = ClassDecl->getClassMethod(Sel)))
466 return MethodDecl;
467
468 // Didn't find one yet - look through protocols.
Chris Lattner0be08822008-07-21 21:32:27 +0000469 for (ObjCInterfaceDecl::protocol_iterator I = ClassDecl->protocol_begin(),
470 E = ClassDecl->protocol_end(); I != E; ++I)
Chris Lattner8bcb5252008-07-21 18:19:38 +0000471 if ((MethodDecl = (*I)->getClassMethod(Sel)))
Chris Lattner10318b82008-03-16 00:19:01 +0000472 return MethodDecl;
Chris Lattner0be08822008-07-21 21:32:27 +0000473
Chris Lattner10318b82008-03-16 00:19:01 +0000474 // Didn't find one yet - now look through categories.
475 ObjCCategoryDecl *CatDecl = ClassDecl->getCategoryList();
476 while (CatDecl) {
477 if ((MethodDecl = CatDecl->getClassMethod(Sel)))
478 return MethodDecl;
479 CatDecl = CatDecl->getNextClassCategory();
480 }
481 ClassDecl = ClassDecl->getSuperClass();
482 }
483 return NULL;
484}
485
Daniel Dunbardd24b9a2008-08-26 06:53:45 +0000486/// getInstanceMethod - This method returns an instance method by
487/// looking in the class implementation. Unlike interfaces, we don't
488/// look outside the implementation.
489ObjCMethodDecl *ObjCImplementationDecl::getInstanceMethod(Selector Sel) const {
Chris Lattner10318b82008-03-16 00:19:01 +0000490 for (instmeth_iterator I = instmeth_begin(), E = instmeth_end(); I != E; ++I)
491 if ((*I)->getSelector() == Sel)
492 return *I;
493 return NULL;
494}
495
Daniel Dunbardd24b9a2008-08-26 06:53:45 +0000496/// getClassMethod - This method returns a class method by looking in
497/// the class implementation. Unlike interfaces, we don't look outside
498/// the implementation.
499ObjCMethodDecl *ObjCImplementationDecl::getClassMethod(Selector Sel) const {
Chris Lattner10318b82008-03-16 00:19:01 +0000500 for (classmeth_iterator I = classmeth_begin(), E = classmeth_end();
501 I != E; ++I)
502 if ((*I)->getSelector() == Sel)
503 return *I;
504 return NULL;
505}
506
Fariborz Jahanian68342282008-12-05 22:32:48 +0000507/// FindPropertyImplDecl - This method looks up a previous ObjCPropertyImplDecl
508/// added to the list of those properties @synthesized/@dynamic in this
509/// @implementation block.
510///
511ObjCPropertyImplDecl *ObjCImplementationDecl::FindPropertyImplDecl(IdentifierInfo *Id) const {
512 for (propimpl_iterator i = propimpl_begin(), e = propimpl_end(); i != e; ++i) {
513 ObjCPropertyImplDecl *PID = *i;
514 if (PID->getPropertyDecl()->getIdentifier() == Id)
515 return PID;
516 }
517 return 0;
518}
519
520/// FindPropertyImplIvarDecl - This method lookup the ivar in the list of
Fariborz Jahanian17eb8882008-12-05 22:36:19 +0000521/// properties implemented in this @implementation block and returns the
522/// implemented property that uses it.
Fariborz Jahanian68342282008-12-05 22:32:48 +0000523///
524ObjCPropertyImplDecl *ObjCImplementationDecl::FindPropertyImplIvarDecl(IdentifierInfo *ivarId) const {
525 for (propimpl_iterator i = propimpl_begin(), e = propimpl_end(); i != e; ++i) {
526 ObjCPropertyImplDecl *PID = *i;
527 if (PID->getPropertyIvarDecl() &&
528 PID->getPropertyIvarDecl()->getIdentifier() == ivarId)
529 return PID;
530 }
531 return 0;
532}
533
534/// FindPropertyImplIvarDecl - This method lookup the ivar in the list of
Chris Lattner715e8482009-02-16 19:24:31 +0000535/// properties implemented in this category @implementation block and returns
536/// the implemented property that uses it.
Fariborz Jahanian68342282008-12-05 22:32:48 +0000537///
Chris Lattner715e8482009-02-16 19:24:31 +0000538ObjCPropertyImplDecl *ObjCCategoryImplDecl::
539FindPropertyImplIvarDecl(IdentifierInfo *ivarId) const {
540 for (propimpl_iterator i = propimpl_begin(), e = propimpl_end(); i != e; ++i){
Fariborz Jahanian68342282008-12-05 22:32:48 +0000541 ObjCPropertyImplDecl *PID = *i;
542 if (PID->getPropertyIvarDecl() &&
543 PID->getPropertyIvarDecl()->getIdentifier() == ivarId)
544 return PID;
545 }
546 return 0;
547}
548
549/// FindPropertyImplDecl - This method looks up a previous ObjCPropertyImplDecl
550/// added to the list of those properties @synthesized/@dynamic in this
551/// category @implementation block.
552///
Chris Lattner715e8482009-02-16 19:24:31 +0000553ObjCPropertyImplDecl *ObjCCategoryImplDecl::
554FindPropertyImplDecl(IdentifierInfo *Id) const {
555 for (propimpl_iterator i = propimpl_begin(), e = propimpl_end(); i != e; ++i){
Fariborz Jahanian68342282008-12-05 22:32:48 +0000556 ObjCPropertyImplDecl *PID = *i;
557 if (PID->getPropertyDecl()->getIdentifier() == Id)
558 return PID;
559 }
560 return 0;
561}
562
Chris Lattner10318b82008-03-16 00:19:01 +0000563// lookupInstanceMethod - This method returns an instance method by looking in
564// the class implementation. Unlike interfaces, we don't look outside the
565// implementation.
Daniel Dunbardd24b9a2008-08-26 06:53:45 +0000566ObjCMethodDecl *ObjCCategoryImplDecl::getInstanceMethod(Selector Sel) const {
Chris Lattner10318b82008-03-16 00:19:01 +0000567 for (instmeth_iterator I = instmeth_begin(), E = instmeth_end(); I != E; ++I)
568 if ((*I)->getSelector() == Sel)
569 return *I;
570 return NULL;
571}
572
573// lookupClassMethod - This method returns an instance method by looking in
574// the class implementation. Unlike interfaces, we don't look outside the
575// implementation.
Daniel Dunbardd24b9a2008-08-26 06:53:45 +0000576ObjCMethodDecl *ObjCCategoryImplDecl::getClassMethod(Selector Sel) const {
Chris Lattner10318b82008-03-16 00:19:01 +0000577 for (classmeth_iterator I = classmeth_begin(), E = classmeth_end();
578 I != E; ++I)
579 if ((*I)->getSelector() == Sel)
580 return *I;
581 return NULL;
582}
583
584// lookupInstanceMethod - Lookup a instance method in the protocol and protocols
585// it inherited.
586ObjCMethodDecl *ObjCProtocolDecl::lookupInstanceMethod(Selector Sel) {
587 ObjCMethodDecl *MethodDecl = NULL;
588
589 if ((MethodDecl = getInstanceMethod(Sel)))
590 return MethodDecl;
591
Chris Lattner0be08822008-07-21 21:32:27 +0000592 for (protocol_iterator I = protocol_begin(), E = protocol_end(); I != E; ++I)
Steve Naroff30fb1da2008-12-18 15:50:41 +0000593 if ((MethodDecl = (*I)->lookupInstanceMethod(Sel)))
Chris Lattner0be08822008-07-21 21:32:27 +0000594 return MethodDecl;
Chris Lattner10318b82008-03-16 00:19:01 +0000595 return NULL;
596}
597
598// lookupInstanceMethod - Lookup a class method in the protocol and protocols
599// it inherited.
600ObjCMethodDecl *ObjCProtocolDecl::lookupClassMethod(Selector Sel) {
601 ObjCMethodDecl *MethodDecl = NULL;
602
603 if ((MethodDecl = getClassMethod(Sel)))
604 return MethodDecl;
605
Chris Lattner0be08822008-07-21 21:32:27 +0000606 for (protocol_iterator I = protocol_begin(), E = protocol_end(); I != E; ++I)
Steve Naroff30fb1da2008-12-18 15:50:41 +0000607 if ((MethodDecl = (*I)->lookupClassMethod(Sel)))
Chris Lattner0be08822008-07-21 21:32:27 +0000608 return MethodDecl;
Chris Lattner10318b82008-03-16 00:19:01 +0000609 return NULL;
610}
611
612/// getSynthesizedMethodSize - Compute size of synthesized method name
613/// as done be the rewrite.
614///
615unsigned ObjCMethodDecl::getSynthesizedMethodSize() const {
616 // syntesized method name is a concatenation of -/+[class-name selector]
617 // Get length of this name.
618 unsigned length = 3; // _I_ or _C_
Chris Lattnerd120b9e2008-11-24 03:54:41 +0000619 length += getClassInterface()->getNameAsString().size()+1; // extra for _
Steve Naroff438be772009-01-08 19:41:02 +0000620 if (const ObjCCategoryImplDecl *CID =
621 dyn_cast<ObjCCategoryImplDecl>(getDeclContext()))
Chris Lattnerd120b9e2008-11-24 03:54:41 +0000622 length += CID->getNameAsString().size()+1;
Chris Lattner3a8f2942008-11-24 03:33:13 +0000623 length += getSelector().getAsString().size(); // selector name
Chris Lattner10318b82008-03-16 00:19:01 +0000624 return length;
625}
626
Chris Lattner052fbcd2008-04-06 05:25:03 +0000627ObjCInterfaceDecl *ObjCMethodDecl::getClassInterface() {
Steve Naroff438be772009-01-08 19:41:02 +0000628 if (ObjCInterfaceDecl *ID = dyn_cast<ObjCInterfaceDecl>(getDeclContext()))
Chris Lattner10318b82008-03-16 00:19:01 +0000629 return ID;
Steve Naroff438be772009-01-08 19:41:02 +0000630 if (ObjCCategoryDecl *CD = dyn_cast<ObjCCategoryDecl>(getDeclContext()))
Chris Lattner10318b82008-03-16 00:19:01 +0000631 return CD->getClassInterface();
632 if (ObjCImplementationDecl *IMD =
Steve Naroff438be772009-01-08 19:41:02 +0000633 dyn_cast<ObjCImplementationDecl>(getDeclContext()))
Chris Lattner10318b82008-03-16 00:19:01 +0000634 return IMD->getClassInterface();
Steve Naroff438be772009-01-08 19:41:02 +0000635 if (ObjCCategoryImplDecl *CID =
636 dyn_cast<ObjCCategoryImplDecl>(getDeclContext()))
Chris Lattner10318b82008-03-16 00:19:01 +0000637 return CID->getClassInterface();
638 assert(false && "unknown method context");
639 return 0;
640}
Chris Lattner44859612008-03-17 01:19:02 +0000641
Fariborz Jahaniandc0569e2008-04-23 00:06:01 +0000642ObjCPropertyImplDecl *ObjCPropertyImplDecl::Create(ASTContext &C,
Douglas Gregor6e4fa2c2009-01-09 00:49:46 +0000643 DeclContext *DC,
Fariborz Jahaniandc0569e2008-04-23 00:06:01 +0000644 SourceLocation atLoc,
645 SourceLocation L,
646 ObjCPropertyDecl *property,
Daniel Dunbar14117fc2008-08-26 04:47:31 +0000647 Kind PK,
Fariborz Jahaniandc0569e2008-04-23 00:06:01 +0000648 ObjCIvarDecl *ivar) {
Steve Naroff5abb0282009-01-27 21:25:57 +0000649 return new (C) ObjCPropertyImplDecl(DC, atLoc, L, property, PK, ivar);
Fariborz Jahaniandc0569e2008-04-23 00:06:01 +0000650}
Chris Lattner44859612008-03-17 01:19:02 +0000651
Chris Lattnereee57c02008-04-04 06:12:32 +0000652