Make ObjCImplDecl inherit from ObjCContainerDecl.

ObjCContainerDecl now is the root class for objc decls that contain methods.

llvm-svn: 77235
This commit is contained in:
Argyrios Kyrtzidis 2009-07-27 19:04:32 +00:00
parent b8aa9589bb
commit 067c407c48
7 changed files with 15 additions and 88 deletions

View File

@ -453,7 +453,6 @@ public:
/// TagDecl
/// ObjCMethodDecl
/// ObjCContainerDecl
/// ObjCImpl
/// LinkageSpecDecl
/// BlockDecl
///

View File

@ -114,11 +114,11 @@ ABSTRACT_DECL(Named, Decl)
DECL(ObjCCategory, ObjCContainerDecl)
DECL(ObjCProtocol, ObjCContainerDecl)
DECL(ObjCInterface, ObjCContainerDecl)
ABSTRACT_DECL(ObjCImpl, ObjCContainerDecl)
DECL(ObjCCategoryImpl, ObjCImplDecl)
DECL(ObjCImplementation, ObjCImplDecl)
DECL(ObjCProperty, NamedDecl)
DECL(ObjCCompatibleAlias, NamedDecl)
ABSTRACT_DECL(ObjCImpl, NamedDecl)
DECL(ObjCCategoryImpl, ObjCImplDecl)
DECL(ObjCImplementation, ObjCImplDecl)
DECL(LinkageSpec, Decl)
DECL(ObjCPropertyImpl, Decl)
DECL(ObjCForwardProtocol, Decl)
@ -132,15 +132,14 @@ DECL_CONTEXT(TranslationUnit)
DECL_CONTEXT(Namespace)
DECL_CONTEXT(LinkageSpec)
DECL_CONTEXT(ObjCMethod)
DECL_CONTEXT_BASE(ObjCImpl)
DECL_CONTEXT_BASE(Tag)
DECL_CONTEXT_BASE(Function)
DECL_CONTEXT_BASE(ObjCContainer)
LAST_DECL_CONTEXT(Block)
// Declaration ranges
DECL_RANGE(Named, OverloadedFunction, ObjCImplementation)
DECL_RANGE(ObjCContainer, ObjCContainer, ObjCInterface)
DECL_RANGE(Named, OverloadedFunction, ObjCCompatibleAlias)
DECL_RANGE(ObjCContainer, ObjCContainer, ObjCImplementation)
DECL_RANGE(Field, Field, ObjCAtDefsField)
DECL_RANGE(Type, Typedef, TemplateTypeParm)
DECL_RANGE(Tag, Enum, ClassTemplatePartialSpecialization)

View File

@ -280,9 +280,8 @@ struct ObjCMethodList {
};
/// ObjCContainerDecl - Represents a container for method declarations.
/// Current sub-classes are ObjCInterfaceDecl, ObjCCategoryDecl, and
/// ObjCProtocolDecl.
/// FIXME: Use for ObjC implementation decls.
/// Current sub-classes are ObjCInterfaceDecl, ObjCCategoryDecl,
/// ObjCProtocolDecl, and ObjCImplDecl.
///
class ObjCContainerDecl : public NamedDecl, public DeclContext {
SourceLocation AtEndLoc; // marks the end of the method container.
@ -839,19 +838,16 @@ public:
static bool classof(const ObjCCategoryDecl *D) { return true; }
};
class ObjCImplDecl : public NamedDecl, public DeclContext {
class ObjCImplDecl : public ObjCContainerDecl {
/// Class interface for this category implementation
ObjCInterfaceDecl *ClassInterface;
SourceLocation EndLoc;
protected:
ObjCImplDecl(Kind DK, DeclContext *DC, SourceLocation L,
ObjCInterfaceDecl *classInterface)
: NamedDecl(DK, DC, L,
classInterface? classInterface->getDeclName()
: DeclarationName()),
DeclContext(DK), ClassInterface(classInterface) {}
: ObjCContainerDecl(DK, DC, L,
classInterface? classInterface->getIdentifier() : 0),
ClassInterface(classInterface) {}
public:
virtual ~ObjCImplDecl() {}
@ -871,15 +867,6 @@ public:
addDecl(method);
}
// Get the local instance/class method declared in this interface.
ObjCMethodDecl *getMethod(Selector Sel, bool isInstance) const;
ObjCMethodDecl *getInstanceMethod(Selector Sel) const {
return getMethod(Sel, true/*isInstance*/);
}
ObjCMethodDecl *getClassMethod(Selector Sel) const {
return getMethod(Sel, false/*isInstance*/);
}
void addPropertyImplementation(ObjCPropertyImplDecl *property);
ObjCPropertyImplDecl *FindPropertyImplDecl(IdentifierInfo *propertyId) const;
@ -894,44 +881,10 @@ public:
return propimpl_iterator(decls_end());
}
typedef filtered_decl_iterator<ObjCMethodDecl,
&ObjCMethodDecl::isInstanceMethod>
instmeth_iterator;
instmeth_iterator instmeth_begin() const {
return instmeth_iterator(decls_begin());
}
instmeth_iterator instmeth_end() const {
return instmeth_iterator(decls_end());
}
typedef filtered_decl_iterator<ObjCMethodDecl,
&ObjCMethodDecl::isClassMethod>
classmeth_iterator;
classmeth_iterator classmeth_begin() const {
return classmeth_iterator(decls_begin());
}
classmeth_iterator classmeth_end() const {
return classmeth_iterator(decls_end());
}
// Location information, modeled after the Stmt API.
virtual SourceRange getSourceRange() const {
return SourceRange(getLocation(), EndLoc);
}
SourceLocation getLocStart() const { return getLocation(); }
SourceLocation getLocEnd() const { return EndLoc; }
void setLocEnd(SourceLocation LE) { EndLoc = LE; };
static bool classof(const Decl *D) {
return D->getKind() >= ObjCImplFirst && D->getKind() <= ObjCImplLast;
}
static bool classof(const ObjCImplDecl *D) { return true; }
static DeclContext *castToDeclContext(const ObjCImplDecl *D) {
return static_cast<DeclContext *>(const_cast<ObjCImplDecl*>(D));
}
static ObjCImplDecl *castFromDeclContext(const DeclContext *DC) {
return static_cast<ObjCImplDecl *>(const_cast<DeclContext*>(DC));
}
};
/// ObjCCategoryImplDecl - An object of this class encapsulates a category

View File

@ -587,28 +587,6 @@ FindPropertyImplDecl(IdentifierInfo *Id) const {
return 0;
}
// getMethod - This method returns an instance/class method by looking in
// the class implementation. Unlike interfaces, we don't look outside the
// implementation.
ObjCMethodDecl *ObjCImplDecl::getMethod(Selector Sel, bool isInstance) const {
// Since instance & class methods can have the same name, the loop below
// ensures we get the correct method.
//
// @interface Whatever
// - (int) class_method;
// + (float) class_method;
// @end
//
lookup_const_iterator Meth, MethEnd;
for (llvm::tie(Meth, MethEnd) = lookup(Sel);
Meth != MethEnd; ++Meth) {
ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(*Meth);
if (MD && MD->isInstanceMethod() == isInstance)
return MD;
}
return 0;
}
//===----------------------------------------------------------------------===//
// ObjCImplementationDecl
//===----------------------------------------------------------------------===//

View File

@ -304,10 +304,9 @@ void PCHDeclReader::VisitObjCPropertyDecl(ObjCPropertyDecl *D) {
}
void PCHDeclReader::VisitObjCImplDecl(ObjCImplDecl *D) {
VisitNamedDecl(D);
VisitObjCContainerDecl(D);
D->setClassInterface(
cast_or_null<ObjCInterfaceDecl>(Reader.GetDecl(Record[Idx++])));
D->setLocEnd(SourceLocation::getFromRawEncoding(Record[Idx++]));
}
void PCHDeclReader::VisitObjCCategoryImplDecl(ObjCCategoryImplDecl *D) {

View File

@ -297,9 +297,8 @@ void PCHDeclWriter::VisitObjCPropertyDecl(ObjCPropertyDecl *D) {
}
void PCHDeclWriter::VisitObjCImplDecl(ObjCImplDecl *D) {
VisitNamedDecl(D);
VisitObjCContainerDecl(D);
Writer.AddDeclRef(D->getClassInterface(), Record);
Writer.AddSourceLocation(D->getLocEnd(), Record);
// Abstract class (no need to define a stable pch::DECL code).
}

View File

@ -1555,12 +1555,12 @@ void Sema::ActOnAtEnd(SourceLocation AtEndLoc, DeclPtrTy classDecl,
CDecl->setAtEndLoc(AtEndLoc);
}
if (ObjCImplementationDecl *IC=dyn_cast<ObjCImplementationDecl>(ClassDecl)) {
IC->setLocEnd(AtEndLoc);
IC->setAtEndLoc(AtEndLoc);
if (ObjCInterfaceDecl* IDecl = IC->getClassInterface())
ImplMethodsVsClassMethods(IC, IDecl);
} else if (ObjCCategoryImplDecl* CatImplClass =
dyn_cast<ObjCCategoryImplDecl>(ClassDecl)) {
CatImplClass->setLocEnd(AtEndLoc);
CatImplClass->setAtEndLoc(AtEndLoc);
// Find category interface decl and then check that all methods declared
// in this interface are implemented in the category @implementation.