Make rtti lazier
Make rtti lazier * rtti.c (enum tinfo_kind): Add TK_DERIVED_TYPES, TK_VMI_CLASS_TYPES, TK_MAX. Delete TK_FIXED. (tinfo_names): New. (typeid_ok_p): Add quotes to error messages. Use get_tinfo_desc. (get_tinfo_decl): Use get_tinfo_desc. (get_pseudo_ti_init): Likewise. Adjust VMI construction. (create_pseudo_type_info): Delete. (get_pseudo_ti_index): Just determine the index. (get_tinfo_desc): New. Create all types lazily. (create_tinfo_types): Just allocate the descriptor array. (emit_support_tinfos): Use non-inserting type lookup. Set builtin location. From-SVN: r249258
This commit is contained in:
parent
bfe8a528aa
commit
ac9a1c7ec5
@ -1,3 +1,19 @@
|
||||
2017-06-16 Nathan Sidwell <nathan@acm.org>
|
||||
|
||||
Make rtti lazier
|
||||
* rtti.c (enum tinfo_kind): Add TK_DERIVED_TYPES,
|
||||
TK_VMI_CLASS_TYPES, TK_MAX. Delete TK_FIXED.
|
||||
(tinfo_names): New.
|
||||
(typeid_ok_p): Add quotes to error messages. Use get_tinfo_desc.
|
||||
(get_tinfo_decl): Use get_tinfo_desc.
|
||||
(get_pseudo_ti_init): Likewise. Adjust VMI construction.
|
||||
(create_pseudo_type_info): Delete.
|
||||
(get_pseudo_ti_index): Just determine the index.
|
||||
(get_tinfo_desc): New. Create all types lazily.
|
||||
(create_tinfo_types): Just allocate the descriptor array.
|
||||
(emit_support_tinfos): Use non-inserting type lookup. Set builtin
|
||||
location.
|
||||
|
||||
2017-06-15 Martin Sebor <msebor@redhat.com>
|
||||
|
||||
PR c++/80560
|
||||
|
493
gcc/cp/rtti.c
493
gcc/cp/rtti.c
@ -75,7 +75,8 @@ enum tinfo_kind
|
||||
{
|
||||
TK_TYPE_INFO_TYPE, /* abi::__type_info_pseudo */
|
||||
TK_BASE_TYPE, /* abi::__base_class_type_info */
|
||||
TK_BUILTIN_TYPE, /* abi::__fundamental_type_info */
|
||||
TK_DERIVED_TYPES, /* Start of types derived from abi::__type_info */
|
||||
TK_BUILTIN_TYPE = TK_DERIVED_TYPES, /* abi::__fundamental_type_info */
|
||||
TK_ARRAY_TYPE, /* abi::__array_type_info */
|
||||
TK_FUNCTION_TYPE, /* abi::__function_type_info */
|
||||
TK_ENUMERAL_TYPE, /* abi::__enum_type_info */
|
||||
@ -83,8 +84,26 @@ enum tinfo_kind
|
||||
TK_POINTER_MEMBER_TYPE, /* abi::__pointer_to_member_type_info */
|
||||
TK_CLASS_TYPE, /* abi::__class_type_info */
|
||||
TK_SI_CLASS_TYPE, /* abi::__si_class_type_info */
|
||||
TK_FIXED /* end of fixed descriptors. */
|
||||
/* ... abi::__vmi_type_info<I> */
|
||||
TK_VMI_CLASS_TYPES, /* abi::__vmi_class_type_info<int> */
|
||||
TK_MAX
|
||||
};
|
||||
|
||||
/* Names of the tinfo types. Must be same order as TK enumeration
|
||||
above. */
|
||||
|
||||
static const char *const tinfo_names[TK_MAX] =
|
||||
{
|
||||
"__type_info",
|
||||
"__base_class_type_info",
|
||||
"__fundamental_type_info",
|
||||
"__array_type_info",
|
||||
"__function_type_info",
|
||||
"__enum_type_info",
|
||||
"__pointer_type_info",
|
||||
"__pointer_to_member_type_info",
|
||||
"__class_type_info",
|
||||
"__si_class_type_info",
|
||||
"__vmi_class_type_info"
|
||||
};
|
||||
|
||||
/* Helper macro to get maximum scalar-width of pointer or of the 'long'-type.
|
||||
@ -115,9 +134,9 @@ static tree generic_initializer (tinfo_s *, tree);
|
||||
static tree ptr_initializer (tinfo_s *, tree);
|
||||
static tree ptm_initializer (tinfo_s *, tree);
|
||||
static tree class_initializer (tinfo_s *, tree, unsigned, ...);
|
||||
static void create_pseudo_type_info (int, const char *, ...);
|
||||
static tree get_pseudo_ti_init (tree, unsigned);
|
||||
static unsigned get_pseudo_ti_index (tree);
|
||||
static tinfo_s *get_tinfo_desc (unsigned);
|
||||
static void create_tinfo_types (void);
|
||||
static bool typeinfo_in_lib_p (tree);
|
||||
|
||||
@ -289,30 +308,27 @@ get_tinfo_decl_dynamic (tree exp, tsubst_flags_t complain)
|
||||
static bool
|
||||
typeid_ok_p (void)
|
||||
{
|
||||
tree pseudo_type_info, type_info_type;
|
||||
|
||||
if (! flag_rtti)
|
||||
{
|
||||
error ("cannot use typeid with -fno-rtti");
|
||||
error ("cannot use %<typeid%> with -fno-rtti");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!COMPLETE_TYPE_P (const_type_info_type_node))
|
||||
{
|
||||
error ("must #include <typeinfo> before using typeid");
|
||||
error ("must %<#include <typeinfo>%> before using %<typeid%>");
|
||||
return false;
|
||||
}
|
||||
|
||||
pseudo_type_info = (*tinfo_descs)[TK_TYPE_INFO_TYPE].type;
|
||||
type_info_type = TYPE_MAIN_VARIANT (const_type_info_type_node);
|
||||
tree pseudo = TYPE_MAIN_VARIANT (get_tinfo_desc (TK_TYPE_INFO_TYPE)->type);
|
||||
tree real = TYPE_MAIN_VARIANT (const_type_info_type_node);
|
||||
|
||||
/* Make sure abi::__type_info_pseudo has the same alias set
|
||||
as std::type_info. */
|
||||
if (! TYPE_ALIAS_SET_KNOWN_P (pseudo_type_info))
|
||||
TYPE_ALIAS_SET (pseudo_type_info) = get_alias_set (type_info_type);
|
||||
if (! TYPE_ALIAS_SET_KNOWN_P (pseudo))
|
||||
TYPE_ALIAS_SET (pseudo) = get_alias_set (real);
|
||||
else
|
||||
gcc_assert (TYPE_ALIAS_SET (pseudo_type_info)
|
||||
== get_alias_set (type_info_type));
|
||||
gcc_assert (TYPE_ALIAS_SET (pseudo) == get_alias_set (real));
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -428,8 +444,8 @@ get_tinfo_decl (tree type)
|
||||
if (!d)
|
||||
{
|
||||
int ix = get_pseudo_ti_index (type);
|
||||
tinfo_s *ti = &(*tinfo_descs)[ix];
|
||||
|
||||
const tinfo_s *ti = get_tinfo_desc (ix);
|
||||
|
||||
d = build_lang_decl (VAR_DECL, name, ti->type);
|
||||
SET_DECL_ASSEMBLER_NAME (d, name);
|
||||
/* Remember the type it is for. */
|
||||
@ -1105,7 +1121,7 @@ typeinfo_in_lib_p (tree type)
|
||||
static tree
|
||||
get_pseudo_ti_init (tree type, unsigned tk_index)
|
||||
{
|
||||
tinfo_s *ti = &(*tinfo_descs)[tk_index];
|
||||
tinfo_s *ti = get_tinfo_desc (tk_index);
|
||||
|
||||
gcc_assert (at_eof);
|
||||
switch (tk_index)
|
||||
@ -1140,22 +1156,18 @@ get_pseudo_ti_init (tree type, unsigned tk_index)
|
||||
int hint = ((CLASSTYPE_REPEATED_BASE_P (type) << 0)
|
||||
| (CLASSTYPE_DIAMOND_SHAPED_P (type) << 1));
|
||||
tree binfo = TYPE_BINFO (type);
|
||||
int nbases = BINFO_N_BASE_BINFOS (binfo);
|
||||
unsigned nbases = BINFO_N_BASE_BINFOS (binfo);
|
||||
vec<tree, va_gc> *base_accesses = BINFO_BASE_ACCESSES (binfo);
|
||||
tree offset_type = LONGPTR_T;
|
||||
tree base_inits = NULL_TREE;
|
||||
int ix;
|
||||
vec<constructor_elt, va_gc> *init_vec = NULL;
|
||||
constructor_elt *e;
|
||||
|
||||
gcc_assert (tk_index >= TK_FIXED);
|
||||
gcc_assert (tk_index - TK_VMI_CLASS_TYPES + 1 == nbases);
|
||||
|
||||
vec_safe_grow (init_vec, nbases);
|
||||
/* Generate the base information initializer. */
|
||||
for (ix = nbases; ix--;)
|
||||
for (unsigned ix = nbases; ix--;)
|
||||
{
|
||||
tree base_binfo = BINFO_BASE_BINFO (binfo, ix);
|
||||
tree base_init;
|
||||
int flags = 0;
|
||||
tree tinfo;
|
||||
tree offset;
|
||||
@ -1185,12 +1197,12 @@ get_pseudo_ti_init (tree type, unsigned tk_index)
|
||||
vec_alloc (v, 2);
|
||||
CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, tinfo);
|
||||
CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, offset);
|
||||
base_init = build_constructor (init_list_type_node, v);
|
||||
e = &(*init_vec)[ix];
|
||||
tree base_init = build_constructor (init_list_type_node, v);
|
||||
constructor_elt *e = &(*init_vec)[ix];
|
||||
e->index = NULL_TREE;
|
||||
e->value = base_init;
|
||||
}
|
||||
base_inits = build_constructor (init_list_type_node, init_vec);
|
||||
tree base_inits = build_constructor (init_list_type_node, init_vec);
|
||||
|
||||
/* get_tinfo_ptr might have reallocated the tinfo_descs vector. */
|
||||
ti = &(*tinfo_descs)[tk_index];
|
||||
@ -1202,69 +1214,6 @@ get_pseudo_ti_init (tree type, unsigned tk_index)
|
||||
}
|
||||
}
|
||||
|
||||
/* Generate the RECORD_TYPE containing the data layout of a type_info
|
||||
derivative as used by the runtime. This layout must be consistent with
|
||||
that defined in the runtime support. Also generate the VAR_DECL for the
|
||||
type's vtable. We explicitly manage the vtable member, and name it for
|
||||
real type as used in the runtime. The RECORD type has a different name,
|
||||
to avoid collisions. Return a TREE_LIST who's TINFO_PSEUDO_TYPE
|
||||
is the generated type and TINFO_VTABLE_NAME is the name of the
|
||||
vtable. We have to delay generating the VAR_DECL of the vtable
|
||||
until the end of the translation, when we'll have seen the library
|
||||
definition, if there was one.
|
||||
|
||||
REAL_NAME is the runtime's name of the type. Trailing arguments are
|
||||
additional FIELD_DECL's for the structure. The final argument must be
|
||||
NULL. */
|
||||
|
||||
static void
|
||||
create_pseudo_type_info (int tk, const char *real_name, ...)
|
||||
{
|
||||
tinfo_s *ti;
|
||||
tree pseudo_type;
|
||||
char *pseudo_name;
|
||||
tree fields;
|
||||
tree field_decl;
|
||||
va_list ap;
|
||||
|
||||
va_start (ap, real_name);
|
||||
|
||||
/* Generate the pseudo type name. */
|
||||
pseudo_name = (char *) alloca (strlen (real_name) + 30);
|
||||
strcpy (pseudo_name, real_name);
|
||||
strcat (pseudo_name, "_pseudo");
|
||||
if (tk >= TK_FIXED)
|
||||
sprintf (pseudo_name + strlen (pseudo_name), "%d", tk - TK_FIXED);
|
||||
|
||||
/* First field is the pseudo type_info base class. */
|
||||
fields = build_decl (input_location,
|
||||
FIELD_DECL, NULL_TREE,
|
||||
(*tinfo_descs)[TK_TYPE_INFO_TYPE].type);
|
||||
|
||||
/* Now add the derived fields. */
|
||||
while ((field_decl = va_arg (ap, tree)))
|
||||
{
|
||||
DECL_CHAIN (field_decl) = fields;
|
||||
fields = field_decl;
|
||||
}
|
||||
|
||||
/* Create the pseudo type. */
|
||||
pseudo_type = make_class_type (RECORD_TYPE);
|
||||
finish_builtin_struct (pseudo_type, pseudo_name, fields, NULL_TREE);
|
||||
CLASSTYPE_AS_BASE (pseudo_type) = pseudo_type;
|
||||
|
||||
ti = &(*tinfo_descs)[tk];
|
||||
ti->type = cp_build_qualified_type (pseudo_type, TYPE_QUAL_CONST);
|
||||
ti->name = get_identifier (real_name);
|
||||
ti->vtable = NULL_TREE;
|
||||
|
||||
/* Pretend this is public so determine_visibility doesn't give vtables
|
||||
internal linkage. */
|
||||
TREE_PUBLIC (TYPE_MAIN_DECL (ti->type)) = 1;
|
||||
|
||||
va_end (ap);
|
||||
}
|
||||
|
||||
/* Return the index of a pseudo type info type node used to describe
|
||||
TYPE. TYPE must be a complete type (or cv void), except at the end
|
||||
of the translation unit. */
|
||||
@ -1299,23 +1248,16 @@ get_pseudo_ti_index (tree type)
|
||||
case UNION_TYPE:
|
||||
case RECORD_TYPE:
|
||||
if (TYPE_PTRMEMFUNC_P (type))
|
||||
{
|
||||
ix = TK_POINTER_MEMBER_TYPE;
|
||||
break;
|
||||
}
|
||||
ix = TK_POINTER_MEMBER_TYPE;
|
||||
else if (!COMPLETE_TYPE_P (type))
|
||||
{
|
||||
if (!at_eof)
|
||||
cxx_incomplete_type_error (NULL_TREE, type);
|
||||
ix = TK_CLASS_TYPE;
|
||||
break;
|
||||
}
|
||||
else if (!TYPE_BINFO (type)
|
||||
|| !BINFO_N_BASE_BINFOS (TYPE_BINFO (type)))
|
||||
{
|
||||
ix = TK_CLASS_TYPE;
|
||||
break;
|
||||
}
|
||||
ix = TK_CLASS_TYPE;
|
||||
else
|
||||
{
|
||||
tree binfo = TYPE_BINFO (type);
|
||||
@ -1327,49 +1269,13 @@ get_pseudo_ti_index (tree type)
|
||||
&& (*base_accesses)[0] == access_public_node
|
||||
&& !BINFO_VIRTUAL_P (base_binfo)
|
||||
&& integer_zerop (BINFO_OFFSET (base_binfo)))
|
||||
{
|
||||
/* single non-virtual public. */
|
||||
ix = TK_SI_CLASS_TYPE;
|
||||
break;
|
||||
}
|
||||
/* single non-virtual public. */
|
||||
ix = TK_SI_CLASS_TYPE;
|
||||
else
|
||||
{
|
||||
tinfo_s *ti;
|
||||
tree array_domain, base_array;
|
||||
|
||||
ix = TK_FIXED + num_bases;
|
||||
if (vec_safe_length (tinfo_descs) <= ix)
|
||||
{
|
||||
/* too short, extend. */
|
||||
unsigned len = vec_safe_length (tinfo_descs);
|
||||
|
||||
vec_safe_grow (tinfo_descs, ix + 1);
|
||||
while (tinfo_descs->iterate (len++, &ti))
|
||||
ti->type = ti->vtable = ti->name = NULL_TREE;
|
||||
}
|
||||
else if ((*tinfo_descs)[ix].type)
|
||||
/* already created. */
|
||||
break;
|
||||
|
||||
/* Create the array of __base_class_type_info entries. */
|
||||
array_domain = build_index_type (size_int (num_bases - 1));
|
||||
base_array = build_array_type ((*tinfo_descs)[TK_BASE_TYPE].type,
|
||||
array_domain);
|
||||
|
||||
push_abi_namespace ();
|
||||
create_pseudo_type_info
|
||||
(ix, "__vmi_class_type_info",
|
||||
build_decl (input_location,
|
||||
FIELD_DECL, NULL_TREE, integer_type_node),
|
||||
build_decl (input_location,
|
||||
FIELD_DECL, NULL_TREE, integer_type_node),
|
||||
build_decl (input_location,
|
||||
FIELD_DECL, NULL_TREE, base_array),
|
||||
NULL);
|
||||
pop_abi_namespace ();
|
||||
break;
|
||||
}
|
||||
ix = TK_VMI_CLASS_TYPES + num_bases - 1;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
ix = TK_BUILTIN_TYPE;
|
||||
break;
|
||||
@ -1377,107 +1283,202 @@ get_pseudo_ti_index (tree type)
|
||||
return ix;
|
||||
}
|
||||
|
||||
/* Make sure the required builtin types exist for generating the type_info
|
||||
variable definitions. */
|
||||
/* Return pointer to tinfo descriptor. Possibly creating the tinfo
|
||||
descriptor in the first place. */
|
||||
|
||||
static tinfo_s *
|
||||
get_tinfo_desc (unsigned ix)
|
||||
{
|
||||
unsigned len = tinfo_descs->length ();
|
||||
|
||||
if (len <= ix)
|
||||
{
|
||||
/* too short, extend. */
|
||||
len = ix + 1 - len;
|
||||
vec_safe_reserve (tinfo_descs, len);
|
||||
tinfo_s elt;
|
||||
elt.type = elt.vtable = elt.name = NULL_TREE;
|
||||
while (len--)
|
||||
tinfo_descs->quick_push (elt);
|
||||
}
|
||||
|
||||
tinfo_s *res = &(*tinfo_descs)[ix];
|
||||
|
||||
if (res->type)
|
||||
return res;
|
||||
|
||||
/* Ok, we have to create it. This layout must be consistent with
|
||||
that defined in the runtime support. We explicitly manage the
|
||||
vtable member, and name it for real type as used in the runtime.
|
||||
The RECORD type has a different name, to avoid collisions. We
|
||||
have to delay generating the VAR_DECL of the vtable until the end
|
||||
of the translation, when we'll have seen the library definition,
|
||||
if there was one. */
|
||||
|
||||
/* Fields to add, chained in reverse order. */
|
||||
tree fields = NULL_TREE;
|
||||
|
||||
if (ix >= TK_DERIVED_TYPES)
|
||||
{
|
||||
/* First field is the pseudo type_info base class. */
|
||||
tree fld_base = build_decl (BUILTINS_LOCATION, FIELD_DECL, NULL_TREE,
|
||||
get_tinfo_desc (TK_TYPE_INFO_TYPE)->type);
|
||||
|
||||
DECL_CHAIN (fld_base) = fields;
|
||||
fields = fld_base;
|
||||
}
|
||||
|
||||
switch (ix)
|
||||
{
|
||||
case TK_TYPE_INFO_TYPE:
|
||||
{
|
||||
tree fld_ptr = build_decl (BUILTINS_LOCATION, FIELD_DECL,
|
||||
NULL_TREE, const_ptr_type_node);
|
||||
fields = fld_ptr;
|
||||
|
||||
tree fld_str = build_decl (BUILTINS_LOCATION, FIELD_DECL,
|
||||
NULL_TREE, const_string_type_node);
|
||||
DECL_CHAIN (fld_str) = fields;
|
||||
fields = fld_str;
|
||||
break;
|
||||
}
|
||||
|
||||
case TK_BASE_TYPE:
|
||||
{
|
||||
/* Base class internal helper. Pointer to base type, offset to
|
||||
base, flags. */
|
||||
tree fld_ptr = build_decl (BUILTINS_LOCATION, FIELD_DECL,
|
||||
NULL_TREE, type_info_ptr_type);
|
||||
DECL_CHAIN (fld_ptr) = fields;
|
||||
fields = fld_ptr;
|
||||
|
||||
tree fld_flag = build_decl (BUILTINS_LOCATION, FIELD_DECL,
|
||||
NULL_TREE, LONGPTR_T);
|
||||
DECL_CHAIN (fld_flag) = fields;
|
||||
fields = fld_flag;
|
||||
break;
|
||||
}
|
||||
|
||||
case TK_BUILTIN_TYPE:
|
||||
/* Fundamental type_info */
|
||||
break;
|
||||
|
||||
case TK_ARRAY_TYPE:
|
||||
break;
|
||||
|
||||
case TK_FUNCTION_TYPE:
|
||||
break;
|
||||
|
||||
case TK_ENUMERAL_TYPE:
|
||||
break;
|
||||
|
||||
case TK_POINTER_TYPE:
|
||||
case TK_POINTER_MEMBER_TYPE:
|
||||
{
|
||||
/* Pointer type_info. Adds two fields, qualification mask and
|
||||
pointer to the pointed to type. This is really a
|
||||
descendant of __pbase_type_info. */
|
||||
tree fld_mask = build_decl (BUILTINS_LOCATION, FIELD_DECL,
|
||||
NULL_TREE, integer_type_node);
|
||||
DECL_CHAIN (fld_mask) = fields;
|
||||
fields = fld_mask;
|
||||
|
||||
tree fld_ptr = build_decl (BUILTINS_LOCATION, FIELD_DECL,
|
||||
NULL_TREE, type_info_ptr_type);
|
||||
DECL_CHAIN (fld_ptr) = fields;
|
||||
fields = fld_ptr;
|
||||
|
||||
if (ix == TK_POINTER_MEMBER_TYPE)
|
||||
{
|
||||
/* Add a pointer to the class too. */
|
||||
tree fld_cls = build_decl (BUILTINS_LOCATION, FIELD_DECL,
|
||||
NULL_TREE, type_info_ptr_type);
|
||||
DECL_CHAIN (fld_cls) = fields;
|
||||
fields = fld_cls;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case TK_CLASS_TYPE:
|
||||
/* Class type_info. No additional fields. */
|
||||
break;
|
||||
|
||||
case TK_SI_CLASS_TYPE:
|
||||
{
|
||||
/* Single public non-virtual base class. Add pointer to base
|
||||
class. This is really a descendant of
|
||||
__class_type_info. */
|
||||
tree fld_ptr = build_decl (BUILTINS_LOCATION, FIELD_DECL,
|
||||
NULL_TREE, type_info_ptr_type);
|
||||
DECL_CHAIN (fld_ptr) = fields;
|
||||
fields = fld_ptr;
|
||||
break;
|
||||
}
|
||||
|
||||
default: /* Multiple inheritance. */
|
||||
{
|
||||
unsigned num_bases = ix - TK_VMI_CLASS_TYPES + 1;
|
||||
|
||||
tree fld_flg = build_decl (BUILTINS_LOCATION, FIELD_DECL,
|
||||
NULL_TREE, integer_type_node);
|
||||
DECL_CHAIN (fld_flg) = fields;
|
||||
fields = fld_flg;
|
||||
|
||||
tree fld_cnt = build_decl (BUILTINS_LOCATION, FIELD_DECL,
|
||||
NULL_TREE, integer_type_node);
|
||||
DECL_CHAIN (fld_cnt) = fields;
|
||||
fields = fld_cnt;
|
||||
|
||||
/* Create the array of __base_class_type_info entries. */
|
||||
tree domain = build_index_type (size_int (num_bases - 1));
|
||||
tree array = build_array_type (get_tinfo_desc (TK_BASE_TYPE)->type,
|
||||
domain);
|
||||
tree fld_ary = build_decl (BUILTINS_LOCATION, FIELD_DECL,
|
||||
NULL_TREE, array);
|
||||
DECL_CHAIN (fld_ary) = fields;
|
||||
fields = fld_ary;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
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)];
|
||||
size_t name_len = strlen (real_name);
|
||||
char *pseudo_name = (char *) alloca (name_len + 30);
|
||||
memcpy (pseudo_name, real_name, name_len);
|
||||
/* Those >= TK_VMI_CLASS_TYPES need a discriminator, may as well
|
||||
apply it to all. See get_peudo_tinfo_index where we make use of
|
||||
this. */
|
||||
sprintf (pseudo_name + name_len, "_pseudo_%d", ix);
|
||||
|
||||
/* Create the pseudo type. */
|
||||
tree pseudo_type = make_class_type (RECORD_TYPE);
|
||||
/* Pass the fields chained in reverse. */
|
||||
finish_builtin_struct (pseudo_type, pseudo_name, fields, NULL_TREE);
|
||||
CLASSTYPE_AS_BASE (pseudo_type) = pseudo_type;
|
||||
|
||||
res->type = cp_build_qualified_type (pseudo_type, TYPE_QUAL_CONST);
|
||||
res->name = get_identifier (real_name);
|
||||
|
||||
/* Pretend this is public so determine_visibility doesn't give vtables
|
||||
internal linkage. */
|
||||
TREE_PUBLIC (TYPE_MAIN_DECL (res->type)) = 1;
|
||||
|
||||
pop_abi_namespace ();
|
||||
return res;
|
||||
}
|
||||
|
||||
/* We lazily create the type info types. */
|
||||
|
||||
static void
|
||||
create_tinfo_types (void)
|
||||
{
|
||||
tinfo_s *ti;
|
||||
|
||||
gcc_assert (!tinfo_descs);
|
||||
|
||||
vec_safe_grow (tinfo_descs, TK_FIXED);
|
||||
|
||||
push_abi_namespace ();
|
||||
|
||||
/* Create the internal type_info structure. This is used as a base for
|
||||
the other structures. */
|
||||
{
|
||||
tree field, fields;
|
||||
|
||||
field = build_decl (BUILTINS_LOCATION,
|
||||
FIELD_DECL, NULL_TREE, const_ptr_type_node);
|
||||
fields = field;
|
||||
|
||||
field = build_decl (BUILTINS_LOCATION,
|
||||
FIELD_DECL, NULL_TREE, const_string_type_node);
|
||||
DECL_CHAIN (field) = fields;
|
||||
fields = field;
|
||||
|
||||
ti = &(*tinfo_descs)[TK_TYPE_INFO_TYPE];
|
||||
ti->type = make_class_type (RECORD_TYPE);
|
||||
ti->vtable = NULL_TREE;
|
||||
ti->name = NULL_TREE;
|
||||
finish_builtin_struct (ti->type, "__type_info_pseudo",
|
||||
fields, NULL_TREE);
|
||||
}
|
||||
|
||||
/* Fundamental type_info */
|
||||
create_pseudo_type_info (TK_BUILTIN_TYPE, "__fundamental_type_info", NULL);
|
||||
|
||||
/* Array, function and enum type_info. No additional fields. */
|
||||
create_pseudo_type_info (TK_ARRAY_TYPE, "__array_type_info", NULL);
|
||||
create_pseudo_type_info (TK_FUNCTION_TYPE, "__function_type_info", NULL);
|
||||
create_pseudo_type_info (TK_ENUMERAL_TYPE, "__enum_type_info", NULL);
|
||||
|
||||
/* Class type_info. No additional fields. */
|
||||
create_pseudo_type_info (TK_CLASS_TYPE, "__class_type_info", NULL);
|
||||
|
||||
/* Single public non-virtual base class. Add pointer to base class.
|
||||
This is really a descendant of __class_type_info. */
|
||||
create_pseudo_type_info (TK_SI_CLASS_TYPE, "__si_class_type_info",
|
||||
build_decl (BUILTINS_LOCATION,
|
||||
FIELD_DECL, NULL_TREE, type_info_ptr_type),
|
||||
NULL);
|
||||
|
||||
/* Base class internal helper. Pointer to base type, offset to base,
|
||||
flags. */
|
||||
{
|
||||
tree field, fields;
|
||||
|
||||
field = build_decl (BUILTINS_LOCATION,
|
||||
FIELD_DECL, NULL_TREE, type_info_ptr_type);
|
||||
fields = field;
|
||||
|
||||
field = build_decl (BUILTINS_LOCATION,
|
||||
FIELD_DECL, NULL_TREE, LONGPTR_T);
|
||||
DECL_CHAIN (field) = fields;
|
||||
fields = field;
|
||||
|
||||
ti = &(*tinfo_descs)[TK_BASE_TYPE];
|
||||
|
||||
ti->type = make_class_type (RECORD_TYPE);
|
||||
ti->vtable = NULL_TREE;
|
||||
ti->name = NULL_TREE;
|
||||
finish_builtin_struct (ti->type, "__base_class_type_info_pseudo",
|
||||
fields, NULL_TREE);
|
||||
}
|
||||
|
||||
/* Pointer type_info. Adds two fields, qualification mask
|
||||
and pointer to the pointed to type. This is really a descendant of
|
||||
__pbase_type_info. */
|
||||
create_pseudo_type_info (TK_POINTER_TYPE, "__pointer_type_info",
|
||||
build_decl (BUILTINS_LOCATION,
|
||||
FIELD_DECL, NULL_TREE, integer_type_node),
|
||||
build_decl (BUILTINS_LOCATION,
|
||||
FIELD_DECL, NULL_TREE, type_info_ptr_type),
|
||||
NULL);
|
||||
|
||||
/* Pointer to member data type_info. Add qualifications flags,
|
||||
pointer to the member's type info and pointer to the class.
|
||||
This is really a descendant of __pbase_type_info. */
|
||||
create_pseudo_type_info (TK_POINTER_MEMBER_TYPE,
|
||||
"__pointer_to_member_type_info",
|
||||
build_decl (BUILTINS_LOCATION,
|
||||
FIELD_DECL, NULL_TREE, integer_type_node),
|
||||
build_decl (BUILTINS_LOCATION,
|
||||
FIELD_DECL, NULL_TREE, type_info_ptr_type),
|
||||
build_decl (BUILTINS_LOCATION,
|
||||
FIELD_DECL, NULL_TREE, type_info_ptr_type),
|
||||
NULL);
|
||||
|
||||
pop_abi_namespace ();
|
||||
vec_alloc (tinfo_descs, TK_MAX + 20);
|
||||
}
|
||||
|
||||
/* Helper for emit_support_tinfos. Emits the type_info descriptor of
|
||||
@ -1545,18 +1546,23 @@ emit_support_tinfos (void)
|
||||
0
|
||||
};
|
||||
int ix;
|
||||
tree bltn_type, dtor;
|
||||
|
||||
push_abi_namespace ();
|
||||
bltn_type = xref_tag (class_type,
|
||||
get_identifier ("__fundamental_type_info"),
|
||||
/*tag_scope=*/ts_current, false);
|
||||
pop_abi_namespace ();
|
||||
/* Look for a defined class. */
|
||||
tree bltn_type = lookup_qualified_name
|
||||
(abi_node, get_identifier ("__fundamental_type_info"), true, false, false);
|
||||
if (TREE_CODE (bltn_type) != TYPE_DECL)
|
||||
return;
|
||||
|
||||
bltn_type = TREE_TYPE (bltn_type);
|
||||
if (!COMPLETE_TYPE_P (bltn_type))
|
||||
return;
|
||||
dtor = CLASSTYPE_DESTRUCTORS (bltn_type);
|
||||
tree dtor = CLASSTYPE_DESTRUCTORS (bltn_type);
|
||||
if (!dtor || DECL_EXTERNAL (dtor))
|
||||
return;
|
||||
|
||||
/* All these are really builtins. So set the location. */
|
||||
location_t saved_loc = input_location;
|
||||
input_location = BUILTINS_LOCATION;
|
||||
doing_runtime = 1;
|
||||
for (ix = 0; fundamentals[ix]; ix++)
|
||||
emit_support_tinfo_1 (*fundamentals[ix]);
|
||||
@ -1568,6 +1574,7 @@ emit_support_tinfos (void)
|
||||
}
|
||||
for (tree t = registered_builtin_types; t; t = TREE_CHAIN (t))
|
||||
emit_support_tinfo_1 (TREE_VALUE (t));
|
||||
input_location = saved_loc;
|
||||
}
|
||||
|
||||
/* Finish a type info decl. DECL_PTR is a pointer to an unemitted
|
||||
@ -1606,7 +1613,7 @@ emit_tinfo_decl (tree decl)
|
||||
TREE_PUBLIC (decl) = 0;
|
||||
DECL_EXTERNAL (decl) = 0;
|
||||
DECL_INTERFACE_KNOWN (decl) = 1;
|
||||
}
|
||||
}u
|
||||
|
||||
import_export_decl (decl);
|
||||
if (DECL_NOT_REALLY_EXTERN (decl) && decl_needed_p (decl))
|
||||
|
Loading…
Reference in New Issue
Block a user