Commit 0dc09a61 by Mark Mitchell Committed by Mark Mitchell

ir.texi: Correct typo.

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

From-SVN: r34396
parent f5579898
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>
......
......@@ -1675,7 +1675,7 @@ that of the result, will be either integral, boolean, or floating-point.
@item ADDR_EXPR
These nodes are used to represent the address of an object. (These
expression will always have pointer or reference type.) The operand may
expressions will always have pointer or reference type.) The operand may
be another expression, or it may be a declaration.
As an extension, G++ allows users to take the address of a label. In
......
......@@ -1557,6 +1557,15 @@ write_expression (expr)
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);
......
......@@ -827,6 +827,9 @@ build_overload_value (type, value, flags)
/* Fall through. */
case REFERENCE_TYPE:
if (TREE_CODE (value) == ADDR_EXPR)
value = TREE_OPERAND (value, 0);
if (TREE_CODE (value) == VAR_DECL)
{
my_friendly_assert (DECL_NAME (value) != 0, 245);
......
......@@ -2762,8 +2762,9 @@ convert_nontype_argument (type, expr)
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
{
......@@ -2950,6 +2951,15 @@ convert_nontype_argument (type, expr)
{
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
......@@ -2957,17 +2967,16 @@ convert_nontype_argument (type, expr)
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. */
......@@ -2980,7 +2989,7 @@ convert_nontype_argument (type, expr)
TREE_TYPE (fn)),
0);
return fn;
expr = fn;
}
else
{
......@@ -2990,15 +2999,16 @@ convert_nontype_argument (type, expr)
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;
......@@ -8589,7 +8599,7 @@ unify (tparms, targs, parm, arg, strict)
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))
......
......@@ -6,6 +6,12 @@ template <int i> void f()
f<i+1>(); // ERROR - excessive recursion
}
// We should never need this specialization because we should issue an
// error first about the recursive template instantions. But, in case
// the compiler fails to catch the error, this will keep it from
// running forever instantiating more and more templates.
template <> void f<100>();
int main()
{
f<0>(); // ERROR - starting here
......
// Build don't link:
// Origin: Mark Mitchell <mark@codesourcery.com>
template <class T, T&>
class C;
template <int& I>
class C<int, I> {};
int i;
C<int, i> c;
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