blob: 21aefdd567bc380c1ca65c88039131e47525061c [file] [log] [blame]
Chris Lattner1e03a562008-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 Dunbare91593e2008-08-11 04:54:23 +000016#include "clang/AST/Stmt.h"
Steve Naroff0de21fd2009-02-22 19:35:57 +000017#include "llvm/ADT/STLExtras.h"
Chris Lattner1e03a562008-03-16 00:19:01 +000018using namespace clang;
19
Chris Lattner6c4ae5d2008-03-16 00:49:28 +000020//===----------------------------------------------------------------------===//
Chris Lattner11e1e1a2009-02-20 21:16:26 +000021// ObjCListBase
22//===----------------------------------------------------------------------===//
23
Chris Lattner38af2de2009-02-20 21:35:13 +000024void ObjCListBase::Destroy(ASTContext &Ctx) {
Chris Lattner4ee413b2009-02-20 21:44:01 +000025 Ctx.Deallocate(List);
Chris Lattner11e1e1a2009-02-20 21:16:26 +000026 NumElts = 0;
27 List = 0;
28}
29
Chris Lattner38af2de2009-02-20 21:35:13 +000030void ObjCListBase::set(void *const* InList, unsigned Elts, ASTContext &Ctx) {
Chris Lattner11e1e1a2009-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.
33
Chris Lattner4ee413b2009-02-20 21:44:01 +000034
35 List = new (Ctx) void*[Elts];
Chris Lattner11e1e1a2009-02-20 21:16:26 +000036 NumElts = Elts;
37 memcpy(List, InList, sizeof(void*)*Elts);
38}
39
40
41//===----------------------------------------------------------------------===//
Chris Lattnerab351632009-02-20 20:59:54 +000042// ObjCInterfaceDecl
Chris Lattner6c4ae5d2008-03-16 00:49:28 +000043//===----------------------------------------------------------------------===//
44
Fariborz Jahanian496b5a82009-06-05 18:16:35 +000045/// getIvarDecl - This method looks up an ivar in this ContextDecl.
46///
47ObjCIvarDecl *
48ObjCContainerDecl::getIvarDecl(ASTContext &Context, IdentifierInfo *Id) const {
49 lookup_const_iterator Ivar, IvarEnd;
50 for (llvm::tie(Ivar, IvarEnd) = lookup(Context, Id);
51 Ivar != IvarEnd; ++Ivar) {
52 if (ObjCIvarDecl *ivar = dyn_cast<ObjCIvarDecl>(*Ivar))
53 return ivar;
54 }
55 return 0;
56}
57
Steve Naroff0701bbb2009-01-08 17:28:14 +000058// Get the local instance method declared in this interface.
Douglas Gregor6ab35242009-04-09 21:40:53 +000059ObjCMethodDecl *
60ObjCContainerDecl::getInstanceMethod(ASTContext &Context, Selector Sel) const {
Steve Naroff0de21fd2009-02-22 19:35:57 +000061 // Since instance & class methods can have the same name, the loop below
62 // ensures we get the correct method.
63 //
64 // @interface Whatever
65 // - (int) class_method;
66 // + (float) class_method;
67 // @end
68 //
69 lookup_const_iterator Meth, MethEnd;
Douglas Gregor6ab35242009-04-09 21:40:53 +000070 for (llvm::tie(Meth, MethEnd) = lookup(Context, Sel);
Steve Naroff0de21fd2009-02-22 19:35:57 +000071 Meth != MethEnd; ++Meth) {
72 ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(*Meth);
73 if (MD && MD->isInstanceMethod())
74 return MD;
75 }
Steve Naroff0701bbb2009-01-08 17:28:14 +000076 return 0;
77}
78
79// Get the local class method declared in this interface.
Douglas Gregor6ab35242009-04-09 21:40:53 +000080ObjCMethodDecl *
81ObjCContainerDecl::getClassMethod(ASTContext &Context, Selector Sel) const {
Steve Naroff0de21fd2009-02-22 19:35:57 +000082 // Since instance & class methods can have the same name, the loop below
83 // ensures we get the correct method.
84 //
85 // @interface Whatever
86 // - (int) class_method;
87 // + (float) class_method;
88 // @end
89 //
90 lookup_const_iterator Meth, MethEnd;
Douglas Gregor6ab35242009-04-09 21:40:53 +000091 for (llvm::tie(Meth, MethEnd) = lookup(Context, Sel);
Steve Naroff0de21fd2009-02-22 19:35:57 +000092 Meth != MethEnd; ++Meth) {
93 ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(*Meth);
94 if (MD && MD->isClassMethod())
95 return MD;
96 }
Steve Naroff0701bbb2009-01-08 17:28:14 +000097 return 0;
98}
99
Fariborz Jahanian559c0c42008-04-21 19:04:53 +0000100/// FindPropertyDeclaration - Finds declaration of the property given its name
101/// in 'PropertyId' and returns it. It returns 0, if not found.
Steve Naroff93983f82009-01-11 12:47:58 +0000102/// FIXME: Convert to DeclContext lookup...
Fariborz Jahanian559c0c42008-04-21 19:04:53 +0000103///
104ObjCPropertyDecl *
Douglas Gregor6ab35242009-04-09 21:40:53 +0000105ObjCContainerDecl::FindPropertyDeclaration(ASTContext &Context,
106 IdentifierInfo *PropertyId) const {
107 for (prop_iterator I = prop_begin(Context), E = prop_end(Context);
108 I != E; ++I)
Chris Lattnerab351632009-02-20 20:59:54 +0000109 if ((*I)->getIdentifier() == PropertyId)
110 return *I;
111
Fariborz Jahaniana66793e2009-01-09 21:04:52 +0000112 const ObjCProtocolDecl *PID = dyn_cast<ObjCProtocolDecl>(this);
113 if (PID) {
Chris Lattnerab351632009-02-20 20:59:54 +0000114 for (ObjCProtocolDecl::protocol_iterator I = PID->protocol_begin(),
115 E = PID->protocol_end(); I != E; ++I)
Douglas Gregor6ab35242009-04-09 21:40:53 +0000116 if (ObjCPropertyDecl *P = (*I)->FindPropertyDeclaration(Context,
117 PropertyId))
Chris Lattnerab351632009-02-20 20:59:54 +0000118 return P;
Fariborz Jahaniana66793e2009-01-09 21:04:52 +0000119 }
120
Fariborz Jahanianf034e9c2009-01-19 18:16:19 +0000121 if (const ObjCInterfaceDecl *OID = dyn_cast<ObjCInterfaceDecl>(this)) {
Steve Naroff09c47192009-01-09 15:36:25 +0000122 // Look through categories.
123 for (ObjCCategoryDecl *Category = OID->getCategoryList();
124 Category; Category = Category->getNextClassCategory()) {
Douglas Gregor6ab35242009-04-09 21:40:53 +0000125 if (ObjCPropertyDecl *P = Category->FindPropertyDeclaration(Context,
126 PropertyId))
Chris Lattnerab351632009-02-20 20:59:54 +0000127 return P;
Steve Naroff09c47192009-01-09 15:36:25 +0000128 }
129 // Look through protocols.
130 for (ObjCInterfaceDecl::protocol_iterator I = OID->protocol_begin(),
131 E = OID->protocol_end(); I != E; ++I) {
Douglas Gregor6ab35242009-04-09 21:40:53 +0000132 if (ObjCPropertyDecl *P = (*I)->FindPropertyDeclaration(Context,
133 PropertyId))
Chris Lattnerab351632009-02-20 20:59:54 +0000134 return P;
Steve Naroff09c47192009-01-09 15:36:25 +0000135 }
136 if (OID->getSuperClass())
Douglas Gregor6ab35242009-04-09 21:40:53 +0000137 return OID->getSuperClass()->FindPropertyDeclaration(Context,
138 PropertyId);
Chris Lattnerab351632009-02-20 20:59:54 +0000139 } else if (const ObjCCategoryDecl *OCD = dyn_cast<ObjCCategoryDecl>(this)) {
Fariborz Jahanianf034e9c2009-01-19 18:16:19 +0000140 // Look through protocols.
141 for (ObjCInterfaceDecl::protocol_iterator I = OCD->protocol_begin(),
142 E = OCD->protocol_end(); I != E; ++I) {
Douglas Gregor6ab35242009-04-09 21:40:53 +0000143 if (ObjCPropertyDecl *P = (*I)->FindPropertyDeclaration(Context,
144 PropertyId))
Chris Lattnerab351632009-02-20 20:59:54 +0000145 return P;
Fariborz Jahanianf034e9c2009-01-19 18:16:19 +0000146 }
147 }
Steve Naroff3d2c22b2008-06-05 13:55:23 +0000148 return 0;
149}
150
Chris Lattner1e03a562008-03-16 00:19:01 +0000151ObjCIvarDecl *ObjCInterfaceDecl::lookupInstanceVariable(
Douglas Gregor6ab35242009-04-09 21:40:53 +0000152 ASTContext &Context, IdentifierInfo *ID, ObjCInterfaceDecl *&clsDeclared) {
Chris Lattner1e03a562008-03-16 00:19:01 +0000153 ObjCInterfaceDecl* ClassDecl = this;
154 while (ClassDecl != NULL) {
Fariborz Jahanian496b5a82009-06-05 18:16:35 +0000155 if (ObjCIvarDecl *I = ClassDecl->getIvarDecl(Context, ID)) {
156 clsDeclared = ClassDecl;
157 return I;
Chris Lattner1e03a562008-03-16 00:19:01 +0000158 }
Fariborz Jahanianaf3e7222009-03-31 00:06:29 +0000159 // look into properties.
Douglas Gregor6ab35242009-04-09 21:40:53 +0000160 for (ObjCInterfaceDecl::prop_iterator I = ClassDecl->prop_begin(Context),
161 E = ClassDecl->prop_end(Context); I != E; ++I) {
Fariborz Jahanianaf3e7222009-03-31 00:06:29 +0000162 ObjCPropertyDecl *PDecl = (*I);
163 if (ObjCIvarDecl *IV = PDecl->getPropertyIvarDecl())
164 if (IV->getIdentifier() == ID) {
165 clsDeclared = ClassDecl;
166 return IV;
167 }
168 }
Chris Lattner1e03a562008-03-16 00:19:01 +0000169 ClassDecl = ClassDecl->getSuperClass();
170 }
171 return NULL;
172}
173
Fariborz Jahaniancd187622009-05-22 17:12:32 +0000174/// lookupInheritedClass - This method returns ObjCInterfaceDecl * of the super
175/// class whose name is passed as argument. If it is not one of the super classes
176/// the it returns NULL.
177ObjCInterfaceDecl *ObjCInterfaceDecl::lookupInheritedClass(
178 const IdentifierInfo*ICName) {
179 ObjCInterfaceDecl* ClassDecl = this;
180 while (ClassDecl != NULL) {
181 if (ClassDecl->getIdentifier() == ICName)
182 return ClassDecl;
183 ClassDecl = ClassDecl->getSuperClass();
184 }
185 return NULL;
186}
187
Chris Lattner1e03a562008-03-16 00:19:01 +0000188/// lookupInstanceMethod - This method returns an instance method by looking in
189/// the class, its categories, and its super classes (using a linear search).
Douglas Gregor6ab35242009-04-09 21:40:53 +0000190ObjCMethodDecl *ObjCInterfaceDecl::lookupInstanceMethod(ASTContext &Context,
191 Selector Sel) {
Chris Lattner1e03a562008-03-16 00:19:01 +0000192 ObjCInterfaceDecl* ClassDecl = this;
193 ObjCMethodDecl *MethodDecl = 0;
194
195 while (ClassDecl != NULL) {
Douglas Gregor6ab35242009-04-09 21:40:53 +0000196 if ((MethodDecl = ClassDecl->getInstanceMethod(Context, Sel)))
Chris Lattner1e03a562008-03-16 00:19:01 +0000197 return MethodDecl;
198
199 // Didn't find one yet - look through protocols.
Chris Lattner3db6cae2008-07-21 18:19:38 +0000200 const ObjCList<ObjCProtocolDecl> &Protocols =
201 ClassDecl->getReferencedProtocols();
202 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
203 E = Protocols.end(); I != E; ++I)
Douglas Gregor6ab35242009-04-09 21:40:53 +0000204 if ((MethodDecl = (*I)->lookupInstanceMethod(Context, Sel)))
Chris Lattner1e03a562008-03-16 00:19:01 +0000205 return MethodDecl;
Chris Lattner3db6cae2008-07-21 18:19:38 +0000206
Chris Lattner1e03a562008-03-16 00:19:01 +0000207 // Didn't find one yet - now look through categories.
208 ObjCCategoryDecl *CatDecl = ClassDecl->getCategoryList();
209 while (CatDecl) {
Douglas Gregor6ab35242009-04-09 21:40:53 +0000210 if ((MethodDecl = CatDecl->getInstanceMethod(Context, Sel)))
Chris Lattner1e03a562008-03-16 00:19:01 +0000211 return MethodDecl;
Steve Naroffb79c01e2008-12-08 20:57:28 +0000212
213 // Didn't find one yet - look through protocols.
214 const ObjCList<ObjCProtocolDecl> &Protocols =
215 CatDecl->getReferencedProtocols();
216 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
217 E = Protocols.end(); I != E; ++I)
Douglas Gregor6ab35242009-04-09 21:40:53 +0000218 if ((MethodDecl = (*I)->lookupInstanceMethod(Context, Sel)))
Steve Naroffb79c01e2008-12-08 20:57:28 +0000219 return MethodDecl;
Chris Lattner1e03a562008-03-16 00:19:01 +0000220 CatDecl = CatDecl->getNextClassCategory();
221 }
222 ClassDecl = ClassDecl->getSuperClass();
223 }
224 return NULL;
225}
226
227// lookupClassMethod - This method returns a class method by looking in the
228// class, its categories, and its super classes (using a linear search).
Douglas Gregor6ab35242009-04-09 21:40:53 +0000229ObjCMethodDecl *ObjCInterfaceDecl::lookupClassMethod(ASTContext &Context,
230 Selector Sel) {
Chris Lattner1e03a562008-03-16 00:19:01 +0000231 ObjCInterfaceDecl* ClassDecl = this;
232 ObjCMethodDecl *MethodDecl = 0;
233
234 while (ClassDecl != NULL) {
Douglas Gregor6ab35242009-04-09 21:40:53 +0000235 if ((MethodDecl = ClassDecl->getClassMethod(Context, Sel)))
Chris Lattner1e03a562008-03-16 00:19:01 +0000236 return MethodDecl;
237
238 // Didn't find one yet - look through protocols.
Chris Lattner780f3292008-07-21 21:32:27 +0000239 for (ObjCInterfaceDecl::protocol_iterator I = ClassDecl->protocol_begin(),
240 E = ClassDecl->protocol_end(); I != E; ++I)
Douglas Gregor6ab35242009-04-09 21:40:53 +0000241 if ((MethodDecl = (*I)->lookupClassMethod(Context, Sel)))
Chris Lattner1e03a562008-03-16 00:19:01 +0000242 return MethodDecl;
Chris Lattner780f3292008-07-21 21:32:27 +0000243
Chris Lattner1e03a562008-03-16 00:19:01 +0000244 // Didn't find one yet - now look through categories.
245 ObjCCategoryDecl *CatDecl = ClassDecl->getCategoryList();
246 while (CatDecl) {
Douglas Gregor6ab35242009-04-09 21:40:53 +0000247 if ((MethodDecl = CatDecl->getClassMethod(Context, Sel)))
Chris Lattner1e03a562008-03-16 00:19:01 +0000248 return MethodDecl;
Steve Naroffb5584222009-02-26 11:32:02 +0000249
250 // Didn't find one yet - look through protocols.
251 const ObjCList<ObjCProtocolDecl> &Protocols =
252 CatDecl->getReferencedProtocols();
253 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
254 E = Protocols.end(); I != E; ++I)
Douglas Gregor6ab35242009-04-09 21:40:53 +0000255 if ((MethodDecl = (*I)->lookupClassMethod(Context, Sel)))
Steve Naroffb5584222009-02-26 11:32:02 +0000256 return MethodDecl;
Chris Lattner1e03a562008-03-16 00:19:01 +0000257 CatDecl = CatDecl->getNextClassCategory();
258 }
259 ClassDecl = ClassDecl->getSuperClass();
260 }
261 return NULL;
262}
263
Chris Lattnerab351632009-02-20 20:59:54 +0000264
265
266//===----------------------------------------------------------------------===//
267// ObjCMethodDecl
268//===----------------------------------------------------------------------===//
269
270ObjCMethodDecl *ObjCMethodDecl::Create(ASTContext &C,
271 SourceLocation beginLoc,
272 SourceLocation endLoc,
273 Selector SelInfo, QualType T,
274 DeclContext *contextDecl,
275 bool isInstance,
276 bool isVariadic,
277 bool isSynthesized,
278 ImplementationControl impControl) {
279 return new (C) ObjCMethodDecl(beginLoc, endLoc,
280 SelInfo, T, contextDecl,
281 isInstance,
282 isVariadic, isSynthesized, impControl);
Chris Lattner1e03a562008-03-16 00:19:01 +0000283}
284
Chris Lattner38af2de2009-02-20 21:35:13 +0000285void ObjCMethodDecl::Destroy(ASTContext &C) {
Chris Lattnerab351632009-02-20 20:59:54 +0000286 if (Body) Body->Destroy(C);
287 if (SelfDecl) SelfDecl->Destroy(C);
288
289 for (param_iterator I=param_begin(), E=param_end(); I!=E; ++I)
290 if (*I) (*I)->Destroy(C);
291
Chris Lattner38af2de2009-02-20 21:35:13 +0000292 ParamInfo.Destroy(C);
Chris Lattnerab351632009-02-20 20:59:54 +0000293
294 Decl::Destroy(C);
Chris Lattner1e03a562008-03-16 00:19:01 +0000295}
296
Chris Lattnerab351632009-02-20 20:59:54 +0000297void ObjCMethodDecl::createImplicitParams(ASTContext &Context,
298 const ObjCInterfaceDecl *OID) {
299 QualType selfTy;
300 if (isInstanceMethod()) {
301 // There may be no interface context due to error in declaration
302 // of the interface (which has been reported). Recover gracefully.
303 if (OID) {
Daniel Dunbar3b3a4582009-04-22 04:34:53 +0000304 selfTy = Context.getObjCInterfaceType(OID);
Chris Lattnerab351632009-02-20 20:59:54 +0000305 selfTy = Context.getPointerType(selfTy);
306 } else {
307 selfTy = Context.getObjCIdType();
308 }
309 } else // we have a factory method.
310 selfTy = Context.getObjCClassType();
311
Steve Naroff53c9d8a2009-04-20 15:06:07 +0000312 setSelfDecl(ImplicitParamDecl::Create(Context, this, SourceLocation(),
313 &Context.Idents.get("self"), selfTy));
Chris Lattnerab351632009-02-20 20:59:54 +0000314
Steve Naroff53c9d8a2009-04-20 15:06:07 +0000315 setCmdDecl(ImplicitParamDecl::Create(Context, this, SourceLocation(),
316 &Context.Idents.get("_cmd"),
317 Context.getObjCSelType()));
Chris Lattnerab351632009-02-20 20:59:54 +0000318}
319
320
321
322/// getSynthesizedMethodSize - Compute size of synthesized method name
323/// as done be the rewrite.
Fariborz Jahanianae6f6fd2008-12-05 22:32:48 +0000324///
Chris Lattnerab351632009-02-20 20:59:54 +0000325unsigned ObjCMethodDecl::getSynthesizedMethodSize() const {
326 // syntesized method name is a concatenation of -/+[class-name selector]
327 // Get length of this name.
328 unsigned length = 3; // _I_ or _C_
329 length += getClassInterface()->getNameAsString().size()+1; // extra for _
330 if (const ObjCCategoryImplDecl *CID =
331 dyn_cast<ObjCCategoryImplDecl>(getDeclContext()))
332 length += CID->getNameAsString().size()+1;
333 length += getSelector().getAsString().size(); // selector name
334 return length;
335}
336
337ObjCInterfaceDecl *ObjCMethodDecl::getClassInterface() {
338 if (ObjCInterfaceDecl *ID = dyn_cast<ObjCInterfaceDecl>(getDeclContext()))
339 return ID;
340 if (ObjCCategoryDecl *CD = dyn_cast<ObjCCategoryDecl>(getDeclContext()))
341 return CD->getClassInterface();
342 if (ObjCImplementationDecl *IMD =
343 dyn_cast<ObjCImplementationDecl>(getDeclContext()))
344 return IMD->getClassInterface();
345 if (ObjCCategoryImplDecl *CID =
346 dyn_cast<ObjCCategoryImplDecl>(getDeclContext()))
347 return CID->getClassInterface();
348 assert(false && "unknown method context");
Fariborz Jahanianae6f6fd2008-12-05 22:32:48 +0000349 return 0;
350}
351
Chris Lattnerab351632009-02-20 20:59:54 +0000352//===----------------------------------------------------------------------===//
353// ObjCInterfaceDecl
354//===----------------------------------------------------------------------===//
355
356ObjCInterfaceDecl *ObjCInterfaceDecl::Create(ASTContext &C,
357 DeclContext *DC,
358 SourceLocation atLoc,
359 IdentifierInfo *Id,
360 SourceLocation ClassLoc,
361 bool ForwardDecl, bool isInternal){
362 return new (C) ObjCInterfaceDecl(DC, atLoc, Id, ClassLoc, ForwardDecl,
363 isInternal);
364}
365
366ObjCInterfaceDecl::
367ObjCInterfaceDecl(DeclContext *DC, SourceLocation atLoc, IdentifierInfo *Id,
368 SourceLocation CLoc, bool FD, bool isInternal)
369 : ObjCContainerDecl(ObjCInterface, DC, atLoc, Id),
370 TypeForDecl(0), SuperClass(0),
371 CategoryList(0), ForwardDecl(FD), InternalInterface(isInternal),
372 ClassLoc(CLoc) {
373}
374
375void ObjCInterfaceDecl::Destroy(ASTContext &C) {
Chris Lattnerd13d3022009-03-31 08:36:08 +0000376 for (ivar_iterator I = ivar_begin(), E = ivar_end(); I != E; ++I)
Chris Lattnerab351632009-02-20 20:59:54 +0000377 if (*I) (*I)->Destroy(C);
378
Chris Lattner38af2de2009-02-20 21:35:13 +0000379 IVars.Destroy(C);
Chris Lattnerab351632009-02-20 20:59:54 +0000380 // FIXME: CategoryList?
381
382 // FIXME: Because there is no clear ownership
383 // role between ObjCInterfaceDecls and the ObjCPropertyDecls that they
384 // reference, we destroy ObjCPropertyDecls in ~TranslationUnit.
385 Decl::Destroy(C);
386}
387
388
389/// FindCategoryDeclaration - Finds category declaration in the list of
390/// categories for this class and returns it. Name of the category is passed
391/// in 'CategoryId'. If category not found, return 0;
Fariborz Jahanianae6f6fd2008-12-05 22:32:48 +0000392///
Chris Lattnerab351632009-02-20 20:59:54 +0000393ObjCCategoryDecl *
394ObjCInterfaceDecl::FindCategoryDeclaration(IdentifierInfo *CategoryId) const {
395 for (ObjCCategoryDecl *Category = getCategoryList();
396 Category; Category = Category->getNextClassCategory())
397 if (Category->getIdentifier() == CategoryId)
398 return Category;
Fariborz Jahanianae6f6fd2008-12-05 22:32:48 +0000399 return 0;
400}
401
Chris Lattnerab351632009-02-20 20:59:54 +0000402//===----------------------------------------------------------------------===//
403// ObjCIvarDecl
404//===----------------------------------------------------------------------===//
405
406ObjCIvarDecl *ObjCIvarDecl::Create(ASTContext &C, DeclContext *DC,
407 SourceLocation L, IdentifierInfo *Id,
408 QualType T, AccessControl ac, Expr *BW) {
409 return new (C) ObjCIvarDecl(DC, L, Id, T, ac, BW);
410}
411
412
413
414//===----------------------------------------------------------------------===//
415// ObjCAtDefsFieldDecl
416//===----------------------------------------------------------------------===//
417
418ObjCAtDefsFieldDecl
419*ObjCAtDefsFieldDecl::Create(ASTContext &C, DeclContext *DC, SourceLocation L,
420 IdentifierInfo *Id, QualType T, Expr *BW) {
421 return new (C) ObjCAtDefsFieldDecl(DC, L, Id, T, BW);
422}
423
424void ObjCAtDefsFieldDecl::Destroy(ASTContext& C) {
425 this->~ObjCAtDefsFieldDecl();
426 C.Deallocate((void *)this);
427}
428
429//===----------------------------------------------------------------------===//
430// ObjCProtocolDecl
431//===----------------------------------------------------------------------===//
432
433ObjCProtocolDecl *ObjCProtocolDecl::Create(ASTContext &C, DeclContext *DC,
434 SourceLocation L,
435 IdentifierInfo *Id) {
436 return new (C) ObjCProtocolDecl(DC, L, Id);
437}
438
439void ObjCProtocolDecl::Destroy(ASTContext &C) {
Chris Lattner38af2de2009-02-20 21:35:13 +0000440 ReferencedProtocols.Destroy(C);
Chris Lattnerab351632009-02-20 20:59:54 +0000441 ObjCContainerDecl::Destroy(C);
442}
443
Steve Naroff91b0b0c2009-03-01 16:12:44 +0000444ObjCProtocolDecl *ObjCProtocolDecl::lookupProtocolNamed(IdentifierInfo *Name) {
445 ObjCProtocolDecl *PDecl = this;
446
447 if (Name == getIdentifier())
448 return PDecl;
449
450 for (protocol_iterator I = protocol_begin(), E = protocol_end(); I != E; ++I)
451 if ((PDecl = (*I)->lookupProtocolNamed(Name)))
452 return PDecl;
453
454 return NULL;
455}
456
Chris Lattnerab351632009-02-20 20:59:54 +0000457// lookupInstanceMethod - Lookup a instance method in the protocol and protocols
458// it inherited.
Douglas Gregor6ab35242009-04-09 21:40:53 +0000459ObjCMethodDecl *ObjCProtocolDecl::lookupInstanceMethod(ASTContext &Context,
460 Selector Sel) {
Chris Lattnerab351632009-02-20 20:59:54 +0000461 ObjCMethodDecl *MethodDecl = NULL;
462
Douglas Gregor6ab35242009-04-09 21:40:53 +0000463 if ((MethodDecl = getInstanceMethod(Context, Sel)))
Chris Lattnerab351632009-02-20 20:59:54 +0000464 return MethodDecl;
465
466 for (protocol_iterator I = protocol_begin(), E = protocol_end(); I != E; ++I)
Douglas Gregor6ab35242009-04-09 21:40:53 +0000467 if ((MethodDecl = (*I)->lookupInstanceMethod(Context, Sel)))
Chris Lattnerab351632009-02-20 20:59:54 +0000468 return MethodDecl;
469 return NULL;
470}
471
472// lookupInstanceMethod - Lookup a class method in the protocol and protocols
473// it inherited.
Douglas Gregor6ab35242009-04-09 21:40:53 +0000474ObjCMethodDecl *ObjCProtocolDecl::lookupClassMethod(ASTContext &Context,
475 Selector Sel) {
Chris Lattnerab351632009-02-20 20:59:54 +0000476 ObjCMethodDecl *MethodDecl = NULL;
477
Douglas Gregor6ab35242009-04-09 21:40:53 +0000478 if ((MethodDecl = getClassMethod(Context, Sel)))
Chris Lattnerab351632009-02-20 20:59:54 +0000479 return MethodDecl;
480
481 for (protocol_iterator I = protocol_begin(), E = protocol_end(); I != E; ++I)
Douglas Gregor6ab35242009-04-09 21:40:53 +0000482 if ((MethodDecl = (*I)->lookupClassMethod(Context, Sel)))
Chris Lattnerab351632009-02-20 20:59:54 +0000483 return MethodDecl;
484 return NULL;
485}
486
487//===----------------------------------------------------------------------===//
488// ObjCClassDecl
489//===----------------------------------------------------------------------===//
490
Chris Lattner38af2de2009-02-20 21:35:13 +0000491ObjCClassDecl::ObjCClassDecl(DeclContext *DC, SourceLocation L,
492 ObjCInterfaceDecl *const *Elts, unsigned nElts,
493 ASTContext &C)
494 : Decl(ObjCClass, DC, L) {
495 ForwardDecls.set(Elts, nElts, C);
496}
497
498
Chris Lattnerab351632009-02-20 20:59:54 +0000499ObjCClassDecl *ObjCClassDecl::Create(ASTContext &C, DeclContext *DC,
500 SourceLocation L,
501 ObjCInterfaceDecl *const *Elts,
502 unsigned nElts) {
Chris Lattner38af2de2009-02-20 21:35:13 +0000503 return new (C) ObjCClassDecl(DC, L, Elts, nElts, C);
Chris Lattnerab351632009-02-20 20:59:54 +0000504}
505
506void ObjCClassDecl::Destroy(ASTContext &C) {
507
508 // FIXME: There is no clear ownership policy now for referenced
509 // ObjCInterfaceDecls. Some of them can be forward declarations that
510 // are never later defined (in which case the ObjCClassDecl owns them)
511 // or the ObjCInterfaceDecl later becomes a real definition later. Ideally
512 // we should have separate objects for forward declarations and definitions,
513 // obviating this problem. Because of this situation, referenced
514 // ObjCInterfaceDecls are destroyed in ~TranslationUnit.
515
Chris Lattner38af2de2009-02-20 21:35:13 +0000516 ForwardDecls.Destroy(C);
Chris Lattnerab351632009-02-20 20:59:54 +0000517 Decl::Destroy(C);
518}
519
520//===----------------------------------------------------------------------===//
521// ObjCForwardProtocolDecl
522//===----------------------------------------------------------------------===//
523
Chris Lattner38af2de2009-02-20 21:35:13 +0000524ObjCForwardProtocolDecl::
525ObjCForwardProtocolDecl(DeclContext *DC, SourceLocation L,
526 ObjCProtocolDecl *const *Elts, unsigned nElts,
527 ASTContext &C)
528: Decl(ObjCForwardProtocol, DC, L) {
529 ReferencedProtocols.set(Elts, nElts, C);
530}
531
532
Chris Lattnerab351632009-02-20 20:59:54 +0000533ObjCForwardProtocolDecl *
534ObjCForwardProtocolDecl::Create(ASTContext &C, DeclContext *DC,
535 SourceLocation L,
536 ObjCProtocolDecl *const *Elts,
537 unsigned NumElts) {
Chris Lattner38af2de2009-02-20 21:35:13 +0000538 return new (C) ObjCForwardProtocolDecl(DC, L, Elts, NumElts, C);
Chris Lattnerab351632009-02-20 20:59:54 +0000539}
540
541void ObjCForwardProtocolDecl::Destroy(ASTContext &C) {
Chris Lattner38af2de2009-02-20 21:35:13 +0000542 ReferencedProtocols.Destroy(C);
Chris Lattnerab351632009-02-20 20:59:54 +0000543 Decl::Destroy(C);
544}
545
546//===----------------------------------------------------------------------===//
547// ObjCCategoryDecl
548//===----------------------------------------------------------------------===//
549
550ObjCCategoryDecl *ObjCCategoryDecl::Create(ASTContext &C, DeclContext *DC,
551 SourceLocation L,
552 IdentifierInfo *Id) {
553 return new (C) ObjCCategoryDecl(DC, L, Id);
554}
555
556//===----------------------------------------------------------------------===//
557// ObjCCategoryImplDecl
558//===----------------------------------------------------------------------===//
559
560ObjCCategoryImplDecl *
561ObjCCategoryImplDecl::Create(ASTContext &C, DeclContext *DC,
562 SourceLocation L,IdentifierInfo *Id,
563 ObjCInterfaceDecl *ClassInterface) {
564 return new (C) ObjCCategoryImplDecl(DC, L, Id, ClassInterface);
565}
566
567
Douglas Gregor653f1b12009-04-23 01:02:12 +0000568void ObjCImplDecl::addPropertyImplementation(ASTContext &Context,
569 ObjCPropertyImplDecl *property) {
Douglas Gregor2c2d43c2009-04-23 02:42:49 +0000570 // FIXME: The context should be correct before we get here.
Douglas Gregor653f1b12009-04-23 01:02:12 +0000571 property->setLexicalDeclContext(this);
572 addDecl(Context, property);
573}
574
Fariborz Jahanianae6f6fd2008-12-05 22:32:48 +0000575/// FindPropertyImplIvarDecl - This method lookup the ivar in the list of
Chris Lattnerd6eed1c2009-02-16 19:24:31 +0000576/// properties implemented in this category @implementation block and returns
577/// the implemented property that uses it.
Fariborz Jahanianae6f6fd2008-12-05 22:32:48 +0000578///
Chris Lattner3aa18612009-02-28 18:42:10 +0000579ObjCPropertyImplDecl *ObjCImplDecl::
Douglas Gregor653f1b12009-04-23 01:02:12 +0000580FindPropertyImplIvarDecl(ASTContext &Context, IdentifierInfo *ivarId) const {
581 for (propimpl_iterator i = propimpl_begin(Context), e = propimpl_end(Context);
582 i != e; ++i){
Fariborz Jahanianae6f6fd2008-12-05 22:32:48 +0000583 ObjCPropertyImplDecl *PID = *i;
584 if (PID->getPropertyIvarDecl() &&
585 PID->getPropertyIvarDecl()->getIdentifier() == ivarId)
586 return PID;
587 }
588 return 0;
589}
590
591/// FindPropertyImplDecl - This method looks up a previous ObjCPropertyImplDecl
592/// added to the list of those properties @synthesized/@dynamic in this
593/// category @implementation block.
594///
Chris Lattner3aa18612009-02-28 18:42:10 +0000595ObjCPropertyImplDecl *ObjCImplDecl::
Douglas Gregor653f1b12009-04-23 01:02:12 +0000596FindPropertyImplDecl(ASTContext &Context, IdentifierInfo *Id) const {
597 for (propimpl_iterator i = propimpl_begin(Context), e = propimpl_end(Context);
598 i != e; ++i){
Fariborz Jahanianae6f6fd2008-12-05 22:32:48 +0000599 ObjCPropertyImplDecl *PID = *i;
600 if (PID->getPropertyDecl()->getIdentifier() == Id)
601 return PID;
602 }
603 return 0;
604}
605
Chris Lattner3aa18612009-02-28 18:42:10 +0000606// getInstanceMethod - This method returns an instance method by looking in
Chris Lattner1e03a562008-03-16 00:19:01 +0000607// the class implementation. Unlike interfaces, we don't look outside the
608// implementation.
Douglas Gregor653f1b12009-04-23 01:02:12 +0000609ObjCMethodDecl *ObjCImplDecl::getInstanceMethod(ASTContext &Context,
610 Selector Sel) const {
611 // Since instance & class methods can have the same name, the loop below
612 // ensures we get the correct method.
613 //
614 // @interface Whatever
615 // - (int) class_method;
616 // + (float) class_method;
617 // @end
618 //
619 lookup_const_iterator Meth, MethEnd;
620 for (llvm::tie(Meth, MethEnd) = lookup(Context, Sel);
621 Meth != MethEnd; ++Meth) {
622 ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(*Meth);
623 if (MD && MD->isInstanceMethod())
624 return MD;
625 }
626 return 0;
Chris Lattner1e03a562008-03-16 00:19:01 +0000627}
628
Chris Lattner3aa18612009-02-28 18:42:10 +0000629// getClassMethod - This method returns an instance method by looking in
Chris Lattner1e03a562008-03-16 00:19:01 +0000630// the class implementation. Unlike interfaces, we don't look outside the
631// implementation.
Douglas Gregor653f1b12009-04-23 01:02:12 +0000632ObjCMethodDecl *ObjCImplDecl::getClassMethod(ASTContext &Context,
633 Selector Sel) const {
634 // Since instance & class methods can have the same name, the loop below
635 // ensures we get the correct method.
636 //
637 // @interface Whatever
638 // - (int) class_method;
639 // + (float) class_method;
640 // @end
641 //
642 lookup_const_iterator Meth, MethEnd;
643 for (llvm::tie(Meth, MethEnd) = lookup(Context, Sel);
644 Meth != MethEnd; ++Meth) {
645 ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(*Meth);
646 if (MD && MD->isClassMethod())
647 return MD;
648 }
649 return 0;
Chris Lattner1e03a562008-03-16 00:19:01 +0000650}
651
Chris Lattnerab351632009-02-20 20:59:54 +0000652//===----------------------------------------------------------------------===//
653// ObjCImplementationDecl
654//===----------------------------------------------------------------------===//
655
656ObjCImplementationDecl *
657ObjCImplementationDecl::Create(ASTContext &C, DeclContext *DC,
658 SourceLocation L,
659 ObjCInterfaceDecl *ClassInterface,
660 ObjCInterfaceDecl *SuperDecl) {
661 return new (C) ObjCImplementationDecl(DC, L, ClassInterface, SuperDecl);
662}
663
Chris Lattnerab351632009-02-20 20:59:54 +0000664//===----------------------------------------------------------------------===//
665// ObjCCompatibleAliasDecl
666//===----------------------------------------------------------------------===//
667
668ObjCCompatibleAliasDecl *
669ObjCCompatibleAliasDecl::Create(ASTContext &C, DeclContext *DC,
670 SourceLocation L,
671 IdentifierInfo *Id,
672 ObjCInterfaceDecl* AliasedClass) {
673 return new (C) ObjCCompatibleAliasDecl(DC, L, Id, AliasedClass);
674}
675
676//===----------------------------------------------------------------------===//
677// ObjCPropertyDecl
678//===----------------------------------------------------------------------===//
679
680ObjCPropertyDecl *ObjCPropertyDecl::Create(ASTContext &C, DeclContext *DC,
681 SourceLocation L,
682 IdentifierInfo *Id,
683 QualType T,
684 PropertyControl propControl) {
685 return new (C) ObjCPropertyDecl(DC, L, Id, T);
686}
687
688
689//===----------------------------------------------------------------------===//
690// ObjCPropertyImplDecl
691//===----------------------------------------------------------------------===//
692
Fariborz Jahanian628b96f2008-04-23 00:06:01 +0000693ObjCPropertyImplDecl *ObjCPropertyImplDecl::Create(ASTContext &C,
Douglas Gregord0434102009-01-09 00:49:46 +0000694 DeclContext *DC,
Fariborz Jahanian628b96f2008-04-23 00:06:01 +0000695 SourceLocation atLoc,
696 SourceLocation L,
697 ObjCPropertyDecl *property,
Daniel Dunbar9f0afd42008-08-26 04:47:31 +0000698 Kind PK,
Fariborz Jahanian628b96f2008-04-23 00:06:01 +0000699 ObjCIvarDecl *ivar) {
Steve Naroff3e970492009-01-27 21:25:57 +0000700 return new (C) ObjCPropertyImplDecl(DC, atLoc, L, property, PK, ivar);
Fariborz Jahanian628b96f2008-04-23 00:06:01 +0000701}
Chris Lattnerf4af5152008-03-17 01:19:02 +0000702
Chris Lattner0ed844b2008-04-04 06:12:32 +0000703