summaryrefslogtreecommitdiff
path: root/gcc/ada/gcc-interface/utils.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/ada/gcc-interface/utils.c')
-rw-r--r--gcc/ada/gcc-interface/utils.c99
1 files changed, 65 insertions, 34 deletions
diff --git a/gcc/ada/gcc-interface/utils.c b/gcc/ada/gcc-interface/utils.c
index e4b96d7b120..fbdf4733833 100644
--- a/gcc/ada/gcc-interface/utils.c
+++ b/gcc/ada/gcc-interface/utils.c
@@ -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)
}
/* 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);