diff options
Diffstat (limited to 'gcc/cp/mangle.cc')
-rw-r--r-- | gcc/cp/mangle.cc | 67 |
1 files changed, 66 insertions, 1 deletions
diff --git a/gcc/cp/mangle.cc b/gcc/cp/mangle.cc index 13d5ded..f48cb22 100644 --- a/gcc/cp/mangle.cc +++ b/gcc/cp/mangle.cc @@ -203,6 +203,7 @@ static void write_conversion_operator_name (const tree); static void write_source_name (tree); static void write_literal_operator_name (tree); static void write_unnamed_type_name (const tree); +static void write_unnamed_enum_name (const tree); static void write_closure_type_name (const tree); static int hwint_to_ascii (unsigned HOST_WIDE_INT, const unsigned int, char *, const unsigned int); @@ -1591,7 +1592,9 @@ write_unqualified_name (tree decl) tree type = TREE_TYPE (decl); if (TREE_CODE (decl) == TYPE_DECL - && TYPE_UNNAMED_P (type)) + && enum_with_enumerator_for_linkage_p (type)) + write_unnamed_enum_name (type); + else if (TREE_CODE (decl) == TYPE_DECL && TYPE_UNNAMED_P (type)) write_unnamed_type_name (type); else if (TREE_CODE (decl) == TYPE_DECL && LAMBDA_TYPE_P (type)) write_closure_type_name (type); @@ -1820,6 +1823,17 @@ write_unnamed_type_name (const tree type) write_compact_number (discriminator); } +/* <unnamed-enum-name> ::= Ue <underlying type> <enumerator source-name> */ + +static void +write_unnamed_enum_name (const tree type) +{ + MANGLE_TRACE_TREE ("unnamed-enum-name", type); + write_string ("Ue"); + write_type (ENUM_UNDERLYING_TYPE (type)); + write_source_name (DECL_NAME (TREE_VALUE (TYPE_VALUES (type)))); +} + /* ABI issue #47: if a function template parameter is not "natural" for its argument we must mangle the parameter. */ @@ -3745,11 +3759,59 @@ write_expression (tree expr) || !zero_init_expr_p (ce->value)) last_nonzero = i; + tree prev_field = NULL_TREE; if (undigested || last_nonzero != UINT_MAX) for (HOST_WIDE_INT i = 0; vec_safe_iterate (elts, i, &ce); ++i) { if (i > last_nonzero) break; + if (!undigested && !CONSTRUCTOR_NO_CLEARING (expr) + && (TREE_CODE (etype) == RECORD_TYPE + || TREE_CODE (etype) == ARRAY_TYPE)) + { + /* Write out any implicit non-trailing zeros + (which we neglected to do before v21). */ + if (TREE_CODE (etype) == RECORD_TYPE) + { + tree field; + if (i == 0) + field = first_field (etype); + else + field = DECL_CHAIN (prev_field); + for (;;) + { + field = next_subobject_field (field); + if (field == ce->index) + break; + if (abi_check (21)) + write_expression (build_zero_cst + (TREE_TYPE (field))); + field = DECL_CHAIN (field); + } + } + else if (TREE_CODE (etype) == ARRAY_TYPE) + { + unsigned HOST_WIDE_INT j; + if (i == 0) + j = 0; + else + j = 1 + tree_to_uhwi (prev_field); + unsigned HOST_WIDE_INT k; + if (TREE_CODE (ce->index) == RANGE_EXPR) + k = tree_to_uhwi (TREE_OPERAND (ce->index, 0)); + else + k = tree_to_uhwi (ce->index); + tree zero = NULL_TREE; + for (; j < k; ++j) + if (abi_check (21)) + { + if (!zero) + zero = build_zero_cst (TREE_TYPE (etype)); + write_expression (zero); + } + } + } + if (!undigested && TREE_CODE (etype) == UNION_TYPE) { /* Express the active member as a designator. */ @@ -3794,6 +3856,9 @@ write_expression (tree expr) else for (unsigned j = 0; j < reps; ++j) write_expression (ce->value); + prev_field = ce->index; + if (prev_field && TREE_CODE (prev_field) == RANGE_EXPR) + prev_field = TREE_OPERAND (prev_field, 1); } } else |