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)
92 /// FindPropertyDeclaration - Finds declaration of the property given its name
93 /// in 'PropertyId' and returns it. It returns 0, if not found.
94 /// FIXME: Convert to DeclContext lookup...
97 ObjCContainerDecl::FindPropertyDeclaration(IdentifierInfo *PropertyId) const {
98 for (prop_iterator I = prop_begin(), E = prop_end(); I != E; ++I)
99 if ((*I)->getIdentifier() == PropertyId)
102 const ObjCProtocolDecl *PID = dyn_cast<ObjCProtocolDecl>(this);
104 for (ObjCProtocolDecl::protocol_iterator I = PID->protocol_begin(),
105 E = PID->protocol_end(); I != E; ++I)
106 if (ObjCPropertyDecl *P = (*I)->FindPropertyDeclaration(PropertyId))
110 if (const ObjCInterfaceDecl *OID = dyn_cast<ObjCInterfaceDecl>(this)) {
111 // Look through categories.
112 for (ObjCCategoryDecl *Category = OID->getCategoryList();
113 Category; Category = Category->getNextClassCategory()) {
114 if (ObjCPropertyDecl *P = Category->FindPropertyDeclaration(PropertyId))
117 // Look through protocols.
118 for (ObjCInterfaceDecl::protocol_iterator I = OID->protocol_begin(),
119 E = OID->protocol_end(); I != E; ++I) {
120 if (ObjCPropertyDecl *P = (*I)->FindPropertyDeclaration(PropertyId))
123 if (OID->getSuperClass())
124 return OID->getSuperClass()->FindPropertyDeclaration(PropertyId);
125 } else if (const ObjCCategoryDecl *OCD = dyn_cast<ObjCCategoryDecl>(this)) {
126 // Look through protocols.
127 for (ObjCInterfaceDecl::protocol_iterator I = OCD->protocol_begin(),
128 E = OCD->protocol_end(); I != E; ++I) {
129 if (ObjCPropertyDecl *P = (*I)->FindPropertyDeclaration(PropertyId))
136 /// FindPropertyVisibleInPrimaryClass - Finds declaration of the property
137 /// with name 'PropertyId' in the primary class; including those in protocols
138 /// (direct or indirect) used by the promary class.
139 /// FIXME: Convert to DeclContext lookup...
142 ObjCContainerDecl::FindPropertyVisibleInPrimaryClass(
143 IdentifierInfo *PropertyId) const {
144 assert(isa<ObjCInterfaceDecl>(this) && "FindPropertyVisibleInPrimaryClass");
145 for (prop_iterator I = prop_begin(), E = prop_end(); I != E; ++I)
146 if ((*I)->getIdentifier() == PropertyId)
148 const ObjCInterfaceDecl *OID = dyn_cast<ObjCInterfaceDecl>(this);
149 // Look through protocols.
150 for (ObjCInterfaceDecl::protocol_iterator I = OID->protocol_begin(),
151 E = OID->protocol_end(); I != E; ++I)
152 if (ObjCPropertyDecl *P = (*I)->FindPropertyDeclaration(PropertyId))
157 void ObjCInterfaceDecl::mergeClassExtensionProtocolList(
158 ObjCProtocolDecl *const* ExtList, unsigned ExtNum,
159 const SourceLocation *Locs,
162 if (ReferencedProtocols.empty()) {
163 ReferencedProtocols.set(ExtList, ExtNum, Locs, C);
166 // Check for duplicate protocol in class's protocol list.
167 // This is (O)2. But it is extremely rare and number of protocols in
168 // class or its extension are very few.
169 llvm::SmallVector<ObjCProtocolDecl*, 8> ProtocolRefs;
170 llvm::SmallVector<SourceLocation, 8> ProtocolLocs;
171 for (unsigned i = 0; i < ExtNum; i++) {
172 bool protocolExists = false;
173 ObjCProtocolDecl *ProtoInExtension = ExtList[i];
174 for (protocol_iterator p = protocol_begin(), e = protocol_end();
176 ObjCProtocolDecl *Proto = (*p);
177 if (C.ProtocolCompatibleWithProtocol(ProtoInExtension, Proto)) {
178 protocolExists = true;
182 // Do we want to warn on a protocol in extension class which
183 // already exist in the class? Probably not.
184 if (!protocolExists) {
185 ProtocolRefs.push_back(ProtoInExtension);
186 ProtocolLocs.push_back(Locs[i]);
189 if (ProtocolRefs.empty())
191 // Merge ProtocolRefs into class's protocol list;
192 protocol_loc_iterator pl = protocol_loc_begin();
193 for (protocol_iterator p = protocol_begin(), e = protocol_end();
195 ProtocolRefs.push_back(*p);
196 ProtocolLocs.push_back(*pl);
198 ReferencedProtocols.Destroy(C);
199 unsigned NumProtoRefs = ProtocolRefs.size();
200 setProtocolList(ProtocolRefs.data(), NumProtoRefs, ProtocolLocs.data(), C);
203 ObjCIvarDecl *ObjCInterfaceDecl::lookupInstanceVariable(IdentifierInfo *ID,
204 ObjCInterfaceDecl *&clsDeclared) {
205 ObjCInterfaceDecl* ClassDecl = this;
206 while (ClassDecl != NULL) {
207 if (ObjCIvarDecl *I = ClassDecl->getIvarDecl(ID)) {
208 clsDeclared = ClassDecl;
211 ClassDecl = ClassDecl->getSuperClass();
216 /// lookupInheritedClass - This method returns ObjCInterfaceDecl * of the super
217 /// class whose name is passed as argument. If it is not one of the super classes
218 /// the it returns NULL.
219 ObjCInterfaceDecl *ObjCInterfaceDecl::lookupInheritedClass(
220 const IdentifierInfo*ICName) {
221 ObjCInterfaceDecl* ClassDecl = this;
222 while (ClassDecl != NULL) {
223 if (ClassDecl->getIdentifier() == ICName)
225 ClassDecl = ClassDecl->getSuperClass();
230 /// lookupMethod - This method returns an instance/class method by looking in
231 /// the class, its categories, and its super classes (using a linear search).
232 ObjCMethodDecl *ObjCInterfaceDecl::lookupMethod(Selector Sel,
233 bool isInstance) const {
234 const ObjCInterfaceDecl* ClassDecl = this;
235 ObjCMethodDecl *MethodDecl = 0;
237 while (ClassDecl != NULL) {
238 if ((MethodDecl = ClassDecl->getMethod(Sel, isInstance)))
241 // Didn't find one yet - look through protocols.
242 const ObjCList<ObjCProtocolDecl> &Protocols =
243 ClassDecl->getReferencedProtocols();
244 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
245 E = Protocols.end(); I != E; ++I)
246 if ((MethodDecl = (*I)->lookupMethod(Sel, isInstance)))
249 // Didn't find one yet - now look through categories.
250 ObjCCategoryDecl *CatDecl = ClassDecl->getCategoryList();
252 if ((MethodDecl = CatDecl->getMethod(Sel, isInstance)))
255 // Didn't find one yet - look through protocols.
256 const ObjCList<ObjCProtocolDecl> &Protocols =
257 CatDecl->getReferencedProtocols();
258 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
259 E = Protocols.end(); I != E; ++I)
260 if ((MethodDecl = (*I)->lookupMethod(Sel, isInstance)))
262 CatDecl = CatDecl->getNextClassCategory();
264 ClassDecl = ClassDecl->getSuperClass();
269 ObjCMethodDecl *ObjCInterfaceDecl::lookupPrivateInstanceMethod(
270 const Selector &Sel) {
271 ObjCMethodDecl *Method = 0;
272 if (ObjCImplementationDecl *ImpDecl = getImplementation())
273 Method = ImpDecl->getInstanceMethod(Sel);
275 if (!Method && getSuperClass())
276 return getSuperClass()->lookupPrivateInstanceMethod(Sel);
280 //===----------------------------------------------------------------------===//
282 //===----------------------------------------------------------------------===//
284 ObjCMethodDecl *ObjCMethodDecl::Create(ASTContext &C,
285 SourceLocation beginLoc,
286 SourceLocation endLoc,
287 Selector SelInfo, QualType T,
288 DeclContext *contextDecl,
292 ImplementationControl impControl) {
293 return new (C) ObjCMethodDecl(beginLoc, endLoc,
294 SelInfo, T, contextDecl,
296 isVariadic, isSynthesized, impControl);
299 void ObjCMethodDecl::Destroy(ASTContext &C) {
300 if (Body) Body->Destroy(C);
301 if (SelfDecl) SelfDecl->Destroy(C);
303 for (param_iterator I=param_begin(), E=param_end(); I!=E; ++I)
304 if (*I) (*I)->Destroy(C);
306 ParamInfo.Destroy(C);
311 /// \brief A definition will return its interface declaration.
312 /// An interface declaration will return its definition.
313 /// Otherwise it will return itself.
314 ObjCMethodDecl *ObjCMethodDecl::getNextRedeclaration() {
315 ASTContext &Ctx = getASTContext();
316 ObjCMethodDecl *Redecl = 0;
317 Decl *CtxD = cast<Decl>(getDeclContext());
319 if (ObjCInterfaceDecl *IFD = dyn_cast<ObjCInterfaceDecl>(CtxD)) {
320 if (ObjCImplementationDecl *ImplD = Ctx.getObjCImplementation(IFD))
321 Redecl = ImplD->getMethod(getSelector(), isInstanceMethod());
323 } else if (ObjCCategoryDecl *CD = dyn_cast<ObjCCategoryDecl>(CtxD)) {
324 if (ObjCCategoryImplDecl *ImplD = Ctx.getObjCImplementation(CD))
325 Redecl = ImplD->getMethod(getSelector(), isInstanceMethod());
327 } else if (ObjCImplementationDecl *ImplD =
328 dyn_cast<ObjCImplementationDecl>(CtxD)) {
329 if (ObjCInterfaceDecl *IFD = ImplD->getClassInterface())
330 Redecl = IFD->getMethod(getSelector(), isInstanceMethod());
332 } else if (ObjCCategoryImplDecl *CImplD =
333 dyn_cast<ObjCCategoryImplDecl>(CtxD)) {
334 if (ObjCCategoryDecl *CatD = CImplD->getCategoryDecl())
335 Redecl = CatD->getMethod(getSelector(), isInstanceMethod());
338 return Redecl ? Redecl : this;
341 ObjCMethodDecl *ObjCMethodDecl::getCanonicalDecl() {
342 Decl *CtxD = cast<Decl>(getDeclContext());
344 if (ObjCImplementationDecl *ImplD = dyn_cast<ObjCImplementationDecl>(CtxD)) {
345 if (ObjCInterfaceDecl *IFD = ImplD->getClassInterface())
346 if (ObjCMethodDecl *MD = IFD->getMethod(getSelector(),
350 } else if (ObjCCategoryImplDecl *CImplD =
351 dyn_cast<ObjCCategoryImplDecl>(CtxD)) {
352 if (ObjCCategoryDecl *CatD = CImplD->getCategoryDecl())
353 if (ObjCMethodDecl *MD = CatD->getMethod(getSelector(),
361 void ObjCMethodDecl::createImplicitParams(ASTContext &Context,
362 const ObjCInterfaceDecl *OID) {
364 if (isInstanceMethod()) {
365 // There may be no interface context due to error in declaration
366 // of the interface (which has been reported). Recover gracefully.
368 selfTy = Context.getObjCInterfaceType(OID);
369 selfTy = Context.getObjCObjectPointerType(selfTy);
371 selfTy = Context.getObjCIdType();
373 } else // we have a factory method.
374 selfTy = Context.getObjCClassType();
376 setSelfDecl(ImplicitParamDecl::Create(Context, this, SourceLocation(),
377 &Context.Idents.get("self"), selfTy));
379 setCmdDecl(ImplicitParamDecl::Create(Context, this, SourceLocation(),
380 &Context.Idents.get("_cmd"),
381 Context.getObjCSelType()));
384 ObjCInterfaceDecl *ObjCMethodDecl::getClassInterface() {
385 if (ObjCInterfaceDecl *ID = dyn_cast<ObjCInterfaceDecl>(getDeclContext()))
387 if (ObjCCategoryDecl *CD = dyn_cast<ObjCCategoryDecl>(getDeclContext()))
388 return CD->getClassInterface();
389 if (ObjCImplDecl *IMD = dyn_cast<ObjCImplDecl>(getDeclContext()))
390 return IMD->getClassInterface();
392 assert(!isa<ObjCProtocolDecl>(getDeclContext()) && "It's a protocol method");
393 assert(false && "unknown method context");
397 //===----------------------------------------------------------------------===//
399 //===----------------------------------------------------------------------===//
401 ObjCInterfaceDecl *ObjCInterfaceDecl::Create(ASTContext &C,
403 SourceLocation atLoc,
405 SourceLocation ClassLoc,
406 bool ForwardDecl, bool isInternal){
407 return new (C) ObjCInterfaceDecl(DC, atLoc, Id, ClassLoc, ForwardDecl,
412 ObjCInterfaceDecl(DeclContext *DC, SourceLocation atLoc, IdentifierInfo *Id,
413 SourceLocation CLoc, bool FD, bool isInternal)
414 : ObjCContainerDecl(ObjCInterface, DC, atLoc, Id),
415 TypeForDecl(0), SuperClass(0),
416 CategoryList(0), ForwardDecl(FD), InternalInterface(isInternal),
420 void ObjCInterfaceDecl::Destroy(ASTContext &C) {
421 for (ivar_iterator I = ivar_begin(), E = ivar_end(); I != E; ++I)
422 if (*I) (*I)->Destroy(C);
425 // FIXME: CategoryList?
427 // FIXME: Because there is no clear ownership
428 // role between ObjCInterfaceDecls and the ObjCPropertyDecls that they
429 // reference, we destroy ObjCPropertyDecls in ~TranslationUnit.
433 ObjCImplementationDecl *ObjCInterfaceDecl::getImplementation() const {
434 return getASTContext().getObjCImplementation(
435 const_cast<ObjCInterfaceDecl*>(this));
438 void ObjCInterfaceDecl::setImplementation(ObjCImplementationDecl *ImplD) {
439 getASTContext().setObjCImplementation(this, ImplD);
443 /// FindCategoryDeclaration - Finds category declaration in the list of
444 /// categories for this class and returns it. Name of the category is passed
445 /// in 'CategoryId'. If category not found, return 0;
448 ObjCInterfaceDecl::FindCategoryDeclaration(IdentifierInfo *CategoryId) const {
449 for (ObjCCategoryDecl *Category = getCategoryList();
450 Category; Category = Category->getNextClassCategory())
451 if (Category->getIdentifier() == CategoryId)
457 ObjCInterfaceDecl::getCategoryInstanceMethod(Selector Sel) const {
458 for (ObjCCategoryDecl *Category = getCategoryList();
459 Category; Category = Category->getNextClassCategory())
460 if (ObjCCategoryImplDecl *Impl = Category->getImplementation())
461 if (ObjCMethodDecl *MD = Impl->getInstanceMethod(Sel))
466 ObjCMethodDecl *ObjCInterfaceDecl::getCategoryClassMethod(Selector Sel) const {
467 for (ObjCCategoryDecl *Category = getCategoryList();
468 Category; Category = Category->getNextClassCategory())
469 if (ObjCCategoryImplDecl *Impl = Category->getImplementation())
470 if (ObjCMethodDecl *MD = Impl->getClassMethod(Sel))
475 /// ClassImplementsProtocol - Checks that 'lProto' protocol
476 /// has been implemented in IDecl class, its super class or categories (if
477 /// lookupCategory is true).
478 bool ObjCInterfaceDecl::ClassImplementsProtocol(ObjCProtocolDecl *lProto,
480 bool RHSIsQualifiedID) {
481 ObjCInterfaceDecl *IDecl = this;
482 // 1st, look up the class.
483 const ObjCList<ObjCProtocolDecl> &Protocols =
484 IDecl->getReferencedProtocols();
486 for (ObjCList<ObjCProtocolDecl>::iterator PI = Protocols.begin(),
487 E = Protocols.end(); PI != E; ++PI) {
488 if (getASTContext().ProtocolCompatibleWithProtocol(lProto, *PI))
490 // This is dubious and is added to be compatible with gcc. In gcc, it is
491 // also allowed assigning a protocol-qualified 'id' type to a LHS object
492 // when protocol in qualified LHS is in list of protocols in the rhs 'id'
493 // object. This IMO, should be a bug.
494 // FIXME: Treat this as an extension, and flag this as an error when GCC
495 // extensions are not enabled.
496 if (RHSIsQualifiedID &&
497 getASTContext().ProtocolCompatibleWithProtocol(*PI, lProto))
501 // 2nd, look up the category.
503 for (ObjCCategoryDecl *CDecl = IDecl->getCategoryList(); CDecl;
504 CDecl = CDecl->getNextClassCategory()) {
505 for (ObjCCategoryDecl::protocol_iterator PI = CDecl->protocol_begin(),
506 E = CDecl->protocol_end(); PI != E; ++PI)
507 if (getASTContext().ProtocolCompatibleWithProtocol(lProto, *PI))
511 // 3rd, look up the super class(s)
512 if (IDecl->getSuperClass())
514 IDecl->getSuperClass()->ClassImplementsProtocol(lProto, lookupCategory,
520 //===----------------------------------------------------------------------===//
522 //===----------------------------------------------------------------------===//
524 ObjCIvarDecl *ObjCIvarDecl::Create(ASTContext &C, DeclContext *DC,
525 SourceLocation L, IdentifierInfo *Id,
526 QualType T, TypeSourceInfo *TInfo,
527 AccessControl ac, Expr *BW) {
528 return new (C) ObjCIvarDecl(DC, L, Id, T, TInfo, ac, BW);
533 //===----------------------------------------------------------------------===//
534 // ObjCAtDefsFieldDecl
535 //===----------------------------------------------------------------------===//
538 *ObjCAtDefsFieldDecl::Create(ASTContext &C, DeclContext *DC, SourceLocation L,
539 IdentifierInfo *Id, QualType T, Expr *BW) {
540 return new (C) ObjCAtDefsFieldDecl(DC, L, Id, T, BW);
543 void ObjCAtDefsFieldDecl::Destroy(ASTContext& C) {
544 this->~ObjCAtDefsFieldDecl();
545 C.Deallocate((void *)this);
548 //===----------------------------------------------------------------------===//
550 //===----------------------------------------------------------------------===//
552 ObjCProtocolDecl *ObjCProtocolDecl::Create(ASTContext &C, DeclContext *DC,
554 IdentifierInfo *Id) {
555 return new (C) ObjCProtocolDecl(DC, L, Id);
558 void ObjCProtocolDecl::Destroy(ASTContext &C) {
559 ReferencedProtocols.Destroy(C);
560 ObjCContainerDecl::Destroy(C);
563 ObjCProtocolDecl *ObjCProtocolDecl::lookupProtocolNamed(IdentifierInfo *Name) {
564 ObjCProtocolDecl *PDecl = this;
566 if (Name == getIdentifier())
569 for (protocol_iterator I = protocol_begin(), E = protocol_end(); I != E; ++I)
570 if ((PDecl = (*I)->lookupProtocolNamed(Name)))
576 // lookupMethod - Lookup a instance/class method in the protocol and protocols
578 ObjCMethodDecl *ObjCProtocolDecl::lookupMethod(Selector Sel,
579 bool isInstance) const {
580 ObjCMethodDecl *MethodDecl = NULL;
582 if ((MethodDecl = getMethod(Sel, isInstance)))
585 for (protocol_iterator I = protocol_begin(), E = protocol_end(); I != E; ++I)
586 if ((MethodDecl = (*I)->lookupMethod(Sel, isInstance)))
591 //===----------------------------------------------------------------------===//
593 //===----------------------------------------------------------------------===//
595 ObjCClassDecl::ObjCClassDecl(DeclContext *DC, SourceLocation L,
596 ObjCInterfaceDecl *const *Elts,
597 const SourceLocation *Locs,
600 : Decl(ObjCClass, DC, L) {
601 setClassList(C, Elts, Locs, nElts);
604 void ObjCClassDecl::setClassList(ASTContext &C, ObjCInterfaceDecl*const*List,
605 const SourceLocation *Locs, unsigned Num) {
606 ForwardDecls = (ObjCClassRef*) C.Allocate(sizeof(ObjCClassRef)*Num,
607 llvm::alignof<ObjCClassRef>());
608 for (unsigned i = 0; i < Num; ++i)
609 new (&ForwardDecls[i]) ObjCClassRef(List[i], Locs[i]);
614 ObjCClassDecl *ObjCClassDecl::Create(ASTContext &C, DeclContext *DC,
616 ObjCInterfaceDecl *const *Elts,
617 const SourceLocation *Locs,
619 return new (C) ObjCClassDecl(DC, L, Elts, Locs, nElts, C);
622 void ObjCClassDecl::Destroy(ASTContext &C) {
623 // ObjCInterfaceDecls registered with a DeclContext will get destroyed
624 // when the DeclContext is destroyed. For those created only by a forward
625 // declaration, the first @class that created the ObjCInterfaceDecl gets
627 // FIXME: Note that this ownership role is very brittle; a better
628 // polict is surely need in the future.
629 for (iterator I = begin(), E = end(); I !=E ; ++I) {
630 ObjCInterfaceDecl *ID = I->getInterface();
631 if (ID->isForwardDecl() && ID->getLocStart() == getLocStart())
635 C.Deallocate(ForwardDecls);
639 SourceRange ObjCClassDecl::getSourceRange() const {
640 // FIXME: We should include the semicolon
642 return SourceRange(getLocation(), ForwardDecls[NumDecls-1].getLocation());
645 //===----------------------------------------------------------------------===//
646 // ObjCForwardProtocolDecl
647 //===----------------------------------------------------------------------===//
649 ObjCForwardProtocolDecl::
650 ObjCForwardProtocolDecl(DeclContext *DC, SourceLocation L,
651 ObjCProtocolDecl *const *Elts, unsigned nElts,
652 const SourceLocation *Locs, ASTContext &C)
653 : Decl(ObjCForwardProtocol, DC, L) {
654 ReferencedProtocols.set(Elts, nElts, Locs, C);
658 ObjCForwardProtocolDecl *
659 ObjCForwardProtocolDecl::Create(ASTContext &C, DeclContext *DC,
661 ObjCProtocolDecl *const *Elts,
663 const SourceLocation *Locs) {
664 return new (C) ObjCForwardProtocolDecl(DC, L, Elts, NumElts, Locs, C);
667 void ObjCForwardProtocolDecl::Destroy(ASTContext &C) {
668 ReferencedProtocols.Destroy(C);
672 //===----------------------------------------------------------------------===//
674 //===----------------------------------------------------------------------===//
676 ObjCCategoryDecl *ObjCCategoryDecl::Create(ASTContext &C, DeclContext *DC,
677 SourceLocation AtLoc,
678 SourceLocation ClassNameLoc,
679 SourceLocation CategoryNameLoc,
680 IdentifierInfo *Id) {
681 return new (C) ObjCCategoryDecl(DC, AtLoc, ClassNameLoc, CategoryNameLoc, Id);
684 ObjCCategoryImplDecl *ObjCCategoryDecl::getImplementation() const {
685 return getASTContext().getObjCImplementation(
686 const_cast<ObjCCategoryDecl*>(this));
689 void ObjCCategoryDecl::setImplementation(ObjCCategoryImplDecl *ImplD) {
690 getASTContext().setObjCImplementation(this, ImplD);
694 //===----------------------------------------------------------------------===//
695 // ObjCCategoryImplDecl
696 //===----------------------------------------------------------------------===//
698 ObjCCategoryImplDecl *
699 ObjCCategoryImplDecl::Create(ASTContext &C, DeclContext *DC,
700 SourceLocation L,IdentifierInfo *Id,
701 ObjCInterfaceDecl *ClassInterface) {
702 return new (C) ObjCCategoryImplDecl(DC, L, Id, ClassInterface);
705 ObjCCategoryDecl *ObjCCategoryImplDecl::getCategoryDecl() const {
706 return getClassInterface()->FindCategoryDeclaration(getIdentifier());
710 void ObjCImplDecl::addPropertyImplementation(ObjCPropertyImplDecl *property) {
711 // FIXME: The context should be correct before we get here.
712 property->setLexicalDeclContext(this);
716 void ObjCImplDecl::setClassInterface(ObjCInterfaceDecl *IFace) {
717 ASTContext &Ctx = getASTContext();
719 if (ObjCImplementationDecl *ImplD
720 = dyn_cast_or_null<ObjCImplementationDecl>(this)) {
722 Ctx.setObjCImplementation(IFace, ImplD);
724 } else if (ObjCCategoryImplDecl *ImplD =
725 dyn_cast_or_null<ObjCCategoryImplDecl>(this)) {
726 if (ObjCCategoryDecl *CD = IFace->FindCategoryDeclaration(getIdentifier()))
727 Ctx.setObjCImplementation(CD, ImplD);
730 ClassInterface = IFace;
733 /// FindPropertyImplIvarDecl - This method lookup the ivar in the list of
734 /// properties implemented in this category @implementation block and returns
735 /// the implemented property that uses it.
737 ObjCPropertyImplDecl *ObjCImplDecl::
738 FindPropertyImplIvarDecl(IdentifierInfo *ivarId) const {
739 for (propimpl_iterator i = propimpl_begin(), e = propimpl_end(); i != e; ++i){
740 ObjCPropertyImplDecl *PID = *i;
741 if (PID->getPropertyIvarDecl() &&
742 PID->getPropertyIvarDecl()->getIdentifier() == ivarId)
748 /// FindPropertyImplDecl - This method looks up a previous ObjCPropertyImplDecl
749 /// added to the list of those properties @synthesized/@dynamic in this
750 /// category @implementation block.
752 ObjCPropertyImplDecl *ObjCImplDecl::
753 FindPropertyImplDecl(IdentifierInfo *Id) const {
754 for (propimpl_iterator i = propimpl_begin(), e = propimpl_end(); i != e; ++i){
755 ObjCPropertyImplDecl *PID = *i;
756 if (PID->getPropertyDecl()->getIdentifier() == Id)
762 //===----------------------------------------------------------------------===//
763 // ObjCImplementationDecl
764 //===----------------------------------------------------------------------===//
766 ObjCImplementationDecl *
767 ObjCImplementationDecl::Create(ASTContext &C, DeclContext *DC,
769 ObjCInterfaceDecl *ClassInterface,
770 ObjCInterfaceDecl *SuperDecl) {
771 return new (C) ObjCImplementationDecl(DC, L, ClassInterface, SuperDecl);
774 //===----------------------------------------------------------------------===//
775 // ObjCCompatibleAliasDecl
776 //===----------------------------------------------------------------------===//
778 ObjCCompatibleAliasDecl *
779 ObjCCompatibleAliasDecl::Create(ASTContext &C, DeclContext *DC,
782 ObjCInterfaceDecl* AliasedClass) {
783 return new (C) ObjCCompatibleAliasDecl(DC, L, Id, AliasedClass);
786 //===----------------------------------------------------------------------===//
788 //===----------------------------------------------------------------------===//
790 ObjCPropertyDecl *ObjCPropertyDecl::Create(ASTContext &C, DeclContext *DC,
793 SourceLocation AtLoc,
795 PropertyControl propControl) {
796 return new (C) ObjCPropertyDecl(DC, L, Id, AtLoc, T);
800 //===----------------------------------------------------------------------===//
801 // ObjCPropertyImplDecl
802 //===----------------------------------------------------------------------===//
804 ObjCPropertyImplDecl *ObjCPropertyImplDecl::Create(ASTContext &C,
806 SourceLocation atLoc,
808 ObjCPropertyDecl *property,
810 ObjCIvarDecl *ivar) {
811 return new (C) ObjCPropertyImplDecl(DC, atLoc, L, property, PK, ivar);