c++: rtti cleanups

Here are a few cleanups from the modules branch.  Generally some RAII,
and a bit of lazy namespace pushing.

	gcc/cp/
	* rtti.c (init_rtti_processing): Move var decl to its init.
	(get_tinfo_decl): Likewise.  Break out creation to called helper
	...
	(get_tinfo_decl_direct): ... here.
	(build_dynamic_cast_1): Move var decls to their initializers.
	(tinfo_base_init): Set decl's location to BUILTINS_LOCATION.
	(get_tinfo_desc): Only push ABI namespace when needed.  Set type's
	context.
This commit is contained in:
Nathan Sidwell 2020-11-03 05:08:18 -08:00
parent 918e8b10a7
commit fbc3f84743

View file

@ -123,6 +123,7 @@ static GTY (()) vec<tinfo_s, va_gc> *tinfo_descs;
static tree ifnonnull (tree, tree, tsubst_flags_t);
static tree tinfo_name (tree, bool);
static tree get_tinfo_decl_direct (tree type, tree name, int pseudo_ix);
static tree build_dynamic_cast_1 (location_t, tree, tree, tsubst_flags_t);
static tree throw_bad_cast (void);
static tree throw_bad_typeid (void);
@ -166,10 +167,8 @@ pop_abi_namespace (void)
void
init_rtti_processing (void)
{
tree type_info_type;
push_nested_namespace (std_node);
type_info_type = xref_tag (class_type, get_identifier ("type_info"));
tree type_info_type = xref_tag (class_type, get_identifier ("type_info"));
pop_nested_namespace (std_node);
const_type_info_type_node
= cp_build_qualified_type (type_info_type, TYPE_QUAL_CONST);
@ -414,9 +413,6 @@ tinfo_name (tree type, bool mark_private)
tree
get_tinfo_decl (tree type)
{
tree name;
tree d;
if (variably_modified_type_p (type, /*fn=*/NULL_TREE))
{
error ("cannot create type information for type %qT because "
@ -429,25 +425,41 @@ get_tinfo_decl (tree type)
type = build_function_type (TREE_TYPE (type),
TREE_CHAIN (TYPE_ARG_TYPES (type)));
type = complete_type (type);
return get_tinfo_decl_direct (type, NULL, -1);
}
/* Get or create a tinfo VAR_DECL directly from the provided information.
The caller must have already checked it is valid to do so. */
static tree
get_tinfo_decl_direct (tree type, tree name, int pseudo_ix)
{
/* For a class type, the variable is cached in the type node
itself. */
tree d = NULL_TREE;
gcc_checking_assert (TREE_CODE (type) != METHOD_TYPE);
if (pseudo_ix < 0)
type = complete_type (type);
if (CLASS_TYPE_P (type))
{
d = CLASSTYPE_TYPEINFO_VAR (TYPE_MAIN_VARIANT (type));
if (d)
return d;
}
d = CLASSTYPE_TYPEINFO_VAR (TYPE_MAIN_VARIANT (type));
name = mangle_typeinfo_for_type (type);
if (!name)
name = mangle_typeinfo_for_type (type);
if (!CLASS_TYPE_P (type))
d = get_global_binding (name);
d = get_global_binding (name);
if (!d)
{
int ix = get_pseudo_ti_index (type);
const tinfo_s *ti = get_tinfo_desc (ix);
/* Create it. */
if (pseudo_ix < 0)
pseudo_ix = get_pseudo_ti_index (type);
const tinfo_s *ti = get_tinfo_desc (pseudo_ix);
d = build_lang_decl (VAR_DECL, name, ti->type);
SET_DECL_ASSEMBLER_NAME (d, name);
/* Remember the type it is for. */
@ -754,23 +766,21 @@ build_dynamic_cast_1 (location_t loc, tree type, tree expr,
dcast_fn = dynamic_cast_node;
if (!dcast_fn)
{
tree tmp;
tree tinfo_ptr;
const char *name;
push_abi_namespace ();
tinfo_ptr = xref_tag (class_type,
get_identifier ("__class_type_info"));
tinfo_ptr = build_pointer_type
(cp_build_qualified_type
(tinfo_ptr, TYPE_QUAL_CONST));
name = "__dynamic_cast";
tmp = build_function_type_list (ptr_type_node,
const_ptr_type_node,
tinfo_ptr, tinfo_ptr,
ptrdiff_type_node, NULL_TREE);
dcast_fn = build_library_fn_ptr (name, tmp,
ECF_LEAF | ECF_PURE | ECF_NOTHROW);
tree tinfo_ptr = xref_tag (class_type,
get_identifier ("__class_type_info"));
tinfo_ptr = cp_build_qualified_type (tinfo_ptr, TYPE_QUAL_CONST);
tinfo_ptr = build_pointer_type (tinfo_ptr);
const char *fn_name = "__dynamic_cast";
/* void *() (void const *, __class_type_info const *,
__class_type_info const *, ptrdiff_t) */
tree fn_type = (build_function_type_list
(ptr_type_node, const_ptr_type_node,
tinfo_ptr, tinfo_ptr, ptrdiff_type_node,
NULL_TREE));
dcast_fn = (build_library_fn_ptr
(fn_name, fn_type, ECF_LEAF | ECF_PURE | ECF_NOTHROW));
pop_abi_namespace ();
dynamic_cast_node = dcast_fn;
}
@ -947,6 +957,8 @@ tinfo_base_init (tinfo_s *ti, tree target)
{
push_abi_namespace ();
tree real_type = xref_tag (class_type, ti->name);
tree real_decl = TYPE_NAME (real_type);
DECL_SOURCE_LOCATION (real_decl) = BUILTINS_LOCATION;
pop_abi_namespace ();
if (!COMPLETE_TYPE_P (real_type))
@ -1450,8 +1462,6 @@ get_tinfo_desc (unsigned ix)
}
}
push_abi_namespace ();
/* Generate the pseudo type name. */
const char *real_name = tinfo_names[ix < TK_VMI_CLASS_TYPES
? ix : unsigned (TK_VMI_CLASS_TYPES)];
@ -1468,6 +1478,7 @@ get_tinfo_desc (unsigned ix)
/* Pass the fields chained in reverse. */
finish_builtin_struct (pseudo_type, pseudo_name, fields, NULL_TREE);
CLASSTYPE_AS_BASE (pseudo_type) = pseudo_type;
DECL_CONTEXT (TYPE_NAME (pseudo_type)) = FROB_CONTEXT (global_namespace);
xref_basetypes (pseudo_type, /*bases=*/NULL_TREE);
res->type = cp_build_qualified_type (pseudo_type, TYPE_QUAL_CONST);
@ -1477,7 +1488,6 @@ get_tinfo_desc (unsigned ix)
internal linkage. */
TREE_PUBLIC (TYPE_MAIN_DECL (res->type)) = 1;
pop_abi_namespace ();
return res;
}
@ -1608,12 +1618,10 @@ emit_support_tinfos (void)
bool
emit_tinfo_decl (tree decl)
{
tree type = TREE_TYPE (DECL_NAME (decl));
int in_library = typeinfo_in_lib_p (type);
gcc_assert (DECL_TINFO_P (decl));
if (in_library)
tree type = TREE_TYPE (DECL_NAME (decl));
if (typeinfo_in_lib_p (type))
{
if (doing_runtime)
DECL_EXTERNAL (decl) = 0;