blob: de10230991a5a52b2daf4fff80c719265da2cec6 [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
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,
Daniel Dunbar5573a582009-04-22 03:45:12 +0000383 const ObjCIvarDecl *OIVD) const {
Daniel Dunbardbc8af72009-04-21 21:41:56 +0000384 assert(!isForwardDecl() && "Invalid interface decl!");
Chris Lattner13f63602009-02-20 20:59:54 +0000385 const RecordDecl *RecordForDecl = Context.addRecordToClass(this);
Chris Lattnereff36ed2009-03-31 08:36:08 +0000386 DeclContext::lookup_const_result Lookup =
Daniel Dunbar5573a582009-04-22 03:45:12 +0000387 RecordForDecl->lookup(Context, OIVD->getDeclName());
388
389 if (Lookup.first != Lookup.second)
390 return cast<FieldDecl>(*Lookup.first);
391
392 // If lookup failed, try the superclass.
393 //
394 // FIXME: This is very non-performant. However, the root problem
395 // here is not the lookup itself. The main issue is that we should
396 // be able to map from an IvarDecl back to the context it lives
397 // inside; then this problem goes away. Currently, however,
398 // IvarDecl's live inside the translation unit!!!!
399 //
400 // Fixing IvarDecl's is less obvious than it might appear, we need
401 // to choose where synthesized ivars should live, and we also need
402 // to decide where to put IvarDecl's which appeared in an
403 // implementation context (either in the situation where they must
404 // duplicate the instance variables, or if there was no instance
405 // declaration).
406 const ObjCInterfaceDecl *OID = getSuperClass();
407 assert(OID && "field decl not found!");
408 return OID->lookupFieldDeclForIvar(Context, OIVD);
Chris Lattner13f63602009-02-20 20:59:54 +0000409}
410
411//===----------------------------------------------------------------------===//
412// ObjCIvarDecl
413//===----------------------------------------------------------------------===//
414
415ObjCIvarDecl *ObjCIvarDecl::Create(ASTContext &C, DeclContext *DC,
416 SourceLocation L, IdentifierInfo *Id,
417 QualType T, AccessControl ac, Expr *BW) {
418 return new (C) ObjCIvarDecl(DC, L, Id, T, ac, BW);
419}
420
421
422
423//===----------------------------------------------------------------------===//
424// ObjCAtDefsFieldDecl
425//===----------------------------------------------------------------------===//
426
427ObjCAtDefsFieldDecl
428*ObjCAtDefsFieldDecl::Create(ASTContext &C, DeclContext *DC, SourceLocation L,
429 IdentifierInfo *Id, QualType T, Expr *BW) {
430 return new (C) ObjCAtDefsFieldDecl(DC, L, Id, T, BW);
431}
432
433void ObjCAtDefsFieldDecl::Destroy(ASTContext& C) {
434 this->~ObjCAtDefsFieldDecl();
435 C.Deallocate((void *)this);
436}
437
438//===----------------------------------------------------------------------===//
439// ObjCProtocolDecl
440//===----------------------------------------------------------------------===//
441
442ObjCProtocolDecl *ObjCProtocolDecl::Create(ASTContext &C, DeclContext *DC,
443 SourceLocation L,
444 IdentifierInfo *Id) {
445 return new (C) ObjCProtocolDecl(DC, L, Id);
446}
447
448void ObjCProtocolDecl::Destroy(ASTContext &C) {
Chris Lattnerdf6133b2009-02-20 21:35:13 +0000449 ReferencedProtocols.Destroy(C);
Chris Lattner13f63602009-02-20 20:59:54 +0000450 ObjCContainerDecl::Destroy(C);
451}
452
Steve Naroff98e71b82009-03-01 16:12:44 +0000453ObjCProtocolDecl *ObjCProtocolDecl::lookupProtocolNamed(IdentifierInfo *Name) {
454 ObjCProtocolDecl *PDecl = this;
455
456 if (Name == getIdentifier())
457 return PDecl;
458
459 for (protocol_iterator I = protocol_begin(), E = protocol_end(); I != E; ++I)
460 if ((PDecl = (*I)->lookupProtocolNamed(Name)))
461 return PDecl;
462
463 return NULL;
464}
465
Chris Lattner13f63602009-02-20 20:59:54 +0000466// lookupInstanceMethod - Lookup a instance method in the protocol and protocols
467// it inherited.
Douglas Gregorc55b0b02009-04-09 21:40:53 +0000468ObjCMethodDecl *ObjCProtocolDecl::lookupInstanceMethod(ASTContext &Context,
469 Selector Sel) {
Chris Lattner13f63602009-02-20 20:59:54 +0000470 ObjCMethodDecl *MethodDecl = NULL;
471
Douglas Gregorc55b0b02009-04-09 21:40:53 +0000472 if ((MethodDecl = getInstanceMethod(Context, Sel)))
Chris Lattner13f63602009-02-20 20:59:54 +0000473 return MethodDecl;
474
475 for (protocol_iterator I = protocol_begin(), E = protocol_end(); I != E; ++I)
Douglas Gregorc55b0b02009-04-09 21:40:53 +0000476 if ((MethodDecl = (*I)->lookupInstanceMethod(Context, Sel)))
Chris Lattner13f63602009-02-20 20:59:54 +0000477 return MethodDecl;
478 return NULL;
479}
480
481// lookupInstanceMethod - Lookup a class method in the protocol and protocols
482// it inherited.
Douglas Gregorc55b0b02009-04-09 21:40:53 +0000483ObjCMethodDecl *ObjCProtocolDecl::lookupClassMethod(ASTContext &Context,
484 Selector Sel) {
Chris Lattner13f63602009-02-20 20:59:54 +0000485 ObjCMethodDecl *MethodDecl = NULL;
486
Douglas Gregorc55b0b02009-04-09 21:40:53 +0000487 if ((MethodDecl = getClassMethod(Context, Sel)))
Chris Lattner13f63602009-02-20 20:59:54 +0000488 return MethodDecl;
489
490 for (protocol_iterator I = protocol_begin(), E = protocol_end(); I != E; ++I)
Douglas Gregorc55b0b02009-04-09 21:40:53 +0000491 if ((MethodDecl = (*I)->lookupClassMethod(Context, Sel)))
Chris Lattner13f63602009-02-20 20:59:54 +0000492 return MethodDecl;
493 return NULL;
494}
495
496//===----------------------------------------------------------------------===//
497// ObjCClassDecl
498//===----------------------------------------------------------------------===//
499
Chris Lattnerdf6133b2009-02-20 21:35:13 +0000500ObjCClassDecl::ObjCClassDecl(DeclContext *DC, SourceLocation L,
501 ObjCInterfaceDecl *const *Elts, unsigned nElts,
502 ASTContext &C)
503 : Decl(ObjCClass, DC, L) {
504 ForwardDecls.set(Elts, nElts, C);
505}
506
507
Chris Lattner13f63602009-02-20 20:59:54 +0000508ObjCClassDecl *ObjCClassDecl::Create(ASTContext &C, DeclContext *DC,
509 SourceLocation L,
510 ObjCInterfaceDecl *const *Elts,
511 unsigned nElts) {
Chris Lattnerdf6133b2009-02-20 21:35:13 +0000512 return new (C) ObjCClassDecl(DC, L, Elts, nElts, C);
Chris Lattner13f63602009-02-20 20:59:54 +0000513}
514
515void ObjCClassDecl::Destroy(ASTContext &C) {
516
517 // FIXME: There is no clear ownership policy now for referenced
518 // ObjCInterfaceDecls. Some of them can be forward declarations that
519 // are never later defined (in which case the ObjCClassDecl owns them)
520 // or the ObjCInterfaceDecl later becomes a real definition later. Ideally
521 // we should have separate objects for forward declarations and definitions,
522 // obviating this problem. Because of this situation, referenced
523 // ObjCInterfaceDecls are destroyed in ~TranslationUnit.
524
Chris Lattnerdf6133b2009-02-20 21:35:13 +0000525 ForwardDecls.Destroy(C);
Chris Lattner13f63602009-02-20 20:59:54 +0000526 Decl::Destroy(C);
527}
528
529//===----------------------------------------------------------------------===//
530// ObjCForwardProtocolDecl
531//===----------------------------------------------------------------------===//
532
Chris Lattnerdf6133b2009-02-20 21:35:13 +0000533ObjCForwardProtocolDecl::
534ObjCForwardProtocolDecl(DeclContext *DC, SourceLocation L,
535 ObjCProtocolDecl *const *Elts, unsigned nElts,
536 ASTContext &C)
537: Decl(ObjCForwardProtocol, DC, L) {
538 ReferencedProtocols.set(Elts, nElts, C);
539}
540
541
Chris Lattner13f63602009-02-20 20:59:54 +0000542ObjCForwardProtocolDecl *
543ObjCForwardProtocolDecl::Create(ASTContext &C, DeclContext *DC,
544 SourceLocation L,
545 ObjCProtocolDecl *const *Elts,
546 unsigned NumElts) {
Chris Lattnerdf6133b2009-02-20 21:35:13 +0000547 return new (C) ObjCForwardProtocolDecl(DC, L, Elts, NumElts, C);
Chris Lattner13f63602009-02-20 20:59:54 +0000548}
549
550void ObjCForwardProtocolDecl::Destroy(ASTContext &C) {
Chris Lattnerdf6133b2009-02-20 21:35:13 +0000551 ReferencedProtocols.Destroy(C);
Chris Lattner13f63602009-02-20 20:59:54 +0000552 Decl::Destroy(C);
553}
554
555//===----------------------------------------------------------------------===//
556// ObjCCategoryDecl
557//===----------------------------------------------------------------------===//
558
559ObjCCategoryDecl *ObjCCategoryDecl::Create(ASTContext &C, DeclContext *DC,
560 SourceLocation L,
561 IdentifierInfo *Id) {
562 return new (C) ObjCCategoryDecl(DC, L, Id);
563}
564
565//===----------------------------------------------------------------------===//
566// ObjCCategoryImplDecl
567//===----------------------------------------------------------------------===//
568
569ObjCCategoryImplDecl *
570ObjCCategoryImplDecl::Create(ASTContext &C, DeclContext *DC,
571 SourceLocation L,IdentifierInfo *Id,
572 ObjCInterfaceDecl *ClassInterface) {
573 return new (C) ObjCCategoryImplDecl(DC, L, Id, ClassInterface);
574}
575
576
Fariborz Jahanian68342282008-12-05 22:32:48 +0000577/// FindPropertyImplIvarDecl - This method lookup the ivar in the list of
Chris Lattner715e8482009-02-16 19:24:31 +0000578/// properties implemented in this category @implementation block and returns
579/// the implemented property that uses it.
Fariborz Jahanian68342282008-12-05 22:32:48 +0000580///
Chris Lattner649b3da2009-02-28 18:42:10 +0000581ObjCPropertyImplDecl *ObjCImplDecl::
Chris Lattner715e8482009-02-16 19:24:31 +0000582FindPropertyImplIvarDecl(IdentifierInfo *ivarId) const {
583 for (propimpl_iterator i = propimpl_begin(), e = propimpl_end(); i != e; ++i){
Fariborz Jahanian68342282008-12-05 22:32:48 +0000584 ObjCPropertyImplDecl *PID = *i;
585 if (PID->getPropertyIvarDecl() &&
586 PID->getPropertyIvarDecl()->getIdentifier() == ivarId)
587 return PID;
588 }
589 return 0;
590}
591
592/// FindPropertyImplDecl - This method looks up a previous ObjCPropertyImplDecl
593/// added to the list of those properties @synthesized/@dynamic in this
594/// category @implementation block.
595///
Chris Lattner649b3da2009-02-28 18:42:10 +0000596ObjCPropertyImplDecl *ObjCImplDecl::
Chris Lattner715e8482009-02-16 19:24:31 +0000597FindPropertyImplDecl(IdentifierInfo *Id) const {
598 for (propimpl_iterator i = propimpl_begin(), e = propimpl_end(); i != e; ++i){
Fariborz Jahanian68342282008-12-05 22:32:48 +0000599 ObjCPropertyImplDecl *PID = *i;
600 if (PID->getPropertyDecl()->getIdentifier() == Id)
601 return PID;
602 }
603 return 0;
604}
605
Chris Lattner649b3da2009-02-28 18:42:10 +0000606// getInstanceMethod - This method returns an instance method by looking in
Chris Lattner10318b82008-03-16 00:19:01 +0000607// the class implementation. Unlike interfaces, we don't look outside the
608// implementation.
Chris Lattner649b3da2009-02-28 18:42:10 +0000609ObjCMethodDecl *ObjCImplDecl::getInstanceMethod(Selector Sel) const {
Chris Lattner10318b82008-03-16 00:19:01 +0000610 for (instmeth_iterator I = instmeth_begin(), E = instmeth_end(); I != E; ++I)
611 if ((*I)->getSelector() == Sel)
612 return *I;
613 return NULL;
614}
615
Chris Lattner649b3da2009-02-28 18:42:10 +0000616// getClassMethod - This method returns an instance method by looking in
Chris Lattner10318b82008-03-16 00:19:01 +0000617// the class implementation. Unlike interfaces, we don't look outside the
618// implementation.
Chris Lattner649b3da2009-02-28 18:42:10 +0000619ObjCMethodDecl *ObjCImplDecl::getClassMethod(Selector Sel) const {
Chris Lattner10318b82008-03-16 00:19:01 +0000620 for (classmeth_iterator I = classmeth_begin(), E = classmeth_end();
621 I != E; ++I)
622 if ((*I)->getSelector() == Sel)
623 return *I;
624 return NULL;
625}
626
Chris Lattner13f63602009-02-20 20:59:54 +0000627//===----------------------------------------------------------------------===//
628// ObjCImplementationDecl
629//===----------------------------------------------------------------------===//
630
631ObjCImplementationDecl *
632ObjCImplementationDecl::Create(ASTContext &C, DeclContext *DC,
633 SourceLocation L,
634 ObjCInterfaceDecl *ClassInterface,
635 ObjCInterfaceDecl *SuperDecl) {
636 return new (C) ObjCImplementationDecl(DC, L, ClassInterface, SuperDecl);
637}
638
639/// Destroy - Call destructors and release memory.
Chris Lattnerdf6133b2009-02-20 21:35:13 +0000640void ObjCImplementationDecl::Destroy(ASTContext &C) {
641 IVars.Destroy(C);
Chris Lattner13f63602009-02-20 20:59:54 +0000642 Decl::Destroy(C);
643}
644
Chris Lattner13f63602009-02-20 20:59:54 +0000645//===----------------------------------------------------------------------===//
646// ObjCCompatibleAliasDecl
647//===----------------------------------------------------------------------===//
648
649ObjCCompatibleAliasDecl *
650ObjCCompatibleAliasDecl::Create(ASTContext &C, DeclContext *DC,
651 SourceLocation L,
652 IdentifierInfo *Id,
653 ObjCInterfaceDecl* AliasedClass) {
654 return new (C) ObjCCompatibleAliasDecl(DC, L, Id, AliasedClass);
655}
656
657//===----------------------------------------------------------------------===//
658// ObjCPropertyDecl
659//===----------------------------------------------------------------------===//
660
661ObjCPropertyDecl *ObjCPropertyDecl::Create(ASTContext &C, DeclContext *DC,
662 SourceLocation L,
663 IdentifierInfo *Id,
664 QualType T,
665 PropertyControl propControl) {
666 return new (C) ObjCPropertyDecl(DC, L, Id, T);
667}
668
669
670//===----------------------------------------------------------------------===//
671// ObjCPropertyImplDecl
672//===----------------------------------------------------------------------===//
673
Fariborz Jahaniandc0569e2008-04-23 00:06:01 +0000674ObjCPropertyImplDecl *ObjCPropertyImplDecl::Create(ASTContext &C,
Douglas Gregor6e4fa2c2009-01-09 00:49:46 +0000675 DeclContext *DC,
Fariborz Jahaniandc0569e2008-04-23 00:06:01 +0000676 SourceLocation atLoc,
677 SourceLocation L,
678 ObjCPropertyDecl *property,
Daniel Dunbar14117fc2008-08-26 04:47:31 +0000679 Kind PK,
Fariborz Jahaniandc0569e2008-04-23 00:06:01 +0000680 ObjCIvarDecl *ivar) {
Steve Naroff5abb0282009-01-27 21:25:57 +0000681 return new (C) ObjCPropertyImplDecl(DC, atLoc, L, property, PK, ivar);
Fariborz Jahaniandc0569e2008-04-23 00:06:01 +0000682}
Chris Lattner44859612008-03-17 01:19:02 +0000683
Chris Lattnereee57c02008-04-04 06:12:32 +0000684