aboutsummaryrefslogtreecommitdiff
path: root/gcc/cp/tree.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/cp/tree.c')
-rw-r--r--gcc/cp/tree.c222
1 files changed, 177 insertions, 45 deletions
diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c
index 9bc37ac..0584a7b 100644
--- a/gcc/cp/tree.c
+++ b/gcc/cp/tree.c
@@ -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,13 +1065,20 @@ 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
{
bool typeless_storage = is_byte_access_type (elt_type);
t = build_array_type (elt_type, index_type, typeless_storage);
+
+ /* Mark as non-dependenty now, this will save time later. */
+ TYPE_DEPENDENT_P_VALID (t) = true;
}
/* Now check whether we already have this array variant. */
@@ -1083,7 +1093,10 @@ 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);
+ /* Mark dependency now, this saves time later. */
+ TYPE_DEPENDENT_P_VALID (t) = true;
+ TYPE_DEPENDENT_P (t) = dependent;
+ set_array_type_canon (t, elt_type, index_type, dependent);
if (!dependent)
{
layout_type (t);
@@ -1319,7 +1332,10 @@ cp_build_qualified_type_real (tree type,
if (!t)
{
- t = build_cplus_array_type (element_type, TYPE_DOMAIN (type));
+ gcc_checking_assert (TYPE_DEPENDENT_P_VALID (type)
+ || !dependent_type_p (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 +1571,9 @@ 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);
+ gcc_checking_assert (TYPE_DEPENDENT_P_VALID (t)
+ || !dependent_type_p (t));
+ result = build_cplus_array_type (type, t0, TYPE_DEPENDENT_P (t));
break;
case FUNCTION_TYPE:
case METHOD_TYPE:
@@ -2218,6 +2236,23 @@ build_ref_qualified_type (tree type, cp_ref_qualifier rqual)
return build_cp_fntype_variant (type, rqual, raises, late);
}
+tree
+make_binding_vec (tree name, unsigned clusters MEM_STAT_DECL)
+{
+ /* Stored in an unsigned short, but we're limited to the number of
+ modules anyway. */
+ gcc_checking_assert (clusters <= (unsigned short)(~0));
+ size_t length = (offsetof (tree_binding_vec, vec)
+ + clusters * sizeof (binding_cluster));
+ tree vec = ggc_alloc_cleared_tree_node_stat (length PASS_MEM_STAT);
+ TREE_SET_CODE (vec, BINDING_VECTOR);
+ BINDING_VECTOR_NAME (vec) = name;
+ BINDING_VECTOR_ALLOC_CLUSTERS (vec) = clusters;
+ BINDING_VECTOR_NUM_CLUSTERS (vec) = 0;
+
+ return vec;
+}
+
/* Make a raw overload node containing FN. */
tree
@@ -2237,10 +2272,11 @@ ovl_make (tree fn, tree next)
return result;
}
-/* Add FN to the (potentially NULL) overload set OVL. USING_OR_HIDDEN
- is > 0, if FN is via a using declaration. USING_OR_HIDDEN is < 0,
- if FN is hidden. (A decl cannot be both using and hidden.) We
- keep the hidden decls first, but remaining ones are unordered. */
+/* Add FN to the (potentially NULL) overload set OVL. USING_OR_HIDDEN is >
+ zero if this is a using-decl. It is > 1 if we're exporting the
+ using decl. USING_OR_HIDDEN is < 0, if FN is hidden. (A decl
+ cannot be both using and hidden.) We keep the hidden decls first,
+ but remaining ones are unordered. */
tree
ovl_insert (tree fn, tree maybe_ovl, int using_or_hidden)
@@ -2264,7 +2300,11 @@ ovl_insert (tree fn, tree maybe_ovl, int using_or_hidden)
if (using_or_hidden < 0)
OVL_HIDDEN_P (maybe_ovl) = true;
if (using_or_hidden > 0)
- OVL_DEDUP_P (maybe_ovl) = OVL_USING_P (maybe_ovl) = true;
+ {
+ OVL_DEDUP_P (maybe_ovl) = OVL_USING_P (maybe_ovl) = true;
+ if (using_or_hidden > 1)
+ OVL_EXPORT_P (maybe_ovl) = true;
+ }
}
else
maybe_ovl = fn;
@@ -2676,6 +2716,52 @@ build_cp_fntype_variant (tree type, cp_ref_qualifier rqual,
return v;
}
+/* TYPE is a function or method type with a deferred exception
+ specification that has been parsed to RAISES. Fixup all the type
+ variants that are affected in place. Via decltype &| noexcept
+ tricks, the unparsed spec could have escaped into the type system.
+ The general case is hard to fixup canonical types for. */
+
+void
+fixup_deferred_exception_variants (tree type, tree raises)
+{
+ tree original = TYPE_RAISES_EXCEPTIONS (type);
+ tree cr = flag_noexcept_type ? canonical_eh_spec (raises) : NULL_TREE;
+
+ gcc_checking_assert (TREE_CODE (TREE_PURPOSE (original))
+ == DEFERRED_PARSE);
+
+ /* Though sucky, this walk will process the canonical variants
+ first. */
+ for (tree variant = TYPE_MAIN_VARIANT (type);
+ variant; variant = TYPE_NEXT_VARIANT (variant))
+ if (TYPE_RAISES_EXCEPTIONS (variant) == original)
+ {
+ gcc_checking_assert (variant != TYPE_MAIN_VARIANT (type));
+
+ if (!TYPE_STRUCTURAL_EQUALITY_P (variant))
+ {
+ cp_cv_quals var_quals = TYPE_QUALS (variant);
+ cp_ref_qualifier rqual = type_memfn_rqual (variant);
+
+ tree v = TYPE_MAIN_VARIANT (type);
+ for (; v; v = TYPE_NEXT_VARIANT (v))
+ if (TYPE_CANONICAL (v) == v
+ && cp_check_qualified_type (v, variant, var_quals,
+ rqual, cr, false))
+ break;
+ TYPE_RAISES_EXCEPTIONS (variant) = raises;
+
+ if (!v)
+ v = build_cp_fntype_variant (TYPE_CANONICAL (variant),
+ rqual, cr, false);
+ TYPE_CANONICAL (variant) = v;
+ }
+ else
+ TYPE_RAISES_EXCEPTIONS (variant) = raises;
+ }
+}
+
/* Build the FUNCTION_TYPE or METHOD_TYPE which may throw exceptions
listed in RAISES. */
@@ -2700,6 +2786,7 @@ bind_template_template_parm (tree t, tree newargs)
t2 = cxx_make_type (BOUND_TEMPLATE_TEMPLATE_PARM);
decl = build_decl (input_location,
TYPE_DECL, DECL_NAME (decl), NULL_TREE);
+ SET_DECL_TEMPLATE_PARM_P (decl);
/* These nodes have to be created to reflect new TYPE_DECL and template
arguments. */
@@ -2921,6 +3008,32 @@ array_type_nelts_total (tree type)
return sz;
}
+/* Return true if FNDECL is std::source_location::current () method. */
+
+bool
+source_location_current_p (tree fndecl)
+{
+ gcc_checking_assert (TREE_CODE (fndecl) == FUNCTION_DECL
+ && DECL_IMMEDIATE_FUNCTION_P (fndecl));
+ if (DECL_NAME (fndecl) == NULL_TREE
+ || TREE_CODE (TREE_TYPE (fndecl)) != FUNCTION_TYPE
+ || TREE_CODE (TREE_TYPE (TREE_TYPE (fndecl))) != RECORD_TYPE
+ || DECL_CONTEXT (fndecl) != TREE_TYPE (TREE_TYPE (fndecl))
+ || !id_equal (DECL_NAME (fndecl), "current"))
+ return false;
+
+ tree source_location = DECL_CONTEXT (fndecl);
+ if (TYPE_NAME (source_location) == NULL_TREE
+ || TREE_CODE (TYPE_NAME (source_location)) != TYPE_DECL
+ || TYPE_IDENTIFIER (source_location) == NULL_TREE
+ || !id_equal (TYPE_IDENTIFIER (source_location),
+ "source_location")
+ || !decl_in_std_namespace_p (TYPE_NAME (source_location)))
+ return false;
+
+ return true;
+}
+
struct bot_data
{
splay_tree target_remap;
@@ -3671,20 +3784,28 @@ cp_tree_equal (tree t1, tree t2)
case CALL_EXPR:
{
- tree arg1, arg2;
- call_expr_arg_iterator iter1, iter2;
- if (KOENIG_LOOKUP_P (t1) != KOENIG_LOOKUP_P (t2)
- || !called_fns_equal (CALL_EXPR_FN (t1), CALL_EXPR_FN (t2)))
+ if (KOENIG_LOOKUP_P (t1) != KOENIG_LOOKUP_P (t2))
return false;
- for (arg1 = first_call_expr_arg (t1, &iter1),
- arg2 = first_call_expr_arg (t2, &iter2);
- arg1 && arg2;
- arg1 = next_call_expr_arg (&iter1),
- arg2 = next_call_expr_arg (&iter2))
- if (!cp_tree_equal (arg1, arg2))
- return false;
- if (arg1 || arg2)
+
+ if (!called_fns_equal (CALL_EXPR_FN (t1), CALL_EXPR_FN (t2)))
+ return false;
+
+ call_expr_arg_iterator iter1, iter2;
+ init_call_expr_arg_iterator (t1, &iter1);
+ init_call_expr_arg_iterator (t2, &iter2);
+ if (iter1.n != iter2.n)
return false;
+
+ while (more_call_expr_args_p (&iter1))
+ {
+ tree arg1 = next_call_expr_arg (&iter1);
+ tree arg2 = next_call_expr_arg (&iter2);
+
+ gcc_checking_assert (arg1 && arg2);
+ if (!cp_tree_equal (arg1, arg2))
+ return false;
+ }
+
return true;
}
@@ -3716,7 +3837,12 @@ cp_tree_equal (tree t1, tree t2)
template. */
if (comparing_specializations
- && DECL_CONTEXT (t1) != DECL_CONTEXT (t2))
+ && DECL_CONTEXT (t1) != DECL_CONTEXT (t2)
+ /* Module duplicate checking can have t1 = new, t2 =
+ existing, and they should be considered matching at this
+ point. */
+ && (DECL_CONTEXT (t1) != map_context_from
+ && DECL_CONTEXT (t2) != map_context_to))
/* When comparing hash table entries, only an exact match is
good enough; we don't want to replace 'this' with the
version from another function. But be more flexible
@@ -3779,16 +3905,11 @@ cp_tree_equal (tree t1, tree t2)
CHECK_CONSTR_ARGS (t2)));
case TREE_VEC:
- {
- unsigned ix;
- if (TREE_VEC_LENGTH (t1) != TREE_VEC_LENGTH (t2))
- return false;
- for (ix = TREE_VEC_LENGTH (t1); ix--;)
- if (!cp_tree_equal (TREE_VEC_ELT (t1, ix),
- TREE_VEC_ELT (t2, ix)))
- return false;
- return true;
- }
+ /* These are template args. Really we should be getting the
+ caller to do this as it knows it to be true. */
+ if (!comp_template_args (t1, t2, NULL, NULL, false))
+ return false;
+ return true;
case SIZEOF_EXPR:
case ALIGNOF_EXPR:
@@ -3858,6 +3979,17 @@ cp_tree_equal (tree t1, tree t2)
return same_type_p (TRAIT_EXPR_TYPE1 (t1), TRAIT_EXPR_TYPE1 (t2))
&& cp_tree_equal (TRAIT_EXPR_TYPE2 (t1), TRAIT_EXPR_TYPE2 (t2));
+ case NON_LVALUE_EXPR:
+ case VIEW_CONVERT_EXPR:
+ /* Used for location wrappers with possibly NULL types. */
+ if (!TREE_TYPE (t1) || !TREE_TYPE (t2))
+ {
+ if (TREE_TYPE (t1) || TREE_TYPE (t2))
+ return false;
+ break;
+ }
+ /* FALLTHROUGH */
+
case CAST_EXPR:
case STATIC_CAST_EXPR:
case REINTERPRET_CAST_EXPR:
@@ -3865,9 +3997,8 @@ cp_tree_equal (tree t1, tree t2)
case DYNAMIC_CAST_EXPR:
case IMPLICIT_CONV_EXPR:
case NEW_EXPR:
+ case BIT_CAST_EXPR:
CASE_CONVERT:
- case NON_LVALUE_EXPR:
- case VIEW_CONVERT_EXPR:
if (!same_type_p (TREE_TYPE (t1), TREE_TYPE (t2)))
return false;
/* Now compare operands as usual. */
@@ -4050,13 +4181,14 @@ is_dummy_object (const_tree ob)
&& TREE_OPERAND (ob, 0) == void_node);
}
-/* Returns true if TYPE is a character type or std::byte. */
+/* Returns true if TYPE is char, unsigned char, or std::byte. */
bool
is_byte_access_type (tree type)
{
type = TYPE_MAIN_VARIANT (type);
- if (char_type_p (type))
+ if (type == char_type_node
+ || type == unsigned_char_type_node)
return true;
return (TREE_CODE (type) == ENUMERAL_TYPE
@@ -5112,6 +5244,7 @@ cp_walk_subtrees (tree *tp, int *walk_subtrees_p, walk_tree_fn func,
case CONST_CAST_EXPR:
case DYNAMIC_CAST_EXPR:
case IMPLICIT_CONV_EXPR:
+ case BIT_CAST_EXPR:
if (TREE_TYPE (*tp))
WALK_SUBTREE (TREE_TYPE (*tp));
@@ -5668,8 +5801,7 @@ cp_fix_function_decl_p (tree decl)
/* Don't fix same_body aliases. Although they don't have their own
CFG, they share it with what they alias to. */
- if (!node || !node->alias
- || !vec_safe_length (node->ref_list.references))
+ if (!node || !node->alias || !node->num_references ())
return true;
}