[cfe-commits] r69849 - in /cfe/trunk: 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

Douglas Gregor dgregor at apple.com
Wed Apr 22 18:02:12 PDT 2009


Author: dgregor
Date: Wed Apr 22 20:02:12 2009
New Revision: 69849

URL: http://llvm.org/viewvc/llvm-project?rev=69849&view=rev
Log:
Eliminate the three SmallVectors in ObjCImplDecl (for instance
methods, class methods, and property implementations) and instead
place all of these entities into the DeclContext.

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


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

Modified: cfe/trunk/include/clang/AST/DeclObjC.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/DeclObjC.h?rev=69849&r1=69848&r2=69849&view=diff

==============================================================================
--- cfe/trunk/include/clang/AST/DeclObjC.h (original)
+++ cfe/trunk/include/clang/AST/DeclObjC.h Wed Apr 22 20:02:12 2009
@@ -796,15 +796,6 @@
   /// 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 @@
   const ObjCInterfaceDecl *getClassInterface() const { return ClassInterface; }
   ObjCInterfaceDecl *getClassInterface() { return ClassInterface; }
   
-  void addInstanceMethod(ObjCMethodDecl *method) {
-    InstanceMethods.push_back(method);
+  void addInstanceMethod(ASTContext &Context, ObjCMethodDecl *method) { 
+    method->setLexicalDeclContext(this);
+    addDecl(Context, method); 
+  }
+  void addClassMethod(ASTContext &Context, ObjCMethodDecl *method) { 
+    method->setLexicalDeclContext(this);
+    addDecl(Context, method); 
   }
-  void addClassMethod(ObjCMethodDecl *method) {
-    ClassMethods.push_back(method);
-  }   
   
   // Get the local instance/class method declared in this interface.
-  ObjCMethodDecl *getInstanceMethod(Selector Sel) const;
-  ObjCMethodDecl *getClassMethod(Selector Sel) const;
-  ObjCMethodDecl *getMethod(Selector Sel, bool isInstance) const {
-    return isInstance ? getInstanceMethod(Sel) : getClassMethod(Sel);
-  }
-  
-  void addPropertyImplementation(ObjCPropertyImplDecl *property) {
-    PropertyImplementations.push_back(property);
+  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; }

Modified: cfe/trunk/lib/AST/ASTContext.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTContext.cpp?rev=69849&r1=69848&r2=69849&view=diff

==============================================================================
--- cfe/trunk/lib/AST/ASTContext.cpp (original)
+++ cfe/trunk/lib/AST/ASTContext.cpp Wed Apr 22 20:02:12 2009
@@ -2142,7 +2142,8 @@
     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 @@
     } 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) {

Modified: cfe/trunk/lib/AST/DeclObjC.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/DeclObjC.cpp?rev=69849&r1=69848&r2=69849&view=diff

==============================================================================
--- cfe/trunk/lib/AST/DeclObjC.cpp (original)
+++ cfe/trunk/lib/AST/DeclObjC.cpp Wed Apr 22 20:02:12 2009
@@ -541,13 +541,20 @@
 }
 
 
+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 @@
 /// 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 @@
 // 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;
 }
 
 //===----------------------------------------------------------------------===//

Modified: cfe/trunk/lib/Analysis/CheckObjCDealloc.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/CheckObjCDealloc.cpp?rev=69849&r1=69848&r2=69849&view=diff

==============================================================================
--- cfe/trunk/lib/Analysis/CheckObjCDealloc.cpp (original)
+++ cfe/trunk/lib/Analysis/CheckObjCDealloc.cpp Wed Apr 22 20:02:12 2009
@@ -147,8 +147,8 @@
   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 @@
   
   // 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)

Modified: cfe/trunk/lib/Analysis/CheckObjCInstMethSignature.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/CheckObjCInstMethSignature.cpp?rev=69849&r1=69848&r2=69849&view=diff

==============================================================================
--- cfe/trunk/lib/Analysis/CheckObjCInstMethSignature.cpp (original)
+++ cfe/trunk/lib/Analysis/CheckObjCInstMethSignature.cpp Wed Apr 22 20:02:12 2009
@@ -79,13 +79,15 @@
   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 @@
 
   // 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) {

Modified: cfe/trunk/lib/Analysis/CheckObjCUnusedIVars.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/CheckObjCUnusedIVars.cpp?rev=69849&r1=69848&r2=69849&view=diff

