blob: f4bb8957307499e5d03cfec31c8a26e877c03d31 [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
Steve Naroff0701bbb2009-01-08 17:28:14 +000045// Get the local instance method declared in this interface.
Douglas Gregor6ab35242009-04-09 21:40:53 +000046ObjCMethodDecl *
47ObjCContainerDecl::getInstanceMethod(ASTContext &Context, Selector Sel) const {
Steve Naroff0de21fd2009-02-22 19:35:57 +000048 // Since instance & class methods can have the same name, the loop below
49 // ensures we get the correct method.
50 //
51 // @interface Whatever
52 // - (int) class_method;
53 // + (float) class_method;
54 // @end
55 //
56 lookup_const_iterator Meth, MethEnd;
Douglas Gregor6ab35242009-04-09 21:40:53 +000057 for (llvm::tie(Meth, MethEnd) = lookup(Context, Sel);
Steve Naroff0de21fd2009-02-22 19:35:57 +000058 Meth != MethEnd; ++Meth) {
59 ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(*Meth);
60 if (MD && MD->isInstanceMethod())
61 return MD;
62 }
Steve Naroff0701bbb2009-01-08 17:28:14 +000063 return 0;
64}
65
66// Get the local class method declared in this interface.
Douglas Gregor6ab35242009-04-09 21:40:53 +000067ObjCMethodDecl *
68ObjCContainerDecl::getClassMethod(ASTContext &Context, Selector Sel) const {
Steve Naroff0de21fd2009-02-22 19:35:57 +000069 // Since instance & class methods can have the same name, the loop below
70 // ensures we get the correct method.
71 //
72 // @interface Whatever
73 // - (int) class_method;
74 // + (float) class_method;
75 // @end
76 //
77 lookup_const_iterator Meth, MethEnd;
Douglas Gregor6ab35242009-04-09 21:40:53 +000078 for (llvm::tie(Meth, MethEnd) = lookup(Context, Sel);
Steve Naroff0de21fd2009-02-22 19:35:57 +000079 Meth != MethEnd; ++Meth) {
80 ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(*Meth);
81 if (MD && MD->isClassMethod())
82 return MD;
83 }
Steve Naroff0701bbb2009-01-08 17:28:14 +000084 return 0;
85}
86
Fariborz Jahanian559c0c42008-04-21 19:04:53 +000087/// FindPropertyDeclaration - Finds declaration of the property given its name
88/// in 'PropertyId' and returns it. It returns 0, if not found.
Steve Naroff93983f82009-01-11 12:47:58 +000089/// FIXME: Convert to DeclContext lookup...
Fariborz Jahanian559c0c42008-04-21 19:04:53 +000090///
91ObjCPropertyDecl *
Douglas Gregor6ab35242009-04-09 21:40:53 +000092ObjCContainerDecl::FindPropertyDeclaration(ASTContext &Context,
93 IdentifierInfo *PropertyId) const {
94 for (prop_iterator I = prop_begin(Context), E = prop_end(Context);
95 I != E; ++I)
Chris Lattnerab351632009-02-20 20:59:54 +000096 if ((*I)->getIdentifier() == PropertyId)
97 return *I;
98
Fariborz Jahaniana66793e2009-01-09 21:04:52 +000099 const ObjCProtocolDecl *PID = dyn_cast<ObjCProtocolDecl>(this);
100 if (PID) {
Chris Lattnerab351632009-02-20 20:59:54 +0000101 for (ObjCProtocolDecl::protocol_iterator I = PID->protocol_begin(),
102 E = PID->protocol_end(); I != E; ++I)
Douglas Gregor6ab35242009-04-09 21:40:53 +0000103 if (ObjCPropertyDecl *P = (*I)->FindPropertyDeclaration(Context,
104 PropertyId))
Chris Lattnerab351632009-02-20 20:59:54 +0000105 return P;
Fariborz Jahaniana66793e2009-01-09 21:04:52 +0000106 }
107
Fariborz Jahanianf034e9c2009-01-19 18:16:19 +0000108 if (const ObjCInterfaceDecl *OID = dyn_cast<ObjCInterfaceDecl>(this)) {
Steve Naroff09c47192009-01-09 15:36:25 +0000109 // Look through categories.
110 for (ObjCCategoryDecl *Category = OID->getCategoryList();
111 Category; Category = Category->getNextClassCategory()) {
Douglas Gregor6ab35242009-04-09 21:40:53 +0000112 if (ObjCPropertyDecl *P = Category->FindPropertyDeclaration(Context,
113 PropertyId))
Chris Lattnerab351632009-02-20 20:59:54 +0000114 return P;
Steve Naroff09c47192009-01-09 15:36:25 +0000115 }
116 // Look through protocols.
117 for (ObjCInterfaceDecl::protocol_iterator I = OID->protocol_begin(),
118 E = OID->protocol_end(); I != E; ++I) {
Douglas Gregor6ab35242009-04-09 21:40:53 +0000119 if (ObjCPropertyDecl *P = (*I)->FindPropertyDeclaration(Context,
120 PropertyId))
Chris Lattnerab351632009-02-20 20:59:54 +0000121 return P;
Steve Naroff09c47192009-01-09 15:36:25 +0000122 }
123 if (OID->getSuperClass())
Douglas Gregor6ab35242009-04-09 21:40:53 +0000124 return OID->getSuperClass()->FindPropertyDeclaration(Context,
125 PropertyId);
Chris Lattnerab351632009-02-20 20:59:54 +0000126 } else if (const ObjCCategoryDecl *OCD = dyn_cast<ObjCCategoryDecl>(this)) {
Fariborz Jahanianf034e9c2009-01-19 18:16:19 +0000127 // Look through protocols.
128 for (ObjCInterfaceDecl::protocol_iterator I = OCD->protocol_begin(),
129 E = OCD->protocol_end(); I != E; ++I) {
Douglas Gregor6ab35242009-04-09 21:40:53 +0000130 if (ObjCPropertyDecl *P = (*I)->FindPropertyDeclaration(Context,
131 PropertyId))
Chris Lattnerab351632009-02-20 20:59:54 +0000132 return P;
Fariborz Jahanianf034e9c2009-01-19 18:16:19 +0000133 }
134 }
Steve Naroff3d2c22b2008-06-05 13:55:23 +0000135 return 0;
136}
137
Chris Lattner1e03a562008-03-16 00:19:01 +0000138ObjCIvarDecl *ObjCInterfaceDecl::lookupInstanceVariable(
Douglas Gregor6ab35242009-04-09 21:40:53 +0000139 ASTContext &Context, IdentifierInfo *ID, ObjCInterfaceDecl *&clsDeclared) {
Chris Lattner1e03a562008-03-16 00:19:01 +0000140 ObjCInterfaceDecl* ClassDecl = this;
141 while (ClassDecl != NULL) {
142 for (ivar_iterator I = ClassDecl->ivar_begin(), E = ClassDecl->ivar_end();
143 I != E; ++I) {
144 if ((*I)->getIdentifier() == ID) {
145 clsDeclared = ClassDecl;
146 return *I;
147 }
148 }
Fariborz Jahanianaf3e7222009-03-31 00:06:29 +0000149 // look into properties.
Douglas Gregor6ab35242009-04-09 21:40:53 +0000150 for (ObjCInterfaceDecl::prop_iterator I = ClassDecl->prop_begin(Context),
151 E = ClassDecl->prop_end(Context); I != E; ++I) {
Fariborz Jahanianaf3e7222009-03-31 00:06:29 +0000152 ObjCPropertyDecl *PDecl = (*I);
153 if (ObjCIvarDecl *IV = PDecl->getPropertyIvarDecl())
154 if (IV->getIdentifier() == ID) {
155 clsDeclared = ClassDecl;
156 return IV;
157 }
158 }
Chris Lattner1e03a562008-03-16 00:19:01 +0000159 ClassDecl = ClassDecl->getSuperClass();
160 }
161 return NULL;
162}
163
Fariborz Jahaniancd187622009-05-22 17:12:32 +0000164/// lookupInheritedClass - This method returns ObjCInterfaceDecl * of the super
165/// class whose name is passed as argument. If it is not one of the super classes
166/// the it returns NULL.
167ObjCInterfaceDecl *ObjCInterfaceDecl::lookupInheritedClass(
168 const IdentifierInfo*ICName) {
169 ObjCInterfaceDecl* ClassDecl = this;
170 while (ClassDecl != NULL) {
171 if (ClassDecl->getIdentifier() == ICName)
172 return ClassDecl;
173 ClassDecl = ClassDecl->getSuperClass();
174 }
175 return NULL;
176}
177
Chris Lattner1e03a562008-03-16 00:19:01 +0000178/// lookupInstanceMethod - This method returns an instance method by looking in
179/// the class, its categories, and its super classes (using a linear search).
Douglas Gregor6ab35242009-04-09 21:40:53 +0000180ObjCMethodDecl *ObjCInterfaceDecl::lookupInstanceMethod(ASTContext &Context,
181 Selector Sel) {
Chris Lattner1e03a562008-03-16 00:19:01 +0000182 ObjCInterfaceDecl* ClassDecl = this;
183 ObjCMethodDecl *MethodDecl = 0;
184
185 while (ClassDecl != NULL) {
Douglas Gregor6ab35242009-04-09 21:40:53 +0000186 if ((MethodDecl = ClassDecl->getInstanceMethod(Context, Sel)))
Chris Lattner1e03a562008-03-16 00:19:01 +0000187 return MethodDecl;
188
189 // Didn't find one yet - look through protocols.
Chris Lattner3db6cae2008-07-21 18:19:38 +0000190 const ObjCList<ObjCProtocolDecl> &Protocols =
191 ClassDecl->getReferencedProtocols();
192 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
193 E = Protocols.end(); I != E; ++I)
Douglas Gregor6ab35242009-04-09 21:40:53 +0000194 if ((MethodDecl = (*I)->lookupInstanceMethod(Context, Sel)))
Chris Lattner1e03a562008-03-16 00:19:01 +0000195 return MethodDecl;
Chris Lattner3db6cae2008-07-21 18:19:38 +0000196
Chris Lattner1e03a562008-03-16 00:19:01 +0000197 // Didn't find one yet - now look through categories.
198 ObjCCategoryDecl *CatDecl = ClassDecl->getCategoryList();
199 while (CatDecl) {
Douglas Gregor6ab35242009-04-09 21:40:53 +0000200 if ((MethodDecl = CatDecl->getInstanceMethod(Context, Sel)))
Chris Lattner1e03a562008-03-16 00:19:01 +0000201 return MethodDecl;
Steve Naroffb79c01e2008-12-08 20:57:28 +0000202
203 // Didn't find one yet - look through protocols.
204 const ObjCList<ObjCProtocolDecl> &Protocols =
205 CatDecl->getReferencedProtocols();
206 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
207 E = Protocols.end(); I != E; ++I)
Douglas Gregor6ab35242009-04-09 21:40:53 +0000208 if ((MethodDecl = (*I)->lookupInstanceMethod(Context, Sel)))
Steve Naroffb79c01e2008-12-08 20:57:28 +0000209 return MethodDecl;
Chris Lattner1e03a562008-03-16 00:19:01 +0000210 CatDecl = CatDecl->getNextClassCategory();
211 }
212 ClassDecl = ClassDecl->getSuperClass();
213 }
214 return NULL;
215}
216
217// lookupClassMethod - This method returns a class method by looking in the
218// class, its categories, and its super classes (using a linear search).
Douglas Gregor6ab35242009-04-09 21:40:53 +0000219ObjCMethodDecl *ObjCInterfaceDecl::lookupClassMethod(ASTContext &Context,
220 Selector Sel) {
Chris Lattner1e03a562008-03-16 00:19:01 +0000221 ObjCInterfaceDecl* ClassDecl = this;
222 ObjCMethodDecl *MethodDecl = 0;
223
224 while (ClassDecl != NULL) {
Douglas Gregor6ab35242009-04-09 21:40:53 +0000225 if ((MethodDecl = ClassDecl->getClassMethod(Context, Sel)))
Chris Lattner1e03a562008-03-16 00:19:01 +0000226 return MethodDecl;
227
228 // Didn't find one yet - look through protocols.
Chris Lattner780f3292008-07-21 21:32:27 +0000229 for (ObjCInterfaceDecl::protocol_iterator I = ClassDecl->protocol_begin(),
230 E = ClassDecl->protocol_end(); I != E; ++I)
Douglas Gregor6ab35242009-04-09 21:40:53 +0000231 if ((MethodDecl = (*I)->lookupClassMethod(Context, Sel)))
Chris Lattner1e03a562008-03-16 00:19:01 +0000232 return MethodDecl;
Chris Lattner780f3292008-07-21 21:32:27 +0000233
Chris Lattner1e03a562008-03-16 00:19:01 +0000234 // Didn't find one yet - now look through categories.
235 ObjCCategoryDecl *CatDecl = ClassDecl->getCategoryList();
236 while (CatDecl) {
Douglas Gregor6ab35242009-04-09 21:40:53 +0000237 if ((MethodDecl = CatDecl->getClassMethod(Context, Sel)))
Chris Lattner1e03a562008-03-16 00:19:01 +0000238 return MethodDecl;
Steve Naroffb5584222009-02-26 11:32:02 +0000239
240 // Didn't find one yet - look through protocols.
241 const ObjCList<ObjCProtocolDecl> &Protocols =
242 CatDecl->getReferencedProtocols();
243 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
244 E = Protocols.end(); I != E; ++I)
Douglas Gregor6ab35242009-04-09 21:40:53 +0000245 if ((MethodDecl = (*I)->lookupClassMethod(Context, Sel)))
Steve Naroffb5584222009-02-26 11:32:02 +0000246 return MethodDecl;
Chris Lattner1e03a562008-03-16 00:19:01 +0000247 CatDecl = CatDecl->getNextClassCategory();
248 }
249 ClassDecl = ClassDecl->getSuperClass();
250 }
251 return NULL;
252}
253
Chris Lattnerab351632009-02-20 20:59:54 +0000254
255
256//===----------------------------------------------------------------------===//
257// ObjCMethodDecl
258//===----------------------------------------------------------------------===//
259
260ObjCMethodDecl *ObjCMethodDecl::Create(ASTContext &C,
261 SourceLocation beginLoc,
262 SourceLocation endLoc,
263 Selector SelInfo, QualType T,
264 DeclContext *contextDecl,
265 bool isInstance,
266 bool isVariadic,
267 bool isSynthesized,
268 ImplementationControl impControl) {
269 return new (C) ObjCMethodDecl(beginLoc, endLoc,
270 SelInfo, T, contextDecl,
271 isInstance,
272 isVariadic, isSynthesized, impControl);
Chris Lattner1e03a562008-03-16 00:19:01 +0000273}
274
Chris Lattner38af2de2009-02-20 21:35:13 +0000275void ObjCMethodDecl::Destroy(ASTContext &C) {
Chris Lattnerab351632009-02-20 20:59:54 +0000276 if (Body) Body->Destroy(C);
277 if (SelfDecl) SelfDecl->Destroy(C);
278
279 for (param_iterator I=param_begin(), E=param_end(); I!=E; ++I)
280 if (*I) (*I)->Destroy(C);
281
Chris Lattner38af2de2009-02-20 21:35:13 +0000282 ParamInfo.Destroy(C);
Chris Lattnerab351632009-02-20 20:59:54 +0000283
284 Decl::Destroy(C);
Chris Lattner1e03a562008-03-16 00:19:01 +0000285}
286
Chris Lattnerab351632009-02-20 20:59:54 +0000287void ObjCMethodDecl::createImplicitParams(ASTContext &Context,
288 const ObjCInterfaceDecl *OID) {
289 QualType selfTy;
290 if (isInstanceMethod()) {
291 // There may be no interface context due to error in declaration
292 // of the interface (which has been reported). Recover gracefully.
293 if (OID) {
Daniel Dunbar3b3a4582009-04-22 04:34:53 +0000294 selfTy = Context.getObjCInterfaceType(OID);
Chris Lattnerab351632009-02-20 20:59:54 +0000295 selfTy = Context.getPointerType(selfTy);
296 } else {
297 selfTy = Context.getObjCIdType();
298 }
299 } else // we have a factory method.
300 selfTy = Context.getObjCClassType();
301
Steve Naroff53c9d8a2009-04-20 15:06:07 +0000302 setSelfDecl(ImplicitParamDecl::Create(Context, this, SourceLocation(),
303 &Context.Idents.get("self"), selfTy));
Chris Lattnerab351632009-02-20 20:59:54 +0000304
Steve Naroff53c9d8a2009-04-20 15:06:07 +0000305 setCmdDecl(ImplicitParamDecl::Create(Context, this, SourceLocation(),
306 &Context.Idents.get("_cmd"),
307 Context.getObjCSelType()));
Chris Lattnerab351632009-02-20 20:59:54 +0000308}
309
310
311
312/// getSynthesizedMethodSize - Compute size of synthesized method name
313/// as done be the rewrite.
Fariborz Jahanianae6f6fd2008-12-05 22:32:48 +0000314///
Chris Lattnerab351632009-02-20 20:59:54 +0000315unsigned ObjCMethodDecl::getSynthesizedMethodSize() const {
316 // syntesized method name is a concatenation of -/+[class-name selector]
317 // Get length of this name.
318 unsigned length = 3; // _I_ or _C_
319 length += getClassInterface()->getNameAsString().size()+1; // extra for _
320 if (const ObjCCategoryImplDecl *CID =
321 dyn_cast<ObjCCategoryImplDecl>(getDeclContext()))
322 length += CID->getNameAsString().size()+1;
323 length += getSelector().getAsString().size(); // selector name
324 return length;
325}
326
327ObjCInterfaceDecl *ObjCMethodDecl::getClassInterface() {
328 if (ObjCInterfaceDecl *ID = dyn_cast<ObjCInterfaceDecl>(getDeclContext()))
329 return ID;
330 if (ObjCCategoryDecl *CD = dyn_cast<ObjCCategoryDecl>(getDeclContext()))
331 return CD->getClassInterface();
332 if (ObjCImplementationDecl *IMD =
333 dyn_cast<ObjCImplementationDecl>(getDeclContext()))
334 return IMD->getClassInterface();
335 if (ObjCCategoryImplDecl *CID =
336 dyn_cast<ObjCCategoryImplDecl>(getDeclContext()))
337 return CID->getClassInterface();
338 assert(false && "unknown method context");
Fariborz Jahanianae6f6fd2008-12-05 22:32:48 +0000339 return 0;
340}
341
Chris Lattnerab351632009-02-20 20:59:54 +0000342//===----------------------------------------------------------------------===//
343// ObjCInterfaceDecl
344//===----------------------------------------------------------------------===//
345
346ObjCInterfaceDecl *ObjCInterfaceDecl::Create(ASTContext &C,
347 DeclContext *DC,
348 SourceLocation atLoc,
349 IdentifierInfo *Id,
350 SourceLocation ClassLoc,
351 bool ForwardDecl, bool isInternal){
352 return new (C) ObjCInterfaceDecl(DC, atLoc, Id, ClassLoc, ForwardDecl,
353 isInternal);
354}
355
356ObjCInterfaceDecl::
357ObjCInterfaceDecl(DeclContext *DC, SourceLocation atLoc, IdentifierInfo *Id,
358 SourceLocation CLoc, bool FD, bool isInternal)
359 : ObjCContainerDecl(ObjCInterface, DC, atLoc, Id),
360 TypeForDecl(0), SuperClass(0),
361 CategoryList(0), ForwardDecl(FD), InternalInterface(isInternal),
362 ClassLoc(CLoc) {
363}
364
365void ObjCInterfaceDecl::Destroy(ASTContext &C) {
Chris Lattnerd13d3022009-03-31 08:36:08 +0000366 for (ivar_iterator I = ivar_begin(), E = ivar_end(); I != E; ++I)
Chris Lattnerab351632009-02-20 20:59:54 +0000367 if (*I) (*I)->Destroy(C);
368
Chris Lattner38af2de2009-02-20 21:35:13 +0000369 IVars.Destroy(C);
Chris Lattnerab351632009-02-20 20:59:54 +0000370 // FIXME: CategoryList?
371
372 // FIXME: Because there is no clear ownership
373 // role between ObjCInterfaceDecls and the ObjCPropertyDecls that they
374 // reference, we destroy ObjCPropertyDecls in ~TranslationUnit.
375 Decl::Destroy(C);
376}
377
378
379/// FindCategoryDeclaration - Finds category declaration in the list of
380/// categories for this class and returns it. Name of the category is passed
381/// in 'CategoryId'. If category not found, return 0;
Fariborz Jahanianae6f6fd2008-12-05 22:32:48 +0000382///
Chris Lattnerab351632009-02-20 20:59:54 +0000383ObjCCategoryDecl *
384ObjCInterfaceDecl::FindCategoryDeclaration(IdentifierInfo *CategoryId) const {
385 for (ObjCCategoryDecl *Category = getCategoryList();
386 Category; Category = Category->getNextClassCategory())
387 if (Category->getIdentifier() == CategoryId)
388 return Category;
Fariborz Jahanianae6f6fd2008-12-05 22:32:48 +0000389 return 0;
390}
391
Chris Lattnerab351632009-02-20 20:59:54 +0000392//===----------------------------------------------------------------------===//
393// ObjCIvarDecl
394//===----------------------------------------------------------------------===//
395
396ObjCIvarDecl *ObjCIvarDecl::Create(ASTContext &C, DeclContext *DC,
397 SourceLocation L, IdentifierInfo *Id,
398 QualType T, AccessControl ac, Expr *BW) {
399 return new (C) ObjCIvarDecl(DC, L, Id, T, ac, BW);
400}
401
402
403
404//===----------------------------------------------------------------------===//
405// ObjCAtDefsFieldDecl
406//===----------------------------------------------------------------------===//
407
408ObjCAtDefsFieldDecl
409*ObjCAtDefsFieldDecl::Create(ASTContext &C, DeclContext *DC, SourceLocation L,
410 IdentifierInfo *Id, QualType T, Expr *BW) {
411 return new (C) ObjCAtDefsFieldDecl(DC, L, Id, T, BW);
412}
413
414void ObjCAtDefsFieldDecl::Destroy(ASTContext& C) {
415 this->~ObjCAtDefsFieldDecl();
416 C.Deallocate((void *)this);
417}
418
419//===----------------------------------------------------------------------===//
420// ObjCProtocolDecl
421//===----------------------------------------------------------------------===//
422
423ObjCProtocolDecl *ObjCProtocolDecl::Create(ASTContext &C, DeclContext *DC,
424 SourceLocation L,
425 IdentifierInfo *Id) {
426 return new (C) ObjCProtocolDecl(DC, L, Id);
427}
428
429void ObjCProtocolDecl::Destroy(ASTContext &C) {
Chris Lattner38af2de2009-02-20 21:35:13 +0000430 ReferencedProtocols.Destroy(C);
Chris Lattnerab351632009-02-20 20:59:54 +0000431 ObjCContainerDecl::Destroy(C);
432}
433
Steve Naroff91b0b0c2009-03-01 16:12:44 +0000434ObjCProtocolDecl *ObjCProtocolDecl::lookupProtocolNamed(IdentifierInfo *Name) {
435 ObjCProtocolDecl *PDecl = this;
436
437 if (Name == getIdentifier())
438 return PDecl;
439
440 for (protocol_iterator I = protocol_begin(), E = protocol_end(); I != E; ++I)
441 if ((PDecl = (*I)->lookupProtocolNamed(Name)))
442 return PDecl;
443
444 return NULL;
445}
446
Chris Lattnerab351632009-02-20 20:59:54 +0000447// lookupInstanceMethod - Lookup a instance method in the protocol and protocols
448// it inherited.
Douglas Gregor6ab35242009-04-09 21:40:53 +0000449ObjCMethodDecl *ObjCProtocolDecl::lookupInstanceMethod(ASTContext &Context,
450 Selector Sel) {
Chris Lattnerab351632009-02-20 20:59:54 +0000451 ObjCMethodDecl *MethodDecl = NULL;
452
Douglas Gregor6ab35242009-04-09 21:40:53 +0000453 if ((MethodDecl = getInstanceMethod(Context, Sel)))
Chris Lattnerab351632009-02-20 20:59:54 +0000454 return MethodDecl;
455
456 for (protocol_iterator I = protocol_begin(), E = protocol_end(); I != E; ++I)
Douglas Gregor6ab35242009-04-09 21:40:53 +0000457 if ((MethodDecl = (*I)->lookupInstanceMethod(Context, Sel)))
Chris Lattnerab351632009-02-20 20:59:54 +0000458 return MethodDecl;
459 return NULL;
460}
461
462// lookupInstanceMethod - Lookup a class method in the protocol and protocols
463// it inherited.
Douglas Gregor6ab35242009-04-09 21:40:53 +0000464ObjCMethodDecl *ObjCProtocolDecl::lookupClassMethod(ASTContext &Context,
465 Selector Sel) {
Chris Lattnerab351632009-02-20 20:59:54 +0000466 ObjCMethodDecl *MethodDecl = NULL;
467
Douglas Gregor6ab35242009-04-09 21:40:53 +0000468 if ((MethodDecl = getClassMethod(Context, Sel)))
Chris Lattnerab351632009-02-20 20:59:54 +0000469 return MethodDecl;
470
471 for (protocol_iterator I = protocol_begin(), E = protocol_end(); I != E; ++I)
Douglas Gregor6ab35242009-04-09 21:40:53 +0000472 if ((MethodDecl = (*I)->lookupClassMethod(Context, Sel)))
Chris Lattnerab351632009-02-20 20:59:54 +0000473 return MethodDecl;
474 return NULL;
475}
476
477//===----------------------------------------------------------------------===//
478// ObjCClassDecl
479//===----------------------------------------------------------------------===//
480
Chris Lattner38af2de2009-02-20 21:35:13 +0000481ObjCClassDecl::ObjCClassDecl(DeclContext *DC, SourceLocation L,
482 ObjCInterfaceDecl *const *Elts, unsigned nElts,
483 ASTContext &C)
484 : Decl(ObjCClass, DC, L) {
485 ForwardDecls.set(Elts, nElts, C);
486}
487
488
Chris Lattnerab351632009-02-20 20:59:54 +0000489ObjCClassDecl *ObjCClassDecl::Create(ASTContext &C, DeclContext *DC,
490 SourceLocation L,
491 ObjCInterfaceDecl *const *Elts,
492 unsigned nElts) {
Chris Lattner38af2de2009-02-20 21:35:13 +0000493 return new (C) ObjCClassDecl(DC, L, Elts, nElts, C);
Chris Lattnerab351632009-02-20 20:59:54 +0000494}
495
496void ObjCClassDecl::Destroy(ASTContext &C) {
497
498 // FIXME: There is no clear ownership policy now for referenced
499 // ObjCInterfaceDecls. Some of them can be forward declarations that
500 // are never later defined (in which case the ObjCClassDecl owns them)
501 // or the ObjCInterfaceDecl later becomes a real definition later. Ideally
502 // we should have separate objects for forward declarations and definitions,
503 // obviating this problem. Because of this situation, referenced
504 // ObjCInterfaceDecls are destroyed in ~TranslationUnit.
505
Chris Lattner38af2de2009-02-20 21:35:13 +0000506 ForwardDecls.Destroy(C);
Chris Lattnerab351632009-02-20 20:59:54 +0000507 Decl::Destroy(C);
508}
509
510//===----------------------------------------------------------------------===//
511// ObjCForwardProtocolDecl
512//===----------------------------------------------------------------------===//
513
Chris Lattner38af2de2009-02-20 21:35:13 +0000514ObjCForwardProtocolDecl::
515ObjCForwardProtocolDecl(DeclContext *DC, SourceLocation L,
516 ObjCProtocolDecl *const *Elts, unsigned nElts,
517 ASTContext &C)
518: Decl(ObjCForwardProtocol, DC, L) {
519 ReferencedProtocols.set(Elts, nElts, C);
520}
521
522
Chris Lattnerab351632009-02-20 20:59:54 +0000523ObjCForwardProtocolDecl *
524ObjCForwardProtocolDecl::Create(ASTContext &C, DeclContext *DC,
525 SourceLocation L,
526 ObjCProtocolDecl *const *Elts,
527 unsigned NumElts) {
Chris Lattner38af2de2009-02-20 21:35:13 +0000528 return new (C) ObjCForwardProtocolDecl(DC, L, Elts, NumElts, C);
Chris Lattnerab351632009-02-20 20:59:54 +0000529}
530
531void ObjCForwardProtocolDecl::Destroy(ASTContext &C) {
Chris Lattner38af2de2009-02-20 21:35:13 +0000532 ReferencedProtocols.Destroy(C);
Chris Lattnerab351632009-02-20 20:59:54 +0000533 Decl::Destroy(C);
534}
535
536//===----------------------------------------------------------------------===//
537// ObjCCategoryDecl
538//===----------------------------------------------------------------------===//
539
540ObjCCategoryDecl *ObjCCategoryDecl::Create(ASTContext &C, DeclContext *DC,
541 SourceLocation L,
542 IdentifierInfo *Id) {
543 return new (C) ObjCCategoryDecl(DC, L, Id);
544}
545
546//===----------------------------------------------------------------------===//
547// ObjCCategoryImplDecl
548//===----------------------------------------------------------------------===//
549
550ObjCCategoryImplDecl *
551ObjCCategoryImplDecl::Create(ASTContext &C, DeclContext *DC,
552 SourceLocation L,IdentifierInfo *Id,
553 ObjCInterfaceDecl *ClassInterface) {
554 return new (C) ObjCCategoryImplDecl(DC, L, Id, ClassInterface);
555}
556
557
Douglas Gregor653f1b12009-04-23 01:02:12 +0000558void ObjCImplDecl::addPropertyImplementation(ASTContext &Context,
559 ObjCPropertyImplDecl *property) {
Douglas Gregor2c2d43c2009-04-23 02:42:49 +0000560 // FIXME: The context should be correct before we get here.
Douglas Gregor653f1b12009-04-23 01:02:12 +0000561 property->setLexicalDeclContext(this);
562 addDecl(Context, property);
563}
564
Fariborz Jahanianae6f6fd2008-12-05 22:32:48 +0000565/// FindPropertyImplIvarDecl - This method lookup the ivar in the list of
Chris Lattnerd6eed1c2009-02-16 19:24:31 +0000566/// properties implemented in this category @implementation block and returns
567/// the implemented property that uses it.
Fariborz Jahanianae6f6fd2008-12-05 22:32:48 +0000568///
Chris Lattner3aa18612009-02-28 18:42:10 +0000569ObjCPropertyImplDecl *ObjCImplDecl::
Douglas Gregor653f1b12009-04-23 01:02:12 +0000570FindPropertyImplIvarDecl(ASTContext &Context, IdentifierInfo *ivarId) const {
571 for (propimpl_iterator i = propimpl_begin(Context), e = propimpl_end(Context);
572 i != e; ++i){
Fariborz Jahanianae6f6fd2008-12-05 22:32:48 +0000573 ObjCPropertyImplDecl *PID = *i;
574 if (PID->getPropertyIvarDecl() &&
575 PID->getPropertyIvarDecl()->getIdentifier() == ivarId)
576 return PID;
577 }
578 return 0;
579}
580
581/// FindPropertyImplDecl - This method looks up a previous ObjCPropertyImplDecl
582/// added to the list of those properties @synthesized/@dynamic in this
583/// category @implementation block.
584///
Chris Lattner3aa18612009-02-28 18:42:10 +0000585ObjCPropertyImplDecl *ObjCImplDecl::
Douglas Gregor653f1b12009-04-23 01:02:12 +0000586FindPropertyImplDecl(ASTContext &Context, IdentifierInfo *Id) const {
587 for (propimpl_iterator i = propimpl_begin(Context), e = propimpl_end(Context);
588 i != e; ++i){
Fariborz Jahanianae6f6fd2008-12-05 22:32:48 +0000589 ObjCPropertyImplDecl *PID = *i;
590 if (PID->getPropertyDecl()->getIdentifier() == Id)
591 return PID;
592 }
593 return 0;
594}
595
Chris Lattner3aa18612009-02-28 18:42:10 +0000596// getInstanceMethod - This method returns an instance method by looking in
Chris Lattner1e03a562008-03-16 00:19:01 +0000597// the class implementation. Unlike interfaces, we don't look outside the
598// implementation.
Douglas Gregor653f1b12009-04-23 01:02:12 +0000599ObjCMethodDecl *ObjCImplDecl::getInstanceMethod(ASTContext &Context,
600 Selector Sel) const {
601 // Since instance & class methods can have the same name, the loop below
602 // ensures we get the correct method.
603 //
604 // @interface Whatever
605 // - (int) class_method;
606 // + (float) class_method;
607 // @end
608 //
609 lookup_const_iterator Meth, MethEnd;
610 for (llvm::tie(Meth, MethEnd) = lookup(Context, Sel);
611 Meth != MethEnd; ++Meth) {
612 ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(*Meth);
613 if (MD && MD->isInstanceMethod())
614 return MD;
615 }
616 return 0;
Chris Lattner1e03a562008-03-16 00:19:01 +0000617}
618
Chris Lattner3aa18612009-02-28 18:42:10 +0000619// getClassMethod - This method returns an instance method by looking in
Chris Lattner1e03a562008-03-16 00:19:01 +0000620// the class implementation. Unlike interfaces, we don't look outside the
621// implementation.
Douglas Gregor653f1b12009-04-23 01:02:12 +0000622ObjCMethodDecl *ObjCImplDecl::getClassMethod(ASTContext &Context,
623 Selector Sel) const {
624 // Since instance & class methods can have the same name, the loop below
625 // ensures we get the correct method.
626 //
627 // @interface Whatever
628 // - (int) class_method;
629 // + (float) class_method;
630 // @end
631 //
632 lookup_const_iterator Meth, MethEnd;
633 for (llvm::tie(Meth, MethEnd) = lookup(Context, Sel);
634 Meth != MethEnd; ++Meth) {
635 ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(*Meth);
636 if (MD && MD->isClassMethod())
637 return MD;
638 }
639 return 0;
Chris Lattner1e03a562008-03-16 00:19:01 +0000640}
641
Chris Lattnerab351632009-02-20 20:59:54 +0000642//===----------------------------------------------------------------------===//
643// ObjCImplementationDecl
644//===----------------------------------------------------------------------===//
645
646ObjCImplementationDecl *
647ObjCImplementationDecl::Create(ASTContext &C, DeclContext *DC,
648 SourceLocation L,
649 ObjCInterfaceDecl *ClassInterface,
650 ObjCInterfaceDecl *SuperDecl) {
651 return new (C) ObjCImplementationDecl(DC, L, ClassInterface, SuperDecl);
652}
653
Chris Lattnerab351632009-02-20 20:59:54 +0000654//===----------------------------------------------------------------------===//
655// ObjCCompatibleAliasDecl
656//===----------------------------------------------------------------------===//
657
658ObjCCompatibleAliasDecl *
659ObjCCompatibleAliasDecl::Create(ASTContext &C, DeclContext *DC,
660 SourceLocation L,
661 IdentifierInfo *Id,
662 ObjCInterfaceDecl* AliasedClass) {
663 return new (C) ObjCCompatibleAliasDecl(DC, L, Id, AliasedClass);
664}
665
666//===----------------------------------------------------------------------===//
667// ObjCPropertyDecl
668//===----------------------------------------------------------------------===//
669
670ObjCPropertyDecl *ObjCPropertyDecl::Create(ASTContext &C, DeclContext *DC,
671 SourceLocation L,
672 IdentifierInfo *Id,
673 QualType T,
674 PropertyControl propControl) {
675 return new (C) ObjCPropertyDecl(DC, L, Id, T);
676}
677
678
679//===----------------------------------------------------------------------===//
680// ObjCPropertyImplDecl
681//===----------------------------------------------------------------------===//
682
Fariborz Jahanian628b96f2008-04-23 00:06:01 +0000683ObjCPropertyImplDecl *ObjCPropertyImplDecl::Create(ASTContext &C,
Douglas Gregord0434102009-01-09 00:49:46 +0000684 DeclContext *DC,
Fariborz Jahanian628b96f2008-04-23 00:06:01 +0000685 SourceLocation atLoc,
686 SourceLocation L,
687 ObjCPropertyDecl *property,
Daniel Dunbar9f0afd42008-08-26 04:47:31 +0000688 Kind PK,
Fariborz Jahanian628b96f2008-04-23 00:06:01 +0000689 ObjCIvarDecl *ivar) {
Steve Naroff3e970492009-01-27 21:25:57 +0000690 return new (C) ObjCPropertyImplDecl(DC, atLoc, L, property, PK, ivar);
Fariborz Jahanian628b96f2008-04-23 00:06:01 +0000691}
Chris Lattnerf4af5152008-03-17 01:19:02 +0000692
Chris Lattner0ed844b2008-04-04 06:12:32 +0000693