+2000-06-04 Mark Mitchell <mark@codesourcery.com>
+
+ * ir.texi: Correct typo.
+ * mangle.c (write_expression): Handle non-type template arguments
+ with reference type.
+ * method.c (build_overload_value): Likewise.
+ * pt.c (convert_nontype_argument): Explicitly represent conversion
+ to a reference with an ADDR_EXPR.
+ (unify): Always unify arguments in left-to-right order.
+
2000-06-03 Alex Samuel <samuel@codesourcery.com>
Mark Mitchell <mark@codesourcery.com>
code = TREE_CODE (expr);
}
+ /* When we bind a variable or function to a non-type template
+ argument with reference type, we create an ADDR_EXPR to show
+ the fact that the entity's address has been taken. But, we
+ don't actually want to output a mangling code for the `&'. */
+ if (TREE_CODE (expr) == ADDR_EXPR
+ && TREE_TYPE (expr)
+ && TREE_CODE (TREE_TYPE (expr)) == REFERENCE_TYPE)
+ expr = TREE_OPERAND (expr, 0);
+
/* If it wasn't any of those, recursively expand the expression. */
write_string (operator_name_info[(int) code].mangled_name);
tree e = expr;
STRIP_NOPS (e);
- if (TREE_CODE (type) == REFERENCE_TYPE
- || TREE_CODE (expr_type) == ARRAY_TYPE)
+ if (TREE_CODE (expr_type) == ARRAY_TYPE
+ || (TREE_CODE (type) == REFERENCE_TYPE
+ && TREE_CODE (e) != ADDR_EXPR))
referent = e;
else
{
{
tree type_referred_to = TREE_TYPE (type);
+ /* If this expression already has reference type, get the
+ underling object. */
+ if (TREE_CODE (expr_type) == REFERENCE_TYPE)
+ {
+ my_friendly_assert (TREE_CODE (expr) == ADDR_EXPR, 20000604);
+ expr = TREE_OPERAND (expr, 0);
+ expr_type = TREE_TYPE (expr);
+ }
+
if (TREE_CODE (type_referred_to) == FUNCTION_TYPE)
{
/* For a non-type template-parameter of type reference to
template-argument represents a set of overloaded
functions, the matching function is selected from the
set (_over.over_). */
- tree fns = expr;
tree fn;
- fn = instantiate_type (type_referred_to, fns, 0);
+ fn = instantiate_type (type_referred_to, expr, 0);
if (fn == error_mark_node)
return error_mark_node;
if (!TREE_PUBLIC (fn))
{
- if (really_overloaded_fn (fns))
+ if (really_overloaded_fn (expr))
/* Don't issue an error here; we might get a different
function if the overloading had worked out
differently. */
TREE_TYPE (fn)),
0);
- return fn;
+ expr = fn;
}
else
{
identical) type of the template-argument. The
template-parameter is bound directly to the
template-argument, which must be an lvalue. */
- if ((TYPE_MAIN_VARIANT (expr_type)
- != TYPE_MAIN_VARIANT (type_referred_to))
+ if (!same_type_p (TYPE_MAIN_VARIANT (expr_type),
+ TYPE_MAIN_VARIANT (type_referred_to))
|| !at_least_as_qualified_p (type_referred_to,
expr_type)
|| !real_lvalue_p (expr))
- return error_mark_node;
- else
- return expr;
+ expr = error_mark_node;
}
+
+ mark_addressable (expr);
+ return build1 (ADDR_EXPR, type, expr);
}
break;
return 1;
if (TREE_VEC_LENGTH (parm) != TREE_VEC_LENGTH (arg))
return 1;
- for (i = TREE_VEC_LENGTH (parm) - 1; i >= 0; i--)
+ for (i = 0; i < TREE_VEC_LENGTH (parm); ++i)
if (unify (tparms, targs,
TREE_VEC_ELT (parm, i), TREE_VEC_ELT (arg, i),
UNIFY_ALLOW_NONE))