From: Mikael Morin <[email protected]>

Regression tested on powerpc64le-unknown-linux-gnu.  OK for master?

-- >8 --

Add accessor functions to get or set the value of the type field of array
descriptors, and remove from the public API the function giving direct acces
to the field.

gcc/fortran/ChangeLog:

        * trans-descriptor.cc (get_type_field): New function.
        (gfc_get_descriptor_field): Use it.
        (gfc_conv_descriptor_type): Make static and rename ...
        (conv_descriptor_type): ... to this.
        (gfc_conv_descriptor_type_get, gfc_conv_descriptor_type_set): New
        functions.
        * trans-descriptor.h (gfc_conv_descriptor_type): Remove declaration.
        (gfc_conv_descriptor_type_get, gfc_conv_descriptor_type_set): New
        declarations.
        * trans-expr.cc (gfc_conv_gfc_desc_to_cfi_desc): Use
        gfc_conv_descriptor_type_get to get the value of the type field.
        * trans-decl.cc (gfc_conv_cfi_to_gfc): Use
        gfc_conv_descriptor_type_set to set the value of the type field.
---
 gcc/fortran/trans-decl.cc       | 23 +++------
 gcc/fortran/trans-descriptor.cc | 90 +++++++++++++++++++++++++++++++--
 gcc/fortran/trans-descriptor.h  |  5 +-
 gcc/fortran/trans-expr.cc       |  2 +-
 4 files changed, 99 insertions(+), 21 deletions(-)

