[cfe-commits] r61929 - in /cfe/trunk: Driver/RewriteObjC.cpp include/clang/AST/DeclBase.h include/clang/AST/DeclObjC.h lib/AST/DeclBase.cpp lib/AST/DeclCXX.cpp lib/AST/DeclObjC.cpp lib/CodeGen/CGObjCGNU.cpp lib/Sema/IdentifierResolver.cpp lib/Sema/Sema.cpp lib/Sema/Sema.h lib/Sema/SemaCXXScopeSpec.cpp lib/Sema/SemaDecl.cpp lib/Sema/SemaDeclCXX.cpp lib/Sema/SemaDeclObjC.cpp lib/Sema/SemaExprCXX.cpp lib/Sema/SemaOverload.cpp

Steve Naroff snaroff at apple.com
Thu Jan 8 09:28:15 PST 2009


Author: snaroff
Date: Thu Jan  8 11:28:14 2009
New Revision: 61929

URL: http://llvm.org/viewvc/llvm-project?rev=61929&view=rev
Log:
This is a large/messy diff that unifies the ObjC AST's with DeclContext.

- ObjCContainerDecl's (ObjCInterfaceDecl/ObjCCategoryDecl/ObjCProtocolDecl), ObjCCategoryImpl, & ObjCImplementation are all DeclContexts.
- ObjCMethodDecl is now a ScopedDecl (so it can play nicely with DeclContext).
- ObjCContainerDecl now does iteration/lookup using DeclContext infrastructure (no more linear search:-)
- Removed ASTContext argument to DeclContext::lookup(). It wasn't being used and complicated it's use from an ObjC AST perspective.
- Added Sema::ProcessPropertyDecl() and removed Sema::diagnosePropertySetterGetterMismatch().
- Simplified Sema::ActOnAtEnd() considerably. Still more work to do.
- Fixed an incorrect casting assumption in Sema::getCurFunctionOrMethodDecl(), now that ObjCMethodDecl is a ScopedDecl.
- Removed addPropertyMethods from ObjCInterfaceDecl/ObjCCategoryDecl/ObjCProtocolDecl.

This passes all the tests on my machine. Since many of the changes are central to the way ObjC finds it's methods, I expect some fallout (and there are still a handful of FIXME's). Nevertheless, this should be a step in the right direction.

Modified:
    cfe/trunk/Driver/RewriteObjC.cpp
    cfe/trunk/include/clang/AST/DeclBase.h
    cfe/trunk/include/clang/AST/DeclObjC.h
    cfe/trunk/lib/AST/DeclBase.cpp
    cfe/trunk/lib/AST/DeclCXX.cpp
    cfe/trunk/lib/AST/DeclObjC.cpp
    cfe/trunk/lib/CodeGen/CGObjCGNU.cpp
    cfe/trunk/lib/Sema/IdentifierResolver.cpp
    cfe/trunk/lib/Sema/Sema.cpp
    cfe/trunk/lib/Sema/Sema.h
    cfe/trunk/lib/Sema/SemaCXXScopeSpec.cpp
    cfe/trunk/lib/Sema/SemaDecl.cpp
    cfe/trunk/lib/Sema/SemaDeclCXX.cpp
    cfe/trunk/lib/Sema/SemaDeclObjC.cpp
    cfe/trunk/lib/Sema/SemaExprCXX.cpp
    cfe/trunk/lib/Sema/SemaOverload.cpp

Modified: cfe/trunk/Driver/RewriteObjC.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/Driver/RewriteObjC.cpp?rev=61929&r1=61928&r2=61929&view=diff

==============================================================================
--- cfe/trunk/Driver/RewriteObjC.cpp (original)
+++ cfe/trunk/Driver/RewriteObjC.cpp Thu Jan  8 11:28:14 2009
@@ -881,9 +881,8 @@
   NameStr += OMD->getClassInterface()->getNameAsString();
   NameStr += "_";
   
-  NamedDecl *MethodContext = OMD->getMethodContext();
   if (ObjCCategoryImplDecl *CID = 
-      dyn_cast<ObjCCategoryImplDecl>(MethodContext)) {
+      dyn_cast<ObjCCategoryImplDecl>(OMD->getMethodContext())) {
     NameStr += CID->getNameAsString();
     NameStr += "_";
   }

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

==============================================================================
--- cfe/trunk/include/clang/AST/DeclBase.h (original)
+++ cfe/trunk/include/clang/AST/DeclBase.h Thu Jan  8 11:28:14 2009
@@ -31,6 +31,10 @@
 class EnumDecl;
 class ObjCMethodDecl;
 class ObjCInterfaceDecl;
+class ObjCCategoryDecl;
+class ObjCProtocolDecl;
+class ObjCImplementationDecl;
+class ObjCCategoryImplDecl;
 class LinkageSpecDecl;
 class BlockDecl;
 class DeclarationName;
@@ -49,14 +53,13 @@
     // Decl
          TranslationUnit,  // [DeclContext]
     //   NamedDecl
-    //     ObjCContainerDecl
+    //     ObjCContainerDecl // [DeclContext]
              ObjCCategory,
              ObjCProtocol,
-             ObjCInterface,  // [DeclContext]
+             ObjCInterface,
            OverloadedFunction,
-           ObjCCategoryImpl,
-           ObjCImplementation,
-           ObjCMethod,  // [DeclContext]
+           ObjCCategoryImpl,  // [DeclContext]
+           ObjCImplementation, // [DeclContext]
            ObjCProperty,
     //     ScopedDecl
              Field,
@@ -84,6 +87,7 @@
                    OriginalParmVar,
   	         NonTypeTemplateParm,
              LinkageSpec, // [DeclContext]
+             ObjCMethod,  // [DeclContext]
            ObjCCompatibleAlias,
            ObjCClass,
            ObjCForwardProtocol,
@@ -95,7 +99,7 @@
     // of the class, to allow efficient classof.
     NamedFirst     = OverloadedFunction , NamedLast     = NonTypeTemplateParm,
     FieldFirst     = Field        , FieldLast     = ObjCAtDefsField,
-    ScopedFirst    = Field        , ScopedLast    = LinkageSpec,
+    ScopedFirst    = Field        , ScopedLast    = ObjCMethod,
     TypeFirst      = Typedef      , TypeLast      = TemplateTypeParm,
     TagFirst       = Enum         , TagLast       = CXXRecord,
     RecordFirst    = Record       , RecordLast    = CXXRecord,
@@ -329,6 +333,14 @@
         return static_cast<ObjCMethodDecl*>(const_cast<From*>(D));
       case Decl::ObjCInterface:
         return static_cast<ObjCInterfaceDecl*>(const_cast<From*>(D));
+      case Decl::ObjCCategory:
+        return static_cast<ObjCCategoryDecl*>(const_cast<From*>(D));
+      case Decl::ObjCProtocol:
+        return static_cast<ObjCProtocolDecl*>(const_cast<From*>(D));
+      case Decl::ObjCImplementation:
+        return static_cast<ObjCImplementationDecl*>(const_cast<From*>(D));
+      case Decl::ObjCCategoryImpl:
+        return static_cast<ObjCCategoryImplDecl*>(const_cast<From*>(D));
       case Decl::LinkageSpec:
         return static_cast<LinkageSpecDecl*>(const_cast<From*>(D));
       case Decl::Block:
@@ -434,7 +446,7 @@
   /// a different set of declarations. This routine returns the
   /// "primary" DeclContext structure, which will contain the
   /// information needed to perform name lookup into this context.
-  DeclContext *getPrimaryContext(ASTContext &Context);
+  DeclContext *getPrimaryContext();
 
   /// getLookupContext - Retrieve the innermost non-transparent
   /// context of this context, which corresponds to the innermost
@@ -481,7 +493,7 @@
   /// declaration into data structure for name lookup.
   void addDecl(ASTContext &Context, ScopedDecl *D, bool AllowLookup = true);
 
-  void buildLookup(ASTContext &Context, DeclContext *DCtx);
+  void buildLookup(DeclContext *DCtx);
 
   /// lookup_iterator - An iterator that provides access to the results
   /// of looking up a name within this context.
@@ -503,8 +515,8 @@
   /// declaration in the "tag" identifier namespace (e.g., values
   /// before types). Note that this routine will not look into parent
   /// contexts.
-  lookup_result lookup(ASTContext &Context, DeclarationName Name);
-  lookup_const_result lookup(ASTContext &Context, DeclarationName Name) const;
+  lookup_result lookup(DeclarationName Name);
+  lookup_const_result lookup(DeclarationName Name) const;
 
   /// insert - Insert the declaration D into this context. Up to two
   /// declarations with the same name can be inserted into a single
@@ -527,6 +539,10 @@
       case Decl::CXXRecord:
       case Decl::ObjCMethod:
       case Decl::ObjCInterface:
+      case Decl::ObjCCategory:
+      case Decl::ObjCProtocol:
+      case Decl::ObjCImplementation:
+      case Decl::ObjCCategoryImpl:
       case Decl::LinkageSpec:
       case Decl::Block:
         return true;
@@ -546,6 +562,10 @@
   static bool classof(const EnumDecl *D) { return true; }
   static bool classof(const ObjCMethodDecl *D) { return true; }
   static bool classof(const ObjCInterfaceDecl *D) { return true; }
+  static bool classof(const ObjCCategoryDecl *D) { return true; }
+  static bool classof(const ObjCProtocolDecl *D) { return true; }
+  static bool classof(const ObjCImplementationDecl *D) { return true; }
+  static bool classof(const ObjCCategoryImplDecl *D) { return true; }
   static bool classof(const LinkageSpecDecl *D) { return true; }
   static bool classof(const BlockDecl *D) { return true; }
 

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

==============================================================================
--- cfe/trunk/include/clang/AST/DeclObjC.h (original)
+++ cfe/trunk/include/clang/AST/DeclObjC.h Thu Jan  8 11:28:14 2009
@@ -93,7 +93,7 @@
 /// A selector represents a unique name for a method. The selector names for
 /// the above methods are setMenu:, menu, replaceSubview:with:, and defaultMenu.
 ///
-class ObjCMethodDecl : public NamedDecl, public DeclContext {
+class ObjCMethodDecl : public ScopedDecl, public DeclContext {
 public:
   enum ImplementationControl { None, Required, Optional };
 private:
@@ -115,7 +115,7 @@
   unsigned objcDeclQualifier : 6;
   
   // Context this method is declared in.
-  NamedDecl *MethodContext;
+  DeclContext *MethodContext;
   
   // Type of this method.
   QualType MethodDeclType;
@@ -140,17 +140,17 @@
   
   ObjCMethodDecl(SourceLocation beginLoc, SourceLocation endLoc,
                  Selector SelInfo, QualType T,
-                 Decl *contextDecl,
+                 DeclContext *contextDecl,
                  bool isInstance = true,
                  bool isVariadic = false,
                  bool isSynthesized = false,
                  ImplementationControl impControl = None)
-  : NamedDecl(ObjCMethod, beginLoc, SelInfo),
+  : ScopedDecl(ObjCMethod, contextDecl, beginLoc, SelInfo, 0),
     DeclContext(ObjCMethod),
     IsInstance(isInstance), IsVariadic(isVariadic),
     IsSynthesized(isSynthesized),
     DeclImplementation(impControl), objcDeclQualifier(OBJC_TQ_None),
-    MethodContext(static_cast<NamedDecl*>(contextDecl)),
+    MethodContext(contextDecl),
     MethodDeclType(T), 
     ParamInfo(0), NumMethodParams(0), 
     EndLoc(endLoc), Body(0), SelfDecl(0), CmdDecl(0) {}
@@ -165,7 +165,7 @@
   static ObjCMethodDecl *Create(ASTContext &C,
                                 SourceLocation beginLoc, 
                                 SourceLocation endLoc, Selector SelInfo,
-                                QualType T, Decl *contextDecl,
+                                QualType T, DeclContext *contextDecl,
                                 bool isInstance = true,
                                 bool isVariadic = false,
                                 bool isSynthesized = false,
@@ -183,7 +183,7 @@
     return SourceRange(getLocation(), EndLoc); 
   }
   
-  NamedDecl *getMethodContext() const { return MethodContext; }
+  DeclContext *getMethodContext() const { return MethodContext; }
   
   ObjCInterfaceDecl *getClassInterface();
   const ObjCInterfaceDecl *getClassInterface() const {
@@ -252,68 +252,177 @@
 
 /// ObjCContainerDecl - Represents a container for method declarations.
 /// Current sub-classes are ObjCInterfaceDecl, ObjCCategoryDecl, and
-/// ObjCProtocolDecl. FIXME: Use for ObjC implementation decls.
-/// STILL UNDER CONSTRUCTION...
+/// ObjCProtocolDecl. 
+/// FIXME: Use for ObjC implementation decls.
+/// FIXME: Consider properties.
+/// FIXME: It would be nice to reduce amount of "boilerplate" iterator code
+/// below. For now, the iterators are modeled after RecordDecl::field_iterator().
+/// If DeclContext ends up providing some support for creating more strongly 
+/// typed iterators, the code below should be reduced considerably.
 ///
-class ObjCContainerDecl : public NamedDecl {
-  /// instance methods
-  ObjCMethodDecl **InstanceMethods;  // Null if not defined
-  unsigned NumInstanceMethods;  // 0 if none.
-  
-  /// class methods
-  ObjCMethodDecl **ClassMethods;  // Null if not defined
-  unsigned NumClassMethods;  // 0 if none
-  
+class ObjCContainerDecl : public NamedDecl, public DeclContext {
   SourceLocation AtEndLoc; // marks the end of the method container.
 public:
 
   ObjCContainerDecl(Kind DK, SourceLocation L, IdentifierInfo *Id)
-    : NamedDecl(DK, L, Id),
-      InstanceMethods(0), NumInstanceMethods(0), 
-      ClassMethods(0), NumClassMethods(0) {}
+    : NamedDecl(DK, L, Id), DeclContext(DK) {}
 
   virtual ~ObjCContainerDecl();
     
-  typedef ObjCMethodDecl * const * instmeth_iterator;
-  instmeth_iterator instmeth_begin() const { return InstanceMethods; }
-  instmeth_iterator instmeth_end() const {
-    return InstanceMethods+NumInstanceMethods;
+  // Iterator access to instance/class methods.
+  class method_iterator {
+  protected:
+    /// Current - Current position within the sequence of declarations
+    /// in this record. 
+    DeclContext::decl_iterator Current;
+
+    /// End - Last position in the sequence of declarations in this
+    /// record.
+    DeclContext::decl_iterator End;
+
+    /// IsInstance - If true, we are iterating through instance methods.
+    /// If false, we are iteratring through class methods.
+    bool IsInstance;
+    
+    /// SkipToNextMethod - Advances the current position up to the next
+    /// ObjCMethodDecl.
+    void SkipToNextMethod() {
+      while (Current != End) {
+        ObjCMethodDecl *M = dyn_cast<ObjCMethodDecl>(*Current);
+        if (M && 
+            (IsInstance && M->isInstance() || !IsInstance && !M->isInstance()))
+          return;
+        ++Current;
+      }
+    }
+
+  public:
+    typedef ObjCMethodDecl const *    value_type;
+    typedef ObjCMethodDecl const *    reference;
+    typedef ObjCMethodDecl const *    pointer;
+    typedef std::ptrdiff_t            difference_type;
+    typedef std::forward_iterator_tag iterator_category;
+
+    method_iterator() : Current(), End(), IsInstance(true) { }
+
+    method_iterator(DeclContext::decl_iterator C, 
+                    DeclContext::decl_iterator E, bool I)
+      : Current(C), End(E), IsInstance(I) {
+      SkipToNextMethod();
+    }
+
+    reference operator*() const { return cast<ObjCMethodDecl>(*Current); }
+
+    pointer operator->() const { return cast<ObjCMethodDecl>(*Current); }
+
+    method_iterator& operator++() {
+      ++Current;
+      SkipToNextMethod();
+      return *this;
+    }
+
+    method_iterator operator++(int) {
+      method_iterator tmp(*this);
+      ++(*this);
+      return tmp;
+    }
+
+    friend bool
+    operator==(const method_iterator& x, const method_iterator& y) {
+      return x.Current == y.Current;
+    }
+
+    friend bool 
+    operator!=(const method_iterator& x, const method_iterator& y) {
+      return x.Current != y.Current;
+    }
+  };
+
+  class instmeth_iterator : public method_iterator {
+  public:
+    typedef ObjCMethodDecl*           value_type;
+    typedef ObjCMethodDecl*           reference;
+    typedef ObjCMethodDecl*           pointer;
+
+    instmeth_iterator() : method_iterator() { }
+
+    instmeth_iterator(DeclContext::decl_iterator C, DeclContext::decl_iterator E)
+      : method_iterator(C, E, true) { }    
+
+    reference operator*() const { return cast<ObjCMethodDecl>(*Current); }
+
+    pointer operator->() const { return cast<ObjCMethodDecl>(*Current); }
+
+    instmeth_iterator& operator++() {
+      ++Current;
+      SkipToNextMethod();
+      return *this;
+    }
+
+    instmeth_iterator operator++(int) {
+      instmeth_iterator tmp(*this);
+      ++(*this);
+      return tmp;
+    }
+  };
+
+  instmeth_iterator instmeth_begin() const {
+    return instmeth_iterator(decls_begin(), decls_end());
   }
-  
-  typedef ObjCMethodDecl * const * classmeth_iterator;
-  classmeth_iterator classmeth_begin() const { return ClassMethods; }
-  classmeth_iterator classmeth_end() const {
-    return ClassMethods+NumClassMethods;
+  instmeth_iterator instmeth_end() const {
+    return instmeth_iterator(decls_end(), decls_end());
   }
 
-  // Get the local instance method declared in this interface.
-  ObjCMethodDecl *getInstanceMethod(Selector Sel) const {
-    for (instmeth_iterator I = instmeth_begin(), E = instmeth_end(); 
-         I != E; ++I) {
-      if ((*I)->getSelector() == Sel)
-        return *I;
+  class classmeth_iterator : public method_iterator {
+  public:
+    typedef ObjCMethodDecl*           value_type;
+    typedef ObjCMethodDecl*           reference;
+    typedef ObjCMethodDecl*           pointer;
+
+    classmeth_iterator() : method_iterator() { }
+
+    classmeth_iterator(DeclContext::decl_iterator C, DeclContext::decl_iterator E)
+      : method_iterator(C, E, false) { }    
+
+    reference operator*() const { return cast<ObjCMethodDecl>(*Current); }
+
+    pointer operator->() const { return cast<ObjCMethodDecl>(*Current); }
+
+    classmeth_iterator& operator++() {
+      ++Current;
+      SkipToNextMethod();
+      return *this;
     }
-    return 0;
-  }
-  // Get the local class method declared in this interface.
-  ObjCMethodDecl *getClassMethod(Selector Sel) const {
-    for (classmeth_iterator I = classmeth_begin(), E = classmeth_end(); 
-         I != E; ++I) {
-      if ((*I)->getSelector() == Sel)
-        return *I;
+
+    classmeth_iterator operator++(int) {
+      classmeth_iterator tmp(*this);
+      ++(*this);
+      return tmp;
     }
-    return 0;
+  };
+  classmeth_iterator classmeth_begin() const {
+    return classmeth_iterator(decls_begin(), decls_end());
   }
+  classmeth_iterator classmeth_end() const {
+    return classmeth_iterator(decls_end(), decls_end());
+  }
+
+  // Get the local instance/class method declared in this interface.
+  ObjCMethodDecl *getInstanceMethod(Selector Sel) const;
+  ObjCMethodDecl *getClassMethod(Selector Sel) const;
   
-  void addMethods(ObjCMethodDecl **insMethods, unsigned numInsMembers,
-                  ObjCMethodDecl **clsMethods, unsigned numClsMembers,
-                  SourceLocation AtEndLoc);
-                  
-  unsigned getNumInstanceMethods() const { return NumInstanceMethods; }
-  unsigned getNumClassMethods() const { return NumClassMethods; }
+  // Get the number of instance/class methods.
+  unsigned getNumInstanceMethods() const;
+  unsigned getNumClassMethods() const;
   
   // Marks the end of the container.
   SourceLocation getAtEndLoc() const { return AtEndLoc; }
+  void setAtEndLoc(SourceLocation L) { AtEndLoc = L; }
+  
+  // This method synthesizes the getter/setter method for the property.
+  // FIXME: Shouldn't this be part of Sema?.
+  void getPropertyMethods(ASTContext &Context, ObjCPropertyDecl* Property,
+                          ObjCMethodDecl *& Getter, ObjCMethodDecl *&Setter);
 };
 
 /// ObjCInterfaceDecl - Represents an ObjC class declaration. For example:
@@ -337,7 +446,7 @@
 ///   Unlike C++, ObjC is a single-rooted class model. In Cocoa, classes
 ///   typically inherit from NSObject (an exception is NSProxy).
 ///
-class ObjCInterfaceDecl : public ObjCContainerDecl, public DeclContext {
+class ObjCInterfaceDecl : public ObjCContainerDecl {
   /// TypeForDecl - This indicates the Type object that represents this
   /// TypeDecl.  It is a cache maintained by ASTContext::getObjCInterfaceType
   Type *TypeForDecl;
@@ -369,7 +478,7 @@
 
   ObjCInterfaceDecl(SourceLocation atLoc, IdentifierInfo *Id,
                     SourceLocation CLoc, bool FD, bool isInternal)
-    : ObjCContainerDecl(ObjCInterface, atLoc, Id), DeclContext(ObjCInterface),
+    : ObjCContainerDecl(ObjCInterface, atLoc, Id),
       TypeForDecl(0), SuperClass(0),
       Ivars(0), NumIvars(0),
       CategoryList(0), PropertyDecl(0), NumPropertyDecl(0),
@@ -424,11 +533,6 @@
   
   void mergeProperties(ObjCPropertyDecl **Properties, unsigned NumProperties);
   
-  void addPropertyMethods(ASTContext &Context,
-                          ObjCPropertyDecl* Property,
-                          llvm::SmallVector<ObjCMethodDecl*, 32> &insMethods,
-                          llvm::DenseMap<Selector, const ObjCMethodDecl*> &InsMap);
-  
   typedef ObjCPropertyDecl * const * classprop_iterator;
   classprop_iterator classprop_begin() const { return PropertyDecl; }
   classprop_iterator classprop_end() const {
@@ -644,11 +748,6 @@
   
   void addProperties(ObjCPropertyDecl **Properties, unsigned NumProperties);
 
-  void addPropertyMethods(ASTContext &Context,
-                          ObjCPropertyDecl* Property,
-                          llvm::SmallVector<ObjCMethodDecl*, 32> &insMethods,
-                          llvm::DenseMap<Selector, const ObjCMethodDecl*> &InsMap);
-  
   typedef ObjCPropertyDecl * const * classprop_iterator;
   classprop_iterator classprop_begin() const { return PropertyDecl; }
   classprop_iterator classprop_end() const {
@@ -839,11 +938,6 @@
 
   void mergeProperties(ObjCPropertyDecl **Properties, unsigned NumProperties);
 
-  void addPropertyMethods(ASTContext &Context,
-                          ObjCPropertyDecl* Property,
-                          llvm::SmallVector<ObjCMethodDecl*, 32> &insMethods,
-                          llvm::DenseMap<Selector, const ObjCMethodDecl*> &InsMap);
-  
   ObjCPropertyDecl *FindPropertyDeclaration(IdentifierInfo *PropertyId) const;
   
   typedef ObjCPropertyDecl * const * classprop_iterator;
@@ -878,7 +972,7 @@
 ///  @dynamic p1,d1;
 /// @end
 ///
-class ObjCCategoryImplDecl : public NamedDecl {
+class ObjCCategoryImplDecl : public NamedDecl, public DeclContext {
   /// Class interface for this category implementation
   ObjCInterfaceDecl *ClassInterface;
 
@@ -895,7 +989,8 @@
 
   ObjCCategoryImplDecl(SourceLocation L, IdentifierInfo *Id,
                        ObjCInterfaceDecl *classInterface)
-    : NamedDecl(ObjCCategoryImpl, L, Id), ClassInterface(classInterface) {}
+    : NamedDecl(ObjCCategoryImpl, L, Id), DeclContext(ObjCCategoryImpl),
+      ClassInterface(classInterface) {}
 public:
   static ObjCCategoryImplDecl *Create(ASTContext &C,
                                       SourceLocation L, IdentifierInfo *Id,
@@ -974,7 +1069,7 @@
 /// the legacy semantics and allow developers to move private ivar declarations
 /// from the class interface to the class implementation (but I digress:-)
 ///
-class ObjCImplementationDecl : public NamedDecl {
+class ObjCImplementationDecl : public NamedDecl, public DeclContext {
   /// Class interface for this implementation
   ObjCInterfaceDecl *ClassInterface;
   
@@ -999,7 +1094,7 @@
   ObjCImplementationDecl(SourceLocation L, IdentifierInfo *Id,
                          ObjCInterfaceDecl *classInterface,
                          ObjCInterfaceDecl *superDecl)
-    : NamedDecl(ObjCImplementation, L, Id),
+    : NamedDecl(ObjCImplementation, L, Id), DeclContext(ObjCImplementation),
       ClassInterface(classInterface), SuperClass(superDecl),
       Ivars(0), NumIvars(0) {}
 public:  

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

==============================================================================
--- cfe/trunk/lib/AST/DeclBase.cpp (original)
+++ cfe/trunk/lib/AST/DeclBase.cpp Thu Jan  8 11:28:14 2009
@@ -419,7 +419,7 @@
   return false;
 }
 
-DeclContext *DeclContext::getPrimaryContext(ASTContext &Context) {
+DeclContext *DeclContext::getPrimaryContext() {
   switch (DeclKind) {
   case Decl::TranslationUnit:
   case Decl::LinkageSpec:
@@ -468,9 +468,15 @@
     return this;
 
   case Decl::ObjCInterface:
+  case Decl::ObjCProtocol:
+  case Decl::ObjCCategory:
     // FIXME: Can Objective-C interfaces be forward-declared?
     return this;
 
+  case Decl::ObjCImplementation:
+  case Decl::ObjCCategoryImpl:
+    return this;
+
   default:
     assert(DeclKind >= Decl::FunctionFirst && DeclKind <= Decl::FunctionLast &&
           "Unknown DeclContext kind");
@@ -486,6 +492,10 @@
   case Decl::CXXRecord:
   case Decl::ObjCMethod:
   case Decl::ObjCInterface:
+  case Decl::ObjCCategory:
+  case Decl::ObjCProtocol:
+  case Decl::ObjCImplementation:
+  case Decl::ObjCCategoryImpl:
   case Decl::LinkageSpec:
   case Decl::Block:
     // There is only one DeclContext for these entities.
@@ -511,7 +521,7 @@
 /// buildLookup - Build the lookup data structure with all of the
 /// declarations in DCtx (and any other contexts linked to it or
 /// transparent contexts nested within it).
-void DeclContext::buildLookup(ASTContext &Context, DeclContext *DCtx) {
+void DeclContext::buildLookup(DeclContext *DCtx) {
   for (; DCtx; DCtx = DCtx->getNextContext()) {
     for (decl_iterator D = DCtx->decls_begin(), DEnd = DCtx->decls_end(); 
          D != DEnd; ++D) {
@@ -522,22 +532,22 @@
       // add its members (recursively).
       if (DeclContext *InnerCtx = dyn_cast<DeclContext>(*D))
         if (InnerCtx->isTransparentContext())
-          buildLookup(Context, InnerCtx->getPrimaryContext(Context));
+          buildLookup(InnerCtx->getPrimaryContext());
     }
   }
 }
 
 DeclContext::lookup_result 
-DeclContext::lookup(ASTContext &Context, DeclarationName Name) {
-  DeclContext *PrimaryContext = getPrimaryContext(Context);
+DeclContext::lookup(DeclarationName Name) {
+  DeclContext *PrimaryContext = getPrimaryContext();
   if (PrimaryContext != this)
-    return PrimaryContext->lookup(Context, Name);
+    return PrimaryContext->lookup(Name);
 
   /// If there is no lookup data structure, build one now by walking
   /// all of the linked DeclContexts (in declaration order!) and
   /// inserting their values.
   if (LookupPtr.getPointer() == 0)
-    buildLookup(Context, this);
+    buildLookup(this);
 
   if (isLookupMap()) {
     StoredDeclsMap *Map = static_cast<StoredDeclsMap*>(LookupPtr.getPointer());
@@ -563,8 +573,8 @@
 }
 
 DeclContext::lookup_const_result 
-DeclContext::lookup(ASTContext &Context, DeclarationName Name) const {
-  return const_cast<DeclContext*>(this)->lookup(Context, Name);
+DeclContext::lookup(DeclarationName Name) const {
+  return const_cast<DeclContext*>(this)->lookup(Name);
 }
 
 const DeclContext *DeclContext::getLookupContext() const {
@@ -575,7 +585,7 @@
 }
 
 void DeclContext::insert(ASTContext &Context, ScopedDecl *D) {
-  DeclContext *PrimaryContext = getPrimaryContext(Context);
+  DeclContext *PrimaryContext = getPrimaryContext();
   if (PrimaryContext != this) {
     PrimaryContext->insert(Context, D);
     return;

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

==============================================================================
--- cfe/trunk/lib/AST/DeclCXX.cpp (original)
+++ cfe/trunk/lib/AST/DeclCXX.cpp Thu Jan  8 11:28:14 2009
@@ -98,7 +98,7 @@
                                            Context.getCanonicalType(ClassType));
   unsigned TypeQuals;
   DeclContext::lookup_const_iterator Con, ConEnd;
-  for (llvm::tie(Con, ConEnd) = this->lookup(Context, ConstructorName);
+  for (llvm::tie(Con, ConEnd) = this->lookup(ConstructorName);
        Con != ConEnd; ++Con) {
     if (cast<CXXConstructorDecl>(*Con)->isCopyConstructor(Context, TypeQuals) &&
         (TypeQuals & QualType::Const) != 0)
@@ -114,7 +114,7 @@
   DeclarationName OpName =Context.DeclarationNames.getCXXOperatorName(OO_Equal);
 
   DeclContext::lookup_const_iterator Op, OpEnd;
-  for (llvm::tie(Op, OpEnd) = this->lookup(Context, OpName);
+  for (llvm::tie(Op, OpEnd) = this->lookup(OpName);
        Op != OpEnd; ++Op) {
     // C++ [class.copy]p9:
     //   A user-declared copy assignment operator is a non-static non-template

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

==============================================================================
--- cfe/trunk/lib/AST/DeclObjC.cpp (original)
+++ cfe/trunk/lib/AST/DeclObjC.cpp Thu Jan  8 11:28:14 2009
@@ -24,7 +24,7 @@
                                        SourceLocation beginLoc, 
                                        SourceLocation endLoc,
                                        Selector SelInfo, QualType T,
-                                       Decl *contextDecl,
+                                       DeclContext *contextDecl,
                                        bool isInstance,
                                        bool isVariadic,
                                        bool isSynthesized,
@@ -61,8 +61,6 @@
 }
 
 ObjCContainerDecl::~ObjCContainerDecl() {
-  delete [] InstanceMethods;
-  delete [] ClassMethods;
 }
 
 ObjCInterfaceDecl::~ObjCInterfaceDecl() {
@@ -362,7 +360,7 @@
   assert(RecordForDecl && "lookupFieldDeclForIvar no storage for class");
   DeclarationName Member = ivar->getDeclName();
   DeclContext::lookup_result Lookup = (const_cast< RecordDecl *>(RecordForDecl))
-                                        ->lookup(Context, Member);
+                                        ->lookup(Member);
   assert((Lookup.first != Lookup.second) && "field decl not found");
   FieldDecl *MemberDecl = dyn_cast<FieldDecl>(*Lookup.first);
   assert(MemberDecl && "field decl not found");
@@ -382,27 +380,6 @@
   }
 }
 
-/// addMethods - Insert instance and methods declarations into
-/// ObjCInterfaceDecl's InsMethods and ClsMethods fields.
-///
-void ObjCContainerDecl::addMethods(ObjCMethodDecl **insMethods, 
-                                   unsigned numInsMembers,
-                                   ObjCMethodDecl **clsMethods,
-                                   unsigned numClsMembers,
-                                   SourceLocation endLoc) {
-  NumInstanceMethods = numInsMembers;
-  if (numInsMembers) {
-    InstanceMethods = new ObjCMethodDecl*[numInsMembers];
-    memcpy(InstanceMethods, insMethods, numInsMembers*sizeof(ObjCMethodDecl*));
-  }
-  NumClassMethods = numClsMembers;
-  if (numClsMembers) {
-    ClassMethods = new ObjCMethodDecl*[numClsMembers];
-    memcpy(ClassMethods, clsMethods, numClsMembers*sizeof(ObjCMethodDecl*));
-  }
-  AtEndLoc = endLoc;
-}
-
 /// addProperties - Insert property declaration AST nodes into
 /// ObjCInterfaceDecl's PropertyDecl field.
 ///
@@ -440,18 +417,45 @@
   }
 }
 
-static void 
-addPropertyMethods(Decl *D,
-                   ASTContext &Context,
-                   ObjCPropertyDecl *property,
-                   llvm::SmallVector<ObjCMethodDecl*, 32> &insMethods,
-                   llvm::DenseMap<Selector, const ObjCMethodDecl*> &InsMap) {
-  ObjCMethodDecl *GetterDecl, *SetterDecl = 0;
-  
-  GetterDecl = const_cast<ObjCMethodDecl*>(InsMap[property->getGetterName()]);
-  if (!property->isReadOnly())
-    SetterDecl = const_cast<ObjCMethodDecl*>(InsMap[property->getSetterName()]);
-  
+// Get the local instance method declared in this interface.
+// FIXME: handle overloading, instance & class methods can have the same name.
+ObjCMethodDecl *ObjCContainerDecl::getInstanceMethod(Selector Sel) const {
+  lookup_const_result MethodResult = lookup(Sel);
+  if (MethodResult.first)
+    return const_cast<ObjCMethodDecl*>(
+             dyn_cast<ObjCMethodDecl>(*MethodResult.first));
+  return 0;
+}
+
+// Get the local class method declared in this interface.
+ObjCMethodDecl *ObjCContainerDecl::getClassMethod(Selector Sel) const {
+  lookup_const_result MethodResult = lookup(Sel);
+  if (MethodResult.first)
+    return const_cast<ObjCMethodDecl*>(
+             dyn_cast<ObjCMethodDecl>(*MethodResult.first));
+  return 0;
+}
+
+unsigned ObjCContainerDecl::getNumInstanceMethods() const {
+  unsigned sum = 0;
+  for (instmeth_iterator I=instmeth_begin(), E=instmeth_end(); I != E; ++I)
+    sum++;
+  return sum;
+}
+unsigned ObjCContainerDecl::getNumClassMethods() const { 
+  unsigned sum = 0;
+  for (classmeth_iterator I=classmeth_begin(), E=classmeth_end(); I != E; ++I)
+    sum++;
+  return sum;
+}
+
+/// addPropertyMethods - Goes through list of properties declared in this class
+/// and builds setter/getter method declartions depending on the setter/getter
+/// attributes of the property.
+///
+void ObjCContainerDecl::getPropertyMethods(
+       ASTContext &Context, ObjCPropertyDecl *property,
+       ObjCMethodDecl *& GetterDecl, ObjCMethodDecl *&SetterDecl) {
   // FIXME: The synthesized property we set here is misleading. We
   // almost always synthesize these methods unless the user explicitly
   // provided prototypes (which is odd, but allowed). Sema should be
@@ -467,15 +471,12 @@
       ObjCMethodDecl::Create(Context, property->getLocation(), 
                              property->getLocation(), 
                              property->getGetterName(), 
-                             property->getType(),
-                             D,
+                             property->getType(), this,
                              true, false, true, 
                              (property->getPropertyImplementation() == 
                               ObjCPropertyDecl::Optional) ? 
                              ObjCMethodDecl::Optional : 
                              ObjCMethodDecl::Required);
-    insMethods.push_back(GetterDecl);
-    InsMap[property->getGetterName()] = GetterDecl;
   }
   else
     // A user declared getter will be synthesize when @synthesize of
@@ -496,15 +497,12 @@
       ObjCMethodDecl::Create(Context, property->getLocation(), 
                              property->getLocation(), 
                              property->getSetterName(), 
-                             Context.VoidTy,
-                             D,
+                             Context.VoidTy, this,
                              true, false, true,
                              (property->getPropertyImplementation() == 
                               ObjCPropertyDecl::Optional) ? 
                              ObjCMethodDecl::Optional : 
                              ObjCMethodDecl::Required);
-    insMethods.push_back(SetterDecl);
-    InsMap[property->getSetterName()] = SetterDecl;
     // Invent the arguments for the setter. We don't bother making a
     // nice name for the argument.
     ParmVarDecl *Argument = ParmVarDecl::Create(Context, 
@@ -523,30 +521,6 @@
   property->setSetterMethodDecl(SetterDecl);
 }
 
-/// addPropertyMethods - Goes through list of properties declared in this class
-/// and builds setter/getter method declartions depending on the setter/getter
-/// attributes of the property.
-///
-void ObjCInterfaceDecl::addPropertyMethods(
-       ASTContext &Context,
-       ObjCPropertyDecl *property,
-       llvm::SmallVector<ObjCMethodDecl*, 32> &insMethods,
-       llvm::DenseMap<Selector, const ObjCMethodDecl*> &InsMap) {
-  ::addPropertyMethods(this, Context, property, insMethods, InsMap);
-}
-
-/// addPropertyMethods - Goes through list of properties declared in this class
-/// and builds setter/getter method declartions depending on the setter/getter
-/// attributes of the property.
-///
-void ObjCCategoryDecl::addPropertyMethods(
-       ASTContext &Context,
-       ObjCPropertyDecl *property,
-       llvm::SmallVector<ObjCMethodDecl*, 32> &insMethods, 
-       llvm::DenseMap<Selector, const ObjCMethodDecl*> &InsMap) {
-  ::addPropertyMethods(this, Context, property, insMethods, InsMap);
-}
-
 /// mergeProperties - Adds properties to the end of list of current properties
 /// for this category.
 
@@ -572,18 +546,6 @@
   }
 }
 
-/// addPropertyMethods - Goes through list of properties declared in this class
-/// and builds setter/getter method declartions depending on the setter/getter
-/// attributes of the property.
-///
-void ObjCProtocolDecl::addPropertyMethods(
-       ASTContext &Context,
-       ObjCPropertyDecl *property,
-       llvm::SmallVector<ObjCMethodDecl*, 32> &insMethods,
-       llvm::DenseMap<Selector, const ObjCMethodDecl*> &InsMap) {
-  ::addPropertyMethods(this, Context, property, insMethods, InsMap);
-}
-
 /// addProperties - Insert property declaration AST nodes into
 /// ObjCProtocolDecl's PropertyDecl field.
 ///
@@ -850,9 +812,8 @@
   // Get length of this name.
   unsigned length = 3;  // _I_ or _C_
   length += getClassInterface()->getNameAsString().size()+1; // extra for _
-  NamedDecl *MethodContext = getMethodContext();
   if (ObjCCategoryImplDecl *CID = 
-      dyn_cast<ObjCCategoryImplDecl>(MethodContext))
+      dyn_cast<ObjCCategoryImplDecl>(getMethodContext()))
     length += CID->getNameAsString().size()+1;
   length += getSelector().getAsString().size(); // selector name
   return length; 

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

==============================================================================
--- cfe/trunk/lib/CodeGen/CGObjCGNU.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGObjCGNU.cpp Thu Jan  8 11:28:14 2009
@@ -630,7 +630,7 @@
   // Collect information about instance methods
   llvm::SmallVector<Selector, 16> InstanceMethodSels;
   llvm::SmallVector<llvm::Constant*, 16> InstanceMethodTypes;
-  for (ObjCCategoryDecl::instmeth_iterator iter = OCD->instmeth_begin(),
+  for (ObjCCategoryImplDecl::instmeth_iterator iter = OCD->instmeth_begin(),
       endIter = OCD->instmeth_end() ; iter != endIter ; iter++) {
     InstanceMethodSels.push_back((*iter)->getSelector());
     std::string TypeStr;
@@ -641,7 +641,7 @@
   // Collect information about class methods
   llvm::SmallVector<Selector, 16> ClassMethodSels;
   llvm::SmallVector<llvm::Constant*, 16> ClassMethodTypes;
-  for (ObjCCategoryDecl::classmeth_iterator iter = OCD->classmeth_begin(),
+  for (ObjCCategoryImplDecl::classmeth_iterator iter = OCD->classmeth_begin(),
       endIter = OCD->classmeth_end() ; iter != endIter ; iter++) {
     ClassMethodSels.push_back((*iter)->getSelector());
     std::string TypeStr;

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

==============================================================================
--- cfe/trunk/lib/Sema/IdentifierResolver.cpp (original)
+++ cfe/trunk/lib/Sema/IdentifierResolver.cpp Thu Jan  8 11:28:14 2009
@@ -161,7 +161,7 @@
     return false;
   }
 
-  return LookupContext(D) == LookupContext(Ctx->getPrimaryContext(Context));
+  return LookupContext(D) == LookupContext(Ctx->getPrimaryContext());
 }
 
 /// AddDecl - Link the decl to its shadowed decl chain.

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

==============================================================================
--- cfe/trunk/lib/Sema/Sema.cpp (original)
+++ cfe/trunk/lib/Sema/Sema.cpp Thu Jan  8 11:28:14 2009
@@ -223,7 +223,7 @@
   while (isa<BlockDecl>(DC))
     DC = DC->getParent();
   if (isa<ObjCMethodDecl>(DC) || isa<FunctionDecl>(DC))
-    return cast<NamedDecl>(DC);
+    return cast<ScopedDecl>(DC);
   return 0;
 }
 

Modified: cfe/trunk/lib/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/Sema.h?rev=61929&r1=61928&r2=61929&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/Sema.h (original)
+++ cfe/trunk/lib/Sema/Sema.h Thu Jan  8 11:28:14 2009
@@ -67,6 +67,7 @@
   class ObjCIvarDecl;
   class ObjCMethodDecl;
   class ObjCPropertyDecl;
+  class ObjCContainerDecl;
   struct BlockSemaInfo;
   class BasePaths;
 
@@ -1166,9 +1167,7 @@
   void CheckObjCPropertyAttributes(QualType PropertyTy, 
                                    SourceLocation Loc,
                                    unsigned &Attributes);
-  void diagnosePropertySetterGetterMismatch(ObjCPropertyDecl *property,
-                                            const ObjCMethodDecl *GetterMethod,
-                                            const ObjCMethodDecl *SetterMethod);
+  void ProcessPropertyDecl(ObjCPropertyDecl *property, ObjCContainerDecl *DC);
   void DiagnosePropertyMismatch(ObjCPropertyDecl *Property, 
                                 ObjCPropertyDecl *SuperProperty,
                                 const IdentifierInfo *Name);

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

==============================================================================
--- cfe/trunk/lib/Sema/SemaCXXScopeSpec.cpp (original)
+++ cfe/trunk/lib/Sema/SemaCXXScopeSpec.cpp Thu Jan  8 11:28:14 2009
@@ -26,7 +26,7 @@
     if (LookupCtx && !LookInParentCtx) {
       IdIsUndeclared = true;
       DeclContext::lookup_const_iterator I, E;
-      for (llvm::tie(I, E) = LookupCtx->lookup(Context, Name); I != E; ++I) {
+      for (llvm::tie(I, E) = LookupCtx->lookup(Name); I != E; ++I) {
        IdIsUndeclared = false;
        if (((*I)->getIdentifierNamespace() & Decl::IDNS_Tag) || 
            isa<TypedefDecl>(*I))

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

==============================================================================
--- cfe/trunk/lib/Sema/SemaDecl.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDecl.cpp Thu Jan  8 11:28:14 2009
@@ -287,7 +287,7 @@
     // Perform qualified name lookup into the LookupCtx.
     // FIXME: Will need to look into base classes and such.
     DeclContext::lookup_const_iterator I, E;
-    for (llvm::tie(I, E) = LookupCtx->lookup(Context, Name); I != E; ++I)
+    for (llvm::tie(I, E) = LookupCtx->lookup(Name); I != E; ++I)
       if ((*I)->isInIdentifierNamespace(NS)) {
         // Ignore non-namespace names if we're only looking for namespaces.
         if (NamespaceNameOnly && !isa<NamespaceDecl>(*I)) continue;
@@ -334,7 +334,7 @@
       while (Ctx && (Ctx->isNamespace() || Ctx->isRecord())) {
         // Look for declarations of this name in this scope.
         DeclContext::lookup_const_iterator I, E;
-        for (llvm::tie(I, E) = Ctx->lookup(Context, Name); I != E; ++I) {
+        for (llvm::tie(I, E) = Ctx->lookup(Name); I != E; ++I) {
           // FIXME: Cache this result in the IdResolver
           if ((*I)->isInIdentifierNamespace(NS)) {
             if (NamespaceNameOnly && !isa<NamespaceDecl>(*I))

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

==============================================================================
--- cfe/trunk/lib/Sema/SemaDeclCXX.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDeclCXX.cpp Thu Jan  8 11:28:14 2009
@@ -681,7 +681,7 @@
   //   using a qualified name. ]
   // Look for a member, first.
   FieldDecl *Member = 0;
-  DeclContext::lookup_result Result = ClassDecl->lookup(Context, MemberOrBase);
+  DeclContext::lookup_result Result = ClassDecl->lookup(MemberOrBase);
   if (Result.first != Result.second)
     Member = dyn_cast<FieldDecl>(*Result.first);
 
@@ -1590,7 +1590,7 @@
     = Context.DeclarationNames.getCXXConstructorName(
                        Context.getCanonicalType(ClassType.getUnqualifiedType()));
   DeclContext::lookup_const_iterator Con, ConEnd;
-  for (llvm::tie(Con, ConEnd) = ClassDecl->lookup(Context, ConstructorName);
+  for (llvm::tie(Con, ConEnd) = ClassDecl->lookup(ConstructorName);
        Con != ConEnd; ++Con) {
     CXXConstructorDecl *Constructor = cast<CXXConstructorDecl>(*Con);
     if ((Kind == IK_Direct) ||

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

==============================================================================
--- cfe/trunk/lib/Sema/SemaDeclObjC.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDeclObjC.cpp Thu Jan  8 11:28:14 2009
@@ -1001,14 +1001,18 @@
   }
 }
 
-/// diagnosePropertySetterGetterMismatch - Make sure that use-defined
-/// setter/getter methods have the property type and issue diagnostics
-/// if they don't.
-///
-void
-Sema::diagnosePropertySetterGetterMismatch(ObjCPropertyDecl *property,
-                                           const ObjCMethodDecl *GetterMethod,
-                                           const ObjCMethodDecl *SetterMethod) {
+/// ProcessPropertyDecl - Make sure that any user-defined setter/getter methods 
+/// have the property type and issue diagnostics if they don't.
+/// Also synthesize a getter/setter method if none exist (and update the
+/// appropriate lookup tables. FIXME: Should reconsider if adding synthesized
+/// methods is the "right" thing to do.
+void Sema::ProcessPropertyDecl(ObjCPropertyDecl *property, 
+                               ObjCContainerDecl *CD) {
+  ObjCMethodDecl *GetterMethod, *SetterMethod;
+  
+  GetterMethod = CD->getInstanceMethod(property->getGetterName());  
+  SetterMethod = CD->getInstanceMethod(property->getSetterName());
+  
   if (GetterMethod &&
       GetterMethod->getResultType() != property->getType()) {
     Diag(property->getLocation(), 
@@ -1031,6 +1035,29 @@
       Diag(SetterMethod->getLocation(), diag::note_declared_at);
     }
   }
+
+  // Synthesize getter/setter methods if none exist.
+  // Add any synthesized methods to the global pool. This allows us to 
+  // handle the following, which is supported by GCC (and part of the design).
+  //
+  // @interface Foo
+  // @property double bar;
+  // @end
+  //
+  // void thisIsUnfortunate() {
+  //   id foo;
+  //   double bar = [foo bar];
+  // }
+  //
+  CD->getPropertyMethods(Context, property, GetterMethod, SetterMethod);
+  if (GetterMethod) {
+    CD->addDecl(Context, GetterMethod);
+    AddInstanceMethodToGlobalPool(GetterMethod);  
+  }
+  if (SetterMethod) {
+    CD->addDecl(Context, SetterMethod);
+    AddInstanceMethodToGlobalPool(SetterMethod);     
+  }
 }
 
 // Note: For class/category implemenations, allMethods/allProperties is
@@ -1046,17 +1073,12 @@
   if (!ClassDecl)
     return;
     
-  llvm::SmallVector<ObjCMethodDecl*, 32> insMethods;
-  llvm::SmallVector<ObjCMethodDecl*, 16> clsMethods;
-  
-  llvm::DenseMap<Selector, const ObjCMethodDecl*> InsMap;
-  llvm::DenseMap<Selector, const ObjCMethodDecl*> ClsMap;
-  
   bool isInterfaceDeclKind = 
         isa<ObjCInterfaceDecl>(ClassDecl) || isa<ObjCCategoryDecl>(ClassDecl)
          || isa<ObjCProtocolDecl>(ClassDecl);
   bool checkIdenticalMethods = isa<ObjCImplementationDecl>(ClassDecl);
   
+  
   if (pNum != 0) {
     if (ObjCInterfaceDecl *IDecl = dyn_cast<ObjCInterfaceDecl>(ClassDecl))
       IDecl->addProperties((ObjCPropertyDecl**)allProperties, pNum);
@@ -1067,7 +1089,14 @@
     else
       assert(false && "ActOnAtEnd - property declaration misplaced");
   }
-  
+
+  DeclContext *DC = dyn_cast<DeclContext>(ClassDecl);
+  assert(DC && "Missing DeclContext");
+
+  // FIXME: Remove these and use the ObjCContainerDecl/DeclContext.
+  llvm::DenseMap<Selector, const ObjCMethodDecl*> InsMap;
+  llvm::DenseMap<Selector, const ObjCMethodDecl*> ClsMap;
+
   for (unsigned i = 0; i < allNum; i++ ) {
     ObjCMethodDecl *Method =
       cast_or_null<ObjCMethodDecl>(static_cast<Decl*>(allMethods[i]));
@@ -1084,7 +1113,7 @@
             << Method->getDeclName();
           Diag(PrevMethod->getLocation(), diag::note_previous_declaration);
       } else {
-        insMethods.push_back(Method);
+        DC->addDecl(Context, Method);
         InsMap[Method->getSelector()] = Method;
         /// The following allows us to typecheck messages to "id".
         AddInstanceMethodToGlobalPool(Method);
@@ -1101,17 +1130,13 @@
           << Method->getDeclName();
         Diag(PrevMethod->getLocation(), diag::note_previous_declaration);
       } else {
-        clsMethods.push_back(Method);
+        DC->addDecl(Context, Method);
         ClsMap[Method->getSelector()] = Method;
         /// The following allows us to typecheck messages to "Class".
         AddFactoryMethodToGlobalPool(Method);
       }
     }
   }
-  // Save the size so we can detect if we've added any property methods.
-  unsigned int insMethodsSizePriorToPropAdds = insMethods.size();
-  unsigned int clsMethodsSizePriorToPropAdds = clsMethods.size();
-  
   if (ObjCInterfaceDecl *I = dyn_cast<ObjCInterfaceDecl>(ClassDecl)) {
     // Compares properties declared in this class to those of its 
     // super class.
@@ -1119,22 +1144,15 @@
     MergeProtocolPropertiesIntoClass(I, I);
     for (ObjCInterfaceDecl::classprop_iterator i = I->classprop_begin(),
          e = I->classprop_end(); i != e; ++i) {
-      diagnosePropertySetterGetterMismatch((*i), InsMap[(*i)->getGetterName()],
-                                           InsMap[(*i)->getSetterName()]);
-      I->addPropertyMethods(Context, *i, insMethods, InsMap);
+      ProcessPropertyDecl((*i), I);
     }
-    I->addMethods(&insMethods[0], insMethods.size(),
-                  &clsMethods[0], clsMethods.size(), AtEndLoc);
-    
+    I->setAtEndLoc(AtEndLoc);
   } else if (ObjCProtocolDecl *P = dyn_cast<ObjCProtocolDecl>(ClassDecl)) {
     for (ObjCProtocolDecl::classprop_iterator i = P->classprop_begin(),
          e = P->classprop_end(); i != e; ++i) {
-      diagnosePropertySetterGetterMismatch((*i), InsMap[(*i)->getGetterName()],
-                                           InsMap[(*i)->getSetterName()]);
-      P->addPropertyMethods(Context, *i, insMethods, InsMap);
+      ProcessPropertyDecl((*i), P);
     }
-    P->addMethods(&insMethods[0], insMethods.size(),
-                  &clsMethods[0], clsMethods.size(), AtEndLoc);
+    P->setAtEndLoc(AtEndLoc);
   }
   else if (ObjCCategoryDecl *C = dyn_cast<ObjCCategoryDecl>(ClassDecl)) {
     // Categories are used to extend the class by declaring new methods.
@@ -1145,12 +1163,9 @@
     MergeProtocolPropertiesIntoClass(C, C);
     for (ObjCCategoryDecl::classprop_iterator i = C->classprop_begin(),
          e = C->classprop_end(); i != e; ++i) {
-      diagnosePropertySetterGetterMismatch((*i), InsMap[(*i)->getGetterName()],
-                                           InsMap[(*i)->getSetterName()]);
-      C->addPropertyMethods(Context, *i, insMethods, InsMap);
+      ProcessPropertyDecl((*i), C);
     }
-    C->addMethods(&insMethods[0], insMethods.size(),
-                  &clsMethods[0], clsMethods.size(), AtEndLoc);
+    C->setAtEndLoc(AtEndLoc);
   }
   else if (ObjCImplementationDecl *IC = 
                 dyn_cast<ObjCImplementationDecl>(ClassDecl)) {
@@ -1173,24 +1188,6 @@
       }
     }
   }
-  // Add any synthesized methods to the global pool. This allows us to 
-  // handle the following, which is supported by GCC (and part of the design).
-  //
-  // @interface Foo
-  // @property double bar;
-  // @end
-  //
-  // void thisIsUnfortunate() {
-  //   id foo;
-  //   double bar = [foo bar];
-  // }
-  //
-  if (insMethodsSizePriorToPropAdds < insMethods.size())
-    for (unsigned i = insMethodsSizePriorToPropAdds; i < insMethods.size(); i++)
-      AddInstanceMethodToGlobalPool(insMethods[i]);     
-  if (clsMethodsSizePriorToPropAdds < clsMethods.size())
-    for (unsigned i = clsMethodsSizePriorToPropAdds; i < clsMethods.size(); i++)
-      AddFactoryMethodToGlobalPool(clsMethods[i]);     
 }
 
 
@@ -1241,7 +1238,7 @@
   
   ObjCMethodDecl* ObjCMethod = 
     ObjCMethodDecl::Create(Context, MethodLoc, EndLoc, Sel, resultDeclType,
-                           ClassDecl, 
+                           dyn_cast<DeclContext>(ClassDecl), 
                            MethodType == tok::minus, isVariadic,
                            false,
                            MethodDeclKind == tok::objc_optional ? 

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

==============================================================================
--- cfe/trunk/lib/Sema/SemaExprCXX.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExprCXX.cpp Thu Jan  8 11:28:14 2009
@@ -414,7 +414,7 @@
                                   FunctionDecl *&Operator)
 {
   DeclContext::lookup_iterator Alloc, AllocEnd;
-  llvm::tie(Alloc, AllocEnd) = Ctx->lookup(Context, Name);
+  llvm::tie(Alloc, AllocEnd) = Ctx->lookup(Name);
   if (Alloc == AllocEnd) {
     if (AllowMissing)
       return false;
@@ -517,7 +517,7 @@
   // Check if this function is already declared.
   {
     DeclContext::lookup_iterator Alloc, AllocEnd;
-    for (llvm::tie(Alloc, AllocEnd) = GlobalCtx->lookup(Context, Name);
+    for (llvm::tie(Alloc, AllocEnd) = GlobalCtx->lookup(Name);
          Alloc != AllocEnd; ++Alloc) {
       // FIXME: Do we need to check for default arguments here?
       FunctionDecl *Func = cast<FunctionDecl>(*Alloc);

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

==============================================================================
--- cfe/trunk/lib/Sema/SemaOverload.cpp (original)
+++ cfe/trunk/lib/Sema/SemaOverload.cpp Thu Jan  8 11:28:14 2009
@@ -1117,7 +1117,7 @@
       = Context.DeclarationNames.getCXXConstructorName(
                                              Context.getCanonicalType(ToType));
     DeclContext::lookup_iterator Con, ConEnd;
-    for (llvm::tie(Con, ConEnd) = ToRecordDecl->lookup(Context, ConstructorName);
+    for (llvm::tie(Con, ConEnd) = ToRecordDecl->lookup(ConstructorName);
          Con != ConEnd; ++Con) {
       CXXConstructorDecl *Constructor = cast<CXXConstructorDecl>(*Con);
       if (Constructor->isConvertingConstructor())
@@ -2141,7 +2141,7 @@
   //        empty.
   if (const RecordType *T1Rec = T1->getAsRecordType()) {
     DeclContext::lookup_const_iterator Oper, OperEnd;
-    for (llvm::tie(Oper, OperEnd) = T1Rec->getDecl()->lookup(Context, OpName);
+    for (llvm::tie(Oper, OperEnd) = T1Rec->getDecl()->lookup(OpName);
          Oper != OperEnd; ++Oper)
       AddMethodCandidate(cast<CXXMethodDecl>(*Oper), Args[0], 
                          Args+1, NumArgs - 1, CandidateSet,
@@ -3392,7 +3392,7 @@
   OverloadCandidateSet CandidateSet;
   DeclarationName OpName = Context.DeclarationNames.getCXXOperatorName(OO_Call);
   DeclContext::lookup_const_iterator Oper, OperEnd;
-  for (llvm::tie(Oper, OperEnd) = Record->getDecl()->lookup(Context, OpName);
+  for (llvm::tie(Oper, OperEnd) = Record->getDecl()->lookup(OpName);
        Oper != OperEnd; ++Oper)
     AddMethodCandidate(cast<CXXMethodDecl>(*Oper), Object, Args, NumArgs, 
                        CandidateSet, /*SuppressUserConversions=*/false);
@@ -3577,7 +3577,7 @@
   const RecordType *BaseRecord = Base->getType()->getAsRecordType();
   
   DeclContext::lookup_const_iterator Oper, OperEnd;
-  for (llvm::tie(Oper, OperEnd) = BaseRecord->getDecl()->lookup(Context, OpName);
+  for (llvm::tie(Oper, OperEnd) = BaseRecord->getDecl()->lookup(OpName);
        Oper != OperEnd; ++Oper)
     AddMethodCandidate(cast<CXXMethodDecl>(*Oper), Base, 0, 0, CandidateSet,
                        /*SuppressUserConversions=*/false);





More information about the cfe-commits mailing list