aboutsummaryrefslogtreecommitdiff
path: root/gcc/cp
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2009-07-22 19:03:22 -0400
committerJason Merrill <jason@gcc.gnu.org>2009-07-22 19:03:22 -0400
commit61e6d522e0b5acd469c16b488926b20af898962e (patch)
tree488c9415969a58d88af4c8fa181992ff70515d95 /gcc/cp
parentdb1a8d988963af9d6891316fc565b5aa38e334be (diff)
downloadgcc-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/cp')
-rw-r--r--gcc/cp/ChangeLog9
-rw-r--r--gcc/cp/cp-tree.h3
-rw-r--r--gcc/cp/mangle.c49
-rw-r--r--gcc/cp/name-lookup.c11
-rw-r--r--gcc/cp/rtti.c2
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;
}