#include "varray.h"
#include "flags.h"
#include "target.h"
+#include "cgraph.h"
/* Debugging support. */
<local-source-name> ::= L <source-name> <discriminator> */
static void
+write_unqualified_id (tree identifier)
+{
+ if (IDENTIFIER_TYPENAME_P (identifier))
+ write_conversion_operator_name (TREE_TYPE (identifier));
+ else if (IDENTIFIER_OPNAME_P (identifier))
+ {
+ int i;
+ const char *mangled_name = NULL;
+
+ /* Unfortunately, there is no easy way to go from the
+ name of the operator back to the corresponding tree
+ code. */
+ for (i = 0; i < MAX_TREE_CODES; ++i)
+ if (operator_name_info[i].identifier == identifier)
+ {
+ /* The ABI says that we prefer binary operator
+ names to unary operator names. */
+ if (operator_name_info[i].arity == 2)
+ {
+ mangled_name = operator_name_info[i].mangled_name;
+ break;
+ }
+ else if (!mangled_name)
+ mangled_name = operator_name_info[i].mangled_name;
+ }
+ else if (assignment_operator_name_info[i].identifier
+ == identifier)
+ {
+ mangled_name
+ = assignment_operator_name_info[i].mangled_name;
+ break;
+ }
+ write_string (mangled_name);
+ }
+ else
+ write_source_name (identifier);
+}
+
+static void
write_unqualified_name (const tree decl)
{
MANGLE_TRACE_TREE ("unqualified-name", decl);
+ if (TREE_CODE (decl) == IDENTIFIER_NODE)
+ {
+ write_unqualified_id (decl);
+ return;
+ }
+
if (DECL_NAME (decl) == NULL_TREE)
{
gcc_assert (DECL_ASSEMBLER_NAME_SET_P (decl));
write_char ('_');
}
else
- write_string ("U8__vector");
+ {
+ G.need_abi_warning = 1;
+ write_string ("U8__vector");
+ }
write_type (TREE_TYPE (type));
break;
write_member_name (tree member)
{
if (TREE_CODE (member) == IDENTIFIER_NODE)
- write_source_name (member);
+ write_unqualified_id (member);
else if (DECL_P (member))
write_unqualified_name (member);
else if (TREE_CODE (member) == TEMPLATE_ID_EXPR)
write_expression (member);
else
{
- tree template_args;
-
write_string ("sr");
write_type (scope);
- /* If MEMBER is a template-id, separate the template
- from the arguments. */
- if (TREE_CODE (member) == TEMPLATE_ID_EXPR)
- {
- template_args = TREE_OPERAND (member, 1);
- member = TREE_OPERAND (member, 0);
- }
- else
- template_args = NULL_TREE;
- /* Write out the name of the MEMBER. */
- if (IDENTIFIER_TYPENAME_P (member))
- write_conversion_operator_name (TREE_TYPE (member));
- else if (IDENTIFIER_OPNAME_P (member))
- {
- int i;
- const char *mangled_name = NULL;
-
- /* Unfortunately, there is no easy way to go from the
- name of the operator back to the corresponding tree
- code. */
- for (i = 0; i < MAX_TREE_CODES; ++i)
- if (operator_name_info[i].identifier == member)
- {
- /* The ABI says that we prefer binary operator
- names to unary operator names. */
- if (operator_name_info[i].arity == 2)
- {
- mangled_name = operator_name_info[i].mangled_name;
- break;
- }
- else if (!mangled_name)
- mangled_name = operator_name_info[i].mangled_name;
- }
- else if (assignment_operator_name_info[i].identifier
- == member)
- {
- mangled_name
- = assignment_operator_name_info[i].mangled_name;
- break;
- }
- write_string (mangled_name);
- }
- else
- write_source_name (member);
- /* Write out the template arguments. */
- if (template_args)
- write_template_args (template_args);
+ write_member_name (member);
}
}
else if (TREE_CODE (expr) == INDIRECT_REF
{
write_expression (TREE_OPERAND (expr, 0));
}
+ else if (TREE_CODE (expr) == IDENTIFIER_NODE)
+ {
+ /* An operator name appearing as a dependent name needs to be
+ specially marked to disambiguate between a use of the operator
+ name and a use of the operator in an expression. */
+ if (IDENTIFIER_OPNAME_P (expr))
+ write_string ("on");
+ write_unqualified_id (expr);
+ }
+ else if (TREE_CODE (expr) == TEMPLATE_ID_EXPR)
+ {
+ tree fn = TREE_OPERAND (expr, 0);
+ if (is_overloaded_fn (fn))
+ fn = DECL_NAME (get_first_fn (fn));
+ if (IDENTIFIER_OPNAME_P (fn))
+ write_string ("on");
+ write_unqualified_id (fn);
+ write_template_args (TREE_OPERAND (expr, 1));
+ }
else
{
int i, len;
&& type_dependent_expression_p_push (expr))
fn = DECL_NAME (get_first_fn (fn));
- if (TREE_CODE (fn) == IDENTIFIER_NODE)
- write_source_name (fn);
- else
- write_expression (fn);
+ write_expression (fn);
}
for (i = 0; i < call_expr_nargs (expr); ++i)
mangle_decl_string (const tree decl)
{
tree result;
+ location_t saved_loc = input_location;
+ tree saved_fn = NULL_TREE;
+ bool template_p = false;
+
+ if (DECL_LANG_SPECIFIC (decl) && DECL_USE_TEMPLATE (decl))
+ {
+ struct tinst_level *tl = current_instantiation ();
+ if (!tl || tl->decl != decl)
+ {
+ template_p = true;
+ saved_fn = current_function_decl;
+ push_tinst_level (decl);
+ current_function_decl = NULL_TREE;
+ }
+ }
+ input_location = DECL_SOURCE_LOCATION (decl);
start_mangling (decl);
if (DEBUG_MANGLE)
fprintf (stderr, "mangle_decl_string = '%s'\n\n",
IDENTIFIER_POINTER (result));
+
+ if (template_p)
+ {
+ pop_tinst_level ();
+ current_function_decl = saved_fn;
+ }
+ input_location = saved_loc;
+
return result;
}
tree id = mangle_decl_string (decl);
id = targetm.mangle_decl_assembler_name (decl, id);
SET_DECL_ASSEMBLER_NAME (decl, id);
+
+ if (G.need_abi_warning)
+ {
+#ifdef ASM_OUTPUT_DEF
+ /* If the mangling will change in the future, emit an alias with the
+ future mangled name for forward-compatibility. */
+ int save_ver;
+ tree id2, alias;
+#endif
+
+ SET_IDENTIFIER_GLOBAL_VALUE (id, decl);
+ if (IDENTIFIER_GLOBAL_VALUE (id) != decl)
+ inform (DECL_SOURCE_LOCATION (decl), "-fabi-version=4 (or =0) "
+ "avoids this error with a change in vector mangling");
+
+#ifdef ASM_OUTPUT_DEF
+ save_ver = flag_abi_version;
+ flag_abi_version = 0;
+ id2 = mangle_decl_string (decl);
+ id2 = targetm.mangle_decl_assembler_name (decl, id2);
+ flag_abi_version = save_ver;
+
+ alias = make_alias_for (decl, id2);
+ DECL_IGNORED_P (alias) = 1;
+ TREE_PUBLIC (alias) = TREE_PUBLIC (decl);
+ DECL_VISIBILITY (alias) = DECL_VISIBILITY (decl);
+ if (vague_linkage_p (decl))
+ DECL_WEAK (alias) = 1;
+ if (TREE_CODE (decl) == FUNCTION_DECL)
+ cgraph_same_body_alias (alias, decl);
+ else
+ varpool_extra_name_alias (alias, decl);
+#endif
+ }
}
/* Generate the mangled representation of TYPE. */