void AddressOf (EmitContext ec, AddressOp mode);
}
- /// <summary>
- /// This interface is implemented by variables
- /// </summary>
+ // 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; }
}
/// <remarks>
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));
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;
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)
{
}
public override bool IsNull {
- get {
- return child.IsNull;
- }
+ get { return child.IsNull; }
}
}
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);
}
{
child.EmitSideEffect (ec);
}
-
}
/// <summary>
"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,
//
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 {
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);
}
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;
}
// 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;
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;
}
}
- 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)
{
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 ()
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)
}
}
- 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))
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 (); }
}
}