aboutsummaryrefslogtreecommitdiff
path: root/gcc/cp
diff options
context:
space:
mode:
authorNathan Sidwell <nathan@codesourcery.com>2000-11-27 12:53:38 +0000
committerNathan Sidwell <nathan@gcc.gnu.org>2000-11-27 12:53:38 +0000
commit76e57b458976f18172c6e0ac1cffea3e6b6a1e24 (patch)
tree3be1b6f05983fb68984fe76dd579c0853828c39d /gcc/cp
parent70bbeb8b66198585061972bd24aca9218d0f1d87 (diff)
downloadgcc-76e57b458976f18172c6e0ac1cffea3e6b6a1e24.zip
gcc-76e57b458976f18172c6e0ac1cffea3e6b6a1e24.tar.gz
gcc-76e57b458976f18172c6e0ac1cffea3e6b6a1e24.tar.bz2
decl.c (grokfndecl): Undo COMPONENT_REF damage caused by bison parser ickiness.
cp: * decl.c (grokfndecl): Undo COMPONENT_REF damage caused by bison parser ickiness. * pt.c (tsubst_friend_function): Enter namespace scope when tsubsting the function name. * cp-tree.h (DECL_TI_TEMPLATE): Update comment to reflect reality. testsuite: * g++.old-deja/g++.other/friend46.C: New test. From-SVN: r37793
Diffstat (limited to 'gcc/cp')
-rw-r--r--gcc/cp/ChangeLog8
-rw-r--r--gcc/cp/cp-tree.h5
-rw-r--r--gcc/cp/decl.c23
-rw-r--r--gcc/cp/pt.c23
4 files changed, 44 insertions, 15 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index f2b1adc..438f29a 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,5 +1,13 @@
2000-11-27 Nathan Sidwell <nathan@codesourcery.com>
+ * decl.c (grokfndecl): Undo COMPONENT_REF damage caused by
+ bison parser ickiness.
+ * pt.c (tsubst_friend_function): Enter namespace scope when
+ tsubsting the function name.
+ * cp-tree.h (DECL_TI_TEMPLATE): Update comment to reflect reality.
+
+2000-11-27 Nathan Sidwell <nathan@codesourcery.com>
+
* cp-tree.h (binfo_from_vbase): Return the virtual base's binfo.
* cvt.c (cp_convert_to_pointer): Add force parameter.
Allow conversions via virtual base if forced.
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index ab10f46..c8cfa25 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -2362,8 +2362,9 @@ struct lang_decl
As a special case, for a member friend template of a template
class, this value will not be a TEMPLATE_DECL, but rather a
- LOOKUP_EXPR or IDENTIFIER_NODE indicating the name of the template
- and any explicit template arguments provided. For example, in:
+ LOOKUP_EXPR, IDENTIFIER_NODE or OVERLOAD indicating the name of
+ the template and any explicit template arguments provided. For
+ example, in:
template <class T> struct S { friend void f<int>(int, double); }
diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
index 380b734..3ca4ff6 100644
--- a/gcc/cp/decl.c
+++ b/gcc/cp/decl.c
@@ -8944,6 +8944,9 @@ grokfndecl (ctype, type, declarator, orig_declarator, virtualp, flags, quals,
orig_declarator);
else
{
+ tree fns = TREE_OPERAND (orig_declarator, 0);
+ tree args = TREE_OPERAND (orig_declarator, 1);
+
if (PROCESSING_REAL_TEMPLATE_DECL_P ())
{
/* Something like `template <class T> friend void f<T>()'. */
@@ -8956,10 +8959,22 @@ grokfndecl (ctype, type, declarator, orig_declarator, virtualp, flags, quals,
/* A friend declaration of the form friend void f<>(). Record
the information in the TEMPLATE_ID_EXPR. */
SET_DECL_IMPLICIT_INSTANTIATION (decl);
- DECL_TEMPLATE_INFO (decl)
- = tree_cons (TREE_OPERAND (orig_declarator, 0),
- TREE_OPERAND (orig_declarator, 1),
- NULL_TREE);
+
+ if (TREE_CODE (fns) == COMPONENT_REF)
+ {
+ /* Due to bison parser ickiness, we will have already looked
+ up an operator_name or PFUNCNAME within the current class
+ (see template_id in parse.y). If the current class contains
+ such a name, we'll get a COMPONENT_REF here. Undo that. */
+
+ my_friendly_assert (TREE_TYPE (TREE_OPERAND (fns, 0))
+ == current_class_type, 20001120);
+ fns = TREE_OPERAND (fns, 1);
+ }
+ my_friendly_assert (TREE_CODE (fns) == IDENTIFIER_NODE
+ || TREE_CODE (fns) == LOOKUP_EXPR
+ || TREE_CODE (fns) == OVERLOAD, 20001120);
+ DECL_TEMPLATE_INFO (decl) = tree_cons (fns, args, NULL_TREE);
if (has_default_arg)
{
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index bbc6700..5827c28 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -4422,17 +4422,22 @@ tsubst_friend_function (decl, args)
function declaration. Now, we have to figure out what
instantiation of what template. */
{
- tree template_id;
+ tree template_id, arglist, fns;
tree new_args;
tree tmpl;
-
- template_id
- = lookup_template_function (tsubst_expr (DECL_TI_TEMPLATE (decl),
- args, /*complain=*/1,
- NULL_TREE),
- tsubst (DECL_TI_ARGS (decl),
- args, /*complain=*/1,
- NULL_TREE));
+ tree ns = CP_DECL_CONTEXT (TYPE_MAIN_DECL (current_class_type));
+
+ /* Friend functions are looked up in the containing namespace scope.
+ We must enter that scope, to avoid finding member functions of the
+ current cless with same name. */
+ push_nested_namespace (ns);
+ fns = tsubst_expr (DECL_TI_TEMPLATE (decl), args,
+ /*complain=*/1, NULL_TREE);
+ pop_nested_namespace (ns);
+ arglist = tsubst (DECL_TI_ARGS (decl), args,
+ /*complain=*/1, NULL_TREE);
+ template_id = lookup_template_function (fns, arglist);
+
new_friend = tsubst (decl, args, /*complain=*/1, NULL_TREE);
tmpl = determine_specialization (template_id, new_friend,
&new_args,