blob: bdbcce750d0bd4b8dacdb24c53e18e9b9c14cb4d [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.
Steve Naroffab63fd62009-01-08 17:28:14 +000046ObjCMethodDecl *ObjCContainerDecl::getInstanceMethod(Selector Sel) const {
Steve Naroffd85ba922009-02-22 19:35:57 +000047 // Since instance & class methods can have the same name, the loop below
48 // ensures we get the correct method.
49 //
50 // @interface Whatever
51 // - (int) class_method;
52 // + (float) class_method;
53 // @end
54 //
55 lookup_const_iterator Meth, MethEnd;
56 for (llvm::tie(Meth, MethEnd) = lookup(Sel);
57 Meth != MethEnd; ++Meth) {
58 ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(*Meth);
59 if (MD && MD->isInstanceMethod())
60 return MD;
61 }
Steve Naroffab63fd62009-01-08 17:28:14 +000062 return 0;
63}
64
65// Get the local class method declared in this interface.
66ObjCMethodDecl *ObjCContainerDecl::getClassMethod(Selector Sel) const {
Steve Naroffd85ba922009-02-22 19:35:57 +000067 // Since instance & class methods can have the same name, the loop below
68 // ensures we get the correct method.
69 //
70 // @interface Whatever
71 // - (int) class_method;
72 // + (float) class_method;
73 // @end
74 //
75 lookup_const_iterator Meth, MethEnd;
76 for (llvm::tie(Meth, MethEnd) = lookup(Sel);
77 Meth != MethEnd; ++Meth) {
78 ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(*Meth);
79 if (MD && MD->isClassMethod())
80 return MD;
81 }
Steve Naroffab63fd62009-01-08 17:28:14 +000082 return 0;
83}
84
Fariborz Jahanianef8a3df2008-04-21 19:04:53 +000085/// FindPropertyDeclaration - Finds declaration of the property given its name
86/// in 'PropertyId' and returns it. It returns 0, if not found.
Steve Naroffdcf1e842009-01-11 12:47:58 +000087/// FIXME: Convert to DeclContext lookup...
Fariborz Jahanianef8a3df2008-04-21 19:04:53 +000088///
89ObjCPropertyDecl *
Steve Naroff451f83c2009-01-09 15:36:25 +000090ObjCContainerDecl::FindPropertyDeclaration(IdentifierInfo *PropertyId) const {
Chris Lattner13f63602009-02-20 20:59:54 +000091 for (prop_iterator I = prop_begin(), E = prop_end(); I != E; ++I)
92 if ((*I)->getIdentifier() == PropertyId)
93 return *I;
94
Fariborz Jahanianfaca5e22009-01-09 21:04:52 +000095 const ObjCProtocolDecl *PID = dyn_cast<ObjCProtocolDecl>(this);
96 if (PID) {
Chris Lattner13f63602009-02-20 20:59:54 +000097 for (ObjCProtocolDecl::protocol_iterator I = PID->protocol_begin(),
98 E = PID->protocol_end(); I != E; ++I)
99 if (ObjCPropertyDecl *P = (*I)->FindPropertyDeclaration(PropertyId))
100 return P;
Fariborz Jahanianfaca5e22009-01-09 21:04:52 +0000101 }
102
Fariborz Jahanian6b0ed6f2009-01-19 18:16:19 +0000103 if (const ObjCInterfaceDecl *OID = dyn_cast<ObjCInterfaceDecl>(this)) {
Steve Naroff451f83c2009-01-09 15:36:25 +0000104 // Look through categories.
105 for (ObjCCategoryDecl *Category = OID->getCategoryList();
106 Category; Category = Category->getNextClassCategory()) {
Chris Lattner13f63602009-02-20 20:59:54 +0000107 if (ObjCPropertyDecl *P = Category->FindPropertyDeclaration(PropertyId))
108 return P;
Steve Naroff451f83c2009-01-09 15:36:25 +0000109 }
110 // Look through protocols.
111 for (ObjCInterfaceDecl::protocol_iterator I = OID->protocol_begin(),
112 E = OID->protocol_end(); I != E; ++I) {
Chris Lattner13f63602009-02-20 20:59:54 +0000113 if (ObjCPropertyDecl *P = (*I)->FindPropertyDeclaration(PropertyId))
114 return P;
Steve Naroff451f83c2009-01-09 15:36:25 +0000115 }
116 if (OID->getSuperClass())
117 return OID->getSuperClass()->FindPropertyDeclaration(PropertyId);
Chris Lattner13f63602009-02-20 20:59:54 +0000118 } else if (const ObjCCategoryDecl *OCD = dyn_cast<ObjCCategoryDecl>(this)) {
Fariborz Jahanian6b0ed6f2009-01-19 18:16:19 +0000119 // Look through protocols.
120 for (ObjCInterfaceDecl::protocol_iterator I = OCD->protocol_begin(),
121 E = OCD->protocol_end(); I != E; ++I) {
Chris Lattner13f63602009-02-20 20:59:54 +0000122 if (ObjCPropertyDecl *P = (*I)->FindPropertyDeclaration(PropertyId))
123 return P;
Fariborz Jahanian6b0ed6f2009-01-19 18:16:19 +0000124 }
125 }
Steve Naroffd1f0eb42008-06-05 13:55:23 +0000126 return 0;
127}
128
Chris Lattner10318b82008-03-16 00:19:01 +0000129ObjCIvarDecl *ObjCInterfaceDecl::lookupInstanceVariable(
130 IdentifierInfo *ID, ObjCInterfaceDecl *&clsDeclared) {
131 ObjCInterfaceDecl* ClassDecl = this;
132 while (ClassDecl != NULL) {
133 for (ivar_iterator I = ClassDecl->ivar_begin(), E = ClassDecl->ivar_end();
134 I != E; ++I) {
135 if ((*I)->getIdentifier() == ID) {
136 clsDeclared = ClassDecl;
137 return *I;
138 }
139 }
140 ClassDecl = ClassDecl->getSuperClass();
141 }
142 return NULL;
143}
144
145/// lookupInstanceMethod - This method returns an instance method by looking in
146/// the class, its categories, and its super classes (using a linear search).
147ObjCMethodDecl *ObjCInterfaceDecl::lookupInstanceMethod(Selector Sel) {
148 ObjCInterfaceDecl* ClassDecl = this;
149 ObjCMethodDecl *MethodDecl = 0;
150
151 while (ClassDecl != NULL) {
152 if ((MethodDecl = ClassDecl->getInstanceMethod(Sel)))
153 return MethodDecl;
154
155 // Didn't find one yet - look through protocols.
Chris Lattner8bcb5252008-07-21 18:19:38 +0000156 const ObjCList<ObjCProtocolDecl> &Protocols =
157 ClassDecl->getReferencedProtocols();
158 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
159 E = Protocols.end(); I != E; ++I)
Steve Naroff0ba24842009-02-26 11:32:02 +0000160 if ((MethodDecl = (*I)->lookupInstanceMethod(Sel)))
Chris Lattner10318b82008-03-16 00:19:01 +0000161 return MethodDecl;
Chris Lattner8bcb5252008-07-21 18:19:38 +0000162
Chris Lattner10318b82008-03-16 00:19:01 +0000163 // Didn't find one yet - now look through categories.
164 ObjCCategoryDecl *CatDecl = ClassDecl->getCategoryList();
165 while (CatDecl) {
166 if ((MethodDecl = CatDecl->getInstanceMethod(Sel)))
167 return MethodDecl;
Steve Naroffaf151802008-12-08 20:57:28 +0000168
169 // Didn't find one yet - look through protocols.
170 const ObjCList<ObjCProtocolDecl> &Protocols =
171 CatDecl->getReferencedProtocols();
172 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
173 E = Protocols.end(); I != E; ++I)
Steve Naroff0ba24842009-02-26 11:32:02 +0000174 if ((MethodDecl = (*I)->lookupInstanceMethod(Sel)))
Steve Naroffaf151802008-12-08 20:57:28 +0000175 return MethodDecl;
Chris Lattner10318b82008-03-16 00:19:01 +0000176 CatDecl = CatDecl->getNextClassCategory();
177 }
178 ClassDecl = ClassDecl->getSuperClass();
179 }
180 return NULL;
181}
182
183// lookupClassMethod - This method returns a class method by looking in the
184// class, its categories, and its super classes (using a linear search).
185ObjCMethodDecl *ObjCInterfaceDecl::lookupClassMethod(Selector Sel) {
186 ObjCInterfaceDecl* ClassDecl = this;
187 ObjCMethodDecl *MethodDecl = 0;
188
189 while (ClassDecl != NULL) {
190 if ((MethodDecl = ClassDecl->getClassMethod(Sel)))
191 return MethodDecl;
192
193 // Didn't find one yet - look through protocols.
Chris Lattner0be08822008-07-21 21:32:27 +0000194 for (ObjCInterfaceDecl::protocol_iterator I = ClassDecl->protocol_begin(),
195 E = ClassDecl->protocol_end(); I != E; ++I)
Steve Naroff0ba24842009-02-26 11:32:02 +0000196 if ((MethodDecl = (*I)->lookupClassMethod(Sel)))
Chris Lattner10318b82008-03-16 00:19:01 +0000197 return MethodDecl;
Chris Lattner0be08822008-07-21 21:32:27 +0000198
Chris Lattner10318b82008-03-16 00:19:01 +0000199 // Didn't find one yet - now look through categories.
200 ObjCCategoryDecl *CatDecl = ClassDecl->getCategoryList();
201 while (CatDecl) {
202 if ((MethodDecl = CatDecl->getClassMethod(Sel)))
203 return MethodDecl;
Steve Naroff0ba24842009-02-26 11:32:02 +0000204
205 // Didn't find one yet - look through protocols.
206 const ObjCList<ObjCProtocolDecl> &Protocols =
207 CatDecl->getReferencedProtocols();
208 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
209 E = Protocols.end(); I != E; ++I)
210 if ((MethodDecl = (*I)->lookupClassMethod(Sel)))
211 return MethodDecl;
Chris Lattner10318b82008-03-16 00:19:01 +0000212 CatDecl = CatDecl->getNextClassCategory();
213 }
214 ClassDecl = ClassDecl->getSuperClass();
215 }
216 return NULL;
217}
218
Chris Lattner13f63602009-02-20 20:59:54 +0000219
220
221//===----------------------------------------------------------------------===//
222// ObjCMethodDecl
223//===----------------------------------------------------------------------===//
224
225ObjCMethodDecl *ObjCMethodDecl::Create(ASTContext &C,
226 SourceLocation beginLoc,
227 SourceLocation endLoc,
228 Selector SelInfo, QualType T,
229 DeclContext *contextDecl,
230 bool isInstance,
231 bool isVariadic,
232 bool isSynthesized,
233 ImplementationControl impControl) {
234 return new (C) ObjCMethodDecl(beginLoc, endLoc,
235 SelInfo, T, contextDecl,
236 isInstance,
237 isVariadic, isSynthesized, impControl);
Chris Lattner10318b82008-03-16 00:19:01 +0000238}
239
Chris Lattnerdf6133b2009-02-20 21:35:13 +0000240void ObjCMethodDecl::Destroy(ASTContext &C) {
Chris Lattner13f63602009-02-20 20:59:54 +0000241 if (Body) Body->Destroy(C);
242 if (SelfDecl) SelfDecl->Destroy(C);
243
244 for (param_iterator I=param_begin(), E=param_end(); I!=E; ++I)
245 if (*I) (*I)->Destroy(C);
246
Chris Lattnerdf6133b2009-02-20 21:35:13 +0000247 ParamInfo.Destroy(C);
Chris Lattner13f63602009-02-20 20:59:54 +0000248
249 Decl::Destroy(C);
Chris Lattner10318b82008-03-16 00:19:01 +0000250}
251
Chris Lattner13f63602009-02-20 20:59:54 +0000252void ObjCMethodDecl::createImplicitParams(ASTContext &Context,
253 const ObjCInterfaceDecl *OID) {
254 QualType selfTy;
255 if (isInstanceMethod()) {
256 // There may be no interface context due to error in declaration
257 // of the interface (which has been reported). Recover gracefully.
258 if (OID) {
259 selfTy =Context.getObjCInterfaceType(const_cast<ObjCInterfaceDecl*>(OID));
260 selfTy = Context.getPointerType(selfTy);
261 } else {
262 selfTy = Context.getObjCIdType();
263 }
264 } else // we have a factory method.
265 selfTy = Context.getObjCClassType();
266
267 SelfDecl = ImplicitParamDecl::Create(Context, this, SourceLocation(),
268 &Context.Idents.get("self"), selfTy);
269
270 CmdDecl = ImplicitParamDecl::Create(Context, this, SourceLocation(),
271 &Context.Idents.get("_cmd"),
272 Context.getObjCSelType());
273}
274
275
276
277/// getSynthesizedMethodSize - Compute size of synthesized method name
278/// as done be the rewrite.
Fariborz Jahanian68342282008-12-05 22:32:48 +0000279///
Chris Lattner13f63602009-02-20 20:59:54 +0000280unsigned ObjCMethodDecl::getSynthesizedMethodSize() const {
281 // syntesized method name is a concatenation of -/+[class-name selector]
282 // Get length of this name.
283 unsigned length = 3; // _I_ or _C_
284 length += getClassInterface()->getNameAsString().size()+1; // extra for _
285 if (const ObjCCategoryImplDecl *CID =
286 dyn_cast<ObjCCategoryImplDecl>(getDeclContext()))
287 length += CID->getNameAsString().size()+1;
288 length += getSelector().getAsString().size(); // selector name
289 return length;
290}
291
292ObjCInterfaceDecl *ObjCMethodDecl::getClassInterface() {
293 if (ObjCInterfaceDecl *ID = dyn_cast<ObjCInterfaceDecl>(getDeclContext()))
294 return ID;
295 if (ObjCCategoryDecl *CD = dyn_cast<ObjCCategoryDecl>(getDeclContext()))
296 return CD->getClassInterface();
297 if (ObjCImplementationDecl *IMD =
298 dyn_cast<ObjCImplementationDecl>(getDeclContext()))
299 return IMD->getClassInterface();
300 if (ObjCCategoryImplDecl *CID =
301 dyn_cast<ObjCCategoryImplDecl>(getDeclContext()))
302 return CID->getClassInterface();
303 assert(false && "unknown method context");
Fariborz Jahanian68342282008-12-05 22:32:48 +0000304 return 0;
305}
306
Chris Lattner13f63602009-02-20 20:59:54 +0000307//===----------------------------------------------------------------------===//
308// ObjCInterfaceDecl
309//===----------------------------------------------------------------------===//
310
311ObjCInterfaceDecl *ObjCInterfaceDecl::Create(ASTContext &C,
312 DeclContext *DC,
313 SourceLocation atLoc,
314 IdentifierInfo *Id,
315 SourceLocation ClassLoc,
316 bool ForwardDecl, bool isInternal){
317 return new (C) ObjCInterfaceDecl(DC, atLoc, Id, ClassLoc, ForwardDecl,
318 isInternal);
319}
320
321ObjCInterfaceDecl::
322ObjCInterfaceDecl(DeclContext *DC, SourceLocation atLoc, IdentifierInfo *Id,
323 SourceLocation CLoc, bool FD, bool isInternal)
324 : ObjCContainerDecl(ObjCInterface, DC, atLoc, Id),
325 TypeForDecl(0), SuperClass(0),
326 CategoryList(0), ForwardDecl(FD), InternalInterface(isInternal),
327 ClassLoc(CLoc) {
328}
329
330void ObjCInterfaceDecl::Destroy(ASTContext &C) {
331 for (ivar_iterator I=ivar_begin(), E=ivar_end(); I!=E; ++I)
332 if (*I) (*I)->Destroy(C);
333
Chris Lattnerdf6133b2009-02-20 21:35:13 +0000334 IVars.Destroy(C);
Chris Lattner13f63602009-02-20 20:59:54 +0000335 // FIXME: CategoryList?
336
337 // FIXME: Because there is no clear ownership
338 // role between ObjCInterfaceDecls and the ObjCPropertyDecls that they
339 // reference, we destroy ObjCPropertyDecls in ~TranslationUnit.
340 Decl::Destroy(C);
341}
342
343
344/// FindCategoryDeclaration - Finds category declaration in the list of
345/// categories for this class and returns it. Name of the category is passed
346/// in 'CategoryId'. If category not found, return 0;
Fariborz Jahanian68342282008-12-05 22:32:48 +0000347///
Chris Lattner13f63602009-02-20 20:59:54 +0000348ObjCCategoryDecl *
349ObjCInterfaceDecl::FindCategoryDeclaration(IdentifierInfo *CategoryId) const {
350 for (ObjCCategoryDecl *Category = getCategoryList();
351 Category; Category = Category->getNextClassCategory())
352 if (Category->getIdentifier() == CategoryId)
353 return Category;
Fariborz Jahanian68342282008-12-05 22:32:48 +0000354 return 0;
355}
356
Chris Lattner13f63602009-02-20 20:59:54 +0000357/// lookupFieldDeclForIvar - looks up a field decl' in the laid out
358/// storage which matches this 'ivar'.
359///
360FieldDecl *ObjCInterfaceDecl::lookupFieldDeclForIvar(ASTContext &Context,
361 const ObjCIvarDecl *IVar) {
362 const RecordDecl *RecordForDecl = Context.addRecordToClass(this);
363 assert(RecordForDecl && "lookupFieldDeclForIvar no storage for class");
364 DeclarationName Member = IVar->getDeclName();
365 DeclContext::lookup_result Lookup =
366 (const_cast< RecordDecl *>(RecordForDecl))->lookup(Member);
367 assert((Lookup.first != Lookup.second) && "field decl not found");
368 FieldDecl *MemberDecl = dyn_cast<FieldDecl>(*Lookup.first);
369 assert(MemberDecl && "field decl not found");
370 return MemberDecl;
371}
372
373//===----------------------------------------------------------------------===//
374// ObjCIvarDecl
375//===----------------------------------------------------------------------===//
376
377ObjCIvarDecl *ObjCIvarDecl::Create(ASTContext &C, DeclContext *DC,
378 SourceLocation L, IdentifierInfo *Id,
379 QualType T, AccessControl ac, Expr *BW) {
380 return new (C) ObjCIvarDecl(DC, L, Id, T, ac, BW);
381}
382
383
384
385//===----------------------------------------------------------------------===//
386// ObjCAtDefsFieldDecl
387//===----------------------------------------------------------------------===//
388
389ObjCAtDefsFieldDecl
390*ObjCAtDefsFieldDecl::Create(ASTContext &C, DeclContext *DC, SourceLocation L,
391 IdentifierInfo *Id, QualType T, Expr *BW) {
392 return new (C) ObjCAtDefsFieldDecl(DC, L, Id, T, BW);
393}
394
395void ObjCAtDefsFieldDecl::Destroy(ASTContext& C) {
396 this->~ObjCAtDefsFieldDecl();
397 C.Deallocate((void *)this);
398}
399
400//===----------------------------------------------------------------------===//
401// ObjCProtocolDecl
402//===----------------------------------------------------------------------===//
403
404ObjCProtocolDecl *ObjCProtocolDecl::Create(ASTContext &C, DeclContext *DC,
405 SourceLocation L,
406 IdentifierInfo *Id) {
407 return new (C) ObjCProtocolDecl(DC, L, Id);
408}
409
410void ObjCProtocolDecl::Destroy(ASTContext &C) {
Chris Lattnerdf6133b2009-02-20 21:35:13 +0000411 ReferencedProtocols.Destroy(C);
Chris Lattner13f63602009-02-20 20:59:54 +0000412 ObjCContainerDecl::Destroy(C);
413}
414
415// lookupInstanceMethod - Lookup a instance method in the protocol and protocols
416// it inherited.
417ObjCMethodDecl *ObjCProtocolDecl::lookupInstanceMethod(Selector Sel) {
418 ObjCMethodDecl *MethodDecl = NULL;
419
420 if ((MethodDecl = getInstanceMethod(Sel)))
421 return MethodDecl;
422
423 for (protocol_iterator I = protocol_begin(), E = protocol_end(); I != E; ++I)
424 if ((MethodDecl = (*I)->lookupInstanceMethod(Sel)))
425 return MethodDecl;
426 return NULL;
427}
428
429// lookupInstanceMethod - Lookup a class method in the protocol and protocols
430// it inherited.
431ObjCMethodDecl *ObjCProtocolDecl::lookupClassMethod(Selector Sel) {
432 ObjCMethodDecl *MethodDecl = NULL;
433
434 if ((MethodDecl = getClassMethod(Sel)))
435 return MethodDecl;
436
437 for (protocol_iterator I = protocol_begin(), E = protocol_end(); I != E; ++I)
438 if ((MethodDecl = (*I)->lookupClassMethod(Sel)))
439 return MethodDecl;
440 return NULL;
441}
442
443//===----------------------------------------------------------------------===//
444// ObjCClassDecl
445//===----------------------------------------------------------------------===//
446
Chris Lattnerdf6133b2009-02-20 21:35:13 +0000447ObjCClassDecl::ObjCClassDecl(DeclContext *DC, SourceLocation L,
448 ObjCInterfaceDecl *const *Elts, unsigned nElts,
449 ASTContext &C)
450 : Decl(ObjCClass, DC, L) {
451 ForwardDecls.set(Elts, nElts, C);
452}
453
454
Chris Lattner13f63602009-02-20 20:59:54 +0000455ObjCClassDecl *ObjCClassDecl::Create(ASTContext &C, DeclContext *DC,
456 SourceLocation L,
457 ObjCInterfaceDecl *const *Elts,
458 unsigned nElts) {
Chris Lattnerdf6133b2009-02-20 21:35:13 +0000459 return new (C) ObjCClassDecl(DC, L, Elts, nElts, C);
Chris Lattner13f63602009-02-20 20:59:54 +0000460}
461
462void ObjCClassDecl::Destroy(ASTContext &C) {
463
464 // FIXME: There is no clear ownership policy now for referenced
465 // ObjCInterfaceDecls. Some of them can be forward declarations that
466 // are never later defined (in which case the ObjCClassDecl owns them)
467 // or the ObjCInterfaceDecl later becomes a real definition later. Ideally
468 // we should have separate objects for forward declarations and definitions,
469 // obviating this problem. Because of this situation, referenced
470 // ObjCInterfaceDecls are destroyed in ~TranslationUnit.
471
Chris Lattnerdf6133b2009-02-20 21:35:13 +0000472 ForwardDecls.Destroy(C);
Chris Lattner13f63602009-02-20 20:59:54 +0000473 Decl::Destroy(C);
474}
475
476//===----------------------------------------------------------------------===//
477// ObjCForwardProtocolDecl
478//===----------------------------------------------------------------------===//
479
Chris Lattnerdf6133b2009-02-20 21:35:13 +0000480ObjCForwardProtocolDecl::
481ObjCForwardProtocolDecl(DeclContext *DC, SourceLocation L,
482 ObjCProtocolDecl *const *Elts, unsigned nElts,
483 ASTContext &C)
484: Decl(ObjCForwardProtocol, DC, L) {
485 ReferencedProtocols.set(Elts, nElts, C);
486}
487
488
Chris Lattner13f63602009-02-20 20:59:54 +0000489ObjCForwardProtocolDecl *
490ObjCForwardProtocolDecl::Create(ASTContext &C, DeclContext *DC,
491 SourceLocation L,
492 ObjCProtocolDecl *const *Elts,
493 unsigned NumElts) {
Chris Lattnerdf6133b2009-02-20 21:35:13 +0000494 return new (C) ObjCForwardProtocolDecl(DC, L, Elts, NumElts, C);
Chris Lattner13f63602009-02-20 20:59:54 +0000495}
496
497void ObjCForwardProtocolDecl::Destroy(ASTContext &C) {
Chris Lattnerdf6133b2009-02-20 21:35:13 +0000498 ReferencedProtocols.Destroy(C);
Chris Lattner13f63602009-02-20 20:59:54 +0000499 Decl::Destroy(C);
500}
501
502//===----------------------------------------------------------------------===//
503// ObjCCategoryDecl
504//===----------------------------------------------------------------------===//
505
506ObjCCategoryDecl *ObjCCategoryDecl::Create(ASTContext &C, DeclContext *DC,
507 SourceLocation L,
508 IdentifierInfo *Id) {
509 return new (C) ObjCCategoryDecl(DC, L, Id);
510}
511
512//===----------------------------------------------------------------------===//
513// ObjCCategoryImplDecl
514//===----------------------------------------------------------------------===//
515
516ObjCCategoryImplDecl *
517ObjCCategoryImplDecl::Create(ASTContext &C, DeclContext *DC,
518 SourceLocation L,IdentifierInfo *Id,
519 ObjCInterfaceDecl *ClassInterface) {
520 return new (C) ObjCCategoryImplDecl(DC, L, Id, ClassInterface);
521}
522
523
Fariborz Jahanian68342282008-12-05 22:32:48 +0000524/// FindPropertyImplIvarDecl - This method lookup the ivar in the list of
Chris Lattner715e8482009-02-16 19:24:31 +0000525/// properties implemented in this category @implementation block and returns
526/// the implemented property that uses it.
Fariborz Jahanian68342282008-12-05 22:32:48 +0000527///
Chris Lattner649b3da2009-02-28 18:42:10 +0000528ObjCPropertyImplDecl *ObjCImplDecl::
Chris Lattner715e8482009-02-16 19:24:31 +0000529FindPropertyImplIvarDecl(IdentifierInfo *ivarId) const {
530 for (propimpl_iterator i = propimpl_begin(), e = propimpl_end(); i != e; ++i){
Fariborz Jahanian68342282008-12-05 22:32:48 +0000531 ObjCPropertyImplDecl *PID = *i;
532 if (PID->getPropertyIvarDecl() &&
533 PID->getPropertyIvarDecl()->getIdentifier() == ivarId)
534 return PID;
535 }
536 return 0;
537}
538
539/// FindPropertyImplDecl - This method looks up a previous ObjCPropertyImplDecl
540/// added to the list of those properties @synthesized/@dynamic in this
541/// category @implementation block.
542///
Chris Lattner649b3da2009-02-28 18:42:10 +0000543ObjCPropertyImplDecl *ObjCImplDecl::
Chris Lattner715e8482009-02-16 19:24:31 +0000544FindPropertyImplDecl(IdentifierInfo *Id) const {
545 for (propimpl_iterator i = propimpl_begin(), e = propimpl_end(); i != e; ++i){
Fariborz Jahanian68342282008-12-05 22:32:48 +0000546 ObjCPropertyImplDecl *PID = *i;
547 if (PID->getPropertyDecl()->getIdentifier() == Id)
548 return PID;
549 }
550 return 0;
551}
552
Chris Lattner649b3da2009-02-28 18:42:10 +0000553// getInstanceMethod - This method returns an instance method by looking in
Chris Lattner10318b82008-03-16 00:19:01 +0000554// the class implementation. Unlike interfaces, we don't look outside the
555// implementation.
Chris Lattner649b3da2009-02-28 18:42:10 +0000556ObjCMethodDecl *ObjCImplDecl::getInstanceMethod(Selector Sel) const {
Chris Lattner10318b82008-03-16 00:19:01 +0000557 for (instmeth_iterator I = instmeth_begin(), E = instmeth_end(); I != E; ++I)
558 if ((*I)->getSelector() == Sel)
559 return *I;
560 return NULL;
561}
562
Chris Lattner649b3da2009-02-28 18:42:10 +0000563// getClassMethod - This method returns an instance method by looking in
Chris Lattner10318b82008-03-16 00:19:01 +0000564// the class implementation. Unlike interfaces, we don't look outside the
565// implementation.
Chris Lattner649b3da2009-02-28 18:42:10 +0000566ObjCMethodDecl *ObjCImplDecl::getClassMethod(Selector Sel) const {
Chris Lattner10318b82008-03-16 00:19:01 +0000567 for (classmeth_iterator I = classmeth_begin(), E = classmeth_end();
568 I != E; ++I)
569 if ((*I)->getSelector() == Sel)
570 return *I;
571 return NULL;
572}
573
Chris Lattner13f63602009-02-20 20:59:54 +0000574//===----------------------------------------------------------------------===//
575// ObjCImplementationDecl
576//===----------------------------------------------------------------------===//
577
578ObjCImplementationDecl *
579ObjCImplementationDecl::Create(ASTContext &C, DeclContext *DC,
580 SourceLocation L,
581 ObjCInterfaceDecl *ClassInterface,
582 ObjCInterfaceDecl *SuperDecl) {
583 return new (C) ObjCImplementationDecl(DC, L, ClassInterface, SuperDecl);
584}
585
586/// Destroy - Call destructors and release memory.
Chris Lattnerdf6133b2009-02-20 21:35:13 +0000587void ObjCImplementationDecl::Destroy(ASTContext &C) {
588 IVars.Destroy(C);
Chris Lattner13f63602009-02-20 20:59:54 +0000589 Decl::Destroy(C);
590}
591
Chris Lattner13f63602009-02-20 20:59:54 +0000592//===----------------------------------------------------------------------===//
593// ObjCCompatibleAliasDecl
594//===----------------------------------------------------------------------===//
595
596ObjCCompatibleAliasDecl *
597ObjCCompatibleAliasDecl::Create(ASTContext &C, DeclContext *DC,
598 SourceLocation L,
599 IdentifierInfo *Id,
600 ObjCInterfaceDecl* AliasedClass) {
601 return new (C) ObjCCompatibleAliasDecl(DC, L, Id, AliasedClass);
602}
603
604//===----------------------------------------------------------------------===//
605// ObjCPropertyDecl
606//===----------------------------------------------------------------------===//
607
608ObjCPropertyDecl *ObjCPropertyDecl::Create(ASTContext &C, DeclContext *DC,
609 SourceLocation L,
610 IdentifierInfo *Id,
611 QualType T,
612 PropertyControl propControl) {
613 return new (C) ObjCPropertyDecl(DC, L, Id, T);
614}
615
616
617//===----------------------------------------------------------------------===//
618// ObjCPropertyImplDecl
619//===----------------------------------------------------------------------===//
620
Fariborz Jahaniandc0569e2008-04-23 00:06:01 +0000621ObjCPropertyImplDecl *ObjCPropertyImplDecl::Create(ASTContext &C,
Douglas Gregor6e4fa2c2009-01-09 00:49:46 +0000622 DeclContext *DC,
Fariborz Jahaniandc0569e2008-04-23 00:06:01 +0000623 SourceLocation atLoc,
624 SourceLocation L,
625 ObjCPropertyDecl *property,
Daniel Dunbar14117fc2008-08-26 04:47:31 +0000626 Kind PK,
Fariborz Jahaniandc0569e2008-04-23 00:06:01 +0000627 ObjCIvarDecl *ivar) {
Steve Naroff5abb0282009-01-27 21:25:57 +0000628 return new (C) ObjCPropertyImplDecl(DC, atLoc, L, property, PK, ivar);
Fariborz Jahaniandc0569e2008-04-23 00:06:01 +0000629}
Chris Lattner44859612008-03-17 01:19:02 +0000630
Chris Lattnereee57c02008-04-04 06:12:32 +0000631