@@ -3940,7 +3940,7 @@ static void gen_descr_array_type_die (tree, struct array_descr_info *, dw_die_re
#if 0
static void gen_entry_point_die (tree, dw_die_ref);
#endif
-static dw_die_ref gen_enumeration_type_die (tree, dw_die_ref);
+static dw_die_ref gen_enumeration_type_die (tree, dw_die_ref, bool);
static dw_die_ref gen_formal_parameter_die (tree, tree, bool, dw_die_ref);
static dw_die_ref gen_formal_parameter_pack_die (tree, tree, dw_die_ref, tree*);
static void gen_unspecified_parameters_die (tree, dw_die_ref);
@@ -3960,7 +3960,7 @@ static void gen_struct_or_union_type_die (tree, dw_die_ref,
enum debug_info_usage);
static void gen_subroutine_type_die (tree, dw_die_ref);
static void gen_typedef_die (tree, dw_die_ref);
-static void gen_type_die (tree, dw_die_ref);
+static void gen_type_die (tree, dw_die_ref, bool = false);
static void gen_block_die (tree, dw_die_ref);
static void decls_for_scope (tree, dw_die_ref, bool = true);
static bool is_naming_typedef_decl (const_tree);
@@ -3976,8 +3976,10 @@ static struct dwarf_file_data * lookup_filename (const char *);
static void retry_incomplete_types (void);
static void gen_type_die_for_member (tree, tree, dw_die_ref);
static void gen_generic_params_dies (tree);
-static void gen_tagged_type_die (tree, dw_die_ref, enum debug_info_usage);
-static void gen_type_die_with_usage (tree, dw_die_ref, enum debug_info_usage);
+static void gen_tagged_type_die (tree, dw_die_ref, enum debug_info_usage,
+ bool = false);
+static void gen_type_die_with_usage (tree, dw_die_ref, enum debug_info_usage,
+ bool = false);
static void splice_child_die (dw_die_ref, dw_die_ref);
static int file_info_cmp (const void *, const void *);
static dw_loc_list_ref new_loc_list (dw_loc_descr_ref, const char *, var_loc_view,
@@ -13665,8 +13667,11 @@ modified_type_die (tree type, int cv_quals, bool reverse,
const int cv_qual_mask = (TYPE_QUAL_CONST | TYPE_QUAL_VOLATILE
| TYPE_QUAL_RESTRICT | TYPE_QUAL_ATOMIC |
ENCODE_QUAL_ADDR_SPACE(~0U));
- const bool reverse_base_type
- = need_endianity_attribute_p (reverse) && is_base_type (type);
+ /* DW_AT_endianity is specified only for base types in the standard. */
+ const bool reverse_type
+ = need_endianity_attribute_p (reverse)
+ && (is_base_type (type)
+ || (TREE_CODE (type) == ENUMERAL_TYPE && !dwarf_strict));
if (code == ERROR_MARK)
return NULL;
@@ -13726,9 +13731,9 @@ modified_type_die (tree type, int cv_quals, bool reverse,
/* DW_AT_endianity doesn't come from a qualifier on the type, so it is
dealt with specially: the DIE with the attribute, if it exists, is
- placed immediately after the regular DIE for the same base type. */
+ placed immediately after the regular DIE for the same type. */
if (mod_type_die
- && (!reverse_base_type
+ && (!reverse_type
|| ((mod_type_die = mod_type_die->die_sib) != NULL
&& get_AT_unsigned (mod_type_die, DW_AT_endianity))))
return mod_type_die;
@@ -13745,7 +13750,7 @@ modified_type_die (tree type, int cv_quals, bool reverse,
tree dtype = TREE_TYPE (name);
/* Skip the typedef for base types with DW_AT_endianity, no big deal. */
- if (qualified_type == dtype && !reverse_base_type)
+ if (qualified_type == dtype && !reverse_type)
{
tree origin = decl_ultimate_origin (name);
@@ -13952,7 +13957,7 @@ modified_type_die (tree type, int cv_quals, bool reverse,
mod_type_die = base_type_die (type, reverse);
/* The DIE with DW_AT_endianity is placed right after the naked DIE. */
- if (reverse_base_type)
+ if (reverse_type)
{
dw_die_ref after_die
= modified_type_die (type, cv_quals, false, context_die);
@@ -13965,6 +13970,17 @@ modified_type_die (tree type, int cv_quals, bool reverse,
}
else
{
+ /* The DIE with DW_AT_endianity is placed right after the naked DIE. */
+ if (reverse_type)
+ {
+ dw_die_ref after_die
+ = modified_type_die (type, cv_quals, false, context_die);
+ gen_type_die (type, context_die, true);
+ gcc_assert (after_die->die_sib
+ && get_AT_unsigned (after_die->die_sib, DW_AT_endianity));
+ return after_die->die_sib;
+ }
+
gen_type_die (type, context_die);
/* We have to get the type_main_variant here (and pass that to the
@@ -14034,7 +14050,7 @@ modified_type_die (tree type, int cv_quals, bool reverse,
}
}
- if (qualified_type && !reverse_base_type)
+ if (qualified_type && !reverse_type)
equate_type_number_to_die (qualified_type, mod_type_die);
if (item_type)
@@ -22824,19 +22840,31 @@ record_type_tag (tree type)
/* Generate a DIE to represent an enumeration type. Note that these DIEs
include all of the information about the enumeration values also. Each
enumerated type name/value is listed as a child of the enumerated type
- DIE. */
+ DIE. REVERSE is true if the type is to be interpreted in the reverse
+ storage order wrt the target order. */
static dw_die_ref
-gen_enumeration_type_die (tree type, dw_die_ref context_die)
+gen_enumeration_type_die (tree type, dw_die_ref context_die, bool reverse)
{
dw_die_ref type_die = lookup_type_die (type);
dw_die_ref orig_type_die = type_die;
- if (type_die == NULL)
+ if (type_die == NULL || reverse)
{
- type_die = new_die (DW_TAG_enumeration_type,
- scope_die_for (type, context_die), type);
- equate_type_number_to_die (type, type_die);
+ /* The DIE with DW_AT_endianity is placed right after the naked DIE. */
+ if (reverse)
+ {
+ gcc_assert (type_die);
+ dw_die_ref after_die = type_die;
+ type_die = new_die_raw (DW_TAG_enumeration_type);
+ add_child_die_after (context_die, type_die, after_die);
+ }
+ else
+ {
+ type_die = new_die (DW_TAG_enumeration_type,
+ scope_die_for (type, context_die), type);
+ equate_type_number_to_die (type, type_die);
+ }
add_name_attribute (type_die, type_tag (type));
if ((dwarf_version >= 4 || !dwarf_strict)
&& ENUM_IS_SCOPED (type))
@@ -22848,6 +22876,9 @@ gen_enumeration_type_die (tree type, dw_die_ref context_die)
TYPE_UNSIGNED (type)
? DW_ATE_unsigned
: DW_ATE_signed);
+ if (reverse)
+ add_AT_unsigned (type_die, DW_AT_endianity,
+ BYTES_BIG_ENDIAN ? DW_END_little : DW_END_big);
}
else if (! TYPE_SIZE (type) || ENUM_IS_OPAQUE (type))
return type_die;
@@ -26155,7 +26186,8 @@ gen_typedef_die (tree decl, dw_die_ref context_die)
static void
gen_tagged_type_die (tree type,
dw_die_ref context_die,
- enum debug_info_usage usage)
+ enum debug_info_usage usage,
+ bool reverse)
{
if (type == NULL_TREE
|| !is_tagged_type (type))
@@ -26200,8 +26232,8 @@ gen_tagged_type_die (tree type,
{
/* This might have been written out by the call to
declare_in_namespace. */
- if (!TREE_ASM_WRITTEN (type))
- gen_enumeration_type_die (type, context_die);
+ if (!TREE_ASM_WRITTEN (type) || reverse)
+ gen_enumeration_type_die (type, context_die, reverse);
}
else
gen_struct_or_union_type_die (type, context_die, usage);
@@ -26215,7 +26247,7 @@ gen_tagged_type_die (tree type,
static void
gen_type_die_with_usage (tree type, dw_die_ref context_die,
- enum debug_info_usage usage)
+ enum debug_info_usage usage, bool reverse)
{
struct array_descr_info info;
@@ -26279,7 +26311,7 @@ gen_type_die_with_usage (tree type, dw_die_ref context_die,
if (debug_type != NULL_TREE && debug_type != type)
{
- gen_type_die_with_usage (debug_type, context_die, usage);
+ gen_type_die_with_usage (debug_type, context_die, usage, reverse);
return;
}
}
@@ -26326,7 +26358,7 @@ gen_type_die_with_usage (tree type, dw_die_ref context_die,
}
}
- if (TREE_ASM_WRITTEN (type))
+ if (TREE_ASM_WRITTEN (type) && !reverse)
{
/* Variable-length types may be incomplete even if
TREE_ASM_WRITTEN. For such types, fall through to
@@ -26398,7 +26430,7 @@ gen_type_die_with_usage (tree type, dw_die_ref context_die,
case RECORD_TYPE:
case UNION_TYPE:
case QUAL_UNION_TYPE:
- gen_tagged_type_die (type, context_die, usage);
+ gen_tagged_type_die (type, context_die, usage, reverse);
return;
case VOID_TYPE:
@@ -26450,11 +26482,11 @@ gen_type_die_with_usage (tree type, dw_die_ref context_die,
}
static void
-gen_type_die (tree type, dw_die_ref context_die)
+gen_type_die (tree type, dw_die_ref context_die, bool reverse)
{
if (type != error_mark_node)
{
- gen_type_die_with_usage (type, context_die, DINFO_USAGE_DIR_USE);
+ gen_type_die_with_usage (type, context_die, DINFO_USAGE_DIR_USE, reverse);
if (flag_checking)
{
dw_die_ref die = lookup_type_die (type);