**** Merged from MCS ****
[mono.git] / mcs / gmcs / ecore.cs
index 0b962aa6ffdbfd5db665fb43e833bb05dd4b0fef..8dd46c5aee3555a64dd43742f0b77feea978e4b5 100755 (executable)
@@ -485,7 +485,11 @@ namespace Mono.CSharp {
                        else if (t == TypeManager.bool_type)
                                return new BoolConstant ((bool) v);
                        else if (TypeManager.IsEnumType (t)){
-                               Constant e = Constantify (v, TypeManager.TypeToCoreType (v.GetType ()));
+                               Type real_type = TypeManager.TypeToCoreType (v.GetType ());
+                               if (real_type == t)
+                                       real_type = real_type.UnderlyingSystemType;
+
+                               Constant e = Constantify (v, real_type);
 
                                return new EnumConstant (e, t);
                        } else
@@ -1552,6 +1556,10 @@ namespace Mono.CSharp {
                {
                        return Child.ConvertToInt ();
                }
+               
+               public override bool IsZeroInteger {
+                       get { return Child.IsZeroInteger; }
+               }
        }
 
        /// <summary>
@@ -1565,11 +1573,13 @@ namespace Mono.CSharp {
                public BoxedCast (Expression expr)
                        : base (expr, TypeManager.object_type) 
                {
+                       eclass = ExprClass.Value;
                }
 
                public BoxedCast (Expression expr, Type target_type)
                        : base (expr, target_type)
                {
+                       eclass = ExprClass.Value;
                }
                
                public override Expression DoResolve (EmitContext ec)
@@ -2095,6 +2105,11 @@ namespace Mono.CSharp {
                        //
                        Block current_block = ec.CurrentBlock;
                        if (current_block != null){
+                               if (is_base && current_block.IsVariableNameUsedInChildBlock(Name)) {
+                                       Report.Error (135, Location, "'" + Name + "' has a different meaning in a child block");
+                                       return null;
+                               }
+
                                LocalInfo vi = current_block.GetLocalInfo (Name);
                                if (vi != null){
                                        Expression var;
@@ -2288,6 +2303,7 @@ namespace Mono.CSharp {
                {
                        if (Type == TypeManager.enum_type ||
                            (Type == TypeManager.value_type && RootContext.StdLib) ||
+                           Type == TypeManager.multicast_delegate_type ||
                            Type == TypeManager.delegate_type ||
                            Type == TypeManager.array_type)
                                return false;
@@ -2331,6 +2347,11 @@ namespace Mono.CSharp {
                        return Type == tobj.Type;
                }
 
+               public override int GetHashCode ()
+               {
+                       return Type.GetHashCode ();
+               }
+               
                public override string ToString ()
                {
                        return Name;
@@ -2865,9 +2886,6 @@ namespace Mono.CSharp {
                                if (!(instance_expr is IMemoryLocation)){
                                        tempo = new LocalTemporary (ec, instance_expr.Type);
                                        
-                                       if (ec.RemapToProxy)
-                                               ec.EmitThis ();
-                       
                                        InstanceExpression.Emit (ec);
                                        tempo.Store (ec);
                                        ml = tempo;
@@ -2876,10 +2894,7 @@ namespace Mono.CSharp {
                                
                                ml.AddressOf (ec, AddressOp.Load);
                        } else {
-                               if (ec.RemapToProxy)
-                                       ec.EmitThis ();
-                               else
-                                       instance_expr.Emit (ec);
+                               instance_expr.Emit (ec);
                        }
                        if (is_volatile)
                                ig.Emit (OpCodes.Volatile);
@@ -2907,10 +2922,7 @@ namespace Mono.CSharp {
 
                                        ml.AddressOf (ec, AddressOp.Store);
                                } else {
-                                       if (ec.RemapToProxy)
-                                               ec.EmitThis ();
-                                       else
-                                               instance.Emit (ec);
+                                       instance.Emit (ec);
                                }
                        }
 
@@ -2992,8 +3004,20 @@ namespace Mono.CSharp {
                                        IMemoryLocation ml = (IMemoryLocation) instance_expr;
 
                                        ml.AddressOf (ec, AddressOp.LoadStore);
-                               } else
+                               } else {
                                        instance_expr.Emit (ec);
+
+                                       if (instance_expr.Type.IsValueType) {
+                                               LocalBuilder local = ig.DeclareLocal (instance_expr.Type);
+                                               ig.Emit(OpCodes.Stloc, local);
+                                               ig.Emit(OpCodes.Ldloca, local);
+                                               ig.Emit(OpCodes.Ldfld, FieldInfo);
+                                               LocalBuilder local2 = ig.DeclareLocal(type);
+                                               ig.Emit(OpCodes.Stloc, local2);
+                                               ig.Emit(OpCodes.Ldloca, local2);
+                                               return;
+                                       }
+                               }
                                ig.Emit (OpCodes.Ldflda, FieldInfo);
                        }
                }
@@ -3094,75 +3118,104 @@ namespace Mono.CSharp {
                        return true;
                }
 
-               MethodInfo GetAccessor (Type invocation_type, string accessor_name)
+               MethodInfo FindAccessor (Type invocation_type, bool is_set)
                {
                        BindingFlags flags = BindingFlags.Public | BindingFlags.NonPublic |
-                               BindingFlags.Static | BindingFlags.Instance;
-                       MemberInfo[] group;
+                               BindingFlags.Static | BindingFlags.Instance |
+                               BindingFlags.DeclaredOnly;
 
-                       group = TypeManager.MemberLookup (
-                               invocation_type, invocation_type, PropertyInfo.DeclaringType,
-                               MemberTypes.Method, flags, accessor_name + "_" + PropertyInfo.Name);
+                       Type current = PropertyInfo.DeclaringType;
+                       for (; current != null; current = current.BaseType) {
+                               MemberInfo[] group = TypeManager.MemberLookup (
+                                       invocation_type, invocation_type, current,
+                                       MemberTypes.Property, flags, PropertyInfo.Name);
 
-                       //
-                       // The first method is the closest to us
-                       //
-                       if (group == null)
+                               if (group == null)
+                                       continue;
+
+                               if (group.Length != 1)
+                                       // Oooops, can this ever happen ?
+                                       return null;
+
+                               PropertyInfo pi = (PropertyInfo) group [0];
+
+                               MethodInfo get = pi.GetGetMethod (true);
+                               MethodInfo set = pi.GetSetMethod (true);
+
+                               if (is_set) {
+                                       if (set != null)
+                                               return set;
+                               } else {
+                                       if (get != null)
+                                               return get;
+                               }
+
+                               MethodInfo accessor = get != null ? get : set;
+                               if (accessor == null)
+                                       continue;
+                               if ((accessor.Attributes & MethodAttributes.NewSlot) != 0)
+                                       break;
+                       }
+
+                       return null;
+               }
+
+               MethodInfo GetAccessor (Type invocation_type, bool is_set)
+               {
+                       MethodInfo mi = FindAccessor (invocation_type, is_set);
+                       if (mi == null)
                                return null;
 
-                       foreach (MethodInfo mi in group) {
-                               MethodAttributes ma = mi.Attributes & MethodAttributes.MemberAccessMask;
+                       MethodAttributes ma = mi.Attributes & MethodAttributes.MemberAccessMask;
 
-                               //
-                               // If only accessible to the current class or children
-                               //
-                               if (ma == MethodAttributes.Private) {
-                                       Type declaring_type = mi.DeclaringType;
+                       //
+                       // If only accessible to the current class or children
+                       //
+                       if (ma == MethodAttributes.Private) {
+                               Type declaring_type = mi.DeclaringType;
                                        
-                                       if (invocation_type != declaring_type){
-                                               if (TypeManager.IsSubclassOrNestedChildOf (invocation_type, mi.DeclaringType))
-                                                       return mi;
-                                               else
-                                                       continue;
-                                       } else
+                               if (invocation_type != declaring_type){
+                                       if (TypeManager.IsSubclassOrNestedChildOf (invocation_type, mi.DeclaringType))
                                                return mi;
-                               }
-                               //
-                               // FamAndAssem requires that we not only derivate, but we are on the
-                               // same assembly.  
-                               //
-                               if (ma == MethodAttributes.FamANDAssem){
-                                       if (mi.DeclaringType.Assembly != invocation_type.Assembly)
-                                               continue;
                                        else
-                                               return mi;
-                               }
+                                               return null;
+                               } else
+                                       return mi;
+                       }
+                       //
+                       // FamAndAssem requires that we not only derivate, but we are on the
+                       // same assembly.  
+                       //
+                       if (ma == MethodAttributes.FamANDAssem){
+                               if (mi.DeclaringType.Assembly != invocation_type.Assembly)
+                                       return null;
+                               else
+                                       return mi;
+                       }
 
-                               // Assembly and FamORAssem succeed if we're in the same assembly.
-                               if ((ma == MethodAttributes.Assembly) || (ma == MethodAttributes.FamORAssem)){
-                                       if (mi.DeclaringType.Assembly == invocation_type.Assembly)
-                                               return mi;
-                               }
+                       // Assembly and FamORAssem succeed if we're in the same assembly.
+                       if ((ma == MethodAttributes.Assembly) || (ma == MethodAttributes.FamORAssem)){
+                               if (mi.DeclaringType.Assembly == invocation_type.Assembly)
+                                       return mi;
+                       }
 
-                               // We already know that we aren't in the same assembly.
-                               if (ma == MethodAttributes.Assembly)
-                                       continue;
+                       // We already know that we aren't in the same assembly.
+                       if (ma == MethodAttributes.Assembly)
+                               return null;
 
-                               // Family and FamANDAssem require that we derive.
-                               if ((ma == MethodAttributes.Family) || (ma == MethodAttributes.FamANDAssem) || (ma == MethodAttributes.FamORAssem)){
-                                       if (!TypeManager.IsSubclassOrNestedChildOf (invocation_type, mi.DeclaringType))
-                                               continue;
-                                       else {
+                       // Family and FamANDAssem require that we derive.
+                       if ((ma == MethodAttributes.Family) || (ma == MethodAttributes.FamANDAssem) || (ma == MethodAttributes.FamORAssem)){
+                               if (!TypeManager.IsSubclassOrNestedChildOf (invocation_type, mi.DeclaringType))
+                                       return null;
+                               else {
+                                       if (!TypeManager.IsNestedChildOf (invocation_type, mi.DeclaringType))
                                                must_do_cs1540_check = true;
 
-                                               return mi;
-                                       }
+                                       return mi;
                                }
-
-                               return mi;
                        }
 
-                       return null;
+                       return mi;
                }
 
                //
@@ -3171,11 +3224,11 @@ namespace Mono.CSharp {
                //
                void ResolveAccessors (EmitContext ec)
                {
-                       getter = GetAccessor (ec.ContainerType, "get");
+                       getter = GetAccessor (ec.ContainerType, false);
                        if ((getter != null) && getter.IsStatic)
                                is_static = true;
 
-                       setter = GetAccessor (ec.ContainerType, "set");
+                       setter = GetAccessor (ec.ContainerType, true);
                        if ((setter != null) && setter.IsStatic)
                                is_static = true;
 
@@ -3218,6 +3271,16 @@ namespace Mono.CSharp {
                
                override public Expression DoResolve (EmitContext ec)
                {
+                       if (getter != null){
+                               if (TypeManager.GetArgumentTypes (getter).Length != 0){
+                                       Report.Error (
+                                               117, loc, "`{0}' does not contain a " +
+                                               "definition for `{1}'.", getter.DeclaringType,
+                                               Name);
+                                       return null;
+                               }
+                       }
+
                        if (getter == null){
                                //
                                // The following condition happens if the PropertyExpr was
@@ -3269,6 +3332,14 @@ namespace Mono.CSharp {
                                return null;
                        }
 
+                       if (TypeManager.GetArgumentTypes (setter).Length != 1){
+                               Report.Error (
+                                       117, loc, "`{0}' does not contain a " +
+                                       "definition for `{1}'.", getter.DeclaringType,
+                                       Name);
+                               return null;
+                       }
+
                        if (!InstanceResolve (ec))
                                return null;