From: Nathan Sidwell Date: Tue, 3 Nov 2020 13:08:18 +0000 (-0800) Subject: c++: rtti cleanups X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=fbc3f847438f2297c31d9eaaec5e662192acb779;p=gcc.git 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. --- diff --git a/gcc/cp/rtti.c b/gcc/cp/rtti.c index 7c4bff76e8c..887aae31bf6 100644 --- a/gcc/cp/rtti.c +++ b/gcc/cp/rtti.c @@ -123,6 +123,7 @@ static GTY (()) vec *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)); + + if (!name) + name = mangle_typeinfo_for_type (type); - 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;