}
int errors = Report.Errors;
- FullNamedExpression fn = ((Expression) obj).ResolveAsTypeStep (ec);
+ FullNamedExpression fn = ((Expression) obj).ResolveAsTypeStep (ec, false);
if (fn == null) {
if (errors != Report.Errors)
expr = cexpr;
} else
- expr = fn.ResolveAsTypeTerminal (ec);
+ expr = fn.ResolveAsTypeTerminal (ec, false);
if ((expr == null) || (expr.Type == null))
return false;
atypes = new Type [count];
for (int i = 0; i < count; i++){
- TypeExpr te = ((Expression) args [i]).ResolveAsTypeTerminal (ec);
+ TypeExpr te = ((Expression) args [i]).ResolveAsTypeTerminal (ec, false);
if (te == null) {
ok = false;
continue;
}
TypeExpr ct = new ConstructedType (ctype, new_args, loc);
- if (ct.ResolveAsTypeStep (ec) == null)
+ if (ct.ResolveAsTypeStep (ec, false) == null)
return false;
ctype = ct.Type;
} else if (ctype.IsGenericParameter) {
bool HasDefaultConstructor (EmitContext ec, Type atype)
{
+ atype = TypeManager.DropGenericTypeArguments (atype);
+
if (atype is TypeBuilder) {
if (atype.IsAbstract)
return false;
}
MethodGroupExpr mg = Expression.MemberLookup (
- ec, atype, ".ctor", MemberTypes.Constructor,
+ ec.ContainerType, atype, ".ctor", MemberTypes.Constructor,
BindingFlags.Public | BindingFlags.Instance |
BindingFlags.DeclaredOnly, loc)
as MethodGroupExpr;
if (!p.Resolve (ec))
ok = false;
}
- if ((return_type != null) && (return_type.ResolveAsTypeTerminal (ec) == null))
+ if ((return_type != null) && (return_type.ResolveAsTypeTerminal (ec, false) == null))
ok = false;
return ok;
public override Expression DoResolve (EmitContext ec)
{
- TypeExpr texpr = expr.ResolveAsTypeTerminal (ec);
+ TypeExpr texpr = expr.ResolveAsTypeTerminal (ec, false);
if (texpr == null)
return null;
args.Add (underlying);
ConstructedType ctype = new ConstructedType (TypeManager.generic_nullable_type, args, loc);
- return ctype.ResolveAsTypeTerminal (ec);
+ return ctype.ResolveAsTypeTerminal (ec, false);
}
}
if (expr == null)
return null;
- if (!(expr is IMemoryLocation))
- temp = new LocalTemporary (ec, expr.Type);
+ temp = new LocalTemporary (ec, expr.Type);
info = new NullableInfo (expr.Type);
type = info.UnderlyingType;
ec.ig.EmitCall (OpCodes.Call, info.HasValue, null);
}
+ public void Store (EmitContext ec)
+ {
+ create_temp (ec);
+ }
+
void create_temp (EmitContext ec)
{
if ((temp != null) && !has_temp) {
public void EmitAssign (EmitContext ec, Expression source,
bool leave_copy, bool prepare_for_load)
{
- source.Emit (ec);
- ec.ig.Emit (OpCodes.Newobj, info.Constructor);
+ InternalWrap wrap = new InternalWrap (source, info, loc);
+ ((IAssignMethod) expr).EmitAssign (ec, wrap, leave_copy, false);
+ }
+
+ protected class InternalWrap : Expression
+ {
+ public Expression expr;
+ public NullableInfo info;
+
+ public InternalWrap (Expression expr, NullableInfo info, Location loc)
+ {
+ this.expr = expr;
+ this.info = info;
+ this.loc = loc;
+
+ type = info.Type;
+ eclass = ExprClass.Value;
+ }
- if (leave_copy)
- ec.ig.Emit (OpCodes.Dup);
+ public override Expression DoResolve (EmitContext ec)
+ {
+ return this;
+ }
- Expression empty = new EmptyExpression (expr.Type);
- ((IAssignMethod) expr).EmitAssign (ec, empty, false, prepare_for_load);
+ public override void Emit (EmitContext ec)
+ {
+ expr.Emit (ec);
+ ec.ig.Emit (OpCodes.Newobj, info.Constructor);
+ }
}
}
return null;
TypeExpr target_type = new NullableType (expr.Type, loc);
- target_type = target_type.ResolveAsTypeTerminal (ec);
+ target_type = target_type.ResolveAsTypeTerminal (ec, false);
if (target_type == null)
return null;
{
public readonly Binary.Operator Oper;
- Expression left, right, underlying, null_value, bool_wrap;
+ Expression left, right, original_left, original_right;
+ Expression underlying, null_value, bool_wrap;
Unwrap left_unwrap, right_unwrap;
bool is_equality, is_comparision, is_boolean;
Location loc)
{
this.Oper = op;
- this.left = left;
- this.right = right;
+ this.left = original_left = left;
+ this.right = original_right = right;
this.loc = loc;
}
return null;
}
- if (((Oper == Binary.Operator.BitwiseAnd) || (Oper == Binary.Operator.BitwiseOr) ||
- (Oper == Binary.Operator.LogicalAnd) || (Oper == Binary.Operator.LogicalOr)) &&
+ if ((Oper == Binary.Operator.LogicalAnd) ||
+ (Oper == Binary.Operator.LogicalOr)) {
+ Binary.Error_OperatorCannotBeApplied (
+ loc, Binary.OperName (Oper),
+ original_left.GetSignatureForError (),
+ original_right.GetSignatureForError ());
+ return null;
+ }
+
+ if (((Oper == Binary.Operator.BitwiseAnd) || (Oper == Binary.Operator.BitwiseOr)) &&
((left.Type == TypeManager.bool_type) && (right.Type == TypeManager.bool_type))) {
Expression empty = new EmptyExpression (TypeManager.bool_type);
bool_wrap = new Wrap (empty, loc).Resolve (ec);
public override void Emit (EmitContext ec)
{
+ if (left_unwrap != null)
+ left_unwrap.Store (ec);
+ if (right_unwrap != null)
+ right_unwrap.Store (ec);
+
if (is_boolean) {
EmitBoolean (ec);
return;