gigi.h (record_builtin_type): Adjust comment.
[platform/upstream/gcc.git] / gcc / ada / gcc-interface / utils.c
index e4b96d7..fbdf473 100644 (file)
@@ -1377,8 +1377,25 @@ maybe_pad_type (tree type, tree size, unsigned int align,
       && !(TREE_CODE (TYPE_NAME (type)) == TYPE_DECL
           && DECL_IGNORED_P (TYPE_NAME (type))))
     {
-      tree marker = make_node (RECORD_TYPE);
       tree name = TYPE_IDENTIFIER (record);
+      tree size_unit = TYPE_SIZE_UNIT (record);
+
+      /* A variable that holds the size is required even with no encoding since
+        it will be referenced by debugging information attributes.  At global
+        level, we need a single variable across all translation units.  */
+      if (size
+         && TREE_CODE (size) != INTEGER_CST
+         && (definition || global_bindings_p ()))
+       {
+         size_unit
+           = create_var_decl (concat_name (name, "XVZ"), NULL_TREE, sizetype,
+                             size_unit, true, global_bindings_p (),
+                             !definition && global_bindings_p (), false,
+                             true, true, NULL, gnat_entity);
+         TYPE_SIZE_UNIT (record) = size_unit;
+       }
+
+      tree marker = make_node (RECORD_TYPE);
       tree orig_name = TYPE_IDENTIFIER (type);
 
       TYPE_NAME (marker) = concat_name (name, "XVS");
@@ -1388,14 +1405,9 @@ maybe_pad_type (tree type, tree size, unsigned int align,
                                             marker, NULL_TREE, NULL_TREE,
                                             0, 0),
                          0, true);
+      TYPE_SIZE_UNIT (marker) = size_unit;
 
       add_parallel_type (record, marker);
-
-      if (definition && size && TREE_CODE (size) != INTEGER_CST)
-       TYPE_SIZE_UNIT (marker)
-         = create_var_decl (concat_name (name, "XVZ"), NULL_TREE, sizetype,
-                            TYPE_SIZE_UNIT (record), false, false, false,
-                            false, NULL, gnat_entity);
     }
 
   rest_of_record_type_compilation (record);
@@ -1537,7 +1549,7 @@ relate_alias_sets (tree gnu_new_type, tree gnu_old_type, enum alias_set_op op)
 }
 \f
 /* Record TYPE as a builtin type for Ada.  NAME is the name of the type.
-   ARTIFICIAL_P is true if it's a type that was generated by the compiler.  */
+   ARTIFICIAL_P is true if the type was generated by the compiler.  */
 
 void
 record_builtin_type (const char *name, tree type, bool artificial_p)
