diff options
author | Jason Merrill <jason@redhat.com> | 2009-07-22 19:03:22 -0400 |
---|---|---|
committer | Jason Merrill <jason@gcc.gnu.org> | 2009-07-22 19:03:22 -0400 |
commit | 61e6d522e0b5acd469c16b488926b20af898962e (patch) | |
tree | 488c9415969a58d88af4c8fa181992ff70515d95 /gcc | |
parent | db1a8d988963af9d6891316fc565b5aa38e334be (diff) | |
download | gcc-61e6d522e0b5acd469c16b488926b20af898962e.zip gcc-61e6d522e0b5acd469c16b488926b20af898962e.tar.gz gcc-61e6d522e0b5acd469c16b488926b20af898962e.tar.bz2 |
mangle.c (mangle_type_string_for_rtti): Rename to be clearer.
* mangle.c (mangle_type_string_for_rtti): Rename to be clearer.
(needs_fake_anon): New.
(write_name): Check it.
(write_nested_name): Add a fake anonymous namespace scope if true.
* name-lookup.c (get_anonymous_namespace_name): No longer static.
* rtti.c, cp-tree.h: Adjust.
* libsupc++/typeinfo (__GXX_MERGED_TYPEINFO_NAMES): Default to 0.
From-SVN: r149964
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/cp/ChangeLog | 9 | ||||
-rw-r--r-- | gcc/cp/cp-tree.h | 3 | ||||
-rw-r--r-- | gcc/cp/mangle.c | 49 | ||||
-rw-r--r-- | gcc/cp/name-lookup.c | 11 | ||||
-rw-r--r-- | gcc/cp/rtti.c | 2 |
5 files changed, 55 insertions, 19 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index c86770e..8517886 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,12 @@ +2009-07-22 Jason Merrill <jason@redhat.com> + + * mangle.c (mangle_type_string_for_rtti): Rename to be clearer. + (needs_fake_anon): New. + (write_name): Check it. + (write_nested_name): Add a fake anonymous namespace scope if true. + * name-lookup.c (get_anonymous_namespace_name): No longer static. + * rtti.c, cp-tree.h: Adjust. + 2009-07-22 Richard Guenther <rguenther@suse.de> PR c++/40799 diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index 6ad039a..2bc2d62 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -4345,6 +4345,7 @@ extern tree type_promotes_to (tree); extern tree perform_qualification_conversions (tree, tree); /* in name-lookup.c */ +extern tree get_anonymous_namespace_name (void); extern tree pushdecl (tree); extern tree pushdecl_maybe_friend (tree, bool); extern void maybe_push_cleanup_level (tree); @@ -5095,7 +5096,7 @@ extern tree merge_exception_specifiers (tree, tree); /* in mangle.c */ extern void init_mangle (void); extern void mangle_decl (tree); -extern const char *mangle_type_string (tree); +extern const char *mangle_type_string_for_rtti (tree); extern tree mangle_typeinfo_for_type (tree); extern tree mangle_typeinfo_string_for_type (tree); extern tree mangle_vtbl_for_type (tree); diff --git a/gcc/cp/mangle.c b/gcc/cp/mangle.c index 1c79dcc..bb046d2 100644 --- a/gcc/cp/mangle.c +++ b/gcc/cp/mangle.c @@ -105,6 +105,10 @@ typedef struct GTY(()) globals { static GTY (()) globals G; +/* Whether or not to pretend that a static function is in an anonymous + namespace. */ +static bool fake_anon_scope; + /* The obstack on which we build mangled names. */ static struct obstack *mangle_obstack; @@ -726,6 +730,20 @@ write_encoding (const tree decl) } } +/* Since we now use strcmp to compare typeinfos on all targets because of + the RTLD_LOCAL problem, we need to munge the typeinfo name used for + local classes of static functions to fix g++.dg/abi/local1.C. We do + that by pretending that the function is in an anonymous namespace. */ + +static bool +needs_fake_anon (const_tree decl) +{ + /* Pretend there's an anonymous namespace right around a static + function if we're mangling for RTTI. */ + return (fake_anon_scope && !TREE_PUBLIC (decl) + && TREE_CODE (decl) == FUNCTION_DECL); +} + /* <name> ::= <unscoped-name> ::= <unscoped-template-name> <template-args> ::= <nested-name> @@ -749,18 +767,23 @@ write_name (tree decl, const int ignore_local_scope) /* In case this is a typedef, fish out the corresponding TYPE_DECL for the main variant. */ decl = TYPE_NAME (TYPE_MAIN_VARIANT (TREE_TYPE (decl))); - context = TYPE_CONTEXT (TYPE_MAIN_VARIANT (TREE_TYPE (decl))); + context = CP_TYPE_CONTEXT (TYPE_MAIN_VARIANT (TREE_TYPE (decl))); } else - context = (DECL_CONTEXT (decl) == NULL) ? NULL : CP_DECL_CONTEXT (decl); + context = CP_DECL_CONTEXT (decl); + + gcc_assert (context != NULL_TREE); + + /* If we need a fake anonymous namespace, force the nested name path. */ + if (needs_fake_anon (decl) && context == global_namespace) + context = error_mark_node; /* A decl in :: or ::std scope is treated specially. The former is mangled using <unscoped-name> or <unscoped-template-name>, the latter with a special substitution. Also, a name that is directly in a local function scope is also mangled with <unscoped-name> rather than a full <nested-name>. */ - if (context == NULL - || context == global_namespace + if (context == global_namespace || DECL_NAMESPACE_STD_P (context) || (ignore_local_scope && TREE_CODE (context) == FUNCTION_DECL)) { @@ -778,6 +801,9 @@ write_name (tree decl, const int ignore_local_scope) } else { + if (context == error_mark_node) + context = global_namespace; + /* Handle local names, unless we asked not to (that is, invoked under <local-name>, to handle only the part of the name under the local scope). */ @@ -790,10 +816,10 @@ write_name (tree decl, const int ignore_local_scope) directly in that function's scope, either decl or one of its enclosing scopes. */ tree local_entity = decl; - while (context != NULL && context != global_namespace) + while (context != global_namespace) { /* Make sure we're always dealing with decls. */ - if (context != NULL && TYPE_P (context)) + if (TYPE_P (context)) context = TYPE_NAME (context); /* Is this a function? */ if (TREE_CODE (context) == FUNCTION_DECL) @@ -837,7 +863,6 @@ write_unscoped_name (const tree decl) /* If not, it should be either in the global namespace, or directly in a local function scope. */ gcc_assert (context == global_namespace - || context == NULL || TREE_CODE (context) == FUNCTION_DECL); write_unqualified_name (decl); @@ -909,6 +934,9 @@ write_nested_name (const tree decl) { /* No, just use <prefix> */ write_prefix (DECL_CONTEXT (decl)); + if (needs_fake_anon (decl)) + /* Pretend this static function is in an anonymous namespace. */ + write_source_name (get_anonymous_namespace_name ()); write_unqualified_name (decl); } write_char ('E'); @@ -2817,15 +2845,18 @@ mangle_decl (const tree decl) SET_DECL_ASSEMBLER_NAME (decl, id); } -/* Generate the mangled representation of TYPE. */ +/* Generate the mangled representation of TYPE for the typeinfo name. */ const char * -mangle_type_string (const tree type) +mangle_type_string_for_rtti (const tree type) { const char *result; start_mangling (type); + /* Mangle in a fake anonymous namespace if necessary. */ + fake_anon_scope = true; write_type (type); + fake_anon_scope = false; result = finish_mangling (/*warn=*/false); if (DEBUG_MANGLE) fprintf (stderr, "mangle_type_string = '%s'\n\n", result); diff --git a/gcc/cp/name-lookup.c b/gcc/cp/name-lookup.c index 7a8016f..c2d8779 100644 --- a/gcc/cp/name-lookup.c +++ b/gcc/cp/name-lookup.c @@ -62,19 +62,14 @@ static GTY(()) tree anonymous_namespace_name; /* Initialize anonymous_namespace_name if necessary, and return it. */ -static tree -get_anonymous_namespace_name(void) +tree +get_anonymous_namespace_name (void) { if (!anonymous_namespace_name) { /* The anonymous namespace has to have a unique name if typeinfo objects are being compared by name. */ - if (! flag_weak || ! SUPPORTS_ONE_ONLY) - anonymous_namespace_name = get_file_function_name ("N"); - else - /* The demangler expects anonymous namespaces to be called - something starting with '_GLOBAL__N_'. */ - anonymous_namespace_name = get_identifier ("_GLOBAL__N_1"); + anonymous_namespace_name = get_file_function_name ("N"); } return anonymous_namespace_name; } diff --git a/gcc/cp/rtti.c b/gcc/cp/rtti.c index 01bba34..8dde479 100644 --- a/gcc/cp/rtti.c +++ b/gcc/cp/rtti.c @@ -356,7 +356,7 @@ tinfo_name (tree type) const char *name; tree name_string; - name = mangle_type_string (type); + name = mangle_type_string_for_rtti (type); name_string = fix_string_type (build_string (strlen (name) + 1, name)); return name_string; } |