X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mcs%2Fmcs%2Fecore.cs;h=e8e0e6f3b86a32a5505d15ec3cdf75e2060dc7dd;hb=06a1ce9f42b0feb1ee6f56c0010a0ffe89ca3249;hp=1e12fd37f9024c5d42a756de1d2060979cd6723e;hpb=7efdb7bead71034ed5db610161f0c3b27b32dc16;p=mono.git diff --git a/mcs/mcs/ecore.cs b/mcs/mcs/ecore.cs index 1e12fd37f90..e8e0e6f3b86 100644 --- a/mcs/mcs/ecore.cs +++ b/mcs/mcs/ecore.cs @@ -97,15 +97,10 @@ namespace Mono.CSharp { void AddressOf (EmitContext ec, AddressOp mode); } - /// - /// This interface is implemented by variables - /// + // TODO: Rename to something meaningful, this is flow-analysis interface only public interface IVariable { - VariableInfo VariableInfo { - get; - } - - bool VerifyFixed (); + VariableInfo VariableInfo { get; } + bool IsFixed { get; } } /// @@ -393,12 +388,6 @@ namespace Mono.CSharp { return; } - if (Type != TypeManager.string_type && this is Constant && !(this is EmptyConstantCast)) { - Report.Error (31, loc, "Constant value `{0}' cannot be converted to a `{1}'", - ((Constant)(this)).GetValue ().ToString (), TypeManager.CSharpName (target)); - return; - } - Report.Error (29, loc, "Cannot implicitly convert type `{0}' to `{1}'", TypeManager.CSharpName (type), TypeManager.CSharpName (target)); @@ -1257,11 +1246,10 @@ namespace Mono.CSharp { return cloned; } - public virtual Expression CreateExpressionTree (EmitContext ec) - { - throw new NotImplementedException ( - "Expression tree conversion not implemented for " + GetType ()); - } + // + // Implementation of expression to expression tree conversion + // + public abstract Expression CreateExpressionTree (EmitContext ec); protected Expression CreateExpressionFactoryCall (string name, ArrayList args) { @@ -1291,6 +1279,11 @@ namespace Mono.CSharp { return texpr; } + + public virtual void MutateHoistedGenericType (AnonymousMethodStorey storey) + { + // TODO: It should probably be type = storey.MutateType (type); + } } /// @@ -1343,7 +1336,7 @@ namespace Mono.CSharp { /// public abstract class TypeCast : Expression { - protected Expression child; + protected readonly Expression child; protected TypeCast (Expression child, Type return_type) { @@ -1383,17 +1376,18 @@ namespace Mono.CSharp { return child.GetAttributableValue (value_type, out value); } - protected override void CloneTo (CloneContext clonectx, Expression t) + public override void MutateHoistedGenericType (AnonymousMethodStorey storey) { - TypeCast target = (TypeCast) t; + child.MutateHoistedGenericType (storey); + } - target.child = child.Clone (clonectx); + protected override void CloneTo (CloneContext clonectx, Expression t) + { + // Nothing to clone } public override bool IsNull { - get { - return child.IsNull; - } + get { return child.IsNull; } } } @@ -1409,6 +1403,10 @@ namespace Mono.CSharp { if (c != null) return new EmptyConstantCast (c, type); + EmptyCast e = child as EmptyCast; + if (e != null) + return new EmptyCast (e.child, type); + return new EmptyCast (child, type); } @@ -1421,7 +1419,6 @@ namespace Mono.CSharp { { child.EmitSideEffect (ec); } - } /// @@ -1864,6 +1861,11 @@ namespace Mono.CSharp { LoadFromPtr (ig, t); } } + + public override void MutateHoistedGenericType (AnonymousMethodStorey storey) + { + type = storey.MutateType (type); + } } /// @@ -2082,24 +2084,12 @@ namespace Mono.CSharp { } public class OpcodeCast : TypeCast { - OpCode op, op2; - bool second_valid; + readonly OpCode op; public OpcodeCast (Expression child, Type return_type, OpCode op) : base (child, return_type) - - { - this.op = op; - second_valid = false; - } - - public OpcodeCast (Expression child, Type return_type, OpCode op, OpCode op2) - : base (child, return_type) - { this.op = op; - this.op2 = op2; - second_valid = true; } public override Expression DoResolve (EmitContext ec) @@ -2114,9 +2104,6 @@ namespace Mono.CSharp { { base.Emit (ec); ec.ig.Emit (op); - - if (second_valid) - ec.ig.Emit (op2); } public Type UnderlyingType { @@ -2128,11 +2115,15 @@ namespace Mono.CSharp { /// This kind of cast is used to encapsulate a child and cast it /// to the class requested /// - public class ClassCast : TypeCast { + public sealed class ClassCast : TypeCast { + Type child_generic_parameter; + public ClassCast (Expression child, Type return_type) : base (child, return_type) { + if (TypeManager.IsGenericParameter (child.Type)) + child_generic_parameter = child.Type; } public override Expression DoResolve (EmitContext ec) @@ -2147,8 +2138,8 @@ namespace Mono.CSharp { { base.Emit (ec); - if (TypeManager.IsGenericParameter (child.Type)) - ec.ig.Emit (OpCodes.Box, child.Type); + if (child_generic_parameter != null) + ec.ig.Emit (OpCodes.Box, child_generic_parameter); #if GMCS_SOURCE if (type.IsGenericParameter) @@ -2157,6 +2148,15 @@ namespace Mono.CSharp { #endif ec.ig.Emit (OpCodes.Castclass, type); } + + public override void MutateHoistedGenericType (AnonymousMethodStorey storey) + { + type = storey.MutateType (type); + if (child_generic_parameter != null) + child_generic_parameter = storey.MutateGenericArgument (child_generic_parameter); + + base.MutateHoistedGenericType (storey); + } } // @@ -2854,6 +2854,11 @@ namespace Mono.CSharp { { return Type.GetHashCode (); } + + public override void MutateHoistedGenericType (AnonymousMethodStorey storey) + { + type = storey.MutateType (type); + } } /// @@ -3117,6 +3122,17 @@ namespace Mono.CSharp { "with an instance reference, qualify it with a type name instead", name); } + public static void Error_BaseAccessInExpressionTree (Location loc) + { + Report.Error (831, loc, "An expression tree may not contain a base access"); + } + + public override void MutateHoistedGenericType (AnonymousMethodStorey storey) + { + if (InstanceExpression != null) + InstanceExpression.MutateHoistedGenericType (storey); + } + // TODO: possible optimalization // Cache resolved constant result in FieldBuilder <-> expression map public virtual MemberExpr ResolveMemberAccess (EmitContext ec, Expression left, Location loc, @@ -3262,6 +3278,7 @@ namespace Mono.CSharp { return base.OverloadResolve (ec, ref arguments, false, loc); e.ExtensionExpression = ExtensionExpression; + e.SetTypeArguments (type_arguments); return e.ResolveOverloadExtensions (ec, arguments, e.namespace_entry, loc); } } @@ -3408,10 +3425,17 @@ namespace Mono.CSharp { // if (TypeManager.DropGenericTypeArguments (p) == TypeManager.expression_type) { p = TypeManager.GetTypeArguments (p) [0]; + } + if (TypeManager.DropGenericTypeArguments (q) == TypeManager.expression_type) { q = TypeManager.GetTypeArguments (q) [0]; } + p = Delegate.GetInvokeMethod (null, p).ReturnType; q = Delegate.GetInvokeMethod (null, q).ReturnType; + if (p == TypeManager.void_type && q != TypeManager.void_type) + return 2; + if (q == TypeManager.void_type && p != TypeManager.void_type) + return 1; } else { if (argument_type == p) return 1; @@ -3635,8 +3659,18 @@ namespace Mono.CSharp { public override Expression CreateExpressionTree (EmitContext ec) { + if (best_candidate == null) { + Report.Error (1953, loc, "An expression tree cannot contain an expression with method group"); + return null; + } + if (best_candidate.IsConstructor) return new TypeOfConstructorInfo (best_candidate, loc); + + IMethodData md = TypeManager.GetMethod (best_candidate); + if (md != null && md.IsExcluded ()) + Report.Error (765, loc, + "Partial methods with only a defining declaration or removed conditional methods cannot be used in an expression tree"); return new TypeOfMethodInfo (best_candidate, loc); } @@ -3676,6 +3710,8 @@ namespace Mono.CSharp { protected virtual void Error_InvalidArguments (EmitContext ec, Location loc, int idx, MethodBase method, Argument a, ParameterData expected_par, Type paramType) { + ExtensionMethodGroupExpr emg = this as ExtensionMethodGroupExpr; + if (a is CollectionElementInitializer.ElementInitializerArgument) { Report.SymbolRelatedToPreviousError (method); if ((expected_par.ParameterModifier (idx) & Parameter.Modifier.ISBYREF) != 0) { @@ -3687,8 +3723,15 @@ namespace Mono.CSharp { TypeManager.CSharpSignature (method)); } else if (delegate_type == null) { Report.SymbolRelatedToPreviousError (method); - Report.Error (1502, loc, "The best overloaded method match for `{0}' has some invalid arguments", - TypeManager.CSharpSignature (method)); + if (emg != null) { + Report.Error (1928, loc, + "Type `{0}' does not contain a member `{1}' and the best extension method overload `{2}' has some invalid arguments", + emg.ExtensionExpression.GetSignatureForError (), + emg.Name, TypeManager.CSharpSignature (method)); + } else { + Report.Error (1502, loc, "The best overloaded method match for `{0}' has some invalid arguments", + TypeManager.CSharpSignature (method)); + } } else Report.Error (1594, loc, "Delegate `{0}' has some invalid arguments", TypeManager.CSharpName (delegate_type)); @@ -3699,10 +3742,10 @@ namespace Mono.CSharp { if (((mod & (Parameter.Modifier.REF | Parameter.Modifier.OUT)) ^ (a.Modifier & (Parameter.Modifier.REF | Parameter.Modifier.OUT))) != 0) { if ((mod & Parameter.Modifier.ISBYREF) == 0) - Report.Error (1615, loc, "Argument `{0}' should not be passed with the `{1}' keyword", + Report.Error (1615, loc, "Argument `#{0}' does not require `{1}' modifier. Consider removing `{1}' modifier", index, Parameter.GetModifierSignature (a.Modifier)); else - Report.Error (1620, loc, "Argument `{0}' must be passed with the `{1}' keyword", + Report.Error (1620, loc, "Argument `#{0}' is missing `{1}' modifier", index, Parameter.GetModifierSignature (mod)); } else { string p1 = a.GetSignatureForError (); @@ -3713,7 +3756,14 @@ namespace Mono.CSharp { Report.SymbolRelatedToPreviousError (a.Expr.Type); Report.SymbolRelatedToPreviousError (paramType); } - Report.Error (1503, loc, "Argument {0}: Cannot convert type `{1}' to `{2}'", index, p1, p2); + + if (idx == 0 && emg != null) { + Report.Error (1929, loc, + "Extension method instance type `{0}' cannot be converted to `{1}'", p1, p2); + } else { + Report.Error (1503, loc, + "Argument `#{0}' cannot convert `{1}' expression to type `{2}'", index, p1, p2); + } } } @@ -3852,26 +3902,16 @@ namespace Mono.CSharp { if (a_type != parameter) return 2; - - return 0; - } - - // FIXME: Kill this abomination (EmitContext.TempEc) - EmitContext prevec = EmitContext.TempEc; - EmitContext.TempEc = ec; - try { + } else { if (delegate_type != null ? !Delegate.IsTypeCovariant (argument.Expr, parameter) : !Convert.ImplicitConversionExists (ec, argument.Expr, parameter)) return 2; - - if (arg_mod != param_mod) - return 1; - - } finally { - EmitContext.TempEc = prevec; } + if (arg_mod != param_mod) + return 1; + return 0; } @@ -3988,6 +4028,19 @@ namespace Mono.CSharp { return null; } + public override void MutateHoistedGenericType (AnonymousMethodStorey storey) + { + base.MutateHoistedGenericType (storey); + + MethodInfo mi = best_candidate as MethodInfo; + if (mi != null) { + best_candidate = storey.MutateGenericMethod (mi); + return; + } + + best_candidate = storey.MutateConstructor ((ConstructorInfo) this); + } + /// /// Find the Applicable Function Members (7.4.2.1) /// @@ -4117,8 +4170,12 @@ namespace Mono.CSharp { } Report.SetMessageRecorder (prev_recorder); - if (msg_recorder != null && msg_recorder.PrintMessages ()) + if (msg_recorder != null && !msg_recorder.IsEmpty) { + if (!may_fail) + msg_recorder.PrintMessages (); + return null; + } int candidate_top = candidates.Count; @@ -4570,7 +4627,8 @@ namespace Mono.CSharp { /// Fully resolved expression that evaluates to a Field /// public class FieldExpr : MemberExpr, IAssignMethod, IMemoryLocation, IVariable { - public readonly FieldInfo FieldInfo; + public FieldInfo FieldInfo; + readonly Type constructed_generic_type; VariableInfo variable_info; LocalTemporary temp; @@ -4591,6 +4649,12 @@ namespace Mono.CSharp { loc = l; } + public FieldExpr (FieldInfo fi, Type genericType, Location l) + : this (fi, l) + { + this.constructed_generic_type = genericType; + } + public override string Name { get { return FieldInfo.Name; @@ -4714,18 +4778,6 @@ namespace Mono.CSharp { } } - AnonymousContainer am = ec.CurrentAnonymousMethod; - if (am != null){ - if (!FieldInfo.IsStatic){ - if (!am.IsIterator && (ec.TypeContainer is Struct)){ - Report.Error (1673, loc, - "Anonymous methods inside structs cannot access instance members of `{0}'. Consider copying `{0}' to a local variable outside the anonymous method and using the local instead", - "this"); - return null; - } - } - } - IFixedBuffer fb = AttributeTester.GetFixedBuffer (FieldInfo); if (fb != null) { if (!ec.InFixedInitializer && ec.ContainerType.IsValueType) { @@ -4743,7 +4795,7 @@ namespace Mono.CSharp { // If the instance expression is a local variable or parameter. IVariable var = InstanceExpression as IVariable; - if ((var == null) || (var.VariableInfo == null)) + if (var == null || var.VariableInfo == null) return this; VariableInfo vi = var.VariableInfo; @@ -4794,7 +4846,7 @@ namespace Mono.CSharp { override public Expression DoResolveLValue (EmitContext ec, Expression right_side) { IVariable var = InstanceExpression as IVariable; - if ((var != null) && (var.VariableInfo != null)) + if (var != null && var.VariableInfo != null) var.VariableInfo.SetFieldAssigned (ec, FieldInfo.Name); bool lvalue_instance = !FieldInfo.IsStatic && FieldInfo.DeclaringType.IsValueType; @@ -4856,19 +4908,20 @@ namespace Mono.CSharp { } } - public bool VerifyFixed () - { - IVariable variable = InstanceExpression as IVariable; - // A variable of the form V.I is fixed when V is a fixed variable of a struct type. - // We defer the InstanceExpression check after the variable check to avoid a - // separate null check on InstanceExpression. - return variable != null && InstanceExpression.Type.IsValueType && variable.VerifyFixed (); - } - public override int GetHashCode () { return FieldInfo.GetHashCode (); } + + public bool IsFixed { + get { + IVariable variable = InstanceExpression as IVariable; + // A variable of the form V.I is fixed when V is a fixed variable of a struct type. + // We defer the InstanceExpression check after the variable check to avoid a + // separate null check on InstanceExpression. + return variable != null && InstanceExpression.Type.IsValueType && variable.IsFixed; + } + } public override bool Equals (object obj) { @@ -4901,21 +4954,21 @@ namespace Mono.CSharp { if (FieldInfo.IsStatic){ if (is_volatile) ig.Emit (OpCodes.Volatile); - - ig.Emit (OpCodes.Ldsfld, FieldInfo); + + ig.Emit (OpCodes.Ldsfld, GetConstructedFieldInfo ()); } else { if (!prepared) EmitInstance (ec, false); IFixedBuffer ff = AttributeTester.GetFixedBuffer (FieldInfo); if (ff != null) { - ig.Emit (OpCodes.Ldflda, FieldInfo); + ig.Emit (OpCodes.Ldflda, GetConstructedFieldInfo ()); ig.Emit (OpCodes.Ldflda, ff.Element); } else { if (is_volatile) ig.Emit (OpCodes.Volatile); - ig.Emit (OpCodes.Ldfld, FieldInfo); + ig.Emit (OpCodes.Ldfld, GetConstructedFieldInfo ()); } } @@ -4961,13 +5014,14 @@ namespace Mono.CSharp { } if (is_static) - ig.Emit (OpCodes.Stsfld, FieldInfo); - else - ig.Emit (OpCodes.Stfld, FieldInfo); + ig.Emit (OpCodes.Stsfld, GetConstructedFieldInfo ()); + else + ig.Emit (OpCodes.Stfld, GetConstructedFieldInfo ()); if (temp != null) { temp.Emit (ec); temp.Release (ec); + temp = null; } } @@ -5030,13 +5084,30 @@ namespace Mono.CSharp { if (FieldInfo.IsStatic){ - ig.Emit (OpCodes.Ldsflda, FieldInfo); + ig.Emit (OpCodes.Ldsflda, GetConstructedFieldInfo ()); } else { if (!prepared) EmitInstance (ec, false); - ig.Emit (OpCodes.Ldflda, FieldInfo); + ig.Emit (OpCodes.Ldflda, GetConstructedFieldInfo ()); } } + + FieldInfo GetConstructedFieldInfo () + { + if (constructed_generic_type == null) + return FieldInfo; +#if GMCS_SOURCE + return TypeBuilder.GetField (constructed_generic_type, FieldInfo); +#else + throw new NotSupportedException (); +#endif + } + + public override void MutateHoistedGenericType (AnonymousMethodStorey storey) + { + FieldInfo = storey.MutateField (FieldInfo); + base.MutateHoistedGenericType (storey); + } } @@ -5089,18 +5160,25 @@ namespace Mono.CSharp { public override Expression CreateExpressionTree (EmitContext ec) { + ArrayList args; if (IsSingleDimensionalArrayLength ()) { - ArrayList args = new ArrayList (1); + args = new ArrayList (1); args.Add (new Argument (InstanceExpression.CreateExpressionTree (ec))); return CreateExpressionFactoryCall ("ArrayLength", args); } - // TODO: it's waiting for PropertyExpr refactoring - //ArrayList args = new ArrayList (2); - //args.Add (new Argument (InstanceExpression.CreateExpressionTree (ec))); - //args.Add (getter expression); - //return CreateExpressionFactoryCall ("Property", args); - return base.CreateExpressionTree (ec); + if (is_base) { + Error_BaseAccessInExpressionTree (loc); + return null; + } + + args = new ArrayList (2); + if (InstanceExpression == null) + args.Add (new Argument (new NullLiteral (loc))); + else + args.Add (new Argument (InstanceExpression.CreateExpressionTree (ec))); + args.Add (new Argument (new TypeOfMethodInfo (getter, loc))); + return CreateExpressionFactoryCall ("Property", args); } public Expression CreateSetterTypeOfExpression () @@ -5181,6 +5259,15 @@ namespace Mono.CSharp { } } + public override void MutateHoistedGenericType (AnonymousMethodStorey storey) + { + if (InstanceExpression != null) + InstanceExpression.MutateHoistedGenericType (storey); + + type = storey.MutateType (type); + getter = storey.MutateGenericMethod (getter); + } + bool InstanceResolve (EmitContext ec, bool lvalue_instance, bool must_do_cs1540_check) { if (is_static) { @@ -5250,7 +5337,7 @@ namespace Mono.CSharp { string t_name = InstanceExpression.Type.Name; int t_name_len = t_name.Length; - return t_name_len > 2 && t_name [t_name_len - 2] == '[' && t_name [t_name_len - 3] != ']'; + return t_name_len > 2 && t_name [t_name_len - 2] == '['; } override public Expression DoResolve (EmitContext ec) @@ -5641,78 +5728,68 @@ namespace Mono.CSharp { } } - public class TemporaryVariable : Expression, IMemoryLocation + public class TemporaryVariable : VariableReference { LocalInfo li; - Variable var; - + public TemporaryVariable (Type type, Location loc) { this.type = type; this.loc = loc; - eclass = ExprClass.Value; + eclass = ExprClass.Variable; } public override Expression CreateExpressionTree (EmitContext ec) { throw new NotSupportedException ("ET"); } - + public override Expression DoResolve (EmitContext ec) { if (li != null) return this; - + TypeExpr te = new TypeExpression (type, loc); li = ec.CurrentBlock.AddTemporaryVariable (te, loc); if (!li.Resolve (ec)) return null; - if (ec.MustCaptureVariable (li)) { - ScopeInfo scope = li.Block.CreateScopeInfo (); - var = scope.AddLocal (li); - type = var.Type; + if (ec.MustCaptureVariable (li) && !ec.IsInProbingMode) { + AnonymousMethodStorey storey = li.Block.Explicit.CreateAnonymousMethodStorey (ec); + storey.CaptureLocalVariable (ec, li); } - - return this; - } - public Variable Variable { - get { return var != null ? var : li.Variable; } + return this; } public override void Emit (EmitContext ec) { - Variable.EmitInstance (ec); - Variable.Emit (ec); + Emit (ec, false); } - - public void EmitLoadAddress (EmitContext ec) + + public void EmitAssign (EmitContext ec, Expression source) { - Variable.EmitInstance (ec); - Variable.EmitAddressOf (ec); + EmitAssign (ec, source, false, false); } - - public void Store (EmitContext ec, Expression right_side) - { - Variable.EmitInstance (ec); - right_side.Emit (ec); - Variable.EmitAssign (ec); + + public override HoistedVariable HoistedVariable { + get { return li.HoistedVariableReference; } } - - public void EmitThis (EmitContext ec) - { - Variable.EmitInstance (ec); + + public override bool IsFixed { + get { return true; } } - - public void EmitStore (EmitContext ec) - { - Variable.EmitAssign (ec); + + public override bool IsRef { + get { return false; } } - - public void AddressOf (EmitContext ec, AddressOp mode) - { - EmitLoadAddress (ec); + + protected override ILocalVariable Variable { + get { return li; } + } + + public override VariableInfo VariableInfo { + get { throw new NotImplementedException (); } } }