X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mcs%2Fgmcs%2Fecore.cs;h=743b255c62697aaa352b5ec0018ebccd130bb2b8;hb=9076dfdec8582c59a2c683da9943496514f8d2dd;hp=37e0ce1853c1c773584fe20047af2ab366a37dac;hpb=84afe617ac7b874f46fbc8bce0280e5083e41166;p=mono.git diff --git a/mcs/gmcs/ecore.cs b/mcs/gmcs/ecore.cs index 37e0ce1853c..743b255c626 100755 --- a/mcs/gmcs/ecore.cs +++ b/mcs/gmcs/ecore.cs @@ -206,22 +206,9 @@ namespace Mono.CSharp { /// /// Utility wrapper routine for Warning, just to beautify the code /// - public void Warning (int warning, string s) + public void Warning (int code, string format, params object[] args) { - if (!Location.IsNull (loc)) - Report.Warning (warning, loc, s); - else - Report.Warning (warning, s); - } - - /// - /// Utility wrapper routine for Warning, only prints the warning if - /// warnings of level `level' are enabled. - /// - public void Warning (int warning, int level, string s) - { - if (level <= RootContext.WarningLevel) - Warning (warning, s); + Report.Warning (code, loc, format, args); } /// @@ -733,12 +720,12 @@ namespace Mono.CSharp { if (qualifier_type != null) - Report.Error_T (122, loc, TypeManager.CSharpName (qualifier_type) + "." + name); + Report.Error (122, loc, "'{0}' is inaccessible due to its protection level", TypeManager.CSharpName (qualifier_type) + "." + name); else if (name == ".ctor") { Report.Error (143, loc, String.Format ("The type {0} has no constructors defined", TypeManager.CSharpName (queried_type))); } else { - Report.Error_T (122, loc, name); + Report.Error (122, loc, "'{0}' is inaccessible due to its protection level", name); } } @@ -1280,13 +1267,6 @@ namespace Mono.CSharp { return 0; } - // - // Default implementation of IAssignMethod.CacheTemporaries - // - public virtual void CacheTemporaries (EmitContext ec) - { - } - static void Error_NegativeArrayIndex (Location loc) { Report.Error (284, loc, "Can not create array with a negative size"); @@ -2269,7 +2249,7 @@ namespace Mono.CSharp { if (!me.IsStatic && TypeManager.IsSubclassOrNestedChildOf (me.InstanceExpression.Type, me.DeclaringType) && me.InstanceExpression.Type != me.DeclaringType && - !me.InstanceExpression.Type.IsSubclassOf (me.DeclaringType) && + !TypeManager.IsSubclassOf (me.InstanceExpression.Type, me.DeclaringType) && (!intermediate || !MemberAccess.IdenticalNameAndTypeName (ec, this, e, loc))) { Error (38, "Cannot access nonstatic member `" + me.Name + "' of " + "outer type `" + me.DeclaringType + "' via nested type `" + @@ -2378,11 +2358,6 @@ namespace Mono.CSharp { } } - public virtual TypeExpr[] GetInterfaces () - { - return TypeManager.GetInterfaces (Type); - } - public abstract TypeExpr DoResolveAsTypeStep (EmitContext ec); public virtual Type ResolveType (EmitContext ec) @@ -2490,6 +2465,16 @@ namespace Mono.CSharp { } } + /// + /// Represents an "unbound generic type", ie. typeof (Foo<>). + /// See 14.5.11. + /// + public class UnboundTypeExpression : TypeLookupExpression { + public UnboundTypeExpression (string name) + : base (name) + { } + } + public class TypeAliasExpression : TypeExpr, IAlias { TypeExpr texpr; TypeArguments args; @@ -2594,6 +2579,7 @@ namespace Mono.CSharp { bool is_explicit_impl = false; bool has_type_arguments = false; bool identical_type_name = false; + bool is_base; public MethodGroupExpr (MemberInfo [] mi, Location l) { @@ -2678,6 +2664,15 @@ namespace Mono.CSharp { } } + public bool IsBase { + get { + return is_base; + } + set { + is_base = value; + } + } + public string Name { get { //return Methods [0].Name; @@ -2824,9 +2819,9 @@ namespace Mono.CSharp { Expression instance_expr; VariableInfo variable_info; - LocalTemporary temporary; - IMemoryLocation instance_ml; - bool have_temporary; + LocalTemporary temp; + bool prepared; + bool is_field_initializer; public FieldExpr (FieldInfo fi, Location l) { @@ -2870,6 +2865,16 @@ namespace Mono.CSharp { } } + public bool IsFieldInitializer { + get { + return is_field_initializer; + } + + set { + is_field_initializer = value; + } + } + public VariableInfo VariableInfo { get { return variable_info; @@ -2970,7 +2975,8 @@ namespace Mono.CSharp { Report_AssignToReadonly (false); Type ctype; - if (ec.TypeContainer.CurrentType != null) + if (!is_field_initializer && + (ec.TypeContainer.CurrentType != null)) ctype = ec.TypeContainer.CurrentType.ResolveType (ec); else ctype = ec.ContainerType; @@ -2992,37 +2998,8 @@ namespace Mono.CSharp { return true; } - - public override void CacheTemporaries (EmitContext ec) - { - if (!FieldInfo.IsStatic && (temporary == null)) - temporary = new LocalTemporary (ec, instance_expr.Type); - } - - void EmitInstance (EmitContext ec) - { - if (instance_expr.Type.IsValueType) - CacheTemporaries (ec); - - if ((temporary == null) || have_temporary) - return; - - if (instance_expr.Type.IsValueType) { - instance_ml = instance_expr as IMemoryLocation; - if (instance_ml == null) { - instance_expr.Emit (ec); - temporary.Store (ec); - instance_ml = temporary; - } - } else { - instance_expr.Emit (ec); - temporary.Store (ec); - } - - have_temporary = true; - } - - override public void Emit (EmitContext ec) + + public void Emit (EmitContext ec, bool leave_copy) { ILGenerator ig = ec.ig; bool is_volatile = false; @@ -3042,46 +3019,52 @@ namespace Mono.CSharp { ig.Emit (OpCodes.Volatile); ig.Emit (OpCodes.Ldsfld, FieldInfo); - return; + } else { + if (!prepared) + EmitInstance (ec); + + if (is_volatile) + ig.Emit (OpCodes.Volatile); + + ig.Emit (OpCodes.Ldfld, FieldInfo); } - - EmitInstance (ec); - if (instance_ml != null) - instance_ml.AddressOf (ec, AddressOp.Load); - else if (temporary != null) - temporary.Emit (ec); - else - instance_expr.Emit (ec); - if (is_volatile) - ig.Emit (OpCodes.Volatile); - - ig.Emit (OpCodes.Ldfld, FieldInfo); + if (leave_copy) { + ec.ig.Emit (OpCodes.Dup); + if (!FieldInfo.IsStatic) { + temp = new LocalTemporary (ec, this.Type); + temp.Store (ec); + } + } } - public void EmitAssign (EmitContext ec, Expression source) + public void EmitAssign (EmitContext ec, Expression source, bool leave_copy, bool prepare_for_load) { FieldAttributes fa = FieldInfo.Attributes; bool is_static = (fa & FieldAttributes.Static) != 0; bool is_readonly = (fa & FieldAttributes.InitOnly) != 0; ILGenerator ig = ec.ig; + prepared = prepare_for_load; if (is_readonly && !ec.IsConstructor){ Report_AssignToReadonly (!is_static); return; } - if (!is_static){ + if (!is_static) { EmitInstance (ec); - if (instance_ml != null) - instance_ml.AddressOf (ec, AddressOp.Store); - else if (temporary != null) - temporary.Emit (ec); - else - instance_expr.Emit (ec); + if (prepare_for_load) + ig.Emit (OpCodes.Dup); } source.Emit (ec); + if (leave_copy) { + ec.ig.Emit (OpCodes.Dup); + if (!FieldInfo.IsStatic) { + temp = new LocalTemporary (ec, this.Type); + temp.Store (ec); + } + } if (FieldInfo is FieldBuilder){ FieldBase f = TypeManager.GetField (FieldInfo); @@ -3097,6 +3080,29 @@ namespace Mono.CSharp { ig.Emit (OpCodes.Stsfld, FieldInfo); else ig.Emit (OpCodes.Stfld, FieldInfo); + + if (temp != null) + temp.Emit (ec); + } + + void EmitInstance (EmitContext ec) + { + if (instance_expr.Type.IsValueType) { + if (instance_expr is IMemoryLocation) { + ((IMemoryLocation) instance_expr).AddressOf (ec, AddressOp.LoadStore); + } else { + LocalTemporary t = new LocalTemporary (ec, instance_expr.Type); + instance_expr.Emit (ec); + t.Store (ec); + t.AddressOf (ec, AddressOp.Store); + } + } else + instance_expr.Emit (ec); + } + + public override void Emit (EmitContext ec) + { + Emit (ec, false); } public void AddressOf (EmitContext ec, AddressOp mode) @@ -3148,20 +3154,7 @@ namespace Mono.CSharp { if (FieldInfo.IsStatic){ ig.Emit (OpCodes.Ldsflda, FieldInfo); } else { - // - // In the case of `This', we call the AddressOf method, which will - // only load the pointer, and not perform an Ldobj immediately after - // the value has been loaded into the stack. - // EmitInstance (ec); - if (instance_ml != null) - instance_ml.AddressOf (ec, AddressOp.LoadStore); - else if (temporary != null) - temporary.Emit (ec); - else if (instance_expr is This) - ((This)instance_expr).AddressOf (ec, AddressOp.LoadStore); - else - instance_expr.Emit (ec); ig.Emit (OpCodes.Ldflda, FieldInfo); } } @@ -3200,8 +3193,8 @@ namespace Mono.CSharp { bool must_do_cs1540_check; Expression instance_expr; - LocalTemporary temporary; - bool have_temporary; + LocalTemporary temp; + bool prepared; public PropertyExpr (EmitContext ec, PropertyInfo pi, Location l) { @@ -3379,7 +3372,7 @@ namespace Mono.CSharp { is_static = true; if (setter == null && getter == null){ - Report.Error_T (122, loc, PropertyInfo.Name); + Report.Error (122, loc, "'{0}' is inaccessible due to its protection level", PropertyInfo.Name); } } @@ -3508,38 +3501,40 @@ namespace Mono.CSharp { return this; } - public override void CacheTemporaries (EmitContext ec) + + + public override void Emit (EmitContext ec) { - if (!is_static){ - // we need to do indirection on the pointer - bool need_address = instance_expr.Type.IsValueType; - temporary = new LocalTemporary (ec, instance_expr.Type, need_address); - } + Emit (ec, false); } - - Expression EmitInstance (EmitContext ec) + + void EmitInstance (EmitContext ec) { - if (temporary != null){ - if (!have_temporary){ - if (temporary.PointsToAddress){ - // must store the managed pointer - IMemoryLocation loc = instance_expr as IMemoryLocation; - loc.AddressOf (ec, AddressOp.LoadStore); - } else - instance_expr.Emit (ec); - temporary.Store (ec); - - have_temporary = true; + if (is_static) + return; + + if (instance_expr.Type.IsValueType) { + if (instance_expr is IMemoryLocation) { + ((IMemoryLocation) instance_expr).AddressOf (ec, AddressOp.LoadStore); + } else { + LocalTemporary t = new LocalTemporary (ec, instance_expr.Type); + instance_expr.Emit (ec); + t.Store (ec); + t.AddressOf (ec, AddressOp.Store); } - return temporary; } else - return instance_expr; + instance_expr.Emit (ec); + + if (prepared) + ec.ig.Emit (OpCodes.Dup); } - override public void Emit (EmitContext ec) + + public void Emit (EmitContext ec, bool leave_copy) { - Expression expr = EmitInstance (ec); - + if (!prepared) + EmitInstance (ec); + // // Special case: length of single dimension array property is turned into ldlen // @@ -3551,30 +3546,50 @@ namespace Mono.CSharp { // System.Array.Length can be called, but the Type does not // support invoking GetArrayRank, so test for that case first // - if (iet != TypeManager.array_type && (iet.GetArrayRank () == 1)){ - expr.Emit (ec); + if (iet != TypeManager.array_type && (iet.GetArrayRank () == 1)) { ec.ig.Emit (OpCodes.Ldlen); ec.ig.Emit (OpCodes.Conv_I4); return; } } - Invocation.EmitCall (ec, IsBase, IsStatic, expr, getter, null, loc); + Invocation.EmitCall (ec, IsBase, IsStatic, new EmptyAddressOf (), getter, null, loc); + + if (!leave_copy) + return; + ec.ig.Emit (OpCodes.Dup); + if (!is_static) { + temp = new LocalTemporary (ec, this.Type); + temp.Store (ec); + } } // // Implements the IAssignMethod interface for assignments // - public void EmitAssign (EmitContext ec, Expression source) + public void EmitAssign (EmitContext ec, Expression source, bool leave_copy, bool prepare_for_load) { - Expression expr = EmitInstance (ec); - - Argument arg = new Argument (source, Argument.AType.Expression); - ArrayList args = new ArrayList (); + prepared = prepare_for_load; + + EmitInstance (ec); - args.Add (arg); - Invocation.EmitCall (ec, IsBase, IsStatic, expr, setter, args, loc); + source.Emit (ec); + if (leave_copy) { + ec.ig.Emit (OpCodes.Dup); + if (!is_static) { + temp = new LocalTemporary (ec, this.Type); + temp.Store (ec); + } + } + + ArrayList args = new ArrayList (1); + args.Add (new Argument (new EmptyAddressOf (), Argument.AType.Expression)); + + Invocation.EmitCall (ec, IsBase, IsStatic, new EmptyAddressOf (), setter, args, loc); + + if (temp != null) + temp.Emit (ec); } override public void EmitStatement (EmitContext ec)