cp-tree.h (BASELINK_P): New macro.
* 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. From-SVN: r26219
This commit is contained in:
parent
ab45646c4e
commit
4bb0968f4e
@ -1,3 +1,17 @@
|
||||
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.
|
||||
|
||||
1999-04-05 Mark Mitchell <mark@codesourcery.com>
|
||||
|
||||
* decl.c (lookup_name_current_level): Tweak, and improve
|
||||
|
@ -33,7 +33,7 @@ Boston, MA 02111-1307, USA. */
|
||||
TREE_INDIRECT_USING (in NAMESPACE_DECL).
|
||||
IDENTIFIER_MARKED (used by search routines).
|
||||
LOCAL_BINDING_P (in CPLUS_BINDING)
|
||||
1: IDENTIFIER_VIRTUAL_P.
|
||||
1: IDENTIFIER_VIRTUAL_P.
|
||||
TI_PENDING_TEMPLATE_FLAG.
|
||||
TEMPLATE_PARMS_FOR_INLINE.
|
||||
DELETE_EXPR_USE_VEC (in DELETE_EXPR).
|
||||
@ -41,6 +41,7 @@ Boston, MA 02111-1307, USA. */
|
||||
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.
|
||||
@ -191,6 +192,14 @@ struct tree_overload
|
||||
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)
|
||||
|
||||
|
@ -1443,7 +1443,7 @@ build_member_call (type, name, parmlist)
|
||||
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)))
|
||||
if (lookup_fnfields (basetype_path, method_name, 0))
|
||||
return build_method_call (decl,
|
||||
TREE_CODE (name) == TEMPLATE_ID_EXPR
|
||||
? name : method_name,
|
||||
|
@ -1207,17 +1207,20 @@ lookup_field_r (binfo, data)
|
||||
{
|
||||
struct lookup_field_info *lfi = (struct lookup_field_info *) data;
|
||||
tree type = BINFO_TYPE (binfo);
|
||||
tree nval;
|
||||
int idx;
|
||||
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. */
|
||||
idx = lookup_fnfields_here (type, lfi->name);
|
||||
if (idx >= 0)
|
||||
nval = TREE_VEC_ELT (CLASSTYPE_METHOD_VEC (type), idx);
|
||||
else
|
||||
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);
|
||||
|
||||
@ -1226,6 +1229,17 @@ lookup_field_r (binfo, data)
|
||||
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))
|
||||
@ -1285,41 +1299,24 @@ lookup_field_r (binfo, data)
|
||||
}
|
||||
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)
|
||||
/* 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))
|
||||
{
|
||||
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;
|
||||
}
|
||||
lfi->rval = nval;
|
||||
return nval;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
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;
|
||||
@ -1445,7 +1442,10 @@ lookup_member (xbasetype, name, protect, want_type)
|
||||
TREE_TYPE (rval)));
|
||||
|
||||
if (rval && is_overloaded_fn (rval))
|
||||
rval = scratch_tree_cons (basetype_path, rval, NULL_TREE);
|
||||
{
|
||||
rval = scratch_tree_cons (basetype_path, rval, NULL_TREE);
|
||||
SET_BASELINK_P (rval);
|
||||
}
|
||||
|
||||
return rval;
|
||||
}
|
||||
|
@ -1223,21 +1223,9 @@ int
|
||||
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);
|
||||
}
|
||||
/* 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)
|
||||
@ -1248,9 +1236,8 @@ int
|
||||
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)
|
||||
/* 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
|
||||
@ -1263,7 +1250,7 @@ get_first_fn (from)
|
||||
{
|
||||
my_friendly_assert (is_overloaded_fn (from), 9);
|
||||
/* A baselink is also considered an overloaded function. */
|
||||
if (TREE_CODE (from) == TREE_LIST)
|
||||
if (BASELINK_P (from))
|
||||
from = TREE_VALUE (from);
|
||||
return OVL_CURRENT (from);
|
||||
}
|
||||
|
9
gcc/testsuite/g++.old-deja/g++.other/crash9.C
Normal file
9
gcc/testsuite/g++.old-deja/g++.other/crash9.C
Normal file
@ -0,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 { };
|
17
gcc/testsuite/g++.old-deja/g++.pt/crash33.C
Normal file
17
gcc/testsuite/g++.old-deja/g++.pt/crash33.C
Normal file
@ -0,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;
|
||||
};
|
Loading…
Reference in New Issue
Block a user