2008-10-04 Ivan N. Zlatev <contact@i-nz.net>
[mono.git] / mcs / mcs / class.cs
index 1edd7ee5bb18f89ed7c73979be259de8a1674412..a0b46cd70a9e4eda4dbffcf0c768684bd0732f58 100644 (file)
@@ -251,8 +251,6 @@ namespace Mono.CSharp {
 
                protected ArrayList type_bases;
 
-               bool members_resolved;
-               bool members_resolved_ok;
                protected bool members_defined;
                bool members_defined_ok;
 
@@ -291,7 +289,7 @@ namespace Mono.CSharp {
 
                public bool AddMember (MemberCore symbol)
                {
-                       return AddToContainer (symbol, symbol.MemberName.MethodName);
+                       return AddToContainer (symbol, symbol.MemberName.Basename);
                }
 
                protected virtual bool AddMemberType (DeclSpace ds)
@@ -428,8 +426,7 @@ namespace Mono.CSharp {
                
                public void AddMethod (Method method)
                {
-                       MemberName mn = method.MemberName;
-                       if (!AddToContainer (method, mn.IsGeneric ? mn.Basename : mn.MethodName))
+                       if (!AddToContainer (method, method.MemberName.Basename))
                                return;
                        
                        if (methods == null)
@@ -443,10 +440,6 @@ namespace Mono.CSharp {
 
                public void AddConstructor (Constructor c)
                {
-                       if (c.Name != MemberName.Name) {
-                               Report.Error (1520, c.Location, "Class, struct, or interface method must have a return type");
-                       }
-
                        bool is_static = (c.ModFlags & Modifiers.STATIC) != 0;
                        if (!AddToContainer (c, is_static ?
                                ConstructorBuilder.ConstructorName : ConstructorBuilder.TypeConstructorName))
@@ -693,19 +686,12 @@ namespace Mono.CSharp {
 
                public void ResolveFieldInitializers (EmitContext ec)
                {
-                       // Field initializers are tricky for partial classes. They have to
-                       // share same costructor (block) but they have they own resolve scope.
-                       DeclSpace orig = ec.DeclContainer;
-
                        if (partial_parts != null) {
                                foreach (TypeContainer part in partial_parts) {
-                                       ec.DeclContainer = part;
                                        part.DoResolveFieldInitializers (ec);
                                }
                        }
-                       ec.DeclContainer = PartialContainer;
                        DoResolveFieldInitializers (ec);
-                       ec.DeclContainer = orig; 
                }
 
                void DoResolveFieldInitializers (EmitContext ec)
@@ -715,33 +701,31 @@ namespace Mono.CSharp {
                                        return;
 
                                bool has_complex_initializer = !RootContext.Optimize;
-                               using (ec.Set (EmitContext.Flags.InFieldInitializer)) {
-                                       int i;
-                                       ExpressionStatement[] init = new ExpressionStatement [initialized_static_fields.Count];
-                                       for (i = 0; i < initialized_static_fields.Count; ++i) {
-                                               FieldInitializer fi = (FieldInitializer) initialized_static_fields [i];
-                                               ExpressionStatement s = fi.ResolveStatement (ec);
-                                               if (s == null) {
-                                                       s = EmptyExpressionStatement.Instance;
-                                               } else if (fi.IsComplexInitializer) {
-                                                       has_complex_initializer |= true;
-                                               }
-
-                                               init [i] = s;
+                               int i;
+                               ExpressionStatement [] init = new ExpressionStatement [initialized_static_fields.Count];
+                               for (i = 0; i < initialized_static_fields.Count; ++i) {
+                                       FieldInitializer fi = (FieldInitializer) initialized_static_fields [i];
+                                       ExpressionStatement s = fi.ResolveStatement (ec);
+                                       if (s == null) {
+                                               s = EmptyExpressionStatement.Instance;
+                                       } else if (fi.IsComplexInitializer) {
+                                               has_complex_initializer |= true;
                                        }
 
-                                       for (i = 0; i < initialized_static_fields.Count; ++i) {
-                                               FieldInitializer fi = (FieldInitializer) initialized_static_fields [i];
-                                               //
-                                               // Need special check to not optimize code like this
-                                               // static int a = b = 5;
-                                               // static int b = 0;
-                                               //
-                                               if (!has_complex_initializer && fi.IsDefaultInitializer)
-                                                       continue;
+                                       init [i] = s;
+                               }
 
-                                               ec.CurrentBlock.AddScopeStatement (new StatementExpression (init [i]));
-                                       }
+                               for (i = 0; i < initialized_static_fields.Count; ++i) {
+                                       FieldInitializer fi = (FieldInitializer) initialized_static_fields [i];
+                                       //
+                                       // Need special check to not optimize code like this
+                                       // static int a = b = 5;
+                                       // static int b = 0;
+                                       //
+                                       if (!has_complex_initializer && fi.IsDefaultInitializer)
+                                               continue;
+
+                                       ec.CurrentBlock.AddScopeStatement (new StatementExpression (init [i]));
                                }
 
                                return;
@@ -750,21 +734,19 @@ namespace Mono.CSharp {
                        if (initialized_fields == null)
                                return;
 
-                       using (ec.Set (EmitContext.Flags.InFieldInitializer)) {
-                               for (int i = 0; i < initialized_fields.Count; ++i) {
-                                       FieldInitializer fi = (FieldInitializer) initialized_fields [i];
-                                       ExpressionStatement s = fi.ResolveStatement (ec);
-                                       if (s == null)
-                                               continue;
+                       for (int i = 0; i < initialized_fields.Count; ++i) {
+                               FieldInitializer fi = (FieldInitializer) initialized_fields [i];
+                               ExpressionStatement s = fi.ResolveStatement (ec);
+                               if (s == null)
+                                       continue;
 
-                                       //
-                                       // Field is re-initialized to its default value => removed
-                                       //
-                                       if (fi.IsDefaultInitializer && RootContext.Optimize)
-                                               continue;
+                               //
+                               // Field is re-initialized to its default value => removed
+                               //
+                               if (fi.IsDefaultInitializer && RootContext.Optimize)
+                                       continue;
 
-                                       ec.CurrentBlock.AddScopeStatement (new StatementExpression (s));
-                               }
+                               ec.CurrentBlock.AddScopeStatement (new StatementExpression (s));
                        }
                }
 
@@ -1121,11 +1103,6 @@ namespace Mono.CSharp {
                                return null;
                        }
 
-                       if (!ResolveMembers ()) {
-                               error = true;
-                               return null;
-                       }
-
                        if (!DefineNestedTypes ()) {
                                error = true;
                                return null;
@@ -1134,37 +1111,6 @@ namespace Mono.CSharp {
                        return TypeBuilder;
                }
 
-               bool ResolveMembers ()
-               {
-                       if (members_resolved)
-                               return members_resolved_ok;
-
-                       members_resolved_ok = DoResolveMembers ();
-                       members_resolved = true;
-
-                       return members_resolved_ok;
-               }
-
-               protected virtual bool DoResolveMembers ()
-               {
-                       if (methods != null) {
-                               foreach (Method method in methods) {
-                                       if (!method.ResolveMembers ())
-                                               return false;
-                               }
-                       }
-
-                       // TODO: this is not really needed
-                       if (operators != null) {
-                               foreach (Operator o in operators) {
-                                       if (!o.ResolveMembers ())
-                                               return false;
-                               }
-                       }
-
-                       return true;
-               }
-
                public override void SetParameterInfo (ArrayList constraints_list)
                {
                        base.SetParameterInfo (constraints_list);
@@ -1322,22 +1268,14 @@ namespace Mono.CSharp {
                        return true;
                }
 
-               public static void Error_KeywordNotAllowed (Location loc)
-               {
-                       Report.Error (1530, loc, "Keyword `new' is not allowed on namespace elements");
-               }
-
                /// <summary>
                ///   Populates our TypeBuilder with fields and methods
                /// </summary>
-               public override bool DefineMembers ()
+               public override bool Define ()
                {
                        if (members_defined)
                                return members_defined_ok;
 
-                       if (!base.DefineMembers ())
-                               return false;
-
                        members_defined_ok = DoDefineMembers ();
                        members_defined = true;
 
@@ -1521,12 +1459,6 @@ namespace Mono.CSharp {
                        }
                }
 
-               public override bool Define ()
-               {
-                       CheckProtectedModifier ();
-                       return true;
-               }
-
                public MemberInfo FindBaseMemberWithSameName (string name, bool ignore_methods)
                {
                        return BaseCache == null ? null : BaseCache.FindMemberWithSameName (name, ignore_methods, null);
@@ -1556,7 +1488,7 @@ namespace Mono.CSharp {
                {
                        ArrayList members = new ArrayList ();
 
-                       DefineMembers ();
+                       Define ();
 
                        if (methods != null) {
                                int len = methods.Count;
@@ -2593,11 +2525,11 @@ namespace Mono.CSharp {
 
                protected override bool AddToContainer (MemberCore symbol, string name)
                {
-                       if (name == MemberName.Name) {
+                       if (name == MemberName.Name && symbol.MemberName.Left == null) {
                                if (symbol is TypeParameter) {
                                        Report.Error (694, symbol.Location,
-                                                     "Type parameter `{0}' has same name as " +
-                                                     "containing type, or method", name);
+                                               "Type parameter `{0}' has same name as containing type, or method",
+                                               symbol.GetSignatureForError ());
                                        return false;
                                }
 
@@ -2661,7 +2593,7 @@ namespace Mono.CSharp {
                        }
 
                        Constructor c = new Constructor (this, MemberName.Name, mods,
-                               Parameters.EmptyReadOnlyParameters,
+                               null, Parameters.EmptyReadOnlyParameters,
                                new GeneratedBaseInitializer (Location),
                                Location);
                        
@@ -2671,17 +2603,23 @@ namespace Mono.CSharp {
 
                public override bool Define ()
                {
-                       if (default_static_constructor == null && PartialContainer.HasStaticFieldInitializer)
-                               DefineDefaultConstructor (true);
+                       CheckProtectedModifier ();
+
+                       base.Define ();
 
                        if (default_static_constructor != null)
                                default_static_constructor.Define ();
 
-                       return base.Define ();
+                       return true;
                }
 
                public override void Emit ()
                {
+                       if (default_static_constructor == null && PartialContainer.HasStaticFieldInitializer) {
+                               DefineDefaultConstructor (true);
+                               default_static_constructor.Define ();
+                       }
+
                        base.Emit ();
 
                        if (declarative_security != null) {
@@ -2800,11 +2738,6 @@ namespace Mono.CSharp {
                                        continue;
                                }
 
-                               if ((m.ModFlags & Modifiers.PROTECTED) != 0) {
-                                       m.CheckProtectedModifier ();
-                                       continue;
-                               }
-
                                if (m is Indexer) {
                                        Report.Error (720, m.Location, "`{0}': cannot declare indexers in a static class", m.GetSignatureForError ());
                                        continue;
@@ -2830,19 +2763,17 @@ namespace Mono.CSharp {
                        base.DefineContainerMembers (list);
                }
 
-               public override TypeBuilder DefineType ()
+               public override bool Define ()
                {
                        if ((ModFlags & Modifiers.ABSTRACT) == Modifiers.ABSTRACT && (ModFlags & (Modifiers.SEALED | Modifiers.STATIC)) != 0) {
                                Report.Error (418, Location, "`{0}': an abstract class cannot be sealed or static", GetSignatureForError ());
-                               return null;
                        }
 
                        if ((ModFlags & (Modifiers.SEALED | Modifiers.STATIC)) == (Modifiers.SEALED | Modifiers.STATIC)) {
                                Report.Error (441, Location, "`{0}': a class cannot be both static and sealed", GetSignatureForError ());
-                               return null;
                        }
 
-                       return base.DefineType ();
+                       return base.Define ();
                }
 
                protected override bool DoDefineMembers ()
@@ -3124,13 +3055,13 @@ namespace Mono.CSharp {
                        }
                }
 
-               const TypeAttributes DefaultTypeAttributes =
-                       TypeAttributes.AutoLayout |
-                       TypeAttributes.Abstract |
-                       TypeAttributes.Interface;
-
                protected override TypeAttributes TypeAttr {
                        get {
+                               const TypeAttributes DefaultTypeAttributes =
+                                       TypeAttributes.AutoLayout |
+                                       TypeAttributes.Abstract |
+                                       TypeAttributes.Interface;
+
                                return base.TypeAttr | DefaultTypeAttributes;
                        }
                }
@@ -3226,23 +3157,7 @@ namespace Mono.CSharp {
                        if (!DefineParameters (Parameters))
                                return false;
 
-                       if ((caching_flags & Flags.MethodOverloadsExist) != 0) {
-                               if (!Parent.MemberCache.CheckExistingMembersOverloads (this,
-                                       MemberName.IsGeneric ? MemberName.Basename : MemberName.MethodName, Parameters))
-                                       return false;
-
-                               // TODO: Find a better way how to check reserved accessors collision
-                               Method m = this as Method;
-                               if (m != null) {
-                                       if (!m.CheckForDuplications ())
-                                               return false;
-                               }
-                       }
-
-                       if (!base.CheckBase ())
-                               return false;
-
-                       return true;
+                       return base.CheckBase ();
                }
 
                //
@@ -3281,7 +3196,7 @@ namespace Mono.CSharp {
                                return true;
                        }
 
-                       return false;
+                       return base.EnableOverloadChecks (overload);
                }
 
                protected override bool VerifyClsCompliance ()
@@ -3345,6 +3260,9 @@ namespace Mono.CSharp {
                {
                        if (!base.CheckBase ())
                                return false;
+
+                       if ((caching_flags & Flags.MethodOverloadsExist) != 0)
+                               CheckForDuplications ();
                        
                        if (IsExplicitImpl)
                                return true;
@@ -3420,6 +3338,12 @@ namespace Mono.CSharp {
                        return true;
                }
 
+               protected virtual bool CheckForDuplications ()
+               {
+                       return Parent.MemberCache.CheckExistingMembersOverloads (
+                               this, GetFullName (MemberName), Parameters.EmptyReadOnlyParameters);
+               }
+
                //
                // Performs various checks on the MethodInfo `mb' regarding the modifier flags
                // that have been defined.
@@ -3547,14 +3471,12 @@ namespace Mono.CSharp {
                                Report.SymbolRelatedToPreviousError (t);
                                if (this is Indexer)
                                        Report.Error (55, Location,
-                                               "Inconsistent accessibility: parameter type `" +
-                                               TypeManager.CSharpName (t) + "' is less " +
-                                               "accessible than indexer `" + GetSignatureForError () + "'");
+                                                     "Inconsistent accessibility: parameter type `{0}' is less accessible than indexer `{1}'",
+                                                     TypeManager.CSharpName (t), GetSignatureForError ());
                                else if (this is Operator)
                                        Report.Error (57, Location,
-                                               "Inconsistent accessibility: parameter type `" +
-                                               TypeManager.CSharpName (t) + "' is less " +
-                                               "accessible than operator `" + GetSignatureForError () + "'");
+                                                     "Inconsistent accessibility: parameter type `{0}' is less accessible than operator `{1}'",
+                                                     TypeManager.CSharpName (t), GetSignatureForError ());
                                else
                                        Report.Error (51, Location,
                                                "Inconsistent accessibility: parameter type `{0}' is less accessible than method `{1}'",
@@ -3564,39 +3486,11 @@ namespace Mono.CSharp {
                        return !error;
                }
 
-               protected override bool DoDefine()
-               {
-                       if (!base.DoDefine ())
-                               return false;
-
-                       if (IsExplicitImpl) {
-                               TypeExpr texpr = MemberName.Left.GetTypeExpression ().ResolveAsTypeTerminal (this, false);
-                               if (texpr == null)
-                                       return false;
-
-                               InterfaceType = texpr.Type;
-
-                               if (!InterfaceType.IsInterface) {
-                                       Report.Error (538, Location, "`{0}' in explicit interface declaration is not an interface", TypeManager.CSharpName (InterfaceType));
-                                       return false;
-                               }
-                               
-                               if (!Parent.PartialContainer.VerifyImplements (this))
-                                       return false;
-                               
-                       }
-                       return true;
-               }
-
                protected bool DoDefineBase ()
                {
-                       if (Name == null)
-                               throw new InternalErrorException ();
-
                        if (IsInterface) {
-                               ModFlags = Modifiers.PUBLIC |
-                                       Modifiers.ABSTRACT |
-                                       Modifiers.VIRTUAL | (ModFlags & Modifiers.UNSAFE) | (ModFlags & Modifiers.NEW);
+                               ModFlags = Modifiers.PUBLIC | Modifiers.ABSTRACT |
+                                       Modifiers.VIRTUAL | (ModFlags & (Modifiers.UNSAFE | Modifiers.NEW));
 
                                flags = MethodAttributes.Public |
                                        MethodAttributes.Abstract |
@@ -3618,18 +3512,17 @@ namespace Mono.CSharp {
                                if ((ModFlags & Modifiers.PARTIAL) != 0) {
                                        Report.Error (754, Location, "A partial method `{0}' cannot explicitly implement an interface",
                                                GetSignatureForError ());
-                                       return false;
                                }
 
                                InterfaceType = iface_texpr.Type;
 
                                if (!InterfaceType.IsInterface) {
-                                       Report.Error (538, Location, "'{0}' in explicit interface declaration is not an interface", TypeManager.CSharpName (InterfaceType));
-                                       return false;
+                                       Report.SymbolRelatedToPreviousError (InterfaceType);
+                                       Report.Error (538, Location, "The type `{0}' in explicit interface declaration is not an interface",
+                                               TypeManager.CSharpName (InterfaceType));
+                               } else {
+                                       Parent.PartialContainer.VerifyImplements (this);
                                }
-
-                               if (!Parent.PartialContainer.VerifyImplements (this))
-                                       return false;
                                
                                Modifiers.Check (Modifiers.AllowedExplicitImplFlags, explicit_mod_flags, 0, Location);
                        }
@@ -3650,6 +3543,23 @@ namespace Mono.CSharp {
                        base.Emit ();
                }
 
+               public override bool EnableOverloadChecks (MemberCore overload)
+               {
+                       //
+                       // Two members can differ in their explicit interface
+                       // type parameter only
+                       //
+                       InterfaceMemberBase imb = overload as InterfaceMemberBase;
+                       if (imb != null && imb.IsExplicitImpl) {
+                               if (IsExplicitImpl) {
+                                       caching_flags |= Flags.MethodOverloadsExist;
+                               }
+                               return true;
+                       }
+
+                       return IsExplicitImpl;
+               }
+
                protected void Error_CannotChangeAccessModifiers (Location loc, MemberInfo base_method, MethodAttributes ma, string suffix)
                {
                        Report.SymbolRelatedToPreviousError (base_method);
@@ -3685,12 +3595,23 @@ namespace Mono.CSharp {
                        set { SetMemberName (new MemberName (MemberName.Left, value, Location)); }
                }
                
+               //
+               // Returns full metadata method name
+               //
                public string GetFullName (MemberName name)
                {
                        if (!IsExplicitImpl)
                                return name.Name;
 
-                       return InterfaceType.FullName.Replace ('+', '.') + "." + name.Name;
+                       //
+                       // When dealing with explicit members a full interface type
+                       // name is added to member name to avoid possible name conflicts
+                       //
+                       // We use CSharpName which gets us full name with benefit of
+                       // replacing predefined names which saves some space and name
+                       // is still unique
+                       //
+                       return TypeManager.CSharpName (InterfaceType) + "." + name.Name;
                }
 
                protected override bool VerifyClsCompliance ()
@@ -3775,13 +3696,22 @@ namespace Mono.CSharp {
                        }
                }
 
+               protected override bool CheckForDuplications ()
+               {
+                       string name = GetFullName (MemberName);
+                       if (MemberName.IsGeneric)
+                               name = MemberName.MakeName (name, MemberName.TypeArguments);
+
+                       return Parent.MemberCache.CheckExistingMembersOverloads (this, name, Parameters);
+               }
+
                public virtual EmitContext CreateEmitContext (DeclSpace tc, ILGenerator ig)
                {
                        return new EmitContext (
                                this, tc, this.ds, Location, ig, MemberType, ModFlags, false);
                }
 
-               protected bool DefineGenericMethod ()
+               public override bool Define ()
                {
                        if (!DoDefineBase ())
                                return false;
@@ -3794,19 +3724,6 @@ namespace Mono.CSharp {
                        }
 #endif
 
-                       return true;
-               }
-
-               public bool ResolveMembers ()
-               {
-                       if (!DefineGenericMethod ())
-                               return false;
-
-                       return true;
-               }
-
-               public override bool Define ()
-               {
                        if (!DoDefine ())
                                return false;
 
@@ -3826,8 +3743,14 @@ namespace Mono.CSharp {
                        if (!CheckBase ())
                                return false;
 
-                       if (block != null && block.IsIterator && !(Parent is IteratorStorey))
+                       if (block != null && block.IsIterator && !(Parent is IteratorStorey)) {
+                               //
+                               // Current method is turned into automatically generated
+                               // wrapper which creates an instance of iterator
+                               //
                                Iterator.CreateIterator (this, Parent.PartialContainer, ModFlags);
+                               ModFlags |= Modifiers.DEBUGGER_HIDDEN;
+                       }
 
                        if (IsPartialDefinition) {
                                caching_flags &= ~Flags.Excluded_Undetected;
@@ -4187,8 +4110,11 @@ namespace Mono.CSharp {
                        base.ApplyAttributeBuilder (a, cb);
                }
 
-               public bool CheckForDuplications ()
+               protected override bool CheckForDuplications ()
                {
+                       if (!base.CheckForDuplications ())
+                               return false;
+
                        ArrayList ar = Parent.PartialContainer.Properties;
                        if (ar != null) {
                                for (int i = 0; i < ar.Count; ++i) {
@@ -4543,10 +4469,10 @@ namespace Mono.CSharp {
                // The spec claims that static is not permitted, but
                // my very own code has static constructors.
                //
-               public Constructor (DeclSpace parent, string name, int mod, Parameters args,
+               public Constructor (DeclSpace parent, string name, int mod, Attributes attrs, Parameters args,
                                    ConstructorInitializer init, Location loc)
                        : base (parent, null, null, mod, AllowedModifiers,
-                               new MemberName (name, loc), null, args)
+                               new MemberName (name, loc), attrs, args)
                {
                        Initializer = init;
                }
@@ -4607,7 +4533,7 @@ namespace Mono.CSharp {
                                return false;
 
                        if ((caching_flags & Flags.MethodOverloadsExist) != 0)
-                               Parent.MemberCache.CheckExistingMembersOverloads (this, ConstructorBuilder.ConstructorName,
+                               Parent.MemberCache.CheckExistingMembersOverloads (this, ConstructorInfo.ConstructorName,
                                        Parameters);
 
                        if (Parent.PartialContainer.Kind == Kind.Struct) {
@@ -5083,15 +5009,8 @@ namespace Mono.CSharp {
                        else
                                declaring_type = container.TypeBuilder;
 
-                       if (implementing != null){
-                               //
-                               // clear the pending implemntation flag
-                               //
-                               pending.ImplementMethod (name, member.InterfaceType, this, member.IsExplicitImpl);
-
-                               if (member.IsExplicitImpl)
-                                       container.TypeBuilder.DefineMethodOverride (
-                                               builder, implementing);
+                       if (implementing != null && member.IsExplicitImpl) {
+                               container.TypeBuilder.DefineMethodOverride (builder, implementing);
                        }
 
                        TypeManager.AddMethod (builder, method);
@@ -5164,6 +5083,13 @@ namespace Mono.CSharp {
                        if (GenericMethod != null)
                                GenericMethod.EmitAttributes ();
 
+                       //
+                       // clear the pending implementation flag
+                       //
+                       if (implementing != null)
+                               parent.PartialContainer.PendingImplementations.ImplementMethod (method.MethodName.Basename,
+                                       member.InterfaceType, this, member.IsExplicitImpl);
+
                        SourceMethod source = SourceMethod.Create (parent, MethodBuilder, method.Block);
 
                        //
@@ -5465,12 +5391,6 @@ namespace Mono.CSharp {
                        if (TypeManager.IsGenericParameter (MemberType))
                                return true;
 
-                       if (MemberType == TypeManager.void_type) {
-                               // TODO: wrong location
-                               Expression.Error_VoidInvalidInTheContext (Location);
-                               return false;
-                       }
-
                        if (MemberType.IsSealed && MemberType.IsAbstract) {
                                Error_VariableOfStaticClass (Location, GetSignatureForError (), MemberType);
                                return false;
@@ -5619,7 +5539,7 @@ namespace Mono.CSharp {
                        Expression size_expr, Attributes attrs, Location loc):
                        base (parent, type, mod, AllowedModifiers, new MemberName (name, loc), attrs)
                {
-                       if (RootContext.Version == LanguageVersion.ISO_1)
+                       if (RootContext.Version < LanguageVersion.ISO_2)
                                Report.FeatureIsNotAvailable (loc, "fixed size buffers");
 
                        this.size_expr = size_expr;
@@ -5922,7 +5842,7 @@ namespace Mono.CSharp {
 
                        if (initializer != null) {
                                ((TypeContainer) Parent).RegisterFieldForInitialization (this,
-                                       new FieldInitializer (FieldBuilder, initializer));
+                                       new FieldInitializer (FieldBuilder, initializer, this));
                        } else {
                                if (Parent.PartialContainer.Kind == Kind.Struct)
                                        CheckStructLayout (member_type, (ModFlags & Modifiers.STATIC) != 0);
@@ -6376,7 +6296,7 @@ namespace Mono.CSharp {
                                CheckForDuplications ();
 
                                if (IsDummy) {
-                                       if (method.InterfaceType != null && method.IsExplicitImpl) {
+                                       if (method.InterfaceType != null && parent.PartialContainer.PendingImplementations != null) {
                                                MethodInfo mi = parent.PartialContainer.PendingImplementations.IsInterfaceMethod (
                                                        MethodName.Name, method.InterfaceType, new MethodData (method, ModFlags, flags, this));
                                                if (mi != null) {
@@ -6469,7 +6389,7 @@ namespace Mono.CSharp {
                                }
                        }
 
-                       protected bool CheckForDuplications () 
+                       protected bool CheckForDuplications ()
                        {
                                if ((caching_flags & Flags.MethodOverloadsExist) == 0)
                                        return true;
@@ -7064,6 +6984,10 @@ namespace Mono.CSharp {
 
                        protected override void EmitMethod(DeclSpace parent)
                        {
+                               if (method_data.implementing != null)
+                                       parent.PartialContainer.PendingImplementations.ImplementMethod (
+                                               Name, method.InterfaceType, method_data, method.IsExplicitImpl);
+                               
                                if ((method.ModFlags & (Modifiers.ABSTRACT | Modifiers.EXTERN)) != 0)
                                        return;
 
@@ -7186,7 +7110,7 @@ namespace Mono.CSharp {
                                }
 
                                ((TypeContainer) Parent).RegisterFieldForInitialization (this,
-                                       new FieldInitializer (FieldBuilder, Initializer));
+                                       new FieldInitializer (FieldBuilder, Initializer, this));
                        }
 
                        return true;
@@ -7547,6 +7471,11 @@ namespace Mono.CSharp {
                        else
                                Set = new SetIndexerMethod (this, set_block);
                }
+
+               protected override bool CheckForDuplications ()
+               {
+                       return Parent.MemberCache.CheckExistingMembersOverloads (this, GetFullName (MemberName), parameters);
+               }
                
                public override bool Define ()
                {
@@ -7596,11 +7525,6 @@ namespace Mono.CSharp {
                                !Parent.PartialContainer.AddMember (Get) || !Parent.PartialContainer.AddMember (Set))
                                return false;
 
-                       if ((caching_flags & Flags.MethodOverloadsExist) != 0) {
-                               if (!Parent.MemberCache.CheckExistingMembersOverloads (this, Name, parameters))
-                                       return false;
-                       }
-
                        flags |= MethodAttributes.HideBySig | MethodAttributes.SpecialName;
                        
                        if (!DefineAccessors ())
@@ -7637,7 +7561,7 @@ namespace Mono.CSharp {
                                return true;
                        }
 
-                       return false;
+                       return base.EnableOverloadChecks (overload);
                }
 
                public override string GetDocCommentName (DeclSpace ds)
@@ -7762,7 +7686,7 @@ namespace Mono.CSharp {
                                 int mod_flags, Parameters parameters,
                                 ToplevelBlock block, Attributes attrs, Location loc)
                        : base (parent, null, ret_type, mod_flags, AllowedModifiers,
-                               new MemberName ("op_" + type.ToString(), loc), attrs, parameters)
+                               new MemberName (GetMetadataName (type), loc), attrs, parameters)
                {
                        OperatorType = type;
                        Block = block;
@@ -7795,11 +7719,6 @@ namespace Mono.CSharp {
                        else if (OperatorType == OpType.Implicit)
                                Parent.MemberCache.CheckExistingMembersOverloads (this, GetMetadataName (OpType.Explicit), Parameters);
 
-                       if (MemberType == TypeManager.void_type) {
-                               Report.Error (590, Location, "User-defined operators cannot return void");
-                               return false;
-                       }
-
                        Type declaring_type = MethodData.DeclaringType;
                        Type return_type = MemberType;
                        Type first_arg_type = ParameterTypes [0];
@@ -7983,24 +7902,24 @@ namespace Mono.CSharp {
                public OpType GetMatchingOperator ()
                {
                        switch (OperatorType) {
-                               case OpType.Equality:
-                                       return OpType.Inequality;
-                               case OpType.Inequality:
-                                       return OpType.Equality;
-                               case OpType.True:
-                                       return OpType.False;
-                               case OpType.False:
-                                       return OpType.True;
-                               case OpType.GreaterThan:
-                                       return OpType.LessThan;
-                               case OpType.LessThan:
-                                       return OpType.GreaterThan;
-                               case OpType.GreaterThanOrEqual:
-                                       return OpType.LessThanOrEqual;
-                               case OpType.LessThanOrEqual:
-                                       return OpType.GreaterThanOrEqual;
-                               default:
-                                       return OpType.TOP;
+                       case OpType.Equality:
+                               return OpType.Inequality;
+                       case OpType.Inequality:
+                               return OpType.Equality;
+                       case OpType.True:
+                               return OpType.False;
+                       case OpType.False:
+                               return OpType.True;
+                       case OpType.GreaterThan:
+                               return OpType.LessThan;
+                       case OpType.LessThan:
+                               return OpType.GreaterThan;
+                       case OpType.GreaterThanOrEqual:
+                               return OpType.LessThanOrEqual;
+                       case OpType.LessThanOrEqual:
+                               return OpType.GreaterThanOrEqual;
+                       default:
+                               return OpType.TOP;
                        }
                }