@@ -2241,9 +2253,6 @@ create_range_type (tree type, tree min, tree max)
 tree
 create_type_stub_decl (tree type_name, tree type)
 {
-  /* Using a named TYPE_DECL ensures that a type name marker is emitted in
-     STABS while setting DECL_ARTIFICIAL ensures that no DW_TAG_typedef is
-     emitted in DWARF.  */
   tree type_decl = build_decl (input_location, TYPE_DECL, type_name, type);
   DECL_ARTIFICIAL (type_decl) = 1;
   TYPE_ARTIFICIAL (type) = 1;
@@ -2251,10 +2260,10 @@ create_type_stub_decl (tree type_name, tree type)
 }
 
 /* Return a TYPE_DECL node.  TYPE_NAME gives the name of the type and TYPE
-   is a ..._TYPE node giving its data type.  ARTIFICIAL_P is true if this
-   is a declaration that was generated by the compiler.  DEBUG_INFO_P is
-   true if we need to write debug information about this type.  GNAT_NODE
-   is used for the position of the decl.  */
+   is a ..._TYPE node giving its data type.  ARTIFICIAL_P is true if the
+   declaration was generated by the compiler.  DEBUG_INFO_P is true if we
+   need to write debug information about this type.  GNAT_NODE is used for
+   the position of the decl.  */
 
 tree
 create_type_decl (tree type_name, tree type, bool artificial_p,
@@ -2322,13 +2331,18 @@ create_type_decl (tree type_name, tree type, bool artificial_p,
    STATIC_FLAG is only relevant when not at top level.  In that case
    it indicates whether to always allocate storage to the variable.
 
+   ARTIFICIAL_P is true if the variable was generated by the compiler.
+
+   DEBUG_INFO_P is true if we need to write debug information for it.
+
    GNAT_NODE is used for the position of the decl.  */
 
 tree
 create_var_decl_1 (tree var_name, tree asm_name, tree type, tree var_init,
                   bool const_flag, bool public_flag, bool extern_flag,
-                  bool static_flag, bool const_decl_allowed_p,
-                  struct attrib *attr_list, Node_Id gnat_node)
+                  bool static_flag, bool artificial_p, bool debug_info_p,
+                  bool const_decl_allowed_p, struct attrib *attr_list,
+                  Node_Id gnat_node)
 {
   /* Whether the object has static storage duration, either explicitly or by
      virtue of being declared at the global level.  */
@@ -2379,10 +2393,14 @@ create_var_decl_1 (tree var_name, tree asm_name, tree type, tree var_init,
   if (var_init && !init_const && global_bindings_p ())
     Check_Elaboration_Code_Allowed (gnat_node);
 
-  DECL_INITIAL  (var_decl) = var_init;
-  TREE_READONLY (var_decl) = const_flag;
+  /* Attach the initializer, if any.  */
+  DECL_INITIAL (var_decl) = var_init;
+
+  /* Directly set some flags.  */
+  DECL_ARTIFICIAL (var_decl) = artificial_p;
   DECL_EXTERNAL (var_decl) = extern_flag;
   TREE_CONSTANT (var_decl) = constant_p;
+  TREE_READONLY (var_decl) = const_flag;
 
   /* We need to allocate static storage for an object with static storage
      duration if it isn't external.  */
@@ -2402,14 +2420,18 @@ create_var_decl_1 (tree var_name, tree asm_name, tree type, tree var_init,
       && !have_global_bss_p ())
     DECL_COMMON (var_decl) = 1;
 
-  /* For an external constant whose initializer is not absolute, do not emit
-     debug info.  In DWARF this would mean a global relocation in a read-only
-     section which runs afoul of the PE-COFF run-time relocation mechanism.  */
-  if (extern_flag
-      && constant_p
-      && var_init
-      && initializer_constant_valid_p (var_init, TREE_TYPE (var_init))
-        != null_pointer_node)
+  /* Do not emit debug info for a CONST_DECL if optimization isn't enabled,
+     since we will create an associated variable.  Likewise for an external
+     constant whose initializer is not absolute, because this would mean a
+     global relocation in a read-only section which runs afoul of the PE-COFF
+     run-time relocation mechanism.  */
+  if (!debug_info_p
+      || (TREE_CODE (var_decl) == CONST_DECL && !optimize)
+      || (extern_flag
+         && constant_p
+         && var_init
+         && initializer_constant_valid_p (var_init, TREE_TYPE (var_init))
+            != null_pointer_node))
     DECL_IGNORED_P (var_decl) = 1;
 
   if (TYPE_VOLATILE (type))
@@ -3023,15 +3045,21 @@ create_label_decl (tree label_name, Node_Id gnat_node)
    node), PARAM_DECL_LIST is the list of the subprogram arguments (a list of
    PARM_DECL nodes chained through the DECL_CHAIN field).
 
-   INLINE_STATUS, PUBLIC_FLAG, EXTERN_FLAG, ARTIFICIAL_FLAG and ATTR_LIST are
-   used to set the appropriate fields in the FUNCTION_DECL.  GNAT_NODE is
-   used for the position of the decl.  */
+   INLINE_STATUS, PUBLIC_FLAG, EXTERN_FLAG and ATTR_LIST are used to set the
+   appropriate fields in the FUNCTION_DECL.
+
+   ARTIFICIAL_P is true if the subprogram was generated by the compiler.
+
+   DEBUG_INFO_P is true if we need to write debug information for it.
+
+   GNAT_NODE is used for the position of the decl.  */
 
 tree
 create_subprog_decl (tree subprog_name, tree asm_name, tree subprog_type,
                     tree param_decl_list, enum inline_status_t inline_status,
-                    bool public_flag, bool extern_flag, bool artificial_flag,
-                    struct attrib *attr_list, Node_Id gnat_node)
+                    bool public_flag, bool extern_flag, bool artificial_p,
+                    bool debug_info_p, struct attrib *attr_list,
+                    Node_Id gnat_node)
 {
   tree subprog_decl = build_decl (input_location, FUNCTION_DECL, subprog_name,
                                  subprog_type);
@@ -3039,7 +3067,7 @@ create_subprog_decl (tree subprog_name, tree asm_name, tree subprog_type,
                                 TREE_TYPE (subprog_type));
   DECL_ARGUMENTS (subprog_decl) = param_decl_list;
 
-  DECL_ARTIFICIAL (subprog_decl) = artificial_flag;
+  DECL_ARTIFICIAL (subprog_decl) = artificial_p;
   DECL_EXTERNAL (subprog_decl) = extern_flag;
 
   switch (inline_status)
@@ -3062,13 +3090,16 @@ create_subprog_decl (tree subprog_name, tree asm_name, tree subprog_type,
 
     case is_enabled:
       DECL_DECLARED_INLINE_P (subprog_decl) = 1;
-      DECL_NO_INLINE_WARNING_P (subprog_decl) = artificial_flag;
+      DECL_NO_INLINE_WARNING_P (subprog_decl) = artificial_p;
       break;
 
     default:
       gcc_unreachable ();
     }
 
+  if (!debug_info_p)
+    DECL_IGNORED_P (subprog_decl) = 1;
+
   TREE_PUBLIC (subprog_decl) = public_flag;
   TREE_READONLY (subprog_decl) = TYPE_READONLY (subprog_type);
   TREE_THIS_VOLATILE (subprog_decl) = TYPE_VOLATILE (subprog_type);