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);
40 void ObjCProtocolList::set(ObjCProtocolDecl* const* InList, unsigned Elts,
41 const SourceLocation *Locs, ASTContext &Ctx) {
45 Locations = new (Ctx) SourceLocation[Elts];
46 memcpy(Locations, Locs, sizeof(SourceLocation) * Elts);
47 set(InList, Elts, Ctx);
50 void ObjCProtocolList::Destroy(ASTContext &Ctx) {
51 Ctx.Deallocate(Locations);
53 ObjCList<ObjCProtocolDecl>::Destroy(Ctx);
56 //===----------------------------------------------------------------------===//
58 //===----------------------------------------------------------------------===//
60 /// getIvarDecl - This method looks up an ivar in this ContextDecl.
63 ObjCContainerDecl::getIvarDecl(IdentifierInfo *Id) const {
64 lookup_const_iterator Ivar, IvarEnd;
65 for (llvm::tie(Ivar, IvarEnd) = lookup(Id); Ivar != IvarEnd; ++Ivar) {
66 if (ObjCIvarDecl *ivar = dyn_cast<ObjCIvarDecl>(*Ivar))
72 // Get the local instance/class method declared in this interface.
74 ObjCContainerDecl::getMethod(Selector Sel, bool isInstance) const {
75 // Since instance & class methods can have the same name, the loop below
76 // ensures we get the correct method.
78 // @interface Whatever
79 // - (int) class_method;
80 // + (float) class_method;
83 lookup_const_iterator Meth, MethEnd;
84 for (llvm::tie(Meth, MethEnd) = lookup(Sel); Meth != MethEnd; ++Meth) {
85 ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(*Meth);
86 if (MD && MD->isInstanceMethod() == isInstance)
93 ObjCPropertyDecl::findPropertyDecl(const DeclContext *DC,
94 IdentifierInfo *propertyID) {
96 DeclContext::lookup_const_iterator I, E;
97 llvm::tie(I, E) = DC->lookup(propertyID);
99 if (ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(*I))
105 /// FindPropertyDeclaration - Finds declaration of the property given its name
106 /// in 'PropertyId' and returns it. It returns 0, if not found.
108 ObjCContainerDecl::FindPropertyDeclaration(IdentifierInfo *PropertyId) const {
110 if (ObjCPropertyDecl *PD =
111 ObjCPropertyDecl::findPropertyDecl(cast<DeclContext>(this), PropertyId))
117 case Decl::ObjCProtocol: {
118 const ObjCProtocolDecl *PID = cast<ObjCProtocolDecl>(this);
119 for (ObjCProtocolDecl::protocol_iterator I = PID->protocol_begin(),
120 E = PID->protocol_end(); I != E; ++I)
121 if (ObjCPropertyDecl *P = (*I)->FindPropertyDeclaration(PropertyId))
125 case Decl::ObjCInterface: {
126 const ObjCInterfaceDecl *OID = cast<ObjCInterfaceDecl>(this);
127 // Look through categories.
128 for (ObjCCategoryDecl *Cat = OID->getCategoryList();
129 Cat; Cat = Cat->getNextClassCategory())
130 if (!Cat->IsClassExtension())
131 if (ObjCPropertyDecl *P = Cat->FindPropertyDeclaration(PropertyId))
134 // Look through protocols.
135 for (ObjCInterfaceDecl::protocol_iterator
136 I = OID->protocol_begin(), E = OID->protocol_end(); I != E; ++I)
137 if (ObjCPropertyDecl *P = (*I)->FindPropertyDeclaration(PropertyId))
140 // Finally, check the super class.
141 if (const ObjCInterfaceDecl *superClass = OID->getSuperClass())
142 return superClass->FindPropertyDeclaration(PropertyId);
145 case Decl::ObjCCategory: {
146 const ObjCCategoryDecl *OCD = cast<ObjCCategoryDecl>(this);
147 // Look through protocols.
148 if (!OCD->IsClassExtension())
149 for (ObjCCategoryDecl::protocol_iterator
150 I = OCD->protocol_begin(), E = OCD->protocol_end(); I != E; ++I)
151 if (ObjCPropertyDecl *P = (*I)->FindPropertyDeclaration(PropertyId))
160 /// FindPropertyVisibleInPrimaryClass - Finds declaration of the property
161 /// with name 'PropertyId' in the primary class; including those in protocols
162 /// (direct or indirect) used by the primary class.
165 ObjCInterfaceDecl::FindPropertyVisibleInPrimaryClass(
166 IdentifierInfo *PropertyId) const {
167 if (ObjCPropertyDecl *PD =
168 ObjCPropertyDecl::findPropertyDecl(cast<DeclContext>(this), PropertyId))
171 // Look through protocols.
172 for (ObjCInterfaceDecl::protocol_iterator
173 I = protocol_begin(), E = protocol_end(); I != E; ++I)
174 if (ObjCPropertyDecl *P = (*I)->FindPropertyDeclaration(PropertyId))
180 void ObjCInterfaceDecl::mergeClassExtensionProtocolList(
181 ObjCProtocolDecl *const* ExtList, unsigned ExtNum,
182 const SourceLocation *Locs,
185 if (ReferencedProtocols.empty()) {
186 ReferencedProtocols.set(ExtList, ExtNum, Locs, C);
189 // Check for duplicate protocol in class's protocol list.
190 // This is (O)2. But it is extremely rare and number of protocols in
191 // class or its extension are very few.
192 llvm::SmallVector<ObjCProtocolDecl*, 8> ProtocolRefs;
193 llvm::SmallVector<SourceLocation, 8> ProtocolLocs;
194 for (unsigned i = 0; i < ExtNum; i++) {
195 bool protocolExists = false;
196 ObjCProtocolDecl *ProtoInExtension = ExtList[i];
197 for (protocol_iterator p = protocol_begin(), e = protocol_end();
199 ObjCProtocolDecl *Proto = (*p);
200 if (C.ProtocolCompatibleWithProtocol(ProtoInExtension, Proto)) {
201 protocolExists = true;
205 // Do we want to warn on a protocol in extension class which
206 // already exist in the class? Probably not.
207 if (!protocolExists) {
208 ProtocolRefs.push_back(ProtoInExtension);
209 ProtocolLocs.push_back(Locs[i]);
212 if (ProtocolRefs.empty())
214 // Merge ProtocolRefs into class's protocol list;
215 protocol_loc_iterator pl = protocol_loc_begin();
216 for (protocol_iterator p = protocol_begin(), e = protocol_end();
218 ProtocolRefs.push_back(*p);
219 ProtocolLocs.push_back(*pl);
221 ReferencedProtocols.Destroy(C);
222 unsigned NumProtoRefs = ProtocolRefs.size();
223 setProtocolList(ProtocolRefs.data(), NumProtoRefs, ProtocolLocs.data(), C);
226 /// getFirstClassExtension - Find first class extension of the given class.
227 ObjCCategoryDecl* ObjCInterfaceDecl::getFirstClassExtension() const {
228 for (ObjCCategoryDecl *CDecl = getCategoryList(); CDecl;
229 CDecl = CDecl->getNextClassCategory())
230 if (CDecl->IsClassExtension())
235 /// getNextClassCategory - Find next class extension in list of categories.
236 const ObjCCategoryDecl* ObjCCategoryDecl::getNextClassExtension() const {
237 for (const ObjCCategoryDecl *CDecl = getNextClassCategory(); CDecl;
238 CDecl = CDecl->getNextClassCategory())
239 if (CDecl->IsClassExtension())
244 ObjCIvarDecl *ObjCInterfaceDecl::lookupInstanceVariable(IdentifierInfo *ID,
245 ObjCInterfaceDecl *&clsDeclared) {
246 ObjCInterfaceDecl* ClassDecl = this;
247 while (ClassDecl != NULL) {
248 if (ObjCIvarDecl *I = ClassDecl->getIvarDecl(ID)) {
249 clsDeclared = ClassDecl;
252 for (const ObjCCategoryDecl *CDecl = ClassDecl->getFirstClassExtension();
253 CDecl; CDecl = CDecl->getNextClassExtension()) {
254 if (ObjCIvarDecl *I = CDecl->getIvarDecl(ID)) {
255 clsDeclared = ClassDecl;
260 ClassDecl = ClassDecl->getSuperClass();
265 /// lookupInheritedClass - This method returns ObjCInterfaceDecl * of the super
266 /// class whose name is passed as argument. If it is not one of the super classes
267 /// the it returns NULL.
268 ObjCInterfaceDecl *ObjCInterfaceDecl::lookupInheritedClass(
269 const IdentifierInfo*ICName) {
270 ObjCInterfaceDecl* ClassDecl = this;
271 while (ClassDecl != NULL) {
272 if (ClassDecl->getIdentifier() == ICName)
274 ClassDecl = ClassDecl->getSuperClass();
279 /// lookupMethod - This method returns an instance/class method by looking in
280 /// the class, its categories, and its super classes (using a linear search).
281 ObjCMethodDecl *ObjCInterfaceDecl::lookupMethod(Selector Sel,
282 bool isInstance) const {
283 const ObjCInterfaceDecl* ClassDecl = this;
284 ObjCMethodDecl *MethodDecl = 0;
286 while (ClassDecl != NULL) {
287 if ((MethodDecl = ClassDecl->getMethod(Sel, isInstance)))
290 // Didn't find one yet - look through protocols.
291 const ObjCList<ObjCProtocolDecl> &Protocols =
292 ClassDecl->getReferencedProtocols();
293 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
294 E = Protocols.end(); I != E; ++I)
295 if ((MethodDecl = (*I)->lookupMethod(Sel, isInstance)))
298 // Didn't find one yet - now look through categories.
299 ObjCCategoryDecl *CatDecl = ClassDecl->getCategoryList();
301 if ((MethodDecl = CatDecl->getMethod(Sel, isInstance)))
304 // Didn't find one yet - look through protocols.
305 const ObjCList<ObjCProtocolDecl> &Protocols =
306 CatDecl->getReferencedProtocols();
307 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
308 E = Protocols.end(); I != E; ++I)
309 if ((MethodDecl = (*I)->lookupMethod(Sel, isInstance)))
311 CatDecl = CatDecl->getNextClassCategory();
313 ClassDecl = ClassDecl->getSuperClass();
318 ObjCMethodDecl *ObjCInterfaceDecl::lookupPrivateInstanceMethod(
319 const Selector &Sel) {
320 ObjCMethodDecl *Method = 0;
321 if (ObjCImplementationDecl *ImpDecl = getImplementation())
322 Method = ImpDecl->getInstanceMethod(Sel);
324 if (!Method && getSuperClass())
325 return getSuperClass()->lookupPrivateInstanceMethod(Sel);
329 //===----------------------------------------------------------------------===//
331 //===----------------------------------------------------------------------===//
333 ObjCMethodDecl *ObjCMethodDecl::Create(ASTContext &C,
334 SourceLocation beginLoc,
335 SourceLocation endLoc,
336 Selector SelInfo, QualType T,
337 TypeSourceInfo *ResultTInfo,
338 DeclContext *contextDecl,
342 ImplementationControl impControl,
343 unsigned numSelectorArgs) {
344 return new (C) ObjCMethodDecl(beginLoc, endLoc,
345 SelInfo, T, ResultTInfo, contextDecl,
347 isVariadic, isSynthesized, impControl,
351 void ObjCMethodDecl::Destroy(ASTContext &C) {
352 if (Body) Body->Destroy(C);
353 if (SelfDecl) SelfDecl->Destroy(C);
355 for (param_iterator I=param_begin(), E=param_end(); I!=E; ++I)
356 if (*I) (*I)->Destroy(C);
358 ParamInfo.Destroy(C);
363 /// \brief A definition will return its interface declaration.
364 /// An interface declaration will return its definition.
365 /// Otherwise it will return itself.
366 ObjCMethodDecl *ObjCMethodDecl::getNextRedeclaration() {
367 ASTContext &Ctx = getASTContext();
368 ObjCMethodDecl *Redecl = 0;
369 Decl *CtxD = cast<Decl>(getDeclContext());
371 if (ObjCInterfaceDecl *IFD = dyn_cast<ObjCInterfaceDecl>(CtxD)) {
372 if (ObjCImplementationDecl *ImplD = Ctx.getObjCImplementation(IFD))
373 Redecl = ImplD->getMethod(getSelector(), isInstanceMethod());
375 } else if (ObjCCategoryDecl *CD = dyn_cast<ObjCCategoryDecl>(CtxD)) {
376 if (ObjCCategoryImplDecl *ImplD = Ctx.getObjCImplementation(CD))
377 Redecl = ImplD->getMethod(getSelector(), isInstanceMethod());
379 } else if (ObjCImplementationDecl *ImplD =
380 dyn_cast<ObjCImplementationDecl>(CtxD)) {
381 if (ObjCInterfaceDecl *IFD = ImplD->getClassInterface())
382 Redecl = IFD->getMethod(getSelector(), isInstanceMethod());
384 } else if (ObjCCategoryImplDecl *CImplD =
385 dyn_cast<ObjCCategoryImplDecl>(CtxD)) {
386 if (ObjCCategoryDecl *CatD = CImplD->getCategoryDecl())
387 Redecl = CatD->getMethod(getSelector(), isInstanceMethod());
390 return Redecl ? Redecl : this;
393 ObjCMethodDecl *ObjCMethodDecl::getCanonicalDecl() {
394 Decl *CtxD = cast<Decl>(getDeclContext());
396 if (ObjCImplementationDecl *ImplD = dyn_cast<ObjCImplementationDecl>(CtxD)) {
397 if (ObjCInterfaceDecl *IFD = ImplD->getClassInterface())
398 if (ObjCMethodDecl *MD = IFD->getMethod(getSelector(),
402 } else if (ObjCCategoryImplDecl *CImplD =
403 dyn_cast<ObjCCategoryImplDecl>(CtxD)) {
404 if (ObjCCategoryDecl *CatD = CImplD->getCategoryDecl())
405 if (ObjCMethodDecl *MD = CatD->getMethod(getSelector(),
413 void ObjCMethodDecl::createImplicitParams(ASTContext &Context,
414 const ObjCInterfaceDecl *OID) {
416 if (isInstanceMethod()) {
417 // There may be no interface context due to error in declaration
418 // of the interface (which has been reported). Recover gracefully.
420 selfTy = Context.getObjCInterfaceType(OID);
421 selfTy = Context.getObjCObjectPointerType(selfTy);
423 selfTy = Context.getObjCIdType();
425 } else // we have a factory method.
426 selfTy = Context.getObjCClassType();
428 setSelfDecl(ImplicitParamDecl::Create(Context, this, SourceLocation(),
429 &Context.Idents.get("self"), selfTy));
431 setCmdDecl(ImplicitParamDecl::Create(Context, this, SourceLocation(),
432 &Context.Idents.get("_cmd"),
433 Context.getObjCSelType()));
436 ObjCInterfaceDecl *ObjCMethodDecl::getClassInterface() {
437 if (ObjCInterfaceDecl *ID = dyn_cast<ObjCInterfaceDecl>(getDeclContext()))
439 if (ObjCCategoryDecl *CD = dyn_cast<ObjCCategoryDecl>(getDeclContext()))
440 return CD->getClassInterface();
441 if (ObjCImplDecl *IMD = dyn_cast<ObjCImplDecl>(getDeclContext()))
442 return IMD->getClassInterface();
444 assert(!isa<ObjCProtocolDecl>(getDeclContext()) && "It's a protocol method");
445 assert(false && "unknown method context");
449 //===----------------------------------------------------------------------===//
451 //===----------------------------------------------------------------------===//
453 ObjCInterfaceDecl *ObjCInterfaceDecl::Create(ASTContext &C,
455 SourceLocation atLoc,
457 SourceLocation ClassLoc,
458 bool ForwardDecl, bool isInternal){
459 return new (C) ObjCInterfaceDecl(DC, atLoc, Id, ClassLoc, ForwardDecl,
464 ObjCInterfaceDecl(DeclContext *DC, SourceLocation atLoc, IdentifierInfo *Id,
465 SourceLocation CLoc, bool FD, bool isInternal)
466 : ObjCContainerDecl(ObjCInterface, DC, atLoc, Id),
467 TypeForDecl(0), SuperClass(0),
468 CategoryList(0), ForwardDecl(FD), InternalInterface(isInternal),
472 void ObjCInterfaceDecl::Destroy(ASTContext &C) {
473 for (ivar_iterator I = ivar_begin(), E = ivar_end(); I != E; ++I)
474 if (*I) (*I)->Destroy(C);
476 // FIXME: CategoryList?
478 // FIXME: Because there is no clear ownership
479 // role between ObjCInterfaceDecls and the ObjCPropertyDecls that they
480 // reference, we destroy ObjCPropertyDecls in ~TranslationUnit.
484 ObjCImplementationDecl *ObjCInterfaceDecl::getImplementation() const {
485 return getASTContext().getObjCImplementation(
486 const_cast<ObjCInterfaceDecl*>(this));
489 void ObjCInterfaceDecl::setImplementation(ObjCImplementationDecl *ImplD) {
490 getASTContext().setObjCImplementation(this, ImplD);
494 /// FindCategoryDeclaration - Finds category declaration in the list of
495 /// categories for this class and returns it. Name of the category is passed
496 /// in 'CategoryId'. If category not found, return 0;
499 ObjCInterfaceDecl::FindCategoryDeclaration(IdentifierInfo *CategoryId) const {
500 for (ObjCCategoryDecl *Category = getCategoryList();
501 Category; Category = Category->getNextClassCategory())
502 if (Category->getIdentifier() == CategoryId)
508 ObjCInterfaceDecl::getCategoryInstanceMethod(Selector Sel) const {
509 for (ObjCCategoryDecl *Category = getCategoryList();
510 Category; Category = Category->getNextClassCategory())
511 if (ObjCCategoryImplDecl *Impl = Category->getImplementation())
512 if (ObjCMethodDecl *MD = Impl->getInstanceMethod(Sel))
517 ObjCMethodDecl *ObjCInterfaceDecl::getCategoryClassMethod(Selector Sel) const {
518 for (ObjCCategoryDecl *Category = getCategoryList();
519 Category; Category = Category->getNextClassCategory())
520 if (ObjCCategoryImplDecl *Impl = Category->getImplementation())
521 if (ObjCMethodDecl *MD = Impl->getClassMethod(Sel))
526 /// ClassImplementsProtocol - Checks that 'lProto' protocol
527 /// has been implemented in IDecl class, its super class or categories (if
528 /// lookupCategory is true).
529 bool ObjCInterfaceDecl::ClassImplementsProtocol(ObjCProtocolDecl *lProto,
531 bool RHSIsQualifiedID) {
532 ObjCInterfaceDecl *IDecl = this;
533 // 1st, look up the class.
534 const ObjCList<ObjCProtocolDecl> &Protocols =
535 IDecl->getReferencedProtocols();
537 for (ObjCList<ObjCProtocolDecl>::iterator PI = Protocols.begin(),
538 E = Protocols.end(); PI != E; ++PI) {
539 if (getASTContext().ProtocolCompatibleWithProtocol(lProto, *PI))
541 // This is dubious and is added to be compatible with gcc. In gcc, it is
542 // also allowed assigning a protocol-qualified 'id' type to a LHS object
543 // when protocol in qualified LHS is in list of protocols in the rhs 'id'
544 // object. This IMO, should be a bug.
545 // FIXME: Treat this as an extension, and flag this as an error when GCC
546 // extensions are not enabled.
547 if (RHSIsQualifiedID &&
548 getASTContext().ProtocolCompatibleWithProtocol(*PI, lProto))
552 // 2nd, look up the category.
554 for (ObjCCategoryDecl *CDecl = IDecl->getCategoryList(); CDecl;
555 CDecl = CDecl->getNextClassCategory()) {
556 for (ObjCCategoryDecl::protocol_iterator PI = CDecl->protocol_begin(),
557 E = CDecl->protocol_end(); PI != E; ++PI)
558 if (getASTContext().ProtocolCompatibleWithProtocol(lProto, *PI))
562 // 3rd, look up the super class(s)
563 if (IDecl->getSuperClass())
565 IDecl->getSuperClass()->ClassImplementsProtocol(lProto, lookupCategory,
571 //===----------------------------------------------------------------------===//
573 //===----------------------------------------------------------------------===//
575 ObjCIvarDecl *ObjCIvarDecl::Create(ASTContext &C, ObjCContainerDecl *DC,
576 SourceLocation L, IdentifierInfo *Id,
577 QualType T, TypeSourceInfo *TInfo,
578 AccessControl ac, Expr *BW) {
580 // Ivar's can only appear in interfaces, implementations (via synthesized
581 // properties), and class extensions (via direct declaration, or synthesized
584 // FIXME: This should really be asserting this:
585 // (isa<ObjCCategoryDecl>(DC) &&
586 // cast<ObjCCategoryDecl>(DC)->IsClassExtension()))
587 // but unfortunately we sometimes place ivars into non-class extension
588 // categories on error. This breaks an AST invariant, and should not be
590 assert((isa<ObjCInterfaceDecl>(DC) || isa<ObjCImplementationDecl>(DC) ||
591 isa<ObjCCategoryDecl>(DC)) &&
592 "Invalid ivar decl context!");
595 return new (C) ObjCIvarDecl(DC, L, Id, T, TInfo, ac, BW);
598 const ObjCInterfaceDecl *ObjCIvarDecl::getContainingInterface() const {
599 const ObjCContainerDecl *DC = cast<ObjCContainerDecl>(getDeclContext());
601 switch (DC->getKind()) {
603 case ObjCCategoryImpl:
605 assert(0 && "invalid ivar container!");
608 // Ivars can only appear in class extension categories.
610 const ObjCCategoryDecl *CD = cast<ObjCCategoryDecl>(DC);
611 assert(CD->IsClassExtension() && "invalid container for ivar!");
612 return CD->getClassInterface();
615 case ObjCImplementation:
616 return cast<ObjCImplementationDecl>(DC)->getClassInterface();
619 return cast<ObjCInterfaceDecl>(DC);
623 //===----------------------------------------------------------------------===//
624 // ObjCAtDefsFieldDecl
625 //===----------------------------------------------------------------------===//
628 *ObjCAtDefsFieldDecl::Create(ASTContext &C, DeclContext *DC, SourceLocation L,
629 IdentifierInfo *Id, QualType T, Expr *BW) {
630 return new (C) ObjCAtDefsFieldDecl(DC, L, Id, T, BW);
633 void ObjCAtDefsFieldDecl::Destroy(ASTContext& C) {
634 this->~ObjCAtDefsFieldDecl();
635 C.Deallocate((void *)this);
638 //===----------------------------------------------------------------------===//
640 //===----------------------------------------------------------------------===//
642 ObjCProtocolDecl *ObjCProtocolDecl::Create(ASTContext &C, DeclContext *DC,
644 IdentifierInfo *Id) {
645 return new (C) ObjCProtocolDecl(DC, L, Id);
648 void ObjCProtocolDecl::Destroy(ASTContext &C) {
649 ReferencedProtocols.Destroy(C);
650 ObjCContainerDecl::Destroy(C);
653 ObjCProtocolDecl *ObjCProtocolDecl::lookupProtocolNamed(IdentifierInfo *Name) {
654 ObjCProtocolDecl *PDecl = this;
656 if (Name == getIdentifier())
659 for (protocol_iterator I = protocol_begin(), E = protocol_end(); I != E; ++I)
660 if ((PDecl = (*I)->lookupProtocolNamed(Name)))
666 // lookupMethod - Lookup a instance/class method in the protocol and protocols
668 ObjCMethodDecl *ObjCProtocolDecl::lookupMethod(Selector Sel,
669 bool isInstance) const {
670 ObjCMethodDecl *MethodDecl = NULL;
672 if ((MethodDecl = getMethod(Sel, isInstance)))
675 for (protocol_iterator I = protocol_begin(), E = protocol_end(); I != E; ++I)
676 if ((MethodDecl = (*I)->lookupMethod(Sel, isInstance)))
681 //===----------------------------------------------------------------------===//
683 //===----------------------------------------------------------------------===//
685 ObjCClassDecl::ObjCClassDecl(DeclContext *DC, SourceLocation L,
686 ObjCInterfaceDecl *const *Elts,
687 const SourceLocation *Locs,
690 : Decl(ObjCClass, DC, L) {
691 setClassList(C, Elts, Locs, nElts);
694 void ObjCClassDecl::setClassList(ASTContext &C, ObjCInterfaceDecl*const*List,
695 const SourceLocation *Locs, unsigned Num) {
696 ForwardDecls = (ObjCClassRef*) C.Allocate(sizeof(ObjCClassRef)*Num,
697 llvm::alignof<ObjCClassRef>());
698 for (unsigned i = 0; i < Num; ++i)
699 new (&ForwardDecls[i]) ObjCClassRef(List[i], Locs[i]);
704 ObjCClassDecl *ObjCClassDecl::Create(ASTContext &C, DeclContext *DC,
706 ObjCInterfaceDecl *const *Elts,
707 const SourceLocation *Locs,
709 return new (C) ObjCClassDecl(DC, L, Elts, Locs, nElts, C);
712 void ObjCClassDecl::Destroy(ASTContext &C) {
713 // ObjCInterfaceDecls registered with a DeclContext will get destroyed
714 // when the DeclContext is destroyed. For those created only by a forward
715 // declaration, the first @class that created the ObjCInterfaceDecl gets
717 // FIXME: Note that this ownership role is very brittle; a better
718 // polict is surely need in the future.
719 for (iterator I = begin(), E = end(); I !=E ; ++I) {
720 ObjCInterfaceDecl *ID = I->getInterface();
721 if (ID->isForwardDecl() && ID->getLocStart() == getLocStart())
725 C.Deallocate(ForwardDecls);
729 SourceRange ObjCClassDecl::getSourceRange() const {
730 // FIXME: We should include the semicolon
732 return SourceRange(getLocation(), ForwardDecls[NumDecls-1].getLocation());
735 //===----------------------------------------------------------------------===//
736 // ObjCForwardProtocolDecl
737 //===----------------------------------------------------------------------===//
739 ObjCForwardProtocolDecl::
740 ObjCForwardProtocolDecl(DeclContext *DC, SourceLocation L,
741 ObjCProtocolDecl *const *Elts, unsigned nElts,
742 const SourceLocation *Locs, ASTContext &C)
743 : Decl(ObjCForwardProtocol, DC, L) {
744 ReferencedProtocols.set(Elts, nElts, Locs, C);
748 ObjCForwardProtocolDecl *
749 ObjCForwardProtocolDecl::Create(ASTContext &C, DeclContext *DC,
751 ObjCProtocolDecl *const *Elts,
753 const SourceLocation *Locs) {
754 return new (C) ObjCForwardProtocolDecl(DC, L, Elts, NumElts, Locs, C);
757 void ObjCForwardProtocolDecl::Destroy(ASTContext &C) {
758 ReferencedProtocols.Destroy(C);
762 //===----------------------------------------------------------------------===//
764 //===----------------------------------------------------------------------===//
766 ObjCCategoryDecl *ObjCCategoryDecl::Create(ASTContext &C, DeclContext *DC,
767 SourceLocation AtLoc,
768 SourceLocation ClassNameLoc,
769 SourceLocation CategoryNameLoc,
770 IdentifierInfo *Id) {
771 return new (C) ObjCCategoryDecl(DC, AtLoc, ClassNameLoc, CategoryNameLoc, Id);
774 ObjCCategoryImplDecl *ObjCCategoryDecl::getImplementation() const {
775 return getASTContext().getObjCImplementation(
776 const_cast<ObjCCategoryDecl*>(this));
779 void ObjCCategoryDecl::setImplementation(ObjCCategoryImplDecl *ImplD) {
780 getASTContext().setObjCImplementation(this, ImplD);
784 //===----------------------------------------------------------------------===//
785 // ObjCCategoryImplDecl
786 //===----------------------------------------------------------------------===//
788 ObjCCategoryImplDecl *
789 ObjCCategoryImplDecl::Create(ASTContext &C, DeclContext *DC,
790 SourceLocation L,IdentifierInfo *Id,
791 ObjCInterfaceDecl *ClassInterface) {
792 return new (C) ObjCCategoryImplDecl(DC, L, Id, ClassInterface);
795 ObjCCategoryDecl *ObjCCategoryImplDecl::getCategoryDecl() const {
796 // The class interface might be NULL if we are working with invalid code.
797 if (const ObjCInterfaceDecl *ID = getClassInterface())
798 return ID->FindCategoryDeclaration(getIdentifier());
803 void ObjCImplDecl::addPropertyImplementation(ObjCPropertyImplDecl *property) {
804 // FIXME: The context should be correct before we get here.
805 property->setLexicalDeclContext(this);
809 void ObjCImplDecl::setClassInterface(ObjCInterfaceDecl *IFace) {
810 ASTContext &Ctx = getASTContext();
812 if (ObjCImplementationDecl *ImplD
813 = dyn_cast_or_null<ObjCImplementationDecl>(this)) {
815 Ctx.setObjCImplementation(IFace, ImplD);
817 } else if (ObjCCategoryImplDecl *ImplD =
818 dyn_cast_or_null<ObjCCategoryImplDecl>(this)) {
819 if (ObjCCategoryDecl *CD = IFace->FindCategoryDeclaration(getIdentifier()))
820 Ctx.setObjCImplementation(CD, ImplD);
823 ClassInterface = IFace;
826 /// FindPropertyImplIvarDecl - This method lookup the ivar in the list of
827 /// properties implemented in this category @implementation block and returns
828 /// the implemented property that uses it.
830 ObjCPropertyImplDecl *ObjCImplDecl::
831 FindPropertyImplIvarDecl(IdentifierInfo *ivarId) const {
832 for (propimpl_iterator i = propimpl_begin(), e = propimpl_end(); i != e; ++i){
833 ObjCPropertyImplDecl *PID = *i;
834 if (PID->getPropertyIvarDecl() &&
835 PID->getPropertyIvarDecl()->getIdentifier() == ivarId)
841 /// FindPropertyImplDecl - This method looks up a previous ObjCPropertyImplDecl
842 /// added to the list of those properties @synthesized/@dynamic in this
843 /// category @implementation block.
845 ObjCPropertyImplDecl *ObjCImplDecl::
846 FindPropertyImplDecl(IdentifierInfo *Id) const {
847 for (propimpl_iterator i = propimpl_begin(), e = propimpl_end(); i != e; ++i){
848 ObjCPropertyImplDecl *PID = *i;
849 if (PID->getPropertyDecl()->getIdentifier() == Id)
855 llvm::raw_ostream &clang::operator<<(llvm::raw_ostream &OS,
856 const ObjCCategoryImplDecl *CID) {
857 OS << CID->getName();
861 //===----------------------------------------------------------------------===//
862 // ObjCImplementationDecl
863 //===----------------------------------------------------------------------===//
865 ObjCImplementationDecl *
866 ObjCImplementationDecl::Create(ASTContext &C, DeclContext *DC,
868 ObjCInterfaceDecl *ClassInterface,
869 ObjCInterfaceDecl *SuperDecl) {
870 return new (C) ObjCImplementationDecl(DC, L, ClassInterface, SuperDecl);
873 llvm::raw_ostream &clang::operator<<(llvm::raw_ostream &OS,
874 const ObjCImplementationDecl *ID) {
879 //===----------------------------------------------------------------------===//
880 // ObjCCompatibleAliasDecl
881 //===----------------------------------------------------------------------===//
883 ObjCCompatibleAliasDecl *
884 ObjCCompatibleAliasDecl::Create(ASTContext &C, DeclContext *DC,
887 ObjCInterfaceDecl* AliasedClass) {
888 return new (C) ObjCCompatibleAliasDecl(DC, L, Id, AliasedClass);
891 //===----------------------------------------------------------------------===//
893 //===----------------------------------------------------------------------===//
895 ObjCPropertyDecl *ObjCPropertyDecl::Create(ASTContext &C, DeclContext *DC,
898 SourceLocation AtLoc,
900 PropertyControl propControl) {
901 return new (C) ObjCPropertyDecl(DC, L, Id, AtLoc, T);
905 //===----------------------------------------------------------------------===//
906 // ObjCPropertyImplDecl
907 //===----------------------------------------------------------------------===//
909 ObjCPropertyImplDecl *ObjCPropertyImplDecl::Create(ASTContext &C,
911 SourceLocation atLoc,
913 ObjCPropertyDecl *property,
915 ObjCIvarDecl *ivar) {
916 return new (C) ObjCPropertyImplDecl(DC, atLoc, L, property, PK, ivar);