From: Nathan Sidwell Date: Wed, 2 Dec 2020 16:27:53 +0000 (-0800) Subject: c++: RTTI accessors for modules X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=af4180513836806e2b351d516af55f6664c8821a;p=gcc.git c++: RTTI accessors for modules The module machinery needs to serialize tinfo types and vars by meaning, not literally. This adds the necessary pieces to rtti. gcc/cp/ * cp-tree.h (DECL_TINFO_P): Also for TYPE_DECLs. (get_tinfo_decl_direct): Declare. (get_pseudo_tinfo_index, get_pseudo_tinfo_type): Declare. * rtti.c (get_tinfo_decl_direct): Externalize. (get_tinfo_desc): Set DECL_TINFO_P on the typedef. (get_pseudo_tinfo_index, get_pseudo_tinfo_type): New. --- diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index 4eaa10bc7fd..d69110f7ab6 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -494,7 +494,7 @@ extern GTY(()) tree cp_global_trees[CPTI_MAX]; 4: IDENTIFIER_MARKED (IDENTIFIER_NODEs) TREE_HAS_CONSTRUCTOR (in INDIRECT_REF, SAVE_EXPR, CONSTRUCTOR, CALL_EXPR, or FIELD_DECL). - DECL_TINFO_P (in VAR_DECL) + DECL_TINFO_P (in VAR_DECL, TYPE_DECL) FUNCTION_REF_QUALIFIED (in FUNCTION_TYPE, METHOD_TYPE) OVL_LOOKUP_P (in OVERLOAD) LOOKUP_FOUND_P (in RECORD_TYPE, UNION_TYPE, ENUMERAL_TYPE, NAMESPACE_DECL) @@ -3350,7 +3350,8 @@ struct GTY(()) lang_decl { /* 1 iff VAR_DECL node NODE is a type-info decl. This flag is set for both the primary typeinfo object and the associated NTBS name. */ -#define DECL_TINFO_P(NODE) TREE_LANG_FLAG_4 (VAR_DECL_CHECK (NODE)) +#define DECL_TINFO_P(NODE) \ + TREE_LANG_FLAG_4 (TREE_CHECK2 (NODE,VAR_DECL,TYPE_DECL)) /* 1 iff VAR_DECL node NODE is virtual table or VTT. We forward to DECL_VIRTUAL_P from the common code, as that has the semantics we @@ -7025,6 +7026,7 @@ extern GTY(()) vec *unemitted_tinfo_decls; extern void init_rtti_processing (void); extern tree build_typeid (tree, tsubst_flags_t); +extern tree get_tinfo_decl_direct (tree, tree, int); extern tree get_tinfo_decl (tree); extern tree get_typeid (tree, tsubst_flags_t); extern tree build_headof (tree); @@ -7032,6 +7034,8 @@ extern tree build_dynamic_cast (location_t, tree, tree, tsubst_flags_t); extern void emit_support_tinfos (void); extern bool emit_tinfo_decl (tree); +extern unsigned get_pseudo_tinfo_index (tree); +extern tree get_pseudo_tinfo_type (unsigned); /* in search.c */ extern bool accessible_base_p (tree, tree, bool); diff --git a/gcc/cp/rtti.c b/gcc/cp/rtti.c index 887aae31bf6..d6288622246 100644 --- a/gcc/cp/rtti.c +++ b/gcc/cp/rtti.c @@ -123,7 +123,6 @@ 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); @@ -431,7 +430,7 @@ get_tinfo_decl (tree type) /* 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 +tree get_tinfo_decl_direct (tree type, tree name, int pseudo_ix) { /* For a class type, the variable is cached in the type node @@ -1479,6 +1478,7 @@ get_tinfo_desc (unsigned ix) 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); + DECL_TINFO_P (TYPE_NAME (pseudo_type)) = true; xref_basetypes (pseudo_type, /*bases=*/NULL_TREE); res->type = cp_build_qualified_type (pseudo_type, TYPE_QUAL_CONST); @@ -1491,6 +1491,36 @@ get_tinfo_desc (unsigned ix) return res; } +/* Return an identifying index for the pseudo type_info TYPE. + We wrote the index at the end of the name, so just scan it from + there. This isn't critical, as it's only on the first use of this + type during module stream out. */ + +unsigned +get_pseudo_tinfo_index (tree type) +{ + tree name = DECL_NAME (TYPE_NAME (type)); + unsigned ix = 0, scale = 1; + size_t len = IDENTIFIER_LENGTH (name); + const char *ptr = IDENTIFIER_POINTER (name) + len; + + for (; *--ptr != '_'; scale *= 10) + { + len--; + gcc_checking_assert (len && ISDIGIT (*ptr)); + ix += (*ptr - '0') * scale; + } + + gcc_assert (len != IDENTIFIER_LENGTH (name)); + return ix; +} + +tree +get_pseudo_tinfo_type (unsigned ix) +{ + return get_tinfo_desc (ix)->type; +} + /* We lazily create the type info types. */ static void