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:
parent
e675f62571
commit
53929c47c5
@ -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.
|
||||
|
@ -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));
|
||||
|
@ -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));
|
||||
|
@ -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);
|
||||
}
|
||||
|
53
gcc/cp/pt.c
53
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 <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
|
||||
|
@ -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.
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user