aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2000-12-21 12:50:10 -0500
committerJason Merrill <jason@gcc.gnu.org>2000-12-21 12:50:10 -0500
commit477f6664a4b1316583e5a71f0edd30faefeeaab5 (patch)
treee6f13c06ffc9b6aad95c7ae50d1a868b3a9baa9f /gcc
parente98df22a4f27fe43b61cbb7b3f29d9e4c9691a2d (diff)
downloadgcc-477f6664a4b1316583e5a71f0edd30faefeeaab5.zip
gcc-477f6664a4b1316583e5a71f0edd30faefeeaab5.tar.gz
gcc-477f6664a4b1316583e5a71f0edd30faefeeaab5.tar.bz2
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
Diffstat (limited to 'gcc')
-rw-r--r--gcc/cp/ChangeLog26
-rw-r--r--gcc/cp/call.c42
-rw-r--r--gcc/cp/cp-tree.h1
-rw-r--r--gcc/cp/error.c18
-rw-r--r--gcc/cp/parse.y14
-rw-r--r--gcc/cp/pt.c2
-rw-r--r--gcc/cp/search.c6
-rw-r--r--gcc/cp/semantics.c3
-rw-r--r--gcc/cp/tree.c31
-rw-r--r--gcc/cp/typeck.c6
-rw-r--r--gcc/cp/typeck2.c13
-rw-r--r--gcc/testsuite/g++.old-deja/g++.benjamin/scope01.C4
-rw-r--r--gcc/testsuite/g++.old-deja/g++.brendan/misc15.C2
-rw-r--r--gcc/testsuite/g++.old-deja/g++.other/call1.C51
-rw-r--r--gcc/testsuite/g++.old-deja/g++.other/lookup18.C8
-rw-r--r--gcc/testsuite/g++.old-deja/g++.other/lookup20.C10
-rw-r--r--gcc/testsuite/g++.old-deja/g++.pt/parms3.C8
17 files changed, 164 insertions, 81 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index fc473fb..0dd5b81 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,29 @@
+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.
diff --git a/gcc/cp/call.c b/gcc/cp/call.c
index 77e29eb..e7de1ba 100644
--- a/gcc/cp/call.c
+++ b/gcc/cp/call.c
@@ -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)
- 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));
- }
+ 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);
}
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 (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);
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index f6d0b82..7c3dce4 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -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));
diff --git a/gcc/cp/error.c b/gcc/cp/error.c
index b208e65..ce11ae1 100644
--- a/gcc/cp/error.c
+++ b/gcc/cp/error.c
@@ -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;
diff --git a/gcc/cp/parse.y b/gcc/cp/parse.y
index 15cf725..4e76394 100644
--- a/gcc/cp/parse.y
+++ b/gcc/cp/parse.y
@@ -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 ($$)); }
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index 3a0096e..50e7ddf 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -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);
diff --git a/gcc/cp/search.c b/gcc/cp/search.c
index 601f08b..2f4a3e9 100644
--- a/gcc/cp/search.c
+++ b/gcc/cp/search.c
@@ -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);
}
diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c
index 856f4ae..28bf1cc 100644
--- a/gcc/cp/semantics.c
+++ b/gcc/cp/semantics.c
@@ -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));
}
diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c
index f86318b..a1089ce 100644
--- a/gcc/cp/tree.c
+++ b/gcc/cp/tree.c
@@ -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. */
diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c
index 6d12cbd..8de99f6 100644
--- a/gcc/cp/typeck.c
+++ b/gcc/cp/typeck.c
@@ -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
diff --git a/gcc/cp/typeck2.c b/gcc/cp/typeck2.c
index d8143f8..c40b81c 100644
--- a/gcc/cp/typeck2.c
+++ b/gcc/cp/typeck2.c
@@ -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);
diff --git a/gcc/testsuite/g++.old-deja/g++.benjamin/scope01.C b/gcc/testsuite/g++.old-deja/g++.benjamin/scope01.C
index 582723a..a834f4f 100644
--- a/gcc/testsuite/g++.old-deja/g++.benjamin/scope01.C
+++ b/gcc/testsuite/g++.old-deja/g++.benjamin/scope01.C
@@ -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
diff --git a/gcc/testsuite/g++.old-deja/g++.brendan/misc15.C b/gcc/testsuite/g++.old-deja/g++.brendan/misc15.C
index 30c4feb..a294e4f 100644
--- a/gcc/testsuite/g++.old-deja/g++.brendan/misc15.C
+++ b/gcc/testsuite/g++.old-deja/g++.brendan/misc15.C
@@ -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; }
};
diff --git a/gcc/testsuite/g++.old-deja/g++.other/call1.C b/gcc/testsuite/g++.old-deja/g++.other/call1.C
new file mode 100644
index 0000000..7341488
--- /dev/null
+++ b/gcc/testsuite/g++.old-deja/g++.other/call1.C
@@ -0,0 +1,51 @@
+// 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();
+}
diff --git a/gcc/testsuite/g++.old-deja/g++.other/lookup18.C b/gcc/testsuite/g++.old-deja/g++.other/lookup18.C
index bec78f8..09549f7 100644
--- a/gcc/testsuite/g++.old-deja/g++.other/lookup18.C
+++ b/gcc/testsuite/g++.old-deja/g++.other/lookup18.C
@@ -1,5 +1,5 @@
-// 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
}
diff --git a/gcc/testsuite/g++.old-deja/g++.other/lookup20.C b/gcc/testsuite/g++.old-deja/g++.other/lookup20.C
new file mode 100644
index 0000000..930c9ab7ad
--- /dev/null
+++ b/gcc/testsuite/g++.old-deja/g++.other/lookup20.C
@@ -0,0 +1,10 @@
+// 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 { };
diff --git a/gcc/testsuite/g++.old-deja/g++.pt/parms3.C b/gcc/testsuite/g++.old-deja/g++.pt/parms3.C
new file mode 100644
index 0000000..031f3d6
--- /dev/null
+++ b/gcc/testsuite/g++.old-deja/g++.pt/parms3.C
@@ -0,0 +1,8 @@
+// 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;
+};