aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJason Merrill <jason@yorick.cygnus.com>1998-08-03 22:11:25 +0000
committerJason Merrill <jason@gcc.gnu.org>1998-08-03 18:11:25 -0400
commitc1def683c1c18e090cd3f7a96fd44c055b41b106 (patch)
tree658df2fa05c67052b68384bdc451e68d4b207eb6
parent090f136ad2e8dda2a6ebb0523b26f420f5f9218a (diff)
downloadgcc-c1def683c1c18e090cd3f7a96fd44c055b41b106.zip
gcc-c1def683c1c18e090cd3f7a96fd44c055b41b106.tar.gz
gcc-c1def683c1c18e090cd3f7a96fd44c055b41b106.tar.bz2
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
-rw-r--r--gcc/cp/ChangeLog13
-rw-r--r--gcc/cp/cp-tree.h2
-rw-r--r--gcc/cp/decl.c32
-rw-r--r--gcc/cp/method.c2
-rw-r--r--gcc/cp/search.c33
-rw-r--r--gcc/cp/typeck.c111
6 files changed, 133 insertions, 60 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index ee6b01f..2d2e7dc 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -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
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index 72a1655..aa84e0f 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -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));
diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
index 0b32a3d..6841905 100644
--- a/gcc/cp/decl.c
+++ b/gcc/cp/decl.c
@@ -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)
{
diff --git a/gcc/cp/method.c b/gcc/cp/method.c
index 18e638c..69ba1b0 100644
--- a/gcc/cp/method.c
+++ b/gcc/cp/method.c
@@ -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;
{
diff --git a/gcc/cp/search.c b/gcc/cp/search.c
index bde0a29..79042e1 100644
--- a/gcc/cp/search.c
+++ b/gcc/cp/search.c
@@ -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);
diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c
index 0ae703b..3e4fd0a 100644
--- a/gcc/cp/typeck.c
+++ b/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);
-
- /* 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)
- {
- aref = save_expr (aref);
-
- delta = build_binary_op
+ e3 = PFN_FROM_PTRMEMFUNC (function);
+
+ 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
+ {
+ /* 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);
+
+ /* 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;
}