X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mcs%2Fmcs%2Fecore.cs;h=9470b01ac6fc4efaa1107081a56d21971bbb060b;hb=d8aae4dd7b6bf2a72a12a62e5359fe76b6567435;hp=5a0888205c9430a5763a4f45653219f79db8127a;hpb=332221c6213b7ad580be6eb78c51ee265b660c2b;p=mono.git
diff --git a/mcs/mcs/ecore.cs b/mcs/mcs/ecore.cs
index 5a0888205c9..9470b01ac6f 100644
--- a/mcs/mcs/ecore.cs
+++ b/mcs/mcs/ecore.cs
@@ -5,7 +5,8 @@
// Miguel de Icaza (miguel@ximian.com)
// Marek Safar (marek.safar@seznam.cz)
//
-// (C) 2001, 2002, 2003 Ximian, Inc.
+// Copyright 2001, 2002, 2003 Ximian, Inc.
+// Copyright 2003-2008 Novell, Inc.
//
//
@@ -96,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; }
}
///
@@ -165,8 +161,7 @@ namespace Mono.CSharp {
return TypeManager.IsPrivateAccessible (invocation_type, mi.DeclaringType) ||
TypeManager.IsNestedChildOf (invocation_type, mi.DeclaringType);
- if (mi.DeclaringType.Assembly == invocation_type.Assembly ||
- TypeManager.IsFriendAssembly (mi.DeclaringType.Assembly)) {
+ if (TypeManager.IsThisOrFriendAssembly (mi.DeclaringType.Assembly)) {
if (ma == MethodAttributes.Assembly || ma == MethodAttributes.FamORAssem)
return true;
} else {
@@ -229,8 +224,16 @@ namespace Mono.CSharp {
// This is used if the expression should be resolved as a type or namespace name.
// the default implementation fails.
//
- public virtual FullNamedExpression ResolveAsTypeStep (IResolveContext ec, bool silent)
+ public virtual FullNamedExpression ResolveAsTypeStep (IResolveContext rc, bool silent)
{
+ if (!silent) {
+ Expression e = this;
+ EmitContext ec = rc as EmitContext;
+ if (ec != null)
+ e = e.Resolve (ec);
+ if (e != null)
+ e.Error_UnexpectedKind (ResolveFlags.Type, loc);
+ }
return null;
}
@@ -347,9 +350,9 @@ namespace Mono.CSharp {
if (TypeManager.IsGenericParameter (Type) && TypeManager.IsGenericParameter (target) && type.Name == target.Name) {
#if GMCS_SOURCE
- string sig1 = Type.DeclaringMethod == null ?
- TypeManager.CSharpName (Type.DeclaringType) :
- TypeManager.CSharpSignature (Type.DeclaringMethod);
+ string sig1 = type.DeclaringMethod == null ?
+ TypeManager.CSharpName (type.DeclaringType) :
+ TypeManager.CSharpSignature (type.DeclaringMethod);
string sig2 = target.DeclaringMethod == null ?
TypeManager.CSharpName (target.DeclaringType) :
TypeManager.CSharpSignature (target.DeclaringMethod);
@@ -377,7 +380,7 @@ namespace Mono.CSharp {
if (b ||
Convert.ExplicitReferenceConversionExists (Type, target) ||
Convert.ExplicitUnsafe (e, target) != null ||
- (ec != null && Convert.UserDefinedConversion (ec, this, target, Location.Null, true) != null))
+ (ec != null && Convert.ExplicitUserConversion (ec, this, target, Location.Null) != null))
{
Report.Error (266, loc, "Cannot implicitly convert type `{0}' to `{1}'. " +
"An explicit conversion exists (are you missing a cast?)",
@@ -385,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));
@@ -577,12 +574,25 @@ namespace Mono.CSharp {
///
public abstract void Emit (EmitContext ec);
+ // Emit code to branch to @target if this expression is equivalent to @on_true.
+ // The default implementation is to emit the value, and then emit a brtrue or brfalse.
+ // Subclasses can provide more efficient implementations, but those MUST be equivalent,
+ // including the use of conditional branches. Note also that a branch MUST be emitted
public virtual void EmitBranchable (EmitContext ec, Label target, bool on_true)
{
Emit (ec);
ec.ig.Emit (on_true ? OpCodes.Brtrue : OpCodes.Brfalse, target);
}
+ // Emit this expression for its side effects, not for its value.
+ // The default implementation is to emit the value, and then throw it away.
+ // Subclasses can provide more efficient implementations, but those MUST be equivalent
+ public virtual void EmitSideEffect (EmitContext ec)
+ {
+ Emit (ec);
+ ec.ig.Emit (OpCodes.Pop);
+ }
+
///
/// Protected constructor. Only derivate types should
/// be able to be created
@@ -893,6 +903,11 @@ namespace Mono.CSharp {
throw new NotImplementedException ();
}
+ protected void Error_PointerInsideExpressionTree ()
+ {
+ Report.Error (1944, loc, "An expression tree cannot contain an unsafe pointer operation");
+ }
+
///
/// Returns an expression that can be used to invoke operator true
/// on the expression if it exists.
@@ -914,7 +929,8 @@ namespace Mono.CSharp {
static Expression GetOperatorTrueOrFalse (EmitContext ec, Expression e, bool is_true, Location loc)
{
MethodGroupExpr operator_group;
- operator_group = MethodLookup (ec.ContainerType, e.Type, is_true ? "op_True" : "op_False", loc) as MethodGroupExpr;
+ string mname = Operator.GetMetadataName (is_true ? Operator.OpType.True : Operator.OpType.False);
+ operator_group = MethodLookup (ec.ContainerType, e.Type, mname, loc) as MethodGroupExpr;
if (operator_group == null)
return null;
@@ -926,7 +942,7 @@ namespace Mono.CSharp {
if (operator_group == null)
return null;
- return new StaticCallExpr ((MethodInfo) operator_group, arguments, loc);
+ return new UserOperatorCall (operator_group, arguments, null, loc);
}
///
@@ -1078,7 +1094,7 @@ namespace Mono.CSharp {
if (t == TypeManager.enum_type)
ig.Emit (OpCodes.Ldind_Ref);
else
- LoadFromPtr (ig, TypeManager.EnumToUnderlying (t));
+ LoadFromPtr (ig, TypeManager.GetEnumUnderlyingType (t));
} else if (t.IsValueType || TypeManager.IsGenericParameter (t))
ig.Emit (OpCodes.Ldobj, t);
else if (t.IsPointer)
@@ -1093,7 +1109,7 @@ namespace Mono.CSharp {
public static void StoreFromPtr (ILGenerator ig, Type type)
{
if (TypeManager.IsEnumType (type))
- type = TypeManager.EnumToUnderlying (type);
+ type = TypeManager.GetEnumUnderlyingType (type);
if (type == TypeManager.int32_type || type == TypeManager.uint32_type)
ig.Emit (OpCodes.Stind_I4);
else if (type == TypeManager.int64_type || type == TypeManager.uint64_type)
@@ -1230,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)
{
@@ -1248,8 +1263,21 @@ namespace Mono.CSharp {
public static Expression CreateExpressionFactoryCall (string name, TypeArguments typeArguments, ArrayList args, Location loc)
{
- TypeExpression texpr = new TypeExpression (LinqExpression.expression_type, loc);
- return new Invocation (new MemberAccess (texpr, name, typeArguments, loc), args);
+ return new Invocation (new MemberAccess (CreateExpressionTypeExpression (loc), name, typeArguments, loc), args);
+ }
+
+ protected static TypeExpr CreateExpressionTypeExpression (Location loc)
+ {
+ TypeExpr texpr = TypeManager.expression_type_expr;
+ if (texpr == null) {
+ Type t = TypeManager.CoreLookupType ("System.Linq.Expressions", "Expression", Kind.Class, true);
+ if (t == null)
+ return null;
+
+ TypeManager.expression_type_expr = texpr = new TypeExpression (t, Location.Null);
+ }
+
+ return texpr;
}
}
@@ -1282,6 +1310,11 @@ namespace Mono.CSharp {
/// Emit that will always leave a value on the stack).
///
public abstract void EmitStatement (EmitContext ec);
+
+ public override void EmitSideEffect (EmitContext ec)
+ {
+ EmitStatement (ec);
+ }
}
///
@@ -1296,33 +1329,28 @@ namespace Mono.CSharp {
/// would be "unsigned int".
///
///
- public class EmptyCast : Expression
+ public abstract class TypeCast : Expression
{
protected Expression child;
- protected EmptyCast (Expression child, Type return_type)
+ protected TypeCast (Expression child, Type return_type)
{
eclass = child.eclass;
loc = child.Location;
type = return_type;
this.child = child;
}
-
- public static Expression Create (Expression child, Type type)
- {
- Constant c = child as Constant;
- if (c != null)
- return new EmptyConstantCast (c, type);
-
- return new EmptyCast (child, type);
- }
public override Expression CreateExpressionTree (EmitContext ec)
{
ArrayList args = new ArrayList (2);
args.Add (new Argument (child.CreateExpressionTree (ec)));
args.Add (new Argument (new TypeOf (new TypeExpression (type, loc), loc)));
- return CreateExpressionFactoryCall ("Convert", args);
+
+ if (type.IsPointer || child.Type.IsPointer)
+ Error_PointerInsideExpressionTree ();
+
+ return CreateExpressionFactoryCall (ec.CheckState ? "ConvertChecked" : "Convert", args);
}
public override Expression DoResolve (EmitContext ec)
@@ -1345,16 +1373,50 @@ namespace Mono.CSharp {
protected override void CloneTo (CloneContext clonectx, Expression t)
{
- EmptyCast target = (EmptyCast) t;
+ TypeCast target = (TypeCast) t;
target.child = child.Clone (clonectx);
}
+
+ public override bool IsNull {
+ get { return child.IsNull; }
+ }
+ }
+
+ public class EmptyCast : TypeCast {
+ EmptyCast (Expression child, Type target_type)
+ : base (child, target_type)
+ {
+ }
+
+ public static Expression Create (Expression child, Type type)
+ {
+ Constant c = child as Constant;
+ 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);
+ }
+
+ public override void EmitBranchable (EmitContext ec, Label label, bool on_true)
+ {
+ child.EmitBranchable (ec, label, on_true);
+ }
+
+ public override void EmitSideEffect (EmitContext ec)
+ {
+ child.EmitSideEffect (ec);
+ }
}
///
/// Performs a cast using an operator (op_Explicit or op_Implicit)
///
- public class OperatorCast : EmptyCast {
+ public class OperatorCast : TypeCast {
MethodInfo conversion_operator;
bool find_explicit;
@@ -1385,7 +1447,7 @@ namespace Mono.CSharp {
foreach (MethodInfo oper in mi) {
ParameterData pd = TypeManager.GetParameterData (oper);
- if (pd.ParameterType (0) == child.Type && oper.ReturnType == type)
+ if (pd.ParameterType (0) == child.Type && TypeManager.TypeToCoreType (oper.ReturnType) == type)
return oper;
}
@@ -1411,7 +1473,7 @@ namespace Mono.CSharp {
///
/// This is a numeric cast to a Decimal
///
- public class CastToDecimal : EmptyCast {
+ public class CastToDecimal : TypeCast {
MethodInfo conversion_operator;
public CastToDecimal (Expression child)
@@ -1440,7 +1502,7 @@ namespace Mono.CSharp {
foreach (MethodInfo oper in mi) {
ParameterData pd = TypeManager.GetParameterData (oper);
- if (pd.ParameterType (0) == child.Type && oper.ReturnType == type)
+ if (pd.ParameterType (0) == child.Type && TypeManager.TypeToCoreType (oper.ReturnType) == type)
return oper;
}
@@ -1458,7 +1520,7 @@ namespace Mono.CSharp {
///
/// This is an explicit numeric cast from a Decimal
///
- public class CastFromDecimal : EmptyCast
+ public class CastFromDecimal : TypeCast
{
static IDictionary operators;
@@ -1483,7 +1545,7 @@ namespace Mono.CSharp {
foreach (MethodInfo oper in all_oper) {
ParameterData pd = TypeManager.GetParameterData (oper);
if (pd.ParameterType (0) == TypeManager.decimal_type)
- operators.Add (oper.ReturnType, oper);
+ operators.Add (TypeManager.TypeToCoreType (oper.ReturnType), oper);
}
}
@@ -1533,6 +1595,17 @@ namespace Mono.CSharp {
return child.ConvertExplicitly (in_checked_context, target_type);
}
+ public override Expression CreateExpressionTree (EmitContext ec)
+ {
+ ArrayList args = new ArrayList (2);
+ args.Add (new Argument (child.CreateExpressionTree (ec)));
+ args.Add (new Argument (new TypeOf (new TypeExpression (type, loc), loc)));
+ if (type.IsPointer)
+ Error_PointerInsideExpressionTree ();
+
+ return CreateExpressionFactoryCall ("Convert", args);
+ }
+
public override Constant Increment ()
{
return child.Increment ();
@@ -1552,13 +1625,23 @@ namespace Mono.CSharp {
public override bool IsZeroInteger {
get { return child.IsZeroInteger; }
- }
+ }
public override void Emit (EmitContext ec)
{
child.Emit (ec);
}
+ public override void EmitBranchable (EmitContext ec, Label label, bool on_true)
+ {
+ child.EmitBranchable (ec, label, on_true);
+ }
+
+ public override void EmitSideEffect (EmitContext ec)
+ {
+ child.EmitSideEffect (ec);
+ }
+
public override Constant ConvertImplicitly (Type target_type)
{
// FIXME: Do we need to check user conversions?
@@ -1596,6 +1679,16 @@ namespace Mono.CSharp {
Child.Emit (ec);
}
+ public override void EmitBranchable (EmitContext ec, Label label, bool on_true)
+ {
+ Child.EmitBranchable (ec, label, on_true);
+ }
+
+ public override void EmitSideEffect (EmitContext ec)
+ {
+ Child.EmitSideEffect (ec);
+ }
+
public override bool GetAttributableValue (Type value_type, out object value)
{
value = GetTypedValue ();
@@ -1687,7 +1780,7 @@ namespace Mono.CSharp {
/// The effect of it is to box the value type emitted by the previous
/// operation.
///
- public class BoxedCast : EmptyCast {
+ public class BoxedCast : TypeCast {
public BoxedCast (Expression expr, Type target_type)
: base (expr, target_type)
@@ -1709,9 +1802,20 @@ namespace Mono.CSharp {
ec.ig.Emit (OpCodes.Box, child.Type);
}
+
+ public override void EmitSideEffect (EmitContext ec)
+ {
+ // boxing is side-effectful, since it involves runtime checks, except when boxing to Object or ValueType
+ // so, we need to emit the box+pop instructions in most cases
+ if (child.Type.IsValueType &&
+ (type == TypeManager.object_type || type == TypeManager.value_type))
+ child.EmitSideEffect (ec);
+ else
+ base.EmitSideEffect (ec);
+ }
}
- public class UnboxCast : EmptyCast {
+ public class UnboxCast : TypeCast {
public UnboxCast (Expression expr, Type return_type)
: base (expr, return_type)
{
@@ -1758,7 +1862,7 @@ namespace Mono.CSharp {
/// context, so they should generate the conv.ovf opcodes instead of
/// conv opcodes.
///
- public class ConvCast : EmptyCast {
+ public class ConvCast : TypeCast {
public enum Mode : byte {
I1_U1, I1_U2, I1_U4, I1_U8, I1_CH,
U1_I1, U1_CH,
@@ -1966,7 +2070,7 @@ namespace Mono.CSharp {
}
}
- public class OpcodeCast : EmptyCast {
+ public class OpcodeCast : TypeCast {
OpCode op, op2;
bool second_valid;
@@ -2002,14 +2106,18 @@ namespace Mono.CSharp {
if (second_valid)
ec.ig.Emit (op2);
- }
+ }
+
+ public Type UnderlyingType {
+ get { return child.Type; }
+ }
}
///
/// This kind of cast is used to encapsulate a child and cast it
/// to the class requested
///
- public class ClassCast : EmptyCast {
+ public class ClassCast : TypeCast {
public ClassCast (Expression child, Type return_type)
: base (child, return_type)
@@ -2039,37 +2147,182 @@ namespace Mono.CSharp {
ec.ig.Emit (OpCodes.Castclass, type);
}
}
+
+ //
+ // Used when resolved expression has different representations for
+ // expression trees and emit phase
+ //
+ public class ReducedExpression : Expression
+ {
+ class ReducedConstantExpression : Constant
+ {
+ readonly Constant expr;
+ readonly Expression orig_expr;
+
+ public ReducedConstantExpression (Constant expr, Expression orig_expr)
+ : base (expr.Location)
+ {
+ this.expr = expr;
+ this.orig_expr = orig_expr;
+ eclass = expr.eclass;
+ type = expr.Type;
+ }
+
+ public override string AsString ()
+ {
+ return expr.AsString ();
+ }
+
+ public override Expression CreateExpressionTree (EmitContext ec)
+ {
+ return orig_expr.CreateExpressionTree (ec);
+ }
+
+ public override object GetValue ()
+ {
+ return expr.GetValue ();
+ }
+
+ public override Constant ConvertExplicitly (bool in_checked_context, Type target_type)
+ {
+ throw new NotImplementedException ();
+ }
+
+ public override Expression DoResolve (EmitContext ec)
+ {
+ return this;
+ }
+
+ public override Constant Increment ()
+ {
+ throw new NotImplementedException ();
+ }
+
+ public override bool IsDefaultValue {
+ get {
+ return expr.IsDefaultValue;
+ }
+ }
+
+ public override bool IsNegative {
+ get {
+ return expr.IsNegative;
+ }
+ }
+
+ public override void Emit (EmitContext ec)
+ {
+ expr.Emit (ec);
+ }
+ }
+
+ readonly Expression expr, orig_expr;
+
+ private ReducedExpression (Expression expr, Expression orig_expr)
+ {
+ this.expr = expr;
+ this.orig_expr = orig_expr;
+ this.loc = orig_expr.Location;
+ }
+
+ public static Expression Create (Constant expr, Expression original_expr)
+ {
+ return new ReducedConstantExpression (expr, original_expr);
+ }
+
+ public static Expression Create (Expression expr, Expression original_expr)
+ {
+ Constant c = expr as Constant;
+ if (c != null)
+ return Create (c, original_expr);
+
+ return new ReducedExpression (expr, original_expr);
+ }
+
+ public override Expression CreateExpressionTree (EmitContext ec)
+ {
+ return orig_expr.CreateExpressionTree (ec);
+ }
+
+ public override Expression DoResolve (EmitContext ec)
+ {
+ eclass = expr.eclass;
+ type = expr.Type;
+ return this;
+ }
+
+ public override void Emit (EmitContext ec)
+ {
+ expr.Emit (ec);
+ }
+
+ public override void EmitBranchable (EmitContext ec, Label target, bool on_true)
+ {
+ expr.EmitBranchable (ec, target, on_true);
+ }
+ }
+
+ //
+ // Unresolved type name expressions
+ //
+ public abstract class ATypeNameExpression : FullNamedExpression
+ {
+ public readonly string Name;
+ protected TypeArguments targs;
+
+ protected ATypeNameExpression (string name, Location l)
+ {
+ Name = name;
+ loc = l;
+ }
+
+ protected ATypeNameExpression (string name, TypeArguments targs, Location l)
+ {
+ Name = name;
+ this.targs = targs;
+ loc = l;
+ }
+
+ public bool HasTypeArguments {
+ get {
+ return targs != null;
+ }
+ }
+
+ public override string GetSignatureForError ()
+ {
+ if (targs != null) {
+ return TypeManager.RemoveGenericArity (Name) + "<" +
+ targs.GetSignatureForError () + ">";
+ }
+
+ return Name;
+ }
+ }
///
/// SimpleName expressions are formed of a single word and only happen at the beginning
/// of a dotted-name.
///
- public class SimpleName : Expression {
- public readonly string Name;
- public readonly TypeArguments Arguments;
+ public class SimpleName : ATypeNameExpression {
bool in_transit;
public SimpleName (string name, Location l)
+ : base (name, l)
{
- Name = name;
- loc = l;
}
public SimpleName (string name, TypeArguments args, Location l)
+ : base (name, args, l)
{
- Name = name;
- Arguments = args;
- loc = l;
}
public SimpleName (string name, TypeParameter[] type_params, Location l)
+ : base (name, l)
{
- Name = name;
- loc = l;
-
- Arguments = new TypeArguments (l);
+ targs = new TypeArguments (l);
foreach (TypeParameter type_param in type_params)
- Arguments.Add (new TypeParameterExpr (type_param, l));
+ targs.Add (new TypeParameterExpr (type_param, l));
}
public static string RemoveGenericArity (string name)
@@ -2102,7 +2355,7 @@ namespace Mono.CSharp {
public SimpleName GetMethodGroup ()
{
- return new SimpleName (RemoveGenericArity (Name), Arguments, loc);
+ return new SimpleName (RemoveGenericArity (Name), targs, loc);
}
public static void Error_ObjectRefRequired (EmitContext ec, Location l, string name)
@@ -2166,7 +2419,7 @@ namespace Mono.CSharp {
Type[] gen_params = TypeManager.GetTypeArguments (t);
- int arg_count = Arguments != null ? Arguments.Count : 0;
+ int arg_count = targs != null ? targs.Count : 0;
for (; (ds != null) && ds.IsGeneric; ds = ds.Parent) {
if (arg_count + ds.CountTypeParameters == gen_params.Length) {
@@ -2174,8 +2427,8 @@ namespace Mono.CSharp {
foreach (TypeParameter param in ds.TypeParameters)
new_args.Add (new TypeParameterExpr (param, loc));
- if (Arguments != null)
- new_args.Add (Arguments);
+ if (targs != null)
+ new_args.Add (targs);
return new ConstructedType (t, new_args, loc);
}
@@ -2201,8 +2454,8 @@ namespace Mono.CSharp {
if (nested != null)
return nested.ResolveAsTypeStep (ec, false);
- if (Arguments != null) {
- ConstructedType ct = new ConstructedType (fne, Arguments, loc);
+ if (targs != null) {
+ ConstructedType ct = new ConstructedType (fne, targs, loc);
return ct.ResolveAsTypeStep (ec, false);
}
@@ -2241,7 +2494,7 @@ namespace Mono.CSharp {
return;
}
- if (Arguments != null) {
+ if (targs != null) {
FullNamedExpression retval = ec.DeclContainer.LookupNamespaceOrType (SimpleName.RemoveGenericArity (Name), loc, true);
if (retval != null) {
Namespace.Error_TypeArgumentsCannotBeUsed (retval.Type, loc);
@@ -2318,7 +2571,7 @@ namespace Mono.CSharp {
if (current_block != null){
LocalInfo vi = current_block.GetLocalInfo (Name);
if (vi != null){
- if (Arguments != null) {
+ if (targs != null) {
Report.Error (307, loc,
"The variable `{0}' cannot be used with type arguments",
Name);
@@ -2338,7 +2591,7 @@ namespace Mono.CSharp {
ParameterReference pref = current_block.Toplevel.GetParameterReference (Name, loc);
if (pref != null) {
- if (Arguments != null) {
+ if (targs != null) {
Report.Error (307, loc,
"The variable `{0}' cannot be used with type arguments",
Name);
@@ -2424,11 +2677,11 @@ namespace Mono.CSharp {
}
if (e is TypeExpr) {
- if (Arguments == null)
+ if (targs == null)
return e;
ConstructedType ct = new ConstructedType (
- (FullNamedExpression) e, Arguments, loc);
+ e.Type, targs, loc);
return ct.ResolveAsTypeStep (ec, false);
}
@@ -2448,7 +2701,7 @@ namespace Mono.CSharp {
if (!me.IsStatic &&
(!intermediate || !IdenticalNameAndTypeName (ec, me, loc))) {
Error_ObjectRefRequired (ec, loc, me.GetSignatureForError ());
- return EmptyExpression.Null;
+ return null;
}
//
@@ -2466,9 +2719,9 @@ namespace Mono.CSharp {
if (me == null)
return null;
- if (Arguments != null) {
- Arguments.Resolve (ec);
- me.SetTypeArguments (Arguments);
+ if (targs != null) {
+ targs.Resolve (ec);
+ me.SetTypeArguments (targs);
}
if (!me.IsStatic && (me.InstanceExpression != null) &&
@@ -2489,26 +2742,6 @@ namespace Mono.CSharp {
return e;
}
- public override void Emit (EmitContext ec)
- {
- throw new InternalErrorException ("The resolve phase was not executed");
- }
-
- public override string ToString ()
- {
- return Name;
- }
-
- public override string GetSignatureForError ()
- {
- if (Arguments != null) {
- return TypeManager.RemoveGenericArity (Name) + "<" +
- Arguments.GetSignatureForError () + ">";
- }
-
- return Name;
- }
-
protected override void CloneTo (CloneContext clonectx, Expression target)
{
// CloneTo: Nothing, we do not keep any state on this expression
@@ -2520,13 +2753,21 @@ namespace Mono.CSharp {
/// section 10.8.1 (Fully Qualified Names).
///
public abstract class FullNamedExpression : Expression {
+
+ public override Expression CreateExpressionTree (EmitContext ec)
+ {
+ throw new NotSupportedException ("ET");
+ }
+
public override FullNamedExpression ResolveAsTypeStep (IResolveContext ec, bool silent)
{
return this;
}
- public abstract string FullName {
- get;
+ public override void Emit (EmitContext ec)
+ {
+ throw new InternalErrorException ("FullNamedExpression `{0}' found in resolved tree",
+ GetSignatureForError ());
}
}
@@ -2549,19 +2790,14 @@ namespace Mono.CSharp {
return ResolveAsTypeTerminal (ec, false);
}
- override public void Emit (EmitContext ec)
- {
- throw new Exception ("Should never be called");
- }
-
public virtual bool CheckAccessLevel (DeclSpace ds)
{
return ds.CheckAccessLevel (Type);
}
- public virtual bool AsAccessible (DeclSpace ds, int flags)
+ public virtual bool AsAccessible (DeclSpace ds)
{
- return ds.AsAccessible (Type, flags);
+ return ds.IsAccessibleAs (Type);
}
public virtual bool IsClass {
@@ -2594,10 +2830,6 @@ namespace Mono.CSharp {
protected abstract TypeExpr DoResolveAsTypeStep (IResolveContext ec);
- public abstract string Name {
- get;
- }
-
public override bool Equals (object obj)
{
TypeExpr tobj = obj as TypeExpr;
@@ -2611,11 +2843,6 @@ namespace Mono.CSharp {
{
return Type.GetHashCode ();
}
-
- public override string ToString ()
- {
- return Name;
- }
}
///
@@ -2638,14 +2865,6 @@ namespace Mono.CSharp {
{
return this;
}
-
- public override string Name {
- get { return Type.ToString (); }
- }
-
- public override string FullName {
- get { return Type.FullName; }
- }
}
///
@@ -2779,14 +2998,6 @@ namespace Mono.CSharp {
return this;
}
- public override string Name {
- get { return name; }
- }
-
- public override string FullName {
- get { return name; }
- }
-
protected override void CloneTo (CloneContext clonectx, Expression target)
{
// CloneTo: Nothing, we do not keep any state on this expression
@@ -2815,6 +3026,11 @@ namespace Mono.CSharp {
loc = l;
}
+ protected override void CloneTo (CloneContext clonectx, Expression target)
+ {
+ // Nothing to clone
+ }
+
protected override TypeExpr DoResolveAsTypeStep (IResolveContext ec)
{
Expression expr;
@@ -2832,99 +3048,6 @@ namespace Mono.CSharp {
type = fne.Type;
return new TypeExpression (type, loc);
}
-
- public override string Name {
- get { return name.FullName; }
- }
-
- public override string FullName {
- get { return name.FullName; }
- }
- }
-
- public class TypeAliasExpression : TypeExpr {
- FullNamedExpression alias;
- TypeExpr texpr;
- TypeArguments args;
- string name;
-
- public TypeAliasExpression (FullNamedExpression alias, TypeArguments args, Location l)
- {
- this.alias = alias;
- this.args = args;
- loc = l;
-
- eclass = ExprClass.Type;
- if (args != null)
- name = alias.FullName + "<" + args.ToString () + ">";
- else
- name = alias.FullName;
- }
-
- public override string Name {
- get { return alias.FullName; }
- }
-
- public override string FullName {
- get { return name; }
- }
-
- protected override TypeExpr DoResolveAsTypeStep (IResolveContext ec)
- {
- texpr = alias.ResolveAsTypeTerminal (ec, false);
- if (texpr == null)
- return null;
-
- Type type = texpr.Type;
- int num_args = TypeManager.GetNumberOfTypeArguments (type);
-
- if (args != null) {
- if (num_args == 0) {
- Report.Error (308, loc,
- "The non-generic type `{0}' cannot " +
- "be used with type arguments.",
- TypeManager.CSharpName (type));
- return null;
- }
-
- ConstructedType ctype = new ConstructedType (type, args, loc);
- return ctype.ResolveAsTypeTerminal (ec, false);
- } else if (num_args > 0) {
- Report.Error (305, loc,
- "Using the generic type `{0}' " +
- "requires {1} type arguments",
- TypeManager.CSharpName (type), num_args.ToString ());
- return null;
- }
-
- return texpr;
- }
-
- public override bool CheckAccessLevel (DeclSpace ds)
- {
- return texpr.CheckAccessLevel (ds);
- }
-
- public override bool AsAccessible (DeclSpace ds, int flags)
- {
- return texpr.AsAccessible (ds, flags);
- }
-
- public override bool IsClass {
- get { return texpr.IsClass; }
- }
-
- public override bool IsValueType {
- get { return texpr.IsValueType; }
- }
-
- public override bool IsInterface {
- get { return texpr.IsInterface; }
- }
-
- public override bool IsSealed {
- get { return texpr.IsSealed; }
- }
}
///
@@ -2983,6 +3106,11 @@ 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");
+ }
+
// TODO: possible optimalization
// Cache resolved constant result in FieldBuilder <-> expression map
public virtual MemberExpr ResolveMemberAccess (EmitContext ec, Expression left, Location loc,
@@ -3123,7 +3251,7 @@ namespace Mono.CSharp {
return null;
// Search continues
- ExtensionMethodGroupExpr e = ns.LookupExtensionMethod (type, null, Name);
+ ExtensionMethodGroupExpr e = ns.LookupExtensionMethod (type, null, Name, loc);
if (e == null)
return base.OverloadResolve (ec, ref arguments, false, loc);
@@ -3259,57 +3387,80 @@ namespace Mono.CSharp {
return (MethodInfo)mg.best_candidate;
}
- ///
- /// Determines "better conversion" as specified in 14.4.2.3
- ///
- /// Returns : p if a->p is better,
- /// q if a->q is better,
- /// null if neither is better
- ///
- static Type BetterConversion (EmitContext ec, Argument a, Type p, Type q)
+ //
+ // 7.4.3.3 Better conversion from expression
+ // Returns : 1 if a->p is better,
+ // 2 if a->q is better,
+ // 0 if neither is better
+ //
+ static int BetterExpressionConversion (EmitContext ec, Argument a, Type p, Type q)
{
Type argument_type = TypeManager.TypeToCoreType (a.Type);
- Expression argument_expr = a.Expr;
+ if (argument_type == TypeManager.anonymous_method_type && RootContext.Version > LanguageVersion.ISO_2) {
+ //
+ // Uwrap delegate from Expression
+ //
+ 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;
+ } else {
+ if (argument_type == p)
+ return 1;
- if (argument_type == null)
- throw new Exception ("Expression of type " + a.Expr +
- " does not resolve its type");
+ if (argument_type == q)
+ return 2;
+ }
- if (p == null || q == null)
- throw new InternalErrorException ("BetterConversion Got a null conversion");
+ return BetterTypeConversion (ec, p, q);
+ }
- if (p == q)
- return null;
+ //
+ // 7.4.3.4 Better conversion from type
+ //
+ public static int BetterTypeConversion (EmitContext ec, Type p, Type q)
+ {
+ if (p == null || q == null)
+ throw new InternalErrorException ("BetterTypeConversion got a null conversion");
- if (argument_expr is NullLiteral)
- {
- //
- // If the argument is null and one of the types to compare is 'object' and
- // the other is a reference type, we prefer the other.
- //
- // This follows from the usual rules:
- // * There is an implicit conversion from 'null' to type 'object'
- // * There is an implicit conversion from 'null' to any reference type
- // * There is an implicit conversion from any reference type to type 'object'
- // * There is no implicit conversion from type 'object' to other reference types
- // => Conversion of 'null' to a reference type is better than conversion to 'object'
- //
- // FIXME: This probably isn't necessary, since the type of a NullLiteral is the
- // null type. I think it used to be 'object' and thus needed a special
- // case to avoid the immediately following two checks.
- //
- if (!p.IsValueType && q == TypeManager.object_type)
- return p;
- if (!q.IsValueType && p == TypeManager.object_type)
- return q;
+ if (p == TypeManager.int32_type) {
+ if (q == TypeManager.uint32_type || q == TypeManager.uint64_type)
+ return 1;
+ } else if (p == TypeManager.int64_type) {
+ if (q == TypeManager.uint64_type)
+ return 1;
+ } else if (p == TypeManager.sbyte_type) {
+ if (q == TypeManager.byte_type || q == TypeManager.ushort_type ||
+ q == TypeManager.uint32_type || q == TypeManager.uint64_type)
+ return 1;
+ } else if (p == TypeManager.short_type) {
+ if (q == TypeManager.ushort_type || q == TypeManager.uint32_type ||
+ q == TypeManager.uint64_type)
+ return 1;
}
-
- if (argument_type == p)
- return p;
- if (argument_type == q)
- return q;
+ if (q == TypeManager.int32_type) {
+ if (p == TypeManager.uint32_type || p == TypeManager.uint64_type)
+ return 2;
+ } if (q == TypeManager.int64_type) {
+ if (p == TypeManager.uint64_type)
+ return 2;
+ } else if (q == TypeManager.sbyte_type) {
+ if (p == TypeManager.byte_type || p == TypeManager.ushort_type ||
+ p == TypeManager.uint32_type || p == TypeManager.uint64_type)
+ return 2;
+ } if (q == TypeManager.short_type) {
+ if (p == TypeManager.ushort_type || p == TypeManager.uint32_type ||
+ p == TypeManager.uint64_type)
+ return 2;
+ }
+ // TODO: this is expensive
Expression p_tmp = new EmptyExpression (p);
Expression q_tmp = new EmptyExpression (q);
@@ -3317,44 +3468,12 @@ namespace Mono.CSharp {
bool q_to_p = Convert.ImplicitConversionExists (ec, q_tmp, p);
if (p_to_q && !q_to_p)
- return p;
+ return 1;
if (q_to_p && !p_to_q)
- return q;
-
- if (p == TypeManager.sbyte_type)
- if (q == TypeManager.byte_type || q == TypeManager.ushort_type ||
- q == TypeManager.uint32_type || q == TypeManager.uint64_type)
- return p;
- if (q == TypeManager.sbyte_type)
- if (p == TypeManager.byte_type || p == TypeManager.ushort_type ||
- p == TypeManager.uint32_type || p == TypeManager.uint64_type)
- return q;
-
- if (p == TypeManager.short_type)
- if (q == TypeManager.ushort_type || q == TypeManager.uint32_type ||
- q == TypeManager.uint64_type)
- return p;
- if (q == TypeManager.short_type)
- if (p == TypeManager.ushort_type || p == TypeManager.uint32_type ||
- p == TypeManager.uint64_type)
- return q;
-
- if (p == TypeManager.int32_type)
- if (q == TypeManager.uint32_type || q == TypeManager.uint64_type)
- return p;
- if (q == TypeManager.int32_type)
- if (p == TypeManager.uint32_type || p == TypeManager.uint64_type)
- return q;
-
- if (p == TypeManager.int64_type)
- if (q == TypeManager.uint64_type)
- return p;
- if (q == TypeManager.int64_type)
- if (p == TypeManager.uint64_type)
- return q;
+ return 2;
- return null;
+ return 0;
}
///
@@ -3398,16 +3517,16 @@ namespace Mono.CSharp {
continue;
same = false;
- Type better = BetterConversion (ec, a, ct, bt);
+ int result = BetterExpressionConversion (ec, a, ct, bt);
// for each argument, the conversion to 'ct' should be no worse than
// the conversion to 'bt'.
- if (better == bt)
+ if (result == 2)
return false;
// for at least one argument, the conversion to 'ct' should be better than
// the conversion to 'bt'.
- if (better == ct)
+ if (result != 0)
better_at_least_one = true;
}
@@ -3513,7 +3632,20 @@ namespace Mono.CSharp {
public override Expression CreateExpressionTree (EmitContext ec)
{
- return new Cast (new TypeExpression (typeof (MethodInfo), loc), new TypeOfMethod (this));
+ 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);
}
override public Expression DoResolve (EmitContext ec)
@@ -3591,6 +3723,12 @@ namespace Mono.CSharp {
Report.Error (1503, loc, "Argument {0}: Cannot convert type `{1}' to `{2}'", index, p1, p2);
}
}
+
+ public override void Error_ValueCannotBeConverted (EmitContext ec, Location loc, Type target, bool expl)
+ {
+ Report.Error (428, loc, "Cannot convert method group `{0}' to non-delegate type `{1}'. Consider using parentheses to invoke the method",
+ Name, TypeManager.CSharpName (target));
+ }
protected virtual int GetApplicableParametersCount (MethodBase method, ParameterData parameters)
{
@@ -3645,7 +3783,8 @@ namespace Mono.CSharp {
return score - 20000;
if (TypeManager.IsGenericMethodDefinition (candidate))
- throw new InternalErrorException ("a generic method definition took part in overload resolution");
+ throw new InternalErrorException ("A generic method `{0}' definition took part in overload resolution",
+ TypeManager.CSharpSignature (candidate));
pd = TypeManager.GetParameterData (candidate);
}
@@ -3692,8 +3831,11 @@ namespace Mono.CSharp {
params_expanded_form = true;
}
- if (score != 0)
+ if (score != 0) {
+ if (params_expanded_form)
+ ++score;
return (arg_count - i) * 2 + score;
+ }
}
if (arg_count != param_count)
@@ -3721,21 +3863,13 @@ namespace Mono.CSharp {
return 0;
}
- // FIXME: Kill this abomination (EmitContext.TempEc)
- EmitContext prevec = EmitContext.TempEc;
- EmitContext.TempEc = ec;
- try {
- if (delegate_type != null ?
- !Delegate.IsTypeCovariant (argument.Expr, parameter) :
- !Convert.ImplicitConversionExists (ec, argument.Expr, parameter))
- return 2;
-
- if (arg_mod != param_mod)
- return 1;
+ if (delegate_type != null ?
+ !Delegate.IsTypeCovariant (argument.Expr, parameter) :
+ !Convert.ImplicitConversionExists (ec, argument.Expr, parameter))
+ return 2;
- } finally {
- EmitContext.TempEc = prevec;
- }
+ if (arg_mod != param_mod)
+ return 1;
return 0;
}
@@ -3993,7 +4127,7 @@ namespace Mono.CSharp {
// not an extension method. We start extension methods lookup from here
//
if (InstanceExpression != null) {
- ExtensionMethodGroupExpr ex_method_lookup = ec.TypeContainer.LookupExtensionMethod (type, Name);
+ ExtensionMethodGroupExpr ex_method_lookup = ec.TypeContainer.LookupExtensionMethod (type, Name, loc);
if (ex_method_lookup != null) {
ex_method_lookup.ExtensionExpression = InstanceExpression;
ex_method_lookup.SetTypeArguments (type_arguments);
@@ -4041,9 +4175,8 @@ namespace Mono.CSharp {
}
}
- if (VerifyArgumentsCompat (ec, ref Arguments, arg_count, best_candidate, cand_params, may_fail, loc))
- throw new InternalErrorException ("Overload verification expected failure");
- return null;
+ if (!VerifyArgumentsCompat (ec, ref Arguments, arg_count, best_candidate, cand_params, may_fail, loc))
+ return null;
}
}
@@ -4148,7 +4281,7 @@ namespace Mono.CSharp {
// should be better than all the others
//
MethodBase ambiguous = null;
- for (int ix = 0; ix < candidate_top; ix++) {
+ for (int ix = 1; ix < candidate_top; ix++) {
MethodBase candidate = (MethodBase) candidates [ix];
if (candidate == best_candidate)
@@ -4299,7 +4432,7 @@ namespace Mono.CSharp {
continue;
}
-
+
Expression conv;
if (TypeManager.IsEqual (a.Type, pt)) {
conv = a.Expr;
@@ -4313,12 +4446,14 @@ namespace Mono.CSharp {
// Convert params arguments to an array initializer
//
if (params_initializers != null) {
- params_initializers.Add (conv);
+ // we choose to use 'a.Expr' rather than 'conv' so that
+ // we don't hide the kind of expression we have (esp. CompoundAssign.Helper)
+ params_initializers.Add (a.Expr);
arguments.RemoveAt (a_idx--);
--arg_count;
continue;
}
-
+
// Update the argument with the implicit conversion
a.Expr = conv;
}
@@ -4326,7 +4461,7 @@ namespace Mono.CSharp {
//
// Fill not provided arguments required by params modifier
//
- if (params_initializers == null && pd.HasParams && arg_count < pd.Count) {
+ if (params_initializers == null && pd.HasParams && arg_count < pd.Count && a_idx + 1 == pd.Count) {
if (arguments == null)
arguments = new ArrayList (1);
@@ -4403,6 +4538,11 @@ namespace Mono.CSharp {
return base.ResolveMemberAccess (ec, left, loc, original);
}
+ public override Expression CreateExpressionTree (EmitContext ec)
+ {
+ throw new NotSupportedException ("ET");
+ }
+
public override Expression DoResolve (EmitContext ec)
{
IConstant ic = TypeManager.GetConstant (constant);
@@ -4498,6 +4638,26 @@ namespace Mono.CSharp {
return base.ResolveMemberAccess (ec, left, loc, original);
}
+ public override Expression CreateExpressionTree (EmitContext ec)
+ {
+ Expression instance;
+ if (InstanceExpression == null) {
+ instance = new NullLiteral (loc);
+ } else {
+ instance = InstanceExpression.CreateExpressionTree (ec);
+ }
+
+ ArrayList args = new ArrayList (2);
+ args.Add (new Argument (instance));
+ args.Add (new Argument (CreateTypeOfExpression ()));
+ return CreateExpressionFactoryCall ("Field", args);
+ }
+
+ public Expression CreateTypeOfExpression ()
+ {
+ return new TypeOfField (FieldInfo, loc);
+ }
+
override public Expression DoResolve (EmitContext ec)
{
return DoResolve (ec, false, false);
@@ -4582,7 +4742,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;
@@ -4633,7 +4793,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;
@@ -4671,7 +4831,7 @@ namespace Mono.CSharp {
}
if (right_side == EmptyExpression.OutAccess &&
- !IsStatic && !(InstanceExpression is This) && DeclaringType.IsSubclassOf (TypeManager.mbr_type)) {
+ !IsStatic && !(InstanceExpression is This) && TypeManager.mbr_type != null && TypeManager.IsSubclassOf (DeclaringType, TypeManager.mbr_type)) {
Report.SymbolRelatedToPreviousError (DeclaringType);
Report.Warning (197, 1, loc,
"Passing `{0}' as ref or out or taking its address may cause a runtime exception because it is a field of a marshal-by-reference class",
@@ -4681,28 +4841,34 @@ namespace Mono.CSharp {
return this;
}
+ bool is_marshal_by_ref ()
+ {
+ return !IsStatic && Type.IsValueType && TypeManager.mbr_type != null && TypeManager.IsSubclassOf (DeclaringType, TypeManager.mbr_type);
+ }
+
public override void CheckMarshalByRefAccess (EmitContext ec)
{
- if (!IsStatic && Type.IsValueType && !(InstanceExpression is This) && DeclaringType.IsSubclassOf (TypeManager.mbr_type)) {
+ if (is_marshal_by_ref () && !(InstanceExpression is This)) {
Report.SymbolRelatedToPreviousError (DeclaringType);
Report.Warning (1690, 1, loc, "Cannot call methods, properties, or indexers on `{0}' because it is a value type member of a marshal-by-reference class",
GetSignatureForError ());
}
}
- 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)
{
@@ -4774,10 +4940,7 @@ namespace Mono.CSharp {
return;
}
- //
- // String concatenation creates a new string instance
- //
- prepared = prepare_for_load && !(source is StringConcat);
+ prepared = prepare_for_load;
EmitInstance (ec, prepared);
source.Emit (ec);
@@ -4813,6 +4976,15 @@ namespace Mono.CSharp {
Emit (ec, false);
}
+ public override void EmitSideEffect (EmitContext ec)
+ {
+ FieldBase f = TypeManager.GetField (FieldInfo);
+ bool is_volatile = f != null && (f.ModFlags & Modifiers.VOLATILE) != 0;
+
+ if (is_volatile || is_marshal_by_ref ())
+ base.EmitSideEffect (ec);
+ }
+
public void AddressOf (EmitContext ec, AddressOp mode)
{
ILGenerator ig = ec.ig;
@@ -4917,18 +5089,30 @@ 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 ()
+ {
+ return new TypeOfMethodInfo (setter, loc);
}
public override Type DeclaringType {
@@ -5044,7 +5228,7 @@ namespace Mono.CSharp {
Error_TypeDoesNotContainDefinition (loc, PropertyInfo.DeclaringType, Name);
return;
}
-
+
StringBuilder sig = new StringBuilder (TypeManager.CSharpName (mi.DeclaringType));
sig.Append ('.');
ParameterData iparams = TypeManager.GetParameterData (mi);
@@ -5068,18 +5252,12 @@ namespace Mono.CSharp {
bool IsSingleDimensionalArrayLength ()
{
- if (getter == TypeManager.system_int_array_get_length ||
- getter == TypeManager.int_array_get_length) {
- Type iet = InstanceExpression.Type;
-
- //
- // System.Array.Length can be called, but the Type does not
- // support invoking GetArrayRank, so test for that case first
- //
- return iet != TypeManager.array_type && (iet.GetArrayRank () == 1);
- }
+ if (DeclaringType != TypeManager.array_type || getter == null || Name != "Length")
+ return false;
- return false;
+ string t_name = InstanceExpression.Type.Name;
+ int t_name_len = t_name.Length;
+ return t_name_len > 2 && t_name [t_name_len - 2] == '[';
}
override public Expression DoResolve (EmitContext ec)
@@ -5250,14 +5428,9 @@ namespace Mono.CSharp {
Expression my_source = source;
if (prepare_for_load) {
- if (source is StringConcat)
- EmitInstance (ec, false);
- else
- prepared = true;
-
+ prepared = true;
source.Emit (ec);
- prepared = true;
if (leave_copy) {
ec.ig.Emit (OpCodes.Dup);
if (!is_static) {
@@ -5374,7 +5547,6 @@ namespace Mono.CSharp {
return base.ResolveMemberAccess (ec, left, loc, original);
}
-
bool InstanceResolve (EmitContext ec, bool must_do_cs1540_check)
{
if (is_static) {
@@ -5402,7 +5574,7 @@ namespace Mono.CSharp {
//
if (must_do_cs1540_check && InstanceExpression != EmptyExpression.Null &&
InstanceExpression.Type != ec.ContainerType &&
- ec.ContainerType.IsSubclassOf (InstanceExpression.Type)) {
+ TypeManager.IsSubclassOf (ec.ContainerType, InstanceExpression.Type)) {
Report.SymbolRelatedToPreviousError (EventInfo);
ErrorIsInaccesible (loc, TypeManager.CSharpSignature (EventInfo));
return false;
@@ -5418,9 +5590,16 @@ namespace Mono.CSharp {
IsAccessorAccessible (invocation_type, remove_accessor, out dummy);
}
+ public override Expression CreateExpressionTree (EmitContext ec)
+ {
+ throw new NotSupportedException ("ET");
+ }
+
public override Expression DoResolveLValue (EmitContext ec, Expression right_side)
{
- return DoResolve (ec);
+ // contexts where an LValue is valid have already devolved to FieldExprs
+ Error_CannotAssign ();
+ return null;
}
public override Expression DoResolve (EmitContext ec)
@@ -5435,14 +5614,25 @@ namespace Mono.CSharp {
if (!InstanceResolve (ec, must_do_cs1540_check))
return null;
+
+ if (!ec.IsInCompoundAssignment) {
+ Error_CannotAssign ();
+ return null;
+ }
return this;
}
public override void Emit (EmitContext ec)
{
- Report.Error (70, loc, "The event `{0}' can only appear on the left hand side of += or -= "+
- "(except on the defining type)", GetSignatureForError ());
+ Error_CannotAssign ();
+ }
+
+ public void Error_CannotAssign ()
+ {
+ Report.Error (70, loc,
+ "The event `{0}' can only appear on the left hand side of += or -= when used outside of the type `{1}'",
+ GetSignatureForError (), TypeManager.CSharpName (EventInfo.DeclaringType));
}
public override string GetSignatureForError ()
@@ -5450,46 +5640,36 @@ namespace Mono.CSharp {
return TypeManager.CSharpSignature (EventInfo);
}
- public void EmitAddOrRemove (EmitContext ec, Expression source)
+ public void EmitAddOrRemove (EmitContext ec, bool is_add, Expression source)
{
- BinaryDelegate source_del = source as BinaryDelegate;
- if (source_del == null) {
- Emit (ec);
- return;
- }
- Expression handler = source_del.Right;
-
- Argument arg = new Argument (handler, Argument.AType.Expression);
- ArrayList args = new ArrayList ();
-
- args.Add (arg);
-
- if (source_del.IsAddition)
- Invocation.EmitCall (
- ec, IsBase, InstanceExpression, add_accessor, args, loc);
- else
- Invocation.EmitCall (
- ec, IsBase, InstanceExpression, remove_accessor, args, loc);
+ ArrayList args = new ArrayList (1);
+ args.Add (new Argument (source, Argument.AType.Expression));
+ Invocation.EmitCall (ec, IsBase, InstanceExpression, is_add ? add_accessor : remove_accessor, args, loc);
}
}
- 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))
@@ -5500,46 +5680,34 @@ namespace Mono.CSharp {
var = scope.AddLocal (li);
type = var.Type;
}
-
+
return this;
}
- public Variable Variable {
- get { return var != null ? var : li.Variable; }
- }
-
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 bool IsFixed {
+ get { return true; }
}
-
- public void EmitThis (EmitContext ec)
- {
- Variable.EmitInstance (ec);
+
+ public override bool IsRef {
+ get { return false; }
}
-
- public void EmitStore (EmitContext ec)
- {
- Variable.EmitAssign (ec);
+
+ public override Variable Variable {
+ get { return var != null ? var : li.Variable; }
}
-
- public void AddressOf (EmitContext ec, AddressOp mode)
- {
- EmitLoadAddress (ec);
+
+ public override VariableInfo VariableInfo {
+ get { throw new NotImplementedException (); }
}
}
@@ -5563,7 +5731,7 @@ namespace Mono.CSharp {
}
}
- public override Expression DoResolveLValue (EmitContext ec, Expression right_side)
+ public bool InferType (EmitContext ec, Expression right_side)
{
if (type != null)
throw new InternalErrorException ("An implicitly typed local variable could not be redefined");
@@ -5572,11 +5740,11 @@ namespace Mono.CSharp {
if (type == TypeManager.null_type || type == TypeManager.void_type || type == TypeManager.anonymous_method_type) {
Report.Error (815, loc, "An implicitly typed local variable declaration cannot be initialized with `{0}'",
right_side.GetSignatureForError ());
- return null;
+ return false;
}
eclass = ExprClass.Variable;
- return this;
+ return true;
}
protected override void Error_TypeOrNamespaceNotFound (IResolveContext ec)