blob: 1651df91413ee121b21677721d2d9aa7817d0c97 [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
Chris Lattner9408eb12009-02-20 06:23:21 +000045 ParamInfo.clear();
Chris Lattnerae538882009-02-20 05:54:35 +000046
Ted Kremenek8c945b12008-06-06 16:45:15 +000047 Decl::Destroy(C);
48}
49
Chris Lattner3e27e632009-02-20 06:03:09 +000050
Chris Lattnereee57c02008-04-04 06:12:32 +000051ObjCInterfaceDecl *ObjCInterfaceDecl::Create(ASTContext &C,
Douglas Gregor6e4fa2c2009-01-09 00:49:46 +000052 DeclContext *DC,
Chris Lattnereee57c02008-04-04 06:12:32 +000053 SourceLocation atLoc,
Steve Naroff7c371742008-04-11 19:35:35 +000054 IdentifierInfo *Id,
55 SourceLocation ClassLoc,
Chris Lattner0db541b2008-03-16 01:15:50 +000056 bool ForwardDecl, bool isInternal){
Steve Naroff5abb0282009-01-27 21:25:57 +000057 return new (C) ObjCInterfaceDecl(DC, atLoc, Id, ClassLoc, ForwardDecl,
Chris Lattner0db541b2008-03-16 01:15:50 +000058 isInternal);
59}
60
Chris Lattner3e27e632009-02-20 06:03:09 +000061ObjCInterfaceDecl::
62ObjCInterfaceDecl(DeclContext *DC, SourceLocation atLoc, IdentifierInfo *Id,
63 SourceLocation CLoc, bool FD, bool isInternal)
64 : ObjCContainerDecl(ObjCInterface, DC, atLoc, Id),
Chris Lattner922132e2009-02-20 06:10:45 +000065 TypeForDecl(0), SuperClass(0),
Chris Lattner3e27e632009-02-20 06:03:09 +000066 CategoryList(0), ForwardDecl(FD), InternalInterface(isInternal),
67 ClassLoc(CLoc) {
Steve Naroffd9d4d502009-01-07 17:57:40 +000068}
69
Chris Lattner3e27e632009-02-20 06:03:09 +000070void ObjCInterfaceDecl::Destroy(ASTContext &C) {
Ted Kremenek8c945b12008-06-06 16:45:15 +000071 for (ivar_iterator I=ivar_begin(), E=ivar_end(); I!=E; ++I)
72 if (*I) (*I)->Destroy(C);
73
Chris Lattner922132e2009-02-20 06:10:45 +000074 IVars.clear();
Chris Lattner3e27e632009-02-20 06:03:09 +000075 // FIXME: CategoryList?
76
Ted Kremenek22db1602008-06-06 17:21:42 +000077 // FIXME: Because there is no clear ownership
78 // role between ObjCInterfaceDecls and the ObjCPropertyDecls that they
79 // reference, we destroy ObjCPropertyDecls in ~TranslationUnit.
Ted Kremenek8c945b12008-06-06 16:45:15 +000080 Decl::Destroy(C);
81}
82
83
Argiris Kirtzidis96e79bf2009-02-17 20:20:37 +000084ObjCIvarDecl *ObjCIvarDecl::Create(ASTContext &C, DeclContext *DC,
85 SourceLocation L, IdentifierInfo *Id,
86 QualType T, AccessControl ac, Expr *BW) {
87 return new (C) ObjCIvarDecl(DC, L, Id, T, ac, BW);
Chris Lattner114add62008-03-16 00:49:28 +000088}
89
Ted Kremeneke5bedfe2008-08-20 03:26:33 +000090
91ObjCAtDefsFieldDecl
Douglas Gregor8acb7272008-12-11 16:49:14 +000092*ObjCAtDefsFieldDecl::Create(ASTContext &C, DeclContext *DC, SourceLocation L,
Ted Kremeneke5bedfe2008-08-20 03:26:33 +000093 IdentifierInfo *Id, QualType T, Expr *BW) {
Steve Naroff5abb0282009-01-27 21:25:57 +000094 return new (C) ObjCAtDefsFieldDecl(DC, L, Id, T, BW);
Ted Kremeneke5bedfe2008-08-20 03:26:33 +000095}
96
97void ObjCAtDefsFieldDecl::Destroy(ASTContext& C) {
98 this->~ObjCAtDefsFieldDecl();
Steve Naroff5abb0282009-01-27 21:25:57 +000099 C.Deallocate((void *)this);
Ted Kremeneke5bedfe2008-08-20 03:26:33 +0000100}
101
Douglas Gregor6e4fa2c2009-01-09 00:49:46 +0000102ObjCProtocolDecl *ObjCProtocolDecl::Create(ASTContext &C, DeclContext *DC,
Chris Lattnereee57c02008-04-04 06:12:32 +0000103 SourceLocation L,
Chris Lattner7afba9c2008-03-16 20:19:15 +0000104 IdentifierInfo *Id) {
Steve Naroff5abb0282009-01-27 21:25:57 +0000105 return new (C) ObjCProtocolDecl(DC, L, Id);
Chris Lattner180f7e22008-03-16 01:23:04 +0000106}
107
Chris Lattnerae538882009-02-20 05:54:35 +0000108void ObjCProtocolDecl::Destroy(ASTContext &C) {
Ted Kremenekc906e5e2008-06-06 19:48:57 +0000109 delete [] PropertyDecl;
Chris Lattnerae538882009-02-20 05:54:35 +0000110 PropertyDecl = 0;
111 ObjCContainerDecl::Destroy(C);
Ted Kremenekc906e5e2008-06-06 19:48:57 +0000112}
113
Ted Kremenekc906e5e2008-06-06 19:48:57 +0000114
Chris Lattnerae538882009-02-20 05:54:35 +0000115
116
Douglas Gregor6e4fa2c2009-01-09 00:49:46 +0000117ObjCClassDecl *ObjCClassDecl::Create(ASTContext &C, DeclContext *DC,
Chris Lattnereee57c02008-04-04 06:12:32 +0000118 SourceLocation L,
Chris Lattnere29dc832008-03-16 20:34:23 +0000119 ObjCInterfaceDecl **Elts, unsigned nElts) {
Steve Naroff5abb0282009-01-27 21:25:57 +0000120 return new (C) ObjCClassDecl(DC, L, Elts, nElts);
Chris Lattnere29dc832008-03-16 20:34:23 +0000121}
122
Chris Lattner3e27e632009-02-20 06:03:09 +0000123ObjCClassDecl::ObjCClassDecl(DeclContext *DC, SourceLocation L,
124 ObjCInterfaceDecl **Elts, unsigned nElts)
125 : Decl(ObjCClass, DC, L) {
126 if (nElts) {
127 ForwardDecls = new ObjCInterfaceDecl*[nElts];
128 memcpy(ForwardDecls, Elts, nElts*sizeof(ObjCInterfaceDecl*));
129 } else {
130 ForwardDecls = 0;
131 }
132 NumForwardDecls = nElts;
Ted Kremenekff291622008-06-06 20:11:53 +0000133}
134
Chris Lattner3e27e632009-02-20 06:03:09 +0000135void ObjCClassDecl::Destroy(ASTContext &C) {
Ted Kremenekff291622008-06-06 20:11:53 +0000136
137 // FIXME: There is no clear ownership policy now for referenced
138 // ObjCInterfaceDecls. Some of them can be forward declarations that
139 // are never later defined (in which case the ObjCClassDecl owns them)
140 // or the ObjCInterfaceDecl later becomes a real definition later. Ideally
141 // we should have separate objects for forward declarations and definitions,
142 // obviating this problem. Because of this situation, referenced
143 // ObjCInterfaceDecls are destroyed in ~TranslationUnit.
144
Chris Lattner3e27e632009-02-20 06:03:09 +0000145 delete [] ForwardDecls;
146 ForwardDecls = 0;
147
Ted Kremenekff291622008-06-06 20:11:53 +0000148 Decl::Destroy(C);
149}
150
Chris Lattnere29dc832008-03-16 20:34:23 +0000151ObjCForwardProtocolDecl *
Douglas Gregor6e4fa2c2009-01-09 00:49:46 +0000152ObjCForwardProtocolDecl::Create(ASTContext &C, DeclContext *DC,
Chris Lattnereee57c02008-04-04 06:12:32 +0000153 SourceLocation L,
Chris Lattnere29dc832008-03-16 20:34:23 +0000154 ObjCProtocolDecl **Elts, unsigned NumElts) {
Steve Naroff5abb0282009-01-27 21:25:57 +0000155 return new (C) ObjCForwardProtocolDecl(DC, L, Elts, NumElts);
Chris Lattnere29dc832008-03-16 20:34:23 +0000156}
157
Chris Lattner3e27e632009-02-20 06:03:09 +0000158ObjCForwardProtocolDecl::
159ObjCForwardProtocolDecl(DeclContext *DC, SourceLocation L,
160 ObjCProtocolDecl **Elts, unsigned nElts)
161 : Decl(ObjCForwardProtocol, DC, L) {
162 NumReferencedProtocols = nElts;
163 if (nElts) {
164 ReferencedProtocols = new ObjCProtocolDecl*[nElts];
165 memcpy(ReferencedProtocols, Elts, nElts*sizeof(ObjCProtocolDecl*));
166 } else {
167 ReferencedProtocols = 0;
168 }
169}
170
171void ObjCForwardProtocolDecl::Destroy(ASTContext &C) {
Ted Kremenek1e5e0bf2008-06-06 21:05:33 +0000172 delete [] ReferencedProtocols;
Chris Lattner3e27e632009-02-20 06:03:09 +0000173 ReferencedProtocols = 0;
Ted Kremenek1e5e0bf2008-06-06 21:05:33 +0000174}
175
Douglas Gregor6e4fa2c2009-01-09 00:49:46 +0000176ObjCCategoryDecl *ObjCCategoryDecl::Create(ASTContext &C, DeclContext *DC,
Chris Lattnereee57c02008-04-04 06:12:32 +0000177 SourceLocation L,
Chris Lattnere29dc832008-03-16 20:34:23 +0000178 IdentifierInfo *Id) {
Steve Naroff5abb0282009-01-27 21:25:57 +0000179 return new (C) ObjCCategoryDecl(DC, L, Id);
Chris Lattnere29dc832008-03-16 20:34:23 +0000180}
181
Chris Lattner1b6de332008-03-16 20:53:07 +0000182ObjCCategoryImplDecl *
Douglas Gregor6e4fa2c2009-01-09 00:49:46 +0000183ObjCCategoryImplDecl::Create(ASTContext &C, DeclContext *DC,
Chris Lattnereee57c02008-04-04 06:12:32 +0000184 SourceLocation L,IdentifierInfo *Id,
Chris Lattner1b6de332008-03-16 20:53:07 +0000185 ObjCInterfaceDecl *ClassInterface) {
Steve Naroff5abb0282009-01-27 21:25:57 +0000186 return new (C) ObjCCategoryImplDecl(DC, L, Id, ClassInterface);
Chris Lattner1b6de332008-03-16 20:53:07 +0000187}
188
189ObjCImplementationDecl *
Douglas Gregor6e4fa2c2009-01-09 00:49:46 +0000190ObjCImplementationDecl::Create(ASTContext &C, DeclContext *DC,
Chris Lattnereee57c02008-04-04 06:12:32 +0000191 SourceLocation L,
Chris Lattner1b6de332008-03-16 20:53:07 +0000192 ObjCInterfaceDecl *ClassInterface,
193 ObjCInterfaceDecl *SuperDecl) {
Steve Naroff5abb0282009-01-27 21:25:57 +0000194 return new (C) ObjCImplementationDecl(DC, L, ClassInterface, SuperDecl);
Chris Lattner1b6de332008-03-16 20:53:07 +0000195}
Chris Lattner10318b82008-03-16 00:19:01 +0000196
Chris Lattner2d1c4312008-03-16 21:17:37 +0000197ObjCCompatibleAliasDecl *
Douglas Gregor6e4fa2c2009-01-09 00:49:46 +0000198ObjCCompatibleAliasDecl::Create(ASTContext &C, DeclContext *DC,
Chris Lattnereee57c02008-04-04 06:12:32 +0000199 SourceLocation L,
Chris Lattner2d1c4312008-03-16 21:17:37 +0000200 IdentifierInfo *Id,
201 ObjCInterfaceDecl* AliasedClass) {
Steve Naroff5abb0282009-01-27 21:25:57 +0000202 return new (C) ObjCCompatibleAliasDecl(DC, L, Id, AliasedClass);
Chris Lattner2d1c4312008-03-16 21:17:37 +0000203}
204
Douglas Gregor6e4fa2c2009-01-09 00:49:46 +0000205ObjCPropertyDecl *ObjCPropertyDecl::Create(ASTContext &C, DeclContext *DC,
Fariborz Jahaniane7071722008-04-11 23:40:25 +0000206 SourceLocation L,
Fariborz Jahanian0ceb4be2008-04-14 23:36:35 +0000207 IdentifierInfo *Id,
Fariborz Jahanian4aa72a72008-05-05 18:51:55 +0000208 QualType T,
209 PropertyControl propControl) {
Steve Naroff5abb0282009-01-27 21:25:57 +0000210 return new (C) ObjCPropertyDecl(DC, L, Id, T);
Chris Lattner2d1c4312008-03-16 21:17:37 +0000211}
212
Chris Lattner10318b82008-03-16 00:19:01 +0000213//===----------------------------------------------------------------------===//
214// Objective-C Decl Implementation
215//===----------------------------------------------------------------------===//
216
Fariborz Jahanian91dd9d32008-12-09 20:23:04 +0000217void ObjCMethodDecl::createImplicitParams(ASTContext &Context,
218 const ObjCInterfaceDecl *OID) {
Daniel Dunbar88116372008-08-26 06:08:30 +0000219 QualType selfTy;
Douglas Gregor5d764842009-01-09 17:18:27 +0000220 if (isInstanceMethod()) {
Daniel Dunbar88116372008-08-26 06:08:30 +0000221 // There may be no interface context due to error in declaration
222 // of the interface (which has been reported). Recover gracefully.
Fariborz Jahanian91dd9d32008-12-09 20:23:04 +0000223 if (OID) {
224 selfTy = Context.getObjCInterfaceType(const_cast<ObjCInterfaceDecl *>(OID));
Daniel Dunbar88116372008-08-26 06:08:30 +0000225 selfTy = Context.getPointerType(selfTy);
226 } else {
227 selfTy = Context.getObjCIdType();
228 }
229 } else // we have a factory method.
230 selfTy = Context.getObjCClassType();
231
232 SelfDecl = ImplicitParamDecl::Create(Context, this,
233 SourceLocation(),
234 &Context.Idents.get("self"),
Douglas Gregoraf8ad2b2009-01-20 01:17:11 +0000235 selfTy);
Daniel Dunbar88116372008-08-26 06:08:30 +0000236
237 CmdDecl = ImplicitParamDecl::Create(Context, this,
238 SourceLocation(),
239 &Context.Idents.get("_cmd"),
Douglas Gregoraf8ad2b2009-01-20 01:17:11 +0000240 Context.getObjCSelType());
Daniel Dunbar88116372008-08-26 06:08:30 +0000241}
242
Fariborz Jahanianef8a3df2008-04-21 19:04:53 +0000243/// FindCategoryDeclaration - Finds category declaration in the list of
244/// categories for this class and returns it. Name of the category is passed
245/// in 'CategoryId'. If category not found, return 0;
246///
247ObjCCategoryDecl *
248 ObjCInterfaceDecl::FindCategoryDeclaration(IdentifierInfo *CategoryId) const {
249 for (ObjCCategoryDecl *Category = getCategoryList();
250 Category; Category = Category->getNextClassCategory())
251 if (Category->getIdentifier() == CategoryId)
252 return Category;
253 return 0;
254}
255
Fariborz Jahanian09772392008-12-13 22:20:28 +0000256/// lookupFieldDeclForIvar - looks up a field decl' in the laid out
257/// storage which matches this 'ivar'.
258///
259FieldDecl *ObjCInterfaceDecl::lookupFieldDeclForIvar(ASTContext &Context,
Fariborz Jahanian86008c02008-12-15 20:35:07 +0000260 const ObjCIvarDecl *ivar) {
Fariborz Jahanian0556b152008-12-17 21:40:49 +0000261 const RecordDecl *RecordForDecl = Context.addRecordToClass(this);
Fariborz Jahanian09772392008-12-13 22:20:28 +0000262 assert(RecordForDecl && "lookupFieldDeclForIvar no storage for class");
263 DeclarationName Member = ivar->getDeclName();
Fariborz Jahanian0556b152008-12-17 21:40:49 +0000264 DeclContext::lookup_result Lookup = (const_cast< RecordDecl *>(RecordForDecl))
Steve Naroffab63fd62009-01-08 17:28:14 +0000265 ->lookup(Member);
Fariborz Jahanian09772392008-12-13 22:20:28 +0000266 assert((Lookup.first != Lookup.second) && "field decl not found");
267 FieldDecl *MemberDecl = dyn_cast<FieldDecl>(*Lookup.first);
268 assert(MemberDecl && "field decl not found");
269 return MemberDecl;
270}
271
Chris Lattner10318b82008-03-16 00:19:01 +0000272/// ObjCAddInstanceVariablesToClassImpl - Checks for correctness of Instance
273/// Variables (Ivars) relative to what declared in @implementation;s class.
274/// Ivars into ObjCImplementationDecl's fields.
275///
276void ObjCImplementationDecl::ObjCAddInstanceVariablesToClassImpl(
277 ObjCIvarDecl **ivars, unsigned numIvars) {
278 NumIvars = numIvars;
279 if (numIvars) {
280 Ivars = new ObjCIvarDecl*[numIvars];
281 memcpy(Ivars, ivars, numIvars*sizeof(ObjCIvarDecl*));
282 }
283}
284
Steve Naroffab63fd62009-01-08 17:28:14 +0000285// Get the local instance method declared in this interface.
286// FIXME: handle overloading, instance & class methods can have the same name.
287ObjCMethodDecl *ObjCContainerDecl::getInstanceMethod(Selector Sel) const {
288 lookup_const_result MethodResult = lookup(Sel);
289 if (MethodResult.first)
290 return const_cast<ObjCMethodDecl*>(
291 dyn_cast<ObjCMethodDecl>(*MethodResult.first));
292 return 0;
293}
294
295// Get the local class method declared in this interface.
296ObjCMethodDecl *ObjCContainerDecl::getClassMethod(Selector Sel) const {
297 lookup_const_result MethodResult = lookup(Sel);
298 if (MethodResult.first)
299 return const_cast<ObjCMethodDecl*>(
300 dyn_cast<ObjCMethodDecl>(*MethodResult.first));
301 return 0;
302}
303
304unsigned ObjCContainerDecl::getNumInstanceMethods() const {
305 unsigned sum = 0;
306 for (instmeth_iterator I=instmeth_begin(), E=instmeth_end(); I != E; ++I)
307 sum++;
308 return sum;
309}
310unsigned ObjCContainerDecl::getNumClassMethods() const {
311 unsigned sum = 0;
312 for (classmeth_iterator I=classmeth_begin(), E=classmeth_end(); I != E; ++I)
313 sum++;
314 return sum;
315}
Steve Naroff56af2002009-01-11 01:06:09 +0000316unsigned ObjCContainerDecl::getNumProperties() const {
317 unsigned sum = 0;
318 for (prop_iterator I=prop_begin(), E=prop_end(); I != E; ++I)
319 sum++;
320 return sum;
321}
Steve Naroffab63fd62009-01-08 17:28:14 +0000322
Fariborz Jahanianef8a3df2008-04-21 19:04:53 +0000323/// FindPropertyDeclaration - Finds declaration of the property given its name
324/// in 'PropertyId' and returns it. It returns 0, if not found.
Steve Naroffdcf1e842009-01-11 12:47:58 +0000325/// FIXME: Convert to DeclContext lookup...
Fariborz Jahanianef8a3df2008-04-21 19:04:53 +0000326///
327ObjCPropertyDecl *
Steve Naroff451f83c2009-01-09 15:36:25 +0000328ObjCContainerDecl::FindPropertyDeclaration(IdentifierInfo *PropertyId) const {
329 for (prop_iterator I = prop_begin(), E = prop_end(); I != E; ++I) {
Fariborz Jahanianef8a3df2008-04-21 19:04:53 +0000330 ObjCPropertyDecl *property = *I;
331 if (property->getIdentifier() == PropertyId)
332 return property;
333 }
Fariborz Jahanianfaca5e22009-01-09 21:04:52 +0000334 const ObjCProtocolDecl *PID = dyn_cast<ObjCProtocolDecl>(this);
335 if (PID) {
336 for (ObjCProtocolDecl::protocol_iterator P = PID->protocol_begin(),
337 E = PID->protocol_end();
338 P != E; ++P)
339 if (ObjCPropertyDecl *property =
340 (*P)->FindPropertyDeclaration(PropertyId))
341 return property;
342 }
343
Fariborz Jahanian6b0ed6f2009-01-19 18:16:19 +0000344 if (const ObjCInterfaceDecl *OID = dyn_cast<ObjCInterfaceDecl>(this)) {
Steve Naroff451f83c2009-01-09 15:36:25 +0000345 // Look through categories.
346 for (ObjCCategoryDecl *Category = OID->getCategoryList();
347 Category; Category = Category->getNextClassCategory()) {
348 ObjCPropertyDecl *property = Category->FindPropertyDeclaration(PropertyId);
349 if (property)
350 return property;
351 }
352 // Look through protocols.
353 for (ObjCInterfaceDecl::protocol_iterator I = OID->protocol_begin(),
354 E = OID->protocol_end(); I != E; ++I) {
355 ObjCProtocolDecl *Protocol = *I;
356 ObjCPropertyDecl *property = Protocol->FindPropertyDeclaration(PropertyId);
357 if (property)
358 return property;
359 }
360 if (OID->getSuperClass())
361 return OID->getSuperClass()->FindPropertyDeclaration(PropertyId);
Steve Naroffd1f0eb42008-06-05 13:55:23 +0000362 }
Fariborz Jahanian6b0ed6f2009-01-19 18:16:19 +0000363 else if (const ObjCCategoryDecl *OCD = dyn_cast<ObjCCategoryDecl>(this)) {
364 // Look through protocols.
365 for (ObjCInterfaceDecl::protocol_iterator I = OCD->protocol_begin(),
366 E = OCD->protocol_end(); I != E; ++I) {
367 ObjCProtocolDecl *Protocol = *I;
368 ObjCPropertyDecl *property = Protocol->FindPropertyDeclaration(PropertyId);
369 if (property)
370 return property;
371 }
372 }
Steve Naroffd1f0eb42008-06-05 13:55:23 +0000373 return 0;
374}
375
Chris Lattner10318b82008-03-16 00:19:01 +0000376ObjCIvarDecl *ObjCInterfaceDecl::lookupInstanceVariable(
377 IdentifierInfo *ID, ObjCInterfaceDecl *&clsDeclared) {
378 ObjCInterfaceDecl* ClassDecl = this;
379 while (ClassDecl != NULL) {
380 for (ivar_iterator I = ClassDecl->ivar_begin(), E = ClassDecl->ivar_end();
381 I != E; ++I) {
382 if ((*I)->getIdentifier() == ID) {
383 clsDeclared = ClassDecl;
384 return *I;
385 }
386 }
387 ClassDecl = ClassDecl->getSuperClass();
388 }
389 return NULL;
390}
391
392/// lookupInstanceMethod - This method returns an instance method by looking in
393/// the class, its categories, and its super classes (using a linear search).
394ObjCMethodDecl *ObjCInterfaceDecl::lookupInstanceMethod(Selector Sel) {
395 ObjCInterfaceDecl* ClassDecl = this;
396 ObjCMethodDecl *MethodDecl = 0;
397
398 while (ClassDecl != NULL) {
399 if ((MethodDecl = ClassDecl->getInstanceMethod(Sel)))
400 return MethodDecl;
401
402 // Didn't find one yet - look through protocols.
Chris Lattner8bcb5252008-07-21 18:19:38 +0000403 const ObjCList<ObjCProtocolDecl> &Protocols =
404 ClassDecl->getReferencedProtocols();
405 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
406 E = Protocols.end(); I != E; ++I)
407 if ((MethodDecl = (*I)->getInstanceMethod(Sel)))
Chris Lattner10318b82008-03-16 00:19:01 +0000408 return MethodDecl;
Chris Lattner8bcb5252008-07-21 18:19:38 +0000409
Chris Lattner10318b82008-03-16 00:19:01 +0000410 // Didn't find one yet - now look through categories.
411 ObjCCategoryDecl *CatDecl = ClassDecl->getCategoryList();
412 while (CatDecl) {
413 if ((MethodDecl = CatDecl->getInstanceMethod(Sel)))
414 return MethodDecl;
Steve Naroffaf151802008-12-08 20:57:28 +0000415
416 // Didn't find one yet - look through protocols.
417 const ObjCList<ObjCProtocolDecl> &Protocols =
418 CatDecl->getReferencedProtocols();
419 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
420 E = Protocols.end(); I != E; ++I)
421 if ((MethodDecl = (*I)->getInstanceMethod(Sel)))
422 return MethodDecl;
Chris Lattner10318b82008-03-16 00:19:01 +0000423 CatDecl = CatDecl->getNextClassCategory();
424 }
425 ClassDecl = ClassDecl->getSuperClass();
426 }
427 return NULL;
428}
429
430// lookupClassMethod - This method returns a class method by looking in the
431// class, its categories, and its super classes (using a linear search).
432ObjCMethodDecl *ObjCInterfaceDecl::lookupClassMethod(Selector Sel) {
433 ObjCInterfaceDecl* ClassDecl = this;
434 ObjCMethodDecl *MethodDecl = 0;
435
436 while (ClassDecl != NULL) {
437 if ((MethodDecl = ClassDecl->getClassMethod(Sel)))
438 return MethodDecl;
439
440 // Didn't find one yet - look through protocols.
Chris Lattner0be08822008-07-21 21:32:27 +0000441 for (ObjCInterfaceDecl::protocol_iterator I = ClassDecl->protocol_begin(),
442 E = ClassDecl->protocol_end(); I != E; ++I)
Chris Lattner8bcb5252008-07-21 18:19:38 +0000443 if ((MethodDecl = (*I)->getClassMethod(Sel)))
Chris Lattner10318b82008-03-16 00:19:01 +0000444 return MethodDecl;
Chris Lattner0be08822008-07-21 21:32:27 +0000445
Chris Lattner10318b82008-03-16 00:19:01 +0000446 // Didn't find one yet - now look through categories.
447 ObjCCategoryDecl *CatDecl = ClassDecl->getCategoryList();
448 while (CatDecl) {
449 if ((MethodDecl = CatDecl->getClassMethod(Sel)))
450 return MethodDecl;
451 CatDecl = CatDecl->getNextClassCategory();
452 }
453 ClassDecl = ClassDecl->getSuperClass();
454 }
455 return NULL;
456}
457
Daniel Dunbardd24b9a2008-08-26 06:53:45 +0000458/// getInstanceMethod - This method returns an instance method by
459/// looking in the class implementation. Unlike interfaces, we don't
460/// look outside the implementation.
461ObjCMethodDecl *ObjCImplementationDecl::getInstanceMethod(Selector Sel) const {
Chris Lattner10318b82008-03-16 00:19:01 +0000462 for (instmeth_iterator I = instmeth_begin(), E = instmeth_end(); I != E; ++I)
463 if ((*I)->getSelector() == Sel)
464 return *I;
465 return NULL;
466}
467
Daniel Dunbardd24b9a2008-08-26 06:53:45 +0000468/// getClassMethod - This method returns a class method by looking in
469/// the class implementation. Unlike interfaces, we don't look outside
470/// the implementation.
471ObjCMethodDecl *ObjCImplementationDecl::getClassMethod(Selector Sel) const {
Chris Lattner10318b82008-03-16 00:19:01 +0000472 for (classmeth_iterator I = classmeth_begin(), E = classmeth_end();
473 I != E; ++I)
474 if ((*I)->getSelector() == Sel)
475 return *I;
476 return NULL;
477}
478
Fariborz Jahanian68342282008-12-05 22:32:48 +0000479/// FindPropertyImplDecl - This method looks up a previous ObjCPropertyImplDecl
480/// added to the list of those properties @synthesized/@dynamic in this
481/// @implementation block.
482///
483ObjCPropertyImplDecl *ObjCImplementationDecl::FindPropertyImplDecl(IdentifierInfo *Id) const {
484 for (propimpl_iterator i = propimpl_begin(), e = propimpl_end(); i != e; ++i) {
485 ObjCPropertyImplDecl *PID = *i;
486 if (PID->getPropertyDecl()->getIdentifier() == Id)
487 return PID;
488 }
489 return 0;
490}
491
492/// FindPropertyImplIvarDecl - This method lookup the ivar in the list of
Fariborz Jahanian17eb8882008-12-05 22:36:19 +0000493/// properties implemented in this @implementation block and returns the
494/// implemented property that uses it.
Fariborz Jahanian68342282008-12-05 22:32:48 +0000495///
496ObjCPropertyImplDecl *ObjCImplementationDecl::FindPropertyImplIvarDecl(IdentifierInfo *ivarId) const {
497 for (propimpl_iterator i = propimpl_begin(), e = propimpl_end(); i != e; ++i) {
498 ObjCPropertyImplDecl *PID = *i;
499 if (PID->getPropertyIvarDecl() &&
500 PID->getPropertyIvarDecl()->getIdentifier() == ivarId)
501 return PID;
502 }
503 return 0;
504}
505
506/// FindPropertyImplIvarDecl - This method lookup the ivar in the list of
Chris Lattner715e8482009-02-16 19:24:31 +0000507/// properties implemented in this category @implementation block and returns
508/// the implemented property that uses it.
Fariborz Jahanian68342282008-12-05 22:32:48 +0000509///
Chris Lattner715e8482009-02-16 19:24:31 +0000510ObjCPropertyImplDecl *ObjCCategoryImplDecl::
511FindPropertyImplIvarDecl(IdentifierInfo *ivarId) const {
512 for (propimpl_iterator i = propimpl_begin(), e = propimpl_end(); i != e; ++i){
Fariborz Jahanian68342282008-12-05 22:32:48 +0000513 ObjCPropertyImplDecl *PID = *i;
514 if (PID->getPropertyIvarDecl() &&
515 PID->getPropertyIvarDecl()->getIdentifier() == ivarId)
516 return PID;
517 }
518 return 0;
519}
520
521/// FindPropertyImplDecl - This method looks up a previous ObjCPropertyImplDecl
522/// added to the list of those properties @synthesized/@dynamic in this
523/// category @implementation block.
524///
Chris Lattner715e8482009-02-16 19:24:31 +0000525ObjCPropertyImplDecl *ObjCCategoryImplDecl::
526FindPropertyImplDecl(IdentifierInfo *Id) const {
527 for (propimpl_iterator i = propimpl_begin(), e = propimpl_end(); i != e; ++i){
Fariborz Jahanian68342282008-12-05 22:32:48 +0000528 ObjCPropertyImplDecl *PID = *i;
529 if (PID->getPropertyDecl()->getIdentifier() == Id)
530 return PID;
531 }
532 return 0;
533}
534
Chris Lattner10318b82008-03-16 00:19:01 +0000535// lookupInstanceMethod - This method returns an instance method by looking in
536// the class implementation. Unlike interfaces, we don't look outside the
537// implementation.
Daniel Dunbardd24b9a2008-08-26 06:53:45 +0000538ObjCMethodDecl *ObjCCategoryImplDecl::getInstanceMethod(Selector Sel) const {
Chris Lattner10318b82008-03-16 00:19:01 +0000539 for (instmeth_iterator I = instmeth_begin(), E = instmeth_end(); I != E; ++I)
540 if ((*I)->getSelector() == Sel)
541 return *I;
542 return NULL;
543}
544
545// lookupClassMethod - This method returns an instance method by looking in
546// the class implementation. Unlike interfaces, we don't look outside the
547// implementation.
Daniel Dunbardd24b9a2008-08-26 06:53:45 +0000548ObjCMethodDecl *ObjCCategoryImplDecl::getClassMethod(Selector Sel) const {
Chris Lattner10318b82008-03-16 00:19:01 +0000549 for (classmeth_iterator I = classmeth_begin(), E = classmeth_end();
550 I != E; ++I)
551 if ((*I)->getSelector() == Sel)
552 return *I;
553 return NULL;
554}
555
556// lookupInstanceMethod - Lookup a instance method in the protocol and protocols
557// it inherited.
558ObjCMethodDecl *ObjCProtocolDecl::lookupInstanceMethod(Selector Sel) {
559 ObjCMethodDecl *MethodDecl = NULL;
560
561 if ((MethodDecl = getInstanceMethod(Sel)))
562 return MethodDecl;
563
Chris Lattner0be08822008-07-21 21:32:27 +0000564 for (protocol_iterator I = protocol_begin(), E = protocol_end(); I != E; ++I)
Steve Naroff30fb1da2008-12-18 15:50:41 +0000565 if ((MethodDecl = (*I)->lookupInstanceMethod(Sel)))
Chris Lattner0be08822008-07-21 21:32:27 +0000566 return MethodDecl;
Chris Lattner10318b82008-03-16 00:19:01 +0000567 return NULL;
568}
569
570// lookupInstanceMethod - Lookup a class method in the protocol and protocols
571// it inherited.
572ObjCMethodDecl *ObjCProtocolDecl::lookupClassMethod(Selector Sel) {
573 ObjCMethodDecl *MethodDecl = NULL;
574
575 if ((MethodDecl = getClassMethod(Sel)))
576 return MethodDecl;
577
Chris Lattner0be08822008-07-21 21:32:27 +0000578 for (protocol_iterator I = protocol_begin(), E = protocol_end(); I != E; ++I)
Steve Naroff30fb1da2008-12-18 15:50:41 +0000579 if ((MethodDecl = (*I)->lookupClassMethod(Sel)))
Chris Lattner0be08822008-07-21 21:32:27 +0000580 return MethodDecl;
Chris Lattner10318b82008-03-16 00:19:01 +0000581 return NULL;
582}
583
584/// getSynthesizedMethodSize - Compute size of synthesized method name
585/// as done be the rewrite.
586///
587unsigned ObjCMethodDecl::getSynthesizedMethodSize() const {
588 // syntesized method name is a concatenation of -/+[class-name selector]
589 // Get length of this name.
590 unsigned length = 3; // _I_ or _C_
Chris Lattnerd120b9e2008-11-24 03:54:41 +0000591 length += getClassInterface()->getNameAsString().size()+1; // extra for _
Steve Naroff438be772009-01-08 19:41:02 +0000592 if (const ObjCCategoryImplDecl *CID =
593 dyn_cast<ObjCCategoryImplDecl>(getDeclContext()))
Chris Lattnerd120b9e2008-11-24 03:54:41 +0000594 length += CID->getNameAsString().size()+1;
Chris Lattner3a8f2942008-11-24 03:33:13 +0000595 length += getSelector().getAsString().size(); // selector name
Chris Lattner10318b82008-03-16 00:19:01 +0000596 return length;
597}
598
Chris Lattner052fbcd2008-04-06 05:25:03 +0000599ObjCInterfaceDecl *ObjCMethodDecl::getClassInterface() {
Steve Naroff438be772009-01-08 19:41:02 +0000600 if (ObjCInterfaceDecl *ID = dyn_cast<ObjCInterfaceDecl>(getDeclContext()))
Chris Lattner10318b82008-03-16 00:19:01 +0000601 return ID;
Steve Naroff438be772009-01-08 19:41:02 +0000602 if (ObjCCategoryDecl *CD = dyn_cast<ObjCCategoryDecl>(getDeclContext()))
Chris Lattner10318b82008-03-16 00:19:01 +0000603 return CD->getClassInterface();
604 if (ObjCImplementationDecl *IMD =
Steve Naroff438be772009-01-08 19:41:02 +0000605 dyn_cast<ObjCImplementationDecl>(getDeclContext()))
Chris Lattner10318b82008-03-16 00:19:01 +0000606 return IMD->getClassInterface();
Steve Naroff438be772009-01-08 19:41:02 +0000607 if (ObjCCategoryImplDecl *CID =
608 dyn_cast<ObjCCategoryImplDecl>(getDeclContext()))
Chris Lattner10318b82008-03-16 00:19:01 +0000609 return CID->getClassInterface();
610 assert(false && "unknown method context");
611 return 0;
612}
Chris Lattner44859612008-03-17 01:19:02 +0000613
Fariborz Jahaniandc0569e2008-04-23 00:06:01 +0000614ObjCPropertyImplDecl *ObjCPropertyImplDecl::Create(ASTContext &C,
Douglas Gregor6e4fa2c2009-01-09 00:49:46 +0000615 DeclContext *DC,
Fariborz Jahaniandc0569e2008-04-23 00:06:01 +0000616 SourceLocation atLoc,
617 SourceLocation L,
618 ObjCPropertyDecl *property,
Daniel Dunbar14117fc2008-08-26 04:47:31 +0000619 Kind PK,
Fariborz Jahaniandc0569e2008-04-23 00:06:01 +0000620 ObjCIvarDecl *ivar) {
Steve Naroff5abb0282009-01-27 21:25:57 +0000621 return new (C) ObjCPropertyImplDecl(DC, atLoc, L, property, PK, ivar);
Fariborz Jahaniandc0569e2008-04-23 00:06:01 +0000622}
Chris Lattner44859612008-03-17 01:19:02 +0000623
Chris Lattnereee57c02008-04-04 06:12:32 +0000624