* 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
+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.
#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)
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));
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));
{
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);
}
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)
{
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
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);
}
/* 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))))
{
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 <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);
- }
+ 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
}
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);
+}
\f
/* Add OFFSET to all base types of T.