]> granicus.if.org Git - clang/commitdiff
Eliminate the three SmallVectors in ObjCImplDecl (for instance
authorDouglas Gregor <dgregor@apple.com>
Thu, 23 Apr 2009 01:02:12 +0000 (01:02 +0000)
committerDouglas Gregor <dgregor@apple.com>
Thu, 23 Apr 2009 01:02:12 +0000 (01:02 +0000)
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

14 files changed:
include/clang/AST/DeclObjC.h
lib/AST/ASTContext.cpp
lib/AST/DeclObjC.cpp
lib/Analysis/CheckObjCDealloc.cpp
lib/Analysis/CheckObjCInstMethSignature.cpp
lib/Analysis/CheckObjCUnusedIVars.cpp
lib/CodeGen/CGObjCGNU.cpp
lib/CodeGen/CGObjCMac.cpp
lib/CodeGen/CodeGenModule.cpp
lib/Sema/SemaDeclObjC.cpp
lib/Sema/SemaExpr.cpp
lib/Sema/SemaExprObjC.cpp
tools/clang-cc/ASTConsumers.cpp
tools/clang-cc/RewriteObjC.cpp

index a3b72d3ff11ffdf8c2ccbbf1b60fc7e7c15066cd..6e32215b30480d2368becc9d01c7d4fe9c7e4d3f 100644 (file)
@@ -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; }
index a855ecf6b306d2982c0b4d031153a8e60950ccd7..3895b134f4686089d6a7e1198a7fc701f84484be 100644 (file)
@@ -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) {
index 1e05eb614148fe3fadb4c645d85523cb19fdd3fc..3bffbf54ac505b1a0d2bcdfcabf49128fb05695a 100644 (file)
@@ -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;
 }
 
 //===----------------------------------------------------------------------===//
index 0d6e7e46a0b74618f9235b3666daccfb25110044..f50d7a19c4209e1d4078d1d3c579e442fb8a90c9 100644 (file)
@@ -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)
index 97e77cc50dae6972307bd5ac44bf2f1f0f36d417..9fec7c1dc1115b98cdedbf2a7974d39103309815 100644 (file)
@@ -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) {
index 57fad8d86b652c2d031193904b4a981c304cf5a7..7979f9c942e695c5d2be6a40924846f3ab1e5f56 100644 (file)
@@ -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.
index 2cf73b64832ba6190b93557583ecc54c6419935b..98102ae9cd3b6caa04aa6d87905d125d8578a3fc 100644 (file)
@@ -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);
index d8ffbbe0de46c44d18ccc9e1b8587ce21eff6767..cf15d2e62c557ac98da34b05321d661297288b80 100644 (file)
@@ -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));
   }
index 0247b693faffb72b9c2442551ef473534f270844..c07eac993bee6e96a338a698a38efbc168707d4c 100644 (file)
@@ -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);
     }
index 2874f27cd3b3658b63a25911933550bb920f449c..c65b1402be32b4d3a9723b2c9db514c4857f2f06 100644 (file)
@@ -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);
index 81bac6631cec31dbcaeb34cdf12221842ed4280c..8490672f4bfe28a35538999bb965616d9542ccdb 100644 (file)
@@ -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);
         }
       }
 
index 0c1f1448028b7b2f18d7b813aa4a21daad83b8ee..23f6f94dc06399c647bdf86640e8d97951b5c2b0 100644 (file)
@@ -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);
     }
   }
 
index b0f06fad24455b077c017a63be14b2a4e0a1066c..7595c2a0fad5d2a6ff468fde9bb7fbd5f733aec1 100644 (file)
@@ -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...
index 842b63010f4df1e3964a90c6f30839be27d84e60..f31e5ccf5f9e0e520e0b73725359144fc4b4e256 100644 (file)
@@ -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";