blob: 629dcca67828de7af0f0837f3d6f22c8117068da [file] [log] [blame]
Chris Lattner89375192008-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 Dunbar221fa942008-08-11 04:54:23 +000016#include "clang/AST/Stmt.h"
Chris Lattner89375192008-03-16 00:19:01 +000017using namespace clang;
18
Chris Lattner8d8829e2008-03-16 00:49:28 +000019//===----------------------------------------------------------------------===//
20// ObjC Decl Allocation/Deallocation Method Implementations
21//===----------------------------------------------------------------------===//
22
Chris Lattnerc5ffed42008-04-04 06:12:32 +000023ObjCMethodDecl *ObjCMethodDecl::Create(ASTContext &C,
24 SourceLocation beginLoc,
Chris Lattner8d8829e2008-03-16 00:49:28 +000025 SourceLocation endLoc,
26 Selector SelInfo, QualType T,
Steve Naroff35c62ae2009-01-08 17:28:14 +000027 DeclContext *contextDecl,
Daniel Dunbar73a73f52008-08-20 18:02:42 +000028 bool isInstance,
Chris Lattner8d8829e2008-03-16 00:49:28 +000029 bool isVariadic,
Fariborz Jahanian8983f172008-05-07 20:53:44 +000030 bool isSynthesized,
Chris Lattnerc5579472008-03-16 00:58:16 +000031 ImplementationControl impControl) {
Steve Naroff13ae6f42009-01-27 21:25:57 +000032 return new (C) ObjCMethodDecl(beginLoc, endLoc,
Chris Lattnerc5ffed42008-04-04 06:12:32 +000033 SelInfo, T, contextDecl,
Daniel Dunbar73a73f52008-08-20 18:02:42 +000034 isInstance,
Fariborz Jahanian8983f172008-05-07 20:53:44 +000035 isVariadic, isSynthesized, impControl);
Chris Lattner96c501e2008-03-16 01:15:50 +000036}
Chris Lattner8d8829e2008-03-16 00:49:28 +000037
Ted Kremenek09a0d042008-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 Lattner55c8d392009-02-20 05:54:35 +000044
45 delete [] ParamInfo;
46 ParamInfo = 0;
47
Ted Kremenek09a0d042008-06-06 16:45:15 +000048 Decl::Destroy(C);
49}
50
Chris Lattner8d10c112009-02-20 06:03:09 +000051
Chris Lattnerc5ffed42008-04-04 06:12:32 +000052ObjCInterfaceDecl *ObjCInterfaceDecl::Create(ASTContext &C,
Douglas Gregorc25d7a72009-01-09 00:49:46 +000053 DeclContext *DC,
Chris Lattnerc5ffed42008-04-04 06:12:32 +000054 SourceLocation atLoc,
Steve Naroff5a4611c2008-04-11 19:35:35 +000055 IdentifierInfo *Id,
56 SourceLocation ClassLoc,
Chris Lattner96c501e2008-03-16 01:15:50 +000057 bool ForwardDecl, bool isInternal){
Steve Naroff13ae6f42009-01-27 21:25:57 +000058 return new (C) ObjCInterfaceDecl(DC, atLoc, Id, ClassLoc, ForwardDecl,
Chris Lattner96c501e2008-03-16 01:15:50 +000059 isInternal);
60}
61
Chris Lattner8d10c112009-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),
Chris Lattnerfa62dc32009-02-20 06:10:45 +000066 TypeForDecl(0), SuperClass(0),
Chris Lattner8d10c112009-02-20 06:03:09 +000067 CategoryList(0), ForwardDecl(FD), InternalInterface(isInternal),
68 ClassLoc(CLoc) {
Steve Naroff639de9c2009-01-07 17:57:40 +000069}
70
Chris Lattner8d10c112009-02-20 06:03:09 +000071void ObjCInterfaceDecl::Destroy(ASTContext &C) {
Ted Kremenek09a0d042008-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 Lattnerfa62dc32009-02-20 06:10:45 +000075 IVars.clear();
Chris Lattner8d10c112009-02-20 06:03:09 +000076 // FIXME: CategoryList?
77
Ted Kremenek5144fe22008-06-06 17:21:42 +000078 // FIXME: Because there is no clear ownership
79 // role between ObjCInterfaceDecls and the ObjCPropertyDecls that they
80 // reference, we destroy ObjCPropertyDecls in ~TranslationUnit.
Ted Kremenek09a0d042008-06-06 16:45:15 +000081 Decl::Destroy(C);
82}
83
84
Argyrios Kyrtzidis0cf66252009-02-17 20:20:37 +000085ObjCIvarDecl *ObjCIvarDecl::Create(ASTContext &C, DeclContext *DC,
86 SourceLocation L, IdentifierInfo *Id,
87 QualType T, AccessControl ac, Expr *BW) {
88 return new (C) ObjCIvarDecl(DC, L, Id, T, ac, BW);
Chris Lattner8d8829e2008-03-16 00:49:28 +000089}
90
Ted Kremenek0e857202008-08-20 03:26:33 +000091
92ObjCAtDefsFieldDecl
Douglas Gregor91f84212008-12-11 16:49:14 +000093*ObjCAtDefsFieldDecl::Create(ASTContext &C, DeclContext *DC, SourceLocation L,
Ted Kremenek0e857202008-08-20 03:26:33 +000094 IdentifierInfo *Id, QualType T, Expr *BW) {
Steve Naroff13ae6f42009-01-27 21:25:57 +000095 return new (C) ObjCAtDefsFieldDecl(DC, L, Id, T, BW);
Ted Kremenek0e857202008-08-20 03:26:33 +000096}
97
98void ObjCAtDefsFieldDecl::Destroy(ASTContext& C) {
99 this->~ObjCAtDefsFieldDecl();
Steve Naroff13ae6f42009-01-27 21:25:57 +0000100 C.Deallocate((void *)this);
Ted Kremenek0e857202008-08-20 03:26:33 +0000101}
102
Douglas Gregorc25d7a72009-01-09 00:49:46 +0000103ObjCProtocolDecl *ObjCProtocolDecl::Create(ASTContext &C, DeclContext *DC,
Chris Lattnerc5ffed42008-04-04 06:12:32 +0000104 SourceLocation L,
Chris Lattneracc04a92008-03-16 20:19:15 +0000105 IdentifierInfo *Id) {
Steve Naroff13ae6f42009-01-27 21:25:57 +0000106 return new (C) ObjCProtocolDecl(DC, L, Id);
Chris Lattnerf87ca0a2008-03-16 01:23:04 +0000107}
108
Chris Lattner55c8d392009-02-20 05:54:35 +0000109void ObjCProtocolDecl::Destroy(ASTContext &C) {
Ted Kremenek2e34af62008-06-06 19:48:57 +0000110 delete [] PropertyDecl;
Chris Lattner55c8d392009-02-20 05:54:35 +0000111 PropertyDecl = 0;
112 ObjCContainerDecl::Destroy(C);
Ted Kremenek2e34af62008-06-06 19:48:57 +0000113}
114
Ted Kremenek2e34af62008-06-06 19:48:57 +0000115
Chris Lattner55c8d392009-02-20 05:54:35 +0000116
117
Douglas Gregorc25d7a72009-01-09 00:49:46 +0000118ObjCClassDecl *ObjCClassDecl::Create(ASTContext &C, DeclContext *DC,
Chris Lattnerc5ffed42008-04-04 06:12:32 +0000119 SourceLocation L,
Chris Lattner1dd77af2008-03-16 20:34:23 +0000120 ObjCInterfaceDecl **Elts, unsigned nElts) {
Steve Naroff13ae6f42009-01-27 21:25:57 +0000121 return new (C) ObjCClassDecl(DC, L, Elts, nElts);
Chris Lattner1dd77af2008-03-16 20:34:23 +0000122}
123
Chris Lattner8d10c112009-02-20 06:03:09 +0000124ObjCClassDecl::ObjCClassDecl(DeclContext *DC, SourceLocation L,
125 ObjCInterfaceDecl **Elts, unsigned nElts)
126 : Decl(ObjCClass, DC, L) {
127 if (nElts) {
128 ForwardDecls = new ObjCInterfaceDecl*[nElts];
129 memcpy(ForwardDecls, Elts, nElts*sizeof(ObjCInterfaceDecl*));
130 } else {
131 ForwardDecls = 0;
132 }
133 NumForwardDecls = nElts;
Ted Kremenek71fff8b2008-06-06 20:11:53 +0000134}
135
Chris Lattner8d10c112009-02-20 06:03:09 +0000136void ObjCClassDecl::Destroy(ASTContext &C) {
Ted Kremenek71fff8b2008-06-06 20:11:53 +0000137
138 // FIXME: There is no clear ownership policy now for referenced
139 // ObjCInterfaceDecls. Some of them can be forward declarations that
140 // are never later defined (in which case the ObjCClassDecl owns them)
141 // or the ObjCInterfaceDecl later becomes a real definition later. Ideally
142 // we should have separate objects for forward declarations and definitions,
143 // obviating this problem. Because of this situation, referenced
144 // ObjCInterfaceDecls are destroyed in ~TranslationUnit.
145
Chris Lattner8d10c112009-02-20 06:03:09 +0000146 delete [] ForwardDecls;
147 ForwardDecls = 0;
148
Ted Kremenek71fff8b2008-06-06 20:11:53 +0000149 Decl::Destroy(C);
150}
151
Chris Lattner1dd77af2008-03-16 20:34:23 +0000152ObjCForwardProtocolDecl *
Douglas Gregorc25d7a72009-01-09 00:49:46 +0000153ObjCForwardProtocolDecl::Create(ASTContext &C, DeclContext *DC,
Chris Lattnerc5ffed42008-04-04 06:12:32 +0000154 SourceLocation L,
Chris Lattner1dd77af2008-03-16 20:34:23 +0000155 ObjCProtocolDecl **Elts, unsigned NumElts) {
Steve Naroff13ae6f42009-01-27 21:25:57 +0000156 return new (C) ObjCForwardProtocolDecl(DC, L, Elts, NumElts);
Chris Lattner1dd77af2008-03-16 20:34:23 +0000157}
158
Chris Lattner8d10c112009-02-20 06:03:09 +0000159ObjCForwardProtocolDecl::
160ObjCForwardProtocolDecl(DeclContext *DC, SourceLocation L,
161 ObjCProtocolDecl **Elts, unsigned nElts)
162 : Decl(ObjCForwardProtocol, DC, L) {
163 NumReferencedProtocols = nElts;
164 if (nElts) {
165 ReferencedProtocols = new ObjCProtocolDecl*[nElts];
166 memcpy(ReferencedProtocols, Elts, nElts*sizeof(ObjCProtocolDecl*));
167 } else {
168 ReferencedProtocols = 0;
169 }
170}
171
172void ObjCForwardProtocolDecl::Destroy(ASTContext &C) {
Ted Kremenekef170492008-06-06 21:05:33 +0000173 delete [] ReferencedProtocols;
Chris Lattner8d10c112009-02-20 06:03:09 +0000174 ReferencedProtocols = 0;
Ted Kremenekef170492008-06-06 21:05:33 +0000175}
176
Douglas Gregorc25d7a72009-01-09 00:49:46 +0000177ObjCCategoryDecl *ObjCCategoryDecl::Create(ASTContext &C, DeclContext *DC,
Chris Lattnerc5ffed42008-04-04 06:12:32 +0000178 SourceLocation L,
Chris Lattner1dd77af2008-03-16 20:34:23 +0000179 IdentifierInfo *Id) {
Steve Naroff13ae6f42009-01-27 21:25:57 +0000180 return new (C) ObjCCategoryDecl(DC, L, Id);
Chris Lattner1dd77af2008-03-16 20:34:23 +0000181}
182
Chris Lattner36ac1ca2008-03-16 20:53:07 +0000183ObjCCategoryImplDecl *
Douglas Gregorc25d7a72009-01-09 00:49:46 +0000184ObjCCategoryImplDecl::Create(ASTContext &C, DeclContext *DC,
Chris Lattnerc5ffed42008-04-04 06:12:32 +0000185 SourceLocation L,IdentifierInfo *Id,
Chris Lattner36ac1ca2008-03-16 20:53:07 +0000186 ObjCInterfaceDecl *ClassInterface) {
Steve Naroff13ae6f42009-01-27 21:25:57 +0000187 return new (C) ObjCCategoryImplDecl(DC, L, Id, ClassInterface);
Chris Lattner36ac1ca2008-03-16 20:53:07 +0000188}
189
190ObjCImplementationDecl *
Douglas Gregorc25d7a72009-01-09 00:49:46 +0000191ObjCImplementationDecl::Create(ASTContext &C, DeclContext *DC,
Chris Lattnerc5ffed42008-04-04 06:12:32 +0000192 SourceLocation L,
Chris Lattner36ac1ca2008-03-16 20:53:07 +0000193 ObjCInterfaceDecl *ClassInterface,
194 ObjCInterfaceDecl *SuperDecl) {
Steve Naroff13ae6f42009-01-27 21:25:57 +0000195 return new (C) ObjCImplementationDecl(DC, L, ClassInterface, SuperDecl);
Chris Lattner36ac1ca2008-03-16 20:53:07 +0000196}
Chris Lattner89375192008-03-16 00:19:01 +0000197
Chris Lattner219b3e92008-03-16 21:17:37 +0000198ObjCCompatibleAliasDecl *
Douglas Gregorc25d7a72009-01-09 00:49:46 +0000199ObjCCompatibleAliasDecl::Create(ASTContext &C, DeclContext *DC,
Chris Lattnerc5ffed42008-04-04 06:12:32 +0000200 SourceLocation L,
Chris Lattner219b3e92008-03-16 21:17:37 +0000201 IdentifierInfo *Id,
202 ObjCInterfaceDecl* AliasedClass) {
Steve Naroff13ae6f42009-01-27 21:25:57 +0000203 return new (C) ObjCCompatibleAliasDecl(DC, L, Id, AliasedClass);
Chris Lattner219b3e92008-03-16 21:17:37 +0000204}
205
Douglas Gregorc25d7a72009-01-09 00:49:46 +0000206ObjCPropertyDecl *ObjCPropertyDecl::Create(ASTContext &C, DeclContext *DC,
Fariborz Jahanian4572b452008-04-11 23:40:25 +0000207 SourceLocation L,
Fariborz Jahanian0152a1a2008-04-14 23:36:35 +0000208 IdentifierInfo *Id,
Fariborz Jahanian8d916862008-05-05 18:51:55 +0000209 QualType T,
210 PropertyControl propControl) {
Steve Naroff13ae6f42009-01-27 21:25:57 +0000211 return new (C) ObjCPropertyDecl(DC, L, Id, T);
Chris Lattner219b3e92008-03-16 21:17:37 +0000212}
213
Chris Lattner89375192008-03-16 00:19:01 +0000214//===----------------------------------------------------------------------===//
215// Objective-C Decl Implementation
216//===----------------------------------------------------------------------===//
217
Fariborz Jahanian3d8552a2008-12-09 20:23:04 +0000218void ObjCMethodDecl::createImplicitParams(ASTContext &Context,
219 const ObjCInterfaceDecl *OID) {
Daniel Dunbare36c39f2008-08-26 06:08:30 +0000220 QualType selfTy;
Douglas Gregorffca3a22009-01-09 17:18:27 +0000221 if (isInstanceMethod()) {
Daniel Dunbare36c39f2008-08-26 06:08:30 +0000222 // There may be no interface context due to error in declaration
223 // of the interface (which has been reported). Recover gracefully.
Fariborz Jahanian3d8552a2008-12-09 20:23:04 +0000224 if (OID) {
225 selfTy = Context.getObjCInterfaceType(const_cast<ObjCInterfaceDecl *>(OID));
Daniel Dunbare36c39f2008-08-26 06:08:30 +0000226 selfTy = Context.getPointerType(selfTy);
227 } else {
228 selfTy = Context.getObjCIdType();
229 }
230 } else // we have a factory method.
231 selfTy = Context.getObjCClassType();
232
233 SelfDecl = ImplicitParamDecl::Create(Context, this,
234 SourceLocation(),
235 &Context.Idents.get("self"),
Douglas Gregor6e6ad602009-01-20 01:17:11 +0000236 selfTy);
Daniel Dunbare36c39f2008-08-26 06:08:30 +0000237
238 CmdDecl = ImplicitParamDecl::Create(Context, this,
239 SourceLocation(),
240 &Context.Idents.get("_cmd"),
Douglas Gregor6e6ad602009-01-20 01:17:11 +0000241 Context.getObjCSelType());
Daniel Dunbare36c39f2008-08-26 06:08:30 +0000242}
243
Chris Lattner89375192008-03-16 00:19:01 +0000244void ObjCMethodDecl::setMethodParams(ParmVarDecl **NewParamInfo,
245 unsigned NumParams) {
246 assert(ParamInfo == 0 && "Already has param info!");
247
248 // Zero params -> null pointer.
249 if (NumParams) {
250 ParamInfo = new ParmVarDecl*[NumParams];
251 memcpy(ParamInfo, NewParamInfo, sizeof(ParmVarDecl*)*NumParams);
252 NumMethodParams = NumParams;
253 }
254}
255
Fariborz Jahaniana054e992008-04-21 19:04:53 +0000256/// FindCategoryDeclaration - Finds category declaration in the list of
257/// categories for this class and returns it. Name of the category is passed
258/// in 'CategoryId'. If category not found, return 0;
259///
260ObjCCategoryDecl *
261 ObjCInterfaceDecl::FindCategoryDeclaration(IdentifierInfo *CategoryId) const {
262 for (ObjCCategoryDecl *Category = getCategoryList();
263 Category; Category = Category->getNextClassCategory())
264 if (Category->getIdentifier() == CategoryId)
265 return Category;
266 return 0;
267}
268
Fariborz Jahanianb1378f92008-12-13 22:20:28 +0000269/// lookupFieldDeclForIvar - looks up a field decl' in the laid out
270/// storage which matches this 'ivar'.
271///
272FieldDecl *ObjCInterfaceDecl::lookupFieldDeclForIvar(ASTContext &Context,
Fariborz Jahanianb517e902008-12-15 20:35:07 +0000273 const ObjCIvarDecl *ivar) {
Fariborz Jahanianf327e892008-12-17 21:40:49 +0000274 const RecordDecl *RecordForDecl = Context.addRecordToClass(this);
Fariborz Jahanianb1378f92008-12-13 22:20:28 +0000275 assert(RecordForDecl && "lookupFieldDeclForIvar no storage for class");
276 DeclarationName Member = ivar->getDeclName();
Fariborz Jahanianf327e892008-12-17 21:40:49 +0000277 DeclContext::lookup_result Lookup = (const_cast< RecordDecl *>(RecordForDecl))
Steve Naroff35c62ae2009-01-08 17:28:14 +0000278 ->lookup(Member);
Fariborz Jahanianb1378f92008-12-13 22:20:28 +0000279 assert((Lookup.first != Lookup.second) && "field decl not found");
280 FieldDecl *MemberDecl = dyn_cast<FieldDecl>(*Lookup.first);
281 assert(MemberDecl && "field decl not found");
282 return MemberDecl;
283}
284
Chris Lattner89375192008-03-16 00:19:01 +0000285/// ObjCAddInstanceVariablesToClassImpl - Checks for correctness of Instance
286/// Variables (Ivars) relative to what declared in @implementation;s class.
287/// Ivars into ObjCImplementationDecl's fields.
288///
289void ObjCImplementationDecl::ObjCAddInstanceVariablesToClassImpl(
290 ObjCIvarDecl **ivars, unsigned numIvars) {
291 NumIvars = numIvars;
292 if (numIvars) {
293 Ivars = new ObjCIvarDecl*[numIvars];
294 memcpy(Ivars, ivars, numIvars*sizeof(ObjCIvarDecl*));
295 }
296}
297
Steve Naroff35c62ae2009-01-08 17:28:14 +0000298// Get the local instance method declared in this interface.
299// FIXME: handle overloading, instance & class methods can have the same name.
300ObjCMethodDecl *ObjCContainerDecl::getInstanceMethod(Selector Sel) const {
301 lookup_const_result MethodResult = lookup(Sel);
302 if (MethodResult.first)
303 return const_cast<ObjCMethodDecl*>(
304 dyn_cast<ObjCMethodDecl>(*MethodResult.first));
305 return 0;
306}
307
308// Get the local class method declared in this interface.
309ObjCMethodDecl *ObjCContainerDecl::getClassMethod(Selector Sel) const {
310 lookup_const_result MethodResult = lookup(Sel);
311 if (MethodResult.first)
312 return const_cast<ObjCMethodDecl*>(
313 dyn_cast<ObjCMethodDecl>(*MethodResult.first));
314 return 0;
315}
316
317unsigned ObjCContainerDecl::getNumInstanceMethods() const {
318 unsigned sum = 0;
319 for (instmeth_iterator I=instmeth_begin(), E=instmeth_end(); I != E; ++I)
320 sum++;
321 return sum;
322}
323unsigned ObjCContainerDecl::getNumClassMethods() const {
324 unsigned sum = 0;
325 for (classmeth_iterator I=classmeth_begin(), E=classmeth_end(); I != E; ++I)
326 sum++;
327 return sum;
328}
Steve Naroff0c0f5ba2009-01-11 01:06:09 +0000329unsigned ObjCContainerDecl::getNumProperties() const {
330 unsigned sum = 0;
331 for (prop_iterator I=prop_begin(), E=prop_end(); I != E; ++I)
332 sum++;
333 return sum;
334}
Steve Naroff35c62ae2009-01-08 17:28:14 +0000335
Fariborz Jahaniana054e992008-04-21 19:04:53 +0000336/// FindPropertyDeclaration - Finds declaration of the property given its name
337/// in 'PropertyId' and returns it. It returns 0, if not found.
Steve Naroffba3dc382009-01-11 12:47:58 +0000338/// FIXME: Convert to DeclContext lookup...
Fariborz Jahaniana054e992008-04-21 19:04:53 +0000339///
340ObjCPropertyDecl *
Steve Naroffb3a87982009-01-09 15:36:25 +0000341ObjCContainerDecl::FindPropertyDeclaration(IdentifierInfo *PropertyId) const {
342 for (prop_iterator I = prop_begin(), E = prop_end(); I != E; ++I) {
Fariborz Jahaniana054e992008-04-21 19:04:53 +0000343 ObjCPropertyDecl *property = *I;
344 if (property->getIdentifier() == PropertyId)
345 return property;
346 }
Fariborz Jahanian519976c2009-01-09 21:04:52 +0000347 const ObjCProtocolDecl *PID = dyn_cast<ObjCProtocolDecl>(this);
348 if (PID) {
349 for (ObjCProtocolDecl::protocol_iterator P = PID->protocol_begin(),
350 E = PID->protocol_end();
351 P != E; ++P)
352 if (ObjCPropertyDecl *property =
353 (*P)->FindPropertyDeclaration(PropertyId))
354 return property;
355 }
356
Fariborz Jahaniandab04842009-01-19 18:16:19 +0000357 if (const ObjCInterfaceDecl *OID = dyn_cast<ObjCInterfaceDecl>(this)) {
Steve Naroffb3a87982009-01-09 15:36:25 +0000358 // Look through categories.
359 for (ObjCCategoryDecl *Category = OID->getCategoryList();
360 Category; Category = Category->getNextClassCategory()) {
361 ObjCPropertyDecl *property = Category->FindPropertyDeclaration(PropertyId);
362 if (property)
363 return property;
364 }
365 // Look through protocols.
366 for (ObjCInterfaceDecl::protocol_iterator I = OID->protocol_begin(),
367 E = OID->protocol_end(); I != E; ++I) {
368 ObjCProtocolDecl *Protocol = *I;
369 ObjCPropertyDecl *property = Protocol->FindPropertyDeclaration(PropertyId);
370 if (property)
371 return property;
372 }
373 if (OID->getSuperClass())
374 return OID->getSuperClass()->FindPropertyDeclaration(PropertyId);
Steve Narofff9c65242008-06-05 13:55:23 +0000375 }
Fariborz Jahaniandab04842009-01-19 18:16:19 +0000376 else if (const ObjCCategoryDecl *OCD = dyn_cast<ObjCCategoryDecl>(this)) {
377 // Look through protocols.
378 for (ObjCInterfaceDecl::protocol_iterator I = OCD->protocol_begin(),
379 E = OCD->protocol_end(); I != E; ++I) {
380 ObjCProtocolDecl *Protocol = *I;
381 ObjCPropertyDecl *property = Protocol->FindPropertyDeclaration(PropertyId);
382 if (property)
383 return property;
384 }
385 }
Steve Narofff9c65242008-06-05 13:55:23 +0000386 return 0;
387}
388
Chris Lattner89375192008-03-16 00:19:01 +0000389ObjCIvarDecl *ObjCInterfaceDecl::lookupInstanceVariable(
390 IdentifierInfo *ID, ObjCInterfaceDecl *&clsDeclared) {
391 ObjCInterfaceDecl* ClassDecl = this;
392 while (ClassDecl != NULL) {
393 for (ivar_iterator I = ClassDecl->ivar_begin(), E = ClassDecl->ivar_end();
394 I != E; ++I) {
395 if ((*I)->getIdentifier() == ID) {
396 clsDeclared = ClassDecl;
397 return *I;
398 }
399 }
400 ClassDecl = ClassDecl->getSuperClass();
401 }
402 return NULL;
403}
404
405/// lookupInstanceMethod - This method returns an instance method by looking in
406/// the class, its categories, and its super classes (using a linear search).
407ObjCMethodDecl *ObjCInterfaceDecl::lookupInstanceMethod(Selector Sel) {
408 ObjCInterfaceDecl* ClassDecl = this;
409 ObjCMethodDecl *MethodDecl = 0;
410
411 while (ClassDecl != NULL) {
412 if ((MethodDecl = ClassDecl->getInstanceMethod(Sel)))
413 return MethodDecl;
414
415 // Didn't find one yet - look through protocols.
Chris Lattnerd0045052008-07-21 18:19:38 +0000416 const ObjCList<ObjCProtocolDecl> &Protocols =
417 ClassDecl->getReferencedProtocols();
418 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
419 E = Protocols.end(); I != E; ++I)
420 if ((MethodDecl = (*I)->getInstanceMethod(Sel)))
Chris Lattner89375192008-03-16 00:19:01 +0000421 return MethodDecl;
Chris Lattnerd0045052008-07-21 18:19:38 +0000422
Chris Lattner89375192008-03-16 00:19:01 +0000423 // Didn't find one yet - now look through categories.
424 ObjCCategoryDecl *CatDecl = ClassDecl->getCategoryList();
425 while (CatDecl) {
426 if ((MethodDecl = CatDecl->getInstanceMethod(Sel)))
427 return MethodDecl;
Steve Naroff5fd31b12008-12-08 20:57:28 +0000428
429 // Didn't find one yet - look through protocols.
430 const ObjCList<ObjCProtocolDecl> &Protocols =
431 CatDecl->getReferencedProtocols();
432 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
433 E = Protocols.end(); I != E; ++I)
434 if ((MethodDecl = (*I)->getInstanceMethod(Sel)))
435 return MethodDecl;
Chris Lattner89375192008-03-16 00:19:01 +0000436 CatDecl = CatDecl->getNextClassCategory();
437 }
438 ClassDecl = ClassDecl->getSuperClass();
439 }
440 return NULL;
441}
442
443// lookupClassMethod - This method returns a class method by looking in the
444// class, its categories, and its super classes (using a linear search).
445ObjCMethodDecl *ObjCInterfaceDecl::lookupClassMethod(Selector Sel) {
446 ObjCInterfaceDecl* ClassDecl = this;
447 ObjCMethodDecl *MethodDecl = 0;
448
449 while (ClassDecl != NULL) {
450 if ((MethodDecl = ClassDecl->getClassMethod(Sel)))
451 return MethodDecl;
452
453 // Didn't find one yet - look through protocols.
Chris Lattner390d39a2008-07-21 21:32:27 +0000454 for (ObjCInterfaceDecl::protocol_iterator I = ClassDecl->protocol_begin(),
455 E = ClassDecl->protocol_end(); I != E; ++I)
Chris Lattnerd0045052008-07-21 18:19:38 +0000456 if ((MethodDecl = (*I)->getClassMethod(Sel)))
Chris Lattner89375192008-03-16 00:19:01 +0000457 return MethodDecl;
Chris Lattner390d39a2008-07-21 21:32:27 +0000458
Chris Lattner89375192008-03-16 00:19:01 +0000459 // Didn't find one yet - now look through categories.
460 ObjCCategoryDecl *CatDecl = ClassDecl->getCategoryList();
461 while (CatDecl) {
462 if ((MethodDecl = CatDecl->getClassMethod(Sel)))
463 return MethodDecl;
464 CatDecl = CatDecl->getNextClassCategory();
465 }
466 ClassDecl = ClassDecl->getSuperClass();
467 }
468 return NULL;
469}
470
Daniel Dunbar6962f5a2008-08-26 06:53:45 +0000471/// getInstanceMethod - This method returns an instance method by
472/// looking in the class implementation. Unlike interfaces, we don't
473/// look outside the implementation.
474ObjCMethodDecl *ObjCImplementationDecl::getInstanceMethod(Selector Sel) const {
Chris Lattner89375192008-03-16 00:19:01 +0000475 for (instmeth_iterator I = instmeth_begin(), E = instmeth_end(); I != E; ++I)
476 if ((*I)->getSelector() == Sel)
477 return *I;
478 return NULL;
479}
480
Daniel Dunbar6962f5a2008-08-26 06:53:45 +0000481/// getClassMethod - This method returns a class method by looking in
482/// the class implementation. Unlike interfaces, we don't look outside
483/// the implementation.
484ObjCMethodDecl *ObjCImplementationDecl::getClassMethod(Selector Sel) const {
Chris Lattner89375192008-03-16 00:19:01 +0000485 for (classmeth_iterator I = classmeth_begin(), E = classmeth_end();
486 I != E; ++I)
487 if ((*I)->getSelector() == Sel)
488 return *I;
489 return NULL;
490}
491
Fariborz Jahanianfbbaf6a2008-12-05 22:32:48 +0000492/// FindPropertyImplDecl - This method looks up a previous ObjCPropertyImplDecl
493/// added to the list of those properties @synthesized/@dynamic in this
494/// @implementation block.
495///
496ObjCPropertyImplDecl *ObjCImplementationDecl::FindPropertyImplDecl(IdentifierInfo *Id) const {
497 for (propimpl_iterator i = propimpl_begin(), e = propimpl_end(); i != e; ++i) {
498 ObjCPropertyImplDecl *PID = *i;
499 if (PID->getPropertyDecl()->getIdentifier() == Id)
500 return PID;
501 }
502 return 0;
503}
504
505/// FindPropertyImplIvarDecl - This method lookup the ivar in the list of
Fariborz Jahanian9c196792008-12-05 22:36:19 +0000506/// properties implemented in this @implementation block and returns the
507/// implemented property that uses it.
Fariborz Jahanianfbbaf6a2008-12-05 22:32:48 +0000508///
509ObjCPropertyImplDecl *ObjCImplementationDecl::FindPropertyImplIvarDecl(IdentifierInfo *ivarId) const {
510 for (propimpl_iterator i = propimpl_begin(), e = propimpl_end(); i != e; ++i) {
511 ObjCPropertyImplDecl *PID = *i;
512 if (PID->getPropertyIvarDecl() &&
513 PID->getPropertyIvarDecl()->getIdentifier() == ivarId)
514 return PID;
515 }
516 return 0;
517}
518
519/// FindPropertyImplIvarDecl - This method lookup the ivar in the list of
Chris Lattneraab70d22009-02-16 19:24:31 +0000520/// properties implemented in this category @implementation block and returns
521/// the implemented property that uses it.
Fariborz Jahanianfbbaf6a2008-12-05 22:32:48 +0000522///
Chris Lattneraab70d22009-02-16 19:24:31 +0000523ObjCPropertyImplDecl *ObjCCategoryImplDecl::
524FindPropertyImplIvarDecl(IdentifierInfo *ivarId) const {
525 for (propimpl_iterator i = propimpl_begin(), e = propimpl_end(); i != e; ++i){
Fariborz Jahanianfbbaf6a2008-12-05 22:32:48 +0000526 ObjCPropertyImplDecl *PID = *i;
527 if (PID->getPropertyIvarDecl() &&
528 PID->getPropertyIvarDecl()->getIdentifier() == ivarId)
529 return PID;
530 }
531 return 0;
532}
533
534/// FindPropertyImplDecl - This method looks up a previous ObjCPropertyImplDecl
535/// added to the list of those properties @synthesized/@dynamic in this
536/// category @implementation block.
537///
Chris Lattneraab70d22009-02-16 19:24:31 +0000538ObjCPropertyImplDecl *ObjCCategoryImplDecl::
539FindPropertyImplDecl(IdentifierInfo *Id) const {
540 for (propimpl_iterator i = propimpl_begin(), e = propimpl_end(); i != e; ++i){
Fariborz Jahanianfbbaf6a2008-12-05 22:32:48 +0000541 ObjCPropertyImplDecl *PID = *i;
542 if (PID->getPropertyDecl()->getIdentifier() == Id)
543 return PID;
544 }
545 return 0;
546}
547
Chris Lattner89375192008-03-16 00:19:01 +0000548// lookupInstanceMethod - This method returns an instance method by looking in
549// the class implementation. Unlike interfaces, we don't look outside the
550// implementation.
Daniel Dunbar6962f5a2008-08-26 06:53:45 +0000551ObjCMethodDecl *ObjCCategoryImplDecl::getInstanceMethod(Selector Sel) const {
Chris Lattner89375192008-03-16 00:19:01 +0000552 for (instmeth_iterator I = instmeth_begin(), E = instmeth_end(); I != E; ++I)
553 if ((*I)->getSelector() == Sel)
554 return *I;
555 return NULL;
556}
557
558// lookupClassMethod - This method returns an instance method by looking in
559// the class implementation. Unlike interfaces, we don't look outside the
560// implementation.
Daniel Dunbar6962f5a2008-08-26 06:53:45 +0000561ObjCMethodDecl *ObjCCategoryImplDecl::getClassMethod(Selector Sel) const {
Chris Lattner89375192008-03-16 00:19:01 +0000562 for (classmeth_iterator I = classmeth_begin(), E = classmeth_end();
563 I != E; ++I)
564 if ((*I)->getSelector() == Sel)
565 return *I;
566 return NULL;
567}
568
569// lookupInstanceMethod - Lookup a instance method in the protocol and protocols
570// it inherited.
571ObjCMethodDecl *ObjCProtocolDecl::lookupInstanceMethod(Selector Sel) {
572 ObjCMethodDecl *MethodDecl = NULL;
573
574 if ((MethodDecl = getInstanceMethod(Sel)))
575 return MethodDecl;
576
Chris Lattner390d39a2008-07-21 21:32:27 +0000577 for (protocol_iterator I = protocol_begin(), E = protocol_end(); I != E; ++I)
Steve Naroffd96f7cc2008-12-18 15:50:41 +0000578 if ((MethodDecl = (*I)->lookupInstanceMethod(Sel)))
Chris Lattner390d39a2008-07-21 21:32:27 +0000579 return MethodDecl;
Chris Lattner89375192008-03-16 00:19:01 +0000580 return NULL;
581}
582
583// lookupInstanceMethod - Lookup a class method in the protocol and protocols
584// it inherited.
585ObjCMethodDecl *ObjCProtocolDecl::lookupClassMethod(Selector Sel) {
586 ObjCMethodDecl *MethodDecl = NULL;
587
588 if ((MethodDecl = getClassMethod(Sel)))
589 return MethodDecl;
590
Chris Lattner390d39a2008-07-21 21:32:27 +0000591 for (protocol_iterator I = protocol_begin(), E = protocol_end(); I != E; ++I)
Steve Naroffd96f7cc2008-12-18 15:50:41 +0000592 if ((MethodDecl = (*I)->lookupClassMethod(Sel)))
Chris Lattner390d39a2008-07-21 21:32:27 +0000593 return MethodDecl;
Chris Lattner89375192008-03-16 00:19:01 +0000594 return NULL;
595}
596
597/// getSynthesizedMethodSize - Compute size of synthesized method name
598/// as done be the rewrite.
599///
600unsigned ObjCMethodDecl::getSynthesizedMethodSize() const {
601 // syntesized method name is a concatenation of -/+[class-name selector]
602 // Get length of this name.
603 unsigned length = 3; // _I_ or _C_
Chris Lattner86d7d912008-11-24 03:54:41 +0000604 length += getClassInterface()->getNameAsString().size()+1; // extra for _
Steve Naroff11b387f2009-01-08 19:41:02 +0000605 if (const ObjCCategoryImplDecl *CID =
606 dyn_cast<ObjCCategoryImplDecl>(getDeclContext()))
Chris Lattner86d7d912008-11-24 03:54:41 +0000607 length += CID->getNameAsString().size()+1;
Chris Lattnere4b95692008-11-24 03:33:13 +0000608 length += getSelector().getAsString().size(); // selector name
Chris Lattner89375192008-03-16 00:19:01 +0000609 return length;
610}
611
Chris Lattner713e6592008-04-06 05:25:03 +0000612ObjCInterfaceDecl *ObjCMethodDecl::getClassInterface() {
Steve Naroff11b387f2009-01-08 19:41:02 +0000613 if (ObjCInterfaceDecl *ID = dyn_cast<ObjCInterfaceDecl>(getDeclContext()))
Chris Lattner89375192008-03-16 00:19:01 +0000614 return ID;
Steve Naroff11b387f2009-01-08 19:41:02 +0000615 if (ObjCCategoryDecl *CD = dyn_cast<ObjCCategoryDecl>(getDeclContext()))
Chris Lattner89375192008-03-16 00:19:01 +0000616 return CD->getClassInterface();
617 if (ObjCImplementationDecl *IMD =
Steve Naroff11b387f2009-01-08 19:41:02 +0000618 dyn_cast<ObjCImplementationDecl>(getDeclContext()))
Chris Lattner89375192008-03-16 00:19:01 +0000619 return IMD->getClassInterface();
Steve Naroff11b387f2009-01-08 19:41:02 +0000620 if (ObjCCategoryImplDecl *CID =
621 dyn_cast<ObjCCategoryImplDecl>(getDeclContext()))
Chris Lattner89375192008-03-16 00:19:01 +0000622 return CID->getClassInterface();
623 assert(false && "unknown method context");
624 return 0;
625}
Chris Lattnered0e1642008-03-17 01:19:02 +0000626
Fariborz Jahanian6efdf1d2008-04-23 00:06:01 +0000627ObjCPropertyImplDecl *ObjCPropertyImplDecl::Create(ASTContext &C,
Douglas Gregorc25d7a72009-01-09 00:49:46 +0000628 DeclContext *DC,
Fariborz Jahanian6efdf1d2008-04-23 00:06:01 +0000629 SourceLocation atLoc,
630 SourceLocation L,
631 ObjCPropertyDecl *property,
Daniel Dunbar3b4fdb02008-08-26 04:47:31 +0000632 Kind PK,
Fariborz Jahanian6efdf1d2008-04-23 00:06:01 +0000633 ObjCIvarDecl *ivar) {
Steve Naroff13ae6f42009-01-27 21:25:57 +0000634 return new (C) ObjCPropertyImplDecl(DC, atLoc, L, property, PK, ivar);
Fariborz Jahanian6efdf1d2008-04-23 00:06:01 +0000635}
Chris Lattnered0e1642008-03-17 01:19:02 +0000636
Chris Lattnerc5ffed42008-04-04 06:12:32 +0000637