https://gcc.gnu.org/g:6ee66376a1b8c97bd0be0eb0a51b90dabbaee58b

commit 6ee66376a1b8c97bd0be0eb0a51b90dabbaee58b
Author: Mikael Morin <mik...@gcc.gnu.org>
Date:   Thu Dec 5 20:30:08 2024 +0100

    Creation méthode initialisation descripteur

Diff:
---
 gcc/fortran/expr.cc        |  25 ++++++---
 gcc/fortran/trans-array.cc | 136 +++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 154 insertions(+), 7 deletions(-)

diff --git a/gcc/fortran/expr.cc b/gcc/fortran/expr.cc
index a997bdae726a..da63c3970938 100644
--- a/gcc/fortran/expr.cc
+++ b/gcc/fortran/expr.cc
@@ -5386,27 +5386,38 @@ gfc_get_full_arrayspec_from_expr (gfc_expr *expr)
   gfc_ref *ref;
 
   if (expr->rank == 0)
-    return NULL;
+    return nullptr;
 
   /* Follow any component references.  */
   if (expr->expr_type == EXPR_VARIABLE
       || expr->expr_type == EXPR_CONSTANT)
     {
-      if (expr->symtree)
-       as = expr->symtree->n.sym->as;
+      gfc_symbol *sym = expr->symtree ? expr->symtree->n.sym : nullptr;
+      if (sym
+         && sym->ts.type == BT_CLASS)
+       as = CLASS_DATA (sym)->as;
+      else if (sym)
+       as = sym->as;
       else
-       as = NULL;
+       as = nullptr;
 
       for (ref = expr->ref; ref; ref = ref->next)
        {
          switch (ref->type)
            {
            case REF_COMPONENT:
-             as = ref->u.c.component->as;
+             {
+               gfc_component *comp = ref->u.c.component;
+               if (comp->ts.type == BT_CLASS)
+                 as = CLASS_DATA (comp)->as;
+               else
+                 as = comp->as;
+             }
              continue;
 
            case REF_SUBSTRING:
            case REF_INQUIRY:
+             as = nullptr;
              continue;
 
            case REF_ARRAY:
@@ -5416,7 +5427,7 @@ gfc_get_full_arrayspec_from_expr (gfc_expr *expr)
                  case AR_ELEMENT:
                  case AR_SECTION:
                  case AR_UNKNOWN:
-                   as = NULL;
+                   as = nullptr;
                    continue;
 
                  case AR_FULL:
@@ -5428,7 +5439,7 @@ gfc_get_full_arrayspec_from_expr (gfc_expr *expr)
        }
     }
   else
-    as = NULL;
+    as = nullptr;
 
   return as;
 }
diff --git a/gcc/fortran/trans-array.cc b/gcc/fortran/trans-array.cc
index a458af322ce8..60c922bb871d 100644
--- a/gcc/fortran/trans-array.cc
+++ b/gcc/fortran/trans-array.cc
@@ -543,6 +543,142 @@ gfc_conv_descriptor_ubound_set (stmtblock_t *block, tree 
desc,
   gfc_add_modify (block, t, fold_convert (TREE_TYPE (t), value));
 }
 
+
+static int
+get_type_info (const gfc_typespec &ts)
+{
+  switch (ts.type)
+    {
+    case BT_INTEGER:
+    case BT_LOGICAL:
+    case BT_REAL:
+    case BT_COMPLEX:
+    case BT_DERIVED:
+    case BT_CHARACTER:
+    case BT_CLASS:
+    case BT_VOID:
+    case BT_UNSIGNED:
+      return ts.type;
+
+    case BT_PROCEDURE:
+    case BT_ASSUMED:
+      return BT_VOID;
+
+    default:
+      gcc_unreachable ();
+      break;
+    }
+
+  return BT_UNKNOWN;
+}
+
+
+static tree
+get_size_info (gfc_typespec &ts)
+{
+  switch (ts.type)
+    {
+    case BT_INTEGER:
+    case BT_LOGICAL:
+    case BT_REAL:
+    case BT_COMPLEX:
+    case BT_DERIVED:
+    case BT_UNSIGNED:
+      return size_in_bytes (TREE_TYPE (gfc_typenode_for_spec (&ts)));
+
+    case BT_CHARACTER:
+      {
+       tree type = gfc_typenode_for_spec (&ts);
+       if (POINTER_TYPE_P (type))
+         type = TREE_TYPE (type);
+       gcc_assert (TREE_CODE (type) == ARRAY_TYPE);
+       tree elt_type = TREE_TYPE (type);
+       tree len = ts.u.cl->backend_decl;
+       return fold_build2_loc (input_location, MULT_EXPR, size_type_node,
+                               size_in_bytes (elt_type),
+                               len);
+      }
+
+    case BT_CLASS:
+      return get_size_info (ts.u.derived->components->ts);
+
+    case BT_PROCEDURE:
+    case BT_VOID:
+    case BT_ASSUMED:
+    default:
+      gcc_unreachable ();
+    }
+
+  return NULL_TREE;
+}
+
+
+static tree
+build_dtype (gfc_typespec &ts, int rank, const symbol_attribute &)
+{
+  tree type = get_dtype_type_node ();
+
+  tree fields = TYPE_FIELDS (type);
+
+  tree elem_len_field = gfc_advance_chain (fields, GFC_DTYPE_ELEM_LEN);
+  tree elem_len_val = get_size_info (ts);
+
+  tree version_field = gfc_advance_chain (fields, GFC_DTYPE_VERSION);
+  tree version_val = build_int_cst (TREE_TYPE (version_field), 0);
+
+  tree rank_field = gfc_advance_chain (fields, GFC_DTYPE_RANK);
+  tree rank_val = build_int_cst (TREE_TYPE (rank_field), rank);
+
+  tree type_info_field = gfc_advance_chain (fields, GFC_DTYPE_TYPE);
+  tree type_info_val = build_int_cst (TREE_TYPE (type_info_field),
+                                     get_type_info (ts));
+
+  return build_constructor_va (type, 4,
+                              elem_len_field, elem_len_val,
+                              version_field, version_val,
+                              rank_field, rank_val,
+                              type_info_field, type_info_val);
+}
+
+
+/* Build a null array descriptor constructor.  */
+
+tree
+gfc_build_null_descriptor (tree type, gfc_typespec &ts, int rank,
+                          const symbol_attribute &attr)
+{
+  gcc_assert (GFC_DESCRIPTOR_TYPE_P (type));
+  gcc_assert (DATA_FIELD == 0);
+  tree fields = TYPE_FIELDS (type);
+
+  tree data_field = gfc_advance_chain (fields, DATA_FIELD);
+  tree data_value = fold_convert (TREE_TYPE (data_field), null_pointer_node);
+
+  tree dtype_field = gfc_advance_chain (fields, DTYPE_FIELD);
+  tree dtype_value = build_dtype (ts, rank, attr);
+
+  return build_constructor_va (type, 2,
+                              data_field, data_value,
+                              dtype_field, dtype_value);
+}
+
+
+void
+gfc_clear_descriptor (gfc_expr *var_ref, gfc_se &var)
+{
+  symbol_attribute attr;
+
+  gfc_array_spec *as = gfc_get_full_arrayspec_from_expr (var_ref);
+  int rank = as != nullptr ? as->rank : 0;
+
+  attr = gfc_expr_attr (var_ref);
+
+  gfc_add_modify (&var.pre, var.expr,
+                 gfc_build_null_descriptor (TREE_TYPE (var.expr), var_ref->ts,
+                                            rank, attr));
+}
+
+
 /* Build a null array descriptor constructor.  */
 
 tree

Reply via email to