mirror of git://gcc.gnu.org/git/gcc.git
mangle.c (mangle_type_string_for_rtti): Reapply 153734.
/gcc/cp 2009-10-30 Jerry Quinn <jlquinn@optonline.net> * mangle.c (mangle_type_string_for_rtti): Reapply 153734. (needs_fake_anon): Likewise. (write_name): Likewise. (write_nested_name): Likewise. * cp-tree.h (mangle_type_string_for_rtti): Likewise. (get_anonymous_namespace): Likewise. * name-lookup.c (get_anonymous_namespace_name): Likewise. * rtti.c (tinfo_name): Likewise, with +1 in the second build_string call fixed. (tinfo_base_init): Likewise. libstdc++/ 2009-10-30 Jerry Quinn <jlquinn@optonline.net> * libsupc++/tinfo.cc (operator=(const type_info&)): Reapply 153734. * libsupc++/typeinfo (type_info::name()): Likewise. * libsupc++/tinfo2.cc (before): Likewise. From-SVN: r153768
This commit is contained in:
parent
a20c8540db
commit
52669d592b
|
|
@ -1,3 +1,16 @@
|
||||||
|
2009-10-30 Jerry Quinn <jlquinn@optonline.net>
|
||||||
|
|
||||||
|
* mangle.c (mangle_type_string_for_rtti): Reapply 153734.
|
||||||
|
(needs_fake_anon): Likewise.
|
||||||
|
(write_name): Likewise.
|
||||||
|
(write_nested_name): Likewise.
|
||||||
|
* cp-tree.h (mangle_type_string_for_rtti): Likewise.
|
||||||
|
(get_anonymous_namespace): Likewise.
|
||||||
|
* name-lookup.c (get_anonymous_namespace_name): Likewise.
|
||||||
|
* rtti.c (tinfo_name): Likewise, with +1 in the second
|
||||||
|
build_string call fixed.
|
||||||
|
(tinfo_base_init): Likewise.
|
||||||
|
|
||||||
2009-10-30 Jason Merrill <jason@redhat.com>
|
2009-10-30 Jason Merrill <jason@redhat.com>
|
||||||
|
|
||||||
Revert:
|
Revert:
|
||||||
|
|
|
||||||
|
|
@ -4517,7 +4517,6 @@ extern tree type_promotes_to (tree);
|
||||||
extern tree perform_qualification_conversions (tree, tree);
|
extern tree perform_qualification_conversions (tree, tree);
|
||||||
|
|
||||||
/* in name-lookup.c */
|
/* in name-lookup.c */
|
||||||
extern tree get_anonymous_namespace_name (void);
|
|
||||||
extern tree pushdecl (tree);
|
extern tree pushdecl (tree);
|
||||||
extern tree pushdecl_maybe_friend (tree, bool);
|
extern tree pushdecl_maybe_friend (tree, bool);
|
||||||
extern void maybe_push_cleanup_level (tree);
|
extern void maybe_push_cleanup_level (tree);
|
||||||
|
|
@ -5299,7 +5298,7 @@ extern tree merge_exception_specifiers (tree, tree);
|
||||||
/* in mangle.c */
|
/* in mangle.c */
|
||||||
extern void init_mangle (void);
|
extern void init_mangle (void);
|
||||||
extern void mangle_decl (tree);
|
extern void mangle_decl (tree);
|
||||||
extern const char *mangle_type_string_for_rtti (tree);
|
extern const char *mangle_type_string (tree);
|
||||||
extern tree mangle_typeinfo_for_type (tree);
|
extern tree mangle_typeinfo_for_type (tree);
|
||||||
extern tree mangle_typeinfo_string_for_type (tree);
|
extern tree mangle_typeinfo_string_for_type (tree);
|
||||||
extern tree mangle_vtbl_for_type (tree);
|
extern tree mangle_vtbl_for_type (tree);
|
||||||
|
|
|
||||||
|
|
@ -105,10 +105,6 @@ typedef struct GTY(()) globals {
|
||||||
|
|
||||||
static GTY (()) globals G;
|
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. */
|
/* The obstack on which we build mangled names. */
|
||||||
static struct obstack *mangle_obstack;
|
static struct obstack *mangle_obstack;
|
||||||
|
|
||||||
|
|
@ -734,20 +730,6 @@ 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);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Lambdas can have a bit more context for mangling, specifically VAR_DECL
|
/* Lambdas can have a bit more context for mangling, specifically VAR_DECL
|
||||||
or PARM_DECL context, which doesn't belong in DECL_CONTEXT. */
|
or PARM_DECL context, which doesn't belong in DECL_CONTEXT. */
|
||||||
|
|
||||||
|
|
@ -791,18 +773,13 @@ write_name (tree decl, const int ignore_local_scope)
|
||||||
|
|
||||||
context = decl_mangling_context (decl);
|
context = decl_mangling_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
|
/* A decl in :: or ::std scope is treated specially. The former is
|
||||||
mangled using <unscoped-name> or <unscoped-template-name>, the
|
mangled using <unscoped-name> or <unscoped-template-name>, the
|
||||||
latter with a special substitution. Also, a name that is
|
latter with a special substitution. Also, a name that is
|
||||||
directly in a local function scope is also mangled with
|
directly in a local function scope is also mangled with
|
||||||
<unscoped-name> rather than a full <nested-name>. */
|
<unscoped-name> rather than a full <nested-name>. */
|
||||||
if (context == global_namespace
|
if (context == NULL
|
||||||
|
|| context == global_namespace
|
||||||
|| DECL_NAMESPACE_STD_P (context)
|
|| DECL_NAMESPACE_STD_P (context)
|
||||||
|| (ignore_local_scope && TREE_CODE (context) == FUNCTION_DECL))
|
|| (ignore_local_scope && TREE_CODE (context) == FUNCTION_DECL))
|
||||||
{
|
{
|
||||||
|
|
@ -820,9 +797,6 @@ write_name (tree decl, const int ignore_local_scope)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (context == error_mark_node)
|
|
||||||
context = global_namespace;
|
|
||||||
|
|
||||||
/* Handle local names, unless we asked not to (that is, invoked
|
/* Handle local names, unless we asked not to (that is, invoked
|
||||||
under <local-name>, to handle only the part of the name under
|
under <local-name>, to handle only the part of the name under
|
||||||
the local scope). */
|
the local scope). */
|
||||||
|
|
@ -835,10 +809,10 @@ write_name (tree decl, const int ignore_local_scope)
|
||||||
directly in that function's scope, either decl or one of
|
directly in that function's scope, either decl or one of
|
||||||
its enclosing scopes. */
|
its enclosing scopes. */
|
||||||
tree local_entity = decl;
|
tree local_entity = decl;
|
||||||
while (context != global_namespace)
|
while (context != NULL && context != global_namespace)
|
||||||
{
|
{
|
||||||
/* Make sure we're always dealing with decls. */
|
/* Make sure we're always dealing with decls. */
|
||||||
if (TYPE_P (context))
|
if (context != NULL && TYPE_P (context))
|
||||||
context = TYPE_NAME (context);
|
context = TYPE_NAME (context);
|
||||||
/* Is this a function? */
|
/* Is this a function? */
|
||||||
if (TREE_CODE (context) == FUNCTION_DECL
|
if (TREE_CODE (context) == FUNCTION_DECL
|
||||||
|
|
@ -883,6 +857,7 @@ write_unscoped_name (const tree decl)
|
||||||
/* If not, it should be either in the global namespace, or directly
|
/* If not, it should be either in the global namespace, or directly
|
||||||
in a local function scope. */
|
in a local function scope. */
|
||||||
gcc_assert (context == global_namespace
|
gcc_assert (context == global_namespace
|
||||||
|
|| context != NULL
|
||||||
|| TREE_CODE (context) == FUNCTION_DECL);
|
|| TREE_CODE (context) == FUNCTION_DECL);
|
||||||
|
|
||||||
write_unqualified_name (decl);
|
write_unqualified_name (decl);
|
||||||
|
|
@ -954,9 +929,6 @@ write_nested_name (const tree decl)
|
||||||
{
|
{
|
||||||
/* No, just use <prefix> */
|
/* No, just use <prefix> */
|
||||||
write_prefix (DECL_CONTEXT (decl));
|
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_unqualified_name (decl);
|
||||||
}
|
}
|
||||||
write_char ('E');
|
write_char ('E');
|
||||||
|
|
@ -3012,18 +2984,15 @@ mangle_decl (const tree decl)
|
||||||
SET_DECL_ASSEMBLER_NAME (decl, id);
|
SET_DECL_ASSEMBLER_NAME (decl, id);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Generate the mangled representation of TYPE for the typeinfo name. */
|
/* Generate the mangled representation of TYPE. */
|
||||||
|
|
||||||
const char *
|
const char *
|
||||||
mangle_type_string_for_rtti (const tree type)
|
mangle_type_string (const tree type)
|
||||||
{
|
{
|
||||||
const char *result;
|
const char *result;
|
||||||
|
|
||||||
start_mangling (type);
|
start_mangling (type);
|
||||||
/* Mangle in a fake anonymous namespace if necessary. */
|
|
||||||
fake_anon_scope = true;
|
|
||||||
write_type (type);
|
write_type (type);
|
||||||
fake_anon_scope = false;
|
|
||||||
result = finish_mangling (/*warn=*/false);
|
result = finish_mangling (/*warn=*/false);
|
||||||
if (DEBUG_MANGLE)
|
if (DEBUG_MANGLE)
|
||||||
fprintf (stderr, "mangle_type_string = '%s'\n\n", result);
|
fprintf (stderr, "mangle_type_string = '%s'\n\n", result);
|
||||||
|
|
|
||||||
|
|
@ -62,14 +62,19 @@ static GTY(()) tree anonymous_namespace_name;
|
||||||
|
|
||||||
/* Initialize anonymous_namespace_name if necessary, and return it. */
|
/* Initialize anonymous_namespace_name if necessary, and return it. */
|
||||||
|
|
||||||
tree
|
static tree
|
||||||
get_anonymous_namespace_name (void)
|
get_anonymous_namespace_name (void)
|
||||||
{
|
{
|
||||||
if (!anonymous_namespace_name)
|
if (!anonymous_namespace_name)
|
||||||
{
|
{
|
||||||
/* The anonymous namespace has to have a unique name
|
/* The anonymous namespace has to have a unique name
|
||||||
if typeinfo objects are being compared by name. */
|
if typeinfo objects are being compared by name. */
|
||||||
anonymous_namespace_name = get_file_function_name ("N");
|
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");
|
||||||
}
|
}
|
||||||
return anonymous_namespace_name;
|
return anonymous_namespace_name;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -102,7 +102,7 @@ VEC(tree,gc) *unemitted_tinfo_decls;
|
||||||
static GTY (()) VEC(tinfo_s,gc) *tinfo_descs;
|
static GTY (()) VEC(tinfo_s,gc) *tinfo_descs;
|
||||||
|
|
||||||
static tree ifnonnull (tree, tree);
|
static tree ifnonnull (tree, tree);
|
||||||
static tree tinfo_name (tree);
|
static tree tinfo_name (tree, bool);
|
||||||
static tree build_dynamic_cast_1 (tree, tree, tsubst_flags_t);
|
static tree build_dynamic_cast_1 (tree, tree, tsubst_flags_t);
|
||||||
static tree throw_bad_cast (void);
|
static tree throw_bad_cast (void);
|
||||||
static tree throw_bad_typeid (void);
|
static tree throw_bad_typeid (void);
|
||||||
|
|
@ -349,16 +349,30 @@ build_typeid (tree exp)
|
||||||
return exp;
|
return exp;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Generate the NTBS name of a type. */
|
/* Generate the NTBS name of a type. If MARK_PRIVATE, put a '*' in front so that
|
||||||
|
comparisons will be done by pointer rather than string comparison. */
|
||||||
static tree
|
static tree
|
||||||
tinfo_name (tree type)
|
tinfo_name (tree type, bool mark_private)
|
||||||
{
|
{
|
||||||
const char *name;
|
const char *name;
|
||||||
|
int length;
|
||||||
tree name_string;
|
tree name_string;
|
||||||
|
|
||||||
name = mangle_type_string_for_rtti (type);
|
name = mangle_type_string (type);
|
||||||
name_string = fix_string_type (build_string (strlen (name) + 1, name));
|
length = strlen (name);
|
||||||
return name_string;
|
|
||||||
|
if (mark_private)
|
||||||
|
{
|
||||||
|
/* Inject '*' at beginning of name to force pointer comparison. */
|
||||||
|
char* buf = (char*) XALLOCAVEC (char, length + 1);
|
||||||
|
buf[0] = '*';
|
||||||
|
memcpy (buf + 1, name, length);
|
||||||
|
name_string = build_string (length + 1, buf);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
name_string = build_string (length + 1, name);
|
||||||
|
|
||||||
|
return fix_string_type (name_string);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Return a VAR_DECL for the internal ABI defined type_info object for
|
/* Return a VAR_DECL for the internal ABI defined type_info object for
|
||||||
|
|
@ -839,13 +853,12 @@ tinfo_base_init (tinfo_s *ti, tree target)
|
||||||
tree vtable_ptr;
|
tree vtable_ptr;
|
||||||
|
|
||||||
{
|
{
|
||||||
tree name_name;
|
tree name_name, name_string;
|
||||||
|
|
||||||
/* Generate the NTBS array variable. */
|
/* Generate the NTBS array variable. */
|
||||||
tree name_type = build_cplus_array_type
|
tree name_type = build_cplus_array_type
|
||||||
(build_qualified_type (char_type_node, TYPE_QUAL_CONST),
|
(build_qualified_type (char_type_node, TYPE_QUAL_CONST),
|
||||||
NULL_TREE);
|
NULL_TREE);
|
||||||
tree name_string = tinfo_name (target);
|
|
||||||
|
|
||||||
/* Determine the name of the variable -- and remember with which
|
/* Determine the name of the variable -- and remember with which
|
||||||
type it is associated. */
|
type it is associated. */
|
||||||
|
|
@ -862,6 +875,7 @@ tinfo_base_init (tinfo_s *ti, tree target)
|
||||||
DECL_TINFO_P (name_decl) = 1;
|
DECL_TINFO_P (name_decl) = 1;
|
||||||
set_linkage_according_to_type (target, name_decl);
|
set_linkage_according_to_type (target, name_decl);
|
||||||
import_export_decl (name_decl);
|
import_export_decl (name_decl);
|
||||||
|
name_string = tinfo_name (target, !TREE_PUBLIC (name_decl));
|
||||||
DECL_INITIAL (name_decl) = name_string;
|
DECL_INITIAL (name_decl) = name_string;
|
||||||
mark_used (name_decl);
|
mark_used (name_decl);
|
||||||
pushdecl_top_level_and_finish (name_decl, name_string);
|
pushdecl_top_level_and_finish (name_decl, name_string);
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,9 @@
|
||||||
|
2009-10-30 Jerry Quinn <jlquinn@optonline.net>
|
||||||
|
|
||||||
|
* libsupc++/tinfo.cc (operator=(const type_info&)): Reapply 153734.
|
||||||
|
* libsupc++/typeinfo (type_info::name()): Likewise.
|
||||||
|
* libsupc++/tinfo2.cc (before): Likewise.
|
||||||
|
|
||||||
2009-10-30 Paolo Carlini <paolo.carlini@oracle.com>
|
2009-10-30 Paolo Carlini <paolo.carlini@oracle.com>
|
||||||
|
|
||||||
* include/bits/random.h: Fix typo in static_assert text.
|
* include/bits/random.h: Fix typo in static_assert text.
|
||||||
|
|
|
||||||
|
|
@ -41,7 +41,8 @@ operator== (const std::type_info& arg) const
|
||||||
#if __GXX_MERGED_TYPEINFO_NAMES
|
#if __GXX_MERGED_TYPEINFO_NAMES
|
||||||
return name () == arg.name ();
|
return name () == arg.name ();
|
||||||
#else
|
#else
|
||||||
return (&arg == this) || (__builtin_strcmp (name (), arg.name ()) == 0);
|
return (&arg == this)
|
||||||
|
|| (name ()[0] != '*' && (__builtin_strcmp (name (), arg.name ()) == 0));
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -37,7 +37,8 @@ type_info::before (const type_info &arg) const
|
||||||
#if __GXX_MERGED_TYPEINFO_NAMES
|
#if __GXX_MERGED_TYPEINFO_NAMES
|
||||||
return name () < arg.name ();
|
return name () < arg.name ();
|
||||||
#else
|
#else
|
||||||
return __builtin_strcmp (name (), arg.name ()) < 0;
|
return (name ()[0] == '*') ? name () < arg.name ()
|
||||||
|
: __builtin_strcmp (name (), arg.name ()) < 0;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -94,7 +94,7 @@ namespace std
|
||||||
/** Returns an @e implementation-defined byte string; this is not
|
/** Returns an @e implementation-defined byte string; this is not
|
||||||
* portable between compilers! */
|
* portable between compilers! */
|
||||||
const char* name() const
|
const char* name() const
|
||||||
{ return __name; }
|
{ return __name[0] == '*' ? __name + 1 : __name; }
|
||||||
|
|
||||||
#if !__GXX_TYPEINFO_EQUALITY_INLINE
|
#if !__GXX_TYPEINFO_EQUALITY_INLINE
|
||||||
// In old abi, or when weak symbols are not supported, there can
|
// In old abi, or when weak symbols are not supported, there can
|
||||||
|
|
@ -110,12 +110,15 @@ namespace std
|
||||||
// we can run into cases where type_info names aren't merged,
|
// we can run into cases where type_info names aren't merged,
|
||||||
// so we still need to do string comparison.
|
// so we still need to do string comparison.
|
||||||
bool before(const type_info& __arg) const
|
bool before(const type_info& __arg) const
|
||||||
{ return __builtin_strcmp (__name, __arg.__name) < 0; }
|
{ return (__name[0] == '*' && __arg.__name[0] == '*')
|
||||||
|
? __name < __arg.__name
|
||||||
|
: __builtin_strcmp (__name, __arg.__name) < 0; }
|
||||||
|
|
||||||
bool operator==(const type_info& __arg) const
|
bool operator==(const type_info& __arg) const
|
||||||
{
|
{
|
||||||
return ((__name == __arg.__name)
|
return ((__name == __arg.__name)
|
||||||
|| __builtin_strcmp (__name, __arg.__name) == 0);
|
|| (__name[0] != '*' &&
|
||||||
|
__builtin_strcmp (__name, __arg.__name) == 0));
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
// On some targets we can rely on type_info's NTBS being unique,
|
// On some targets we can rely on type_info's NTBS being unique,
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue