Commit ac9a1c7e by Nathan Sidwell Committed by Nathan Sidwell

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
parent bfe8a528
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> 2017-06-15 Martin Sebor <msebor@redhat.com>
PR c++/80560 PR c++/80560
......
...@@ -75,7 +75,8 @@ enum tinfo_kind ...@@ -75,7 +75,8 @@ enum tinfo_kind
{ {
TK_TYPE_INFO_TYPE, /* abi::__type_info_pseudo */ TK_TYPE_INFO_TYPE, /* abi::__type_info_pseudo */
TK_BASE_TYPE, /* abi::__base_class_type_info */ 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_ARRAY_TYPE, /* abi::__array_type_info */
TK_FUNCTION_TYPE, /* abi::__function_type_info */ TK_FUNCTION_TYPE, /* abi::__function_type_info */
TK_ENUMERAL_TYPE, /* abi::__enum_type_info */ TK_ENUMERAL_TYPE, /* abi::__enum_type_info */
...@@ -83,8 +84,26 @@ enum tinfo_kind ...@@ -83,8 +84,26 @@ enum tinfo_kind
TK_POINTER_MEMBER_TYPE, /* abi::__pointer_to_member_type_info */ TK_POINTER_MEMBER_TYPE, /* abi::__pointer_to_member_type_info */
TK_CLASS_TYPE, /* abi::__class_type_info */ TK_CLASS_TYPE, /* abi::__class_type_info */
TK_SI_CLASS_TYPE, /* abi::__si_class_type_info */ TK_SI_CLASS_TYPE, /* abi::__si_class_type_info */
TK_FIXED /* end of fixed descriptors. */ TK_VMI_CLASS_TYPES, /* abi::__vmi_class_type_info<int> */
/* ... abi::__vmi_type_info<I> */ 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. /* 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); ...@@ -115,9 +134,9 @@ static tree generic_initializer (tinfo_s *, tree);
static tree ptr_initializer (tinfo_s *, tree); static tree ptr_initializer (tinfo_s *, tree);
static tree ptm_initializer (tinfo_s *, tree); static tree ptm_initializer (tinfo_s *, tree);
static tree class_initializer (tinfo_s *, tree, unsigned, ...); 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 tree get_pseudo_ti_init (tree, unsigned);
static unsigned get_pseudo_ti_index (tree); static unsigned get_pseudo_ti_index (tree);
static tinfo_s *get_tinfo_desc (unsigned);
static void create_tinfo_types (void); static void create_tinfo_types (void);
static bool typeinfo_in_lib_p (tree); static bool typeinfo_in_lib_p (tree);
...@@ -289,30 +308,27 @@ get_tinfo_decl_dynamic (tree exp, tsubst_flags_t complain) ...@@ -289,30 +308,27 @@ get_tinfo_decl_dynamic (tree exp, tsubst_flags_t complain)
static bool static bool
typeid_ok_p (void) typeid_ok_p (void)
{ {
tree pseudo_type_info, type_info_type;
if (! flag_rtti) if (! flag_rtti)
{ {
error ("cannot use typeid with -fno-rtti"); error ("cannot use %<typeid%> with -fno-rtti");
return false; return false;
} }
if (!COMPLETE_TYPE_P (const_type_info_type_node)) 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; return false;
} }
pseudo_type_info = (*tinfo_descs)[TK_TYPE_INFO_TYPE].type; tree pseudo = TYPE_MAIN_VARIANT (get_tinfo_desc (TK_TYPE_INFO_TYPE)->type);
type_info_type = TYPE_MAIN_VARIANT (const_type_info_type_node); tree real = TYPE_MAIN_VARIANT (const_type_info_type_node);
/* Make sure abi::__type_info_pseudo has the same alias set /* Make sure abi::__type_info_pseudo has the same alias set
as std::type_info. */ as std::type_info. */
if (! TYPE_ALIAS_SET_KNOWN_P (pseudo_type_info)) if (! TYPE_ALIAS_SET_KNOWN_P (pseudo))
TYPE_ALIAS_SET (pseudo_type_info) = get_alias_set (type_info_type); TYPE_ALIAS_SET (pseudo) = get_alias_set (real);
else else
gcc_assert (TYPE_ALIAS_SET (pseudo_type_info) gcc_assert (TYPE_ALIAS_SET (pseudo) == get_alias_set (real));
== get_alias_set (type_info_type));
return true; return true;
} }
...@@ -428,8 +444,8 @@ get_tinfo_decl (tree type) ...@@ -428,8 +444,8 @@ get_tinfo_decl (tree type)
if (!d) if (!d)
{ {
int ix = get_pseudo_ti_index (type); 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); d = build_lang_decl (VAR_DECL, name, ti->type);
SET_DECL_ASSEMBLER_NAME (d, name); SET_DECL_ASSEMBLER_NAME (d, name);
/* Remember the type it is for. */ /* Remember the type it is for. */
...@@ -1105,7 +1121,7 @@ typeinfo_in_lib_p (tree type) ...@@ -1105,7 +1121,7 @@ typeinfo_in_lib_p (tree type)
static tree static tree
get_pseudo_ti_init (tree type, unsigned tk_index) 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); gcc_assert (at_eof);
switch (tk_index) switch (tk_index)
...@@ -1140,22 +1156,18 @@ get_pseudo_ti_init (tree type, unsigned tk_index) ...@@ -1140,22 +1156,18 @@ get_pseudo_ti_init (tree type, unsigned tk_index)
int hint = ((CLASSTYPE_REPEATED_BASE_P (type) << 0) int hint = ((CLASSTYPE_REPEATED_BASE_P (type) << 0)
| (CLASSTYPE_DIAMOND_SHAPED_P (type) << 1)); | (CLASSTYPE_DIAMOND_SHAPED_P (type) << 1));
tree binfo = TYPE_BINFO (type); 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); vec<tree, va_gc> *base_accesses = BINFO_BASE_ACCESSES (binfo);
tree offset_type = LONGPTR_T; tree offset_type = LONGPTR_T;
tree base_inits = NULL_TREE;
int ix;
vec<constructor_elt, va_gc> *init_vec = NULL; 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); vec_safe_grow (init_vec, nbases);
/* Generate the base information initializer. */ /* Generate the base information initializer. */
for (ix = nbases; ix--;) for (unsigned ix = nbases; ix--;)
{ {
tree base_binfo = BINFO_BASE_BINFO (binfo, ix); tree base_binfo = BINFO_BASE_BINFO (binfo, ix);
tree base_init;
int flags = 0; int flags = 0;
tree tinfo; tree tinfo;
tree offset; tree offset;
...@@ -1185,12 +1197,12 @@ get_pseudo_ti_init (tree type, unsigned tk_index) ...@@ -1185,12 +1197,12 @@ get_pseudo_ti_init (tree type, unsigned tk_index)
vec_alloc (v, 2); vec_alloc (v, 2);
CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, tinfo); CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, tinfo);
CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, offset); CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, offset);
base_init = build_constructor (init_list_type_node, v); tree base_init = build_constructor (init_list_type_node, v);
e = &(*init_vec)[ix]; constructor_elt *e = &(*init_vec)[ix];
e->index = NULL_TREE; e->index = NULL_TREE;
e->value = base_init; 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. */ /* get_tinfo_ptr might have reallocated the tinfo_descs vector. */
ti = &(*tinfo_descs)[tk_index]; ti = &(*tinfo_descs)[tk_index];
...@@ -1202,69 +1214,6 @@ get_pseudo_ti_init (tree type, unsigned 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 /* 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 TYPE. TYPE must be a complete type (or cv void), except at the end
of the translation unit. */ of the translation unit. */
...@@ -1299,23 +1248,16 @@ get_pseudo_ti_index (tree type) ...@@ -1299,23 +1248,16 @@ get_pseudo_ti_index (tree type)
case UNION_TYPE: case UNION_TYPE:
case RECORD_TYPE: case RECORD_TYPE:
if (TYPE_PTRMEMFUNC_P (type)) if (TYPE_PTRMEMFUNC_P (type))
{ ix = TK_POINTER_MEMBER_TYPE;
ix = TK_POINTER_MEMBER_TYPE;
break;
}
else if (!COMPLETE_TYPE_P (type)) else if (!COMPLETE_TYPE_P (type))
{ {
if (!at_eof) if (!at_eof)
cxx_incomplete_type_error (NULL_TREE, type); cxx_incomplete_type_error (NULL_TREE, type);
ix = TK_CLASS_TYPE; ix = TK_CLASS_TYPE;
break;
} }
else if (!TYPE_BINFO (type) else if (!TYPE_BINFO (type)
|| !BINFO_N_BASE_BINFOS (TYPE_BINFO (type))) || !BINFO_N_BASE_BINFOS (TYPE_BINFO (type)))
{ ix = TK_CLASS_TYPE;
ix = TK_CLASS_TYPE;
break;
}
else else
{ {
tree binfo = TYPE_BINFO (type); tree binfo = TYPE_BINFO (type);
...@@ -1327,49 +1269,13 @@ get_pseudo_ti_index (tree type) ...@@ -1327,49 +1269,13 @@ get_pseudo_ti_index (tree type)
&& (*base_accesses)[0] == access_public_node && (*base_accesses)[0] == access_public_node
&& !BINFO_VIRTUAL_P (base_binfo) && !BINFO_VIRTUAL_P (base_binfo)
&& integer_zerop (BINFO_OFFSET (base_binfo))) && integer_zerop (BINFO_OFFSET (base_binfo)))
{ /* single non-virtual public. */
/* single non-virtual public. */ ix = TK_SI_CLASS_TYPE;
ix = TK_SI_CLASS_TYPE;
break;
}
else else
{ ix = TK_VMI_CLASS_TYPES + num_bases - 1;
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;
}
} }
break;
default: default:
ix = TK_BUILTIN_TYPE; ix = TK_BUILTIN_TYPE;
break; break;
...@@ -1377,107 +1283,202 @@ get_pseudo_ti_index (tree type) ...@@ -1377,107 +1283,202 @@ get_pseudo_ti_index (tree type)
return ix; return ix;
} }
/* Make sure the required builtin types exist for generating the type_info /* Return pointer to tinfo descriptor. Possibly creating the tinfo
variable definitions. */ descriptor in the first place. */
static void static tinfo_s *
create_tinfo_types (void) get_tinfo_desc (unsigned ix)
{ {
tinfo_s *ti; unsigned len = tinfo_descs->length ();
gcc_assert (!tinfo_descs); 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);
}
vec_safe_grow (tinfo_descs, TK_FIXED); tinfo_s *res = &(*tinfo_descs)[ix];
push_abi_namespace (); if (res->type)
return res;
/* Create the internal type_info structure. This is used as a base for /* Ok, we have to create it. This layout must be consistent with
the other structures. */ that defined in the runtime support. We explicitly manage the
{ vtable member, and name it for real type as used in the runtime.
tree field, fields; The RECORD type has a different name, to avoid collisions. We
have to delay generating the VAR_DECL of the vtable until the end
field = build_decl (BUILTINS_LOCATION, of the translation, when we'll have seen the library definition,
FIELD_DECL, NULL_TREE, const_ptr_type_node); if there was one. */
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 */ /* Fields to add, chained in reverse order. */
create_pseudo_type_info (TK_BUILTIN_TYPE, "__fundamental_type_info", NULL); tree fields = NULL_TREE;
/* Array, function and enum type_info. No additional fields. */ if (ix >= TK_DERIVED_TYPES)
create_pseudo_type_info (TK_ARRAY_TYPE, "__array_type_info", NULL); {
create_pseudo_type_info (TK_FUNCTION_TYPE, "__function_type_info", NULL); /* First field is the pseudo type_info base class. */
create_pseudo_type_info (TK_ENUMERAL_TYPE, "__enum_type_info", NULL); tree fld_base = build_decl (BUILTINS_LOCATION, FIELD_DECL, NULL_TREE,
get_tinfo_desc (TK_TYPE_INFO_TYPE)->type);
/* Class type_info. No additional fields. */ DECL_CHAIN (fld_base) = fields;
create_pseudo_type_info (TK_CLASS_TYPE, "__class_type_info", NULL); fields = fld_base;
}
/* Single public non-virtual base class. Add pointer to base class. switch (ix)
This is really a descendant of __class_type_info. */ {
create_pseudo_type_info (TK_SI_CLASS_TYPE, "__si_class_type_info", case TK_TYPE_INFO_TYPE:
build_decl (BUILTINS_LOCATION, {
FIELD_DECL, NULL_TREE, type_info_ptr_type), tree fld_ptr = build_decl (BUILTINS_LOCATION, FIELD_DECL,
NULL); 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;
}
/* Base class internal helper. Pointer to base type, offset to base, case TK_BASE_TYPE:
flags. */ {
{ /* Base class internal helper. Pointer to base type, offset to
tree field, fields; 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;
}
field = build_decl (BUILTINS_LOCATION, case TK_BUILTIN_TYPE:
FIELD_DECL, NULL_TREE, type_info_ptr_type); /* Fundamental type_info */
fields = field; break;
field = build_decl (BUILTINS_LOCATION, case TK_ARRAY_TYPE:
FIELD_DECL, NULL_TREE, LONGPTR_T); break;
DECL_CHAIN (field) = fields;
fields = field;
ti = &(*tinfo_descs)[TK_BASE_TYPE]; case TK_FUNCTION_TYPE:
break;
ti->type = make_class_type (RECORD_TYPE); case TK_ENUMERAL_TYPE:
ti->vtable = NULL_TREE; break;
ti->name = NULL_TREE;
finish_builtin_struct (ti->type, "__base_class_type_info_pseudo", case TK_POINTER_TYPE:
fields, NULL_TREE); 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);
/* Pointer type_info. Adds two fields, qualification mask /* Create the pseudo type. */
and pointer to the pointed to type. This is really a descendant of tree pseudo_type = make_class_type (RECORD_TYPE);
__pbase_type_info. */ /* Pass the fields chained in reverse. */
create_pseudo_type_info (TK_POINTER_TYPE, "__pointer_type_info", finish_builtin_struct (pseudo_type, pseudo_name, fields, NULL_TREE);
build_decl (BUILTINS_LOCATION, CLASSTYPE_AS_BASE (pseudo_type) = pseudo_type;
FIELD_DECL, NULL_TREE, integer_type_node),
build_decl (BUILTINS_LOCATION, res->type = cp_build_qualified_type (pseudo_type, TYPE_QUAL_CONST);
FIELD_DECL, NULL_TREE, type_info_ptr_type), res->name = get_identifier (real_name);
NULL);
/* Pretend this is public so determine_visibility doesn't give vtables
/* Pointer to member data type_info. Add qualifications flags, internal linkage. */
pointer to the member's type info and pointer to the class. TREE_PUBLIC (TYPE_MAIN_DECL (res->type)) = 1;
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 (); pop_abi_namespace ();
return res;
}
/* We lazily create the type info types. */
static void
create_tinfo_types (void)
{
gcc_assert (!tinfo_descs);
vec_alloc (tinfo_descs, TK_MAX + 20);
} }
/* Helper for emit_support_tinfos. Emits the type_info descriptor of /* Helper for emit_support_tinfos. Emits the type_info descriptor of
...@@ -1545,18 +1546,23 @@ emit_support_tinfos (void) ...@@ -1545,18 +1546,23 @@ emit_support_tinfos (void)
0 0
}; };
int ix; int ix;
tree bltn_type, dtor;
push_abi_namespace (); /* Look for a defined class. */
bltn_type = xref_tag (class_type, tree bltn_type = lookup_qualified_name
get_identifier ("__fundamental_type_info"), (abi_node, get_identifier ("__fundamental_type_info"), true, false, false);
/*tag_scope=*/ts_current, false); if (TREE_CODE (bltn_type) != TYPE_DECL)
pop_abi_namespace (); return;
bltn_type = TREE_TYPE (bltn_type);
if (!COMPLETE_TYPE_P (bltn_type)) if (!COMPLETE_TYPE_P (bltn_type))
return; return;
dtor = CLASSTYPE_DESTRUCTORS (bltn_type); tree dtor = CLASSTYPE_DESTRUCTORS (bltn_type);
if (!dtor || DECL_EXTERNAL (dtor)) if (!dtor || DECL_EXTERNAL (dtor))
return; return;
/* All these are really builtins. So set the location. */
location_t saved_loc = input_location;
input_location = BUILTINS_LOCATION;
doing_runtime = 1; doing_runtime = 1;
for (ix = 0; fundamentals[ix]; ix++) for (ix = 0; fundamentals[ix]; ix++)
emit_support_tinfo_1 (*fundamentals[ix]); emit_support_tinfo_1 (*fundamentals[ix]);
...@@ -1568,6 +1574,7 @@ emit_support_tinfos (void) ...@@ -1568,6 +1574,7 @@ emit_support_tinfos (void)
} }
for (tree t = registered_builtin_types; t; t = TREE_CHAIN (t)) for (tree t = registered_builtin_types; t; t = TREE_CHAIN (t))
emit_support_tinfo_1 (TREE_VALUE (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 /* Finish a type info decl. DECL_PTR is a pointer to an unemitted
...@@ -1606,7 +1613,7 @@ emit_tinfo_decl (tree decl) ...@@ -1606,7 +1613,7 @@ emit_tinfo_decl (tree decl)
TREE_PUBLIC (decl) = 0; TREE_PUBLIC (decl) = 0;
DECL_EXTERNAL (decl) = 0; DECL_EXTERNAL (decl) = 0;
DECL_INTERFACE_KNOWN (decl) = 1; DECL_INTERFACE_KNOWN (decl) = 1;
} }u
import_export_decl (decl); import_export_decl (decl);
if (DECL_NOT_REALLY_EXTERN (decl) && decl_needed_p (decl)) if (DECL_NOT_REALLY_EXTERN (decl) && decl_needed_p (decl))
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment