X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mcs%2Fmcs%2Fdecl.cs;h=6b341f0de709f57eaea7ab56f55ae425ca5b0d56;hb=f8be5461467b13a0423adc77b4f0ad897537d532;hp=eec79dc079789b3257249cd65b92b217d67dba73;hpb=26b4edf53aa74a37fcb806d3a77e97629711ee6b;p=mono.git diff --git a/mcs/mcs/decl.cs b/mcs/mcs/decl.cs index eec79dc0797..6b341f0de70 100644 --- a/mcs/mcs/decl.cs +++ b/mcs/mcs/decl.cs @@ -9,7 +9,6 @@ // Copyright 2001 Ximian, Inc (http://www.ximian.com) // Copyright 2004-2008 Novell, Inc // -// TODO: Move the method verification stuff from the class.cs and interface.cs here // using System; @@ -27,6 +26,9 @@ using System.Xml; namespace Mono.CSharp { + // + // Better name would be DottenName + // public class MemberName { public readonly string Name; public readonly TypeArguments TypeArguments; @@ -95,6 +97,7 @@ namespace Mono.CSharp { this.Left = (right.Left == null) ? left : new MemberName (left, right.Left); } + // TODO: Remove public string GetName () { return GetName (false); @@ -114,20 +117,10 @@ namespace Mono.CSharp { public string GetName (bool is_generic) { string name = is_generic ? Basename : Name; - string connect = is_double_colon ? "::" : "."; if (Left != null) - return Left.GetName (is_generic) + connect + name; - else - return name; - } + return Left.GetName (is_generic) + (is_double_colon ? "::" : ".") + name; - public string GetTypeName () - { - string connect = is_double_colon ? "::" : "."; - if (Left != null) - return Left.GetTypeName () + connect + MakeName (Name, TypeArguments); - else - return MakeName (Name, TypeArguments); + return name; } public ATypeNameExpression GetTypeExpression () @@ -159,27 +152,10 @@ namespace Mono.CSharp { get { if (TypeArguments != null) return MakeName (Name, TypeArguments); - else - return Name; + return Name; } } - public string MethodName { - get { - string connect = is_double_colon ? "::" : "."; - if (Left != null) - return Left.FullyQualifiedName + connect + Name; - else - return Name; - } - } - - // Please use this only for error reporting. For normal uses, just use the Equals and GetHashCode methods that make - // MemberName a proper hash key, and avoid tons of memory allocations - string FullyQualifiedName { - get { return TypeArguments == null ? MethodName : MethodName + "<" + TypeArguments.GetSignatureForError () + ">"; } - } - public string GetSignatureForError () { string append = TypeArguments == null ? "" : "<" + TypeArguments.GetSignatureForError () + ">"; @@ -245,8 +221,8 @@ namespace Mono.CSharp { { if (args == null) return name; - else - return name + "`" + args.Count; + + return name + "`" + args.Count; } public static string MakeName (string name, int count) @@ -265,6 +241,7 @@ namespace Mono.CSharp { /// protected string cached_name; + // TODO: Remove in favor of MemberName public string Name { get { if (cached_name == null) @@ -372,14 +349,21 @@ namespace Mono.CSharp { } } else { if ((ModFlags & (Modifiers.ABSTRACT | Modifiers.EXTERN | Modifiers.PARTIAL)) == 0) { - if (RootContext.Version >= LanguageVersion.LINQ && this is Property.PropertyMethod && - !(this is Indexer.GetIndexerMethod || this is Indexer.SetIndexerMethod)) { - Report.Error (840, Location, "`{0}' must have a body because it is not marked abstract or extern. The property can be automatically implemented when you define both accessors", - GetSignatureForError ()); - } else { - Report.Error (501, Location, "`{0}' must have a body because it is not marked abstract, extern, or partial", - GetSignatureForError ()); + if (RootContext.Version >= LanguageVersion.V_3) { + Property.PropertyMethod pm = this as Property.PropertyMethod; + if (pm is Indexer.GetIndexerMethod || pm is Indexer.SetIndexerMethod) + pm = null; + + if (pm != null && (pm.Property.Get.IsDummy || pm.Property.Set.IsDummy)) { + Report.Error (840, Location, + "`{0}' must have a body because it is not marked abstract or extern. The property can be automatically implemented when you define both accessors", + GetSignatureForError ()); + return false; + } } + + Report.Error (501, Location, "`{0}' must have a body because it is not marked abstract, extern, or partial", + GetSignatureForError ()); return false; } } @@ -404,8 +388,8 @@ namespace Mono.CSharp { return; } - if (((Parent.ModFlags & Modifiers.SEALED) != 0) && - ((ModFlags & Modifiers.OVERRIDE) == 0) && (Name != "Finalize")) { + if ((Parent.ModFlags & Modifiers.SEALED) != 0 && (ModFlags & Modifiers.OVERRIDE) == 0 && + !(this is Destructor)) { Report.Warning (628, 4, Location, "`{0}': new protected member declared in sealed class", GetSignatureForError ()); return; @@ -474,10 +458,10 @@ namespace Mono.CSharp { caching_flags &= ~Flags.Obsolete_Undetected; - if (OptAttributes == null || TypeManager.obsolete_attribute_type == null) + if (OptAttributes == null) return null; - Attribute obsolete_attr = OptAttributes.Search (TypeManager.obsolete_attribute_type); + Attribute obsolete_attr = OptAttributes.Search (PredefinedAttributes.Get.Obsolete); if (obsolete_attr == null) return null; @@ -573,17 +557,15 @@ namespace Mono.CSharp { while (TypeManager.HasElementType (p)) p = TypeManager.GetElementType (p); -#if GMCS_SOURCE - if (p.IsGenericParameter) + if (TypeManager.IsGenericParameter (p)) return true; if (TypeManager.IsGenericType (p)) { - foreach (Type t in p.GetGenericArguments ()) { + foreach (Type t in TypeManager.GetTypeArguments (p)) { if (!IsAccessibleAs (t)) return false; } } -#endif for (Type p_parent = null; p != null; p = p_parent) { p_parent = p.DeclaringType; @@ -595,57 +577,57 @@ namespace Mono.CSharp { for (MemberCore mc = this; !same_access_restrictions && mc != null && mc.Parent != null; mc = mc.Parent) { AccessLevel al = GetAccessLevelFromModifiers (mc.ModFlags); switch (pAccess) { - case AccessLevel.Internal: - if (al == AccessLevel.Private || al == AccessLevel.Internal) - same_access_restrictions = TypeManager.IsThisOrFriendAssembly (p.Assembly); - - break; - - case AccessLevel.Protected: - if (al == AccessLevel.Protected) { - same_access_restrictions = mc.Parent.IsBaseType (p_parent); - break; - } - - if (al == AccessLevel.Private) { - // - // When type is private and any of its parents derives from - // protected type then the type is accessible - // - while (mc.Parent != null) { - if (mc.Parent.IsBaseType (p_parent)) - same_access_restrictions = true; - mc = mc.Parent; - } - } - - break; - - case AccessLevel.ProtectedOrInternal: - if (al == AccessLevel.Protected) - same_access_restrictions = mc.Parent.IsBaseType (p_parent); - else if (al == AccessLevel.Internal) - same_access_restrictions = TypeManager.IsThisOrFriendAssembly (p.Assembly); - else if (al == AccessLevel.ProtectedOrInternal) - same_access_restrictions = mc.Parent.IsBaseType (p_parent) && - TypeManager.IsThisOrFriendAssembly (p.Assembly); - + case AccessLevel.Internal: + if (al == AccessLevel.Private || al == AccessLevel.Internal) + same_access_restrictions = TypeManager.IsThisOrFriendAssembly (p.Assembly); + + break; + + case AccessLevel.Protected: + if (al == AccessLevel.Protected) { + same_access_restrictions = mc.Parent.IsBaseType (p_parent); break; - - case AccessLevel.Private: + } + + if (al == AccessLevel.Private) { // - // Both are private and share same parent + // When type is private and any of its parents derives from + // protected type then the type is accessible // - if (al == AccessLevel.Private) - same_access_restrictions = TypeManager.IsEqual (mc.Parent.TypeBuilder, p_parent); - - break; - - default: - throw new InternalErrorException (al.ToString ()); + while (mc.Parent != null) { + if (mc.Parent.IsBaseType (p_parent)) + same_access_restrictions = true; + mc = mc.Parent; + } + } + + break; + + case AccessLevel.ProtectedOrInternal: + if (al == AccessLevel.Protected) + same_access_restrictions = mc.Parent.IsBaseType (p_parent); + else if (al == AccessLevel.Internal) + same_access_restrictions = TypeManager.IsThisOrFriendAssembly (p.Assembly); + else if (al == AccessLevel.ProtectedOrInternal) + same_access_restrictions = mc.Parent.IsBaseType (p_parent) && + TypeManager.IsThisOrFriendAssembly (p.Assembly); + + break; + + case AccessLevel.Private: + // + // Both are private and share same parent + // + if (al == AccessLevel.Private) + same_access_restrictions = TypeManager.IsEqual (mc.Parent.TypeBuilder, p_parent); + + break; + + default: + throw new InternalErrorException (al.ToString ()); } } - + if (!same_access_restrictions) return false; } @@ -699,9 +681,9 @@ namespace Mono.CSharp { caching_flags &= ~Flags.HasCompliantAttribute_Undetected; - if (OptAttributes != null && TypeManager.cls_compliant_attribute_type != null) { + if (OptAttributes != null) { Attribute cls_attribute = OptAttributes.Search ( - TypeManager.cls_compliant_attribute_type); + PredefinedAttributes.Get.CLSCompliant); if (cls_attribute != null) { caching_flags |= Flags.HasClsCompliantAttribute; bool value = cls_attribute.GetClsCompliantAttributeValue (); @@ -752,24 +734,31 @@ namespace Mono.CSharp { { if (!IsClsComplianceRequired ()) { if (HasClsCompliantAttribute && Report.WarningLevel >= 2) { - if (!IsExposedFromAssembly ()) - Report.Warning (3019, 2, Location, "CLS compliance checking will not be performed on `{0}' because it is not visible from outside this assembly", GetSignatureForError ()); - if (!CodeGen.Assembly.IsClsCompliant) - Report.Warning (3021, 2, Location, "`{0}' does not need a CLSCompliant attribute because the assembly is not marked as CLS-compliant", GetSignatureForError ()); + if (!IsExposedFromAssembly ()) { + Attribute a = OptAttributes.Search (PredefinedAttributes.Get.CLSCompliant); + Report.Warning (3019, 2, a.Location, "CLS compliance checking will not be performed on `{0}' because it is not visible from outside this assembly", GetSignatureForError ()); + } + + if (!CodeGen.Assembly.IsClsCompliant) { + Attribute a = OptAttributes.Search (PredefinedAttributes.Get.CLSCompliant); + Report.Warning (3021, 2, a.Location, "`{0}' does not need a CLSCompliant attribute because the assembly is not marked as CLS-compliant", GetSignatureForError ()); + } } return false; } if (HasClsCompliantAttribute) { if (CodeGen.Assembly.ClsCompliantAttribute == null && !CodeGen.Assembly.IsClsCompliant) { - Report.Warning (3014, 1, Location, + Attribute a = OptAttributes.Search (PredefinedAttributes.Get.CLSCompliant); + Report.Warning (3014, 1, a.Location, "`{0}' cannot be marked as CLS-compliant because the assembly is not marked as CLS-compliant", GetSignatureForError ()); return false; } if (!Parent.IsClsComplianceRequired ()) { - Report.Warning (3018, 1, Location, "`{0}' cannot be marked as CLS-compliant because it is a member of non CLS-compliant type `{1}'", + Attribute a = OptAttributes.Search (PredefinedAttributes.Get.CLSCompliant); + Report.Warning (3018, 1, a.Location, "`{0}' cannot be marked as CLS-compliant because it is a member of non CLS-compliant type `{1}'", GetSignatureForError (), Parent.GetSignatureForError ()); return false; } @@ -887,6 +876,8 @@ namespace Mono.CSharp { protected readonly bool is_generic; readonly int count_type_params; + protected TypeParameter[] type_params; + TypeParameter[] type_param_list; // // Whether we are Generic @@ -936,6 +927,9 @@ namespace Mono.CSharp { return true; } + if (((mc.ModFlags | symbol.ModFlags) & Modifiers.COMPILER_GENERATED) != 0) + return true; + if (symbol.EnableOverloadChecks (mc)) return true; @@ -945,13 +939,13 @@ namespace Mono.CSharp { return false; } - if (this is RootTypes) { + if (this is ModuleContainer) { Report.Error (101, symbol.Location, "The namespace `{0}' already contains a definition for `{1}'", ((DeclSpace)symbol).NamespaceEntry.GetSignatureForError (), symbol.MemberName.Name); } else if (symbol is TypeParameter) { Report.Error (692, symbol.Location, - "Duplicate type parameter `{0}'", name); + "Duplicate type parameter `{0}'", symbol.GetSignatureForError ()); } else { Report.Error (102, symbol.Location, "The type `{0}' already contains a definition for `{1}'", @@ -961,7 +955,7 @@ namespace Mono.CSharp { return false; } - protected virtual void RemoveFromContainer (string name) + protected void RemoveFromContainer (string name) { defined_names.Remove (name); } @@ -989,6 +983,11 @@ namespace Mono.CSharp { get { return (Parent != null && Parent.Parent == null); } } + public virtual bool IsUnmanagedType () + { + return false; + } + public virtual void CloseType () { if ((caching_flags & Flags.CloseTypeCreated) == 0){ @@ -1011,7 +1010,7 @@ namespace Mono.CSharp { } protected virtual TypeAttributes TypeAttr { - get { return CodeGen.Module.DefaultCharSetType; } + get { return Module.DefaultCharSetType; } } /// @@ -1019,19 +1018,6 @@ namespace Mono.CSharp { /// public abstract TypeBuilder DefineType (); - /// - /// Define all members, but don't apply any attributes or do anything which may - /// access not-yet-defined classes. This method also creates the MemberCache. - /// - public virtual bool DefineMembers () - { - if (((ModFlags & Modifiers.NEW) != 0) && IsTopLevel) { - Report.Error (1530, Location, "Keyword `new' is not allowed on namespace elements"); - return false; - } - return true; - } - protected void Error_MissingPartialModifier (MemberCore type) { Report.Error (260, type.Location, @@ -1041,7 +1027,6 @@ namespace Mono.CSharp { public override void Emit () { -#if GMCS_SOURCE if (type_params != null) { int offset = count_type_params - type_params.Length; for (int i = offset; i < type_params.Length; i++) @@ -1049,8 +1034,7 @@ namespace Mono.CSharp { } if ((ModFlags & Modifiers.COMPILER_GENERATED) != 0 && !Parent.IsCompilerGenerated) - TypeBuilder.SetCustomAttribute (TypeManager.GetCompilerGeneratedAttribute (Location)); -#endif + PredefinedAttributes.Get.CompilerGenerated.EmitAttribute (TypeBuilder); base.Emit (); } @@ -1062,8 +1046,8 @@ namespace Mono.CSharp { public bool CheckAccessLevel (Type check_type) { - TypeBuilder tb = TypeBuilder; -#if GMCS_SOURCE + Type tb = TypeBuilder; + if (this is GenericMethod) { tb = Parent.TypeBuilder; @@ -1072,18 +1056,22 @@ namespace Mono.CSharp { if (TypeBuilder == null) return true; } -#endif check_type = TypeManager.DropGenericTypeArguments (check_type); if (check_type == tb) return true; + // TODO: When called from LocalUsingAliasEntry tb is null + // because we are in RootDeclSpace + if (tb == null) + tb = typeof (RootDeclSpace); + // // Broken Microsoft runtime, return public for arrays, no matter what // the accessibility is for their underlying class, and they return // NonPublic visibility for pointers // - if (check_type.IsArray || check_type.IsPointer) + if (TypeManager.HasElementType (check_type)) return CheckAccessLevel (TypeManager.GetElementType (check_type)); TypeAttributes check_attr = check_type.Attributes & TypeAttributes.VisibilityMask; @@ -1183,7 +1171,6 @@ namespace Mono.CSharp { if ((t == null) || !CheckAccessLevel (t)) continue; -#if GMCS_SOURCE if (!TypeManager.IsGenericType (current_type)) return t; @@ -1192,6 +1179,7 @@ namespace Mono.CSharp { for (int i = 0; i < args.Length; i++) targs [i] = args [i]; +#if GMCS_SOURCE t = t.MakeGenericType (targs); #endif @@ -1255,21 +1243,19 @@ namespace Mono.CSharp { get; } - public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb) + public virtual ModuleContainer Module { + get { return Parent.Module; } + } + + public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb, PredefinedAttributes pa) { - if (a.Type == TypeManager.required_attr_type) { + if (a.Type == pa.Required) { Report.Error (1608, a.Location, "The RequiredAttribute attribute is not permitted on C# types"); return; } TypeBuilder.SetCustomAttribute (cb); } - // - // Extensions for generics - // - protected TypeParameter[] type_params; - TypeParameter[] type_param_list; - TypeParameter[] initialize_type_params () { if (type_param_list != null) @@ -1348,9 +1334,14 @@ namespace Mono.CSharp { } } + Variance variance = name.Variance; + if (name.Variance != Variance.None && !(this is Delegate || this is Interface)) { + Report.Error (1960, name.Location, "Variant type parameters can only be used with interfaces and delegates"); + variance = Variance.None; + } + type_params [i] = new TypeParameter ( - Parent, this, name.Name, constraints, name.OptAttributes, - Location); + Parent, this, name.Name, constraints, name.OptAttributes, variance, Location); AddToContainer (type_params [i], name.Name); } @@ -1861,9 +1852,10 @@ namespace Mono.CSharp { AddMember (mi.MemberType, GetBindingFlags (mc.ModFlags), Container, mi.Name, mi); } - public void AddGenericMember (MemberInfo mi, MemberCore mc) + public void AddGenericMember (MemberInfo mi, InterfaceMemberBase mc) { - AddMember (mi.MemberType, GetBindingFlags (mc.ModFlags), Container, mc.MemberName.Basename, mi); + AddMember (mi.MemberType, GetBindingFlags (mc.ModFlags), Container, + MemberName.MakeName (mc.GetFullName (mc.MemberName), mc.MemberName.TypeArguments), mi); } public void AddNestedType (DeclSpace type) @@ -2322,9 +2314,6 @@ namespace Mono.CSharp { return null; EntryType entry_type = EntryType.Static | EntryType.Method | EntryType.NotExtensionMethod; - if (publicOnly) { - entry_type |= EntryType.Public; - } EntryType found_entry_type = entry_type & ~EntryType.NotExtensionMethod; ArrayList candidates = null; @@ -2332,6 +2321,16 @@ namespace Mono.CSharp { if ((entry.EntryType & entry_type) == found_entry_type) { MethodBase mb = (MethodBase)entry.Member; + // Simple accessibility check + if ((entry.EntryType & EntryType.Public) == 0 && publicOnly) { + MethodAttributes ma = mb.Attributes & MethodAttributes.MemberAccessMask; + if (ma != MethodAttributes.Assembly && ma != MethodAttributes.FamORAssem) + continue; + + if (!TypeManager.IsThisOrFriendAssembly (mb.DeclaringType.Assembly)) + continue; + } + IMethodData md = TypeManager.GetMethod (mb); AParametersCollection pd = md == null ? TypeManager.GetParameterData (mb) : md.ParameterInfo; @@ -2388,7 +2387,7 @@ namespace Mono.CSharp { if (is_property) { if ((entry.EntryType & EntryType.Field) != 0) { fi = (FieldInfo)entry.Member; - cmp_attrs = Parameters.EmptyReadOnlyParameters; + cmp_attrs = ParametersCompiled.EmptyReadOnlyParameters; } else { pi = (PropertyInfo) entry.Member; cmp_attrs = TypeManager.GetParameterData (pi); @@ -2418,7 +2417,7 @@ namespace Mono.CSharp { // // Check for assembly methods // - if (mi.DeclaringType.Assembly != CodeGen.Assembly.Builder) + if (fi.DeclaringType.Assembly != CodeGen.Assembly.Builder) continue; break; } @@ -2565,31 +2564,31 @@ namespace Mono.CSharp { // TODO: Does anyone know easier way how to detect that member is internal ? switch (member_entry.EntryType & EntryType.MaskType) { - case EntryType.Constructor: - continue; - - case EntryType.Field: - if ((((FieldInfo)member_entry.Member).Attributes & (FieldAttributes.Assembly | FieldAttributes.Public)) == FieldAttributes.Assembly) - continue; - break; - - case EntryType.Method: - if ((((MethodInfo)member_entry.Member).Attributes & (MethodAttributes.Assembly | MethodAttributes.Public)) == MethodAttributes.Assembly) - continue; - break; - - case EntryType.Property: - PropertyInfo pi = (PropertyInfo)member_entry.Member; - if (pi.GetSetMethod () == null && pi.GetGetMethod () == null) - continue; - break; - - case EntryType.Event: - EventInfo ei = (EventInfo)member_entry.Member; - MethodInfo mi = ei.GetAddMethod (); - if ((mi.Attributes & (MethodAttributes.Assembly | MethodAttributes.Public)) == MethodAttributes.Assembly) - continue; - break; + case EntryType.Constructor: + continue; + + case EntryType.Field: + if ((((FieldInfo)member_entry.Member).Attributes & (FieldAttributes.Assembly | FieldAttributes.Public)) == FieldAttributes.Assembly) + continue; + break; + + case EntryType.Method: + if ((((MethodInfo)member_entry.Member).Attributes & (MethodAttributes.Assembly | MethodAttributes.Public)) == MethodAttributes.Assembly) + continue; + break; + + case EntryType.Property: + PropertyInfo pi = (PropertyInfo)member_entry.Member; + if (pi.GetSetMethod () == null && pi.GetGetMethod () == null) + continue; + break; + + case EntryType.Event: + EventInfo ei = (EventInfo)member_entry.Member; + MethodInfo mi = ei.GetAddMethod (); + if ((mi.Attributes & (MethodAttributes.Assembly | MethodAttributes.Public)) == MethodAttributes.Assembly) + continue; + break; } string lcase = ((string)entry.Key).ToLower (System.Globalization.CultureInfo.InvariantCulture); locase_table [lcase] = member_entry.Member; @@ -2640,19 +2639,23 @@ namespace Mono.CSharp { Report.SymbolRelatedToPreviousError (entry.Member); switch (result) { - case AttributeTester.Result.RefOutArrayError: - Report.Warning (3006, 1, method.Location, "Overloaded method `{0}' differing only in ref or out, or in array rank, is not CLS-compliant", method.GetSignatureForError ()); - continue; - case AttributeTester.Result.ArrayArrayError: - Report.Warning (3007, 1, method.Location, "Overloaded method `{0}' differing only by unnamed array types is not CLS-compliant", method.GetSignatureForError ()); - continue; + case AttributeTester.Result.RefOutArrayError: + Report.Warning (3006, 1, method.Location, + "Overloaded method `{0}' differing only in ref or out, or in array rank, is not CLS-compliant", + method.GetSignatureForError ()); + continue; + case AttributeTester.Result.ArrayArrayError: + Report.Warning (3007, 1, method.Location, + "Overloaded method `{0}' differing only by unnamed array types is not CLS-compliant", + method.GetSignatureForError ()); + continue; } throw new NotImplementedException (result.ToString ()); } } - public bool CheckExistingMembersOverloads (MemberCore member, string name, Parameters parameters) + public bool CheckExistingMembersOverloads (MemberCore member, string name, ParametersCompiled parameters) { ArrayList entries = (ArrayList)member_hash [name]; if (entries == null) @@ -2672,12 +2675,12 @@ namespace Mono.CSharp { p_types = pd.Types; } else { MethodBase mb = (MethodBase) ce.Member; -#if GMCS_SOURCE + // TODO: This is more like a hack, because we are adding generic methods // twice with and without arity name - if (mb.IsGenericMethod && !member.MemberName.IsGeneric) + if (TypeManager.IsGenericMethod (mb) && !member.MemberName.IsGeneric) continue; -#endif + pd = TypeManager.GetParameterData (mb); p_types = pd.Types; } @@ -2693,11 +2696,11 @@ namespace Mono.CSharp { type_b = p_types [ii]; #if GMCS_SOURCE - if (type_a.IsGenericParameter && type_a.DeclaringMethod != null) - type_a = null; + if (TypeManager.IsGenericParameter (type_a) && type_a.DeclaringMethod != null) + type_a = typeof (TypeParameter); - if (type_b.IsGenericParameter && type_b.DeclaringMethod != null) - type_b = null; + if (TypeManager.IsGenericParameter (type_b) && type_b.DeclaringMethod != null) + type_b = typeof (TypeParameter); #endif if ((pd.FixedParameters [ii].ModFlags & Parameter.Modifier.ISBYREF) != (parameters.FixedParameters [ii].ModFlags & Parameter.Modifier.ISBYREF)) @@ -2737,9 +2740,15 @@ namespace Mono.CSharp { "A partial method declaration and partial method implementation must be both an extension method or neither"); } } else { - Report.Error (663, member.Location, - "An overloaded method `{0}' cannot differ on use of parameter modifiers only", - member.GetSignatureForError ()); + if (member is Constructor) { + Report.Error (851, member.Location, + "Overloaded contructor `{0}' cannot differ on use of parameter modifiers only", + member.GetSignatureForError ()); + } else { + Report.Error (663, member.Location, + "Overloaded method `{0}' cannot differ on use of parameter modifiers only", + member.GetSignatureForError ()); + } } return false; }