[mono-vb] mbas patch for handling enums better

Bernie Solomon bernard@ugs.com
Mon, 9 Aug 2004 14:02:35 -0700

This is a multi-part message in MIME format.

Content-Type: text/plain;
Content-Transfer-Encoding: 7bit

I attach a patch to improve the handling of enums - in
particular do the implicit conversions that VB does
to underlying type - or a type the underlying type can
itself be implicitly converted too. 

I also attach a test program which fails without these
changes and works with.

Note this is incomplete as it doesn't as yet check
access to types properly but at least lets some valid code

OK to commit?

Bernie Solomon
Content-Type: text/plain;
Content-Transfer-Encoding: quoted-printable
Content-Disposition: attachment;

Index: ecore.cs=0A=
RCS file: /cvs/public/mcs/mbas/ecore.cs,v=0A=
retrieving revision 1.35=0A=
diff -u -p -r1.35 ecore.cs=0A=
--- ecore.cs	20 Jul 2004 07:32:08 -0000	1.35=0A=
+++ ecore.cs	9 Aug 2004 19:56:29 -0000=0A=
@@ -1047,6 +1047,13 @@ namespace Mono.MonoBASIC {=0A=
 			if (expr_type =3D=3D target_type)=0A=
 				return true;=0A=
+			// Conversions from enum to underlying type are widening.=0A=
+			if (expr_type.IsSubclassOf (TypeManager.enum_type))=0A=
+				expr_type =3D TypeManager.EnumToUnderlying (expr_type);=0A=
+			if (expr_type =3D=3D target_type)=0A=
+				return true;=0A=
 			// First numeric conversions =0A=
 			if (expr_type =3D=3D TypeManager.sbyte_type){=0A=
@@ -1789,11 +1796,14 @@ namespace Mono.MonoBASIC {=0A=
 			if (e !=3D null)=0A=
 				return e;=0A=
-			if (target_type.IsSubclassOf (TypeManager.enum_type) && expr is =
-				IntLiteral i =3D (IntLiteral) expr;=0A=
-				if (i.Value =3D=3D 0)=0A=
-					return new EmptyCast (expr, target_type);=0A=
+			if (expr.Type.IsSubclassOf (TypeManager.enum_type)) {=0A=
+				expr_type =3D TypeManager.EnumToUnderlying (expr.Type);=0A=
+				expr =3D new EmptyCast (expr, expr_type);=0A=
+				if (expr_type =3D=3D target_type)=0A=
+					return expr;=0A=
+				e =3D ImplicitNumericConversion (ec, expr, target_type, loc);=0A=
+				if (e !=3D null)=0A=
+					return e;=0A=
 			if (ec.InUnsafe) {=0A=
Index: expression.cs=0A=
RCS file: /cvs/public/mcs/mbas/expression.cs,v=0A=
retrieving revision 1.54=0A=
diff -u -p -r1.54 expression.cs=0A=
--- expression.cs	6 Aug 2004 18:29:34 -0000	1.54=0A=
+++ expression.cs	9 Aug 2004 19:56:29 -0000=0A=
@@ -5763,16 +5763,12 @@ namespace Mono.MonoBASIC {=0A=
 						Enum en =3D TypeManager.LookupEnum (decl_type);=0A=
 						Constant c;=0A=
-						if (en !=3D null) {=0A=
+						if (en !=3D null)=0A=
 							c =3D Constantify (o, en.UnderlyingType);=0A=
-							return new EnumConstant (c, en.UnderlyingType);=0A=
-						}=0A=
-						else {=0A=
+						else=0A=
 							c =3D Constantify (o, enum_member.Type);=0A=
-							return new EnumConstant (c, enum_member.Type);=0A=
-						}=0A=
-						=0A=
-						=0A=
+						return new EnumConstant (c, decl_type);=0A=
 					Expression exp =3D Constantify (o, t);=0A=
@@ -5921,6 +5917,28 @@ namespace Mono.MonoBASIC {=0A=
 			Type expr_type =3D expr.Type;=0A=
+			if (expr is TypeExpr){=0A=
+				//FIXME: add access level check=0A=
+				//if (!ec.DeclSpace.CheckAccessLevel (expr_type)) {=0A=
+				//		Error (30390, "'" + TypeManager.MonoBASIC_Name (expr_type) + "' =
" +=0A=
+				//		       "is inaccessible because of its protection level");=0A=
+				//	return null;=0A=
+				//}=0A=
+				if (expr_type =3D=3D TypeManager.enum_type || =
expr_type.IsSubclassOf (TypeManager.enum_type)){=0A=
+					Enum en =3D TypeManager.LookupEnum (expr_type);=0A=
+					if (en !=3D null) {=0A=
+						object value =3D en.LookupEnumValue (ec, Identifier, loc);=0A=
+						=0A=
+						if (value !=3D null){=0A=
+							Constant c =3D Constantify (value, en.UnderlyingType);=0A=
+							return new EnumConstant (c, expr_type);=0A=
+						}=0A=
+					}=0A=
+				}=0A=
+			}=0A=
+			=0A=
 			if (expr_type.IsPointer){=0A=
 				Error (23, "The '.' operator can not be applied to pointer operands =
(" +=0A=
 				       TypeManager.MonoBASIC_Name (expr_type) + ")");=0A=

Content-Type: text/plain;
Content-Transfer-Encoding: quoted-printable
Content-Disposition: attachment;

Imports System=0A=
Module M=0A=
Enum E=0A=
End Enum=0A=
Sub InInt(ByVal i As Integer)=0A=
End Sub=0A=
Sub InLong(ByVal i As Long)=0A=
End Sub=0A=
Sub InEnum(ByVal e As E)=0A=
End Sub=0A=
Sub Main=0A=
    Dim e1 As E=0A=
    e1 =3D E.A=0A=
    If e1.GetType().ToString() <> GetType(E).ToString() Then=0A=
        Throw New Exception("#A1: wrong type")=0A=
    End If=0A=
    If E.A.GetType().ToString() <> GetType(E).ToString() Then=0A=
        Throw New Exception("#A2: wrong type")=0A=
    End If=0A=
    Dim e2 As E=0A=
    e2 =3D e1=0A=
    Dim i As Integer=0A=
    i =3D e2=0A=
End Sub=0A=
End Module=0A=