Merge pull request #606 from sesef/master
[mono.git] / mcs / mcs / class.cs
index cc1cc614d419432a8ba110d966e53c980463e567..a13adb2ef79335f5e47d7394c9d4d7cea8832dd0 100644 (file)
@@ -17,9 +17,9 @@ using System.Collections.Generic;
 using System.Runtime.InteropServices;
 using System.Security;
 using System.Security.Permissions;
-using System.Linq;
 using System.Text;
 using System.Diagnostics;
+using Mono.CompilerServices.SymbolWriter;
 
 #if NET_2_1
 using XmlElement = System.Object;
@@ -69,6 +69,12 @@ namespace Mono.CSharp
                        }
                }
 
+               public Dictionary<string, MemberCore> DefinedNames {
+                       get {
+                               return defined_names;
+                       }
+               }
+
                public TypeDefinition PartialContainer {
                        get {
                                return main_container;
@@ -84,7 +90,15 @@ namespace Mono.CSharp
                        }
                }
 
-               public virtual void AddCompilerGeneratedClass (CompilerGeneratedClass c)
+               //
+               // Any unattached attributes during parsing get added here. User
+               // by FULL_AST mode
+               //
+               public Attributes UnattachedAttributes {
+                       get; set;
+               }
+
+               public virtual void AddCompilerGeneratedClass (CompilerGeneratedContainer c)
                {
                        containers.Add (c);
                }
@@ -246,7 +260,14 @@ namespace Mono.CSharp
                {
                        if (containers != null) {
                                foreach (var t in containers) {
-                                       t.PrepareEmit ();
+                                       try {
+                                               t.PrepareEmit ();
+                                       } catch (Exception e) {
+                                               if (MemberName == MemberName.Null)
+                                                       throw;
+
+                                               throw new InternalErrorException (t, e);
+                                       }
                                }
                        }
                }
@@ -276,6 +297,15 @@ namespace Mono.CSharp
                        return true;
                }
 
+               public virtual void ExpandBaseInterfaces ()
+               {
+                       if (containers != null) {
+                               foreach (TypeContainer tc in containers) {
+                                       tc.ExpandBaseInterfaces ();
+                               }
+                       }
+               }
+
                protected virtual void DefineNamespace ()
                {
                        if (containers != null) {
@@ -324,12 +354,28 @@ namespace Mono.CSharp
                        return MemberName.GetSignatureForError ();
                }
 
+               public string GetSignatureForMetadata ()
+               {
+#if STATIC
+                       if (Parent is TypeDefinition) {
+                               return Parent.GetSignatureForMetadata () + "+" + TypeNameParser.Escape (MemberName.Basename);
+                       }
+
+                       var sb = new StringBuilder ();
+                       CreateMetadataName (sb);
+                       return sb.ToString ();
+#else
+                       throw new NotImplementedException ();
+#endif
+               }
+
                public virtual void RemoveContainer (TypeContainer cont)
                {
                        if (containers != null)
                                containers.Remove (cont);
 
-                       defined_names.Remove (cont.Basename);
+                       var tc = Parent == Module ? Module : this;
+                       tc.defined_names.Remove (cont.Basename);
                }
 
                public virtual void VerifyMembers ()
@@ -339,6 +385,15 @@ namespace Mono.CSharp
                                        tc.VerifyMembers ();
                        }
                }
+
+               public override void WriteDebugSymbol (MonoSymbolFile file)
+               {
+                       if (containers != null) {
+                               foreach (TypeContainer tc in containers) {
+                                       tc.WriteDebugSymbol (file);
+                               }
+                       }
+               }
        }
 
        public abstract class TypeDefinition : TypeContainer, ITypeDefinition
@@ -488,6 +543,7 @@ namespace Mono.CSharp
 
                public int DynamicSitesCounter;
                public int AnonymousMethodsCounter;
+               public int MethodGroupsCounter;
 
                static readonly string[] attribute_targets = new string[] { "type" };
 
@@ -617,6 +673,18 @@ namespace Mono.CSharp
                        }
                }
 
+               public bool IsPartial {
+                       get {
+                               return (ModFlags & Modifiers.PARTIAL) != 0;
+                       }
+               }
+
+               bool ITypeDefinition.IsTypeForwarder {
+                       get {
+                               return false;
+                       }
+               }
+
                //
                // Returns true for secondary partial containers
                //
@@ -692,7 +760,7 @@ namespace Mono.CSharp
                        base.AddTypeContainer (tc);
                }
 
-               public override void AddCompilerGeneratedClass (CompilerGeneratedClass c)
+               public override void AddCompilerGeneratedClass (CompilerGeneratedContainer c)
                {
                        members.Add (c);
 
@@ -952,6 +1020,9 @@ namespace Mono.CSharp
 
                internal override void GenerateDocComment (DocumentationBuilder builder)
                {
+                       if (IsPartialPart)
+                               return;
+
                        base.GenerateDocComment (builder);
 
                        foreach (var member in members)
@@ -1159,7 +1230,7 @@ namespace Mono.CSharp
                        //
                        // Sets .size to 1 for structs with no instance fields
                        //
-                       int type_size = Kind == MemberKind.Struct && first_nonstatic_field == null ? 1 : 0;
+                       int type_size = Kind == MemberKind.Struct && first_nonstatic_field == null && !(this is StateMachine) ? 1 : 0;
 
                        var parent_def = Parent as TypeDefinition;
                        if (parent_def == null) {
@@ -1241,6 +1312,18 @@ namespace Mono.CSharp
                }
 
 
+               public SourceMethodBuilder CreateMethodSymbolEntry ()
+               {
+                       if (Module.DeclaringAssembly.SymbolWriter == null)
+                               return null;
+
+                       var source_file = GetCompilationSourceFile ();
+                       if (source_file == null)
+                               return null;
+
+                       return new SourceMethodBuilder (source_file.SymbolUnitEntry);
+               }
+
                //
                // Creates a proxy base method call inside this container for hoisted base member calls
                //
@@ -1259,23 +1342,13 @@ namespace Mono.CSharp
                        }
 
                        if (proxy_method == null) {
-                               string name = CompilerGeneratedClass.MakeName (method.Name, null, "BaseCallProxy", hoisted_base_call_proxies.Count);
-                               var base_parameters = new Parameter[method.Parameters.Count];
-                               for (int i = 0; i < base_parameters.Length; ++i) {
-                                       var base_param = method.Parameters.FixedParameters[i];
-                                       base_parameters[i] = new Parameter (new TypeExpression (method.Parameters.Types[i], Location),
-                                               base_param.Name, base_param.ModFlags, null, Location);
-                                       base_parameters[i].Resolve (this, i);
-                               }
-
-                               var cloned_params = ParametersCompiled.CreateFullyResolved (base_parameters, method.Parameters.Types);
-                               if (method.Parameters.HasArglist) {
-                                       cloned_params.FixedParameters[0] = new Parameter (null, "__arglist", Parameter.Modifier.NONE, null, Location);
-                                       cloned_params.Types[0] = Module.PredefinedTypes.RuntimeArgumentHandle.Resolve ();
-                               }
+                               string name = CompilerGeneratedContainer.MakeName (method.Name, null, "BaseCallProxy", hoisted_base_call_proxies.Count);
 
                                MemberName member_name;
                                TypeArguments targs = null;
+                               TypeSpec return_type = method.ReturnType;
+                               var local_param_types = method.Parameters.Types;
+
                                if (method.IsGeneric) {
                                        //
                                        // Copy all base generic method type parameters info
@@ -1287,19 +1360,42 @@ namespace Mono.CSharp
                                        targs.Arguments = new TypeSpec[hoisted_tparams.Length];
                                        for (int i = 0; i < hoisted_tparams.Length; ++i) {
                                                var tp = hoisted_tparams[i];
-                                               tparams.Add (new TypeParameter (tp, null, new MemberName (tp.Name, Location), null));
+                                               var local_tp = new TypeParameter (tp, null, new MemberName (tp.Name, Location), null);
+                                               tparams.Add (local_tp);
 
                                                targs.Add (new SimpleName (tp.Name, Location));
-                                               targs.Arguments[i] = tp;
+                                               targs.Arguments[i] = local_tp.Type;
                                        }
 
                                        member_name = new MemberName (name, tparams, Location);
+
+                                       //
+                                       // Mutate any method type parameters from original
+                                       // to newly created hoisted version
+                                       //
+                                       var mutator = new TypeParameterMutator (hoisted_tparams, tparams);
+                                       return_type = mutator.Mutate (return_type);
+                                       local_param_types = mutator.Mutate (local_param_types);
                                } else {
                                        member_name = new MemberName (name);
                                }
 
+                               var base_parameters = new Parameter[method.Parameters.Count];
+                               for (int i = 0; i < base_parameters.Length; ++i) {
+                                       var base_param = method.Parameters.FixedParameters[i];
+                                       base_parameters[i] = new Parameter (new TypeExpression (local_param_types [i], Location),
+                                               base_param.Name, base_param.ModFlags, null, Location);
+                                       base_parameters[i].Resolve (this, i);
+                               }
+
+                               var cloned_params = ParametersCompiled.CreateFullyResolved (base_parameters, method.Parameters.Types);
+                               if (method.Parameters.HasArglist) {
+                                       cloned_params.FixedParameters[0] = new Parameter (null, "__arglist", Parameter.Modifier.NONE, null, Location);
+                                       cloned_params.Types[0] = Module.PredefinedTypes.RuntimeArgumentHandle.Resolve ();
+                               }
+
                                // Compiler generated proxy
-                               proxy_method = new Method (this, new TypeExpression (method.ReturnType, Location),
+                               proxy_method = new Method (this, new TypeExpression (return_type, Location),
                                        Modifiers.PRIVATE | Modifiers.COMPILER_GENERATED | Modifiers.DEBUGGER_HIDDEN,
                                        member_name, cloned_params, null);
 
@@ -1392,12 +1488,14 @@ namespace Mono.CSharp
                                            GetSignatureForError (), cycle.GetSignatureForError ());
 
                                        iface_exprs = null;
+                                       PartialContainer.iface_exprs = null;
                                } else {
                                        Report.Error (146, Location,
                                                "Circular base class dependency involving `{0}' and `{1}'",
                                                GetSignatureForError (), cycle.GetSignatureForError ());
 
                                        base_type = null;
+                                       PartialContainer.base_type = null;
                                }
                        }
 
@@ -1411,26 +1509,6 @@ namespace Mono.CSharp
                                                continue;
 
                                        TypeBuilder.AddInterfaceImplementation (iface_type.GetMetaInfo ());
-
-                                       // Ensure the base is always setup
-                                       var compiled_iface = iface_type.MemberDefinition as Interface;
-                                       if (compiled_iface != null) {
-                                               // TODO: Need DefineBaseType only
-                                               compiled_iface.DefineContainer ();
-                                       }
-
-                                       if (iface_type.Interfaces != null) {
-                                               var base_ifaces = new List<TypeSpec> (iface_type.Interfaces);
-                                               for (int i = 0; i < base_ifaces.Count; ++i) {
-                                                       var ii_iface_type = base_ifaces[i];
-                                                       if (spec.AddInterfaceDefined (ii_iface_type)) {
-                                                               TypeBuilder.AddInterfaceImplementation (ii_iface_type.GetMetaInfo ());
-
-                                                               if (ii_iface_type.Interfaces != null)
-                                                                       base_ifaces.AddRange (ii_iface_type.Interfaces);
-                                                       }
-                                               }
-                                       }
                                }
                        }
 
@@ -1453,8 +1531,75 @@ namespace Mono.CSharp
                        return true;
                }
 
+               public override void ExpandBaseInterfaces ()
+               {
+                       if (!IsPartialPart)
+                               DoExpandBaseInterfaces ();
+
+                       base.ExpandBaseInterfaces ();
+               }
+
+               public void DoExpandBaseInterfaces ()
+               {
+                       if ((caching_flags & Flags.InterfacesExpanded) != 0)
+                               return;
+
+                       caching_flags |= Flags.InterfacesExpanded;
+
+                       //
+                       // Expand base interfaces. It cannot be done earlier because all partial
+                       // interface parts need to be defined before the type they are used from
+                       //
+                       if (iface_exprs != null) {
+                               foreach (var iface in iface_exprs) {
+                                       if (iface == null)
+                                               continue;
+
+                                       var td = iface.MemberDefinition as TypeDefinition;
+                                       if (td != null)
+                                               td.DoExpandBaseInterfaces ();
+
+                                       if (iface.Interfaces == null)
+                                               continue;
+
+                                       foreach (var biface in iface.Interfaces) {
+                                               if (spec.AddInterfaceDefined (biface)) {
+                                                       TypeBuilder.AddInterfaceImplementation (biface.GetMetaInfo ());
+                                               }
+                                       }
+                               }
+                       }
+
+                       //
+                       // Include all base type interfaces too, see ImportTypeBase for details
+                       //
+                       if (base_type != null) {
+                               var td = base_type.MemberDefinition as TypeDefinition;
+                               if (td != null)
+                                       td.DoExpandBaseInterfaces ();
+
+                               //
+                               // Simply use base interfaces only, they are all expanded which makes
+                               // it easy to handle generic type argument propagation with single
+                               // inflator only.
+                               //
+                               // interface IA<T> : IB<T>
+                               // interface IB<U> : IC<U>
+                               // interface IC<V>
+                               //
+                               if (base_type.Interfaces != null) {
+                                       foreach (var iface in base_type.Interfaces) {
+                                               spec.AddInterfaceDefined (iface);
+                                       }
+                               }
+                       }
+               }
+
                public override void PrepareEmit ()
                {
+                       if ((caching_flags & Flags.CloseTypeCreated) != 0)
+                               return;
+
                        foreach (var member in members) {
                                var pm = member as IParametersMember;
                                if (pm != null) {
@@ -1633,9 +1778,6 @@ namespace Mono.CSharp
                                        if (compiled_iface != null)
                                                compiled_iface.Define ();
 
-                                       if (Kind == MemberKind.Interface)
-                                               MemberCache.AddInterface (iface_type);
-
                                        ObsoleteAttribute oa = iface_type.GetAttributeObsolete ();
                                        if (oa != null && !IsObsolete)
                                                AttributeTester.Report_ObsoleteMessage (oa, iface_type.GetSignatureForError (), Location, Report);
@@ -1653,21 +1795,25 @@ namespace Mono.CSharp
                                        }
 
                                        if (iface_type.IsGenericOrParentIsGeneric) {
-                                               if (spec.Interfaces != null) {
-                                                       foreach (var prev_iface in iface_exprs) {
-                                                               if (prev_iface == iface_type)
-                                                                       break;
-
-                                                               if (!TypeSpecComparer.Unify.IsEqual (iface_type, prev_iface))
-                                                                       continue;
-
-                                                               Report.Error (695, Location,
-                                                                       "`{0}' cannot implement both `{1}' and `{2}' because they may unify for some type parameter substitutions",
-                                                                       GetSignatureForError (), prev_iface.GetSignatureForError (), iface_type.GetSignatureForError ());
-                                                       }
+                                               foreach (var prev_iface in iface_exprs) {
+                                                       if (prev_iface == iface_type || prev_iface == null)
+                                                               break;
+
+                                                       if (!TypeSpecComparer.Unify.IsEqual (iface_type, prev_iface))
+                                                               continue;
+
+                                                       Report.Error (695, Location,
+                                                               "`{0}' cannot implement both `{1}' and `{2}' because they may unify for some type parameter substitutions",
+                                                               GetSignatureForError (), prev_iface.GetSignatureForError (), iface_type.GetSignatureForError ());
                                                }
                                        }
                                }
+
+                               if (Kind == MemberKind.Interface) {
+                                       foreach (var iface in spec.Interfaces) {
+                                               MemberCache.AddInterface (iface);
+                                       }
+                               }
                        }
 
                        if (base_type != null) {
@@ -1686,11 +1832,6 @@ namespace Mono.CSharp
                                        }
                                }
 
-                               if (base_type.Interfaces != null) {
-                                       foreach (var iface in base_type.Interfaces)
-                                               spec.AddInterface (iface);
-                               }
-
                                var baseContainer = base_type.MemberDefinition as ClassOrStruct;
                                if (baseContainer != null) {
                                        baseContainer.Define ();
@@ -1769,13 +1910,20 @@ namespace Mono.CSharp
                                return;
 
                        string class_indexer_name = null;
-                       has_normal_indexers = true;
 
                        //
                        // Check normal indexers for consistent name, explicit interface implementation
                        // indexers are ignored
                        //
                        foreach (var indexer in indexers) {
+                               //
+                               // FindMembers can return unfiltered full hierarchy names
+                               //
+                               if (indexer.DeclaringType != spec)
+                                       continue;
+
+                               has_normal_indexers = true;
+
                                if (class_indexer_name == null) {
                                        indexer_name = class_indexer_name = indexer.Name;
                                        continue;
@@ -1853,7 +2001,7 @@ namespace Mono.CSharp
                                                continue;
 
                                        //
-                                       // Don't be pendatic over serializable attributes
+                                       // Don't be pedantic when type requires specific layout
                                        //
                                        if (f.OptAttributes != null || PartialContainer.HasStructLayout)
                                                continue;
@@ -1865,10 +2013,6 @@ namespace Mono.CSharp
                                        } else if (TypeSpec.IsReferenceType (f.MemberType)) {
                                                value = "null";
                                        } else {
-                                               // Ignore this warning for struct value fields (they are always initialized)
-                                               if (f.MemberType.IsStruct)
-                                                       continue;
-
                                                value = null;
                                        }
 
@@ -1888,28 +2032,28 @@ namespace Mono.CSharp
                        if (OptAttributes != null)
                                OptAttributes.Emit ();
 
-                       if (!IsTopLevel) {
-                               MemberSpec candidate;
-                               bool overrides = false;
-                               var conflict_symbol = MemberCache.FindBaseMember (this, out candidate, ref overrides);
-                               if (conflict_symbol == null && candidate == null) {
-                                       if ((ModFlags & Modifiers.NEW) != 0)
-                                               Report.Warning (109, 4, Location, "The member `{0}' does not hide an inherited member. The new keyword is not required",
-                                                       GetSignatureForError ());
-                               } else {
-                                       if ((ModFlags & Modifiers.NEW) == 0) {
-                                               if (candidate == null)
-                                                       candidate = conflict_symbol;
+                       if (!IsCompilerGenerated) {
+                               if (!IsTopLevel) {
+                                       MemberSpec candidate;
+                                       bool overrides = false;
+                                       var conflict_symbol = MemberCache.FindBaseMember (this, out candidate, ref overrides);
+                                       if (conflict_symbol == null && candidate == null) {
+                                               if ((ModFlags & Modifiers.NEW) != 0)
+                                                       Report.Warning (109, 4, Location, "The member `{0}' does not hide an inherited member. The new keyword is not required",
+                                                               GetSignatureForError ());
+                                       } else {
+                                               if ((ModFlags & Modifiers.NEW) == 0) {
+                                                       if (candidate == null)
+                                                               candidate = conflict_symbol;
 
-                                               Report.SymbolRelatedToPreviousError (candidate);
-                                               Report.Warning (108, 2, Location, "`{0}' hides inherited member `{1}'. Use the new keyword if hiding was intended",
-                                                       GetSignatureForError (), candidate.GetSignatureForError ());
+                                                       Report.SymbolRelatedToPreviousError (candidate);
+                                                       Report.Warning (108, 2, Location, "`{0}' hides inherited member `{1}'. Use the new keyword if hiding was intended",
+                                                               GetSignatureForError (), candidate.GetSignatureForError ());
+                                               }
                                        }
                                }
-                       }
 
-                       // Run constraints check on all possible generic types
-                       if ((ModFlags & Modifiers.COMPILER_GENERATED) == 0) {
+                               // Run constraints check on all possible generic types
                                if (base_type != null && base_type_expr != null) {
                                        ConstraintChecker.Check (this, base_type, base_type_expr.Location);
                                }
@@ -2238,6 +2382,16 @@ namespace Mono.CSharp
                        cached_method |= CachedMethods.GetHashCode;
                }
 
+               public override void WriteDebugSymbol (MonoSymbolFile file)
+               {
+                       if (IsPartialPart)
+                               return;
+
+                       foreach (var m in members) {
+                               m.WriteDebugSymbol (file);
+                       }
+               }
+
                /// <summary>
                /// Method container contains Equals method
                /// </summary>
@@ -2275,6 +2429,8 @@ namespace Mono.CSharp
 
        public abstract class ClassOrStruct : TypeDefinition
        {
+               public const TypeAttributes StaticClassAttribute = TypeAttributes.Abstract | TypeAttributes.Sealed;
+
                SecurityType declarative_security;
 
                public ClassOrStruct (TypeContainer parent, MemberName name, Attributes attrs, MemberKind kind)
@@ -2284,7 +2440,19 @@ namespace Mono.CSharp
 
                protected override TypeAttributes TypeAttr {
                        get {
-                               return has_static_constructor ? base.TypeAttr : base.TypeAttr | TypeAttributes.BeforeFieldInit;
+                               TypeAttributes ta = base.TypeAttr;
+                               if (!has_static_constructor)
+                                       ta |= TypeAttributes.BeforeFieldInit;
+
+                               if (Kind == MemberKind.Class) {
+                                       ta |= TypeAttributes.AutoLayout | TypeAttributes.Class;
+                                       if (IsStatic)
+                                               ta |= StaticClassAttribute;
+                               } else {
+                                       ta |= TypeAttributes.SequentialLayout;
+                               }
+
+                               return ta;
                        }
                }
 
@@ -2310,16 +2478,6 @@ namespace Mono.CSharp
                        base.AddNameToContainer (symbol, name);
                }
 
-               public override void VerifyMembers ()
-               {
-                       base.VerifyMembers ();
-
-                       if (containers != null) {
-                               foreach (var t in containers)
-                                       t.VerifyMembers ();
-                       }
-               }
-
                public override void ApplyAttributeBuilder (Attribute a, MethodSpec ctor, byte[] cdata, PredefinedAttributes pa)
                {
                        if (a.IsValidSecurityAttribute ()) {
@@ -2344,7 +2502,7 @@ namespace Mono.CSharp
                /// <summary>
                /// Defines the default constructors 
                /// </summary>
-               protected Constructor DefineDefaultConstructor (bool is_static)
+               protected virtual Constructor DefineDefaultConstructor (bool is_static)
                {
                        // The default instance constructor is public
                        // If the class is abstract, the default constructor is protected
@@ -2399,8 +2557,8 @@ namespace Mono.CSharp
        }
 
 
-       // TODO: should be sealed
-       public class Class : ClassOrStruct {
+       public sealed class Class : ClassOrStruct
+       {
                const Modifiers AllowedModifiers =
                        Modifiers.NEW |
                        Modifiers.PUBLIC |
@@ -2412,8 +2570,6 @@ namespace Mono.CSharp
                        Modifiers.STATIC |
                        Modifiers.UNSAFE;
 
-               public const TypeAttributes StaticClassAttribute = TypeAttributes.Abstract | TypeAttributes.Sealed;
-
                public Class (TypeContainer parent, MemberName name, Modifiers mod, Attributes attrs)
                        : base (parent, name, attrs, MemberKind.Class)
                {
@@ -2607,23 +2763,10 @@ namespace Mono.CSharp
                        caching_flags |= Flags.Excluded;
                        return conditions;
                }
-
-               //
-               // FIXME: How do we deal with the user specifying a different
-               // layout?
-               //
-               protected override TypeAttributes TypeAttr {
-                       get {
-                               TypeAttributes ta = base.TypeAttr | TypeAttributes.AutoLayout | TypeAttributes.Class;
-                               if (IsStatic)
-                                       ta |= StaticClassAttribute;
-                               return ta;
-                       }
-               }
        }
 
-       public sealed class Struct : ClassOrStruct {
-
+       public sealed class Struct : ClassOrStruct
+       {
                bool is_unmanaged, has_unmanaged_check_done;
                bool InTransit;
 
@@ -2795,16 +2938,6 @@ namespace Mono.CSharp
                        return ifaces;
                }
 
-               protected override TypeAttributes TypeAttr {
-                       get {
-                               const TypeAttributes DefaultTypeAttributes =
-                                       TypeAttributes.SequentialLayout |
-                                       TypeAttributes.Sealed;
-
-                               return base.TypeAttr | DefaultTypeAttributes;
-                       }
-               }
-
                public override void RegisterFieldForInitialization (MemberCore field, FieldInitializer expression)
                {
                        if ((field.ModFlags & Modifiers.STATIC) == 0) {
@@ -3258,7 +3391,7 @@ namespace Mono.CSharp
                {
                        // for extern static method must be specified either DllImport attribute or MethodImplAttribute.
                        // We are more strict than csc and report this as an error because SRE does not allow emit that
-                       if ((ModFlags & Modifiers.EXTERN) != 0 && !is_external_implementation) {
+                       if ((ModFlags & Modifiers.EXTERN) != 0 && !is_external_implementation && (OptAttributes == null || !OptAttributes.HasResolveError ())) {
                                if (this is Constructor) {
                                        Report.Warning (824, 1, Location,
                                                "Constructor `{0}' is marked `external' but has no external implementation specified", GetSignatureForError ());
@@ -3366,6 +3499,16 @@ namespace Mono.CSharp
                        get { return IsExplicitImpl || base.IsUsed; }
                }
 
+               public override void SetConstraints (List<Constraints> constraints_list)
+               {
+                       if (((ModFlags & Modifiers.OVERRIDE) != 0 || IsExplicitImpl)) {
+                               Report.Error (460, Location,
+                                       "`{0}': Cannot specify constraints for overrides and explicit interface implementation methods",
+                                       GetSignatureForError ());
+                       }
+
+                       base.SetConstraints (constraints_list);
+               }
        }
 
        public abstract class MemberBase : MemberCore
@@ -3379,7 +3522,9 @@ namespace Mono.CSharp
                {
                        this.Parent = parent;
                        this.type_expr = type;
-                       ModFlags = ModifiersExtensions.Check (allowed_mod, mod, def_mod, Location, Report);
+
+                       if (name != MemberName.Null)
+                               ModFlags = ModifiersExtensions.Check (allowed_mod, mod, def_mod, Location, Report);
                }
 
                #region Properties