diff --git a/gcc/fortran/trans-decl.cc b/gcc/fortran/trans-decl.cc
index cf35cac5c31..2243cf9da13 100644
--- a/gcc/fortran/trans-decl.cc
+++ b/gcc/fortran/trans-decl.cc
@@ -7341,25 +7341,20 @@ gfc_conv_cfi_to_gfc (stmtblock_t *init, stmtblock_t 
*finally,
       ctype = fold_build2_loc (input_location, BIT_AND_EXPR, TREE_TYPE (ctype),
                               ctype, build_int_cst (TREE_TYPE (ctype),
                                                     CFI_type_mask));
-      tree type = gfc_conv_descriptor_type (gfc_desc);
 
       /* if (CFI_type_cptr) BT_VOID else BT_UNKNOWN  */
       /* Note: BT_VOID is could also be CFI_type_funcptr, but assume c_ptr. */
       cond = fold_build2_loc (input_location, EQ_EXPR, boolean_type_node, 
ctype,
                              build_int_cst (TREE_TYPE (ctype), CFI_type_cptr));
-      tmp = fold_build2_loc (input_location, MODIFY_EXPR, void_type_node, type,
-                            build_int_cst (TREE_TYPE (type), BT_VOID));
-      tmp2 = fold_build2_loc (input_location, MODIFY_EXPR, void_type_node,
-                             type,
-                             build_int_cst (TREE_TYPE (type), BT_UNKNOWN));
+      tmp = gfc_conv_descriptor_type_set (gfc_desc, BT_VOID);
+      tmp2 = gfc_conv_descriptor_type_set (gfc_desc, BT_UNKNOWN);
       tmp2 = fold_build3_loc (input_location, COND_EXPR, void_type_node, cond,
                              tmp, tmp2);
       /* if (CFI_type_struct) BT_DERIVED else  < tmp2 >  */
       cond = fold_build2_loc (input_location, EQ_EXPR, boolean_type_node, 
ctype,
                              build_int_cst (TREE_TYPE (ctype),
                                             CFI_type_struct));
-      tmp = fold_build2_loc (input_location, MODIFY_EXPR, void_type_node, type,
-                            build_int_cst (TREE_TYPE (type), BT_DERIVED));
+      tmp = gfc_conv_descriptor_type_set (gfc_desc, BT_DERIVED);
       tmp2 = fold_build3_loc (input_location, COND_EXPR, void_type_node, cond,
                              tmp, tmp2);
       /* if (CFI_type_Character) BT_CHARACTER else  < tmp2 >  */
@@ -7368,8 +7363,7 @@ gfc_conv_cfi_to_gfc (stmtblock_t *init, stmtblock_t 
*finally,
       cond = fold_build2_loc (input_location, EQ_EXPR, boolean_type_node, 
ctype,
                              build_int_cst (TREE_TYPE (ctype),
                              CFI_type_Character));
-      tmp = fold_build2_loc (input_location, MODIFY_EXPR, void_type_node, type,
-                            build_int_cst (TREE_TYPE (type), BT_CHARACTER));
+      tmp = gfc_conv_descriptor_type_set (gfc_desc, BT_CHARACTER);
       tmp2 = fold_build3_loc (input_location, COND_EXPR, void_type_node, cond,
                              tmp, tmp2);
       /* if (CFI_type_ucs4_char) BT_CHARACTER else  < tmp2 >  */
@@ -7381,16 +7375,14 @@ gfc_conv_cfi_to_gfc (stmtblock_t *init, stmtblock_t 
*finally,
       cond = fold_build2_loc (input_location, EQ_EXPR, boolean_type_node, tmp,
                              build_int_cst (TREE_TYPE (tmp),
                                             CFI_type_ucs4_char));
-      tmp = fold_build2_loc (input_location, MODIFY_EXPR, void_type_node, type,
-                            build_int_cst (TREE_TYPE (type), BT_CHARACTER));
+      tmp = gfc_conv_descriptor_type_set (gfc_desc, BT_CHARACTER);
       tmp2 = fold_build3_loc (input_location, COND_EXPR, void_type_node, cond,
                              tmp, tmp2);
       /* if (CFI_type_Complex) BT_COMPLEX + cfi->elem_len/2 else  < tmp2 >  */
       cond = fold_build2_loc (input_location, EQ_EXPR, boolean_type_node, 
ctype,
                              build_int_cst (TREE_TYPE (ctype),
                              CFI_type_Complex));
-      tmp = fold_build2_loc (input_location, MODIFY_EXPR, void_type_node, type,
-                            build_int_cst (TREE_TYPE (type), BT_COMPLEX));
+      tmp = gfc_conv_descriptor_type_set (gfc_desc, BT_COMPLEX);
       tmp2 = fold_build3_loc (input_location, COND_EXPR, void_type_node, cond,
                              tmp, tmp2);
       /* if (CFI_type_Integer || CFI_type_Logical || CFI_type_Real)
@@ -7408,8 +7400,7 @@ gfc_conv_cfi_to_gfc (stmtblock_t *init, stmtblock_t 
*finally,
                                             CFI_type_Real));
       cond = fold_build2_loc (input_location, TRUTH_OR_EXPR, boolean_type_node,
                              cond, tmp);
-      tmp = fold_build2_loc (input_location, MODIFY_EXPR, void_type_node,
-                            type, fold_convert (TREE_TYPE (type), ctype));
+      tmp = gfc_conv_descriptor_type_set (gfc_desc, ctype);
       tmp2 = fold_build3_loc (input_location, COND_EXPR, void_type_node, cond,
                              tmp, tmp2);
       gfc_add_expr_to_block (&block, tmp2);
diff --git a/gcc/fortran/trans-descriptor.cc b/gcc/fortran/trans-descriptor.cc
index a00bed09f94..9e8dd46e273 100644
--- a/gcc/fortran/trans-descriptor.cc
+++ b/gcc/fortran/trans-descriptor.cc
@@ -61,13 +61,28 @@ along with GCC; see the file COPYING3.  If not see
 #define LBOUND_SUBFIELD 1
 #define UBOUND_SUBFIELD 2
 
+
+/* Get FIELD_IDX'th field in struct TYPE.  */
+
+static tree
+get_type_field (tree type, unsigned field_idx)
+{
+  tree field = gfc_advance_chain (TYPE_FIELDS (type), field_idx);
+  gcc_assert (field != NULL_TREE);
+
+  return field;
+}
+
+
+/* Get FIELD_IDX'th field in array descriptor DESC.  */
+
 static tree
 gfc_get_descriptor_field (tree desc, unsigned field_idx)
 {
   tree type = TREE_TYPE (desc);
   gcc_assert (GFC_DESCRIPTOR_TYPE_P (type));
 
-  tree field = gfc_advance_chain (TYPE_FIELDS (type), field_idx);
+  tree field = get_type_field (type, field_idx);
   gcc_assert (field != NULL_TREE);
 
   return fold_build3_loc (input_location, COMPONENT_REF, TREE_TYPE (field),
@@ -283,8 +298,11 @@ gfc_conv_descriptor_attribute (tree desc)
                          dtype, tmp, NULL_TREE);
 }
 
-tree
-gfc_conv_descriptor_type (tree desc)
+
+/* Return a reference to the type discriminator of array descriptor DESC.  */
+
+static tree
+conv_descriptor_type (tree desc)
 {
   tree tmp;
   tree dtype;
@@ -297,6 +315,72 @@ gfc_conv_descriptor_type (tree desc)
                          dtype, tmp, NULL_TREE);
 }
 
+/* Return the value of the type discriminator of the array descriptor DESC.  */
+
+tree
+gfc_conv_descriptor_type_get (tree desc)
+{
+  return conv_descriptor_type (desc);
+}
+
+/* Add code to BLOCK setting to VALUE the type discriminator of the array
+   descriptor DESC.  */
+
+void
+gfc_conv_descriptor_type_set (stmtblock_t *block, tree desc, tree value)
+{
+  location_t loc = input_location;
+  tree t = conv_descriptor_type (desc);
+  gfc_add_modify_loc (loc, block, t,
+                     fold_convert_loc (loc, TREE_TYPE (t), value));
+}
+
+/* Add code to BLOCK setting to VALUE the type discriminator of the array
+   descriptor DESC.  */
+
+void
+gfc_conv_descriptor_type_set (stmtblock_t *block, tree desc, int value)
+{
+  tree type = TREE_TYPE (desc);
+  gcc_assert (GFC_DESCRIPTOR_TYPE_P (type));
+
+  tree dtype = get_type_field (type, DTYPE_FIELD);
+  gcc_assert (dtype != NULL_TREE);
+
+  tree field = get_type_field (TREE_TYPE (dtype), GFC_DTYPE_TYPE);
+  gcc_assert (field != NULL_TREE);
+
+  tree type_value = build_int_cst (TREE_TYPE (field), value);
+  gfc_conv_descriptor_type_set (block, desc, type_value);
+}
+
+/* Return some code setting to VALUE the type discriminator of the array
+   descriptor DESC.  */
+
+tree
+gfc_conv_descriptor_type_set (tree desc, tree value)
+{
+  stmtblock_t block;
+
+  gfc_init_block (&block);
+  gfc_conv_descriptor_type_set (&block, desc, value);
+  return gfc_finish_block (&block);
+}
+
+/* Return some code setting to VALUE the type discriminator of the array
+   descriptor DESC.  */
+
+tree
+gfc_conv_descriptor_type_set (tree desc, int value)
+{
+  stmtblock_t block;
+
+  gfc_init_block (&block);
+  gfc_conv_descriptor_type_set (&block, desc, value);
+  return gfc_finish_block (&block);
+}
+
+
 tree
 gfc_get_descriptor_dimension (tree desc)
 {
diff --git a/gcc/fortran/trans-descriptor.h b/gcc/fortran/trans-descriptor.h
index cdf2295abe4..fae9bd49671 100644
--- a/gcc/fortran/trans-descriptor.h
+++ b/gcc/fortran/trans-descriptor.h
@@ -22,7 +22,6 @@ along with GCC; see the file COPYING3.  If not see
 
 tree gfc_conv_descriptor_dtype (tree);
 tree gfc_conv_descriptor_attribute (tree);
-tree gfc_conv_descriptor_type (tree);
 tree gfc_get_descriptor_dimension (tree);
 tree gfc_conv_descriptor_dimension (tree, tree);
 tree gfc_conv_descriptor_token (tree);
@@ -32,6 +31,7 @@ tree gfc_conv_descriptor_offset_get (tree);
 tree gfc_conv_descriptor_elem_len_get (tree);
 tree gfc_conv_descriptor_version_get (tree);
 tree gfc_conv_descriptor_rank_get (tree);
+tree gfc_conv_descriptor_type_get (tree);
 tree gfc_conv_descriptor_span_get (tree);
 
 tree gfc_conv_descriptor_stride_get (tree, tree);
@@ -44,6 +44,9 @@ void gfc_conv_descriptor_elem_len_set (stmtblock_t *, tree, 
tree);
 void gfc_conv_descriptor_version_set (stmtblock_t *, tree, tree);
 void gfc_conv_descriptor_rank_set (stmtblock_t *, tree, tree);
 void gfc_conv_descriptor_rank_set (stmtblock_t *, tree, int);
+void gfc_conv_descriptor_type_set (stmtblock_t *, tree, tree);
+tree gfc_conv_descriptor_type_set (tree, tree);
+tree gfc_conv_descriptor_type_set (tree, int);
 void gfc_conv_descriptor_span_set (stmtblock_t *, tree, tree);
 void gfc_conv_descriptor_stride_set (stmtblock_t *, tree, tree, tree);
 void gfc_conv_descriptor_lbound_set (stmtblock_t *, tree, tree, tree);
diff --git a/gcc/fortran/trans-expr.cc b/gcc/fortran/trans-expr.cc
index 4a87cf717d5..30ac2c5d46e 100644
--- a/gcc/fortran/trans-expr.cc
+++ b/gcc/fortran/trans-expr.cc
@@ -6303,7 +6303,7 @@ gfc_conv_gfc_desc_to_cfi_desc (gfc_se *parmse, gfc_expr 
*e, gfc_symbol *fsym)
       tree cond;
       tree ctype = gfc_get_cfi_desc_type (cfi);
       tree type = fold_convert (TREE_TYPE (ctype),
-                               gfc_conv_descriptor_type (gfc));
+                               gfc_conv_descriptor_type_get (gfc));
       tree kind = fold_convert (TREE_TYPE (ctype),
                                gfc_conv_descriptor_elem_len_get (gfc));
       kind = fold_build2_loc (input_location, LSHIFT_EXPR, TREE_TYPE (type),
-- 
2.51.0

Reply via email to