Commit 477f6664 by Jason Merrill Committed by Jason Merrill

pt.c (tsubst_decl): A FUNCTION_DECL has DECL_RESULT, not DECL_TEMPLATE_RESULT.

        * pt.c (tsubst_decl): A FUNCTION_DECL has DECL_RESULT, not
        DECL_TEMPLATE_RESULT.

        * search.c (lookup_field_r): Call lookup_fnfields_1, not
        lookup_fnfields_here.

        * parse.y (typename_sub2): Return the TYPE_DECL, not the type.

        * call.c (build_object_call): Also allow conversions that return
        reference to pointer to function.
        (add_conv_candidate): Handle totype being ref to ptr to fn.
        (build_field_call): Also allow members of type reference to function.
        Lose support for calling pointer to METHOD_TYPE fields.

        * error.c (dump_expr): Handle *_CAST_EXPR.

        * typeck2.c (build_scoped_ref): Always convert to the naming class.

        * tree.c (break_out_cleanups): Lose.
        * cp-tree.h: Remove prototype.
        * typeck.c (build_component_ref): Don't break_out_cleanups.
        (build_compound_expr): Likewise.
        * semantics.c (finish_expr_stmt): Likewise.

From-SVN: r38417
parent e98df22a
2000-12-20 Jason Merrill <jason@redhat.com>
* pt.c (tsubst_decl): A FUNCTION_DECL has DECL_RESULT, not
DECL_TEMPLATE_RESULT.
* search.c (lookup_field_r): Call lookup_fnfields_1, not
lookup_fnfields_here.
* parse.y (typename_sub2): Return the TYPE_DECL, not the type.
* call.c (build_object_call): Also allow conversions that return
reference to pointer to function.
(add_conv_candidate): Handle totype being ref to ptr to fn.
(build_field_call): Also allow members of type reference to function.
Lose support for calling pointer to METHOD_TYPE fields.
* error.c (dump_expr): Handle *_CAST_EXPR.
* typeck2.c (build_scoped_ref): Always convert to the naming class.
* tree.c (break_out_cleanups): Lose.
* cp-tree.h: Remove prototype.
* typeck.c (build_component_ref): Don't break_out_cleanups.
(build_compound_expr): Likewise.
* semantics.c (finish_expr_stmt): Likewise.
2000-12-20 Richard Henderson <rth@redhat.com>
* cp-tree.h: Update declarations.
......
......@@ -156,15 +156,11 @@ build_field_call (basetype_path, instance_ptr, name, parms)
if (IS_AGGR_TYPE (TREE_TYPE (instance)))
return build_opfncall (CALL_EXPR, LOOKUP_NORMAL,
instance, parms, NULL_TREE);
else if (TREE_CODE (TREE_TYPE (instance)) == POINTER_TYPE)
{
if (TREE_CODE (TREE_TYPE (TREE_TYPE (instance))) == FUNCTION_TYPE)
else if (TREE_CODE (TREE_TYPE (instance)) == FUNCTION_TYPE
|| (TREE_CODE (TREE_TYPE (instance)) == POINTER_TYPE
&& (TREE_CODE (TREE_TYPE (TREE_TYPE (instance)))
== FUNCTION_TYPE)))
return build_function_call (instance, parms);
else if (TREE_CODE (TREE_TYPE (TREE_TYPE (instance)))
== METHOD_TYPE)
return build_function_call
(instance, tree_cons (NULL_TREE, instance_ptr, parms));
}
}
return NULL_TREE;
......@@ -1422,13 +1418,19 @@ add_conv_candidate (candidates, fn, obj, arglist)
tree fn, obj, arglist;
{
tree totype = TREE_TYPE (TREE_TYPE (fn));
tree parmlist = TYPE_ARG_TYPES (TREE_TYPE (totype));
int i, len = list_length (arglist) + 1;
tree convs = make_tree_vec (len);
tree parmnode = parmlist;
tree argnode = arglist;
int viable = 1;
int flags = LOOKUP_NORMAL;
int i, len, viable, flags;
tree parmlist, convs, parmnode, argnode;
for (parmlist = totype; TREE_CODE (parmlist) != FUNCTION_TYPE; )
parmlist = TREE_TYPE (parmlist);
parmlist = TYPE_ARG_TYPES (parmlist);
len = list_length (arglist) + 1;
convs = make_tree_vec (len);
parmnode = parmlist;
argnode = arglist;
viable = 1;
flags = LOOKUP_NORMAL;
/* Don't bother looking up the same type twice. */
if (candidates && candidates->fn == totype)
......@@ -2659,8 +2661,12 @@ build_object_call (obj, args)
tree totype = TREE_TYPE (TREE_TYPE (OVL_CURRENT (fns)));
if ((TREE_CODE (totype) == POINTER_TYPE
|| TREE_CODE (totype) == REFERENCE_TYPE)
&& TREE_CODE (TREE_TYPE (totype)) == FUNCTION_TYPE)
|| (TREE_CODE (totype) == REFERENCE_TYPE
&& TREE_CODE (TREE_TYPE (totype)) == FUNCTION_TYPE)
|| (TREE_CODE (totype) == REFERENCE_TYPE
&& TREE_CODE (TREE_TYPE (totype)) == POINTER_TYPE
&& TREE_CODE (TREE_TYPE (TREE_TYPE (totype))) == FUNCTION_TYPE))
for (; fns; fns = OVL_NEXT (fns))
{
tree fn = OVL_CURRENT (fns);
......
......@@ -4401,7 +4401,6 @@ extern int lvalue_p PARAMS ((tree));
extern int lvalue_or_else PARAMS ((tree, const char *));
extern tree build_cplus_new PARAMS ((tree, tree));
extern tree get_target_expr PARAMS ((tree));
extern tree break_out_cleanups PARAMS ((tree));
extern tree break_out_calls PARAMS ((tree));
extern tree build_cplus_method_type PARAMS ((tree, tree, tree));
extern tree build_cplus_staticfn_type PARAMS ((tree, tree, tree));
......
......@@ -2051,6 +2051,24 @@ dump_expr (t, flags)
}
break;
case STATIC_CAST_EXPR:
output_add_string (scratch_buffer, "static_cast<");
goto cast;
case REINTERPRET_CAST_EXPR:
output_add_string (scratch_buffer, "reinterpret_cast<");
goto cast;
case CONST_CAST_EXPR:
output_add_string (scratch_buffer, "const_cast<");
goto cast;
case DYNAMIC_CAST_EXPR:
output_add_string (scratch_buffer, "dynamic_cast<");
cast:
dump_type (TREE_TYPE (t), flags);
output_add_string (scratch_buffer, ">(");
dump_expr (TREE_OPERAND (t, 0), flags);
print_right_paren (scratch_buffer);
break;
case LOOKUP_EXPR:
print_tree_identifier (scratch_buffer, TREE_OPERAND (t, 0));
break;
......
......@@ -3056,6 +3056,8 @@ typename_sub1:
{
if (TREE_CODE ($1) == IDENTIFIER_NODE)
cp_error ("`%T' is not a class or namespace", $1);
else if (TREE_CODE ($1) == TYPE_DECL)
$$ = TREE_TYPE ($1);
}
| typename_sub1 typename_sub2
{
......@@ -3078,24 +3080,26 @@ typename_sub1:
= make_typename_type ($1, $3, /*complain=*/1); }
;
/* This needs to return a TYPE_DECL for simple names so that we don't
forget what name was used. */
typename_sub2:
TYPENAME SCOPE
{
if (TREE_CODE ($1) != IDENTIFIER_NODE)
$1 = lastiddecl;
if (TREE_CODE ($1) != TYPE_DECL)
$$ = lastiddecl;
/* Retrieve the type for the identifier, which might involve
some computation. */
got_scope = $$ = complete_type (IDENTIFIER_TYPE_VALUE ($1));
got_scope = complete_type (TREE_TYPE ($$));
if ($$ == error_mark_node)
cp_error ("`%T' is not a class or namespace", $1);
}
| SELFNAME SCOPE
{
if (TREE_CODE ($1) != IDENTIFIER_NODE)
if (TREE_CODE ($1) != TYPE_DECL)
$$ = lastiddecl;
got_scope = $$ = complete_type (TREE_TYPE ($$));
got_scope = complete_type (TREE_TYPE ($$));
}
| template_type SCOPE
{ got_scope = $$ = complete_type (TREE_TYPE ($$)); }
......
......@@ -5715,7 +5715,7 @@ tsubst_decl (t, args, type, in_decl)
DECL_ARGUMENTS (r) = tsubst (DECL_ARGUMENTS (t), args,
/*complain=*/1, t);
DECL_TEMPLATE_RESULT (r) = NULL_TREE;
DECL_RESULT (r) = NULL_TREE;
TREE_STATIC (r) = 0;
TREE_PUBLIC (r) = TREE_PUBLIC (t);
......
......@@ -1251,7 +1251,9 @@ is_subobject_of_p (parent, binfo, most_derived)
/* Very similar to lookup_fnfields_1 but it ensures that at least one
function was declared inside the class given by TYPE. It really should
only return functions that match the given TYPE. */
only return functions that match the given TYPE. Therefore, it should
only be called for situations that ignore using-declarations, such as
determining overrides. */
static int
lookup_fnfields_here (type, name)
......@@ -1359,7 +1361,7 @@ lookup_field_r (binfo, data)
with the same name, the type is hidden by the function. */
if (!lfi->want_type)
{
int idx = lookup_fnfields_here (type, lfi->name);
int idx = lookup_fnfields_1 (type, lfi->name);
if (idx >= 0)
nval = TREE_VEC_ELT (CLASSTYPE_METHOD_VEC (type), idx);
}
......
......@@ -214,9 +214,6 @@ finish_expr_stmt (expr)
if (stmts_are_full_exprs_p ())
expr = convert_to_void (expr, "statement");
if (!processing_template_decl)
expr = break_out_cleanups (expr);
r = add_stmt (build_stmt (EXPR_STMT, expr));
}
......
......@@ -317,37 +317,6 @@ get_target_expr (init)
return build_target_expr_with_type (init, TREE_TYPE (init));
}
/* Recursively search EXP for CALL_EXPRs that need cleanups and replace
these CALL_EXPRs with tree nodes that will perform the cleanups. */
tree
break_out_cleanups (exp)
tree exp;
{
tree tmp = exp;
if (TREE_CODE (tmp) == CALL_EXPR
&& TYPE_HAS_NONTRIVIAL_DESTRUCTOR (TREE_TYPE (tmp)))
return build_cplus_new (TREE_TYPE (tmp), tmp);
while (TREE_CODE (tmp) == NOP_EXPR
|| TREE_CODE (tmp) == CONVERT_EXPR
|| TREE_CODE (tmp) == NON_LVALUE_EXPR)
{
if (TREE_CODE (TREE_OPERAND (tmp, 0)) == CALL_EXPR
&& TYPE_HAS_NONTRIVIAL_DESTRUCTOR (TREE_TYPE (TREE_OPERAND (tmp, 0))))
{
TREE_OPERAND (tmp, 0)
= build_cplus_new (TREE_TYPE (TREE_OPERAND (tmp, 0)),
TREE_OPERAND (tmp, 0));
break;
}
else
tmp = TREE_OPERAND (tmp, 0);
}
return exp;
}
/* Recursively perform a preorder search EXP for CALL_EXPRs, making
copies where they are found. Returns a deep copy all nodes transitively
containing CALL_EXPRs. */
......
......@@ -2278,8 +2278,7 @@ build_component_ref (datum, component, basetype_path, protect)
field_type = cp_build_qualified_type (field_type, type_quals);
}
ref = fold (build (COMPONENT_REF, field_type,
break_out_cleanups (datum), field));
ref = fold (build (COMPONENT_REF, field_type, datum, field));
/* Mark the expression const or volatile, as appropriate. Even
though we've dealt with the type above, we still have to mark the
......@@ -5039,8 +5038,7 @@ build_compound_expr (list)
if (! TREE_SIDE_EFFECTS (first) && ! pedantic)
return rest;
return build (COMPOUND_EXPR, TREE_TYPE (rest),
break_out_cleanups (first), rest);
return build (COMPOUND_EXPR, TREE_TYPE (rest), first, rest);
}
tree
......
......@@ -957,9 +957,10 @@ process_init_constructor (type, init, elts)
the A part of the C object named by X. In this case,
DATUM would be x, and BASETYPE would be A.
Note that this is nonconformant; the standard specifies that first
we look up ii in A, then convert x to an L& and pull out the ii part.
But narrowing seems to be standard practice, so let's do it anyway. */
I used to think that this was nonconformant, that the standard specified
that first we look up ii in A, then convert x to an L& and pull out the
ii part. But in fact, it does say that we convert x to an A&; A here
is known as the "naming class". (jason 2000-12-19) */
tree
build_scoped_ref (datum, basetype)
......@@ -967,16 +968,10 @@ build_scoped_ref (datum, basetype)
tree basetype;
{
tree ref;
tree type = TREE_TYPE (datum);
if (datum == error_mark_node)
return error_mark_node;
/* Don't do this if it would cause an error or if we're being pedantic. */
if (! ACCESSIBLY_UNIQUELY_DERIVED_P (basetype, type)
|| pedantic)
return datum;
ref = build_unary_op (ADDR_EXPR, datum, 0);
ref = convert_pointer_to (basetype, ref);
......
......@@ -19,8 +19,8 @@ class C : public A, public B {};
void foo() {
// straight call
C x;
x.A::ii = 5; // ERROR - L is ambiguous base
x.A::foo(x.A::ii); // ERROR - L is ambiguous base
x.A::ii = 5;
x.A::foo(x.A::ii);
// 5.1 Primary expressions
// p 8
......
......@@ -9,5 +9,5 @@ struct B : public A {
struct C : public A {
};
struct D : public C, public B {
void fun() { C::aa = 10; } // ERROR - conversion to A is ambiguous
void fun() { C::aa = 10; }
};
// Test that various calls to non-functions work.
void f () { }
typedef void (*fptr)();
typedef void (&fref)();
fptr p = f;
fref r = f;
const fptr &pr = p;
struct A {
fptr p;
A (fptr n): p(n) { }
operator fptr () { return p; }
};
struct B {
fref r;
B (fptr n): r(*n) { }
operator const fref () { return r; }
};
struct C {
const fptr &pr;
C (fptr n): pr(n) { }
operator const fptr& () { return pr; }
};
int main ()
{
f();
p();
r();
pr();
A a (f);
a();
a.p();
B b (f);
b();
b.r();
C c (f);
c();
c.pr();
}
// Test that referring to an ambiguous base in name lookup does not
// interfere with accessing the field, which is not ambiguous.
// Test that referring to an ambiguous base in name lookup prevents
// access to the field, even though the field is not ambiguous.
// Build don't link:
......@@ -14,10 +14,10 @@ struct E: public C, public D {
};
void E::f() {
B::i = 0;
B::i = 0; // ERROR - B is ambiguous
}
void f () {
E e;
e.B::i = 0;
e.B::i = 0; // ERROR - B is ambiguous
}
// Bug: typename_sub2 returned the type, so we tried to look up "A" in B.
// Build don't link:
struct A { struct A1 { }; };
struct B {
typedef A Q;
};
struct C: public B::Q::A1 { };
// Test that we can represent static_casts in template arg lists.
// Build don't link:
template <int I> struct A { };
template <class T> struct B {
A<static_cast<T>(3.14)> a;
};
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