summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDouglas Gregor <dgregor@apple.com>2009-04-23 01:02:12 +0000
committerDouglas Gregor <dgregor@apple.com>2009-04-23 01:02:12 +0000
commit653f1b1bf293a9bd96fd4dd6372e779cc7af1597 (patch)
tree8f4f4bbb5f2d6fa627550d8d8c94d5ec5e059b39
parent70e5a14c6076d63833c62d1d6d628c26309897c1 (diff)
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
-rw-r--r--include/clang/AST/DeclObjC.h84
-rw-r--r--lib/AST/ASTContext.cpp6
-rw-r--r--lib/AST/DeclObjC.cpp63
-rw-r--r--lib/Analysis/CheckObjCDealloc.cpp8
-rw-r--r--lib/Analysis/CheckObjCInstMethSignature.cpp8
-rw-r--r--lib/Analysis/CheckObjCUnusedIVars.cpp13
-rw-r--r--lib/CodeGen/CGObjCGNU.cpp24
-rw-r--r--lib/CodeGen/CGObjCMac.cpp50
-rw-r--r--lib/CodeGen/CodeGenModule.cpp9
-rw-r--r--lib/Sema/SemaDeclObjC.cpp55
-rw-r--r--lib/Sema/SemaExpr.cpp8
-rw-r--r--lib/Sema/SemaExprObjC.cpp14
-rw-r--r--tools/clang-cc/ASTConsumers.cpp27
-rw-r--r--tools/clang-cc/RewriteObjC.cpp112
14 files changed, 297 insertions, 184 deletions
diff --git a/include/clang/AST/DeclObjC.h b/include/clang/AST/DeclObjC.h
index a3b72d3ff1..6e32215b30 100644
--- a/include/clang/AST/DeclObjC.h
+++ b/include/clang/AST/DeclObjC.h
@@ -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(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);
+ void addClassMethod(ASTContext &Context, ObjCMethodDecl *method) {
+ method->setLexicalDeclContext(this);
+ addDecl(Context, method);
}
- void addPropertyImplementation(ObjCPropertyImplDecl *property) {
- PropertyImplementations.push_back(property);
+ // Get the local instance/class method declared in this interface.
+ 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);
}
- ObjCPropertyImplDecl *FindPropertyImplDecl(IdentifierInfo *propertyId) const;
- ObjCPropertyImplDecl *FindPropertyImplIvarDecl(IdentifierInfo *ivarId) const;
+ void addPropertyImplementation(ASTContext &Context,
+ ObjCPropertyImplDecl *property);
- 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; }
diff --git a/lib/AST/ASTContext.cpp b/lib/AST/ASTContext.cpp
index a855ecf6b3..3895b134f4 100644
--- a/lib/AST/ASTContext.cpp
+++ b/lib/AST/ASTContext.cpp
@@ -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) {
diff --git a/lib/AST/DeclObjC.cpp b/lib/AST/DeclObjC.cpp
index 1e05eb6141..3bffbf54ac 100644
--- a/lib/AST/DeclObjC.cpp
+++ b/lib/AST/DeclObjC.cpp
@@ -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;
}
//===----------------------------------------------------------------------===//
diff --git a/lib/Analysis/CheckObjCDealloc.cpp b/lib/Analysis/CheckObjCDealloc.cpp
index 0d6e7e46a0..f50d7a19c4 100644
--- a/lib/Analysis/CheckObjCDealloc.cpp
+++ b/lib/Analysis/CheckObjCDealloc.cpp
@@ -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)
diff --git a/lib/Analysis/CheckObjCInstMethSignature.cpp b/lib/Analysis/CheckObjCInstMethSignature.cpp
index 97e77cc50d..9fec7c1dc1 100644
--- a/lib/Analysis/CheckObjCInstMethSignature.cpp
+++ b/lib/Analysis/CheckObjCInstMethSignature.cpp
@@ -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) {
diff --git a/lib/Analysis/CheckObjCUnusedIVars.cpp b/lib/Analysis/CheckObjCUnusedIVars.cpp
index 57fad8d86b..7979f9c942 100644
--- a/lib/Analysis/CheckObjCUnusedIVars.cpp
+++ b/lib/Analysis/CheckObjCUnusedIVars.cpp
@@ -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.
diff --git a/lib/CodeGen/CGObjCGNU.cpp b/lib/CodeGen/CGObjCGNU.cpp
index 2cf73b6483..98102ae9cd 100644
--- a/lib/CodeGen/CGObjCGNU.cpp
+++ b/lib/CodeGen/CGObjCGNU.cpp
@@ -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);
diff --git a/lib/CodeGen/CGObjCMac.cpp b/lib/CodeGen/CGObjCMac.cpp
index d8ffbbe0de..cf15d2e62c 100644
--- a/lib/CodeGen/CGObjCMac.cpp
+++ b/lib/CodeGen/CGObjCMac.cpp
@@ -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));
}
diff --git a/lib/CodeGen/CodeGenModule.cpp b/lib/CodeGen/CodeGenModule.cpp
index 0247b693fa..c07eac993b 100644
--- a/lib/CodeGen/CodeGenModule.cpp
+++ b/lib/CodeGen/CodeGenModule.cpp
@@ -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);
}
diff --git a/lib/Sema/SemaDeclObjC.cpp b/lib/Sema/SemaDeclObjC.cpp
index 2874f27cd3..c65b1402be 100644
--- a/lib/Sema/SemaDeclObjC.cpp
+++ b/lib/Sema/SemaDeclObjC.cpp
@@ -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);
diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp
index 81bac6631c..8490672f4b 100644
--- a/lib/Sema/SemaExpr.cpp
+++ b/lib/Sema/SemaExpr.cpp
@@ -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);
}
}
diff --git a/lib/Sema/SemaExprObjC.cpp b/lib/Sema/SemaExprObjC.cpp
index 0c1f144802..23f6f94dc0 100644
--- a/lib/Sema/SemaExprObjC.cpp
+++ b/lib/Sema/SemaExprObjC.cpp
@@ -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);
}
}
diff --git a/tools/clang-cc/ASTConsumers.cpp b/tools/clang-cc/ASTConsumers.cpp
index b0f06fad24..7595c2a0fa 100644
--- a/tools/clang-cc/ASTConsumers.cpp
+++ b/tools/clang-cc/ASTConsumers.cpp
@@ -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...
diff --git a/tools/clang-cc/RewriteObjC.cpp b/tools/clang-cc/RewriteObjC.cpp
index 842b63010f..f31e5ccf5f 100644
--- a/tools/clang-cc/RewriteObjC.cpp
+++ b/tools/clang-cc/RewriteObjC.cpp
@@ -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";