==============================================================================
--- cfe/trunk/lib/Analysis/CheckObjCUnusedIVars.cpp (original)
+++ cfe/trunk/lib/Analysis/CheckObjCUnusedIVars.cpp Wed Apr 22 20:02:12 2009
@@ -61,7 +61,8 @@
   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 @@
     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.

Modified: cfe/trunk/lib/CodeGen/CGObjCGNU.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGObjCGNU.cpp?rev=69849&r1=69848&r2=69849&view=diff

==============================================================================
--- cfe/trunk/lib/CodeGen/CGObjCGNU.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGObjCGNU.cpp Wed Apr 22 20:02:12 2009
@@ -671,8 +671,10 @@
   // 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 @@
   // 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 @@
   // 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 @@
   // 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);

Modified: cfe/trunk/lib/CodeGen/CGObjCMac.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGObjCMac.cpp?rev=69849&r1=69848&r2=69849&view=diff

==============================================================================
--- cfe/trunk/lib/CodeGen/CGObjCMac.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGObjCMac.cpp Wed Apr 22 20:02:12 2009
@@ -1764,13 +1764,15 @@
                       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 @@
     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 @@
   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 @@
   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 @@
   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));
   }

Modified: cfe/trunk/lib/CodeGen/CodeGenModule.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenModule.cpp?rev=69849&r1=69848&r2=69849&view=diff

==============================================================================
--- cfe/trunk/lib/CodeGen/CodeGenModule.cpp (original)
+++ cfe/trunk/lib/CodeGen/CodeGenModule.cpp Wed Apr 22 20:02:12 2009
@@ -1292,8 +1292,9 @@
 /// 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 @@
       // 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);
     }

Modified: cfe/trunk/lib/Sema/SemaDeclObjC.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclObjC.cpp?rev=69849&r1=69848&r2=69849&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/SemaDeclObjC.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDeclObjC.cpp Wed Apr 22 20:02:12 2009
@@ -824,19 +824,19 @@
   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 @@
   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 @@
           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 @@
     }
     
     ObjCMethodDecl *ImpMethodDecl = 
-      IMPDecl->getInstanceMethod((*I)->getSelector());
+      IMPDecl->getInstanceMethod(Context, (*I)->getSelector());
     ObjCMethodDecl *IntfMethodDecl = 
       CDecl->getInstanceMethod(Context, (*I)->getSelector());
     assert(IntfMethodDecl && 
@@ -967,8 +969,9 @@
   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 @@
       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 @@
   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 @@
                                   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 @@
       }
     
     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);

Modified: cfe/trunk/lib/Sema/SemaExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=69849&r1=69848&r2=69849&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/SemaExpr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExpr.cpp Wed Apr 22 20:02:12 2009
@@ -1809,7 +1809,7 @@
   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 @@
     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 @@
     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 @@
       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);
         }
       }
 

Modified: cfe/trunk/lib/Sema/SemaExprObjC.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExprObjC.cpp?rev=69849&r1=69848&r2=69849&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/SemaExprObjC.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExprObjC.cpp Wed Apr 22 20:02:12 2009
@@ -224,13 +224,13 @@
   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 @@
     // 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 @@
       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 @@
       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);
     }
   }
 

Modified: cfe/trunk/tools/clang-cc/ASTConsumers.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/clang-cc/ASTConsumers.cpp?rev=69849&r1=69848&r2=69849&view=diff

==============================================================================
--- cfe/trunk/tools/clang-cc/ASTConsumers.cpp (original)
+++ cfe/trunk/tools/clang-cc/ASTConsumers.cpp Wed Apr 22 20:02:12 2009
@@ -346,8 +346,12 @@
   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 @@
     }
   }
   
-  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 @@
     }
   }
   
-  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 @@
   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...

Modified: cfe/trunk/tools/clang-cc/RewriteObjC.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/clang-cc/RewriteObjC.cpp?rev=69849&r1=69848&r2=69849&view=diff

==============================================================================
--- cfe/trunk/tools/clang-cc/RewriteObjC.cpp (original)
+++ cfe/trunk/tools/clang-cc/RewriteObjC.cpp Wed Apr 22 20:02:12 2009
@@ -286,9 +286,9 @@
     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 @@
   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 @@
   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 @@
     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 @@
   }
   
   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 @@
                 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 @@
 
 // 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 @@
    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 @@
   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 @@
   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 @@
   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 @@
   }
   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 @@
   }
   
   // 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 @@
   // 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 @@
   }
   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"; 





More information about the cfe-commits mailing list