diff options
author | mmitchel <mmitchel@138bc75d-0d04-0410-961f-82ee72b054a4> | 2002-10-04 04:59:39 +0000 |
---|---|---|
committer | mmitchel <mmitchel@138bc75d-0d04-0410-961f-82ee72b054a4> | 2002-10-04 04:59:39 +0000 |
commit | 18f2b9d54acfd4f16a85182fae7ec70628cafef2 (patch) | |
tree | 2a6564ee9bc95c1a339ca2aa488debfeb614d0be /gcc/cp | |
parent | 3d03336145a01c7501a2383f31707dfdce613e17 (diff) | |
download | gcc-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/ChangeLog | 23 | ||||
-rw-r--r-- | gcc/cp/mangle.c | 107 |
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)); } |