method.c (set_mangled_name_for_decl): Change return type to void.

* method.c (set_mangled_name_for_decl): Change return type to void.
	* decl.c (lookup_name_real): A namespace-level decl takes priority
	over implicit typename.  Avoid doing the same lookup twice.
	* search.c (dependent_base_p): New fn.
	(dfs_pushdecls, dfs_compress_decls): Use it.
	* typeck.c (get_member_function_from_ptrfunc): Don't try to handle
	virtual functions if the type doesn't have any.

From-SVN: r21551
This commit is contained in:
Jason Merrill 1998-08-03 22:11:25 +00:00 committed by Jason Merrill
parent 090f136ad2
commit c1def683c1
6 changed files with 130 additions and 57 deletions

View File

@ -1,3 +1,16 @@
1998-08-03 Jason Merrill <jason@yorick.cygnus.com>
* method.c (set_mangled_name_for_decl): Change return type to void.
* decl.c (lookup_name_real): A namespace-level decl takes priority
over implicit typename. Avoid doing the same lookup twice.
* search.c (dependent_base_p): New fn.
(dfs_pushdecls, dfs_compress_decls): Use it.
* typeck.c (get_member_function_from_ptrfunc): Don't try to handle
virtual functions if the type doesn't have any.
1998-08-03 Mark Mitchell <mark@markmitchell.com>
* decl2.c (grokfield): Don't mangle the name of a TYPE_DECL if it

View File

@ -2733,7 +2733,7 @@ extern tree build_static_name PROTO((tree, tree));
extern tree build_decl_overload PROTO((tree, tree, int));
extern tree build_decl_overload_real PROTO((tree, tree, tree, tree,
tree, int));
extern tree set_mangled_name_for_decl PROTO((tree));
extern void set_mangled_name_for_decl PROTO((tree));
extern tree build_typename_overload PROTO((tree));
extern tree build_overload_with_type PROTO((tree, tree));
extern tree build_destructor_name PROTO((tree));

View File

