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
This commit is contained in:
Jason Merrill 1998-07-21 18:16:09 +00:00 committed by Jason Merrill
parent e675f62571
commit 53929c47c5
6 changed files with 75 additions and 44 deletions

View File

@ -1,3 +1,11 @@
1998-07-21 Jason Merrill <jason@yorick.cygnus.com>
* 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 <brolley@cygnus.com>
* lex.c (mbchar.h): #include it.

View File

@ -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));

View File

@ -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));

View File

@ -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);
}

View File

@ -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 <int N> 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);
tree a = maybe_fold_nontype_arg (arg);
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 <int N> 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);
}
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

View File

@ -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.