Author: martin
Date: 2006-09-19 09:16:40 -0400 (Tue, 19 Sep 2006)
New Revision: 65635
Modified:
trunk/mcs/mcs/ChangeLog
trunk/mcs/mcs/expression.cs
trunk/mcs/mcs/typemanager.cs
Log:
2006-09-19 Martin Baulig <[EMAIL PROTECTED]>
* expression.cs (Probe, As, Is): Merged with the gmcs version.
Modified: trunk/mcs/mcs/ChangeLog
===================================================================
--- trunk/mcs/mcs/ChangeLog 2006-09-19 13:11:12 UTC (rev 65634)
+++ trunk/mcs/mcs/ChangeLog 2006-09-19 13:16:40 UTC (rev 65635)
@@ -1,5 +1,9 @@
2006-09-19 Martin Baulig <[EMAIL PROTECTED]>
+ * expression.cs (Probe, As, Is): Merged with the gmcs version.
+
+2006-09-19 Martin Baulig <[EMAIL PROTECTED]>
+
* typemanager.cs: Merged with the gmcs version.
2006-09-16 Raja R Harinath <[EMAIL PROTECTED]>
Modified: trunk/mcs/mcs/expression.cs
===================================================================
--- trunk/mcs/mcs/expression.cs 2006-09-19 13:11:12 UTC (rev 65634)
+++ trunk/mcs/mcs/expression.cs 2006-09-19 13:16:40 UTC (rev 65635)
@@ -1045,7 +1045,7 @@
public abstract class Probe : Expression {
public Expression ProbeType;
protected Expression expr;
- protected Type probe_type;
+ protected TypeExpr probe_type_expr;
public Probe (Expression expr, Expression probe_type, Location
l)
{
@@ -1062,12 +1062,10 @@
public override Expression DoResolve (EmitContext ec)
{
- TypeExpr texpr = ProbeType.ResolveAsTypeTerminal (ec,
false);
- if (texpr == null)
+ probe_type_expr = ProbeType.ResolveAsTypeTerminal (ec,
false);
+ if (probe_type_expr == null)
return null;
- probe_type = texpr.Type;
-
expr = expr.Resolve (ec);
if (expr == null)
return null;
@@ -1118,14 +1116,14 @@
ig.Emit (OpCodes.Ceq);
return;
case Action.Probe:
- ig.Emit (OpCodes.Isinst, probe_type);
+ ig.Emit (OpCodes.Isinst, probe_type_expr.Type);
ig.Emit (OpCodes.Ldnull);
ig.Emit (OpCodes.Cgt_Un);
return;
}
throw new Exception ("never reached");
}
-
+
public override void EmitBranchable (EmitContext ec, Label
target, bool onTrue)
{
ILGenerator ig = ec.ig;
@@ -1148,7 +1146,7 @@
return;
case Action.Probe:
expr.Emit (ec);
- ig.Emit (OpCodes.Isinst, probe_type);
+ ig.Emit (OpCodes.Isinst, probe_type_expr.Type);
ig.Emit (onTrue ? OpCodes.Brtrue :
OpCodes.Brfalse, target);
return;
}
@@ -1173,6 +1171,7 @@
// First case, if at compile time, there is an implicit
conversion
// then e != null (objects) or true (value types)
//
+ Type probe_type = probe_type_expr.Type;
e = Convert.ImplicitConversionStandard (ec, expr,
probe_type, loc);
if (e != null && !(e is NullCast)){
expr = e;
@@ -1183,6 +1182,9 @@
warning_always_matches = true;
} else if (Convert.ExplicitReferenceConversionExists
(etype, probe_type)){
+ if (TypeManager.IsGenericParameter (etype))
+ expr = new BoxedCast (expr, etype);
+
//
// Second case: explicit reference convresion
//
@@ -1190,6 +1192,10 @@
action = Action.AlwaysFalse;
else
action = Action.Probe;
+ } else if (TypeManager.ContainsGenericParameters
(etype) ||
+ TypeManager.ContainsGenericParameters
(probe_type)) {
+ expr = new BoxedCast (expr, etype);
+ action = Action.Probe;
} else {
action = Action.AlwaysFalse;
warning_never_matches = true;
@@ -1225,7 +1231,7 @@
expr.Emit (ec);
if (do_isinst)
- ig.Emit (OpCodes.Isinst, probe_type);
+ ig.Emit (OpCodes.Isinst, probe_type_expr.Type);
}
static void Error_CannotConvertType (Type source, Type target,
Location loc)
@@ -1244,30 +1250,66 @@
return null;
}
- type = probe_type;
+ type = probe_type_expr.Type;
eclass = ExprClass.Value;
Type etype = expr.Type;
- if (TypeManager.IsValueType (probe_type)){
+ if (type.IsValueType) {
Report.Error (77, loc, "The as operator must be
used with a reference type (`" +
- TypeManager.CSharpName
(probe_type) + "' is a value type)");
+ TypeManager.CSharpName (type) +
"' is a value type)");
return null;
}
+
+#if GMCS_SOURCE
+ //
+ // If the type is a type parameter, ensure
+ // that it is constrained by a class
+ //
+ TypeParameterExpr tpe = probe_type_expr as
TypeParameterExpr;
+ if (tpe != null){
+ Constraints constraints =
tpe.TypeParameter.Constraints;
+ bool error = false;
+
+ if (constraints == null)
+ error = true;
+ else {
+ if (!constraints.HasClassConstraint)
+ if ((constraints.Attributes &
GenericParameterAttributes.ReferenceTypeConstraint) == 0)
+ error = true;
+ }
+ if (error){
+ Report.Error (413, loc,
+ "The as operator requires
that the `{0}' type parameter be constrained by a class",
+
probe_type_expr.GetSignatureForError ());
+ return null;
+ }
+ }
+#endif
- Expression e = Convert.ImplicitConversion (ec, expr,
probe_type, loc);
+ Expression e = Convert.ImplicitConversion (ec, expr,
type, loc);
if (e != null){
expr = e;
do_isinst = false;
return this;
}
- if (Convert.ExplicitReferenceConversionExists (etype,
probe_type)){
+ if (Convert.ExplicitReferenceConversionExists (etype,
type)){
+ if (TypeManager.IsGenericParameter (etype))
+ expr = new BoxedCast (expr, etype);
+
do_isinst = true;
return this;
}
- Error_CannotConvertType (etype, probe_type, loc);
+ if (TypeManager.ContainsGenericParameters (etype) ||
+ TypeManager.ContainsGenericParameters (type)) {
+ expr = new BoxedCast (expr, etype);
+ do_isinst = true;
+ return this;
+ }
+
+ Error_CannotConvertType (etype, type, loc);
return null;
}
Modified: trunk/mcs/mcs/typemanager.cs
===================================================================
--- trunk/mcs/mcs/typemanager.cs 2006-09-19 13:11:12 UTC (rev 65634)
+++ trunk/mcs/mcs/typemanager.cs 2006-09-19 13:16:40 UTC (rev 65635)
@@ -2668,6 +2668,15 @@
#endif
}
+ public static bool ContainsGenericParameters (Type type)
+ {
+#if GMCS_SOURCE
+ return type.ContainsGenericParameters;
+#else
+ return false;
+#endif
+ }
+
#if !GMCS_SOURCE
public static bool IsEqual (Type a, Type b)
{
_______________________________________________
Mono-patches maillist - [email protected]
http://lists.ximian.com/mailman/listinfo/mono-patches