Eliminate the three SmallVectors in ObjCImplDecl (for instance

methods, class methods, and property implementations) and instead
place all of these entities into the DeclContext.

This eliminates more linear walks when looking for class or instance
methods and should make PCH (de-)serialization of ObjCDecls trivial
(and lazy).



git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@69849 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Douglas Gregor 2009-04-23 01:02:12 +00:00
Родитель 70e5a14c60
Коммит 653f1b1bf2
14 изменённых файлов: 297 добавлений и 184 удалений

Просмотреть файл

@ -796,15 +796,6 @@ class ObjCImplDecl : public Decl, public DeclContext {
/// Class interface for this category implementation
ObjCInterfaceDecl *ClassInterface;
/// implemented instance methods
llvm::SmallVector<ObjCMethodDecl*, 16> InstanceMethods;
/// implemented class methods
llvm::SmallVector<ObjCMethodDecl*, 16> ClassMethods;
/// Property Implementations in this category
llvm::SmallVector<ObjCPropertyImplDecl*, 8> PropertyImplementations;
SourceLocation EndLoc;
protected:
@ -819,46 +810,61 @@ public:
const ObjCInterfaceDecl *getClassInterface() const { return ClassInterface; }
ObjCInterfaceDecl *getClassInterface() { return ClassInterface; }
void addInstanceMethod(ObjCMethodDecl *method) {
InstanceMethods.push_back(method);
void addInstanceMethod(ASTContext &Context, ObjCMethodDecl *method) {
method->setLexicalDeclContext(this);
addDecl(Context, method);
}
void addClassMethod(ASTContext &Context, ObjCMethodDecl *method) {
method->setLexicalDeclContext(this);
addDecl(Context, method);
}
void addClassMethod(ObjCMethodDecl *method) {
ClassMethods.push_back(method);
}
// Get the local instance/class method declared in this interface.
ObjCMethodDecl *getInstanceMethod(Selector Sel) const;
ObjCMethodDecl *getClassMethod(Selector Sel) const;
ObjCMethodDecl *getMethod(Selector Sel, bool isInstance) const {
return isInstance ? getInstanceMethod(Sel) : getClassMethod(Sel);
ObjCMethodDecl *getInstanceMethod(ASTContext &Context, Selector Sel) const;
ObjCMethodDecl *getClassMethod(ASTContext &Context, Selector Sel) const;
ObjCMethodDecl *getMethod(ASTContext &Context, Selector Sel,
bool isInstance) const {
return isInstance ? getInstanceMethod(Context, Sel)
: getClassMethod(Context, Sel);
}
void addPropertyImplementation(ObjCPropertyImplDecl *property) {
PropertyImplementations.push_back(property);
}
void addPropertyImplementation(ASTContext &Context,
ObjCPropertyImplDecl *property);
ObjCPropertyImplDecl *FindPropertyImplDecl(IdentifierInfo *propertyId) const;
ObjCPropertyImplDecl *FindPropertyImplIvarDecl(IdentifierInfo *ivarId) const;
typedef llvm::SmallVector<ObjCPropertyImplDecl*, 8>::const_iterator
propimpl_iterator;
propimpl_iterator propimpl_begin() const {
return PropertyImplementations.begin();
ObjCPropertyImplDecl *FindPropertyImplDecl(ASTContext &Context,
IdentifierInfo *propertyId) const;
ObjCPropertyImplDecl *FindPropertyImplIvarDecl(ASTContext &Context,
IdentifierInfo *ivarId) const;
// Iterator access to properties.
typedef specific_decl_iterator<ObjCPropertyImplDecl> propimpl_iterator;
propimpl_iterator propimpl_begin(ASTContext &Context) const {
return propimpl_iterator(decls_begin(Context));
}
propimpl_iterator propimpl_end() const {
return PropertyImplementations.end();
propimpl_iterator propimpl_end(ASTContext &Context) const {
return propimpl_iterator(decls_end(Context));
}
typedef llvm::SmallVector<ObjCMethodDecl*, 32>::const_iterator
typedef filtered_decl_iterator<ObjCMethodDecl,
&ObjCMethodDecl::isInstanceMethod>
instmeth_iterator;
instmeth_iterator instmeth_begin() const { return InstanceMethods.begin(); }
instmeth_iterator instmeth_end() const { return InstanceMethods.end(); }
typedef llvm::SmallVector<ObjCMethodDecl*, 32>::const_iterator
instmeth_iterator instmeth_begin(ASTContext &Context) const {
return instmeth_iterator(decls_begin(Context));
}
instmeth_iterator instmeth_end(ASTContext &Context) const {
return instmeth_iterator(decls_end(Context));
}
typedef filtered_decl_iterator<ObjCMethodDecl,
&ObjCMethodDecl::isClassMethod>
classmeth_iterator;
classmeth_iterator classmeth_begin() const { return ClassMethods.begin(); }
classmeth_iterator classmeth_end() const { return ClassMethods.end(); }
classmeth_iterator classmeth_begin(ASTContext &Context) const {
return classmeth_iterator(decls_begin(Context));
}
classmeth_iterator classmeth_end(ASTContext &Context) const {
return classmeth_iterator(decls_end(Context));
}
// Location information, modeled after the Stmt API.
SourceLocation getLocStart() const { return getLocation(); }
SourceLocation getLocEnd() const { return EndLoc; }

Просмотреть файл

@ -2142,7 +2142,8 @@ void ASTContext::getObjCEncodingForPropertyDecl(const ObjCPropertyDecl *PD,
if (const ObjCCategoryImplDecl *CID =
dyn_cast<ObjCCategoryImplDecl>(Container)) {
for (ObjCCategoryImplDecl::propimpl_iterator
i = CID->propimpl_begin(), e = CID->propimpl_end(); i != e; ++i) {
i = CID->propimpl_begin(*this), e = CID->propimpl_end(*this);
i != e; ++i) {
ObjCPropertyImplDecl *PID = *i;
if (PID->getPropertyDecl() == PD) {
if (PID->getPropertyImplementation()==ObjCPropertyImplDecl::Dynamic) {
@ -2155,7 +2156,8 @@ void ASTContext::getObjCEncodingForPropertyDecl(const ObjCPropertyDecl *PD,
} else {
const ObjCImplementationDecl *OID=cast<ObjCImplementationDecl>(Container);
for (ObjCCategoryImplDecl::propimpl_iterator
i = OID->propimpl_begin(), e = OID->propimpl_end(); i != e; ++i) {
i = OID->propimpl_begin(*this), e = OID->propimpl_end(*this);
i != e; ++i) {
ObjCPropertyImplDecl *PID = *i;
if (PID->getPropertyDecl() == PD) {
if (PID->getPropertyImplementation()==ObjCPropertyImplDecl::Dynamic) {

Просмотреть файл

@ -541,13 +541,20 @@ ObjCCategoryImplDecl::Create(ASTContext &C, DeclContext *DC,
}
void ObjCImplDecl::addPropertyImplementation(ASTContext &Context,
ObjCPropertyImplDecl *property) {
property->setLexicalDeclContext(this);
addDecl(Context, property);
}
/// FindPropertyImplIvarDecl - This method lookup the ivar in the list of
/// properties implemented in this category @implementation block and returns
/// the implemented property that uses it.
///
ObjCPropertyImplDecl *ObjCImplDecl::
FindPropertyImplIvarDecl(IdentifierInfo *ivarId) const {
for (propimpl_iterator i = propimpl_begin(), e = propimpl_end(); i != e; ++i){
FindPropertyImplIvarDecl(ASTContext &Context, IdentifierInfo *ivarId) const {
for (propimpl_iterator i = propimpl_begin(Context), e = propimpl_end(Context);
i != e; ++i){
ObjCPropertyImplDecl *PID = *i;
if (PID->getPropertyIvarDecl() &&
PID->getPropertyIvarDecl()->getIdentifier() == ivarId)
@ -561,8 +568,9 @@ FindPropertyImplIvarDecl(IdentifierInfo *ivarId) const {
/// category @implementation block.
///
ObjCPropertyImplDecl *ObjCImplDecl::
FindPropertyImplDecl(IdentifierInfo *Id) const {
for (propimpl_iterator i = propimpl_begin(), e = propimpl_end(); i != e; ++i){
FindPropertyImplDecl(ASTContext &Context, IdentifierInfo *Id) const {
for (propimpl_iterator i = propimpl_begin(Context), e = propimpl_end(Context);
i != e; ++i){
ObjCPropertyImplDecl *PID = *i;
if (PID->getPropertyDecl()->getIdentifier() == Id)
return PID;
@ -573,22 +581,47 @@ FindPropertyImplDecl(IdentifierInfo *Id) const {
// getInstanceMethod - This method returns an instance method by looking in
// the class implementation. Unlike interfaces, we don't look outside the
// implementation.
ObjCMethodDecl *ObjCImplDecl::getInstanceMethod(Selector Sel) const {
for (instmeth_iterator I = instmeth_begin(), E = instmeth_end(); I != E; ++I)
if ((*I)->getSelector() == Sel)
return *I;
return NULL;
ObjCMethodDecl *ObjCImplDecl::getInstanceMethod(ASTContext &Context,
Selector Sel) 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(Context, Sel);
Meth != MethEnd; ++Meth) {
ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(*Meth);
if (MD && MD->isInstanceMethod())
return MD;
}
return 0;
}
// getClassMethod - This method returns an instance method by looking in
// the class implementation. Unlike interfaces, we don't look outside the
// implementation.
ObjCMethodDecl *ObjCImplDecl::getClassMethod(Selector Sel) const {
for (classmeth_iterator I = classmeth_begin(), E = classmeth_end();
I != E; ++I)
if ((*I)->getSelector() == Sel)
return *I;
return NULL;
ObjCMethodDecl *ObjCImplDecl::getClassMethod(ASTContext &Context,
Selector Sel) 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(Context, Sel);
Meth != MethEnd; ++Meth) {
ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(*Meth);
if (MD && MD->isClassMethod())
return MD;
}
return 0;
}
//===----------------------------------------------------------------------===//

Просмотреть файл

@ -147,8 +147,8 @@ void clang::CheckObjCDealloc(ObjCImplementationDecl* D,
ObjCMethodDecl* MD = 0;
// Scan the instance methods for "dealloc".
for (ObjCImplementationDecl::instmeth_iterator I = D->instmeth_begin(),
E = D->instmeth_end(); I!=E; ++I) {
for (ObjCImplementationDecl::instmeth_iterator I = D->instmeth_begin(Ctx),
E = D->instmeth_end(Ctx); I!=E; ++I) {
if ((*I)->getSelector() == S) {
MD = *I;
@ -198,8 +198,8 @@ void clang::CheckObjCDealloc(ObjCImplementationDecl* D,
// Scan for missing and extra releases of ivars used by implementations
// of synthesized properties
for (ObjCImplementationDecl::propimpl_iterator I = D->propimpl_begin(),
E = D->propimpl_end(); I!=E; ++I) {
for (ObjCImplementationDecl::propimpl_iterator I = D->propimpl_begin(Ctx),
E = D->propimpl_end(Ctx); I!=E; ++I) {
// We can only check the synthesized properties
if((*I)->getPropertyImplementation() != ObjCPropertyImplDecl::Synthesize)

Просмотреть файл

@ -79,13 +79,15 @@ void clang::CheckObjCInstMethSignature(ObjCImplementationDecl* ID,
if (!C)
return;
ASTContext& Ctx = BR.getContext();
// Build a DenseMap of the methods for quick querying.
typedef llvm::DenseMap<Selector,ObjCMethodDecl*> MapTy;
MapTy IMeths;
unsigned NumMethods = 0;
for (ObjCImplementationDecl::instmeth_iterator I=ID->instmeth_begin(),
E=ID->instmeth_end(); I!=E; ++I) {
for (ObjCImplementationDecl::instmeth_iterator I=ID->instmeth_begin(Ctx),
E=ID->instmeth_end(Ctx); I!=E; ++I) {
ObjCMethodDecl* M = *I;
IMeths[M->getSelector()] = M;
@ -94,8 +96,6 @@ void clang::CheckObjCInstMethSignature(ObjCImplementationDecl* ID,
// Now recurse the class hierarchy chain looking for methods with the
// same signatures.
ASTContext& Ctx = BR.getContext();
while (C && NumMethods) {
for (ObjCInterfaceDecl::instmeth_iterator I=C->instmeth_begin(Ctx),
E=C->instmeth_end(Ctx); I!=E; ++I) {

Просмотреть файл

@ -61,7 +61,8 @@ void clang::CheckObjCUnusedIvar(ObjCImplementationDecl* D, BugReporter& BR) {
IvarUsageMap M;
ASTContext &Ctx = BR.getContext();
// Iterate over the ivars.
for (ObjCInterfaceDecl::ivar_iterator I=ID->ivar_begin(), E=ID->ivar_end();
I!=E; ++I) {
@ -83,14 +84,14 @@ void clang::CheckObjCUnusedIvar(ObjCImplementationDecl* D, BugReporter& BR) {
return;
// Now scan the methods for accesses.
for (ObjCImplementationDecl::instmeth_iterator I = D->instmeth_begin(),
E = D->instmeth_end(); I!=E; ++I)
Scan(M, (*I)->getBody(BR.getContext()));
for (ObjCImplementationDecl::instmeth_iterator I = D->instmeth_begin(Ctx),
E = D->instmeth_end(Ctx); I!=E; ++I)
Scan(M, (*I)->getBody(Ctx));
// Scan for @synthesized property methods that act as setters/getters
// to an ivar.
for (ObjCImplementationDecl::propimpl_iterator I = D->propimpl_begin(),
E = D->propimpl_end(); I!=E; ++I)
for (ObjCImplementationDecl::propimpl_iterator I = D->propimpl_begin(Ctx),
E = D->propimpl_end(Ctx); I!=E; ++I)
Scan(M, *I);
// Find ivars that are unused.

Просмотреть файл

@ -671,8 +671,10 @@ void CGObjCGNU::GenerateCategory(const ObjCCategoryImplDecl *OCD) {
// Collect information about instance methods
llvm::SmallVector<Selector, 16> InstanceMethodSels;
llvm::SmallVector<llvm::Constant*, 16> InstanceMethodTypes;
for (ObjCCategoryImplDecl::instmeth_iterator iter = OCD->instmeth_begin(),
endIter = OCD->instmeth_end() ; iter != endIter ; iter++) {
for (ObjCCategoryImplDecl::instmeth_iterator
iter = OCD->instmeth_begin(CGM.getContext()),
endIter = OCD->instmeth_end(CGM.getContext());
iter != endIter ; iter++) {
InstanceMethodSels.push_back((*iter)->getSelector());
std::string TypeStr;
CGM.getContext().getObjCEncodingForMethodDecl(*iter,TypeStr);
@ -682,8 +684,10 @@ void CGObjCGNU::GenerateCategory(const ObjCCategoryImplDecl *OCD) {
// Collect information about class methods
llvm::SmallVector<Selector, 16> ClassMethodSels;
llvm::SmallVector<llvm::Constant*, 16> ClassMethodTypes;
for (ObjCCategoryImplDecl::classmeth_iterator iter = OCD->classmeth_begin(),
endIter = OCD->classmeth_end() ; iter != endIter ; iter++) {
for (ObjCCategoryImplDecl::classmeth_iterator
iter = OCD->classmeth_begin(CGM.getContext()),
endIter = OCD->classmeth_end(CGM.getContext());
iter != endIter ; iter++) {
ClassMethodSels.push_back((*iter)->getSelector());
std::string TypeStr;
CGM.getContext().getObjCEncodingForMethodDecl(*iter,TypeStr);
@ -761,8 +765,10 @@ void CGObjCGNU::GenerateClass(const ObjCImplementationDecl *OID) {
// Collect information about instance methods
llvm::SmallVector<Selector, 16> InstanceMethodSels;
llvm::SmallVector<llvm::Constant*, 16> InstanceMethodTypes;
for (ObjCImplementationDecl::instmeth_iterator iter = OID->instmeth_begin(),
endIter = OID->instmeth_end() ; iter != endIter ; iter++) {
for (ObjCImplementationDecl::instmeth_iterator
iter = OID->instmeth_begin(CGM.getContext()),
endIter = OID->instmeth_end(CGM.getContext());
iter != endIter ; iter++) {
InstanceMethodSels.push_back((*iter)->getSelector());
std::string TypeStr;
Context.getObjCEncodingForMethodDecl((*iter),TypeStr);
@ -772,8 +778,10 @@ void CGObjCGNU::GenerateClass(const ObjCImplementationDecl *OID) {
// Collect information about class methods
llvm::SmallVector<Selector, 16> ClassMethodSels;
llvm::SmallVector<llvm::Constant*, 16> ClassMethodTypes;
for (ObjCImplementationDecl::classmeth_iterator iter = OID->classmeth_begin(),
endIter = OID->classmeth_end() ; iter != endIter ; iter++) {
for (ObjCImplementationDecl::classmeth_iterator
iter = OID->classmeth_begin(CGM.getContext()),
endIter = OID->classmeth_end(CGM.getContext());
iter != endIter ; iter++) {
ClassMethodSels.push_back((*iter)->getSelector());
std::string TypeStr;
Context.getObjCEncodingForMethodDecl((*iter),TypeStr);

Просмотреть файл

@ -1764,13 +1764,15 @@ void CGObjCMac::GenerateCategory(const ObjCCategoryImplDecl *OCD) {
OCD->getNameAsString());
std::vector<llvm::Constant*> InstanceMethods, ClassMethods;
for (ObjCCategoryImplDecl::instmeth_iterator i = OCD->instmeth_begin(),
e = OCD->instmeth_end(); i != e; ++i) {
for (ObjCCategoryImplDecl::instmeth_iterator
i = OCD->instmeth_begin(CGM.getContext()),
e = OCD->instmeth_end(CGM.getContext()); i != e; ++i) {
// Instance methods should always be defined.
InstanceMethods.push_back(GetMethodConstant(*i));
}
for (ObjCCategoryImplDecl::classmeth_iterator i = OCD->classmeth_begin(),
e = OCD->classmeth_end(); i != e; ++i) {
for (ObjCCategoryImplDecl::classmeth_iterator
i = OCD->classmeth_begin(CGM.getContext()),
e = OCD->classmeth_end(CGM.getContext()); i != e; ++i) {
// Class methods should always be defined.
ClassMethods.push_back(GetMethodConstant(*i));
}
@ -1865,19 +1867,22 @@ void CGObjCMac::GenerateClass(const ObjCImplementationDecl *ID) {
Flags |= eClassFlags_Hidden;
std::vector<llvm::Constant*> InstanceMethods, ClassMethods;
for (ObjCImplementationDecl::instmeth_iterator i = ID->instmeth_begin(),
e = ID->instmeth_end(); i != e; ++i) {
for (ObjCImplementationDecl::instmeth_iterator
i = ID->instmeth_begin(CGM.getContext()),
e = ID->instmeth_end(CGM.getContext()); i != e; ++i) {
// Instance methods should always be defined.
InstanceMethods.push_back(GetMethodConstant(*i));
}
for (ObjCImplementationDecl::classmeth_iterator i = ID->classmeth_begin(),
e = ID->classmeth_end(); i != e; ++i) {
for (ObjCImplementationDecl::classmeth_iterator
i = ID->classmeth_begin(CGM.getContext()),
e = ID->classmeth_end(CGM.getContext()); i != e; ++i) {
// Class methods should always be defined.
ClassMethods.push_back(GetMethodConstant(*i));
}
for (ObjCImplementationDecl::propimpl_iterator i = ID->propimpl_begin(),
e = ID->propimpl_end(); i != e; ++i) {
for (ObjCImplementationDecl::propimpl_iterator
i = ID->propimpl_begin(CGM.getContext()),
e = ID->propimpl_end(CGM.getContext()); i != e; ++i) {
ObjCPropertyImplDecl *PID = *i;
if (PID->getPropertyImplementation() == ObjCPropertyImplDecl::Synthesize) {
@ -4169,20 +4174,23 @@ llvm::GlobalVariable * CGObjCNonFragileABIMac::BuildClassRoTInitializer(
std::string MethodListName("\01l_OBJC_$_");
if (flags & CLS_META) {
MethodListName += "CLASS_METHODS_" + ID->getNameAsString();
for (ObjCImplementationDecl::classmeth_iterator i = ID->classmeth_begin(),
e = ID->classmeth_end(); i != e; ++i) {
for (ObjCImplementationDecl::classmeth_iterator
i = ID->classmeth_begin(CGM.getContext()),
e = ID->classmeth_end(CGM.getContext()); i != e; ++i) {
// Class methods should always be defined.
Methods.push_back(GetMethodConstant(*i));
}
} else {
MethodListName += "INSTANCE_METHODS_" + ID->getNameAsString();
for (ObjCImplementationDecl::instmeth_iterator i = ID->instmeth_begin(),
e = ID->instmeth_end(); i != e; ++i) {
for (ObjCImplementationDecl::instmeth_iterator
i = ID->instmeth_begin(CGM.getContext()),
e = ID->instmeth_end(CGM.getContext()); i != e; ++i) {
// Instance methods should always be defined.
Methods.push_back(GetMethodConstant(*i));
}
for (ObjCImplementationDecl::propimpl_iterator i = ID->propimpl_begin(),
e = ID->propimpl_end(); i != e; ++i) {
for (ObjCImplementationDecl::propimpl_iterator
i = ID->propimpl_begin(CGM.getContext()),
e = ID->propimpl_end(CGM.getContext()); i != e; ++i) {
ObjCPropertyImplDecl *PID = *i;
if (PID->getPropertyImplementation() == ObjCPropertyImplDecl::Synthesize){
@ -4466,8 +4474,9 @@ void CGObjCNonFragileABIMac::GenerateCategory(const ObjCCategoryImplDecl *OCD)
MethodListName += "INSTANCE_METHODS_" + Interface->getNameAsString() +
"_$_" + OCD->getNameAsString();
for (ObjCCategoryImplDecl::instmeth_iterator i = OCD->instmeth_begin(),
e = OCD->instmeth_end(); i != e; ++i) {
for (ObjCCategoryImplDecl::instmeth_iterator
i = OCD->instmeth_begin(CGM.getContext()),
e = OCD->instmeth_end(CGM.getContext()); i != e; ++i) {
// Instance methods should always be defined.
Methods.push_back(GetMethodConstant(*i));
}
@ -4480,8 +4489,9 @@ void CGObjCNonFragileABIMac::GenerateCategory(const ObjCCategoryImplDecl *OCD)
MethodListName += "CLASS_METHODS_" + Interface->getNameAsString() + "_$_" +
OCD->getNameAsString();
Methods.clear();
for (ObjCCategoryImplDecl::classmeth_iterator i = OCD->classmeth_begin(),
e = OCD->classmeth_end(); i != e; ++i) {
for (ObjCCategoryImplDecl::classmeth_iterator
i = OCD->classmeth_begin(CGM.getContext()),
e = OCD->classmeth_end(CGM.getContext()); i != e; ++i) {
// Class methods should always be defined.
Methods.push_back(GetMethodConstant(*i));
}

Просмотреть файл

@ -1292,8 +1292,9 @@ llvm::Constant *CodeGenModule::GetAddrOfConstantCString(const std::string &str,
/// properties for an implementation.
void CodeGenModule::EmitObjCPropertyImplementations(const
ObjCImplementationDecl *D) {
for (ObjCImplementationDecl::propimpl_iterator i = D->propimpl_begin(),
e = D->propimpl_end(); i != e; ++i) {
for (ObjCImplementationDecl::propimpl_iterator
i = D->propimpl_begin(getContext()),
e = D->propimpl_end(getContext()); i != e; ++i) {
ObjCPropertyImplDecl *PID = *i;
// Dynamic is just for type-checking.
@ -1305,11 +1306,11 @@ void CodeGenModule::EmitObjCPropertyImplementations(const
// we want, that just indicates if the decl came from a
// property. What we want to know is if the method is defined in
// this implementation.
if (!D->getInstanceMethod(PD->getGetterName()))
if (!D->getInstanceMethod(getContext(), PD->getGetterName()))
CodeGenFunction(*this).GenerateObjCGetter(
const_cast<ObjCImplementationDecl *>(D), PID);
if (!PD->isReadOnly() &&
!D->getInstanceMethod(PD->getSetterName()))
!D->getInstanceMethod(getContext(), PD->getSetterName()))
CodeGenFunction(*this).GenerateObjCSetter(
const_cast<ObjCImplementationDecl *>(D), PID);
}

Просмотреть файл

@ -824,19 +824,19 @@ bool Sema::isPropertyReadonly(ObjCPropertyDecl *PDecl,
if (ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(CurContext)) {
if (ObjCImplementationDecl *IMD =
dyn_cast<ObjCImplementationDecl>(OMD->getDeclContext())) {
if (IMD->getInstanceMethod(PDecl->getSetterName()))
if (IMD->getInstanceMethod(Context, PDecl->getSetterName()))
return false;
}
else if (ObjCCategoryImplDecl *CIMD =
dyn_cast<ObjCCategoryImplDecl>(OMD->getDeclContext())) {
if (CIMD->getInstanceMethod(PDecl->getSetterName()))
if (CIMD->getInstanceMethod(Context, PDecl->getSetterName()))
return false;
}
}
// Lastly, look through the implementation (if one is in scope).
if (ObjCImplementationDecl *ImpDecl =
ObjCImplementations[IDecl->getIdentifier()])
if (ImpDecl->getInstanceMethod(PDecl->getSetterName()))
if (ImpDecl->getInstanceMethod(Context, PDecl->getSetterName()))
return false;
// If all fails, look at the super class.
if (ObjCInterfaceDecl *SIDecl = IDecl->getSuperClass())
@ -906,8 +906,9 @@ void Sema::ImplMethodsVsClassMethods(ObjCImplDecl* IMPDecl,
llvm::DenseSet<Selector> InsMap;
// Check and see if instance methods in class interface have been
// implemented in the implementation class.
for (ObjCImplementationDecl::instmeth_iterator I = IMPDecl->instmeth_begin(),
E = IMPDecl->instmeth_end(); I != E; ++I)
for (ObjCImplementationDecl::instmeth_iterator
I = IMPDecl->instmeth_begin(Context),
E = IMPDecl->instmeth_end(Context); I != E; ++I)
InsMap.insert((*I)->getSelector());
// Check and see if properties declared in the interface have either 1)
@ -921,8 +922,9 @@ void Sema::ImplMethodsVsClassMethods(ObjCImplDecl* IMPDecl,
continue;
ObjCPropertyImplDecl *PI = 0;
// Is there a matching propery synthesize/dynamic?
for (ObjCImplDecl::propimpl_iterator I = IMPDecl->propimpl_begin(),
EI = IMPDecl->propimpl_end(); I != EI; ++I)
for (ObjCImplDecl::propimpl_iterator
I = IMPDecl->propimpl_begin(Context),
EI = IMPDecl->propimpl_end(Context); I != EI; ++I)
if ((*I)->getPropertyDecl() == Prop) {
PI = (*I);
break;
@ -954,7 +956,7 @@ void Sema::ImplMethodsVsClassMethods(ObjCImplDecl* IMPDecl,
}
ObjCMethodDecl *ImpMethodDecl =
IMPDecl->getInstanceMethod((*I)->getSelector());
IMPDecl->getInstanceMethod(Context, (*I)->getSelector());
ObjCMethodDecl *IntfMethodDecl =
CDecl->getInstanceMethod(Context, (*I)->getSelector());
assert(IntfMethodDecl &&
@ -967,8 +969,9 @@ void Sema::ImplMethodsVsClassMethods(ObjCImplDecl* IMPDecl,
llvm::DenseSet<Selector> ClsMap;
// Check and see if class methods in class interface have been
// implemented in the implementation class.
for (ObjCImplementationDecl::classmeth_iterator I =IMPDecl->classmeth_begin(),
E = IMPDecl->classmeth_end(); I != E; ++I)
for (ObjCImplementationDecl::classmeth_iterator
I = IMPDecl->classmeth_begin(Context),
E = IMPDecl->classmeth_end(Context); I != E; ++I)
ClsMap.insert((*I)->getSelector());
for (ObjCInterfaceDecl::classmeth_iterator
@ -979,7 +982,7 @@ void Sema::ImplMethodsVsClassMethods(ObjCImplDecl* IMPDecl,
WarnUndefinedMethod(IMPDecl->getLocation(), *I, IncompleteImpl);
else {
ObjCMethodDecl *ImpMethodDecl =
IMPDecl->getClassMethod((*I)->getSelector());
IMPDecl->getClassMethod(Context, (*I)->getSelector());
ObjCMethodDecl *IntfMethodDecl =
CDecl->getClassMethod(Context, (*I)->getSelector());
WarnConflictingTypedMethods(ImpMethodDecl, IntfMethodDecl);
@ -1526,21 +1529,21 @@ Sema::DeclPtrTy Sema::ActOnMethodDeclaration(
if (ObjCImplementationDecl *ImpDecl =
dyn_cast<ObjCImplementationDecl>(ClassDecl)) {
if (MethodType == tok::minus) {
PrevMethod = ImpDecl->getInstanceMethod(Sel);
ImpDecl->addInstanceMethod(ObjCMethod);
PrevMethod = ImpDecl->getInstanceMethod(Context, Sel);
ImpDecl->addInstanceMethod(Context, ObjCMethod);
} else {
PrevMethod = ImpDecl->getClassMethod(Sel);
ImpDecl->addClassMethod(ObjCMethod);
PrevMethod = ImpDecl->getClassMethod(Context, Sel);
ImpDecl->addClassMethod(Context, ObjCMethod);
}
}
else if (ObjCCategoryImplDecl *CatImpDecl =
dyn_cast<ObjCCategoryImplDecl>(ClassDecl)) {
if (MethodType == tok::minus) {
PrevMethod = CatImpDecl->getInstanceMethod(Sel);
CatImpDecl->addInstanceMethod(ObjCMethod);
PrevMethod = CatImpDecl->getInstanceMethod(Context, Sel);
CatImpDecl->addInstanceMethod(Context, ObjCMethod);
} else {
PrevMethod = CatImpDecl->getClassMethod(Sel);
CatImpDecl->addClassMethod(ObjCMethod);
PrevMethod = CatImpDecl->getClassMethod(Context, Sel);
CatImpDecl->addClassMethod(Context, ObjCMethod);
}
}
if (PrevMethod) {
@ -1898,28 +1901,28 @@ Sema::DeclPtrTy Sema::ActOnPropertyImplDecl(SourceLocation AtLoc,
ObjCPropertyImplDecl::Synthesize
: ObjCPropertyImplDecl::Dynamic),
Ivar);
CurContext->addDecl(Context, PIDecl);
if (IC) {
if (Synthesize)
if (ObjCPropertyImplDecl *PPIDecl =
IC->FindPropertyImplIvarDecl(PropertyIvar)) {
IC->FindPropertyImplIvarDecl(Context, PropertyIvar)) {
Diag(PropertyLoc, diag::error_duplicate_ivar_use)
<< PropertyId << PPIDecl->getPropertyDecl()->getIdentifier()
<< PropertyIvar;
Diag(PPIDecl->getLocation(), diag::note_previous_use);
}
if (ObjCPropertyImplDecl *PPIDecl = IC->FindPropertyImplDecl(PropertyId)) {
if (ObjCPropertyImplDecl *PPIDecl
= IC->FindPropertyImplDecl(Context, PropertyId)) {
Diag(PropertyLoc, diag::error_property_implemented) << PropertyId;
Diag(PPIDecl->getLocation(), diag::note_previous_declaration);
return DeclPtrTy();
}
IC->addPropertyImplementation(PIDecl);
IC->addPropertyImplementation(Context, PIDecl);
}
else {
if (Synthesize)
if (ObjCPropertyImplDecl *PPIDecl =
CatImplClass->FindPropertyImplIvarDecl(PropertyIvar)) {
CatImplClass->FindPropertyImplIvarDecl(Context, PropertyIvar)) {
Diag(PropertyLoc, diag::error_duplicate_ivar_use)
<< PropertyId << PPIDecl->getPropertyDecl()->getIdentifier()
<< PropertyIvar;
@ -1927,12 +1930,12 @@ Sema::DeclPtrTy Sema::ActOnPropertyImplDecl(SourceLocation AtLoc,
}
if (ObjCPropertyImplDecl *PPIDecl =
CatImplClass->FindPropertyImplDecl(PropertyId)) {
CatImplClass->FindPropertyImplDecl(Context, PropertyId)) {
Diag(PropertyLoc, diag::error_property_implemented) << PropertyId;
Diag(PPIDecl->getLocation(), diag::note_previous_declaration);
return DeclPtrTy();
}
CatImplClass->addPropertyImplementation(PIDecl);
CatImplClass->addPropertyImplementation(Context, PIDecl);
}
return DeclPtrTy::make(PIDecl);

Просмотреть файл

@ -1809,7 +1809,7 @@ ObjCMethodDecl *Sema::FindMethodInNestedImplementations(
ObjCMethodDecl *Method = 0;
if (ObjCImplementationDecl *ImpDecl =
Sema::ObjCImplementations[IFace->getIdentifier()])
Method = ImpDecl->getInstanceMethod(Sel);
Method = ImpDecl->getInstanceMethod(Context, Sel);
if (!Method && IFace->getSuperClass())
return FindMethodInNestedImplementations(IFace->getSuperClass(), Sel);
@ -2037,7 +2037,7 @@ Sema::ActOnMemberReferenceExpr(Scope *S, ExprArg Base, SourceLocation OpLoc,
if (!Getter) {
for (unsigned i = 0; i < ObjCCategoryImpls.size() && !Getter; i++) {
if (ObjCCategoryImpls[i]->getClassInterface() == IFace)
Getter = ObjCCategoryImpls[i]->getInstanceMethod(Sel);
Getter = ObjCCategoryImpls[i]->getInstanceMethod(Context, Sel);
}
}
if (Getter) {
@ -2060,7 +2060,7 @@ Sema::ActOnMemberReferenceExpr(Scope *S, ExprArg Base, SourceLocation OpLoc,
if (!Setter) {
for (unsigned i = 0; i < ObjCCategoryImpls.size() && !Setter; i++) {
if (ObjCCategoryImpls[i]->getClassInterface() == IFace)
Setter = ObjCCategoryImpls[i]->getInstanceMethod(SetterSel);
Setter = ObjCCategoryImpls[i]->getInstanceMethod(Context, SetterSel);
}
}
@ -2141,7 +2141,7 @@ Sema::ActOnMemberReferenceExpr(Scope *S, ExprArg Base, SourceLocation OpLoc,
if (!Setter) {
for (unsigned i = 0; i < ObjCCategoryImpls.size() && !Setter; i++) {
if (ObjCCategoryImpls[i]->getClassInterface() == IFace)
Setter = ObjCCategoryImpls[i]->getClassMethod(SetterSel);
Setter = ObjCCategoryImpls[i]->getClassMethod(Context, SetterSel);
}
}

Просмотреть файл

@ -224,13 +224,13 @@ ObjCMethodDecl *Sema::LookupPrivateClassMethod(Selector Sel,
while (ClassDecl && !Method) {
if (ObjCImplementationDecl *ImpDecl =
ObjCImplementations[ClassDecl->getIdentifier()])
Method = ImpDecl->getClassMethod(Sel);
Method = ImpDecl->getClassMethod(Context, Sel);
// Look through local category implementations associated with the class.
if (!Method) {
for (unsigned i = 0; i < ObjCCategoryImpls.size() && !Method; i++) {
if (ObjCCategoryImpls[i]->getClassInterface() == ClassDecl)
Method = ObjCCategoryImpls[i]->getClassMethod(Sel);
Method = ObjCCategoryImpls[i]->getClassMethod(Context, Sel);
}
}
@ -257,13 +257,13 @@ ObjCMethodDecl *Sema::LookupPrivateInstanceMethod(Selector Sel,
// If we have implementations in scope, check "private" methods.
if (ObjCImplementationDecl *ImpDecl =
ObjCImplementations[ClassDecl->getIdentifier()])
Method = ImpDecl->getInstanceMethod(Sel);
Method = ImpDecl->getInstanceMethod(Context, Sel);
// Look through local category implementations associated with the class.
if (!Method) {
for (unsigned i = 0; i < ObjCCategoryImpls.size() && !Method; i++) {
if (ObjCCategoryImpls[i]->getClassInterface() == ClassDecl)
Method = ObjCCategoryImpls[i]->getInstanceMethod(Sel);
Method = ObjCCategoryImpls[i]->getInstanceMethod(Context, Sel);
}
}
ClassDecl = ClassDecl->getSuperClass();
@ -290,7 +290,7 @@ Action::OwningExprResult Sema::ActOnClassPropertyRefExpr(
if (ObjCInterfaceDecl *ClassDecl = CurMeth->getClassInterface())
if (ObjCImplementationDecl *ImpDecl =
ObjCImplementations[ClassDecl->getIdentifier()])
Getter = ImpDecl->getClassMethod(Sel);
Getter = ImpDecl->getClassMethod(Context, Sel);
if (Getter) {
// FIXME: refactor/share with ActOnMemberReference().
@ -312,13 +312,13 @@ Action::OwningExprResult Sema::ActOnClassPropertyRefExpr(
if (ObjCInterfaceDecl *ClassDecl = CurMeth->getClassInterface())
if (ObjCImplementationDecl *ImpDecl =
ObjCImplementations[ClassDecl->getIdentifier()])
Setter = ImpDecl->getClassMethod(SetterSel);
Setter = ImpDecl->getClassMethod(Context, SetterSel);
}
// Look through local category implementations associated with the class.
if (!Setter) {
for (unsigned i = 0; i < ObjCCategoryImpls.size() && !Setter; i++) {
if (ObjCCategoryImpls[i]->getClassInterface() == IFace)
Setter = ObjCCategoryImpls[i]->getClassMethod(SetterSel);
Setter = ObjCCategoryImpls[i]->getClassMethod(Context, SetterSel);
}
}

Просмотреть файл

@ -346,8 +346,12 @@ void DeclPrinter::PrintObjCImplementationDecl(ObjCImplementationDecl *OID) {
else
Out << "@implementation " << I;
for (ObjCImplementationDecl::instmeth_iterator I = OID->instmeth_begin(),
E = OID->instmeth_end(); I != E; ++I) {
// FIXME: Don't use a NULL context
ASTContext *Context = 0;
for (ObjCImplementationDecl::instmeth_iterator
I = OID->instmeth_begin(*Context),
E = OID->instmeth_end(*Context);
I != E; ++I) {
ObjCMethodDecl *OMD = *I;
PrintObjCMethodDecl(OMD);
if (OMD->getBody()) {
@ -357,8 +361,10 @@ void DeclPrinter::PrintObjCImplementationDecl(ObjCImplementationDecl *OID) {
}
}
for (ObjCImplementationDecl::classmeth_iterator I = OID->classmeth_begin(),
E = OID->classmeth_end(); I != E; ++I) {
for (ObjCImplementationDecl::classmeth_iterator
I = OID->classmeth_begin(*Context),
E = OID->classmeth_end(*Context);
I != E; ++I) {
ObjCMethodDecl *OMD = *I;
PrintObjCMethodDecl(OMD);
if (OMD->getBody()) {
@ -368,8 +374,9 @@ void DeclPrinter::PrintObjCImplementationDecl(ObjCImplementationDecl *OID) {
}
}
for (ObjCImplementationDecl::propimpl_iterator I = OID->propimpl_begin(),
E = OID->propimpl_end(); I != E; ++I)
for (ObjCImplementationDecl::propimpl_iterator
I = OID->propimpl_begin(*Context),
E = OID->propimpl_end(*Context); I != E; ++I)
PrintObjCPropertyImplDecl(*I);
Out << "@end\n";
@ -441,8 +448,12 @@ void DeclPrinter::PrintObjCCategoryImplDecl(ObjCCategoryImplDecl *PID) {
Out << "@implementation "
<< PID->getClassInterface()->getNameAsString()
<< '(' << PID->getNameAsString() << ");\n";
for (ObjCCategoryImplDecl::propimpl_iterator I = PID->propimpl_begin(),
E = PID->propimpl_end(); I != E; ++I)
// FIXME: Don't use a NULL context here
ASTContext *Context = 0;
for (ObjCCategoryImplDecl::propimpl_iterator
I = PID->propimpl_begin(*Context),
E = PID->propimpl_end(*Context); I != E; ++I)
PrintObjCPropertyImplDecl(*I);
Out << "@end\n";
// FIXME: implement the rest...

Просмотреть файл

@ -286,9 +286,9 @@ namespace {
void RewriteObjCCategoryImplDecl(ObjCCategoryImplDecl *CDecl,
std::string &Result);
typedef ObjCCategoryImplDecl::instmeth_iterator instmeth_iterator;
void RewriteObjCMethodsMetaData(instmeth_iterator MethodBegin,
instmeth_iterator MethodEnd,
template<typename MethodIterator>
void RewriteObjCMethodsMetaData(MethodIterator MethodBegin,
MethodIterator MethodEnd,
bool IsInstanceMethod,
const char *prefix,
const char *ClassName,
@ -699,15 +699,6 @@ void RewriteObjC::RewritePropertyImplDecl(ObjCPropertyImplDecl *PID,
Getr += "; }";
InsertText(onePastSemiLoc, Getr.c_str(), Getr.size());
// Add the rewritten getter to trigger meta data generation. An alternate, and
// possibly cleaner approach is to hack RewriteObjCMethodsMetaData() to deal
// with properties explicitly. The following addInstanceMethod() required far
// less code change (and actually models what the rewriter is doing).
if (IMD)
IMD->addInstanceMethod(PD->getGetterMethodDecl());
else
CID->addInstanceMethod(PD->getGetterMethodDecl());
if (PD->isReadOnly())
return;
@ -723,12 +714,6 @@ void RewriteObjC::RewritePropertyImplDecl(ObjCPropertyImplDecl *PID,
Setr += PD->getNameAsCString();
Setr += "; }";
InsertText(onePastSemiLoc, Setr.c_str(), Setr.size());
// Add the rewritten setter to trigger meta data generation.
if (IMD)
IMD->addInstanceMethod(PD->getSetterMethodDecl());
else
CID->addInstanceMethod(PD->getSetterMethodDecl());
}
void RewriteObjC::RewriteForwardClassDecl(ObjCClassDecl *ClassDecl) {
@ -988,8 +973,9 @@ void RewriteObjC::RewriteImplementationDecl(Decl *OID) {
InsertText(CID->getLocStart(), "// ", 3);
for (ObjCCategoryImplDecl::instmeth_iterator
I = IMD ? IMD->instmeth_begin() : CID->instmeth_begin(),
E = IMD ? IMD->instmeth_end() : CID->instmeth_end(); I != E; ++I) {
I = IMD ? IMD->instmeth_begin(*Context) : CID->instmeth_begin(*Context),
E = IMD ? IMD->instmeth_end(*Context) : CID->instmeth_end(*Context);
I != E; ++I) {
std::string ResultStr;
ObjCMethodDecl *OMD = *I;
RewriteObjCMethodDecl(OMD, ResultStr);
@ -1003,8 +989,9 @@ void RewriteObjC::RewriteImplementationDecl(Decl *OID) {
}
for (ObjCCategoryImplDecl::classmeth_iterator
I = IMD ? IMD->classmeth_begin() : CID->classmeth_begin(),
E = IMD ? IMD->classmeth_end() : CID->classmeth_end(); I != E; ++I) {
I = IMD ? IMD->classmeth_begin(*Context) : CID->classmeth_begin(*Context),
E = IMD ? IMD->classmeth_end(*Context) : CID->classmeth_end(*Context);
I != E; ++I) {
std::string ResultStr;
ObjCMethodDecl *OMD = *I;
RewriteObjCMethodDecl(OMD, ResultStr);
@ -1017,8 +1004,9 @@ void RewriteObjC::RewriteImplementationDecl(Decl *OID) {
ResultStr.c_str(), ResultStr.size());
}
for (ObjCCategoryImplDecl::propimpl_iterator
I = IMD ? IMD->propimpl_begin() : CID->propimpl_begin(),
E = IMD ? IMD->propimpl_end() : CID->propimpl_end(); I != E; ++I) {
I = IMD ? IMD->propimpl_begin(*Context) : CID->propimpl_begin(*Context),
E = IMD ? IMD->propimpl_end(*Context) : CID->propimpl_end(*Context);
I != E; ++I) {
RewritePropertyImplDecl(*I, IMD, CID);
}
@ -2785,8 +2773,9 @@ void RewriteObjC::SynthesizeObjCInternalStruct(ObjCInterfaceDecl *CDecl,
// RewriteObjCMethodsMetaData - Rewrite methods metadata for instance or
/// class methods.
void RewriteObjC::RewriteObjCMethodsMetaData(instmeth_iterator MethodBegin,
instmeth_iterator MethodEnd,
template<typename MethodIterator>
void RewriteObjC::RewriteObjCMethodsMetaData(MethodIterator MethodBegin,
MethodIterator MethodEnd,
bool IsInstanceMethod,
const char *prefix,
const char *ClassName,
@ -2818,11 +2807,12 @@ void RewriteObjC::RewriteObjCMethodsMetaData(instmeth_iterator MethodBegin,
struct _objc_method method_list[];
}
*/
unsigned NumMethods = std::distance(MethodBegin, MethodEnd);
Result += "\nstatic struct {\n";
Result += "\tstruct _objc_method_list *next_method;\n";
Result += "\tint method_count;\n";
Result += "\tstruct _objc_method method_list[";
Result += utostr(MethodEnd-MethodBegin);
Result += utostr(NumMethods);
Result += "];\n} _OBJC_";
Result += prefix;
Result += IsInstanceMethod ? "INSTANCE" : "CLASS";
@ -2831,7 +2821,7 @@ void RewriteObjC::RewriteObjCMethodsMetaData(instmeth_iterator MethodBegin,
Result += " __attribute__ ((used, section (\"__OBJC, __";
Result += IsInstanceMethod ? "inst" : "cls";
Result += "_meth\")))= ";
Result += "{\n\t0, " + utostr(MethodEnd-MethodBegin) + "\n";
Result += "{\n\t0, " + utostr(NumMethods) + "\n";
Result += "\t,{{(SEL)\"";
Result += (*MethodBegin)->getSelector().getAsString().c_str();
@ -3057,14 +3047,38 @@ void RewriteObjC::RewriteObjCCategoryImplDecl(ObjCCategoryImplDecl *IDecl,
std::string FullCategoryName = ClassDecl->getNameAsString();
FullCategoryName += '_';
FullCategoryName += IDecl->getNameAsString();
// Build _objc_method_list for class's instance methods if needed
RewriteObjCMethodsMetaData(IDecl->instmeth_begin(), IDecl->instmeth_end(),
llvm::SmallVector<ObjCMethodDecl *, 32>
InstanceMethods(IDecl->instmeth_begin(*Context),
IDecl->instmeth_end(*Context));
// If any of our property implementations have associated getters or
// setters, produce metadata for them as well.
for (ObjCImplDecl::propimpl_iterator Prop = IDecl->propimpl_begin(*Context),
PropEnd = IDecl->propimpl_end(*Context);
Prop != PropEnd; ++Prop) {
if ((*Prop)->getPropertyImplementation() == ObjCPropertyImplDecl::Dynamic)
continue;
if (!(*Prop)->getPropertyIvarDecl())
continue;
ObjCPropertyDecl *PD = (*Prop)->getPropertyDecl();
if (!PD)
continue;
if (ObjCMethodDecl *Getter = PD->getGetterMethodDecl())
InstanceMethods.push_back(Getter);
if (PD->isReadOnly())
continue;
if (ObjCMethodDecl *Setter = PD->getSetterMethodDecl())
InstanceMethods.push_back(Setter);
}
RewriteObjCMethodsMetaData(InstanceMethods.begin(), InstanceMethods.end(),
true, "CATEGORY_", FullCategoryName.c_str(),
Result);
// Build _objc_method_list for class's class methods if needed
RewriteObjCMethodsMetaData(IDecl->classmeth_begin(), IDecl->classmeth_end(),
RewriteObjCMethodsMetaData(IDecl->classmeth_begin(*Context),
IDecl->classmeth_end(*Context),
false, "CATEGORY_", FullCategoryName.c_str(),
Result);
@ -3108,7 +3122,7 @@ void RewriteObjC::RewriteObjCCategoryImplDecl(ObjCCategoryImplDecl *IDecl,
Result += ClassDecl->getNameAsString();
Result += "\"\n";
if (IDecl->instmeth_begin() != IDecl->instmeth_end()) {
if (IDecl->instmeth_begin(*Context) != IDecl->instmeth_end(*Context)) {
Result += "\t, (struct _objc_method_list *)"
"&_OBJC_CATEGORY_INSTANCE_METHODS_";
Result += FullCategoryName;
@ -3116,7 +3130,7 @@ void RewriteObjC::RewriteObjCCategoryImplDecl(ObjCCategoryImplDecl *IDecl,
}
else
Result += "\t, 0\n";
if (IDecl->classmeth_begin() != IDecl->classmeth_end()) {
if (IDecl->classmeth_begin(*Context) != IDecl->classmeth_end(*Context)) {
Result += "\t, (struct _objc_method_list *)"
"&_OBJC_CATEGORY_CLASS_METHODS_";
Result += FullCategoryName;
@ -3241,11 +3255,35 @@ void RewriteObjC::RewriteObjCClassMetaData(ObjCImplementationDecl *IDecl,
}
// Build _objc_method_list for class's instance methods if needed
RewriteObjCMethodsMetaData(IDecl->instmeth_begin(), IDecl->instmeth_end(),
llvm::SmallVector<ObjCMethodDecl *, 32>
InstanceMethods(IDecl->instmeth_begin(*Context),
IDecl->instmeth_end(*Context));
// If any of our property implementations have associated getters or
// setters, produce metadata for them as well.
for (ObjCImplDecl::propimpl_iterator Prop = IDecl->propimpl_begin(*Context),
PropEnd = IDecl->propimpl_end(*Context);
Prop != PropEnd; ++Prop) {
if ((*Prop)->getPropertyImplementation() == ObjCPropertyImplDecl::Dynamic)
continue;
if (!(*Prop)->getPropertyIvarDecl())
continue;
ObjCPropertyDecl *PD = (*Prop)->getPropertyDecl();
if (!PD)
continue;
if (ObjCMethodDecl *Getter = PD->getGetterMethodDecl())
InstanceMethods.push_back(Getter);
if (PD->isReadOnly())
continue;
if (ObjCMethodDecl *Setter = PD->getSetterMethodDecl())
InstanceMethods.push_back(Setter);
}
RewriteObjCMethodsMetaData(InstanceMethods.begin(), InstanceMethods.end(),
true, "", IDecl->getNameAsCString(), Result);
// Build _objc_method_list for class's class methods if needed
RewriteObjCMethodsMetaData(IDecl->classmeth_begin(), IDecl->classmeth_end(),
RewriteObjCMethodsMetaData(IDecl->classmeth_begin(*Context),
IDecl->classmeth_end(*Context),
false, "", IDecl->getNameAsCString(), Result);
// Protocols referenced in class declaration?
@ -3319,7 +3357,7 @@ void RewriteObjC::RewriteObjCClassMetaData(ObjCImplementationDecl *IDecl,
// Set 'ivars' field for root class to 0. ObjC1 runtime does not use it.
// 'info' field is initialized to CLS_META(2) for metaclass
Result += ", 0,2, sizeof(struct _objc_class), 0";
if (IDecl->classmeth_begin() != IDecl->classmeth_end()) {
if (IDecl->classmeth_begin(*Context) != IDecl->classmeth_end(*Context)) {
Result += "\n\t, (struct _objc_method_list *)&_OBJC_CLASS_METHODS_";
Result += IDecl->getNameAsString();
Result += "\n";
@ -3372,7 +3410,7 @@ void RewriteObjC::RewriteObjCClassMetaData(ObjCImplementationDecl *IDecl,
}
else
Result += ",0";
if (IDecl->instmeth_begin() != IDecl->instmeth_end()) {
if (IDecl->instmeth_begin(*Context) != IDecl->instmeth_end(*Context)) {
Result += ", (struct _objc_method_list *)&_OBJC_INSTANCE_METHODS_";
Result += CDecl->getNameAsString();
Result += ", 0\n\t";