public override void Emit (EmitContext ec)
{
var call = new CallEmitter ();
- call.EmitPredefined (ec, oper, arguments);
+ call.EmitPredefined (ec, oper, arguments, loc);
}
public override SLE.Expression MakeExpression (BuilderContext ctx)
if (l.IsPointer || r.IsPointer)
return ResolveOperatorPointer (rc, l, r);
+ // User operators
+ expr = ResolveUserOperator (rc, left, right);
+ if (expr != null)
+ return expr;
+
+
bool lenum = l.IsEnum;
bool renum = r.IsEnum;
if ((oper & (Operator.ComparisonMask | Operator.BitwiseMask)) != 0) {
return expr;
}
}
-
- // User operators
- expr = ResolveUserOperator (rc, left, right);
- if (expr != null)
- return expr;
}
//
//
// Now try lifted version of predefined operators
//
- result = ResolveOperatorPredefined (ec, ec.Module.OperatorsBinaryEqualityLifted, no_arg_conv);
- if (result != null)
- return result;
+ if (no_arg_conv && !l.IsNullableType) {
+ //
+ // Optimizes cases which won't match
+ //
+ } else {
+ result = ResolveOperatorPredefined (ec, ec.Module.OperatorsBinaryEqualityLifted, no_arg_conv);
+ if (result != null)
+ return result;
+ }
//
// The == and != operators permit one operand to be a value of a nullable
/// </remarks>
public override void EmitBranchable (EmitContext ec, Label target, bool on_true)
{
+ if (ec.HasSet (BuilderContext.Options.AsyncBody) && right.ContainsEmitWithAwait ()) {
+ left = left.EmitToField (ec);
+
+ if ((oper & Operator.LogicalMask) == 0) {
+ right = right.EmitToField (ec);
+ }
+ }
+
//
// This is more complicated than it looks, but its just to avoid
// duplicated tests: basically, we allow ==, !=, >, <, >= and <=
if (member_expr != null)
member_expr = member_expr.Resolve (ec);
} else {
- member_expr = expr.Resolve (ec, ResolveFlags.VariableOrValue | ResolveFlags.MethodGroup);
+ member_expr = expr.Resolve (ec);
}
if (member_expr == null)
}
if (vr != null) {
+ ec.MarkCallEntry (loc);
ec.Emit (OpCodes.Call, method);
return false;
}
}
if (type is TypeParameterSpec)
- return DoEmitTypeParameter (ec);
+ return DoEmitTypeParameter (ec);
+ ec.MarkCallEntry (loc);
ec.Emit (OpCodes.Newobj, method);
return true;
}
e = e.ResolveLValue (rc, right_side);
} else {
- e = e.Resolve (rc, ResolveFlags.VariableOrValue | ResolveFlags.Type);
+ e = e.Resolve (rc, ResolveFlags.VariableOrValue | ResolveFlags.Type | ResolveFlags.MethodGroup);
}
return e;
public override void Emit (EmitContext ec)
{
source.Emit (ec);
+ ec.MarkCallEntry (loc);
ec.Emit (OpCodes.Call, method);
}
this.loc = loc;
}
+ public CollectionElementInitializer (Location loc)
+ : base (null, null)
+ {
+ this.loc = loc;
+ }
+
public override Expression CreateExpressionTree (ResolveContext ec)
{
Arguments args = new Arguments (2);