/* Name mangling for the 3.0 -*- C++ -*- ABI.
- Copyright (C) 2000-2018 Free Software Foundation, Inc.
+ Copyright (C) 2000-2021 Free Software Foundation, Inc.
Written by Alex Samuel <samuel@codesourcery.com>
This file is part of GCC.
/* True if the mangling will be different in C++17 mode. */
bool need_cxx17_warning;
+
+ /* True if we mangled a module name. */
+ bool mod;
};
static GTY (()) globals G;
'\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0'
};
-static int decl_is_template_id (const tree, tree* const);
+static tree maybe_template_info (const tree);
/* Functions for handling substitutions. */
write_number ((NUMBER), /*unsigned_p=*/1, 10)
/* If DECL is a template instance (including the uninstantiated template
- itself), return nonzero and, if TEMPLATE_INFO is non-NULL, set
- *TEMPLATE_INFO to its template info. Otherwise return zero. */
+ itself), return its TEMPLATE_INFO. Otherwise return NULL. */
-static int
-decl_is_template_id (const tree decl, tree* const template_info)
+static tree
+maybe_template_info (const tree decl)
{
if (TREE_CODE (decl) == TYPE_DECL)
{
const tree type = TREE_TYPE (decl);
if (CLASS_TYPE_P (type) && CLASSTYPE_TEMPLATE_ID_P (type))
- {
- if (template_info != NULL)
- /* For a templated TYPE_DECL, the template info is hanging
- off the type. */
- *template_info = TYPE_TEMPLATE_INFO (type);
- return 1;
- }
+ return TYPE_TEMPLATE_INFO (type);
}
else
{
- /* Check if this is a primary template. */
+ /* Check if the template is a primary template. */
if (DECL_LANG_SPECIFIC (decl) != NULL
&& VAR_OR_FUNCTION_DECL_P (decl)
&& DECL_TEMPLATE_INFO (decl)
- && PRIMARY_TEMPLATE_P (DECL_TI_TEMPLATE (decl))
- && TREE_CODE (decl) != TEMPLATE_DECL)
- {
- if (template_info != NULL)
- /* For most templated decls, the template info is hanging
- off the decl. */
- *template_info = DECL_TEMPLATE_INFO (decl);
- return 1;
- }
+ && PRIMARY_TEMPLATE_P (DECL_TI_TEMPLATE (decl)))
+ return DECL_TEMPLATE_INFO (decl);
}
/* It's not a template id. */
- return 0;
+ return NULL_TREE;
}
/* Produce debugging output of current substitution candidates. */
else
node = cp_build_qualified_type (TYPE_MAIN_VARIANT (node),
cp_type_quals (node));
- if (TREE_CODE (node) == FUNCTION_TYPE
- || TREE_CODE (node) == METHOD_TYPE)
+ if (FUNC_OR_METHOD_TYPE_P (node))
{
node = build_ref_qualified_type (node, type_memfn_rqual (orig));
tree r = canonical_eh_spec (TYPE_RAISES_EXCEPTIONS (orig));
{
tree args = CLASSTYPE_TI_ARGS (type);
if (TREE_VEC_LENGTH (args) == 3
- && same_type_p (TREE_VEC_ELT (args, 0), char_type_node)
+ && template_args_equal (TREE_VEC_ELT (args, 0), char_type_node)
&& is_std_substitution_char (TREE_VEC_ELT (args, 1),
SUBID_CHAR_TRAITS)
&& is_std_substitution_char (TREE_VEC_ELT (args, 2),
args <char, std::char_traits<char> > . */
tree args = CLASSTYPE_TI_ARGS (type);
if (TREE_VEC_LENGTH (args) == 2
- && TYPE_P (TREE_VEC_ELT (args, 0))
- && same_type_p (TREE_VEC_ELT (args, 0), char_type_node)
+ && template_args_equal (TREE_VEC_ELT (args, 0), char_type_node)
&& is_std_substitution_char (TREE_VEC_ELT (args, 1),
SUBID_CHAR_TRAITS))
{
return (!DECL_CONSTRUCTOR_P (decl)
&& !DECL_DESTRUCTOR_P (decl)
&& !DECL_CONV_FN_P (decl)
- && decl_is_template_id (decl, NULL));
+ && maybe_template_info (decl));
}
/* <encoding> ::= <function name> <bare-function-type>
{
tree fn_type;
tree d;
- bool tmpl = decl_is_template_id (decl, NULL);
- if (tmpl)
+ if (maybe_template_info (decl))
{
fn_type = get_mostly_instantiated_function_type (decl);
/* FN_TYPE will not have parameter types for in-charge or
}
}
+/* Interface to substitution and identifer mangling, used by the
+ module name mangler. */
+
+void
+mangle_module_substitution (int v)
+{
+ if (v < 10)
+ {
+ write_char ('_');
+ write_char ('0' + v);
+ }
+ else
+ {
+ write_char ('W');
+ write_unsigned_number (v - 10);
+ write_char ('_');
+ }
+}
+
+void
+mangle_identifier (char c, tree id)
+{
+ if (c)
+ write_char (c);
+ write_source_name (id);
+}
+
+/* If the outermost non-namespace context (including DECL itself) is
+ a module-linkage decl, mangle the module information. For module
+ global initializers we need to include the partition part.
+
+ <module-name> ::= W <module-id>+ E
+ <module-id> :: <unqualified-name>
+ || _ <digit> ;; short backref
+ || W <number> _ ;; long backref
+ || P <module-id> ;; partition introducer
+*/
+
+static void
+write_module (int m, bool include_partition)
+{
+ G.mod = true;
+
+ write_char ('W');
+ mangle_module (m, include_partition);
+ write_char ('E');
+}
+
+static void
+maybe_write_module (tree decl)
+{
+ int m = get_originating_module (decl, true);
+ if (m >= 0)
+ write_module (m, false);
+}
+
/* Lambdas can have a bit more context for mangling, specifically VAR_DECL
or PARM_DECL context, which doesn't belong in DECL_CONTEXT. */
else if (template_type_parameter_p (decl))
/* template type parms have no mangling context. */
return NULL_TREE;
- return CP_DECL_CONTEXT (decl);
+
+ tcontext = CP_DECL_CONTEXT (decl);
+
+ /* Ignore the artificial declare reduction functions. */
+ if (tcontext
+ && TREE_CODE (tcontext) == FUNCTION_DECL
+ && DECL_OMP_DECLARE_REDUCTION_P (tcontext))
+ return decl_mangling_context (tcontext);
+
+ return tcontext;
}
/* <name> ::= <unscoped-name>
decl = TYPE_NAME (TYPE_MAIN_VARIANT (TREE_TYPE (decl)));
}
+ if (modules_p ())
+ maybe_write_module (decl);
+
context = decl_mangling_context (decl);
gcc_assert (context != NULL_TREE);
|| (abi_version_at_least (7)
&& TREE_CODE (context) == PARM_DECL))))
{
- tree template_info;
/* Is this a template instance? */
- if (decl_is_template_id (decl, &template_info))
+ if (tree info = maybe_template_info (decl))
{
/* Yes: use <unscoped-template-name>. */
- write_unscoped_template_name (TI_TEMPLATE (template_info));
- write_template_args (TI_ARGS (template_info));
+ write_unscoped_template_name (TI_TEMPLATE (info));
+ write_template_args (TI_ARGS (info));
}
else
/* Everything else gets an <unqualified-name>. */
static void
write_nested_name (const tree decl)
{
- tree template_info;
-
MANGLE_TRACE_TREE ("nested-name", decl);
write_char ('N');
}
/* Is this a template instance? */
- if (decl_is_template_id (decl, &template_info))
+ if (tree info = maybe_template_info (decl))
{
/* Yes, use <template-prefix>. */
write_template_prefix (decl);
- write_template_args (TI_ARGS (template_info));
+ write_template_args (TI_ARGS (info));
}
else if ((!abi_version_at_least (10) || TREE_CODE (decl) == TYPE_DECL)
&& TREE_CODE (TREE_TYPE (decl)) == TYPENAME_TYPE)
write_prefix (const tree node)
{
tree decl;
- /* Non-NULL if NODE represents a template-id. */
- tree template_info = NULL;
if (node == NULL
|| node == global_namespace)
if (find_substitution (node))
return;
+ tree template_info = NULL_TREE;
if (DECL_P (node))
{
/* If this is a function or parm decl, that means we've hit function
return;
decl = node;
- decl_is_template_id (decl, &template_info);
+ template_info = maybe_template_info (decl);
}
else
{
/* Node is a type. */
decl = TYPE_NAME (node);
+ /* The DECL might not point at the node. */
if (CLASSTYPE_TEMPLATE_ID_P (node))
template_info = TYPE_TEMPLATE_INFO (node);
}
if (TREE_CODE (node) == TEMPLATE_TYPE_PARM)
write_template_param (node);
- else if (template_info != NULL)
+ else if (template_info)
/* Templated. */
{
write_template_prefix (decl);
tree decl = DECL_P (node) ? node : TYPE_NAME (node);
tree type = DECL_P (node) ? TREE_TYPE (node) : node;
tree context = decl_mangling_context (decl);
- tree template_info;
tree templ;
tree substitution;
MANGLE_TRACE_TREE ("template-prefix", node);
/* Find the template decl. */
- if (decl_is_template_id (decl, &template_info))
- templ = TI_TEMPLATE (template_info);
+ if (tree info = maybe_template_info (decl))
+ templ = TI_TEMPLATE (info);
else if (TREE_CODE (type) == TYPENAME_TYPE)
/* For a typename type, all we have is the name. */
templ = DECL_NAME (decl);
/* Conversion operator. Handle it right here.
<operator> ::= cv <type> */
tree type;
- if (decl_is_template_id (decl, NULL))
+ if (maybe_template_info (decl))
{
tree fn_type;
fn_type = get_mostly_instantiated_function_type (decl);
type = TREE_TYPE (fn_type);
}
else if (FNDECL_USED_AUTO (decl))
- type = (DECL_STRUCT_FUNCTION (decl)->language
- ->x_auto_return_pattern);
+ type = DECL_SAVED_AUTO_RETURN_TYPE (decl);
else
type = DECL_CONV_FN_TYPE (decl);
write_conversion_operator_name (type);
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))
+ else if (TREE_CODE (decl) == TYPE_DECL && LAMBDA_TYPE_P (type))
write_closure_type_name (type);
else
write_source_name (DECL_NAME (decl));
write_name (entity, /*ignore_local_scope=*/1);
if (DECL_DISCRIMINATOR_P (local_entity)
&& !(TREE_CODE (local_entity) == TYPE_DECL
- && (LAMBDA_TYPE_P (TREE_TYPE (local_entity))
- || TYPE_UNNAMED_P (TREE_TYPE (local_entity)))))
+ && TYPE_ANON_P (TREE_TYPE (local_entity))))
write_discriminator (discriminator_for_local_entity (local_entity));
}
}
t = cp_build_type_attribute_variant (t, attrs);
}
gcc_assert (t != type);
- if (TREE_CODE (t) == FUNCTION_TYPE
- || TREE_CODE (t) == METHOD_TYPE)
+ if (FUNC_OR_METHOD_TYPE_P (t))
{
t = build_ref_qualified_type (t, type_memfn_rqual (type));
if (flag_noexcept_type)
/* See through any typedefs. */
type = TYPE_MAIN_VARIANT (type);
- if (TREE_CODE (type) == FUNCTION_TYPE
- || TREE_CODE (type) == METHOD_TYPE)
+ if (FUNC_OR_METHOD_TYPE_P (type))
type = cxx_copy_lang_qualifiers (type, type_orig);
/* According to the C++ ABI, some library classes are passed the
break;
case TYPEOF_TYPE:
- sorry ("mangling typeof, use decltype instead");
+ sorry ("mangling %<typeof%>, use %<decltype%> instead");
break;
case UNDERLYING_TYPE:
- sorry ("mangling __underlying_type");
+ sorry ("mangling %<__underlying_type%>");
break;
case LANG_TYPE:
return strcmp (as1->name, as2->name);
}
+/* Return true if we should mangle a type attribute with name NAME. */
+
+static bool
+mangle_type_attribute_p (tree name)
+{
+ const attribute_spec *as = lookup_attribute_spec (name);
+ if (!as || !as->affects_type_identity)
+ return false;
+
+ /* Skip internal-only attributes, which are distinguished from others
+ by having a space. At present, all internal-only attributes that
+ affect type identity are target-specific and are handled by
+ targetm.mangle_type instead.
+
+ Another reason to do this is that a space isn't a valid identifier
+ character for most file formats. */
+ if (strchr (IDENTIFIER_POINTER (name), ' '))
+ return false;
+
+ /* The following attributes are mangled specially. */
+ if (is_attribute_p ("transaction_safe", name))
+ return false;
+ if (is_attribute_p ("abi_tag", name))
+ return false;
+
+ return true;
+}
+
/* Non-terminal <CV-qualifiers> for type nodes. Returns the number of
CV-qualifiers written for TYPE.
{
auto_vec<tree> vec;
for (tree a = TYPE_ATTRIBUTES (type); a; a = TREE_CHAIN (a))
- {
- tree name = get_attribute_name (a);
- const attribute_spec *as = lookup_attribute_spec (name);
- if (as && as->affects_type_identity
- && !is_attribute_p ("transaction_safe", name)
- && !is_attribute_p ("abi_tag", name))
- vec.safe_push (a);
- }
+ if (mangle_type_attribute_p (get_attribute_name (a)))
+ vec.safe_push (a);
if (abi_warn_or_compat_version_crosses (10) && !vec.is_empty ())
G.need_abi_warning = true;
if (abi_version_at_least (10))
break;
case INTEGER_TYPE:
- /* TYPE may still be wchar_t, char16_t, or char32_t, since that
+ /* TYPE may still be wchar_t, char8_t, char16_t, or char32_t, since that
isn't in integer_type_nodes. */
if (type == wchar_type_node)
write_char ('w');
+ else if (type == char8_type_node)
+ write_string ("Du");
else if (type == char16_type_node)
write_string ("Ds");
else if (type == char32_type_node)
write_char ('d');
else if (type == long_double_type_node)
write_char ('e');
- else if (type == dfloat32_type_node)
+ else if (type == dfloat32_type_node || type == fallback_dfloat32_type)
write_string ("Df");
- else if (type == dfloat64_type_node)
+ else if (type == dfloat64_type_node || type == fallback_dfloat64_type)
write_string ("Dd");
- else if (type == dfloat128_type_node)
+ else if (type == dfloat128_type_node || type == fallback_dfloat128_type)
write_string ("De");
else
gcc_unreachable ();
write_unqualified_id (member);
}
else if (DECL_P (member))
- write_unqualified_name (member);
+ {
+ gcc_assert (!DECL_OVERLOADED_OPERATOR_P (member));
+ write_unqualified_name (member);
+ }
else if (TREE_CODE (member) == TEMPLATE_ID_EXPR)
{
tree name = TREE_OPERAND (member, 0);
write_expression (member);
}
+/* EXPR is a base COMPONENT_REF; write the minimized base conversion path for
+ converting to BASE, or just the conversion of EXPR if BASE is null.
+
+ "Given a fully explicit base path P := C_n -> ... -> C_0, the minimized base
+ path Min(P) is defined as follows: let C_i be the last element for which the
+ conversion to C_0 is unambiguous; if that element is C_n, the minimized path
+ is C_n -> C_0; otherwise, the minimized path is Min(C_n -> ... -> C_i) ->
+ C_0."
+
+ We mangle the conversion to C_i if it's different from C_n. */
+
+static bool
+write_base_ref (tree expr, tree base = NULL_TREE)
+{
+ if (TREE_CODE (expr) != COMPONENT_REF)
+ return false;
+
+ tree field = TREE_OPERAND (expr, 1);
+
+ if (TREE_CODE (field) != FIELD_DECL || !DECL_FIELD_IS_BASE (field))
+ return false;
+
+ tree object = TREE_OPERAND (expr, 0);
+
+ tree binfo = NULL_TREE;
+ if (base)
+ {
+ tree cur = TREE_TYPE (object);
+ binfo = lookup_base (cur, base, ba_unique, NULL, tf_none);
+ }
+ else
+ /* We're at the end of the base conversion chain, so it can't be
+ ambiguous. */
+ base = TREE_TYPE (field);
+
+ if (binfo == error_mark_node)
+ {
+ /* cur->base is ambiguous, so make the conversion to
+ last explicit, expressed as a cast (last&)object. */
+ tree last = TREE_TYPE (expr);
+ write_string (OVL_OP_INFO (false, CAST_EXPR)->mangled_name);
+ write_type (build_reference_type (last));
+ write_expression (object);
+ }
+ else if (write_base_ref (object, base))
+ /* cur->base is unambiguous, but we had another base conversion
+ underneath and wrote it out. */;
+ else
+ /* No more base conversions, just write out the object. */
+ write_expression (object);
+
+ return true;
+}
+
/* <expression> ::= <unary operator-name> <expression>
::= <binary operator-name> <expression> <expression>
::= <expr-primary>
/* Skip NOP_EXPR and CONVERT_EXPR. They can occur when (say) a pointer
argument is converted (via qualification conversions) to another type. */
while (CONVERT_EXPR_CODE_P (code)
+ || code == IMPLICIT_CONV_EXPR
|| location_wrapper_p (expr)
/* Parentheses aren't mangled. */
|| code == PAREN_EXPR
else
goto normal_expr;
}
- else if (TREE_CODE (expr) == ALIGNOF_EXPR
- && TYPE_P (TREE_OPERAND (expr, 0)))
+ else if (TREE_CODE (expr) == ALIGNOF_EXPR)
{
- write_string ("at");
- write_type (TREE_OPERAND (expr, 0));
+ if (!ALIGNOF_EXPR_STD_P (expr))
+ {
+ if (abi_warn_or_compat_version_crosses (15))
+ G.need_abi_warning = true;
+ if (abi_version_at_least (15))
+ {
+ /* We used to mangle __alignof__ like alignof. */
+ write_string ("v111__alignof__");
+ if (TYPE_P (TREE_OPERAND (expr, 0)))
+ write_type (TREE_OPERAND (expr, 0));
+ else
+ write_expression (TREE_OPERAND (expr, 0));
+ return;
+ }
+ }
+ if (TYPE_P (TREE_OPERAND (expr, 0)))
+ {
+ write_string ("at");
+ write_type (TREE_OPERAND (expr, 0));
+ }
+ else
+ goto normal_expr;
}
else if (code == SCOPE_REF
|| code == BASELINK)
{
scope = TREE_OPERAND (expr, 0);
member = TREE_OPERAND (expr, 1);
- gcc_assert (!BASELINK_P (member));
+ if (BASELINK_P (member))
+ member = BASELINK_FUNCTIONS (member);
}
else
{
write_expression (member);
else
{
+ gcc_assert (code != BASELINK || BASELINK_QUALIFIED_P (expr));
write_string ("sr");
write_type (scope);
write_member_name (member);
}
else if (code == CONSTRUCTOR)
{
- vec<constructor_elt, va_gc> *elts = CONSTRUCTOR_ELTS (expr);
- unsigned i; tree val;
+ bool braced_init = BRACE_ENCLOSED_INITIALIZER_P (expr);
+ tree etype = TREE_TYPE (expr);
- if (BRACE_ENCLOSED_INITIALIZER_P (expr))
+ if (braced_init)
write_string ("il");
else
{
write_string ("tl");
- write_type (TREE_TYPE (expr));
+ write_type (etype);
+ }
+
+ bool nontriv = !trivial_type_p (etype);
+ if (nontriv || !zero_init_expr_p (expr))
+ {
+ /* Convert braced initializer lists to STRING_CSTs so that
+ A<"Foo"> mangles the same as A<{'F', 'o', 'o', 0}> while
+ still using the latter mangling for strings that
+ originated as braced initializer lists. */
+ expr = braced_lists_to_strings (etype, expr);
+
+ if (TREE_CODE (expr) == CONSTRUCTOR)
+ {
+ vec<constructor_elt, va_gc> *elts = CONSTRUCTOR_ELTS (expr);
+ unsigned last_nonzero = UINT_MAX, i;
+ constructor_elt *ce;
+ tree val;
+
+ if (!nontriv)
+ FOR_EACH_CONSTRUCTOR_VALUE (elts, i, val)
+ if (!zero_init_expr_p (val))
+ last_nonzero = i;
+
+ if (nontriv || last_nonzero != UINT_MAX)
+ for (HOST_WIDE_INT i = 0; vec_safe_iterate (elts, i, &ce); ++i)
+ {
+ if (i > last_nonzero)
+ break;
+ /* FIXME handle RANGE_EXPR */
+ if (TREE_CODE (etype) == UNION_TYPE)
+ {
+ /* Express the active member as a designator. */
+ write_string ("di");
+ write_unqualified_name (ce->index);
+ }
+ write_expression (ce->value);
+ }
+ }
+ else
+ {
+ gcc_assert (TREE_CODE (expr) == STRING_CST);
+ write_expression (expr);
+ }
}
- FOR_EACH_CONSTRUCTOR_VALUE (elts, i, val)
- write_expression (val);
write_char ('E');
}
else if (code == LAMBDA_EXPR)
}
else if (dependent_name (expr))
{
- write_unqualified_id (dependent_name (expr));
+ tree name = dependent_name (expr);
+ gcc_assert (!IDENTIFIER_ANY_OP_P (name));
+ write_unqualified_id (name);
}
else
{
ob = TREE_OPERAND (ob, 0);
write_expression (ob);
}
+ else if (write_base_ref (expr))
+ return;
else if (!is_dummy_object (ob))
{
write_string ("dt");
/* Mangle a dependent name as the name, not whatever happens to
be the first function in the overload set. */
- if ((TREE_CODE (fn) == FUNCTION_DECL
- || TREE_CODE (fn) == OVERLOAD)
+ if (OVL_P (fn)
&& type_dependent_expression_p_push (expr))
fn = OVL_NAME (fn);
static void
write_template_arg_literal (const tree value)
{
- write_char ('L');
- write_type (TREE_TYPE (value));
+ if (TREE_CODE (value) == STRING_CST)
+ /* Temporarily mangle strings as braced initializer lists. */
+ write_string ("tl");
+ else
+ write_char ('L');
+
+ tree valtype = TREE_TYPE (value);
+ write_type (valtype);
/* Write a null member pointer value as (type)0, regardless of its
real representation. */
case INTEGER_CST:
gcc_assert (!same_type_p (TREE_TYPE (value), boolean_type_node)
|| integer_zerop (value) || integer_onep (value));
- write_integer_cst (value);
+ if (!(abi_version_at_least (14)
+ && NULLPTR_TYPE_P (TREE_TYPE (value))))
+ write_integer_cst (value);
break;
case REAL_CST:
break;
case STRING_CST:
- sorry ("string literal in function template signature");
- break;
+ {
+ /* Mangle strings the same as braced initializer lists. */
+ unsigned n = TREE_STRING_LENGTH (value);
+ const char *str = TREE_STRING_POINTER (value);
+
+ /* Count the number of trailing nuls and subtract them from
+ STRSIZE because they don't need to be mangled. */
+ for (const char *p = str + n - 1; ; --p)
+ {
+ if (*p || p == str)
+ {
+ n -= str + n - !!*p - p;
+ break;
+ }
+ }
+ tree eltype = TREE_TYPE (valtype);
+ for (const char *p = str; n--; ++p)
+ {
+ write_char ('L');
+ write_type (eltype);
+ write_unsigned_number (*(const unsigned char*)p);
+ write_string ("E");
+ }
+ break;
+ }
default:
gcc_unreachable ();
if (template_parm_object_p (node))
/* We want to mangle the argument, not the var we stored it in. */
- node = DECL_INITIAL (node);
+ node = tparm_object_argument (node);
/* Strip a conversion added by convert_nontype_argument. */
if (TREE_CODE (node) == IMPLICIT_CONV_EXPR)
G.entity = entity;
G.need_abi_warning = false;
G.need_cxx17_warning = false;
+ G.mod = false;
obstack_free (&name_obstack, name_base);
mangle_obstack = &name_obstack;
name_base = obstack_alloc (&name_obstack, 0);
}
-/* Done with mangling. If WARN is true, and the name of G.entity will
- be mangled differently in a future version of the ABI, issue a
- warning. */
+/* Done with mangling. Release the data. */
static void
finish_mangling_internal (void)
/* Clear all the substitutions. */
vec_safe_truncate (G.substitutions, 0);
+ if (G.mod)
+ mangle_module_fini ();
+
/* Null-terminate the string. */
write_char ('\0');
}
subst_identifiers[SUBID_BASIC_IOSTREAM] = get_identifier ("basic_iostream");
}
+/* Generate a mangling for MODULE's global initializer fn. */
+
+tree
+mangle_module_global_init (int module)
+{
+ start_mangling (NULL_TREE);
+
+ write_string ("_ZGI");
+ write_module (module, true);
+ write_char ('v');
+
+ return finish_mangling_get_identifier ();
+}
+
/* Generate the mangled name of DECL. */
static tree
mangle_decl_string (const tree decl)
{
tree result;
- location_t saved_loc = input_location;
tree saved_fn = NULL_TREE;
bool template_p = false;
current_function_decl = NULL_TREE;
}
}
- input_location = DECL_SOURCE_LOCATION (decl);
+ iloc_sentinel ils (DECL_SOURCE_LOCATION (decl));
start_mangling (decl);
pop_tinst_level ();
current_function_decl = saved_fn;
}
- input_location = saved_loc;
return result;
}
if (for_decl && DECL_THUNK_P (for_decl))
warning_at (DECL_SOURCE_LOCATION (t), OPT_Wabi,
"the mangled name of a thunk for %qD changes between "
- "-fabi-version=%d and -fabi-version=%d",
+ "%<-fabi-version=%d%> and %<-fabi-version=%d%>",
t, flag_abi_version, warn_abi_version);
else if (for_decl)
warning_at (DECL_SOURCE_LOCATION (for_decl), OPT_Wabi,
"the mangled name of %qD changes between "
- "-fabi-version=%d and -fabi-version=%d",
+ "%<-fabi-version=%d%> and %<-fabi-version=%d%>",
for_decl, flag_abi_version, warn_abi_version);
else
warning_at (DECL_SOURCE_LOCATION (t), OPT_Wabi,
"the mangled name of the initialization guard variable "
- "for %qD changes between -fabi-version=%d and "
- "-fabi-version=%d",
+ "for %qD changes between %<-fabi-version=%d%> and "
+ "%<-fabi-version=%d%>",
t, flag_abi_version, warn_abi_version);
}
}
}
/* Return an identifier for the name of a temporary variable used to
- initialize a static reference. This isn't part of the ABI, but we might
- as well call them something readable. */
-
-static GTY(()) int temp_count;
+ initialize a static reference. This is now part of the ABI. */
tree
mangle_ref_init_variable (const tree variable)
write_name (variable, /*ignore_local_scope=*/0);
/* Avoid name clashes with aggregate initialization of multiple
references at once. */
- write_unsigned_number (temp_count++);
+ write_compact_number (current_ref_temp_count++);
return finish_mangling_get_identifier ();
}