This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
C++ PATCH for more tidbits
- To: egcs-patches at egcs dot cygnus dot com
- Subject: C++ PATCH for more tidbits
- From: Mark Mitchell <mark at codesourcery dot com>
- Date: Tue, 6 Apr 1999 14:39:46 -0700
- Reply-to: mark at codesourcery dot com
Here's another patch that fixes up a couple of little problems left in
the wake of recent name-lookup changes.
--
Mark Mitchell mark@codesourcery.com
CodeSourcery, LLC http://www.codesourcery.com
1999-04-06 Mark Mitchell <mark@codesourcery.com>
* cp-tree.h (BASELINK_P): New macro.
(SET_BASELINK_P): Likewise.
* init.c (build_member_call): Remove needless assignment in if
statement.
* search.c (lookup_field_r): Fix handling when we are looking
specifically for a type; these are not hidden by functions and
variables.
(lookup_member): Use SET_BASELINK_P.
* tree.c (is_overloaded_fn): Use BASELINK_P.
(really_overloaed_fn): Likewise.
(get_first_fn): Likewise.
Index: testsuite/g++.old-deja/g++.other/crash9.C
===================================================================
RCS file: crash9.C
diff -N crash9.C
*** /dev/null Sat Dec 5 20:30:03 1998
--- crash9.C Tue Apr 6 14:32:45 1999
***************
*** 0 ****
--- 1,9 ----
+ // Build don't link:
+ // Origin: Jason Merrill <jason@cygnus.com>
+
+ struct A { };
+ struct B : public A
+ {
+ int A;
+ };
+ struct C : public B { };
Index: testsuite/g++.old-deja/g++.pt/crash33.C
===================================================================
RCS file: crash33.C
diff -N crash33.C
*** /dev/null Sat Dec 5 20:30:03 1998
--- crash33.C Tue Apr 6 14:32:45 1999
***************
*** 0 ****
--- 1,17 ----
+ // Build don't link:
+ // Origin: Theodore Papadopoulo <Theodore.Papadopoulo@sophia.inria.fr>
+
+ class A {
+ public:
+ template <class T> T& f(T& t) const;
+ };
+
+ class B {
+ public:
+ template <class T> T& f(T& t) const;
+ };
+
+ class C: public A,B {
+ public:
+ template <class T> T& f(T& t) const;
+ };
Index: testsuite/cp/cp-tree.h
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/cp/cp-tree.h,v
retrieving revision 1.213
diff -c -p -r1.213 cp-tree.h
*** cp-tree.h 1999/04/02 15:36:01 1.213
--- cp-tree.h 1999/04/06 21:32:48
*************** Boston, MA 02111-1307, USA. */
*** 33,39 ****
TREE_INDIRECT_USING (in NAMESPACE_DECL).
IDENTIFIER_MARKED (used by search routines).
LOCAL_BINDING_P (in CPLUS_BINDING)
! 1: IDENTIFIER_VIRTUAL_P.
TI_PENDING_TEMPLATE_FLAG.
TEMPLATE_PARMS_FOR_INLINE.
DELETE_EXPR_USE_VEC (in DELETE_EXPR).
--- 33,39 ----
TREE_INDIRECT_USING (in NAMESPACE_DECL).
IDENTIFIER_MARKED (used by search routines).
LOCAL_BINDING_P (in CPLUS_BINDING)
! 1: IDENTIFIER_VIRTUAL_P.
TI_PENDING_TEMPLATE_FLAG.
TEMPLATE_PARMS_FOR_INLINE.
DELETE_EXPR_USE_VEC (in DELETE_EXPR).
*************** Boston, MA 02111-1307, USA. */
*** 41,46 ****
--- 41,47 ----
TYPE_USES_COMPLEX_INHERITANCE (in _TYPE).
C_DECLARED_LABEL_FLAG.
INHERITED_VALUE_BINDING_P (in CPLUS_BINDING)
+ BASELINK_P (in TREE_LIST)
2: IDENTIFIER_OPNAME_P.
BINFO_VBASE_MARKED.
BINFO_FIELDS_MARKED.
*************** struct tree_overload
*** 190,195 ****
--- 191,204 ----
char common[sizeof (struct tree_common)];
tree function;
};
+
+ /* A `baselink' is a TREE_LIST whose TREE_PURPOSE is a BINFO
+ indicating a particular base class, and whose TREE_VALUE is a
+ (possibly overloaded) function from that base class. */
+ #define BASELINK_P(NODE) \
+ (TREE_CODE ((NODE)) == TREE_LIST && TREE_LANG_FLAG_1 ((NODE)))
+ #define SET_BASELINK_P(NODE) \
+ (TREE_LANG_FLAG_1 ((NODE)) = 1)
#define WRAPPER_PTR(NODE) (((struct tree_wrapper*)NODE)->u.ptr)
#define WRAPPER_INT(NODE) (((struct tree_wrapper*)NODE)->u.i)
Index: testsuite/cp/init.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/cp/init.c,v
retrieving revision 1.92
diff -c -p -r1.92 init.c
*** init.c 1999/04/02 15:36:15 1.92
--- init.c 1999/04/06 21:32:50
*************** build_member_call (type, name, parmlist)
*** 1443,1449 ****
if (method_name == constructor_name (type)
|| method_name == constructor_name_full (type))
return build_functional_cast (type, parmlist);
! if ((t = lookup_fnfields (basetype_path, method_name, 0)))
return build_method_call (decl,
TREE_CODE (name) == TEMPLATE_ID_EXPR
? name : method_name,
--- 1443,1449 ----
if (method_name == constructor_name (type)
|| method_name == constructor_name_full (type))
return build_functional_cast (type, parmlist);
! if (lookup_fnfields (basetype_path, method_name, 0))
return build_method_call (decl,
TREE_CODE (name) == TEMPLATE_ID_EXPR
? name : method_name,
Index: testsuite/cp/search.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/cp/search.c,v
retrieving revision 1.92
diff -c -p -r1.92 search.c
*** search.c 1999/04/05 12:34:20 1.92
--- search.c 1999/04/06 21:32:58
*************** lookup_field_r (binfo, data)
*** 1207,1223 ****
{
struct lookup_field_info *lfi = (struct lookup_field_info *) data;
tree type = BINFO_TYPE (binfo);
! tree nval;
! int idx;
int from_dep_base_p;
/* First, look for a function. There can't be a function and a data
member with the same name, and if there's a function and a type
with the same name, the type is hidden by the function. */
! idx = lookup_fnfields_here (type, lfi->name);
! if (idx >= 0)
! nval = TREE_VEC_ELT (CLASSTYPE_METHOD_VEC (type), idx);
! else
/* Look for a data member or type. */
nval = lookup_field_1 (type, lfi->name);
--- 1207,1226 ----
{
struct lookup_field_info *lfi = (struct lookup_field_info *) data;
tree type = BINFO_TYPE (binfo);
! tree nval = NULL_TREE;
int from_dep_base_p;
/* First, look for a function. There can't be a function and a data
member with the same name, and if there's a function and a type
with the same name, the type is hidden by the function. */
! if (!lfi->want_type)
! {
! int idx = lookup_fnfields_here (type, lfi->name);
! if (idx >= 0)
! nval = TREE_VEC_ELT (CLASSTYPE_METHOD_VEC (type), idx);
! }
!
! if (!nval)
/* Look for a data member or type. */
nval = lookup_field_1 (type, lfi->name);
*************** lookup_field_r (binfo, data)
*** 1226,1231 ****
--- 1229,1245 ----
if (!nval)
return NULL_TREE;
+ /* If we're looking up a type (as with an elaborated type specifier)
+ we ignore all non-types we find. */
+ if (lfi->want_type && TREE_CODE (nval) != TYPE_DECL)
+ {
+ nval = purpose_member (lfi->name, CLASSTYPE_TAGS (type));
+ if (nval)
+ nval = TYPE_MAIN_DECL (TREE_VALUE (nval));
+ else
+ return NULL_TREE;
+ }
+
/* You must name a template base class with a template-id. */
if (!same_type_p (type, lfi->type)
&& template_self_reference_p (type, nval))
*************** lookup_field_r (binfo, data)
*** 1285,1325 ****
}
else
{
! /* The new lookup is the best we've got so far. Verify that
! it's the kind of thing we're looking for. */
! if (lfi->want_type && TREE_CODE (nval) != TYPE_DECL)
{
! nval = purpose_member (lfi->name, CLASSTYPE_TAGS (type));
! if (nval)
! {
! nval = TYPE_MAIN_DECL (TREE_VALUE (nval));
! if (!same_type_p (type, lfi->type)
! && template_self_reference_p (type, nval))
! nval = NULL_TREE;
! }
}
! if (nval)
! {
! /* If the thing we're looking for is a virtual base class,
! then we know we've got what we want at this point;
! there's no way to get an ambiguity. */
! if (VBASE_NAME_P (lfi->name))
! {
! lfi->rval = nval;
! return nval;
! }
!
! if (from_dep_base_p && TREE_CODE (nval) != TYPE_DECL
! /* We need to return a member template class so we can
! define partial specializations. Is there a better
! way? */
! && !DECL_CLASS_TEMPLATE_P (nval))
! /* The thing we're looking for isn't a type, so the implicit
! typename extension doesn't apply, so we just pretend we
! didn't find anything. */
! return NULL_TREE;
! }
lfi->rval = nval;
lfi->from_dep_base_p = from_dep_base_p;
--- 1299,1322 ----
}
else
{
! /* If the thing we're looking for is a virtual base class, then
! we know we've got what we want at this point; there's no way
! to get an ambiguity. */
! if (VBASE_NAME_P (lfi->name))
{
! lfi->rval = nval;
! return nval;
}
! if (from_dep_base_p && TREE_CODE (nval) != TYPE_DECL
! /* We need to return a member template class so we can
! define partial specializations. Is there a better
! way? */
! && !DECL_CLASS_TEMPLATE_P (nval))
! /* The thing we're looking for isn't a type, so the implicit
! typename extension doesn't apply, so we just pretend we
! didn't find anything. */
! return NULL_TREE;
lfi->rval = nval;
lfi->from_dep_base_p = from_dep_base_p;
*************** lookup_member (xbasetype, name, protect,
*** 1444,1451 ****
name, name,
TREE_TYPE (rval)));
! if (rval && is_overloaded_fn (rval))
! rval = scratch_tree_cons (basetype_path, rval, NULL_TREE);
return rval;
}
--- 1441,1451 ----
name, name,
TREE_TYPE (rval)));
! if (rval && is_overloaded_fn (rval))
! {
! rval = scratch_tree_cons (basetype_path, rval, NULL_TREE);
! SET_BASELINK_P (rval);
! }
return rval;
}
Index: testsuite/cp/tree.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/cp/tree.c,v
retrieving revision 1.103
diff -c -p -r1.103 tree.c
*** tree.c 1999/03/31 18:59:19 1.103
--- tree.c 1999/04/06 21:32:59
*************** int
*** 1223,1243 ****
is_overloaded_fn (x)
tree x;
{
! /* XXX A baselink is also considered an overloaded function.
! As is a placeholder from push_class_decls.
! As is an expression like X::f. */
! if (TREE_CODE (x) == TREE_LIST)
! {
! if (TREE_PURPOSE (x) == error_mark_node)
! {
! x = TREE_VALUE (x);
! my_friendly_assert (TREE_CODE (x) == TREE_LIST, 981121);
! }
! my_friendly_assert (TREE_CODE (TREE_PURPOSE (x)) == TREE_VEC
! || TREE_CODE (TREE_PURPOSE (x)) == IDENTIFIER_NODE,
! 388);
! x = TREE_VALUE (x);
! }
return (TREE_CODE (x) == FUNCTION_DECL
|| TREE_CODE (x) == TEMPLATE_ID_EXPR
|| DECL_FUNCTION_TEMPLATE_P (x)
--- 1223,1231 ----
is_overloaded_fn (x)
tree x;
{
! /* A baselink is also considered an overloaded function. */
! if (BASELINK_P (x))
! x = TREE_VALUE (x);
return (TREE_CODE (x) == FUNCTION_DECL
|| TREE_CODE (x) == TEMPLATE_ID_EXPR
|| DECL_FUNCTION_TEMPLATE_P (x)
*************** int
*** 1248,1256 ****
really_overloaded_fn (x)
tree x;
{
! /* A baselink is also considered an overloaded function.
! This might also be an ambiguous class member. */
! if (TREE_CODE (x) == TREE_LIST)
x = TREE_VALUE (x);
return (TREE_CODE (x) == OVERLOAD
&& (TREE_CHAIN (x) != NULL_TREE
--- 1236,1243 ----
really_overloaded_fn (x)
tree x;
{
! /* A baselink is also considered an overloaded function. */
! if (BASELINK_P (x))
x = TREE_VALUE (x);
return (TREE_CODE (x) == OVERLOAD
&& (TREE_CHAIN (x) != NULL_TREE
*************** get_first_fn (from)
*** 1263,1269 ****
{
my_friendly_assert (is_overloaded_fn (from), 9);
/* A baselink is also considered an overloaded function. */
! if (TREE_CODE (from) == TREE_LIST)
from = TREE_VALUE (from);
return OVL_CURRENT (from);
}
--- 1250,1256 ----
{
my_friendly_assert (is_overloaded_fn (from), 9);
/* A baselink is also considered an overloaded function. */
! if (BASELINK_P (from))
from = TREE_VALUE (from);
return OVL_CURRENT (from);
}