Merge pull request #2869 from BrzVlad/feature-mod-union-opt
[mono.git] / mcs / mcs / class.cs
index aeea78ec730329a7353c850120db1309e0bc6c21..bcf7ddffa21cd928e8b8a6cbfb811c2735940f7f 100644 (file)
@@ -92,7 +92,7 @@ namespace Mono.CSharp
                }
 
                //
-               // Any unattached attributes during parsing get added here. User
+               // Any unattached attributes during parsing get added here. Used
                // by FULL_AST mode
                //
                public Attributes UnattachedAttributes {
@@ -530,7 +530,6 @@ namespace Mono.CSharp
 
                bool has_normal_indexers;
                string indexer_name;
-               protected bool requires_delayed_unmanagedtype_check;
                bool error;
                bool members_defined;
                bool members_defined_ok;
@@ -941,7 +940,8 @@ namespace Mono.CSharp
 
                TypeParameterSpec[] ITypeDefinition.TypeParameters {
                        get {
-                               return PartialContainer.CurrentTypeParameters.Types;
+                               var ctp = PartialContainer.CurrentTypeParameters;
+                               return ctp == null ? TypeParameterSpec.EmptyTypes : ctp.Types;
                        }
                }
 
@@ -1729,21 +1729,9 @@ namespace Mono.CSharp
                                return;
 
                        foreach (var member in members) {
-                               var pbm = member as PropertyBasedMember;
-                               if (pbm != null) {
+                               var pbm = member as MemberBase;
+                               if (pbm != null)
                                        pbm.PrepareEmit ();
-                                       continue;
-                               }
-
-                               var mc = member as MethodCore;
-                               if (mc != null) {
-                                       mc.PrepareEmit ();
-                                       continue;
-                               }
-
-                               var c = member as Const;
-                               if (c != null)
-                                       c.DefineValue ();
                        }
 
                        base.PrepareEmit ();
@@ -1802,6 +1790,10 @@ namespace Mono.CSharp
 
                        this.spec = spec;
                        current_type = null;
+                       if (class_partial_parts != null) {
+                               foreach (var part in class_partial_parts)
+                                       part.spec = spec;
+                       }
                }
 
                public override void RemoveContainer (TypeContainer cont)
@@ -1909,9 +1901,7 @@ namespace Mono.CSharp
                                        if (compiled_iface != null)
                                                compiled_iface.Define ();
 
-                                       ObsoleteAttribute oa = iface_type.GetAttributeObsolete ();
-                                       if (oa != null && !IsObsolete)
-                                               AttributeTester.Report_ObsoleteMessage (oa, iface_type.GetSignatureForError (), Location, Report);
+                                       iface_type.CheckObsoleteness (this, Location);
 
                                        if (iface_type.Arity > 0) {
                                                // TODO: passing `this' is wrong, should be base type iface instead
@@ -1952,9 +1942,7 @@ namespace Mono.CSharp
                                // Run checks skipped during DefineType (e.g FullNamedExpression::ResolveAsType)
                                //
                                if (base_type_expr != null) {
-                                       ObsoleteAttribute obsolete_attr = base_type.GetAttributeObsolete ();
-                                       if (obsolete_attr != null && !IsObsolete)
-                                               AttributeTester.Report_ObsoleteMessage (obsolete_attr, base_type.GetSignatureForError (), base_type_expr.Location, Report);
+                                       base_type.CheckObsoleteness (this, base_type_expr.Location);
 
                                        if (IsGenericOrParentIsGeneric && base_type.IsAttribute) {
                                                Report.Error (698, base_type_expr.Location,
@@ -2011,15 +1999,6 @@ namespace Mono.CSharp
                                CheckPairedOperators ();
                        }
 
-                       if (requires_delayed_unmanagedtype_check) {
-                               requires_delayed_unmanagedtype_check = false;
-                               foreach (var member in members) {
-                                       var f = member as Field;
-                                       if (f != null && f.MemberType != null && f.MemberType.IsPointer)
-                                               TypeManager.VerifyUnmanaged (Module, f.MemberType, f.Location);
-                               }
-                       }
-
                        ComputeIndexerName();
 
                        if (HasEquals && !HasGetHashCode) {
@@ -2723,6 +2702,22 @@ namespace Mono.CSharp
                        return true;
                }
 
+               public override void PrepareEmit ()
+               {
+                       var s = this as Struct;
+                       if (s == null || !s.HasUnmanagedCheckDone) {
+                               for (int i = 0; i < Members.Count; ++i) {
+                                       var f = Members [i] as Field;
+                                       if (f == null || f.MemberType == null || !f.MemberType.IsPointer)
+                                               continue;
+
+                                       TypeManager.VerifyUnmanaged (Module, f.MemberType, f.Location);
+                               }
+                       }
+
+                       base.PrepareEmit ();
+               }
+
                public override void Emit ()
                {
                        if (!has_static_constructor && HasStaticFieldInitializer) {
@@ -2971,7 +2966,7 @@ namespace Mono.CSharp
 
        public sealed class Struct : ClassOrStruct
        {
-               bool is_unmanaged, has_unmanaged_check_done;
+               bool is_unmanaged, has_unmanaged_check_done, requires_delayed_unmanagedtype_check;
                bool InTransit;
 
                // <summary>
@@ -3101,6 +3096,12 @@ namespace Mono.CSharp
                        base.Emit ();
                }
 
+               public bool HasUnmanagedCheckDone {
+                       get {
+                               return has_unmanaged_check_done;
+                       }
+               }
+
                bool HasUserDefaultConstructor ()
                {
                        foreach (var m in PartialContainer.Members) {
@@ -3423,7 +3424,7 @@ namespace Mono.CSharp
                                        ModFlags |= Modifiers.NEW;
                                        if (!IsCompilerGenerated) {
                                                Report.SymbolRelatedToPreviousError (base_member);
-                                               if (!IsInterface && (base_member.Modifiers & (Modifiers.ABSTRACT | Modifiers.VIRTUAL | Modifiers.OVERRIDE)) != 0) {
+                                               if ((base_member.Kind & MemberKind.NestedMask) == 0 && !IsInterface && (base_member.Modifiers & (Modifiers.ABSTRACT | Modifiers.VIRTUAL | Modifiers.OVERRIDE)) != 0) {
                                                        Report.Warning (114, 2, Location, "`{0}' hides inherited member `{1}'. To make the current member override that implementation, add the override keyword. Otherwise add the new keyword",
                                                                GetSignatureForError (), base_member.GetSignatureForError ());
                                                } else {
@@ -3434,9 +3435,16 @@ namespace Mono.CSharp
                                }
 
                                if (!IsInterface && base_member.IsAbstract && !overrides && !IsStatic) {
-                                       Report.SymbolRelatedToPreviousError (base_member);
-                                       Report.Error (533, Location, "`{0}' hides inherited abstract member `{1}'",
-                                               GetSignatureForError (), base_member.GetSignatureForError ());
+                                       switch (base_member.Kind) {
+                                       case MemberKind.Event:
+                                       case MemberKind.Indexer:
+                                       case MemberKind.Method:
+                                       case MemberKind.Property:
+                                               Report.SymbolRelatedToPreviousError (base_member);
+                                               Report.Error (533, Location, "`{0}' hides inherited abstract member `{1}'",
+                                                       GetSignatureForError (), base_member.GetSignatureForError ());
+                                               break;
+                                       }
                                }
                        }
 
@@ -3762,6 +3770,9 @@ namespace Mono.CSharp
                        get {
                                return type_expr;
                        }
+                       set {
+                               type_expr = value;
+                       }
                }
 
                #endregion
@@ -3867,6 +3878,12 @@ namespace Mono.CSharp
                        return Parent.GetSignatureForDocumentation () + "." + MemberName.Basename;
                }
 
+               public virtual void PrepareEmit ()
+               {
+                       if (member_type != null && type_expr != null)
+                               member_type.CheckObsoleteness (this, type_expr.Location);
+               }
+
                protected virtual bool ResolveMemberType ()
                {
                        if (member_type != null)