This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[C++ PATCH]: Using declarations
- To: gcc-patches at gcc dot gnu dot org
- Subject: [C++ PATCH]: Using declarations
- From: Nathan Sidwell <nathan at codesourcery dot com>
- Date: Wed, 03 Jan 2001 15:26:16 +0000
- Organization: Codesourcery LLC
Hi,
This patch fixes some faults with using declarations, used to inject
base class members. In particlar, we'd reject
struct B : A {
struct Foo {};
using A::Foo; // A::Foo is a member fn of A
};
but accept
struct B : A {
struct Foo {};
void Foo (); // declare local member fn
using A::Foo; // A::Foo is a member fn of A
};
built & tested on i686-pc-linux-gnu, ok?
nathan
--
Dr Nathan Sidwell :: http://www.codesourcery.com :: CodeSourcery LLC
'But that's a lie.' - 'Yes it is. What's your point?'
nathan@codesourcery.com : http://www.cs.bris.ac.uk/~nathan/ : nathan@acm.org
2001-01-03 Nathan Sidwell <nathan@codesourcery.com>
* class.c (handle_using_decl): Reject using of constructor name
of sourcing class. Allow injecting of a method with same name as
nested class. Fixup error messages.
Index: cp/class.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/cp/class.c,v
retrieving revision 1.346
diff -c -3 -p -r1.346 class.c
*** class.c 2000/12/07 14:26:37 1.346
--- class.c 2000/12/11 10:15:33
*************** handle_using_decl (using_decl, t)
*** 1527,1535 ****
if (name == constructor_name (ctype)
|| name == constructor_name_full (ctype))
{
! cp_error_at ("using-declaration for constructor", using_decl);
return;
}
fdecl = lookup_member (binfo, name, 0, 0);
--- 1527,1541 ----
if (name == constructor_name (ctype)
|| name == constructor_name_full (ctype))
{
! cp_error_at ("`%D' names constructor", using_decl);
return;
}
+ if (name == constructor_name (t)
+ || name == constructor_name_full (t))
+ {
+ cp_error_at ("`%D' invalid in `%T'", using_decl, t);
+ return;
+ }
fdecl = lookup_member (binfo, name, 0, 0);
*************** handle_using_decl (using_decl, t)
*** 1567,1582 ****
the same name already present in the current class. */;
else
{
! cp_error ("`%D' invalid in `%#T'", using_decl, t);
cp_error_at (" because of local method `%#D' with same name",
OVL_CURRENT (old_value));
return;
}
}
! else
{
! cp_error ("`%D' invalid in `%#T'", using_decl, t);
! cp_error_at (" because of local field `%#D' with same name", old_value);
return;
}
--- 1573,1588 ----
the same name already present in the current class. */;
else
{
! cp_error_at ("`%D' invalid in `%#T'", using_decl, t);
cp_error_at (" because of local method `%#D' with same name",
OVL_CURRENT (old_value));
return;
}
}
! else if (!DECL_ARTIFICIAL (old_value))
{
! cp_error_at ("`%D' invalid in `%#T'", using_decl, t);
! cp_error_at (" because of local member `%#D' with same name", old_value);
return;
}
// Build don't link:
// Copyright (C) 2000 Free Software Foundation, Inc.
// Contributed by Nathan Sidwell 14 Nov 2000 <nathan@codesourcery.com>
// We rejected using decls bringing in functions from a base which would hide a
// nested class of the same name, but only if we had no functions by that name
// already. Also, we failed to find that using declaration during lookup. Also
// we failed to reject using declarations which matched the constructor name.
struct A
{
int f ();
void D ();
};
struct A2 {
typedef int f;
};
struct B : A
{
using A::f;
struct f {};
};
struct C : A
{
using A::f;
int f (int);
struct f {};
};
void foo (B *bp, C* cp)
{
bp->f ();
cp->f ();
}
struct D : A
{
using A::D; // ERROR - names constructor
};