From: Jason Merrill Date: Tue, 21 Jul 1998 18:16:09 +0000 (+0000) Subject: tree.c (canonical_type_variant): New fn to handle arrays. X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=53929c47c5c916744f34d54b63b1d984a3e2584f;p=gcc.git tree.c (canonical_type_variant): New fn to handle arrays. * tree.c (canonical_type_variant): New fn to handle arrays. * cp-tree.h (CANONICAL_TYPE_VARIANT): Remove. * pt.c (unify, default case): Also fold arg. Fix array bounds case. * method.c (process_overload_item): Use build_overload_value for arrays. From-SVN: r21324 --- diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index bcfaec9442f..d9cace222ed 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,11 @@ +1998-07-21 Jason Merrill + + * tree.c (canonical_type_variant): New fn to handle arrays. + * cp-tree.h (CANONICAL_TYPE_VARIANT): Remove. + * pt.c (unify, default case): Also fold arg. Fix array bounds case. + * method.c (process_overload_item): Use build_overload_value for + arrays. + 1998-07-20 Dave Brolley * lex.c (mbchar.h): #include it. diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index f6c1e23bdd6..b844355f0ff 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -676,14 +676,6 @@ struct lang_type #define TYPE_HAS_ASSIGNMENT(NODE) (TYPE_LANG_SPECIFIC(NODE)->type_flags.has_assignment) #define TYPE_HAS_REAL_ASSIGNMENT(NODE) (TYPE_LANG_SPECIFIC(NODE)->type_flags.has_real_assignment) -/* Returns the canonical version of TYPE. In other words, if TYPE is - a typedef, returns the underlying type. The cv-qualification of - the type returned matches the type input; they will always be - compatible types. */ -#define CANONICAL_TYPE_VARIANT(NODE) \ - (cp_build_type_variant (TYPE_MAIN_VARIANT (NODE), \ - TYPE_READONLY (NODE), TYPE_VOLATILE (NODE))) - /* Nonzero for _CLASSTYPE means that operator new and delete are defined, respectively. */ #define TYPE_GETS_NEW(NODE) (TYPE_LANG_SPECIFIC(NODE)->type_flags.gets_new) @@ -1728,6 +1720,7 @@ extern void check_function_format PROTO((tree, tree, tree)); NOP_EXPR is used as a special case (see truthvalue_conversion). */ extern void binary_op_error PROTO((enum tree_code)); extern tree cp_build_type_variant PROTO((tree, int, int)); +extern tree canonical_type_variant PROTO((tree)); extern void c_expand_expr_stmt PROTO((tree)); /* Validate the expression after `case' and apply default promotions. */ extern tree check_case_value PROTO((tree)); diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index 913b9abd00a..986b8c05336 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -3002,7 +3002,7 @@ duplicate_decls (newdecl, olddecl) TREE_TYPE (newdecl) = TREE_TYPE (olddecl) = newtype; /* Lay the type out, unless already done. */ - if (newtype != CANONICAL_TYPE_VARIANT (oldtype) + if (newtype != canonical_type_variant (oldtype) && TREE_TYPE (newdecl) != error_mark_node && !(processing_template_decl && uses_template_parms (newdecl))) layout_type (TREE_TYPE (newdecl)); diff --git a/gcc/cp/method.c b/gcc/cp/method.c index 6c4fd46d192..d718a44920b 100644 --- a/gcc/cp/method.c +++ b/gcc/cp/method.c @@ -1005,7 +1005,7 @@ build_mangled_name_for_type_with_Gcode (type, extra_Gcode) { if (TYPE_PTRMEMFUNC_P (type)) type = TYPE_PTRMEMFUNC_FN_TYPE (type); - type = CANONICAL_TYPE_VARIANT (type); + type = canonical_type_variant (type); process_modifiers (type); process_overload_item (type, extra_Gcode); } @@ -1069,7 +1069,7 @@ build_mangled_name (parmtypes, begin, end) for (; parmtypes && parmtypes != void_list_node; parmtypes = TREE_CHAIN (parmtypes)) { - tree parmtype = CANONICAL_TYPE_VARIANT (TREE_VALUE (parmtypes)); + tree parmtype = canonical_type_variant (TREE_VALUE (parmtypes)); if (old_style_repeats) { @@ -1245,12 +1245,18 @@ process_overload_item (parmtype, extra_Gcode) if (TYPE_DOMAIN (parmtype) == NULL_TREE) error("pointer/reference to array of unknown bound in parm type"); else - { - length = array_type_nelts (parmtype); - if (TREE_CODE (length) == INTEGER_CST) - icat (TREE_INT_CST_LOW (length) + 1); - } - OB_PUTC ('_'); + { + tree length = array_type_nelts (parmtype); + if (TREE_CODE (length) != INTEGER_CST || flag_do_squangling) + { + length = fold (build (PLUS_EXPR, TREE_TYPE (length), + length, integer_one_node)); + STRIP_NOPS (length); + } + build_overload_value (sizetype, length, 1); + } + if (numeric_output_need_bar && ! flag_do_squangling) + OB_PUTC ('_'); goto more; } #else @@ -1611,7 +1617,7 @@ build_decl_overload_real (dname, parms, ret_type, tparms, targs, tree temp = TREE_VALUE (t); TREE_USED (temp) = 0; /* clear out the type variant in case we used it */ - temp = CANONICAL_TYPE_VARIANT (temp); + temp = canonical_type_variant (temp); TREE_USED (temp) = 0; t = TREE_CHAIN (t); } diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 0f1dbdd8662..eaf73ef6f00 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -6577,6 +6577,30 @@ unify (tparms, targs, parm, arg, strict, explicit_mask) /* Matched cases are handled by the ARG == PARM test above. */ return 1; + case MINUS_EXPR: + if (TREE_CODE (TREE_OPERAND (parm, 1)) == INTEGER_CST) + { + /* We handle this case specially, since it comes up with + arrays. In particular, something like: + + template void f(int (&x)[N]); + + Here, we are trying to unify the range type, which + looks like [0 ... (N - 1)]. */ + tree t, t1, t2; + t1 = TREE_OPERAND (parm, 0); + t2 = TREE_OPERAND (parm, 1); + + /* Should this be a regular fold? */ + t = maybe_fold_nontype_arg (build (PLUS_EXPR, + integer_type_node, + arg, t2)); + + return unify (tparms, targs, t1, t, UNIFY_ALLOW_NONE, + explicit_mask); + } + /* else fall through */ + default: if (IS_EXPR_CODE_CLASS (TREE_CODE_CLASS (TREE_CODE (parm)))) { @@ -6596,34 +6620,11 @@ unify (tparms, targs, parm, arg, strict, explicit_mask) figuring it out. */ tree t = maybe_fold_nontype_arg (tsubst_expr (parm, targs, NULL_TREE)); - enum tree_code tc = TREE_CODE (t); - - if (tc == MINUS_EXPR - && TREE_CODE (TREE_OPERAND (t, 0)) == TEMPLATE_PARM_INDEX - && TREE_CODE (TREE_OPERAND (t, 1)) == INTEGER_CST) - { - /* We handle this case specially, since it comes up with - arrays. In particular, something like: - - template void f(int (&x)[N]); - - Here, we are trying to unify the range type, which - looks like [0 ... (N - 1)]. */ - tree t1, t2; - t1 = TREE_OPERAND (parm, 0); - t2 = TREE_OPERAND (parm, 1); - - t = maybe_fold_nontype_arg (build (PLUS_EXPR, - integer_type_node, - arg, t2)); - - return unify (tparms, targs, t1, t, UNIFY_ALLOW_NONE, - explicit_mask); - } + tree a = maybe_fold_nontype_arg (arg); - if (!IS_EXPR_CODE_CLASS (TREE_CODE_CLASS (tc))) + if (!IS_EXPR_CODE_CLASS (TREE_CODE_CLASS (TREE_CODE (t)))) /* Good, we mangaged to simplify the exression. */ - return unify (tparms, targs, t, arg, UNIFY_ALLOW_NONE, + return unify (tparms, targs, t, a, UNIFY_ALLOW_NONE, explicit_mask); else /* Bad, we couldn't simplify this. Assume it doesn't diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c index 2a5ad2b6d59..02243282e5e 100644 --- a/gcc/cp/tree.c +++ b/gcc/cp/tree.c @@ -546,6 +546,29 @@ cp_build_type_variant (type, constp, volatilep) } return build_type_variant (type, constp, volatilep); } + +/* Returns the canonical version of TYPE. In other words, if TYPE is + a typedef, returns the underlying type. The cv-qualification of + the type returned matches the type input; they will always be + compatible types. */ + +tree +canonical_type_variant (t) + tree t; +{ + int constp, volatilep; + if (TREE_CODE (t) == ARRAY_TYPE) + { + constp = TYPE_READONLY (TREE_TYPE (t)); + volatilep = TYPE_VOLATILE (TREE_TYPE (t)); + } + else + { + constp = TYPE_READONLY (t); + volatilep = TYPE_VOLATILE (t); + } + return cp_build_type_variant (TYPE_MAIN_VARIANT (t), constp, volatilep); +} /* Add OFFSET to all base types of T.