diff options
Diffstat (limited to 'clang')
-rw-r--r-- | clang/include/clang/AST/DeclObjC.h | 84 | ||||
-rw-r--r-- | clang/lib/AST/ASTContext.cpp | 6 | ||||
-rw-r--r-- | clang/lib/AST/DeclObjC.cpp | 63 | ||||
-rw-r--r-- | clang/lib/Analysis/CheckObjCDealloc.cpp | 8 | ||||
-rw-r--r-- | clang/lib/Analysis/CheckObjCInstMethSignature.cpp | 8 | ||||
-rw-r--r-- | clang/lib/Analysis/CheckObjCUnusedIVars.cpp | 13 | ||||
-rw-r--r-- | clang/lib/CodeGen/CGObjCGNU.cpp | 24 | ||||
-rw-r--r-- | clang/lib/CodeGen/CGObjCMac.cpp | 50 | ||||
-rw-r--r-- | clang/lib/CodeGen/CodeGenModule.cpp | 9 | ||||
-rw-r--r-- | clang/lib/Sema/SemaDeclObjC.cpp | 55 | ||||
-rw-r--r-- | clang/lib/Sema/SemaExpr.cpp | 8 | ||||
-rw-r--r-- | clang/lib/Sema/SemaExprObjC.cpp | 14 | ||||
-rw-r--r-- | clang/tools/clang-cc/ASTConsumers.cpp | 27 | ||||
-rw-r--r-- | clang/tools/clang-cc/RewriteObjC.cpp | 112 |
14 files changed, 297 insertions, 184 deletions
diff --git a/clang/include/clang/AST/DeclObjC.h b/clang/include/clang/AST/DeclObjC.h index a3b72d3ff11..6e32215b304 100644 --- a/clang/include/clang/AST/DeclObjC.h +++ b/clang/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/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp index a855ecf6b30..3895b134f46 100644 --- a/clang/lib/AST/ASTContext.cpp +++ b/clang/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/clang/lib/AST/DeclObjC.cpp b/clang/lib/AST/DeclObjC.cpp index 1e05eb61414..3bffbf54ac5 100644 --- a/clang/lib/AST/DeclObjC.cpp +++ b/clang/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/clang/lib/Analysis/CheckObjCDealloc.cpp b/clang/lib/Analysis/CheckObjCDealloc.cpp index 0d6e7e46a0b..f50d7a19c42 100644 --- a/clang/lib/Analysis/CheckObjCDealloc.cpp +++ b/clang/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/clang/lib/Analysis/CheckObjCInstMethSignature.cpp b/clang/lib/Analysis/CheckObjCInstMethSignature.cpp index 97e77cc50da..9fec7c1dc11 100644 --- a/clang/lib/Analysis/CheckObjCInstMethSignature.cpp +++ b/clang/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/clang/lib/Analysis/CheckObjCUnusedIVars.cpp b/clang/lib/Analysis/CheckObjCUnusedIVars.cpp index 57fad8d86b6..7979f9c942e 100644 --- a/clang/lib/Analysis/CheckObjCUnusedIVars.cpp +++ b/clang/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/clang/lib/CodeGen/CGObjCGNU.cpp b/clang/lib/CodeGen/CGObjCGNU.cpp index 2cf73b64832..98102ae9cd3 100644 --- a/clang/lib/CodeGen/CGObjCGNU.cpp +++ b/clang/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/clang/lib/CodeGen/CGObjCMac.cpp b/clang/lib/CodeGen/CGObjCMac.cpp index d8ffbbe0de4..cf15d2e62c5 100644 --- a/clang/lib/CodeGen/CGObjCMac.cpp +++ b/clang/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/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp index 0247b693faf..c07eac993be 100644 --- a/clang/lib/CodeGen/CodeGenModule.cpp +++ b/clang/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/clang/lib/Sema/SemaDeclObjC.cpp b/clang/lib/Sema/SemaDeclObjC.cpp index 2874f27cd3b..c65b1402be3 100644 --- a/clang/lib/Sema/SemaDeclObjC.cpp +++ b/clang/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/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index 81bac6631ce..8490672f4bf 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/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/clang/lib/Sema/SemaExprObjC.cpp b/clang/lib/Sema/SemaExprObjC.cpp index 0c1f1448028..23f6f94dc06 100644 --- a/clang/lib/Sema/SemaExprObjC.cpp +++ b/clang/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/clang/tools/clang-cc/ASTConsumers.cpp b/clang/tools/clang-cc/ASTConsumers.cpp index b0f06fad244..7595c2a0fad 100644 --- a/clang/tools/clang-cc/ASTConsumers.cpp +++ b/clang/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/clang/tools/clang-cc/RewriteObjC.cpp b/clang/tools/clang-cc/RewriteObjC.cpp index 842b63010f4..f31e5ccf5f9 100644 --- a/clang/tools/clang-cc/RewriteObjC.cpp +++ b/clang/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"; |