summaryrefslogtreecommitdiff
path: root/gcc/cp
diff options
context:
space:
mode:
authormmitchel <mmitchel@138bc75d-0d04-0410-961f-82ee72b054a4>2002-10-04 04:59:39 +0000
committermmitchel <mmitchel@138bc75d-0d04-0410-961f-82ee72b054a4>2002-10-04 04:59:39 +0000
commit18f2b9d54acfd4f16a85182fae7ec70628cafef2 (patch)
tree2a6564ee9bc95c1a339ca2aa488debfeb614d0be /gcc/cp
parent3d03336145a01c7501a2383f31707dfdce613e17 (diff)
downloadgcc-18f2b9d54acfd4f16a85182fae7ec70628cafef2.tar.gz
* doc/invoke.texi (-Wabi): Document mangling bug.
PR c++/8006 * mangle.c (CLASSTYPE_TEMPLATE_ID_P): Handle instances of template template parameters. (globals): Add entity and need_abi_warning. (decl_is_template_id): Use TYPE_TEMPLATE_INFO, not CLASSTYPE_TEMPLATE_INFO. (is_std_substitution): Use CLASSTYPE_TI_TEMPLATE, not TYPE_TI_TEMPLATE. (write_prefix): Handle typename types correctly. (write_template_prefix): Handle template template parameters correctly. (start_mangling): Add entity parameter. (finish_mangling): Warn about names whose mangling will change. (mangle_decl_string): Adjust. (mangle_type_string): Likewise. (mangle_special_for_type): Likewise. (mangle_ctor_vtbl_for_type): Likewise. (mangle_thunk): Likewise. (mangle_guard_variable): Likewise. (mangle_ref_init_variable): Likewise. PR c++/8006 * g++.dg/abi/mangle9.C: New test. * g++.dg/abi/mangle10.C: New test. * g++.dg/abi/mangle11.C: New test. * g++.dg/abi/mangle12.C: New test. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@57799 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/cp')
-rw-r--r--gcc/cp/ChangeLog23
-rw-r--r--gcc/cp/mangle.c107
2 files changed, 95 insertions, 35 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 521b4971ce1..f10a56466b9 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,26 @@
+2002-10-03 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/8006
+ * mangle.c (CLASSTYPE_TEMPLATE_ID_P): Handle instances of template
+ template parameters.
+ (globals): Add entity and need_abi_warning.
+ (decl_is_template_id): Use TYPE_TEMPLATE_INFO, not
+ CLASSTYPE_TEMPLATE_INFO.
+ (is_std_substitution): Use CLASSTYPE_TI_TEMPLATE, not
+ TYPE_TI_TEMPLATE.
+ (write_prefix): Handle typename types correctly.
+ (write_template_prefix): Handle template template parameters
+ correctly.
+ (start_mangling): Add entity parameter.
+ (finish_mangling): Warn about names whose mangling will change.
+ (mangle_decl_string): Adjust.
+ (mangle_type_string): Likewise.
+ (mangle_special_for_type): Likewise.
+ (mangle_ctor_vtbl_for_type): Likewise.
+ (mangle_thunk): Likewise.
+ (mangle_guard_variable): Likewise.
+ (mangle_ref_init_variable): Likewise.
+
2002-10-02 Mark Mitchell <mark@codesourcery.com>
PR c++/7188.
diff --git a/gcc/cp/mangle.c b/gcc/cp/mangle.c
index c7bd31299db..76fd5f7e425 100644
--- a/gcc/cp/mangle.c
+++ b/gcc/cp/mangle.c
@@ -80,10 +80,11 @@
that hard to distinguish A<T> from A, where A<T> is the type as
instantiated outside of the template, and A is the type used
without parameters inside the template. */
-#define CLASSTYPE_TEMPLATE_ID_P(NODE) \
- (TYPE_LANG_SPECIFIC (NODE) != NULL \
- && CLASSTYPE_TEMPLATE_INFO (NODE) != NULL \
- && (PRIMARY_TEMPLATE_P (CLASSTYPE_TI_TEMPLATE (NODE))))
+#define CLASSTYPE_TEMPLATE_ID_P(NODE) \
+ (TYPE_LANG_SPECIFIC (NODE) != NULL \
+ && (TREE_CODE (NODE) == BOUND_TEMPLATE_TEMPLATE_PARM \
+ || (CLASSTYPE_TEMPLATE_INFO (NODE) != NULL \
+ && (PRIMARY_TEMPLATE_P (CLASSTYPE_TI_TEMPLATE (NODE))))))
/* Things we only need one of. This module is not reentrant. */
static struct globals
@@ -95,10 +96,17 @@ static struct globals
we've seen them. */
varray_type substitutions;
+ /* The entity that is being mangled. */
+ tree entity;
+
/* We are mangling an internal symbol. It is important to keep those
involving template parmeters distinct by distinguishing their level
and, for non-type parms, their type. */
bool internal_mangling_p;
+
+ /* True if the mangling will be different in a future version of the
+ ABI. */
+ bool need_abi_warning;
} G;
/* Indices into subst_identifiers. These are identifiers used in
@@ -192,8 +200,8 @@ static const char *mangle_decl_string PARAMS ((tree));
/* Control functions. */
-static inline void start_mangling PARAMS ((void));
-static inline const char *finish_mangling PARAMS ((void));
+static inline void start_mangling (tree);
+static inline const char *finish_mangling (bool);
static tree mangle_special_for_type PARAMS ((tree, const char *));
/* Foreign language functions. */
@@ -250,7 +258,7 @@ decl_is_template_id (decl, template_info)
if (template_info != NULL)
/* For a templated TYPE_DECL, the template info is hanging
off the type. */
- *template_info = CLASSTYPE_TEMPLATE_INFO (type);
+ *template_info = TYPE_TEMPLATE_INFO (type);
return 1;
}
}
@@ -398,8 +406,8 @@ is_std_substitution (node, index)
return (DECL_NAMESPACE_STD_P (CP_DECL_CONTEXT (decl))
&& TYPE_LANG_SPECIFIC (type)
- && CLASSTYPE_TEMPLATE_INFO (type)
- && (DECL_NAME (CLASSTYPE_TI_TEMPLATE (type))
+ && TYPE_TEMPLATE_INFO (type)
+ && (DECL_NAME (TYPE_TI_TEMPLATE (type))
== subst_identifiers[index]));
}
@@ -837,7 +845,8 @@ write_nested_name (decl)
write_char ('E');
}
-/* <prefix> ::= <prefix> <unqualified-name>>
+/* <prefix> ::= <prefix> <unqualified-name>
+ ::= <template-param>
::= <template-prefix> <template-args>
::= # empty
::= <substitution> */
@@ -860,7 +869,6 @@ write_prefix (node)
return;
if (DECL_P (node))
- /* Node is a decl. */
{
/* If this is a function decl, that means we've hit function
scope, so this prefix must be for a local name. In this
@@ -874,14 +882,22 @@ write_prefix (node)
decl_is_template_id (decl, &template_info);
}
else
- /* Node is a type. */
{
+ /* Node is a type. */
decl = TYPE_NAME (node);
if (CLASSTYPE_TEMPLATE_ID_P (node))
- template_info = CLASSTYPE_TEMPLATE_INFO (node);
+ template_info = TYPE_TEMPLATE_INFO (node);
}
- if (template_info != NULL)
+ /* In G++ 3.2, the name of the template parameter was used. */
+ if (TREE_CODE (node) == TEMPLATE_TYPE_PARM
+ && !abi_version_at_least (2))
+ G.need_abi_warning = true;
+
+ if (TREE_CODE (node) == TEMPLATE_TYPE_PARM
+ && abi_version_at_least (2))
+ write_template_param (node);
+ else if (template_info != NULL)
/* Templated. */
{
write_template_prefix (decl);
@@ -898,6 +914,7 @@ write_prefix (node)
}
/* <template-prefix> ::= <prefix> <template component>
+ ::= <template-param>
::= <substitution> */
static void
@@ -917,7 +934,7 @@ write_template_prefix (node)
if (decl_is_template_id (decl, &template_info))
template = TI_TEMPLATE (template_info);
else if (CLASSTYPE_TEMPLATE_ID_P (type))
- template = CLASSTYPE_TI_TEMPLATE (type);
+ template = TYPE_TI_TEMPLATE (type);
else
/* Oops, not a template. */
abort ();
@@ -952,8 +969,19 @@ write_template_prefix (node)
if (find_substitution (substitution))
return;
- write_prefix (context);
- write_unqualified_name (decl);
+ /* In G++ 3.2, the name of the template template parameter was used. */
+ if (TREE_CODE (TREE_TYPE (template)) == TEMPLATE_TEMPLATE_PARM
+ && !abi_version_at_least (2))
+ G.need_abi_warning = true;
+
+ if (TREE_CODE (TREE_TYPE (template)) == TEMPLATE_TEMPLATE_PARM
+ && abi_version_at_least (2))
+ write_template_param (TREE_TYPE (template));
+ else
+ {
+ write_prefix (context);
+ write_unqualified_name (decl);
+ }
add_substitution (substitution);
}
@@ -2168,20 +2196,29 @@ write_substitution (seq_id)
write_char ('_');
}
-/* Start mangling a new name or type. */
+/* Start mangling ENTITY. */
static inline void
-start_mangling ()
+start_mangling (tree entity)
{
+ G.entity = entity;
+ G.need_abi_warning = false;
VARRAY_TREE_INIT (G.substitutions, 1, "mangling substitutions");
obstack_free (&G.name_obstack, obstack_base (&G.name_obstack));
}
-/* Done with mangling. Return the generated mangled name. */
+/* Done with mangling. Return the generated mangled name. If WARN is
+ true, and the name of G.entity will be mangled differently in a
+ future version of the ABI, issue a warning. */
static inline const char *
-finish_mangling ()
+finish_mangling (bool warn)
{
+ if (warn_abi && warn && G.need_abi_warning)
+ warning ("the mangled name of `%D' will change in a future "
+ "version of GCC",
+ G.entity);
+
/* Clear all the substitutions. */
G.substitutions = 0;
@@ -2216,7 +2253,7 @@ mangle_decl_string (decl)
{
const char *result;
- start_mangling ();
+ start_mangling (decl);
if (TREE_CODE (decl) == TYPE_DECL)
write_type (TREE_TYPE (decl));
@@ -2243,7 +2280,7 @@ mangle_decl_string (decl)
write_string (" *INTERNAL* ");
}
- result = finish_mangling ();
+ result = finish_mangling (/*warn=*/true);
if (DEBUG_MANGLE)
fprintf (stderr, "mangle_decl_string = '%s'\n\n", result);
return result;
@@ -2268,9 +2305,9 @@ mangle_type_string (type)
{
const char *result;
- start_mangling ();
+ start_mangling (type);
write_type (type);
- result = finish_mangling ();
+ result = finish_mangling (/*warn=*/false);
if (DEBUG_MANGLE)
fprintf (stderr, "mangle_type_string = '%s'\n\n", result);
return result;
@@ -2298,7 +2335,7 @@ mangle_special_for_type (type, code)
/* We don't have an actual decl here for the special component, so
we can't just process the <encoded-name>. Instead, fake it. */
- start_mangling ();
+ start_mangling (type);
/* Start the mangling. */
write_string ("_Z");
@@ -2306,7 +2343,7 @@ mangle_special_for_type (type, code)
/* Add the type. */
write_type (type);
- result = finish_mangling ();
+ result = finish_mangling (/*warn=*/false);
if (DEBUG_MANGLE)
fprintf (stderr, "mangle_special_for_type = %s\n\n", result);
@@ -2373,7 +2410,7 @@ mangle_ctor_vtbl_for_type (type, binfo)
{
const char *result;
- start_mangling ();
+ start_mangling (type);
write_string ("_Z");
write_string ("TC");
@@ -2382,7 +2419,7 @@ mangle_ctor_vtbl_for_type (type, binfo)
write_char ('_');
write_type (BINFO_TYPE (binfo));
- result = finish_mangling ();
+ result = finish_mangling (/*warn=*/false);
if (DEBUG_MANGLE)
fprintf (stderr, "mangle_ctor_vtbl_for_type = %s\n\n", result);
return get_identifier (result);
@@ -2406,7 +2443,7 @@ mangle_thunk (fn_decl, offset, vcall_offset)
{
const char *result;
- start_mangling ();
+ start_mangling (fn_decl);
write_string ("_Z");
/* The <special-name> for virtual thunks is Tv, for non-virtual
@@ -2432,7 +2469,7 @@ mangle_thunk (fn_decl, offset, vcall_offset)
/* Scoped name. */
write_encoding (fn_decl);
- result = finish_mangling ();
+ result = finish_mangling (/*warn=*/false);
if (DEBUG_MANGLE)
fprintf (stderr, "mangle_thunk = %s\n\n", result);
return get_identifier (result);
@@ -2484,7 +2521,7 @@ tree
mangle_guard_variable (variable)
tree variable;
{
- start_mangling ();
+ start_mangling (variable);
write_string ("_ZGV");
if (strncmp (IDENTIFIER_POINTER (DECL_NAME (variable)), "_ZGR", 4) == 0)
/* The name of a guard variable for a reference temporary should refer
@@ -2492,7 +2529,7 @@ mangle_guard_variable (variable)
write_string (IDENTIFIER_POINTER (DECL_NAME (variable)) + 4);
else
write_name (variable, /*ignore_local_scope=*/0);
- return get_identifier (finish_mangling ());
+ return get_identifier (finish_mangling (/*warn=*/false));
}
/* Return an identifier for the name of a temporary variable used to
@@ -2503,10 +2540,10 @@ tree
mangle_ref_init_variable (variable)
tree variable;
{
- start_mangling ();
+ start_mangling (variable);
write_string ("_ZGR");
write_name (variable, /*ignore_local_scope=*/0);
- return get_identifier (finish_mangling ());
+ return get_identifier (finish_mangling (/*warn=*/false));
}