Commit 53929c47 by Jason Merrill Committed by Jason Merrill

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
parent e675f625
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> 1998-07-20 Dave Brolley <brolley@cygnus.com>
* lex.c (mbchar.h): #include it. * lex.c (mbchar.h): #include it.
......
...@@ -676,14 +676,6 @@ struct lang_type ...@@ -676,14 +676,6 @@ struct lang_type
#define TYPE_HAS_ASSIGNMENT(NODE) (TYPE_LANG_SPECIFIC(NODE)->type_flags.has_assignment) #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) #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, /* Nonzero for _CLASSTYPE means that operator new and delete are defined,
respectively. */ respectively. */
#define TYPE_GETS_NEW(NODE) (TYPE_LANG_SPECIFIC(NODE)->type_flags.gets_new) #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)); ...@@ -1728,6 +1720,7 @@ extern void check_function_format PROTO((tree, tree, tree));
NOP_EXPR is used as a special case (see truthvalue_conversion). */ NOP_EXPR is used as a special case (see truthvalue_conversion). */
extern void binary_op_error PROTO((enum tree_code)); extern void binary_op_error PROTO((enum tree_code));
extern tree cp_build_type_variant PROTO((tree, int, int)); 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)); extern void c_expand_expr_stmt PROTO((tree));
/* Validate the expression after `case' and apply default promotions. */ /* Validate the expression after `case' and apply default promotions. */
extern tree check_case_value PROTO((tree)); extern tree check_case_value PROTO((tree));
......
...@@ -3002,7 +3002,7 @@ duplicate_decls (newdecl, olddecl) ...@@ -3002,7 +3002,7 @@ duplicate_decls (newdecl, olddecl)
TREE_TYPE (newdecl) = TREE_TYPE (olddecl) = newtype; TREE_TYPE (newdecl) = TREE_TYPE (olddecl) = newtype;
/* Lay the type out, unless already done. */ /* 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 && TREE_TYPE (newdecl) != error_mark_node
&& !(processing_template_decl && uses_template_parms (newdecl))) && !(processing_template_decl && uses_template_parms (newdecl)))
layout_type (TREE_TYPE (newdecl)); layout_type (TREE_TYPE (newdecl));
......
...@@ -1005,7 +1005,7 @@ build_mangled_name_for_type_with_Gcode (type, extra_Gcode) ...@@ -1005,7 +1005,7 @@ build_mangled_name_for_type_with_Gcode (type, extra_Gcode)
{ {
if (TYPE_PTRMEMFUNC_P (type)) if (TYPE_PTRMEMFUNC_P (type))
type = TYPE_PTRMEMFUNC_FN_TYPE (type); type = TYPE_PTRMEMFUNC_FN_TYPE (type);
type = CANONICAL_TYPE_VARIANT (type); type = canonical_type_variant (type);
process_modifiers (type); process_modifiers (type);
process_overload_item (type, extra_Gcode); process_overload_item (type, extra_Gcode);
} }
...@@ -1069,7 +1069,7 @@ build_mangled_name (parmtypes, begin, end) ...@@ -1069,7 +1069,7 @@ build_mangled_name (parmtypes, begin, end)
for (; parmtypes && parmtypes != void_list_node; for (; parmtypes && parmtypes != void_list_node;
parmtypes = TREE_CHAIN (parmtypes)) parmtypes = TREE_CHAIN (parmtypes))
{ {
tree parmtype = CANONICAL_TYPE_VARIANT (TREE_VALUE (parmtypes)); tree parmtype = canonical_type_variant (TREE_VALUE (parmtypes));
if (old_style_repeats) if (old_style_repeats)
{ {
...@@ -1245,12 +1245,18 @@ process_overload_item (parmtype, extra_Gcode) ...@@ -1245,12 +1245,18 @@ process_overload_item (parmtype, extra_Gcode)
if (TYPE_DOMAIN (parmtype) == NULL_TREE) if (TYPE_DOMAIN (parmtype) == NULL_TREE)
error("pointer/reference to array of unknown bound in parm type"); error("pointer/reference to array of unknown bound in parm type");
else else
{ {
length = array_type_nelts (parmtype); tree length = array_type_nelts (parmtype);
if (TREE_CODE (length) == INTEGER_CST) if (TREE_CODE (length) != INTEGER_CST || flag_do_squangling)
icat (TREE_INT_CST_LOW (length) + 1); {
} length = fold (build (PLUS_EXPR, TREE_TYPE (length),
OB_PUTC ('_'); 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; goto more;
} }
#else #else
...@@ -1611,7 +1617,7 @@ build_decl_overload_real (dname, parms, ret_type, tparms, targs, ...@@ -1611,7 +1617,7 @@ build_decl_overload_real (dname, parms, ret_type, tparms, targs,
tree temp = TREE_VALUE (t); tree temp = TREE_VALUE (t);
TREE_USED (temp) = 0; TREE_USED (temp) = 0;
/* clear out the type variant in case we used it */ /* clear out the type variant in case we used it */
temp = CANONICAL_TYPE_VARIANT (temp); temp = canonical_type_variant (temp);
TREE_USED (temp) = 0; TREE_USED (temp) = 0;
t = TREE_CHAIN (t); t = TREE_CHAIN (t);
} }
......
...@@ -6577,6 +6577,30 @@ unify (tparms, targs, parm, arg, strict, explicit_mask) ...@@ -6577,6 +6577,30 @@ unify (tparms, targs, parm, arg, strict, explicit_mask)
/* Matched cases are handled by the ARG == PARM test above. */ /* Matched cases are handled by the ARG == PARM test above. */
return 1; 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: default:
if (IS_EXPR_CODE_CLASS (TREE_CODE_CLASS (TREE_CODE (parm)))) if (IS_EXPR_CODE_CLASS (TREE_CODE_CLASS (TREE_CODE (parm))))
{ {
...@@ -6596,34 +6620,11 @@ unify (tparms, targs, parm, arg, strict, explicit_mask) ...@@ -6596,34 +6620,11 @@ unify (tparms, targs, parm, arg, strict, explicit_mask)
figuring it out. */ figuring it out. */
tree t = tree t =
maybe_fold_nontype_arg (tsubst_expr (parm, targs, NULL_TREE)); 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. */ /* 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); explicit_mask);
else else
/* Bad, we couldn't simplify this. Assume it doesn't /* Bad, we couldn't simplify this. Assume it doesn't
......
...@@ -546,6 +546,29 @@ cp_build_type_variant (type, constp, volatilep) ...@@ -546,6 +546,29 @@ cp_build_type_variant (type, constp, volatilep)
} }
return 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. /* Add OFFSET to all base types of T.
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment