OSDN Git Service

PR middle-end/42068
[pf3gnuchains/gcc-fork.git] / gcc / ada / gcc-interface / utils.c
index c79dd4e..5175654 100644 (file)
@@ -560,19 +560,18 @@ record_builtin_type (const char *name, tree type)
     debug_hooks->type_decl (type_decl, false);
 }
 \f
-/* Given a record type RECORD_TYPE and a chain of FIELD_DECL nodes FIELDLIST,
+/* Given a record type RECORD_TYPE and a list of FIELD_DECL nodes FIELD_LIST,
    finish constructing the record or union type.  If REP_LEVEL is zero, this
    record has no representation clause and so will be entirely laid out here.
    If REP_LEVEL is one, this record has a representation clause and has been
    laid out already; only set the sizes and alignment.  If REP_LEVEL is two,
    this record is derived from a parent record and thus inherits its layout;
-   only make a pass on the fields to finalize them.  If DO_NOT_FINALIZE is
-   true, the record type is expected to be modified afterwards so it will
-   not be sent to the back-end for finalization.  */
+   only make a pass on the fields to finalize them.  DEBUG_INFO_P is true if
+   we need to write debug information about this type.  */
 
 void
-finish_record_type (tree record_type, tree fieldlist, int rep_level,
-                   bool do_not_finalize)
+finish_record_type (tree record_type, tree field_list, int rep_level,
+                   bool debug_info_p)
 {
   enum tree_code code = TREE_CODE (record_type);
   tree name = TYPE_NAME (record_type);
@@ -583,7 +582,7 @@ finish_record_type (tree record_type, tree fieldlist, int rep_level,
   bool had_align = TYPE_ALIGN (record_type) != 0;
   tree field;
 
-  TYPE_FIELDS (record_type) = fieldlist;
+  TYPE_FIELDS (record_type) = field_list;
 
   /* Always attach the TYPE_STUB_DECL for a record type.  It is required to
      generate debug info and have a parallel type.  */
@@ -627,9 +626,9 @@ finish_record_type (tree record_type, tree fieldlist, int rep_level,
      handled yet, and adjust DECL_NONADDRESSABLE_P accordingly.  */
 
   if (code == QUAL_UNION_TYPE)
-    fieldlist = nreverse (fieldlist);
+    field_list = nreverse (field_list);
 
-  for (field = fieldlist; field; field = TREE_CHAIN (field))
+  for (field = field_list; field; field = TREE_CHAIN (field))
     {
       tree type = TREE_TYPE (field);
       tree pos = bit_position (field);
@@ -733,7 +732,7 @@ finish_record_type (tree record_type, tree fieldlist, int rep_level,
     }
 
   if (code == QUAL_UNION_TYPE)
-    nreverse (fieldlist);
+    nreverse (field_list);
 
   if (rep_level < 2)
     {
@@ -764,24 +763,24 @@ finish_record_type (tree record_type, tree fieldlist, int rep_level,
        }
     }
 
-  if (!do_not_finalize)
+  if (debug_info_p)
     rest_of_record_type_compilation (record_type);
 }
 
-/* Wrap up compilation of RECORD_TYPE, i.e. most notably output all
-   the debug information associated with it.  It need not be invoked
-   directly in most cases since finish_record_type takes care of doing
-   so, unless explicitly requested not to through DO_NOT_FINALIZE.  */
+/* Wrap up compilation of RECORD_TYPE, i.e. output all the debug information
+   associated with it.  It need not be invoked directly in most cases since
+   finish_record_type takes care of doing so, but this can be necessary if
+   a parallel type is to be attached to the record type.  */
 
 void
 rest_of_record_type_compilation (tree record_type)
 {
-  tree fieldlist = TYPE_FIELDS (record_type);
+  tree field_list = TYPE_FIELDS (record_type);
   tree field;
   enum tree_code code = TREE_CODE (record_type);
   bool var_size = false;
 
-  for (field = fieldlist; field; field = TREE_CHAIN (field))
+  for (field = field_list; field; field = TREE_CHAIN (field))
     {
       /* We need to make an XVE/XVU record if any field has variable size,
         whether or not the record does.  For example, if we have a union,
@@ -1158,6 +1157,23 @@ copy_type (tree type)
 {
   tree new_type = copy_node (type);
 
+  /* Unshare the language-specific data.  */
+  if (TYPE_LANG_SPECIFIC (type))
+    {
+      TYPE_LANG_SPECIFIC (new_type) = NULL;
+      SET_TYPE_LANG_SPECIFIC (new_type, GET_TYPE_LANG_SPECIFIC (type));
+    }
+
+  /* And the contents of the language-specific slot if needed.  */
+  if ((INTEGRAL_TYPE_P (type) || TREE_CODE (type) == REAL_TYPE)
+      && TYPE_RM_VALUES (type))
+    {
+      TYPE_RM_VALUES (new_type) = NULL_TREE;
+      SET_TYPE_RM_SIZE (new_type, TYPE_RM_SIZE (type));
+      SET_TYPE_RM_MIN_VALUE (new_type, TYPE_RM_MIN_VALUE (type));
+      SET_TYPE_RM_MAX_VALUE (new_type, TYPE_RM_MAX_VALUE (type));
+    }
+
   /* copy_node clears this field instead of copying it, because it is
      aliased with TREE_CHAIN.  */
   TYPE_STUB_DECL (new_type) = TYPE_STUB_DECL (type);
@@ -1371,6 +1387,13 @@ create_var_decl_1 (tree var_name, tree asm_name, tree type, tree var_init,
      that is, not violating a No_Elaboration_Code restriction.  */
   if (global_bindings_p () && var_init != 0 && ! init_const)
     Check_Elaboration_Code_Allowed (gnat_node);
+  DECL_INITIAL  (var_decl) = var_init;
+  TREE_READONLY (var_decl) = const_flag;
+  DECL_EXTERNAL (var_decl) = extern_flag;
+  TREE_PUBLIC   (var_decl) = public_flag || extern_flag;
+  TREE_CONSTANT (var_decl) = constant_p;
+  TREE_THIS_VOLATILE (var_decl) = TREE_SIDE_EFFECTS (var_decl)
+    = TYPE_VOLATILE (type);
 
   /* Ada doesn't feature Fortran-like COMMON variables so we shouldn't
      try to fiddle with DECL_COMMON.  However, on platforms that don't
@@ -1378,15 +1401,9 @@ create_var_decl_1 (tree var_name, tree asm_name, tree type, tree var_init,
      go in DATA instead, thus increasing the size of the executable.  */
   if (!flag_no_common
       && TREE_CODE (var_decl) == VAR_DECL
+      && TREE_PUBLIC   (var_decl)
       && !have_global_bss_p ())
     DECL_COMMON (var_decl) = 1;
-  DECL_INITIAL  (var_decl) = var_init;
-  TREE_READONLY (var_decl) = const_flag;
-  DECL_EXTERNAL (var_decl) = extern_flag;
-  TREE_PUBLIC   (var_decl) = public_flag || extern_flag;
-  TREE_CONSTANT (var_decl) = constant_p;
-  TREE_THIS_VOLATILE (var_decl) = TREE_SIDE_EFFECTS (var_decl)
-    = TYPE_VOLATILE (type);
 
   /* If it's public and not external, always allocate storage for it.
      At the global binding level we need to allocate static storage for the
@@ -1404,10 +1421,12 @@ create_var_decl_1 (tree var_name, tree asm_name, tree type, tree var_init,
           != null_pointer_node)
     DECL_IGNORED_P (var_decl) = 1;
 
-  if (asm_name && VAR_OR_FUNCTION_DECL_P (var_decl))
-    SET_DECL_ASSEMBLER_NAME (var_decl, asm_name);
-
-  process_attributes (var_decl, attr_list);
+  if (TREE_CODE (var_decl) == VAR_DECL)
+    {
+      if (asm_name)
+       SET_DECL_ASSEMBLER_NAME (var_decl, asm_name);
+      process_attributes (var_decl, attr_list);
+    }
 
   /* Add this decl to the current binding level.  */
   gnat_pushdecl (var_decl, gnat_node);
@@ -2799,7 +2818,7 @@ build_vms_descriptor32 (tree type, Mechanism_Type mech, Entity_Id gnat_entity)
     }
 
   TYPE_NAME (record_type) = create_concat_name (gnat_entity, "DESC");
-  finish_record_type (record_type, field_list, 0, true);
+  finish_record_type (record_type, field_list, 0, false);
   return record_type;
 }
 
@@ -3113,7 +3132,7 @@ build_vms_descriptor (tree type, Mechanism_Type mech, Entity_Id gnat_entity)
     }
 
   TYPE_NAME (record64_type) = create_concat_name (gnat_entity, "DESC64");
-  finish_record_type (record64_type, field_list64, 0, true);
+  finish_record_type (record64_type, field_list64, 0, false);
   return record64_type;
 }
 
@@ -3525,7 +3544,7 @@ build_unc_object_type (tree template_type, tree object_type, tree name)
   finish_record_type (type,
                      chainon (chainon (NULL_TREE, template_field),
                               array_field),
-                     0, false);
+                     0, true);
 
   return type;
 }