@ -5074,11 +5074,11 @@ lookup_name_real (name, prefer_type, nonclass, namespaces_only)
/* Add implicit 'typename' to types from template bases. lookup_field
will do this for us. If classval is actually from an enclosing
scope, lookup_nested_field will get it for us. */
if (processing_template_decl
&& classval && TREE_CODE (classval) == TYPE_DECL
&& ! currently_open_class (DECL_CONTEXT (classval))
&& uses_template_parms (current_class_type)
&& ! DECL_ARTIFICIAL (classval))
else if (processing_template_decl
&& classval && TREE_CODE (classval) == TYPE_DECL
&& ! currently_open_class (DECL_CONTEXT (classval))
&& uses_template_parms (current_class_type)
&& ! DECL_ARTIFICIAL (classval))
classval = lookup_field (current_class_type, name, 0, 1);
/* yylex() calls this with -2, since we should never start digging for
@ -5121,6 +5121,28 @@ lookup_name_real (name, prefer_type, nonclass, namespaces_only)
else
val = unqualified_namespace_lookup (name, flags);
if (classval && TREE_CODE (val) == TYPE_DECL
&& TREE_CODE (TREE_TYPE (val)) == TYPENAME_TYPE
&& TREE_TYPE (TREE_TYPE (val)))
{
tree nsval = unqualified_namespace_lookup (name, flags);
if (val && nsval && TREE_CODE (nsval) == TYPE_DECL)
{
static int explained;
cp_warning ("namespace-scope type `%#D'", nsval);
cp_warning
(" is used instead of `%D' from dependent base class", val);
if (! explained)
{
explained = 1;
cp_warning (" (use `typename %D' if that's what you meant)",
val);
}
val = nsval;
}
}
done:
if (val)
{

View File

@ -1663,7 +1663,7 @@ build_decl_overload (dname, parms, for_method)
/* Set the mangled name (DECL_ASSEMBLER_NAME) for DECL. */
tree
void
set_mangled_name_for_decl (decl)
tree decl;
{

View File

@ -3480,6 +3480,23 @@ envelope_add_decl (type, decl, values)
}
}
/* Returns 1 iff BINFO is a base we shouldn't really be able to see into,
because it (or one of the intermediate bases) depends on template parms. */
static int
dependent_base_p (binfo)
tree binfo;
{
for (; binfo; binfo = BINFO_INHERITANCE_CHAIN (binfo))
{
if (binfo == current_class_type)
break;
if (uses_template_parms (TREE_TYPE (binfo)))
return 1;
}
return 0;
}
/* Add the instance variables which this class contributed to the
current class binding contour. When a redefinition occurs, if the
redefinition is strictly within a single inheritance path, we just
@ -3506,9 +3523,18 @@ dfs_pushdecls (binfo)
tree type = BINFO_TYPE (binfo);
tree fields, *methods, *end;
tree method_vec;
int dummy = 0;
/* Only record types if we're a template base. */
if (processing_template_decl && type != current_class_type
&& dependent_base_p (binfo))
dummy = 1;
for (fields = TYPE_FIELDS (type); fields; fields = TREE_CHAIN (fields))
{
if (dummy && TREE_CODE (fields) != TYPE_DECL)
continue;
/* Unmark so that if we are in a constructor, and then find that
this field was initialized by a base initializer,
we can emit an error message. */
@ -3546,7 +3572,7 @@ dfs_pushdecls (binfo)
}
method_vec = CLASSTYPE_METHOD_VEC (type);
if (method_vec)
if (method_vec && ! dummy)
{
/* Farm out constructors and destructors. */
methods = &TREE_VEC_ELT (method_vec, 2);
@ -3598,7 +3624,10 @@ dfs_compress_decls (binfo)
tree type = BINFO_TYPE (binfo);
tree method_vec = CLASSTYPE_METHOD_VEC (type);
if (method_vec != 0)
if (processing_template_decl && type != current_class_type
&& dependent_base_p (binfo))
/* We only record types if we're a template base. */;
else if (method_vec != 0)
{
/* Farm out constructors and destructors. */
tree *methods = &TREE_VEC_ELT (method_vec, 2);

View File

@ -2669,7 +2669,7 @@ get_member_function_from_ptrfunc (instance_ptrptr, function)
if (TYPE_PTRMEMFUNC_P (TREE_TYPE (function)))
{
tree fntype, idx, e1, delta, delta2, e2, e3, aref, vtbl;
tree instance;
tree instance, basetype;
tree instance_ptr = *instance_ptrptr;
@ -2680,61 +2680,76 @@ get_member_function_from_ptrfunc (instance_ptrptr, function)
function = save_expr (function);
fntype = TYPE_PTRMEMFUNC_FN_TYPE (TREE_TYPE (function));
basetype = TYPE_METHOD_BASETYPE (TREE_TYPE (fntype));
/* Promoting idx before saving it improves performance on RISC
targets. Without promoting, the first compare used
load-with-sign-extend, while the second used normal load then
shift to sign-extend. An optimizer flaw, perhaps, but it's easier
to make this change. */
idx = save_expr (default_conversion
(build_component_ref (function,
index_identifier,
NULL_TREE, 0)));
e1 = build_binary_op (GT_EXPR, idx, integer_zero_node, 1);
delta = cp_convert (ptrdiff_type_node,
build_component_ref (function, delta_identifier,
NULL_TREE, 0));
delta2 = DELTA2_FROM_PTRMEMFUNC (function);
e3 = PFN_FROM_PTRMEMFUNC (function);
/* Convert down to the right base, before using the instance. */
instance
= convert_pointer_to_real (TYPE_METHOD_BASETYPE (TREE_TYPE (fntype)),
instance_ptr);
if (instance == error_mark_node && instance_ptr != error_mark_node)
return instance;
vtbl = convert_pointer_to (ptr_type_node, instance);
vtbl
= build (PLUS_EXPR,
build_pointer_type (build_pointer_type (vtable_entry_type)),
vtbl, cp_convert (ptrdiff_type_node, delta2));
vtbl = build_indirect_ref (vtbl, NULL_PTR);
aref = build_array_ref (vtbl, build_binary_op (MINUS_EXPR,
idx,
integer_one_node, 1));
if (! flag_vtable_thunks)
if (TYPE_SIZE (basetype) != NULL_TREE
&& ! TYPE_VIRTUAL_P (basetype))
/* If basetype doesn't have virtual functions, don't emit code to
handle that case. */
e1 = e3;
else
{
aref = save_expr (aref);
/* Promoting idx before saving it improves performance on RISC
targets. Without promoting, the first compare used
load-with-sign-extend, while the second used normal load then
shift to sign-extend. An optimizer flaw, perhaps, but it's
easier to make this change. */
idx = save_expr (default_conversion
(build_component_ref (function,
index_identifier,
NULL_TREE, 0)));
e1 = build_binary_op (GT_EXPR, idx, integer_zero_node, 1);
delta = build_binary_op
/* Convert down to the right base, before using the instance. */
instance = convert_pointer_to_real (basetype, instance_ptr);
if (instance == error_mark_node && instance_ptr != error_mark_node)
return instance;
vtbl = convert_pointer_to (ptr_type_node, instance);
delta2 = DELTA2_FROM_PTRMEMFUNC (function);
vtbl = build
(PLUS_EXPR,
build_conditional_expr (e1, build_component_ref (aref,
build_pointer_type (build_pointer_type (vtable_entry_type)),
vtbl, cp_convert (ptrdiff_type_node, delta2));
vtbl = build_indirect_ref (vtbl, NULL_PTR);
aref = build_array_ref (vtbl, build_binary_op (MINUS_EXPR,
idx,
integer_one_node, 1));
if (! flag_vtable_thunks)
{
aref = save_expr (aref);
delta = build_binary_op
(PLUS_EXPR,
build_conditional_expr (e1,
build_component_ref (aref,
delta_identifier,
NULL_TREE, 0),
integer_zero_node),
delta, 1);
integer_zero_node),
delta, 1);
}
if (flag_vtable_thunks)
e2 = aref;
else
e2 = build_component_ref (aref, pfn_identifier, NULL_TREE, 0);
TREE_TYPE (e2) = TREE_TYPE (e3);
e1 = build_conditional_expr (e1, e2, e3);
/* Make sure this doesn't get evaluated first inside one of the
branches of the COND_EXPR. */
if (TREE_CODE (instance_ptr) == SAVE_EXPR)
e1 = build (COMPOUND_EXPR, TREE_TYPE (e1),
instance_ptr, e1);
}
*instance_ptrptr = build (PLUS_EXPR, TREE_TYPE (instance_ptr),
instance_ptr, delta);
if (flag_vtable_thunks)
e2 = aref;
else
e2 = build_component_ref (aref, pfn_identifier, NULL_TREE, 0);
e3 = PFN_FROM_PTRMEMFUNC (function);
TREE_TYPE (e2) = TREE_TYPE (e3);
e1 = build_conditional_expr (e1, e2, e3);
if (instance_ptr == error_mark_node
&& TREE_CODE (e1) != ADDR_EXPR
@ -2742,12 +2757,6 @@ get_member_function_from_ptrfunc (instance_ptrptr, function)
cp_error ("object missing in `%E'", function);
function = e1;
/* Make sure this doesn't get evaluated first inside one of the
branches of the COND_EXPR. */
if (TREE_CODE (instance_ptr) == SAVE_EXPR)
function = build (COMPOUND_EXPR, TREE_TYPE (function),
instance_ptr, function);
}
return function;
}