blob: 9cc22912caff687dba65a144c32cf164cfbd7abc [file] [log] [blame]
Chris Lattner10318b82008-03-16 00:19:01 +00001//===--- DeclObjC.cpp - ObjC Declaration AST Node Implementation ----------===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file implements the Objective-C related Decl classes.
11//
12//===----------------------------------------------------------------------===//
13
14#include "clang/AST/DeclObjC.h"
15#include "clang/AST/ASTContext.h"
Daniel Dunbarde300732008-08-11 04:54:23 +000016#include "clang/AST/Stmt.h"
Steve Naroffd85ba922009-02-22 19:35:57 +000017#include "llvm/ADT/STLExtras.h"
Chris Lattner10318b82008-03-16 00:19:01 +000018using namespace clang;
19
Chris Lattner114add62008-03-16 00:49:28 +000020//===----------------------------------------------------------------------===//
Chris Lattner217eb8c2009-02-20 21:16:26 +000021// ObjCListBase
22//===----------------------------------------------------------------------===//
23
Chris Lattnerdf6133b2009-02-20 21:35:13 +000024void ObjCListBase::Destroy(ASTContext &Ctx) {
Chris Lattnercf6c8282009-02-20 21:44:01 +000025 Ctx.Deallocate(List);
Chris Lattner217eb8c2009-02-20 21:16:26 +000026 NumElts = 0;
27 List = 0;
28}
29
Chris Lattnerdf6133b2009-02-20 21:35:13 +000030void ObjCListBase::set(void *const* InList, unsigned Elts, ASTContext &Ctx) {
Chris Lattner217eb8c2009-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 Lattnercf6c8282009-02-20 21:44:01 +000034
35 List = new (Ctx) void*[Elts];
Chris Lattner217eb8c2009-02-20 21:16:26 +000036 NumElts = Elts;
37 memcpy(List, InList, sizeof(void*)*Elts);
38}
39
40
41//===----------------------------------------------------------------------===//
Chris Lattner13f63602009-02-20 20:59:54 +000042// ObjCInterfaceDecl
Chris Lattner114add62008-03-16 00:49:28 +000043//===----------------------------------------------------------------------===//
44
Steve Naroffab63fd62009-01-08 17:28:14 +000045// Get the local instance method declared in this interface.
Douglas Gregorc55b0b02009-04-09 21:40:53 +000046ObjCMethodDecl *
47ObjCContainerDecl::getInstanceMethod(ASTContext &Context, Selector Sel) const {
Steve Naroffd85ba922009-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 Gregorc55b0b02009-04-09 21:40:53 +000057 for (llvm::tie(Meth, MethEnd) = lookup(Context, Sel);
Steve Naroffd85ba922009-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 Naroffab63fd62009-01-08 17:28:14 +000063 return 0;
64}
65
66// Get the local class method declared in this interface.
Douglas Gregorc55b0b02009-04-09 21:40:53 +000067ObjCMethodDecl *
68ObjCContainerDecl::getClassMethod(ASTContext &Context, Selector Sel) const {
Steve Naroffd85ba922009-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 Gregorc55b0b02009-04-09 21:40:53 +000078 for (llvm::tie(Meth, MethEnd) = lookup(Context, Sel);
Steve Naroffd85ba922009-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 Naroffab63fd62009-01-08 17:28:14 +000084 return 0;
85}
86
Fariborz Jahanianef8a3df2008-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 Naroffdcf1e842009-01-11 12:47:58 +000089/// FIXME: Convert to DeclContext lookup...
Fariborz Jahanianef8a3df2008-04-21 19:04:53 +000090///
91ObjCPropertyDecl *
Douglas Gregorc55b0b02009-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 Lattner13f63602009-02-20 20:59:54 +000096 if ((*I)->getIdentifier() == PropertyId)
97 return *I;
98
Fariborz Jahanianfaca5e22009-01-09 21:04:52 +000099 const ObjCProtocolDecl *PID = dyn_cast<ObjCProtocolDecl>(this);
100 if (PID) {
Chris Lattner13f63602009-02-20 20:59:54 +0000101 for (ObjCProtocolDecl::protocol_iterator I = PID->protocol_begin(),
102 E = PID->protocol_end(); I != E; ++I)
Douglas Gregorc55b0b02009-04-09 21:40:53 +0000103 if (ObjCPropertyDecl *P = (*I)->FindPropertyDeclaration(Context,
104 PropertyId))
Chris Lattner13f63602009-02-20 20:59:54 +0000105 return P;
Fariborz Jahanianfaca5e22009-01-09 21:04:52 +0000106 }
107
Fariborz Jahanian6b0ed6f2009-01-19 18:16:19 +0000108 if (const ObjCInterfaceDecl *OID = dyn_cast<ObjCInterfaceDecl>(this)) {
Steve Naroff451f83c2009-01-09 15:36:25 +0000109 // Look through categories.
110 for (ObjCCategoryDecl *Category = OID->getCategoryList();
111 Category; Category = Category->getNextClassCategory()) {
Douglas Gregorc55b0b02009-04-09 21:40:53 +0000112 if (ObjCPropertyDecl *P = Category->FindPropertyDeclaration(Context,
113 PropertyId))
Chris Lattner13f63602009-02-20 20:59:54 +0000114 return P;
Steve Naroff451f83c2009-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 Gregorc55b0b02009-04-09 21:40:53 +0000119 if (ObjCPropertyDecl *P = (*I)->FindPropertyDeclaration(Context,
120 PropertyId))
Chris Lattner13f63602009-02-20 20:59:54 +0000121 return P;
Steve Naroff451f83c2009-01-09 15:36:25 +0000122 }
123 if (OID->getSuperClass())
Douglas Gregorc55b0b02009-04-09 21:40:53 +0000124 return OID->getSuperClass()->FindPropertyDeclaration(Context,
125 PropertyId);
Chris Lattner13f63602009-02-20 20:59:54 +0000126 } else if (const ObjCCategoryDecl *OCD = dyn_cast<ObjCCategoryDecl>(this)) {
Fariborz Jahanian6b0ed6f2009-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 Gregorc55b0b02009-04-09 21:40:53 +0000130 if (ObjCPropertyDecl *P = (*I)->FindPropertyDeclaration(Context,
131 PropertyId))
Chris Lattner13f63602009-02-20 20:59:54 +0000132 return P;
Fariborz Jahanian6b0ed6f2009-01-19 18:16:19 +0000133 }
134 }
Steve Naroffd1f0eb42008-06-05 13:55:23 +0000135 return 0;
136}
137
Chris Lattner10318b82008-03-16 00:19:01 +0000138ObjCIvarDecl *ObjCInterfaceDecl::lookupInstanceVariable(
Douglas Gregorc55b0b02009-04-09 21:40:53 +0000139 ASTContext &Context, IdentifierInfo *ID, ObjCInterfaceDecl *&clsDeclared) {
Chris Lattner10318b82008-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 Jahanianc625fa92009-03-31 00:06:29 +0000149 // look into properties.
Douglas Gregorc55b0b02009-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 Jahanianc625fa92009-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 Lattner10318b82008-03-16 00:19:01 +0000159 ClassDecl = ClassDecl->getSuperClass();
160 }
161 return NULL;
162}
163
164/// lookupInstanceMethod - This method returns an instance method by looking in
165/// the class, its categories, and its super classes (using a linear search).
Douglas Gregorc55b0b02009-04-09 21:40:53 +0000166ObjCMethodDecl *ObjCInterfaceDecl::lookupInstanceMethod(ASTContext &Context,
167 Selector Sel) {
Chris Lattner10318b82008-03-16 00:19:01 +0000168 ObjCInterfaceDecl* ClassDecl = this;
169 ObjCMethodDecl *MethodDecl = 0;
170
171 while (ClassDecl != NULL) {
Douglas Gregorc55b0b02009-04-09 21:40:53 +0000172 if ((MethodDecl = ClassDecl->getInstanceMethod(Context, Sel)))
Chris Lattner10318b82008-03-16 00:19:01 +0000173 return MethodDecl;
174
175 // Didn't find one yet - look through protocols.
Chris Lattner8bcb5252008-07-21 18:19:38 +0000176 const ObjCList<ObjCProtocolDecl> &Protocols =
177 ClassDecl->getReferencedProtocols();
178 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
179 E = Protocols.end(); I != E; ++I)
Douglas Gregorc55b0b02009-04-09 21:40:53 +0000180 if ((MethodDecl = (*I)->lookupInstanceMethod(Context, Sel)))
Chris Lattner10318b82008-03-16 00:19:01 +0000181 return MethodDecl;
Chris Lattner8bcb5252008-07-21 18:19:38 +0000182
Chris Lattner10318b82008-03-16 00:19:01 +0000183 // Didn't find one yet - now look through categories.
184 ObjCCategoryDecl *CatDecl = ClassDecl->getCategoryList();
185 while (CatDecl) {
Douglas Gregorc55b0b02009-04-09 21:40:53 +0000186 if ((MethodDecl = CatDecl->getInstanceMethod(Context, Sel)))
Chris Lattner10318b82008-03-16 00:19:01 +0000187 return MethodDecl;
Steve Naroffaf151802008-12-08 20:57:28 +0000188
189 // Didn't find one yet - look through protocols.
190 const ObjCList<ObjCProtocolDecl> &Protocols =
191 CatDecl->getReferencedProtocols();
192 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
193 E = Protocols.end(); I != E; ++I)
Douglas Gregorc55b0b02009-04-09 21:40:53 +0000194 if ((MethodDecl = (*I)->lookupInstanceMethod(Context, Sel)))
Steve Naroffaf151802008-12-08 20:57:28 +0000195 return MethodDecl;
Chris Lattner10318b82008-03-16 00:19:01 +0000196 CatDecl = CatDecl->getNextClassCategory();
197 }
198 ClassDecl = ClassDecl->getSuperClass();
199 }
200 return NULL;
201}
202
203// lookupClassMethod - This method returns a class method by looking in the
204// class, its categories, and its super classes (using a linear search).
Douglas Gregorc55b0b02009-04-09 21:40:53 +0000205ObjCMethodDecl *ObjCInterfaceDecl::lookupClassMethod(ASTContext &Context,
206 Selector Sel) {
Chris Lattner10318b82008-03-16 00:19:01 +0000207 ObjCInterfaceDecl* ClassDecl = this;
208 ObjCMethodDecl *MethodDecl = 0;
209
210 while (ClassDecl != NULL) {
Douglas Gregorc55b0b02009-04-09 21:40:53 +0000211 if ((MethodDecl = ClassDecl->getClassMethod(Context, Sel)))
Chris Lattner10318b82008-03-16 00:19:01 +0000212 return MethodDecl;
213
214 // Didn't find one yet - look through protocols.
Chris Lattner0be08822008-07-21 21:32:27 +0000215 for (ObjCInterfaceDecl::protocol_iterator I = ClassDecl->protocol_begin(),
216 E = ClassDecl->protocol_end(); I != E; ++I)
Douglas Gregorc55b0b02009-04-09 21:40:53 +0000217 if ((MethodDecl = (*I)->lookupClassMethod(Context, Sel)))
Chris Lattner10318b82008-03-16 00:19:01 +0000218 return MethodDecl;
Chris Lattner0be08822008-07-21 21:32:27 +0000219
Chris Lattner10318b82008-03-16 00:19:01 +0000220 // Didn't find one yet - now look through categories.
221 ObjCCategoryDecl *CatDecl = ClassDecl->getCategoryList();
222 while (CatDecl) {
Douglas Gregorc55b0b02009-04-09 21:40:53 +0000223 if ((MethodDecl = CatDecl->getClassMethod(Context, Sel)))
Chris Lattner10318b82008-03-16 00:19:01 +0000224 return MethodDecl;
Steve Naroff0ba24842009-02-26 11:32:02 +0000225
226 // Didn't find one yet - look through protocols.
227 const ObjCList<ObjCProtocolDecl> &Protocols =
228 CatDecl->getReferencedProtocols();
229 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
230 E = Protocols.end(); I != E; ++I)
Douglas Gregorc55b0b02009-04-09 21:40:53 +0000231 if ((MethodDecl = (*I)->lookupClassMethod(Context, Sel)))
Steve Naroff0ba24842009-02-26 11:32:02 +0000232 return MethodDecl;
Chris Lattner10318b82008-03-16 00:19:01 +0000233 CatDecl = CatDecl->getNextClassCategory();
234 }
235 ClassDecl = ClassDecl->getSuperClass();
236 }
237 return NULL;
238}
239
Chris Lattner13f63602009-02-20 20:59:54 +0000240
241
242//===----------------------------------------------------------------------===//
243// ObjCMethodDecl
244//===----------------------------------------------------------------------===//
245
246ObjCMethodDecl *ObjCMethodDecl::Create(ASTContext &C,
247 SourceLocation beginLoc,
248 SourceLocation endLoc,
249 Selector SelInfo, QualType T,
250 DeclContext *contextDecl,
251 bool isInstance,
252 bool isVariadic,
253 bool isSynthesized,
254 ImplementationControl impControl) {
255 return new (C) ObjCMethodDecl(beginLoc, endLoc,
256 SelInfo, T, contextDecl,
257 isInstance,
258 isVariadic, isSynthesized, impControl);
Chris Lattner10318b82008-03-16 00:19:01 +0000259}
260
Chris Lattnerdf6133b2009-02-20 21:35:13 +0000261void ObjCMethodDecl::Destroy(ASTContext &C) {
Chris Lattner13f63602009-02-20 20:59:54 +0000262 if (Body) Body->Destroy(C);
263 if (SelfDecl) SelfDecl->Destroy(C);
264
265 for (param_iterator I=param_begin(), E=param_end(); I!=E; ++I)
266 if (*I) (*I)->Destroy(C);
267
Chris Lattnerdf6133b2009-02-20 21:35:13 +0000268 ParamInfo.Destroy(C);
Chris Lattner13f63602009-02-20 20:59:54 +0000269
270 Decl::Destroy(C);
Chris Lattner10318b82008-03-16 00:19:01 +0000271}
272
Chris Lattner13f63602009-02-20 20:59:54 +0000273void ObjCMethodDecl::createImplicitParams(ASTContext &Context,
274 const ObjCInterfaceDecl *OID) {
275 QualType selfTy;
276 if (isInstanceMethod()) {
277 // There may be no interface context due to error in declaration
278 // of the interface (which has been reported). Recover gracefully.
279 if (OID) {
280 selfTy =Context.getObjCInterfaceType(const_cast<ObjCInterfaceDecl*>(OID));
281 selfTy = Context.getPointerType(selfTy);
282 } else {
283 selfTy = Context.getObjCIdType();
284 }
285 } else // we have a factory method.
286 selfTy = Context.getObjCClassType();
287
Steve Naroff79ea0e02009-04-20 15:06:07 +0000288 setSelfDecl(ImplicitParamDecl::Create(Context, this, SourceLocation(),
289 &Context.Idents.get("self"), selfTy));
Chris Lattner13f63602009-02-20 20:59:54 +0000290
Steve Naroff79ea0e02009-04-20 15:06:07 +0000291 setCmdDecl(ImplicitParamDecl::Create(Context, this, SourceLocation(),
292 &Context.Idents.get("_cmd"),
293 Context.getObjCSelType()));
Chris Lattner13f63602009-02-20 20:59:54 +0000294}
295
296
297
298/// getSynthesizedMethodSize - Compute size of synthesized method name
299/// as done be the rewrite.
Fariborz Jahanian68342282008-12-05 22:32:48 +0000300///
Chris Lattner13f63602009-02-20 20:59:54 +0000301unsigned ObjCMethodDecl::getSynthesizedMethodSize() const {
302 // syntesized method name is a concatenation of -/+[class-name selector]
303 // Get length of this name.
304 unsigned length = 3; // _I_ or _C_
305 length += getClassInterface()->getNameAsString().size()+1; // extra for _
306 if (const ObjCCategoryImplDecl *CID =
307 dyn_cast<ObjCCategoryImplDecl>(getDeclContext()))
308 length += CID->getNameAsString().size()+1;
309 length += getSelector().getAsString().size(); // selector name
310 return length;
311}
312
313ObjCInterfaceDecl *ObjCMethodDecl::getClassInterface() {
314 if (ObjCInterfaceDecl *ID = dyn_cast<ObjCInterfaceDecl>(getDeclContext()))
315 return ID;
316 if (ObjCCategoryDecl *CD = dyn_cast<ObjCCategoryDecl>(getDeclContext()))
317 return CD->getClassInterface();
318 if (ObjCImplementationDecl *IMD =
319 dyn_cast<ObjCImplementationDecl>(getDeclContext()))
320 return IMD->getClassInterface();
321 if (ObjCCategoryImplDecl *CID =
322 dyn_cast<ObjCCategoryImplDecl>(getDeclContext()))
323 return CID->getClassInterface();
324 assert(false && "unknown method context");
Fariborz Jahanian68342282008-12-05 22:32:48 +0000325 return 0;
326}
327
Chris Lattner13f63602009-02-20 20:59:54 +0000328//===----------------------------------------------------------------------===//
329// ObjCInterfaceDecl
330//===----------------------------------------------------------------------===//
331
332ObjCInterfaceDecl *ObjCInterfaceDecl::Create(ASTContext &C,
333 DeclContext *DC,
334 SourceLocation atLoc,
335 IdentifierInfo *Id,
336 SourceLocation ClassLoc,
337 bool ForwardDecl, bool isInternal){
338 return new (C) ObjCInterfaceDecl(DC, atLoc, Id, ClassLoc, ForwardDecl,
339 isInternal);
340}
341
342ObjCInterfaceDecl::
343ObjCInterfaceDecl(DeclContext *DC, SourceLocation atLoc, IdentifierInfo *Id,
344 SourceLocation CLoc, bool FD, bool isInternal)
345 : ObjCContainerDecl(ObjCInterface, DC, atLoc, Id),
346 TypeForDecl(0), SuperClass(0),
347 CategoryList(0), ForwardDecl(FD), InternalInterface(isInternal),
348 ClassLoc(CLoc) {
349}
350
351void ObjCInterfaceDecl::Destroy(ASTContext &C) {
Chris Lattnereff36ed2009-03-31 08:36:08 +0000352 for (ivar_iterator I = ivar_begin(), E = ivar_end(); I != E; ++I)
Chris Lattner13f63602009-02-20 20:59:54 +0000353 if (*I) (*I)->Destroy(C);
354
Chris Lattnerdf6133b2009-02-20 21:35:13 +0000355 IVars.Destroy(C);
Chris Lattner13f63602009-02-20 20:59:54 +0000356 // FIXME: CategoryList?
357
358 // FIXME: Because there is no clear ownership
359 // role between ObjCInterfaceDecls and the ObjCPropertyDecls that they
360 // reference, we destroy ObjCPropertyDecls in ~TranslationUnit.
361 Decl::Destroy(C);
362}
363
364
365/// FindCategoryDeclaration - Finds category declaration in the list of
366/// categories for this class and returns it. Name of the category is passed
367/// in 'CategoryId'. If category not found, return 0;
Fariborz Jahanian68342282008-12-05 22:32:48 +0000368///
Chris Lattner13f63602009-02-20 20:59:54 +0000369ObjCCategoryDecl *
370ObjCInterfaceDecl::FindCategoryDeclaration(IdentifierInfo *CategoryId) const {
371 for (ObjCCategoryDecl *Category = getCategoryList();
372 Category; Category = Category->getNextClassCategory())
373 if (Category->getIdentifier() == CategoryId)
374 return Category;
Fariborz Jahanian68342282008-12-05 22:32:48 +0000375 return 0;
376}
377
Daniel Dunbarf0587c62009-04-20 00:37:55 +0000378/// lookupFieldDeclForIvar - looks up a field decl in the laid out
Chris Lattner13f63602009-02-20 20:59:54 +0000379/// storage which matches this 'ivar'.
380///
Daniel Dunbarf0587c62009-04-20 00:37:55 +0000381const FieldDecl *
382ObjCInterfaceDecl::lookupFieldDeclForIvar(ASTContext &Context,
383 const ObjCIvarDecl *IVar) const {
Chris Lattner13f63602009-02-20 20:59:54 +0000384 const RecordDecl *RecordForDecl = Context.addRecordToClass(this);
385 assert(RecordForDecl && "lookupFieldDeclForIvar no storage for class");
Chris Lattnereff36ed2009-03-31 08:36:08 +0000386 DeclContext::lookup_const_result Lookup =
Douglas Gregorc55b0b02009-04-09 21:40:53 +0000387 RecordForDecl->lookup(Context, IVar->getDeclName());
Chris Lattner13f63602009-02-20 20:59:54 +0000388 assert((Lookup.first != Lookup.second) && "field decl not found");
Chris Lattnereff36ed2009-03-31 08:36:08 +0000389 return cast<FieldDecl>(*Lookup.first);
Chris Lattner13f63602009-02-20 20:59:54 +0000390}
391
392//===----------------------------------------------------------------------===//
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 Lattnerdf6133b2009-02-20 21:35:13 +0000430 ReferencedProtocols.Destroy(C);
Chris Lattner13f63602009-02-20 20:59:54 +0000431 ObjCContainerDecl::Destroy(C);
432}
433
Steve Naroff98e71b82009-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 Lattner13f63602009-02-20 20:59:54 +0000447// lookupInstanceMethod - Lookup a instance method in the protocol and protocols
448// it inherited.
Douglas Gregorc55b0b02009-04-09 21:40:53 +0000449ObjCMethodDecl *ObjCProtocolDecl::lookupInstanceMethod(ASTContext &Context,
450 Selector Sel) {
Chris Lattner13f63602009-02-20 20:59:54 +0000451 ObjCMethodDecl *MethodDecl = NULL;
452
Douglas Gregorc55b0b02009-04-09 21:40:53 +0000453 if ((MethodDecl = getInstanceMethod(Context, Sel)))
Chris Lattner13f63602009-02-20 20:59:54 +0000454 return MethodDecl;
455
456 for (protocol_iterator I = protocol_begin(), E = protocol_end(); I != E; ++I)
Douglas Gregorc55b0b02009-04-09 21:40:53 +0000457 if ((MethodDecl = (*I)->lookupInstanceMethod(Context, Sel)))
Chris Lattner13f63602009-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 Gregorc55b0b02009-04-09 21:40:53 +0000464ObjCMethodDecl *ObjCProtocolDecl::lookupClassMethod(ASTContext &Context,
465 Selector Sel) {
Chris Lattner13f63602009-02-20 20:59:54 +0000466 ObjCMethodDecl *MethodDecl = NULL;
467
Douglas Gregorc55b0b02009-04-09 21:40:53 +0000468 if ((MethodDecl = getClassMethod(Context, Sel)))
Chris Lattner13f63602009-02-20 20:59:54 +0000469 return MethodDecl;
470
471 for (protocol_iterator I = protocol_begin(), E = protocol_end(); I != E; ++I)
Douglas Gregorc55b0b02009-04-09 21:40:53 +0000472 if ((MethodDecl = (*I)->lookupClassMethod(Context, Sel)))
Chris Lattner13f63602009-02-20 20:59:54 +0000473 return MethodDecl;
474 return NULL;
475}
476
477//===----------------------------------------------------------------------===//
478// ObjCClassDecl
479//===----------------------------------------------------------------------===//
480
Chris Lattnerdf6133b2009-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 Lattner13f63602009-02-20 20:59:54 +0000489ObjCClassDecl *ObjCClassDecl::Create(ASTContext &C, DeclContext *DC,
490 SourceLocation L,
491 ObjCInterfaceDecl *const *Elts,
492 unsigned nElts) {
Chris Lattnerdf6133b2009-02-20 21:35:13 +0000493 return new (C) ObjCClassDecl(DC, L, Elts, nElts, C);
Chris Lattner13f63602009-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 Lattnerdf6133b2009-02-20 21:35:13 +0000506 ForwardDecls.Destroy(C);
Chris Lattner13f63602009-02-20 20:59:54 +0000507 Decl::Destroy(C);
508}
509
510//===----------------------------------------------------------------------===//
511// ObjCForwardProtocolDecl
512//===----------------------------------------------------------------------===//
513
Chris Lattnerdf6133b2009-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 Lattner13f63602009-02-20 20:59:54 +0000523ObjCForwardProtocolDecl *
524ObjCForwardProtocolDecl::Create(ASTContext &C, DeclContext *DC,
525 SourceLocation L,
526 ObjCProtocolDecl *const *Elts,
527 unsigned NumElts) {
Chris Lattnerdf6133b2009-02-20 21:35:13 +0000528 return new (C) ObjCForwardProtocolDecl(DC, L, Elts, NumElts, C);
Chris Lattner13f63602009-02-20 20:59:54 +0000529}
530
531void ObjCForwardProtocolDecl::Destroy(ASTContext &C) {
Chris Lattnerdf6133b2009-02-20 21:35:13 +0000532 ReferencedProtocols.Destroy(C);
Chris Lattner13f63602009-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
Fariborz Jahanian68342282008-12-05 22:32:48 +0000558/// FindPropertyImplIvarDecl - This method lookup the ivar in the list of
Chris Lattner715e8482009-02-16 19:24:31 +0000559/// properties implemented in this category @implementation block and returns
560/// the implemented property that uses it.
Fariborz Jahanian68342282008-12-05 22:32:48 +0000561///
Chris Lattner649b3da2009-02-28 18:42:10 +0000562ObjCPropertyImplDecl *ObjCImplDecl::
Chris Lattner715e8482009-02-16 19:24:31 +0000563FindPropertyImplIvarDecl(IdentifierInfo *ivarId) const {
564 for (propimpl_iterator i = propimpl_begin(), e = propimpl_end(); i != e; ++i){
Fariborz Jahanian68342282008-12-05 22:32:48 +0000565 ObjCPropertyImplDecl *PID = *i;
566 if (PID->getPropertyIvarDecl() &&
567 PID->getPropertyIvarDecl()->getIdentifier() == ivarId)
568 return PID;
569 }
570 return 0;
571}
572
573/// FindPropertyImplDecl - This method looks up a previous ObjCPropertyImplDecl
574/// added to the list of those properties @synthesized/@dynamic in this
575/// category @implementation block.
576///
Chris Lattner649b3da2009-02-28 18:42:10 +0000577ObjCPropertyImplDecl *ObjCImplDecl::
Chris Lattner715e8482009-02-16 19:24:31 +0000578FindPropertyImplDecl(IdentifierInfo *Id) const {
579 for (propimpl_iterator i = propimpl_begin(), e = propimpl_end(); i != e; ++i){
Fariborz Jahanian68342282008-12-05 22:32:48 +0000580 ObjCPropertyImplDecl *PID = *i;
581 if (PID->getPropertyDecl()->getIdentifier() == Id)
582 return PID;
583 }
584 return 0;
585}
586
Chris Lattner649b3da2009-02-28 18:42:10 +0000587// getInstanceMethod - This method returns an instance method by looking in
Chris Lattner10318b82008-03-16 00:19:01 +0000588// the class implementation. Unlike interfaces, we don't look outside the
589// implementation.
Chris Lattner649b3da2009-02-28 18:42:10 +0000590ObjCMethodDecl *ObjCImplDecl::getInstanceMethod(Selector Sel) const {
Chris Lattner10318b82008-03-16 00:19:01 +0000591 for (instmeth_iterator I = instmeth_begin(), E = instmeth_end(); I != E; ++I)
592 if ((*I)->getSelector() == Sel)
593 return *I;
594 return NULL;
595}
596
Chris Lattner649b3da2009-02-28 18:42:10 +0000597// getClassMethod - This method returns an instance method by looking in
Chris Lattner10318b82008-03-16 00:19:01 +0000598// the class implementation. Unlike interfaces, we don't look outside the
599// implementation.
Chris Lattner649b3da2009-02-28 18:42:10 +0000600ObjCMethodDecl *ObjCImplDecl::getClassMethod(Selector Sel) const {
Chris Lattner10318b82008-03-16 00:19:01 +0000601 for (classmeth_iterator I = classmeth_begin(), E = classmeth_end();
602 I != E; ++I)
603 if ((*I)->getSelector() == Sel)
604 return *I;
605 return NULL;
606}
607
Chris Lattner13f63602009-02-20 20:59:54 +0000608//===----------------------------------------------------------------------===//
609// ObjCImplementationDecl
610//===----------------------------------------------------------------------===//
611
612ObjCImplementationDecl *
613ObjCImplementationDecl::Create(ASTContext &C, DeclContext *DC,
614 SourceLocation L,
615 ObjCInterfaceDecl *ClassInterface,
616 ObjCInterfaceDecl *SuperDecl) {
617 return new (C) ObjCImplementationDecl(DC, L, ClassInterface, SuperDecl);
618}
619
620/// Destroy - Call destructors and release memory.
Chris Lattnerdf6133b2009-02-20 21:35:13 +0000621void ObjCImplementationDecl::Destroy(ASTContext &C) {
622 IVars.Destroy(C);
Chris Lattner13f63602009-02-20 20:59:54 +0000623 Decl::Destroy(C);
624}
625
Chris Lattner13f63602009-02-20 20:59:54 +0000626//===----------------------------------------------------------------------===//
627// ObjCCompatibleAliasDecl
628//===----------------------------------------------------------------------===//
629
630ObjCCompatibleAliasDecl *
631ObjCCompatibleAliasDecl::Create(ASTContext &C, DeclContext *DC,
632 SourceLocation L,
633 IdentifierInfo *Id,
634 ObjCInterfaceDecl* AliasedClass) {
635 return new (C) ObjCCompatibleAliasDecl(DC, L, Id, AliasedClass);
636}
637
638//===----------------------------------------------------------------------===//
639// ObjCPropertyDecl
640//===----------------------------------------------------------------------===//
641
642ObjCPropertyDecl *ObjCPropertyDecl::Create(ASTContext &C, DeclContext *DC,
643 SourceLocation L,
644 IdentifierInfo *Id,
645 QualType T,
646 PropertyControl propControl) {
647 return new (C) ObjCPropertyDecl(DC, L, Id, T);
648}
649
650
651//===----------------------------------------------------------------------===//
652// ObjCPropertyImplDecl
653//===----------------------------------------------------------------------===//
654
Fariborz Jahaniandc0569e2008-04-23 00:06:01 +0000655ObjCPropertyImplDecl *ObjCPropertyImplDecl::Create(ASTContext &C,
Douglas Gregor6e4fa2c2009-01-09 00:49:46 +0000656 DeclContext *DC,
Fariborz Jahaniandc0569e2008-04-23 00:06:01 +0000657 SourceLocation atLoc,
658 SourceLocation L,
659 ObjCPropertyDecl *property,
Daniel Dunbar14117fc2008-08-26 04:47:31 +0000660 Kind PK,
Fariborz Jahaniandc0569e2008-04-23 00:06:01 +0000661 ObjCIvarDecl *ivar) {
Steve Naroff5abb0282009-01-27 21:25:57 +0000662 return new (C) ObjCPropertyImplDecl(DC, atLoc, L, property, PK, ivar);
Fariborz Jahaniandc0569e2008-04-23 00:06:01 +0000663}
Chris Lattner44859612008-03-17 01:19:02 +0000664
Chris Lattnereee57c02008-04-04 06:12:32 +0000665