[m-rev.] diff: avoid some incomplete switches in the C# backend

Julien Fischer jfischer at opturion.com
Tue Mar 7 12:11:48 AEDT 2017


Avoid some incomplete switches in the C# backend.

This also fixes some (probably) broken behaviour for the backend's support for
the uint type.

compiler/mlds_to_cs.m:
      As above.

Julien.

diff --git a/compiler/mlds_to_cs.m b/compiler/mlds_to_cs.m
index 13a076d..6ce2f7e 100644
--- a/compiler/mlds_to_cs.m
+++ b/compiler/mlds_to_cs.m
@@ -2525,24 +2525,52 @@ type_category_is_array(CtorCat) = IsArray :-
      list(int)::out) is semidet.

  hand_defined_type(Type, CtorCat, SubstituteName, ArrayDims) :-
+    require_complete_switch [CtorCat] (
+        CtorCat = ctor_cat_system(TypeCtorCatSystem),
+        hand_defined_system_type_info(TypeCtorCatSystem, SubstituteName, ArrayDims)
+    ;
+        CtorCat = ctor_cat_user(TypeCtorCatUser),
+        hand_defined_user_type(TypeCtorCatUser, Type, SubstituteName, ArrayDims)
+    ;
+        ( CtorCat = ctor_cat_builtin(_)
+        ; CtorCat = ctor_cat_builtin_dummy
+        ; CtorCat = ctor_cat_enum(_)
+        ; CtorCat = ctor_cat_higher_order
+        ; CtorCat = ctor_cat_tuple
+        ; CtorCat = ctor_cat_variable
+        ; CtorCat = ctor_cat_void
+        ),
+        fail
+    ).
+
+:- pred hand_defined_system_type_info(type_ctor_cat_system::in, string::out,
+    list(int)::out) is det.
+
+hand_defined_system_type_info(TypeCtorCatSystem, SubstituteName, ArrayDims) :-
      (
-        CtorCat = ctor_cat_system(cat_system_type_info),
+        TypeCtorCatSystem = cat_system_type_info,
          SubstituteName = "runtime.TypeInfo_Struct",
          ArrayDims = []
      ;
-        CtorCat = ctor_cat_system(cat_system_type_ctor_info),
+        TypeCtorCatSystem = cat_system_type_ctor_info,
          SubstituteName = "runtime.TypeCtorInfo_Struct",
          ArrayDims = []
      ;
-        CtorCat = ctor_cat_system(cat_system_typeclass_info),
+        TypeCtorCatSystem = cat_system_typeclass_info,
          SubstituteName = "/* typeclass_info */ object",
          ArrayDims = [0]
      ;
-        CtorCat = ctor_cat_system(cat_system_base_typeclass_info),
+        TypeCtorCatSystem = cat_system_base_typeclass_info,
          SubstituteName = "/* base_typeclass_info */ object",
          ArrayDims = [0]
-    ;
-        CtorCat = ctor_cat_user(cat_user_general),
+    ).
+
+:- pred hand_defined_user_type(type_ctor_cat_user::in, mer_type::in,
+    string::out, list(int)::out) is semidet.
+
+hand_defined_user_type(TypeCtorCatUser, Type, SubstituteName, ArrayDims) :-
+    require_complete_switch [TypeCtorCatUser] (
+        TypeCtorCatUser = cat_user_general,
          ( if Type = type_desc_type then
              SubstituteName = "runtime.TypeInfo_Struct"
          else if Type = pseudo_type_desc_type then
@@ -2553,6 +2581,11 @@ hand_defined_type(Type, CtorCat, SubstituteName, ArrayDims) :-
              fail
          ),
          ArrayDims = []
+    ;
+        ( TypeCtorCatUser = cat_user_direct_dummy
+        ; TypeCtorCatUser = cat_user_notag
+        ),
+        fail
      ).

  :- pred boxed_type_to_string(csharp_out_info::in, mlds_type::in, string::out)
@@ -3563,27 +3596,92 @@ output_unboxed_rval(Info, Type, Expr, !IO) :-

  :- pred csharp_builtin_type(mlds_type::in, string::out) is semidet.

-csharp_builtin_type(Type, "int") :-
-    Type = mlds_native_int_type.
-csharp_builtin_type(Type, "int") :-
-    Type = mercury_type(builtin_type(builtin_type_int), _, _).
-csharp_builtin_type(Type, "double") :-
-    Type = mlds_native_float_type.
-csharp_builtin_type(Type, "double") :-
-    Type = mercury_type(builtin_type(builtin_type_float), _, _).
-    % C# `char' not large enough for code points so we must use `int'.
-csharp_builtin_type(Type, "int") :-
-    Type = mlds_native_char_type.
-csharp_builtin_type(Type, "int") :-
-    Type = mercury_type(builtin_type(builtin_type_char), _, _).
-csharp_builtin_type(Type, "bool") :-
-    Type = mlds_native_bool_type.
-csharp_builtin_type(Type, "int") :-
-    % The test for defined/3 is logically redundant since all dummy
-    % types are defined types, but enables the compiler to infer that
-    % this disjunction is a switch.
-    Type = mercury_type(defined_type(_, _, _), TypeCtorCat, _),
-    TypeCtorCat = ctor_cat_builtin_dummy.
+csharp_builtin_type(Type, TargetType) :-
+    require_complete_switch [Type] (
+        Type = mlds_native_bool_type,
+        TargetType = "bool"
+    ;
+        % C# `char' is not large enough for code points so we must use `int'.
+        ( Type = mlds_native_int_type
+        ; Type = mlds_native_char_type
+        ),
+        TargetType = "int"
+    ;
+        Type = mlds_native_uint_type,
+        TargetType = "uint"
+    ;
+        Type = mlds_native_float_type,
+        TargetType = "double"
+    ;
+        Type = mercury_type(MerType, TypeCtorCat, _),
+        require_complete_switch [MerType] (
+            MerType = builtin_type(BuiltinType),
+            require_complete_switch [BuiltinType] (
+                ( BuiltinType = builtin_type_char
+                ; BuiltinType = builtin_type_int
+                ),
+                TargetType = "int"
+            ;
+                BuiltinType = builtin_type_uint,
+                TargetType = "uint"
+            ;
+                BuiltinType = builtin_type_float,
+                TargetType = "double"
+            ;
+                BuiltinType = builtin_type_string,
+                fail
+            )
+    ;
+            MerType = defined_type(_, _, _),
+            require_complete_switch [TypeCtorCat] (
+                % io.state and store.store(S) are dummy variables for which we
+                % pass an arbitrary integer. For this reason they should have
+                % the C# type `int'.
+                TypeCtorCat = ctor_cat_builtin_dummy,
+                TargetType = "int"
+            ;
+                ( TypeCtorCat = ctor_cat_builtin(_)
+                ; TypeCtorCat = ctor_cat_higher_order
+                ; TypeCtorCat = ctor_cat_tuple
+                ; TypeCtorCat = ctor_cat_enum(_)
+                ; TypeCtorCat = ctor_cat_variable
+                ; TypeCtorCat = ctor_cat_system(_)
+                ; TypeCtorCat = ctor_cat_void
+                ; TypeCtorCat = ctor_cat_user(_)
+                ),
+                fail
+            )
+        ;
+            ( MerType = type_variable(_, _)
+            ; MerType = tuple_type(_, _)
+            ; MerType = higher_order_type(_, _, _, _, _)
+            ; MerType = apply_n_type(_, _, _)
+            ; MerType = kinded_type(_, _)
+            ),
+            fail
+        )
+    ;
+        ( Type = mlds_foreign_type(_)
+        ; Type = mlds_mercury_array_type(_)
+        ; Type = mlds_cont_type(_)
+        ; Type = mlds_commit_type
+        ; Type = mlds_class_type(_, _, _)
+        ; Type = mlds_array_type(_)
+        ; Type = mlds_mostly_generic_array_type(_)
+        ; Type = mlds_ptr_type(_)
+        ; Type = mlds_func_type(_)
+        ; Type = mlds_generic_type
+        ; Type = mlds_generic_env_ptr_type
+        ; Type = mlds_type_info_type
+        ; Type = mlds_pseudo_type_info_type
+        ; Type = mlds_rtti_type(_)
+        ; Type = mlds_tabling_type(_)
+        ),
+        fail
+    ;
+        Type = mlds_unknown_type,
+        unexpected($file, $pred, "unknown typed")
+    ).

  :- pred output_std_unop(csharp_out_info::in, builtin_ops.unary_op::in,
      mlds_rval::in, io::di, io::uo) is det.


More information about the reviews mailing list