mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-02-06 22:30:45 +08:00
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:
parent
090f136ad2
commit
c1def683c1
@ -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
|
||||
|
@ -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));
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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;
|
||||
{
|
||||
|
@ -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);
|
||||
|
105
gcc/cp/typeck.c
105
gcc/cp/typeck.c
@ -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;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user