blob: bcd2e08f6d6b48176e98d70fb8bf4d432f7ea4f1 [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) {
Daniel Dunbarbe1ff272009-04-22 04:34:53 +0000280 selfTy = Context.getObjCInterfaceType(OID);
Chris Lattner13f63602009-02-20 20:59:54 +0000281 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
Chris Lattner13f63602009-02-20 20:59:54 +0000378//===----------------------------------------------------------------------===//
379// ObjCIvarDecl
380//===----------------------------------------------------------------------===//
381
382ObjCIvarDecl *ObjCIvarDecl::Create(ASTContext &C, DeclContext *DC,
383 SourceLocation L, IdentifierInfo *Id,
384 QualType T, AccessControl ac, Expr *BW) {
385 return new (C) ObjCIvarDecl(DC, L, Id, T, ac, BW);
386}
387
388
389
390//===----------------------------------------------------------------------===//
391// ObjCAtDefsFieldDecl
392//===----------------------------------------------------------------------===//
393
394ObjCAtDefsFieldDecl
395*ObjCAtDefsFieldDecl::Create(ASTContext &C, DeclContext *DC, SourceLocation L,
396 IdentifierInfo *Id, QualType T, Expr *BW) {
397 return new (C) ObjCAtDefsFieldDecl(DC, L, Id, T, BW);
398}
399
400void ObjCAtDefsFieldDecl::Destroy(ASTContext& C) {
401 this->~ObjCAtDefsFieldDecl();
402 C.Deallocate((void *)this);
403}
404
405//===----------------------------------------------------------------------===//
406// ObjCProtocolDecl
407//===----------------------------------------------------------------------===//
408
409ObjCProtocolDecl *ObjCProtocolDecl::Create(ASTContext &C, DeclContext *DC,
410 SourceLocation L,
411 IdentifierInfo *Id) {
412 return new (C) ObjCProtocolDecl(DC, L, Id);
413}
414
415void ObjCProtocolDecl::Destroy(ASTContext &C) {
Chris Lattnerdf6133b2009-02-20 21:35:13 +0000416 ReferencedProtocols.Destroy(C);
Chris Lattner13f63602009-02-20 20:59:54 +0000417 ObjCContainerDecl::Destroy(C);
418}
419
Steve Naroff98e71b82009-03-01 16:12:44 +0000420ObjCProtocolDecl *ObjCProtocolDecl::lookupProtocolNamed(IdentifierInfo *Name) {
421 ObjCProtocolDecl *PDecl = this;
422
423 if (Name == getIdentifier())
424 return PDecl;
425
426 for (protocol_iterator I = protocol_begin(), E = protocol_end(); I != E; ++I)
427 if ((PDecl = (*I)->lookupProtocolNamed(Name)))
428 return PDecl;
429
430 return NULL;
431}
432
Chris Lattner13f63602009-02-20 20:59:54 +0000433// lookupInstanceMethod - Lookup a instance method in the protocol and protocols
434// it inherited.
Douglas Gregorc55b0b02009-04-09 21:40:53 +0000435ObjCMethodDecl *ObjCProtocolDecl::lookupInstanceMethod(ASTContext &Context,
436 Selector Sel) {
Chris Lattner13f63602009-02-20 20:59:54 +0000437 ObjCMethodDecl *MethodDecl = NULL;
438
Douglas Gregorc55b0b02009-04-09 21:40:53 +0000439 if ((MethodDecl = getInstanceMethod(Context, Sel)))
Chris Lattner13f63602009-02-20 20:59:54 +0000440 return MethodDecl;
441
442 for (protocol_iterator I = protocol_begin(), E = protocol_end(); I != E; ++I)
Douglas Gregorc55b0b02009-04-09 21:40:53 +0000443 if ((MethodDecl = (*I)->lookupInstanceMethod(Context, Sel)))
Chris Lattner13f63602009-02-20 20:59:54 +0000444 return MethodDecl;
445 return NULL;
446}
447
448// lookupInstanceMethod - Lookup a class method in the protocol and protocols
449// it inherited.
Douglas Gregorc55b0b02009-04-09 21:40:53 +0000450ObjCMethodDecl *ObjCProtocolDecl::lookupClassMethod(ASTContext &Context,
451 Selector Sel) {
Chris Lattner13f63602009-02-20 20:59:54 +0000452 ObjCMethodDecl *MethodDecl = NULL;
453
Douglas Gregorc55b0b02009-04-09 21:40:53 +0000454 if ((MethodDecl = getClassMethod(Context, Sel)))
Chris Lattner13f63602009-02-20 20:59:54 +0000455 return MethodDecl;
456
457 for (protocol_iterator I = protocol_begin(), E = protocol_end(); I != E; ++I)
Douglas Gregorc55b0b02009-04-09 21:40:53 +0000458 if ((MethodDecl = (*I)->lookupClassMethod(Context, Sel)))
Chris Lattner13f63602009-02-20 20:59:54 +0000459 return MethodDecl;
460 return NULL;
461}
462
463//===----------------------------------------------------------------------===//
464// ObjCClassDecl
465//===----------------------------------------------------------------------===//
466
Chris Lattnerdf6133b2009-02-20 21:35:13 +0000467ObjCClassDecl::ObjCClassDecl(DeclContext *DC, SourceLocation L,
468 ObjCInterfaceDecl *const *Elts, unsigned nElts,
469 ASTContext &C)
470 : Decl(ObjCClass, DC, L) {
471 ForwardDecls.set(Elts, nElts, C);
472}
473
474
Chris Lattner13f63602009-02-20 20:59:54 +0000475ObjCClassDecl *ObjCClassDecl::Create(ASTContext &C, DeclContext *DC,
476 SourceLocation L,
477 ObjCInterfaceDecl *const *Elts,
478 unsigned nElts) {
Chris Lattnerdf6133b2009-02-20 21:35:13 +0000479 return new (C) ObjCClassDecl(DC, L, Elts, nElts, C);
Chris Lattner13f63602009-02-20 20:59:54 +0000480}
481
482void ObjCClassDecl::Destroy(ASTContext &C) {
483
484 // FIXME: There is no clear ownership policy now for referenced
485 // ObjCInterfaceDecls. Some of them can be forward declarations that
486 // are never later defined (in which case the ObjCClassDecl owns them)
487 // or the ObjCInterfaceDecl later becomes a real definition later. Ideally
488 // we should have separate objects for forward declarations and definitions,
489 // obviating this problem. Because of this situation, referenced
490 // ObjCInterfaceDecls are destroyed in ~TranslationUnit.
491
Chris Lattnerdf6133b2009-02-20 21:35:13 +0000492 ForwardDecls.Destroy(C);
Chris Lattner13f63602009-02-20 20:59:54 +0000493 Decl::Destroy(C);
494}
495
496//===----------------------------------------------------------------------===//
497// ObjCForwardProtocolDecl
498//===----------------------------------------------------------------------===//
499
Chris Lattnerdf6133b2009-02-20 21:35:13 +0000500ObjCForwardProtocolDecl::
501ObjCForwardProtocolDecl(DeclContext *DC, SourceLocation L,
502 ObjCProtocolDecl *const *Elts, unsigned nElts,
503 ASTContext &C)
504: Decl(ObjCForwardProtocol, DC, L) {
505 ReferencedProtocols.set(Elts, nElts, C);
506}
507
508
Chris Lattner13f63602009-02-20 20:59:54 +0000509ObjCForwardProtocolDecl *
510ObjCForwardProtocolDecl::Create(ASTContext &C, DeclContext *DC,
511 SourceLocation L,
512 ObjCProtocolDecl *const *Elts,
513 unsigned NumElts) {
Chris Lattnerdf6133b2009-02-20 21:35:13 +0000514 return new (C) ObjCForwardProtocolDecl(DC, L, Elts, NumElts, C);
Chris Lattner13f63602009-02-20 20:59:54 +0000515}
516
517void ObjCForwardProtocolDecl::Destroy(ASTContext &C) {
Chris Lattnerdf6133b2009-02-20 21:35:13 +0000518 ReferencedProtocols.Destroy(C);
Chris Lattner13f63602009-02-20 20:59:54 +0000519 Decl::Destroy(C);
520}
521
522//===----------------------------------------------------------------------===//
523// ObjCCategoryDecl
524//===----------------------------------------------------------------------===//
525
526ObjCCategoryDecl *ObjCCategoryDecl::Create(ASTContext &C, DeclContext *DC,
527 SourceLocation L,
528 IdentifierInfo *Id) {
529 return new (C) ObjCCategoryDecl(DC, L, Id);
530}
531
532//===----------------------------------------------------------------------===//
533// ObjCCategoryImplDecl
534//===----------------------------------------------------------------------===//
535
536ObjCCategoryImplDecl *
537ObjCCategoryImplDecl::Create(ASTContext &C, DeclContext *DC,
538 SourceLocation L,IdentifierInfo *Id,
539 ObjCInterfaceDecl *ClassInterface) {
540 return new (C) ObjCCategoryImplDecl(DC, L, Id, ClassInterface);
541}
542
543
Douglas Gregorcd19b572009-04-23 01:02:12 +0000544void ObjCImplDecl::addPropertyImplementation(ASTContext &Context,
545 ObjCPropertyImplDecl *property) {
Douglas Gregorbd336c52009-04-23 02:42:49 +0000546 // FIXME: The context should be correct before we get here.
Douglas Gregorcd19b572009-04-23 01:02:12 +0000547 property->setLexicalDeclContext(this);
548 addDecl(Context, property);
549}
550
Fariborz Jahanian68342282008-12-05 22:32:48 +0000551/// FindPropertyImplIvarDecl - This method lookup the ivar in the list of
Chris Lattner715e8482009-02-16 19:24:31 +0000552/// properties implemented in this category @implementation block and returns
553/// the implemented property that uses it.
Fariborz Jahanian68342282008-12-05 22:32:48 +0000554///
Chris Lattner649b3da2009-02-28 18:42:10 +0000555ObjCPropertyImplDecl *ObjCImplDecl::
Douglas Gregorcd19b572009-04-23 01:02:12 +0000556FindPropertyImplIvarDecl(ASTContext &Context, IdentifierInfo *ivarId) const {
557 for (propimpl_iterator i = propimpl_begin(Context), e = propimpl_end(Context);
558 i != e; ++i){
Fariborz Jahanian68342282008-12-05 22:32:48 +0000559 ObjCPropertyImplDecl *PID = *i;
560 if (PID->getPropertyIvarDecl() &&
561 PID->getPropertyIvarDecl()->getIdentifier() == ivarId)
562 return PID;
563 }
564 return 0;
565}
566
567/// FindPropertyImplDecl - This method looks up a previous ObjCPropertyImplDecl
568/// added to the list of those properties @synthesized/@dynamic in this
569/// category @implementation block.
570///
Chris Lattner649b3da2009-02-28 18:42:10 +0000571ObjCPropertyImplDecl *ObjCImplDecl::
Douglas Gregorcd19b572009-04-23 01:02:12 +0000572FindPropertyImplDecl(ASTContext &Context, IdentifierInfo *Id) const {
573 for (propimpl_iterator i = propimpl_begin(Context), e = propimpl_end(Context);
574 i != e; ++i){
Fariborz Jahanian68342282008-12-05 22:32:48 +0000575 ObjCPropertyImplDecl *PID = *i;
576 if (PID->getPropertyDecl()->getIdentifier() == Id)
577 return PID;
578 }
579 return 0;
580}
581
Chris Lattner649b3da2009-02-28 18:42:10 +0000582// getInstanceMethod - This method returns an instance method by looking in
Chris Lattner10318b82008-03-16 00:19:01 +0000583// the class implementation. Unlike interfaces, we don't look outside the
584// implementation.
Douglas Gregorcd19b572009-04-23 01:02:12 +0000585ObjCMethodDecl *ObjCImplDecl::getInstanceMethod(ASTContext &Context,
586 Selector Sel) const {
587 // Since instance & class methods can have the same name, the loop below
588 // ensures we get the correct method.
589 //
590 // @interface Whatever
591 // - (int) class_method;
592 // + (float) class_method;
593 // @end
594 //
595 lookup_const_iterator Meth, MethEnd;
596 for (llvm::tie(Meth, MethEnd) = lookup(Context, Sel);
597 Meth != MethEnd; ++Meth) {
598 ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(*Meth);
599 if (MD && MD->isInstanceMethod())
600 return MD;
601 }
602 return 0;
Chris Lattner10318b82008-03-16 00:19:01 +0000603}
604
Chris Lattner649b3da2009-02-28 18:42:10 +0000605// getClassMethod - This method returns an instance method by looking in
Chris Lattner10318b82008-03-16 00:19:01 +0000606// the class implementation. Unlike interfaces, we don't look outside the
607// implementation.
Douglas Gregorcd19b572009-04-23 01:02:12 +0000608ObjCMethodDecl *ObjCImplDecl::getClassMethod(ASTContext &Context,
609 Selector Sel) const {
610 // Since instance & class methods can have the same name, the loop below
611 // ensures we get the correct method.
612 //
613 // @interface Whatever
614 // - (int) class_method;
615 // + (float) class_method;
616 // @end
617 //
618 lookup_const_iterator Meth, MethEnd;
619 for (llvm::tie(Meth, MethEnd) = lookup(Context, Sel);
620 Meth != MethEnd; ++Meth) {
621 ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(*Meth);
622 if (MD && MD->isClassMethod())
623 return MD;
624 }
625 return 0;
Chris Lattner10318b82008-03-16 00:19:01 +0000626}
627
Chris Lattner13f63602009-02-20 20:59:54 +0000628//===----------------------------------------------------------------------===//
629// ObjCImplementationDecl
630//===----------------------------------------------------------------------===//
631
632ObjCImplementationDecl *
633ObjCImplementationDecl::Create(ASTContext &C, DeclContext *DC,
634 SourceLocation L,
635 ObjCInterfaceDecl *ClassInterface,
636 ObjCInterfaceDecl *SuperDecl) {
637 return new (C) ObjCImplementationDecl(DC, L, ClassInterface, SuperDecl);
638}
639
Chris Lattner13f63602009-02-20 20:59:54 +0000640//===----------------------------------------------------------------------===//
641// ObjCCompatibleAliasDecl
642//===----------------------------------------------------------------------===//
643
644ObjCCompatibleAliasDecl *
645ObjCCompatibleAliasDecl::Create(ASTContext &C, DeclContext *DC,
646 SourceLocation L,
647 IdentifierInfo *Id,
648 ObjCInterfaceDecl* AliasedClass) {
649 return new (C) ObjCCompatibleAliasDecl(DC, L, Id, AliasedClass);
650}
651
652//===----------------------------------------------------------------------===//
653// ObjCPropertyDecl
654//===----------------------------------------------------------------------===//
655
656ObjCPropertyDecl *ObjCPropertyDecl::Create(ASTContext &C, DeclContext *DC,
657 SourceLocation L,
658 IdentifierInfo *Id,
659 QualType T,
660 PropertyControl propControl) {
661 return new (C) ObjCPropertyDecl(DC, L, Id, T);
662}
663
664
665//===----------------------------------------------------------------------===//
666// ObjCPropertyImplDecl
667//===----------------------------------------------------------------------===//
668
Fariborz Jahaniandc0569e2008-04-23 00:06:01 +0000669ObjCPropertyImplDecl *ObjCPropertyImplDecl::Create(ASTContext &C,
Douglas Gregor6e4fa2c2009-01-09 00:49:46 +0000670 DeclContext *DC,
Fariborz Jahaniandc0569e2008-04-23 00:06:01 +0000671 SourceLocation atLoc,
672 SourceLocation L,
673 ObjCPropertyDecl *property,
Daniel Dunbar14117fc2008-08-26 04:47:31 +0000674 Kind PK,
Fariborz Jahaniandc0569e2008-04-23 00:06:01 +0000675 ObjCIvarDecl *ivar) {
Steve Naroff5abb0282009-01-27 21:25:57 +0000676 return new (C) ObjCPropertyImplDecl(DC, atLoc, L, property, PK, ivar);
Fariborz Jahaniandc0569e2008-04-23 00:06:01 +0000677}
Chris Lattner44859612008-03-17 01:19:02 +0000678
Chris Lattnereee57c02008-04-04 06:12:32 +0000679