@@ -5327,6 +5500,10 @@ extern int function_depth;
in structrual_comptypes. */
extern int comparing_specializations;
+/* Nonzero if we are inside eq_specializations, which affects
+ resolving of typenames in structural_comptypes. */
+extern int comparing_typenames;
+
/* In parser.c. */
/* Nonzero if we are parsing an unevaluated operand: an operand to
@@ -6457,6 +6651,7 @@ extern bool check_omp_return (void);
extern tree make_typename_type (tree, tree, enum tag_types, tsubst_flags_t);
extern tree build_typename_type (tree, tree, tree, tag_types);
extern tree make_unbound_class_template (tree, tree, tree, tsubst_flags_t);
+extern tree make_unbound_class_template_raw (tree, tree, tree);
extern tree build_library_fn_ptr (const char *, tree, int);
extern tree build_cp_library_fn_ptr (const char *, tree, int);
extern tree push_library_fn (tree, tree, tree, int);
@@ -6731,8 +6926,11 @@ extern tree unqualified_fn_lookup_error (cp_expr);
extern tree make_conv_op_name (tree);
extern tree build_lang_decl (enum tree_code, tree, tree);
extern tree build_lang_decl_loc (location_t, enum tree_code, tree, tree);
+extern bool maybe_add_lang_decl_raw (tree, bool decomp_p);
+extern bool maybe_add_lang_type_raw (tree);
extern void retrofit_lang_decl (tree);
extern void fit_decomposition_lang_decl (tree, tree);
+extern void fit_ptrmem_type_decl (tree, tree);
extern tree copy_decl (tree CXX_MEM_STAT_INFO);
extern tree copy_type (tree CXX_MEM_STAT_INFO);
extern tree cxx_make_type (enum tree_code CXX_MEM_STAT_INFO);
@@ -6793,6 +7089,7 @@ extern void maybe_show_extern_c_location (void);
extern bool literal_integer_zerop (const_tree);
/* in pt.c */
+extern tree canonical_type_parameter (tree);
extern void push_access_scope (tree);
extern void pop_access_scope (tree);
extern bool check_template_shadow (tree);
@@ -6986,6 +7293,7 @@ extern GTY(()) vec<tree, va_gc> *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);
@@ -6993,6 +7301,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);
@@ -7340,7 +7650,7 @@ extern bool is_local_temp (tree);
extern tree build_aggr_init_expr (tree, tree);
extern tree get_target_expr (tree);
extern tree get_target_expr_sfinae (tree, tsubst_flags_t);
-extern tree build_cplus_array_type (tree, tree);
+extern tree build_cplus_array_type (tree, tree, int is_dep = -1);
extern tree build_array_of_n_type (tree, int);
extern bool array_of_runtime_bound_p (tree);
extern bool vla_type_p (tree);
@@ -678,7 +880,7 @@ build_lang_decl_loc (location_t loc, enum tree_code code, tree name, tree type)
/* Maybe add a raw lang_decl to T, a decl. Return true if it needed
one. */
-static bool
+bool
maybe_add_lang_decl_raw (tree t, bool decomp_p)
{
size_t size;
@@ -803,6 +1005,9 @@ cxx_dup_lang_specific_decl (tree node)
struct lang_decl *ld = (struct lang_decl *) ggc_internal_alloc (size);
memcpy (ld, DECL_LANG_SPECIFIC (node), size);
DECL_LANG_SPECIFIC (node) = ld;
+ DECL_MODULE_ENTITY_P (node) = false;
+ DECL_MODULE_IMPORT_P (node) = false;
+ DECL_ATTACHED_DECLS_P (node) = false;
if (GATHER_STATISTICS)
{
@@ -831,8 +1036,7 @@ copy_lang_type (tree node)
if (! TYPE_LANG_SPECIFIC (node))
return;
- struct lang_type *lt
- = (struct lang_type *) ggc_internal_alloc (sizeof (struct lang_type));
+ auto *lt = (struct lang_type *) ggc_internal_alloc (sizeof (struct lang_type));
memcpy (lt, TYPE_LANG_SPECIFIC (node), (sizeof (struct lang_type)));
TYPE_LANG_SPECIFIC (node) = lt;
@@ -858,15 +1062,15 @@ copy_type (tree type MEM_STAT_DECL)
/* Add a raw lang_type to T, a type, should it need one. */
-static bool
+bool
maybe_add_lang_type_raw (tree t)
{
if (!RECORD_OR_UNION_CODE_P (TREE_CODE (t)))
return false;
- TYPE_LANG_SPECIFIC (t)
- = (struct lang_type *) (ggc_internal_cleared_alloc
- (sizeof (struct lang_type)));
+ auto *lt = (struct lang_type *) (ggc_internal_cleared_alloc
+ (sizeof (struct lang_type)));
+ TYPE_LANG_SPECIFIC (t) = lt;
if (GATHER_STATISTICS)
{
@@ -1709,9 +1708,11 @@ register_specialization (tree spec, tree tmpl, tree args, bool is_friend,
return spec;
}
-/* Returns true iff two spec_entry nodes are equivalent. */
-
+/* Restricts tree and type comparisons. */
int comparing_specializations;
+int comparing_typenames;
+
+/* Returns true iff two spec_entry nodes are equivalent. */
bool
spec_hasher::equal (spec_entry *e1, spec_entry *e2)
@@ -1719,6 +1720,7 @@ spec_hasher::equal (spec_entry *e1, spec_entry *e2)
int equal;
++comparing_specializations;
+ ++comparing_typenames;
equal = (e1->tmpl == e2->tmpl
&& comp_template_args (e1->args, e2->args));
if (equal && flag_concepts
@@ -1734,6 +1736,7 @@ spec_hasher::equal (spec_entry *e1, spec_entry *e2)
equal = equivalent_constraints (c1, c2);
}
--comparing_specializations;
+ --comparing_typenames;
return equal;
}
@@ -4435,7 +4438,7 @@ build_template_parm_index (int index,
parameter. Returns the canonical type parameter, which may be TYPE
if no such parameter existed. */
-static tree
+tree
canonical_type_parameter (tree type)
{
int idx = TEMPLATE_TYPE_IDX (type);
@@ -13205,19 +13244,24 @@ tsubst_argument_pack (tree orig_arg, tree args, tsubst_flags_t complain,
tree in_decl)
{
/* Substitute into each of the arguments. */
- tree new_arg = TYPE_P (orig_arg)
- ? cxx_make_type (TREE_CODE (orig_arg))
- : make_node (TREE_CODE (orig_arg));
-
tree pack_args = tsubst_template_args (ARGUMENT_PACK_ARGS (orig_arg),
args, complain, in_decl);
- if (pack_args == error_mark_node)
- new_arg = error_mark_node;
- else
- SET_ARGUMENT_PACK_ARGS (new_arg, pack_args);
+ tree new_arg = error_mark_node;
+ if (pack_args != error_mark_node)
+ {
+ if (TYPE_P (orig_arg))
+ {
+ new_arg = cxx_make_type (TREE_CODE (orig_arg));
+ SET_TYPE_STRUCTURAL_EQUALITY (new_arg);
+ }
+ else
+ {
+ new_arg = make_node (TREE_CODE (orig_arg));
+ TREE_CONSTANT (new_arg) = TREE_CONSTANT (orig_arg);
+ }
- if (TREE_CODE (new_arg) == NONTYPE_ARGUMENT_PACK)
- TREE_CONSTANT (new_arg) = TREE_CONSTANT (orig_arg);
+ SET_ARGUMENT_PACK_ARGS (new_arg, pack_args);
+ }
return new_arg;
}
@@ -1256,16 +1256,15 @@ structural_comptypes (tree t1, tree t2, int strict)
gcc_assert (TYPE_P (t1) && TYPE_P (t2));
- if (!comparing_specializations)
- {
- /* TYPENAME_TYPEs should be resolved if the qualifying scope is the
- current instantiation. */
- if (TREE_CODE (t1) == TYPENAME_TYPE)
- t1 = resolve_typename_type (t1, /*only_current_p=*/true);
-
- if (TREE_CODE (t2) == TYPENAME_TYPE)
- t2 = resolve_typename_type (t2, /*only_current_p=*/true);
- }
+ /* TYPENAME_TYPEs should be resolved if the qualifying scope is the
+ current instantiation, and we don't care about typename
+ structural equality. The comparing_typenames check is after the
+ code check, in order to early-out the common case. */
+ if (TREE_CODE (t1) == TYPENAME_TYPE && !comparing_typenames)
+ t1 = resolve_typename_type (t1, /*only_current_p=*/true);
+
+ if (TREE_CODE (t2) == TYPENAME_TYPE && !comparing_typenames)
+ t2 = resolve_typename_type (t2, /*only_current_p=*/true);
if (TYPE_PTRMEMFUNC_P (t1))
t1 = TYPE_PTRMEMFUNC_FN_TYPE (t1);
@@ -123,7 +123,6 @@ 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);
@@ -431,7 +434,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
@@ -1491,6 +1495,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
@@ -998,7 +998,7 @@ build_min_array_type (tree elt_type, tree index_type)
build_cplus_array_type. */
static void
-set_array_type_canon (tree t, tree elt_type, tree index_type)
+set_array_type_canon (tree t, tree elt_type, tree index_type, bool dep)
{
/* Set the canonical type for this new node. */
if (TYPE_STRUCTURAL_EQUALITY_P (elt_type)
@@ -1009,30 +1009,33 @@ set_array_type_canon (tree t, tree elt_type, tree index_type)
TYPE_CANONICAL (t)
= build_cplus_array_type (TYPE_CANONICAL (elt_type),
index_type
- ? TYPE_CANONICAL (index_type) : index_type);
+ ? TYPE_CANONICAL (index_type) : index_type,
+ dep);
else
TYPE_CANONICAL (t) = t;
}
/* Like build_array_type, but handle special C++ semantics: an array of a
variant element type is a variant of the array of the main variant of
- the element type. */
+ the element type. IS_DEPENDENT is -ve if we should determine the
+ dependency. Otherwise its bool value indicates dependency. */
tree
-build_cplus_array_type (tree elt_type, tree index_type)
+build_cplus_array_type (tree elt_type, tree index_type, int dependent)
{
tree t;
if (elt_type == error_mark_node || index_type == error_mark_node)
return error_mark_node;
- bool dependent = (uses_template_parms (elt_type)
- || (index_type && uses_template_parms (index_type)));
+ if (dependent < 0)
+ dependent = (uses_template_parms (elt_type)
+ || (index_type && uses_template_parms (index_type)));
if (elt_type != TYPE_MAIN_VARIANT (elt_type))
/* Start with an array of the TYPE_MAIN_VARIANT. */
t = build_cplus_array_type (TYPE_MAIN_VARIANT (elt_type),
- index_type);
+ index_type, dependent);
else if (dependent)
{
/* Since type_hash_canon calls layout_type, we need to use our own
@@ -1062,7 +1065,11 @@ build_cplus_array_type (tree elt_type, tree index_type)
*e = t;
/* Set the canonical type for this new node. */
- set_array_type_canon (t, elt_type, index_type);
+ set_array_type_canon (t, elt_type, index_type, dependent);
+
+ /* Mark it as dependent now, this saves time later. */
+ TYPE_DEPENDENT_P_VALID (t) = true;
+ TYPE_DEPENDENT_P (t) = true;
}
}
else
@@ -1083,7 +1090,7 @@ build_cplus_array_type (tree elt_type, tree index_type)
if (!t)
{
t = build_min_array_type (elt_type, index_type);
- set_array_type_canon (t, elt_type, index_type);
+ set_array_type_canon (t, elt_type, index_type, dependent);
if (!dependent)
{
layout_type (t);
@@ -1319,7 +1326,8 @@ cp_build_qualified_type_real (tree type,
if (!t)
{
- t = build_cplus_array_type (element_type, TYPE_DOMAIN (type));
+ t = build_cplus_array_type (element_type, TYPE_DOMAIN (type),
+ TYPE_DEPENDENT_P (type));
/* Keep the typedef name. */
if (TYPE_NAME (t) != TYPE_NAME (type))
@@ -1555,7 +1563,7 @@ strip_typedefs (tree t, bool *remove_attributes, unsigned int flags)
case ARRAY_TYPE:
type = strip_typedefs (TREE_TYPE (t), remove_attributes, flags);
t0 = strip_typedefs (TYPE_DOMAIN (t), remove_attributes, flags);
- result = build_cplus_array_type (type, t0);
+ result = build_cplus_array_type (type, t0, TYPE_DEPENDENT_P (t));
break;
case FUNCTION_TYPE:
case METHOD_TYPE: