[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/Sem

Daniel Dunbar daniel at zuster.org
Thu Jan 8 17:20:32 PST 2009


Hi Steve,

My tester is pointing at this for a .98% slowdown at -fsyntax-only (of
parts of Sketch, essentially Cocoa.h). I was really hoping we were
going to see a speedup from this! Can you investigate?

 - Daniel

On Thu, Jan 8, 2009 at 9:28 AM, Steve Naroff <snaroff at apple.com> wrote:
> 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);
>
>
> _______________________________________________
> cfe-commits mailing list
> cfe-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
>



More information about the cfe-commits mailing list