blob: 4185ac1682891cae70dd3ad81a21d0d69969a4d7 [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"
Steve Naroffc4173fa2009-02-22 19:35:57 +000017#include "llvm/ADT/STLExtras.h"
Chris Lattner89375192008-03-16 00:19:01 +000018using namespace clang;
19
Chris Lattner8d8829e2008-03-16 00:49:28 +000020//===----------------------------------------------------------------------===//
Chris Lattner4d1eb762009-02-20 21:16:26 +000021// ObjCListBase
22//===----------------------------------------------------------------------===//
23
Chris Lattner22298722009-02-20 21:35:13 +000024void ObjCListBase::Destroy(ASTContext &Ctx) {
Chris Lattner7c981a72009-02-20 21:44:01 +000025 Ctx.Deallocate(List);
Chris Lattner4d1eb762009-02-20 21:16:26 +000026 NumElts = 0;
27 List = 0;
28}
29
Chris Lattner22298722009-02-20 21:35:13 +000030void ObjCListBase::set(void *const* InList, unsigned Elts, ASTContext &Ctx) {
Chris Lattner4d1eb762009-02-20 21:16:26 +000031 assert(List == 0 && "Elements already set!");
32 if (Elts == 0) return; // Setting to an empty list is a noop.
Mike Stump11289f42009-09-09 15:08:12 +000033
34
Chris Lattner7c981a72009-02-20 21:44:01 +000035 List = new (Ctx) void*[Elts];
Chris Lattner4d1eb762009-02-20 21:16:26 +000036 NumElts = Elts;
37 memcpy(List, InList, sizeof(void*)*Elts);
38}
39
40
41//===----------------------------------------------------------------------===//
Chris Lattnerf1ccb0c2009-02-20 20:59:54 +000042// ObjCInterfaceDecl
Chris Lattner8d8829e2008-03-16 00:49:28 +000043//===----------------------------------------------------------------------===//
44
Fariborz Jahanian68453832009-06-05 18:16:35 +000045/// getIvarDecl - This method looks up an ivar in this ContextDecl.
46///
47ObjCIvarDecl *
Argyrios Kyrtzidiscfbfe782009-06-30 02:36:12 +000048ObjCContainerDecl::getIvarDecl(IdentifierInfo *Id) const {
Fariborz Jahanian68453832009-06-05 18:16:35 +000049 lookup_const_iterator Ivar, IvarEnd;
Argyrios Kyrtzidiscfbfe782009-06-30 02:36:12 +000050 for (llvm::tie(Ivar, IvarEnd) = lookup(Id); Ivar != IvarEnd; ++Ivar) {
Fariborz Jahanian68453832009-06-05 18:16:35 +000051 if (ObjCIvarDecl *ivar = dyn_cast<ObjCIvarDecl>(*Ivar))
52 return ivar;
53 }
54 return 0;
55}
56
Argyrios Kyrtzidis6de05602009-07-25 22:15:22 +000057// Get the local instance/class method declared in this interface.
Douglas Gregorbcced4e2009-04-09 21:40:53 +000058ObjCMethodDecl *
Argyrios Kyrtzidis6de05602009-07-25 22:15:22 +000059ObjCContainerDecl::getMethod(Selector Sel, bool isInstance) const {
Steve Naroffc4173fa2009-02-22 19:35:57 +000060 // Since instance & class methods can have the same name, the loop below
61 // ensures we get the correct method.
62 //
63 // @interface Whatever
64 // - (int) class_method;
65 // + (float) class_method;
66 // @end
67 //
68 lookup_const_iterator Meth, MethEnd;
Argyrios Kyrtzidiscfbfe782009-06-30 02:36:12 +000069 for (llvm::tie(Meth, MethEnd) = lookup(Sel); Meth != MethEnd; ++Meth) {
Steve Naroffc4173fa2009-02-22 19:35:57 +000070 ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(*Meth);
Argyrios Kyrtzidis6de05602009-07-25 22:15:22 +000071 if (MD && MD->isInstanceMethod() == isInstance)
Steve Naroffc4173fa2009-02-22 19:35:57 +000072 return MD;
73 }
Steve Naroff35c62ae2009-01-08 17:28:14 +000074 return 0;
75}
76
Fariborz Jahaniana054e992008-04-21 19:04:53 +000077/// FindPropertyDeclaration - Finds declaration of the property given its name
78/// in 'PropertyId' and returns it. It returns 0, if not found.
Steve Naroffba3dc382009-01-11 12:47:58 +000079/// FIXME: Convert to DeclContext lookup...
Fariborz Jahaniana054e992008-04-21 19:04:53 +000080///
81ObjCPropertyDecl *
Argyrios Kyrtzidiscfbfe782009-06-30 02:36:12 +000082ObjCContainerDecl::FindPropertyDeclaration(IdentifierInfo *PropertyId) const {
83 for (prop_iterator I = prop_begin(), E = prop_end(); I != E; ++I)
Chris Lattnerf1ccb0c2009-02-20 20:59:54 +000084 if ((*I)->getIdentifier() == PropertyId)
85 return *I;
Mike Stump11289f42009-09-09 15:08:12 +000086
Fariborz Jahanian519976c2009-01-09 21:04:52 +000087 const ObjCProtocolDecl *PID = dyn_cast<ObjCProtocolDecl>(this);
88 if (PID) {
Mike Stump11289f42009-09-09 15:08:12 +000089 for (ObjCProtocolDecl::protocol_iterator I = PID->protocol_begin(),
Chris Lattnerf1ccb0c2009-02-20 20:59:54 +000090 E = PID->protocol_end(); I != E; ++I)
Argyrios Kyrtzidiscfbfe782009-06-30 02:36:12 +000091 if (ObjCPropertyDecl *P = (*I)->FindPropertyDeclaration(PropertyId))
Chris Lattnerf1ccb0c2009-02-20 20:59:54 +000092 return P;
Fariborz Jahanian519976c2009-01-09 21:04:52 +000093 }
Mike Stump11289f42009-09-09 15:08:12 +000094
Fariborz Jahaniandab04842009-01-19 18:16:19 +000095 if (const ObjCInterfaceDecl *OID = dyn_cast<ObjCInterfaceDecl>(this)) {
Steve Naroffb3a87982009-01-09 15:36:25 +000096 // Look through categories.
97 for (ObjCCategoryDecl *Category = OID->getCategoryList();
98 Category; Category = Category->getNextClassCategory()) {
Argyrios Kyrtzidiscfbfe782009-06-30 02:36:12 +000099 if (ObjCPropertyDecl *P = Category->FindPropertyDeclaration(PropertyId))
Chris Lattnerf1ccb0c2009-02-20 20:59:54 +0000100 return P;
Steve Naroffb3a87982009-01-09 15:36:25 +0000101 }
102 // Look through protocols.
103 for (ObjCInterfaceDecl::protocol_iterator I = OID->protocol_begin(),
104 E = OID->protocol_end(); I != E; ++I) {
Argyrios Kyrtzidiscfbfe782009-06-30 02:36:12 +0000105 if (ObjCPropertyDecl *P = (*I)->FindPropertyDeclaration(PropertyId))
Chris Lattnerf1ccb0c2009-02-20 20:59:54 +0000106 return P;
Steve Naroffb3a87982009-01-09 15:36:25 +0000107 }
108 if (OID->getSuperClass())
Argyrios Kyrtzidiscfbfe782009-06-30 02:36:12 +0000109 return OID->getSuperClass()->FindPropertyDeclaration(PropertyId);
Chris Lattnerf1ccb0c2009-02-20 20:59:54 +0000110 } else if (const ObjCCategoryDecl *OCD = dyn_cast<ObjCCategoryDecl>(this)) {
Fariborz Jahaniandab04842009-01-19 18:16:19 +0000111 // Look through protocols.
112 for (ObjCInterfaceDecl::protocol_iterator I = OCD->protocol_begin(),
113 E = OCD->protocol_end(); I != E; ++I) {
Argyrios Kyrtzidiscfbfe782009-06-30 02:36:12 +0000114 if (ObjCPropertyDecl *P = (*I)->FindPropertyDeclaration(PropertyId))
Chris Lattnerf1ccb0c2009-02-20 20:59:54 +0000115 return P;
Fariborz Jahaniandab04842009-01-19 18:16:19 +0000116 }
117 }
Steve Narofff9c65242008-06-05 13:55:23 +0000118 return 0;
119}
120
Argyrios Kyrtzidiscfbfe782009-06-30 02:36:12 +0000121ObjCIvarDecl *ObjCInterfaceDecl::lookupInstanceVariable(IdentifierInfo *ID,
122 ObjCInterfaceDecl *&clsDeclared) {
Chris Lattner89375192008-03-16 00:19:01 +0000123 ObjCInterfaceDecl* ClassDecl = this;
124 while (ClassDecl != NULL) {
Argyrios Kyrtzidiscfbfe782009-06-30 02:36:12 +0000125 if (ObjCIvarDecl *I = ClassDecl->getIvarDecl(ID)) {
Fariborz Jahanian68453832009-06-05 18:16:35 +0000126 clsDeclared = ClassDecl;
127 return I;
Chris Lattner89375192008-03-16 00:19:01 +0000128 }
129 ClassDecl = ClassDecl->getSuperClass();
130 }
131 return NULL;
132}
133
Fariborz Jahaniandb3a4c12009-05-22 17:12:32 +0000134/// lookupInheritedClass - This method returns ObjCInterfaceDecl * of the super
135/// class whose name is passed as argument. If it is not one of the super classes
136/// the it returns NULL.
137ObjCInterfaceDecl *ObjCInterfaceDecl::lookupInheritedClass(
138 const IdentifierInfo*ICName) {
139 ObjCInterfaceDecl* ClassDecl = this;
140 while (ClassDecl != NULL) {
141 if (ClassDecl->getIdentifier() == ICName)
142 return ClassDecl;
143 ClassDecl = ClassDecl->getSuperClass();
144 }
145 return NULL;
146}
147
Argyrios Kyrtzidis553376b2009-07-25 22:15:51 +0000148/// lookupMethod - This method returns an instance/class method by looking in
Chris Lattner89375192008-03-16 00:19:01 +0000149/// the class, its categories, and its super classes (using a linear search).
Argyrios Kyrtzidis553376b2009-07-25 22:15:51 +0000150ObjCMethodDecl *ObjCInterfaceDecl::lookupMethod(Selector Sel,
151 bool isInstance) const {
152 const ObjCInterfaceDecl* ClassDecl = this;
Chris Lattner89375192008-03-16 00:19:01 +0000153 ObjCMethodDecl *MethodDecl = 0;
Mike Stump11289f42009-09-09 15:08:12 +0000154
Chris Lattner89375192008-03-16 00:19:01 +0000155 while (ClassDecl != NULL) {
Argyrios Kyrtzidis553376b2009-07-25 22:15:51 +0000156 if ((MethodDecl = ClassDecl->getMethod(Sel, isInstance)))
Chris Lattner89375192008-03-16 00:19:01 +0000157 return MethodDecl;
Mike Stump11289f42009-09-09 15:08:12 +0000158
Chris Lattner89375192008-03-16 00:19:01 +0000159 // Didn't find one yet - look through protocols.
Chris Lattnerd0045052008-07-21 18:19:38 +0000160 const ObjCList<ObjCProtocolDecl> &Protocols =
161 ClassDecl->getReferencedProtocols();
162 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
163 E = Protocols.end(); I != E; ++I)
Argyrios Kyrtzidis553376b2009-07-25 22:15:51 +0000164 if ((MethodDecl = (*I)->lookupMethod(Sel, isInstance)))
Chris Lattner89375192008-03-16 00:19:01 +0000165 return MethodDecl;
Mike Stump11289f42009-09-09 15:08:12 +0000166
Chris Lattner89375192008-03-16 00:19:01 +0000167 // Didn't find one yet - now look through categories.
168 ObjCCategoryDecl *CatDecl = ClassDecl->getCategoryList();
169 while (CatDecl) {
Argyrios Kyrtzidis553376b2009-07-25 22:15:51 +0000170 if ((MethodDecl = CatDecl->getMethod(Sel, isInstance)))
Chris Lattner89375192008-03-16 00:19:01 +0000171 return MethodDecl;
Mike Stump11289f42009-09-09 15:08:12 +0000172
Steve Naroff5fd31b12008-12-08 20:57:28 +0000173 // Didn't find one yet - look through protocols.
174 const ObjCList<ObjCProtocolDecl> &Protocols =
175 CatDecl->getReferencedProtocols();
176 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
177 E = Protocols.end(); I != E; ++I)
Argyrios Kyrtzidis553376b2009-07-25 22:15:51 +0000178 if ((MethodDecl = (*I)->lookupMethod(Sel, isInstance)))
Steve Naroff8ec27842009-02-26 11:32:02 +0000179 return MethodDecl;
Chris Lattner89375192008-03-16 00:19:01 +0000180 CatDecl = CatDecl->getNextClassCategory();
181 }
182 ClassDecl = ClassDecl->getSuperClass();
183 }
184 return NULL;
185}
186
Steve Naroffbb69c942009-10-01 23:46:04 +0000187ObjCMethodDecl *ObjCInterfaceDecl::lookupPrivateInstanceMethod(
188 const Selector &Sel) {
189 ObjCMethodDecl *Method = 0;
190 if (ObjCImplementationDecl *ImpDecl = getImplementation())
191 Method = ImpDecl->getInstanceMethod(Sel);
192
193 if (!Method && getSuperClass())
194 return getSuperClass()->lookupPrivateInstanceMethod(Sel);
195 return Method;
196}
Chris Lattnerf1ccb0c2009-02-20 20:59:54 +0000197
198//===----------------------------------------------------------------------===//
199// ObjCMethodDecl
200//===----------------------------------------------------------------------===//
201
202ObjCMethodDecl *ObjCMethodDecl::Create(ASTContext &C,
Mike Stump11289f42009-09-09 15:08:12 +0000203 SourceLocation beginLoc,
Chris Lattnerf1ccb0c2009-02-20 20:59:54 +0000204 SourceLocation endLoc,
205 Selector SelInfo, QualType T,
206 DeclContext *contextDecl,
207 bool isInstance,
208 bool isVariadic,
209 bool isSynthesized,
210 ImplementationControl impControl) {
211 return new (C) ObjCMethodDecl(beginLoc, endLoc,
212 SelInfo, T, contextDecl,
Mike Stump11289f42009-09-09 15:08:12 +0000213 isInstance,
Chris Lattnerf1ccb0c2009-02-20 20:59:54 +0000214 isVariadic, isSynthesized, impControl);
Chris Lattner89375192008-03-16 00:19:01 +0000215}
216
Chris Lattner22298722009-02-20 21:35:13 +0000217void ObjCMethodDecl::Destroy(ASTContext &C) {
Chris Lattnerf1ccb0c2009-02-20 20:59:54 +0000218 if (Body) Body->Destroy(C);
219 if (SelfDecl) SelfDecl->Destroy(C);
Mike Stump11289f42009-09-09 15:08:12 +0000220
Chris Lattnerf1ccb0c2009-02-20 20:59:54 +0000221 for (param_iterator I=param_begin(), E=param_end(); I!=E; ++I)
222 if (*I) (*I)->Destroy(C);
223
Chris Lattner22298722009-02-20 21:35:13 +0000224 ParamInfo.Destroy(C);
Chris Lattnerf1ccb0c2009-02-20 20:59:54 +0000225
226 Decl::Destroy(C);
Chris Lattner89375192008-03-16 00:19:01 +0000227}
228
Argyrios Kyrtzidisa8cf0be2009-07-21 00:06:36 +0000229/// \brief A definition will return its interface declaration.
230/// An interface declaration will return its definition.
231/// Otherwise it will return itself.
232ObjCMethodDecl *ObjCMethodDecl::getNextRedeclaration() {
233 ASTContext &Ctx = getASTContext();
234 ObjCMethodDecl *Redecl = 0;
235 Decl *CtxD = cast<Decl>(getDeclContext());
236
237 if (ObjCInterfaceDecl *IFD = dyn_cast<ObjCInterfaceDecl>(CtxD)) {
238 if (ObjCImplementationDecl *ImplD = Ctx.getObjCImplementation(IFD))
239 Redecl = ImplD->getMethod(getSelector(), isInstanceMethod());
240
241 } else if (ObjCCategoryDecl *CD = dyn_cast<ObjCCategoryDecl>(CtxD)) {
242 if (ObjCCategoryImplDecl *ImplD = Ctx.getObjCImplementation(CD))
243 Redecl = ImplD->getMethod(getSelector(), isInstanceMethod());
244
Argyrios Kyrtzidisa56fa192009-07-28 05:11:05 +0000245 } else if (ObjCImplementationDecl *ImplD =
246 dyn_cast<ObjCImplementationDecl>(CtxD)) {
Argyrios Kyrtzidisa8cf0be2009-07-21 00:06:36 +0000247 if (ObjCInterfaceDecl *IFD = ImplD->getClassInterface())
248 Redecl = IFD->getMethod(getSelector(), isInstanceMethod());
Argyrios Kyrtzidisa56fa192009-07-28 05:11:05 +0000249
250 } else if (ObjCCategoryImplDecl *CImplD =
251 dyn_cast<ObjCCategoryImplDecl>(CtxD)) {
252 if (ObjCCategoryDecl *CatD = CImplD->getCategoryClass())
253 Redecl = CatD->getMethod(getSelector(), isInstanceMethod());
Argyrios Kyrtzidisa8cf0be2009-07-21 00:06:36 +0000254 }
255
256 return Redecl ? Redecl : this;
257}
258
Argyrios Kyrtzidisf390c432009-07-28 05:11:17 +0000259ObjCMethodDecl *ObjCMethodDecl::getCanonicalDecl() {
260 Decl *CtxD = cast<Decl>(getDeclContext());
261
262 if (ObjCImplementationDecl *ImplD = dyn_cast<ObjCImplementationDecl>(CtxD)) {
263 if (ObjCInterfaceDecl *IFD = ImplD->getClassInterface())
264 if (ObjCMethodDecl *MD = IFD->getMethod(getSelector(),
265 isInstanceMethod()))
266 return MD;
267
268 } else if (ObjCCategoryImplDecl *CImplD =
269 dyn_cast<ObjCCategoryImplDecl>(CtxD)) {
270 if (ObjCCategoryDecl *CatD = CImplD->getCategoryClass())
271 if (ObjCMethodDecl *MD = CatD->getMethod(getSelector(),
272 isInstanceMethod()))
273 return MD;
274 }
275
276 return this;
277}
278
Mike Stump11289f42009-09-09 15:08:12 +0000279void ObjCMethodDecl::createImplicitParams(ASTContext &Context,
Chris Lattnerf1ccb0c2009-02-20 20:59:54 +0000280 const ObjCInterfaceDecl *OID) {
281 QualType selfTy;
282 if (isInstanceMethod()) {
283 // There may be no interface context due to error in declaration
284 // of the interface (which has been reported). Recover gracefully.
285 if (OID) {
Daniel Dunbaraefc2b92009-04-22 04:34:53 +0000286 selfTy = Context.getObjCInterfaceType(OID);
Steve Naroff7cae42b2009-07-10 23:34:53 +0000287 selfTy = Context.getObjCObjectPointerType(selfTy);
Chris Lattnerf1ccb0c2009-02-20 20:59:54 +0000288 } else {
289 selfTy = Context.getObjCIdType();
290 }
291 } else // we have a factory method.
292 selfTy = Context.getObjCClassType();
293
Mike Stump11289f42009-09-09 15:08:12 +0000294 setSelfDecl(ImplicitParamDecl::Create(Context, this, SourceLocation(),
Steve Naroff04f2d142009-04-20 15:06:07 +0000295 &Context.Idents.get("self"), selfTy));
Chris Lattnerf1ccb0c2009-02-20 20:59:54 +0000296
Mike Stump11289f42009-09-09 15:08:12 +0000297 setCmdDecl(ImplicitParamDecl::Create(Context, this, SourceLocation(),
298 &Context.Idents.get("_cmd"),
Steve Naroff04f2d142009-04-20 15:06:07 +0000299 Context.getObjCSelType()));
Chris Lattnerf1ccb0c2009-02-20 20:59:54 +0000300}
301
Chris Lattnerf1ccb0c2009-02-20 20:59:54 +0000302ObjCInterfaceDecl *ObjCMethodDecl::getClassInterface() {
303 if (ObjCInterfaceDecl *ID = dyn_cast<ObjCInterfaceDecl>(getDeclContext()))
304 return ID;
305 if (ObjCCategoryDecl *CD = dyn_cast<ObjCCategoryDecl>(getDeclContext()))
306 return CD->getClassInterface();
Argyrios Kyrtzidis2cee40d2009-07-28 05:10:52 +0000307 if (ObjCImplDecl *IMD = dyn_cast<ObjCImplDecl>(getDeclContext()))
Chris Lattnerf1ccb0c2009-02-20 20:59:54 +0000308 return IMD->getClassInterface();
Argyrios Kyrtzidis2cee40d2009-07-28 05:10:52 +0000309
310 assert(!isa<ObjCProtocolDecl>(getDeclContext()) && "It's a protocol method");
Chris Lattnerf1ccb0c2009-02-20 20:59:54 +0000311 assert(false && "unknown method context");
Fariborz Jahanianfbbaf6a2008-12-05 22:32:48 +0000312 return 0;
313}
314
Chris Lattnerf1ccb0c2009-02-20 20:59:54 +0000315//===----------------------------------------------------------------------===//
316// ObjCInterfaceDecl
317//===----------------------------------------------------------------------===//
318
319ObjCInterfaceDecl *ObjCInterfaceDecl::Create(ASTContext &C,
320 DeclContext *DC,
321 SourceLocation atLoc,
Mike Stump11289f42009-09-09 15:08:12 +0000322 IdentifierInfo *Id,
Chris Lattnerf1ccb0c2009-02-20 20:59:54 +0000323 SourceLocation ClassLoc,
324 bool ForwardDecl, bool isInternal){
325 return new (C) ObjCInterfaceDecl(DC, atLoc, Id, ClassLoc, ForwardDecl,
326 isInternal);
327}
328
329ObjCInterfaceDecl::
330ObjCInterfaceDecl(DeclContext *DC, SourceLocation atLoc, IdentifierInfo *Id,
331 SourceLocation CLoc, bool FD, bool isInternal)
332 : ObjCContainerDecl(ObjCInterface, DC, atLoc, Id),
333 TypeForDecl(0), SuperClass(0),
334 CategoryList(0), ForwardDecl(FD), InternalInterface(isInternal),
335 ClassLoc(CLoc) {
336}
337
Mike Stump11289f42009-09-09 15:08:12 +0000338void ObjCInterfaceDecl::Destroy(ASTContext &C) {
Chris Lattnerd8a47c42009-03-31 08:36:08 +0000339 for (ivar_iterator I = ivar_begin(), E = ivar_end(); I != E; ++I)
Chris Lattnerf1ccb0c2009-02-20 20:59:54 +0000340 if (*I) (*I)->Destroy(C);
Mike Stump11289f42009-09-09 15:08:12 +0000341
Chris Lattner22298722009-02-20 21:35:13 +0000342 IVars.Destroy(C);
Chris Lattnerf1ccb0c2009-02-20 20:59:54 +0000343 // FIXME: CategoryList?
Mike Stump11289f42009-09-09 15:08:12 +0000344
Chris Lattnerf1ccb0c2009-02-20 20:59:54 +0000345 // FIXME: Because there is no clear ownership
346 // role between ObjCInterfaceDecls and the ObjCPropertyDecls that they
347 // reference, we destroy ObjCPropertyDecls in ~TranslationUnit.
348 Decl::Destroy(C);
349}
350
Argyrios Kyrtzidis6d9fab72009-07-21 00:05:53 +0000351ObjCImplementationDecl *ObjCInterfaceDecl::getImplementation() const {
352 return getASTContext().getObjCImplementation(
353 const_cast<ObjCInterfaceDecl*>(this));
354}
355
356void ObjCInterfaceDecl::setImplementation(ObjCImplementationDecl *ImplD) {
357 getASTContext().setObjCImplementation(this, ImplD);
358}
359
Chris Lattnerf1ccb0c2009-02-20 20:59:54 +0000360
361/// FindCategoryDeclaration - Finds category declaration in the list of
362/// categories for this class and returns it. Name of the category is passed
363/// in 'CategoryId'. If category not found, return 0;
Fariborz Jahanianfbbaf6a2008-12-05 22:32:48 +0000364///
Chris Lattnerf1ccb0c2009-02-20 20:59:54 +0000365ObjCCategoryDecl *
366ObjCInterfaceDecl::FindCategoryDeclaration(IdentifierInfo *CategoryId) const {
367 for (ObjCCategoryDecl *Category = getCategoryList();
368 Category; Category = Category->getNextClassCategory())
369 if (Category->getIdentifier() == CategoryId)
370 return Category;
Fariborz Jahanianfbbaf6a2008-12-05 22:32:48 +0000371 return 0;
372}
373
Argyrios Kyrtzidis1559d67b2009-07-21 00:06:20 +0000374ObjCMethodDecl *
375ObjCInterfaceDecl::getCategoryInstanceMethod(Selector Sel) const {
376 for (ObjCCategoryDecl *Category = getCategoryList();
377 Category; Category = Category->getNextClassCategory())
378 if (ObjCCategoryImplDecl *Impl = Category->getImplementation())
379 if (ObjCMethodDecl *MD = Impl->getInstanceMethod(Sel))
380 return MD;
381 return 0;
382}
383
384ObjCMethodDecl *ObjCInterfaceDecl::getCategoryClassMethod(Selector Sel) const {
385 for (ObjCCategoryDecl *Category = getCategoryList();
386 Category; Category = Category->getNextClassCategory())
387 if (ObjCCategoryImplDecl *Impl = Category->getImplementation())
388 if (ObjCMethodDecl *MD = Impl->getClassMethod(Sel))
389 return MD;
390 return 0;
391}
392
Fariborz Jahanian3f8917a2009-08-11 22:02:25 +0000393/// ClassImplementsProtocol - Checks that 'lProto' protocol
394/// has been implemented in IDecl class, its super class or categories (if
395/// lookupCategory is true).
396bool ObjCInterfaceDecl::ClassImplementsProtocol(ObjCProtocolDecl *lProto,
397 bool lookupCategory,
398 bool RHSIsQualifiedID) {
399 ObjCInterfaceDecl *IDecl = this;
400 // 1st, look up the class.
401 const ObjCList<ObjCProtocolDecl> &Protocols =
402 IDecl->getReferencedProtocols();
Mike Stump11289f42009-09-09 15:08:12 +0000403
Fariborz Jahanian3f8917a2009-08-11 22:02:25 +0000404 for (ObjCList<ObjCProtocolDecl>::iterator PI = Protocols.begin(),
405 E = Protocols.end(); PI != E; ++PI) {
406 if (getASTContext().ProtocolCompatibleWithProtocol(lProto, *PI))
407 return true;
408 // This is dubious and is added to be compatible with gcc. In gcc, it is
409 // also allowed assigning a protocol-qualified 'id' type to a LHS object
410 // when protocol in qualified LHS is in list of protocols in the rhs 'id'
411 // object. This IMO, should be a bug.
412 // FIXME: Treat this as an extension, and flag this as an error when GCC
413 // extensions are not enabled.
Mike Stump11289f42009-09-09 15:08:12 +0000414 if (RHSIsQualifiedID &&
Fariborz Jahanian3f8917a2009-08-11 22:02:25 +0000415 getASTContext().ProtocolCompatibleWithProtocol(*PI, lProto))
416 return true;
417 }
Mike Stump11289f42009-09-09 15:08:12 +0000418
Fariborz Jahanian3f8917a2009-08-11 22:02:25 +0000419 // 2nd, look up the category.
420 if (lookupCategory)
421 for (ObjCCategoryDecl *CDecl = IDecl->getCategoryList(); CDecl;
422 CDecl = CDecl->getNextClassCategory()) {
423 for (ObjCCategoryDecl::protocol_iterator PI = CDecl->protocol_begin(),
424 E = CDecl->protocol_end(); PI != E; ++PI)
425 if (getASTContext().ProtocolCompatibleWithProtocol(lProto, *PI))
426 return true;
427 }
Mike Stump11289f42009-09-09 15:08:12 +0000428
Fariborz Jahanian3f8917a2009-08-11 22:02:25 +0000429 // 3rd, look up the super class(s)
430 if (IDecl->getSuperClass())
431 return
432 IDecl->getSuperClass()->ClassImplementsProtocol(lProto, lookupCategory,
433 RHSIsQualifiedID);
Mike Stump11289f42009-09-09 15:08:12 +0000434
Fariborz Jahanian3f8917a2009-08-11 22:02:25 +0000435 return false;
436}
437
Chris Lattnerf1ccb0c2009-02-20 20:59:54 +0000438//===----------------------------------------------------------------------===//
439// ObjCIvarDecl
440//===----------------------------------------------------------------------===//
441
442ObjCIvarDecl *ObjCIvarDecl::Create(ASTContext &C, DeclContext *DC,
443 SourceLocation L, IdentifierInfo *Id,
Argyrios Kyrtzidis60ed5602009-08-19 01:27:57 +0000444 QualType T, DeclaratorInfo *DInfo,
445 AccessControl ac, Expr *BW) {
446 return new (C) ObjCIvarDecl(DC, L, Id, T, DInfo, ac, BW);
Chris Lattnerf1ccb0c2009-02-20 20:59:54 +0000447}
448
449
450
451//===----------------------------------------------------------------------===//
452// ObjCAtDefsFieldDecl
453//===----------------------------------------------------------------------===//
454
455ObjCAtDefsFieldDecl
456*ObjCAtDefsFieldDecl::Create(ASTContext &C, DeclContext *DC, SourceLocation L,
457 IdentifierInfo *Id, QualType T, Expr *BW) {
458 return new (C) ObjCAtDefsFieldDecl(DC, L, Id, T, BW);
459}
460
461void ObjCAtDefsFieldDecl::Destroy(ASTContext& C) {
462 this->~ObjCAtDefsFieldDecl();
Mike Stump11289f42009-09-09 15:08:12 +0000463 C.Deallocate((void *)this);
Chris Lattnerf1ccb0c2009-02-20 20:59:54 +0000464}
465
466//===----------------------------------------------------------------------===//
467// ObjCProtocolDecl
468//===----------------------------------------------------------------------===//
469
470ObjCProtocolDecl *ObjCProtocolDecl::Create(ASTContext &C, DeclContext *DC,
Mike Stump11289f42009-09-09 15:08:12 +0000471 SourceLocation L,
Chris Lattnerf1ccb0c2009-02-20 20:59:54 +0000472 IdentifierInfo *Id) {
473 return new (C) ObjCProtocolDecl(DC, L, Id);
474}
475
476void ObjCProtocolDecl::Destroy(ASTContext &C) {
Chris Lattner22298722009-02-20 21:35:13 +0000477 ReferencedProtocols.Destroy(C);
Chris Lattnerf1ccb0c2009-02-20 20:59:54 +0000478 ObjCContainerDecl::Destroy(C);
479}
480
Steve Naroff114aecb2009-03-01 16:12:44 +0000481ObjCProtocolDecl *ObjCProtocolDecl::lookupProtocolNamed(IdentifierInfo *Name) {
482 ObjCProtocolDecl *PDecl = this;
483
484 if (Name == getIdentifier())
485 return PDecl;
486
487 for (protocol_iterator I = protocol_begin(), E = protocol_end(); I != E; ++I)
488 if ((PDecl = (*I)->lookupProtocolNamed(Name)))
489 return PDecl;
Mike Stump11289f42009-09-09 15:08:12 +0000490
Steve Naroff114aecb2009-03-01 16:12:44 +0000491 return NULL;
492}
493
Argyrios Kyrtzidise6ed65b2009-07-25 22:15:38 +0000494// lookupMethod - Lookup a instance/class method in the protocol and protocols
Chris Lattnerf1ccb0c2009-02-20 20:59:54 +0000495// it inherited.
Argyrios Kyrtzidise6ed65b2009-07-25 22:15:38 +0000496ObjCMethodDecl *ObjCProtocolDecl::lookupMethod(Selector Sel,
497 bool isInstance) const {
Chris Lattnerf1ccb0c2009-02-20 20:59:54 +0000498 ObjCMethodDecl *MethodDecl = NULL;
Mike Stump11289f42009-09-09 15:08:12 +0000499
Argyrios Kyrtzidise6ed65b2009-07-25 22:15:38 +0000500 if ((MethodDecl = getMethod(Sel, isInstance)))
Chris Lattnerf1ccb0c2009-02-20 20:59:54 +0000501 return MethodDecl;
Mike Stump11289f42009-09-09 15:08:12 +0000502
Chris Lattnerf1ccb0c2009-02-20 20:59:54 +0000503 for (protocol_iterator I = protocol_begin(), E = protocol_end(); I != E; ++I)
Argyrios Kyrtzidise6ed65b2009-07-25 22:15:38 +0000504 if ((MethodDecl = (*I)->lookupMethod(Sel, isInstance)))
Chris Lattnerf1ccb0c2009-02-20 20:59:54 +0000505 return MethodDecl;
506 return NULL;
507}
508
509//===----------------------------------------------------------------------===//
510// ObjCClassDecl
511//===----------------------------------------------------------------------===//
512
Mike Stump11289f42009-09-09 15:08:12 +0000513ObjCClassDecl::ObjCClassDecl(DeclContext *DC, SourceLocation L,
Chris Lattner22298722009-02-20 21:35:13 +0000514 ObjCInterfaceDecl *const *Elts, unsigned nElts,
515 ASTContext &C)
516 : Decl(ObjCClass, DC, L) {
517 ForwardDecls.set(Elts, nElts, C);
518}
519
520
Chris Lattnerf1ccb0c2009-02-20 20:59:54 +0000521ObjCClassDecl *ObjCClassDecl::Create(ASTContext &C, DeclContext *DC,
522 SourceLocation L,
523 ObjCInterfaceDecl *const *Elts,
524 unsigned nElts) {
Chris Lattner22298722009-02-20 21:35:13 +0000525 return new (C) ObjCClassDecl(DC, L, Elts, nElts, C);
Chris Lattnerf1ccb0c2009-02-20 20:59:54 +0000526}
527
528void ObjCClassDecl::Destroy(ASTContext &C) {
Mike Stump11289f42009-09-09 15:08:12 +0000529
Chris Lattnerf1ccb0c2009-02-20 20:59:54 +0000530 // FIXME: There is no clear ownership policy now for referenced
531 // ObjCInterfaceDecls. Some of them can be forward declarations that
532 // are never later defined (in which case the ObjCClassDecl owns them)
533 // or the ObjCInterfaceDecl later becomes a real definition later. Ideally
534 // we should have separate objects for forward declarations and definitions,
535 // obviating this problem. Because of this situation, referenced
536 // ObjCInterfaceDecls are destroyed in ~TranslationUnit.
Mike Stump11289f42009-09-09 15:08:12 +0000537
Chris Lattner22298722009-02-20 21:35:13 +0000538 ForwardDecls.Destroy(C);
Chris Lattnerf1ccb0c2009-02-20 20:59:54 +0000539 Decl::Destroy(C);
540}
541
542//===----------------------------------------------------------------------===//
543// ObjCForwardProtocolDecl
544//===----------------------------------------------------------------------===//
545
Chris Lattner22298722009-02-20 21:35:13 +0000546ObjCForwardProtocolDecl::
547ObjCForwardProtocolDecl(DeclContext *DC, SourceLocation L,
548 ObjCProtocolDecl *const *Elts, unsigned nElts,
549 ASTContext &C)
Mike Stump11289f42009-09-09 15:08:12 +0000550: Decl(ObjCForwardProtocol, DC, L) {
Chris Lattner22298722009-02-20 21:35:13 +0000551 ReferencedProtocols.set(Elts, nElts, C);
552}
553
554
Chris Lattnerf1ccb0c2009-02-20 20:59:54 +0000555ObjCForwardProtocolDecl *
556ObjCForwardProtocolDecl::Create(ASTContext &C, DeclContext *DC,
Mike Stump11289f42009-09-09 15:08:12 +0000557 SourceLocation L,
Chris Lattnerf1ccb0c2009-02-20 20:59:54 +0000558 ObjCProtocolDecl *const *Elts,
559 unsigned NumElts) {
Chris Lattner22298722009-02-20 21:35:13 +0000560 return new (C) ObjCForwardProtocolDecl(DC, L, Elts, NumElts, C);
Chris Lattnerf1ccb0c2009-02-20 20:59:54 +0000561}
562
563void ObjCForwardProtocolDecl::Destroy(ASTContext &C) {
Chris Lattner22298722009-02-20 21:35:13 +0000564 ReferencedProtocols.Destroy(C);
Chris Lattnerf1ccb0c2009-02-20 20:59:54 +0000565 Decl::Destroy(C);
566}
567
568//===----------------------------------------------------------------------===//
569// ObjCCategoryDecl
570//===----------------------------------------------------------------------===//
571
572ObjCCategoryDecl *ObjCCategoryDecl::Create(ASTContext &C, DeclContext *DC,
573 SourceLocation L,
574 IdentifierInfo *Id) {
575 return new (C) ObjCCategoryDecl(DC, L, Id);
576}
577
Argyrios Kyrtzidis6d9fab72009-07-21 00:05:53 +0000578ObjCCategoryImplDecl *ObjCCategoryDecl::getImplementation() const {
579 return getASTContext().getObjCImplementation(
580 const_cast<ObjCCategoryDecl*>(this));
581}
582
583void ObjCCategoryDecl::setImplementation(ObjCCategoryImplDecl *ImplD) {
584 getASTContext().setObjCImplementation(this, ImplD);
585}
586
587
Chris Lattnerf1ccb0c2009-02-20 20:59:54 +0000588//===----------------------------------------------------------------------===//
589// ObjCCategoryImplDecl
590//===----------------------------------------------------------------------===//
591
592ObjCCategoryImplDecl *
593ObjCCategoryImplDecl::Create(ASTContext &C, DeclContext *DC,
594 SourceLocation L,IdentifierInfo *Id,
595 ObjCInterfaceDecl *ClassInterface) {
596 return new (C) ObjCCategoryImplDecl(DC, L, Id, ClassInterface);
597}
598
Argyrios Kyrtzidisa56fa192009-07-28 05:11:05 +0000599ObjCCategoryDecl *ObjCCategoryImplDecl::getCategoryClass() const {
600 return getClassInterface()->FindCategoryDeclaration(getIdentifier());
601}
602
Chris Lattnerf1ccb0c2009-02-20 20:59:54 +0000603
Argyrios Kyrtzidiscfbfe782009-06-30 02:36:12 +0000604void ObjCImplDecl::addPropertyImplementation(ObjCPropertyImplDecl *property) {
Douglas Gregor9a13efd2009-04-23 02:42:49 +0000605 // FIXME: The context should be correct before we get here.
Douglas Gregor29bd76f2009-04-23 01:02:12 +0000606 property->setLexicalDeclContext(this);
Argyrios Kyrtzidiscfbfe782009-06-30 02:36:12 +0000607 addDecl(property);
Douglas Gregor29bd76f2009-04-23 01:02:12 +0000608}
609
Argyrios Kyrtzidis6d9fab72009-07-21 00:05:53 +0000610void ObjCImplDecl::setClassInterface(ObjCInterfaceDecl *IFace) {
611 ASTContext &Ctx = getASTContext();
612
613 if (ObjCImplementationDecl *ImplD
Duncan Sands49c29ee2009-07-21 07:56:29 +0000614 = dyn_cast_or_null<ObjCImplementationDecl>(this)) {
Argyrios Kyrtzidis6d9fab72009-07-21 00:05:53 +0000615 if (IFace)
616 Ctx.setObjCImplementation(IFace, ImplD);
617
Duncan Sands49c29ee2009-07-21 07:56:29 +0000618 } else if (ObjCCategoryImplDecl *ImplD =
Argyrios Kyrtzidis6d9fab72009-07-21 00:05:53 +0000619 dyn_cast_or_null<ObjCCategoryImplDecl>(this)) {
620 if (ObjCCategoryDecl *CD = IFace->FindCategoryDeclaration(getIdentifier()))
621 Ctx.setObjCImplementation(CD, ImplD);
622 }
623
624 ClassInterface = IFace;
625}
626
Fariborz Jahanianfbbaf6a2008-12-05 22:32:48 +0000627/// FindPropertyImplIvarDecl - This method lookup the ivar in the list of
Chris Lattneraab70d22009-02-16 19:24:31 +0000628/// properties implemented in this category @implementation block and returns
629/// the implemented property that uses it.
Fariborz Jahanianfbbaf6a2008-12-05 22:32:48 +0000630///
Chris Lattnera9ca0522009-02-28 18:42:10 +0000631ObjCPropertyImplDecl *ObjCImplDecl::
Argyrios Kyrtzidiscfbfe782009-06-30 02:36:12 +0000632FindPropertyImplIvarDecl(IdentifierInfo *ivarId) const {
633 for (propimpl_iterator i = propimpl_begin(), e = propimpl_end(); i != e; ++i){
Fariborz Jahanianfbbaf6a2008-12-05 22:32:48 +0000634 ObjCPropertyImplDecl *PID = *i;
635 if (PID->getPropertyIvarDecl() &&
636 PID->getPropertyIvarDecl()->getIdentifier() == ivarId)
637 return PID;
638 }
639 return 0;
640}
641
642/// FindPropertyImplDecl - This method looks up a previous ObjCPropertyImplDecl
643/// added to the list of those properties @synthesized/@dynamic in this
644/// category @implementation block.
645///
Chris Lattnera9ca0522009-02-28 18:42:10 +0000646ObjCPropertyImplDecl *ObjCImplDecl::
Argyrios Kyrtzidiscfbfe782009-06-30 02:36:12 +0000647FindPropertyImplDecl(IdentifierInfo *Id) const {
648 for (propimpl_iterator i = propimpl_begin(), e = propimpl_end(); i != e; ++i){
Fariborz Jahanianfbbaf6a2008-12-05 22:32:48 +0000649 ObjCPropertyImplDecl *PID = *i;
650 if (PID->getPropertyDecl()->getIdentifier() == Id)
651 return PID;
652 }
653 return 0;
654}
655
Chris Lattnerf1ccb0c2009-02-20 20:59:54 +0000656//===----------------------------------------------------------------------===//
657// ObjCImplementationDecl
658//===----------------------------------------------------------------------===//
659
660ObjCImplementationDecl *
Mike Stump11289f42009-09-09 15:08:12 +0000661ObjCImplementationDecl::Create(ASTContext &C, DeclContext *DC,
Chris Lattnerf1ccb0c2009-02-20 20:59:54 +0000662 SourceLocation L,
663 ObjCInterfaceDecl *ClassInterface,
664 ObjCInterfaceDecl *SuperDecl) {
665 return new (C) ObjCImplementationDecl(DC, L, ClassInterface, SuperDecl);
666}
667
Chris Lattnerf1ccb0c2009-02-20 20:59:54 +0000668//===----------------------------------------------------------------------===//
669// ObjCCompatibleAliasDecl
670//===----------------------------------------------------------------------===//
671
672ObjCCompatibleAliasDecl *
673ObjCCompatibleAliasDecl::Create(ASTContext &C, DeclContext *DC,
674 SourceLocation L,
Mike Stump11289f42009-09-09 15:08:12 +0000675 IdentifierInfo *Id,
Chris Lattnerf1ccb0c2009-02-20 20:59:54 +0000676 ObjCInterfaceDecl* AliasedClass) {
677 return new (C) ObjCCompatibleAliasDecl(DC, L, Id, AliasedClass);
678}
679
680//===----------------------------------------------------------------------===//
681// ObjCPropertyDecl
682//===----------------------------------------------------------------------===//
683
684ObjCPropertyDecl *ObjCPropertyDecl::Create(ASTContext &C, DeclContext *DC,
685 SourceLocation L,
686 IdentifierInfo *Id,
687 QualType T,
688 PropertyControl propControl) {
689 return new (C) ObjCPropertyDecl(DC, L, Id, T);
690}
691
692
693//===----------------------------------------------------------------------===//
694// ObjCPropertyImplDecl
695//===----------------------------------------------------------------------===//
696
Fariborz Jahanian6efdf1d2008-04-23 00:06:01 +0000697ObjCPropertyImplDecl *ObjCPropertyImplDecl::Create(ASTContext &C,
Douglas Gregorc25d7a72009-01-09 00:49:46 +0000698 DeclContext *DC,
Fariborz Jahanian6efdf1d2008-04-23 00:06:01 +0000699 SourceLocation atLoc,
700 SourceLocation L,
701 ObjCPropertyDecl *property,
Daniel Dunbar3b4fdb02008-08-26 04:47:31 +0000702 Kind PK,
Fariborz Jahanian6efdf1d2008-04-23 00:06:01 +0000703 ObjCIvarDecl *ivar) {
Steve Naroff13ae6f42009-01-27 21:25:57 +0000704 return new (C) ObjCPropertyImplDecl(DC, atLoc, L, property, PK, ivar);
Fariborz Jahanian6efdf1d2008-04-23 00:06:01 +0000705}
Chris Lattnered0e1642008-03-17 01:19:02 +0000706
Chris Lattnerc5ffed42008-04-04 06:12:32 +0000707