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 (); }
}
}