1 //===--- DeclObjC.cpp - ObjC Declaration AST Node Implementation ----------===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This file implements the Objective-C related Decl classes.
12 //===----------------------------------------------------------------------===//
14 #include "clang/AST/DeclObjC.h"
15 #include "clang/AST/ASTContext.h"
16 #include "clang/AST/Stmt.h"
17 #include "llvm/ADT/STLExtras.h"
18 using namespace clang;
20 //===----------------------------------------------------------------------===//
22 //===----------------------------------------------------------------------===//
24 void ObjCListBase::Destroy(ASTContext &Ctx) {
30 void ObjCListBase::set(void *const* InList, unsigned Elts, ASTContext &Ctx) {
31 assert(List == 0 && "Elements already set!");
32 if (Elts == 0) return; // Setting to an empty list is a noop.
35 List = new (Ctx) void*[Elts];
37 memcpy(List, InList, sizeof(void*)*Elts);
41 //===----------------------------------------------------------------------===//
43 //===----------------------------------------------------------------------===//
45 /// getIvarDecl - This method looks up an ivar in this ContextDecl.
48 ObjCContainerDecl::getIvarDecl(IdentifierInfo *Id) const {
49 lookup_const_iterator Ivar, IvarEnd;
50 for (llvm::tie(Ivar, IvarEnd) = lookup(Id); Ivar != IvarEnd; ++Ivar) {
51 if (ObjCIvarDecl *ivar = dyn_cast<ObjCIvarDecl>(*Ivar))
57 // Get the local instance method declared in this interface.
59 ObjCContainerDecl::getInstanceMethod(Selector Sel) const {
60 // Since instance & class methods can have the same name, the loop below
61 // ensures we get the correct method.
63 // @interface Whatever
64 // - (int) class_method;
65 // + (float) class_method;
68 lookup_const_iterator Meth, MethEnd;
69 for (llvm::tie(Meth, MethEnd) = lookup(Sel); Meth != MethEnd; ++Meth) {
70 ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(*Meth);
71 if (MD && MD->isInstanceMethod())
77 // Get the local class method declared in this interface.
79 ObjCContainerDecl::getClassMethod(Selector Sel) const {
80 // Since instance & class methods can have the same name, the loop below
81 // ensures we get the correct method.
83 // @interface Whatever
84 // - (int) class_method;
85 // + (float) class_method;
88 lookup_const_iterator Meth, MethEnd;
89 for (llvm::tie(Meth, MethEnd) = lookup(Sel); Meth != MethEnd; ++Meth) {
90 ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(*Meth);
91 if (MD && MD->isClassMethod())
97 /// FindPropertyDeclaration - Finds declaration of the property given its name
98 /// in 'PropertyId' and returns it. It returns 0, if not found.
99 /// FIXME: Convert to DeclContext lookup...
102 ObjCContainerDecl::FindPropertyDeclaration(IdentifierInfo *PropertyId) const {
103 for (prop_iterator I = prop_begin(), E = prop_end(); I != E; ++I)
104 if ((*I)->getIdentifier() == PropertyId)
107 const ObjCProtocolDecl *PID = dyn_cast<ObjCProtocolDecl>(this);
109 for (ObjCProtocolDecl::protocol_iterator I = PID->protocol_begin(),
110 E = PID->protocol_end(); I != E; ++I)
111 if (ObjCPropertyDecl *P = (*I)->FindPropertyDeclaration(PropertyId))
115 if (const ObjCInterfaceDecl *OID = dyn_cast<ObjCInterfaceDecl>(this)) {
116 // Look through categories.
117 for (ObjCCategoryDecl *Category = OID->getCategoryList();
118 Category; Category = Category->getNextClassCategory()) {
119 if (ObjCPropertyDecl *P = Category->FindPropertyDeclaration(PropertyId))
122 // Look through protocols.
123 for (ObjCInterfaceDecl::protocol_iterator I = OID->protocol_begin(),
124 E = OID->protocol_end(); I != E; ++I) {
125 if (ObjCPropertyDecl *P = (*I)->FindPropertyDeclaration(PropertyId))
128 if (OID->getSuperClass())
129 return OID->getSuperClass()->FindPropertyDeclaration(PropertyId);
130 } else if (const ObjCCategoryDecl *OCD = dyn_cast<ObjCCategoryDecl>(this)) {
131 // Look through protocols.
132 for (ObjCInterfaceDecl::protocol_iterator I = OCD->protocol_begin(),
133 E = OCD->protocol_end(); I != E; ++I) {
134 if (ObjCPropertyDecl *P = (*I)->FindPropertyDeclaration(PropertyId))
141 ObjCIvarDecl *ObjCInterfaceDecl::lookupInstanceVariable(IdentifierInfo *ID,
142 ObjCInterfaceDecl *&clsDeclared) {
143 ObjCInterfaceDecl* ClassDecl = this;
144 while (ClassDecl != NULL) {
145 if (ObjCIvarDecl *I = ClassDecl->getIvarDecl(ID)) {
146 clsDeclared = ClassDecl;
149 ClassDecl = ClassDecl->getSuperClass();
154 /// lookupInheritedClass - This method returns ObjCInterfaceDecl * of the super
155 /// class whose name is passed as argument. If it is not one of the super classes
156 /// the it returns NULL.
157 ObjCInterfaceDecl *ObjCInterfaceDecl::lookupInheritedClass(
158 const IdentifierInfo*ICName) {
159 ObjCInterfaceDecl* ClassDecl = this;
160 while (ClassDecl != NULL) {
161 if (ClassDecl->getIdentifier() == ICName)
163 ClassDecl = ClassDecl->getSuperClass();
168 /// lookupInstanceMethod - This method returns an instance method by looking in
169 /// the class, its categories, and its super classes (using a linear search).
170 ObjCMethodDecl *ObjCInterfaceDecl::lookupInstanceMethod(Selector Sel) {
171 ObjCInterfaceDecl* ClassDecl = this;
172 ObjCMethodDecl *MethodDecl = 0;
174 while (ClassDecl != NULL) {
175 if ((MethodDecl = ClassDecl->getInstanceMethod(Sel)))
178 // Didn't find one yet - look through protocols.
179 const ObjCList<ObjCProtocolDecl> &Protocols =
180 ClassDecl->getReferencedProtocols();
181 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
182 E = Protocols.end(); I != E; ++I)
183 if ((MethodDecl = (*I)->lookupInstanceMethod(Sel)))
186 // Didn't find one yet - now look through categories.
187 ObjCCategoryDecl *CatDecl = ClassDecl->getCategoryList();
189 if ((MethodDecl = CatDecl->getInstanceMethod(Sel)))
192 // Didn't find one yet - look through protocols.
193 const ObjCList<ObjCProtocolDecl> &Protocols =
194 CatDecl->getReferencedProtocols();
195 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
196 E = Protocols.end(); I != E; ++I)
197 if ((MethodDecl = (*I)->lookupInstanceMethod(Sel)))
199 CatDecl = CatDecl->getNextClassCategory();
201 ClassDecl = ClassDecl->getSuperClass();
206 // lookupClassMethod - This method returns a class method by looking in the
207 // class, its categories, and its super classes (using a linear search).
208 ObjCMethodDecl *ObjCInterfaceDecl::lookupClassMethod(Selector Sel) {
209 ObjCInterfaceDecl* ClassDecl = this;
210 ObjCMethodDecl *MethodDecl = 0;
212 while (ClassDecl != NULL) {
213 if ((MethodDecl = ClassDecl->getClassMethod(Sel)))
216 // Didn't find one yet - look through protocols.
217 for (ObjCInterfaceDecl::protocol_iterator I = ClassDecl->protocol_begin(),
218 E = ClassDecl->protocol_end(); I != E; ++I)
219 if ((MethodDecl = (*I)->lookupClassMethod(Sel)))
222 // Didn't find one yet - now look through categories.
223 ObjCCategoryDecl *CatDecl = ClassDecl->getCategoryList();
225 if ((MethodDecl = CatDecl->getClassMethod(Sel)))
228 // Didn't find one yet - look through protocols.
229 const ObjCList<ObjCProtocolDecl> &Protocols =
230 CatDecl->getReferencedProtocols();
231 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
232 E = Protocols.end(); I != E; ++I)
233 if ((MethodDecl = (*I)->lookupClassMethod(Sel)))
235 CatDecl = CatDecl->getNextClassCategory();
237 ClassDecl = ClassDecl->getSuperClass();
244 //===----------------------------------------------------------------------===//
246 //===----------------------------------------------------------------------===//
248 ObjCMethodDecl *ObjCMethodDecl::Create(ASTContext &C,
249 SourceLocation beginLoc,
250 SourceLocation endLoc,
251 Selector SelInfo, QualType T,
252 DeclContext *contextDecl,
256 ImplementationControl impControl) {
257 return new (C) ObjCMethodDecl(beginLoc, endLoc,
258 SelInfo, T, contextDecl,
260 isVariadic, isSynthesized, impControl);
263 void ObjCMethodDecl::Destroy(ASTContext &C) {
264 if (Body) Body->Destroy(C);
265 if (SelfDecl) SelfDecl->Destroy(C);
267 for (param_iterator I=param_begin(), E=param_end(); I!=E; ++I)
268 if (*I) (*I)->Destroy(C);
270 ParamInfo.Destroy(C);
275 void ObjCMethodDecl::createImplicitParams(ASTContext &Context,
276 const ObjCInterfaceDecl *OID) {
278 if (isInstanceMethod()) {
279 // There may be no interface context due to error in declaration
280 // of the interface (which has been reported). Recover gracefully.
282 selfTy = Context.getObjCInterfaceType(OID);
283 selfTy = Context.getPointerType(selfTy);
285 selfTy = Context.getObjCIdType();
287 } else // we have a factory method.
288 selfTy = Context.getObjCClassType();
290 setSelfDecl(ImplicitParamDecl::Create(Context, this, SourceLocation(),
291 &Context.Idents.get("self"), selfTy));
293 setCmdDecl(ImplicitParamDecl::Create(Context, this, SourceLocation(),
294 &Context.Idents.get("_cmd"),
295 Context.getObjCSelType()));
300 /// getSynthesizedMethodSize - Compute size of synthesized method name
301 /// as done be the rewrite.
303 unsigned ObjCMethodDecl::getSynthesizedMethodSize() const {
304 // syntesized method name is a concatenation of -/+[class-name selector]
305 // Get length of this name.
306 unsigned length = 3; // _I_ or _C_
307 length += getClassInterface()->getNameAsString().size()+1; // extra for _
308 if (const ObjCCategoryImplDecl *CID =
309 dyn_cast<ObjCCategoryImplDecl>(getDeclContext()))
310 length += CID->getNameAsString().size()+1;
311 length += getSelector().getAsString().size(); // selector name
315 ObjCInterfaceDecl *ObjCMethodDecl::getClassInterface() {
316 if (ObjCInterfaceDecl *ID = dyn_cast<ObjCInterfaceDecl>(getDeclContext()))
318 if (ObjCCategoryDecl *CD = dyn_cast<ObjCCategoryDecl>(getDeclContext()))
319 return CD->getClassInterface();
320 if (ObjCImplementationDecl *IMD =
321 dyn_cast<ObjCImplementationDecl>(getDeclContext()))
322 return IMD->getClassInterface();
323 if (ObjCCategoryImplDecl *CID =
324 dyn_cast<ObjCCategoryImplDecl>(getDeclContext()))
325 return CID->getClassInterface();
326 assert(false && "unknown method context");
330 //===----------------------------------------------------------------------===//
332 //===----------------------------------------------------------------------===//
334 ObjCInterfaceDecl *ObjCInterfaceDecl::Create(ASTContext &C,
336 SourceLocation atLoc,
338 SourceLocation ClassLoc,
339 bool ForwardDecl, bool isInternal){
340 return new (C) ObjCInterfaceDecl(DC, atLoc, Id, ClassLoc, ForwardDecl,
345 ObjCInterfaceDecl(DeclContext *DC, SourceLocation atLoc, IdentifierInfo *Id,
346 SourceLocation CLoc, bool FD, bool isInternal)
347 : ObjCContainerDecl(ObjCInterface, DC, atLoc, Id),
348 TypeForDecl(0), SuperClass(0),
349 CategoryList(0), ForwardDecl(FD), InternalInterface(isInternal),
353 void ObjCInterfaceDecl::Destroy(ASTContext &C) {
354 for (ivar_iterator I = ivar_begin(), E = ivar_end(); I != E; ++I)
355 if (*I) (*I)->Destroy(C);
358 // FIXME: CategoryList?
360 // FIXME: Because there is no clear ownership
361 // role between ObjCInterfaceDecls and the ObjCPropertyDecls that they
362 // reference, we destroy ObjCPropertyDecls in ~TranslationUnit.
367 /// FindCategoryDeclaration - Finds category declaration in the list of
368 /// categories for this class and returns it. Name of the category is passed
369 /// in 'CategoryId'. If category not found, return 0;
372 ObjCInterfaceDecl::FindCategoryDeclaration(IdentifierInfo *CategoryId) const {
373 for (ObjCCategoryDecl *Category = getCategoryList();
374 Category; Category = Category->getNextClassCategory())
375 if (Category->getIdentifier() == CategoryId)
380 //===----------------------------------------------------------------------===//
382 //===----------------------------------------------------------------------===//
384 ObjCIvarDecl *ObjCIvarDecl::Create(ASTContext &C, DeclContext *DC,
385 SourceLocation L, IdentifierInfo *Id,
386 QualType T, AccessControl ac, Expr *BW) {
387 return new (C) ObjCIvarDecl(DC, L, Id, T, ac, BW);
392 //===----------------------------------------------------------------------===//
393 // ObjCAtDefsFieldDecl
394 //===----------------------------------------------------------------------===//
397 *ObjCAtDefsFieldDecl::Create(ASTContext &C, DeclContext *DC, SourceLocation L,
398 IdentifierInfo *Id, QualType T, Expr *BW) {
399 return new (C) ObjCAtDefsFieldDecl(DC, L, Id, T, BW);
402 void ObjCAtDefsFieldDecl::Destroy(ASTContext& C) {
403 this->~ObjCAtDefsFieldDecl();
404 C.Deallocate((void *)this);
407 //===----------------------------------------------------------------------===//
409 //===----------------------------------------------------------------------===//
411 ObjCProtocolDecl *ObjCProtocolDecl::Create(ASTContext &C, DeclContext *DC,
413 IdentifierInfo *Id) {
414 return new (C) ObjCProtocolDecl(DC, L, Id);
417 void ObjCProtocolDecl::Destroy(ASTContext &C) {
418 ReferencedProtocols.Destroy(C);
419 ObjCContainerDecl::Destroy(C);
422 ObjCProtocolDecl *ObjCProtocolDecl::lookupProtocolNamed(IdentifierInfo *Name) {
423 ObjCProtocolDecl *PDecl = this;
425 if (Name == getIdentifier())
428 for (protocol_iterator I = protocol_begin(), E = protocol_end(); I != E; ++I)
429 if ((PDecl = (*I)->lookupProtocolNamed(Name)))
435 // lookupInstanceMethod - Lookup a instance method in the protocol and protocols
437 ObjCMethodDecl *ObjCProtocolDecl::lookupInstanceMethod(Selector Sel) {
438 ObjCMethodDecl *MethodDecl = NULL;
440 if ((MethodDecl = getInstanceMethod(Sel)))
443 for (protocol_iterator I = protocol_begin(), E = protocol_end(); I != E; ++I)
444 if ((MethodDecl = (*I)->lookupInstanceMethod(Sel)))
449 // lookupInstanceMethod - Lookup a class method in the protocol and protocols
451 ObjCMethodDecl *ObjCProtocolDecl::lookupClassMethod(Selector Sel) {
452 ObjCMethodDecl *MethodDecl = NULL;
454 if ((MethodDecl = getClassMethod(Sel)))
457 for (protocol_iterator I = protocol_begin(), E = protocol_end(); I != E; ++I)
458 if ((MethodDecl = (*I)->lookupClassMethod(Sel)))
463 //===----------------------------------------------------------------------===//
465 //===----------------------------------------------------------------------===//
467 ObjCClassDecl::ObjCClassDecl(DeclContext *DC, SourceLocation L,
468 ObjCInterfaceDecl *const *Elts, unsigned nElts,
470 : Decl(ObjCClass, DC, L) {
471 ForwardDecls.set(Elts, nElts, C);
475 ObjCClassDecl *ObjCClassDecl::Create(ASTContext &C, DeclContext *DC,
477 ObjCInterfaceDecl *const *Elts,
479 return new (C) ObjCClassDecl(DC, L, Elts, nElts, C);
482 void ObjCClassDecl::Destroy(ASTContext &C) {
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.
492 ForwardDecls.Destroy(C);
496 //===----------------------------------------------------------------------===//
497 // ObjCForwardProtocolDecl
498 //===----------------------------------------------------------------------===//
500 ObjCForwardProtocolDecl::
501 ObjCForwardProtocolDecl(DeclContext *DC, SourceLocation L,
502 ObjCProtocolDecl *const *Elts, unsigned nElts,
504 : Decl(ObjCForwardProtocol, DC, L) {
505 ReferencedProtocols.set(Elts, nElts, C);
509 ObjCForwardProtocolDecl *
510 ObjCForwardProtocolDecl::Create(ASTContext &C, DeclContext *DC,
512 ObjCProtocolDecl *const *Elts,
514 return new (C) ObjCForwardProtocolDecl(DC, L, Elts, NumElts, C);
517 void ObjCForwardProtocolDecl::Destroy(ASTContext &C) {
518 ReferencedProtocols.Destroy(C);
522 //===----------------------------------------------------------------------===//
524 //===----------------------------------------------------------------------===//
526 ObjCCategoryDecl *ObjCCategoryDecl::Create(ASTContext &C, DeclContext *DC,
528 IdentifierInfo *Id) {
529 return new (C) ObjCCategoryDecl(DC, L, Id);
532 //===----------------------------------------------------------------------===//
533 // ObjCCategoryImplDecl
534 //===----------------------------------------------------------------------===//
536 ObjCCategoryImplDecl *
537 ObjCCategoryImplDecl::Create(ASTContext &C, DeclContext *DC,
538 SourceLocation L,IdentifierInfo *Id,
539 ObjCInterfaceDecl *ClassInterface) {
540 return new (C) ObjCCategoryImplDecl(DC, L, Id, ClassInterface);
544 void ObjCImplDecl::addPropertyImplementation(ObjCPropertyImplDecl *property) {
545 // FIXME: The context should be correct before we get here.
546 property->setLexicalDeclContext(this);
550 /// FindPropertyImplIvarDecl - This method lookup the ivar in the list of
551 /// properties implemented in this category @implementation block and returns
552 /// the implemented property that uses it.
554 ObjCPropertyImplDecl *ObjCImplDecl::
555 FindPropertyImplIvarDecl(IdentifierInfo *ivarId) const {
556 for (propimpl_iterator i = propimpl_begin(), e = propimpl_end(); i != e; ++i){
557 ObjCPropertyImplDecl *PID = *i;
558 if (PID->getPropertyIvarDecl() &&
559 PID->getPropertyIvarDecl()->getIdentifier() == ivarId)
565 /// FindPropertyImplDecl - This method looks up a previous ObjCPropertyImplDecl
566 /// added to the list of those properties @synthesized/@dynamic in this
567 /// category @implementation block.
569 ObjCPropertyImplDecl *ObjCImplDecl::
570 FindPropertyImplDecl(IdentifierInfo *Id) const {
571 for (propimpl_iterator i = propimpl_begin(), e = propimpl_end(); i != e; ++i){
572 ObjCPropertyImplDecl *PID = *i;
573 if (PID->getPropertyDecl()->getIdentifier() == Id)
579 // getInstanceMethod - This method returns an instance method by looking in
580 // the class implementation. Unlike interfaces, we don't look outside the
582 ObjCMethodDecl *ObjCImplDecl::getInstanceMethod(Selector Sel) const {
583 // Since instance & class methods can have the same name, the loop below
584 // ensures we get the correct method.
586 // @interface Whatever
587 // - (int) class_method;
588 // + (float) class_method;
591 lookup_const_iterator Meth, MethEnd;
592 for (llvm::tie(Meth, MethEnd) = lookup(Sel);
593 Meth != MethEnd; ++Meth) {
594 ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(*Meth);
595 if (MD && MD->isInstanceMethod())
601 // getClassMethod - This method returns an instance method by looking in
602 // the class implementation. Unlike interfaces, we don't look outside the
604 ObjCMethodDecl *ObjCImplDecl::getClassMethod(Selector Sel) const {
605 // Since instance & class methods can have the same name, the loop below
606 // ensures we get the correct method.
608 // @interface Whatever
609 // - (int) class_method;
610 // + (float) class_method;
613 lookup_const_iterator Meth, MethEnd;
614 for (llvm::tie(Meth, MethEnd) = lookup(Sel);
615 Meth != MethEnd; ++Meth) {
616 ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(*Meth);
617 if (MD && MD->isClassMethod())
623 //===----------------------------------------------------------------------===//
624 // ObjCImplementationDecl
625 //===----------------------------------------------------------------------===//
627 ObjCImplementationDecl *
628 ObjCImplementationDecl::Create(ASTContext &C, DeclContext *DC,
630 ObjCInterfaceDecl *ClassInterface,
631 ObjCInterfaceDecl *SuperDecl) {
632 return new (C) ObjCImplementationDecl(DC, L, ClassInterface, SuperDecl);
635 //===----------------------------------------------------------------------===//
636 // ObjCCompatibleAliasDecl
637 //===----------------------------------------------------------------------===//
639 ObjCCompatibleAliasDecl *
640 ObjCCompatibleAliasDecl::Create(ASTContext &C, DeclContext *DC,
643 ObjCInterfaceDecl* AliasedClass) {
644 return new (C) ObjCCompatibleAliasDecl(DC, L, Id, AliasedClass);
647 //===----------------------------------------------------------------------===//
649 //===----------------------------------------------------------------------===//
651 ObjCPropertyDecl *ObjCPropertyDecl::Create(ASTContext &C, DeclContext *DC,
655 PropertyControl propControl) {
656 return new (C) ObjCPropertyDecl(DC, L, Id, T);
660 //===----------------------------------------------------------------------===//
661 // ObjCPropertyImplDecl
662 //===----------------------------------------------------------------------===//
664 ObjCPropertyImplDecl *ObjCPropertyImplDecl::Create(ASTContext &C,
666 SourceLocation atLoc,
668 ObjCPropertyDecl *property,
670 ObjCIvarDecl *ivar) {
671 return new (C) ObjCPropertyImplDecl(DC, atLoc, L, property, PK, ivar);