diff options
Diffstat (limited to 'gcc/cp/tree.c')
-rw-r--r-- | gcc/cp/tree.c | 222 |
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; } |