This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: Qualified friends
- To: egcs-patches at egcs dot cygnus dot com
- Subject: Re: Qualified friends
- From: "Martin v. Loewis" <martin at mira dot isdn dot cs dot tu-berlin dot de>
- Date: Wed, 24 Feb 1999 12:26:40 +0100
- References: <199902210950.KAA08701@mira.isdn.cs.tu-berlin.de> <36D28C0A.48B5A68A@acm.org>
> Another bug me thinks.
Indeed. This would always fail if a global function is friend of a
namespace-scoped class. The reason is that we can't distinguish in
DECL_CONTEXT between 'uninitialized context', and 'context is
global_namespace'.
Below is a patch. Please let me know if it works.
Martin
1999-02-24 Martin von Löwis <loewis@informatik.hu-berlin.de>
* decl.c (grokdeclarator): Set current_namespace when pushing
friends.
(grokfndecl): Likewise, for mangling.
//Build don't link:
namespace M {
class S;
}
void foo(M::S *);
namespace M {
class S {
friend void ::foo(S *);
void Fn();
static S s;
};
}
void ::foo(M::S *ptr) {
M::S::s.Fn();
ptr->Fn();
}
Index: decl.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/cp/decl.c,v
retrieving revision 1.312
diff -c -p -r1.312 decl.c
*** decl.c 1999/02/21 16:38:14 1.312
--- decl.c 1999/02/24 09:43:42
*************** grokfndecl (ctype, type, declarator, ori
*** 8512,8518 ****
if (! ctype && ! processing_template_decl
&& DECL_LANGUAGE (decl) != lang_c
&& (! DECL_USE_TEMPLATE (decl) || name_mangling_version < 1))
! set_mangled_name_for_decl (decl);
if (funcdef_flag)
/* Make the init_value nonzero so pushdecl knows this is not
--- 8512,8526 ----
if (! ctype && ! processing_template_decl
&& DECL_LANGUAGE (decl) != lang_c
&& (! DECL_USE_TEMPLATE (decl) || name_mangling_version < 1))
! {
! /* When mangling, we need current_namespace to be the namespace
! of the decl we are making. */
! tree saved_namespace = current_namespace;
! if (in_namespace)
! current_namespace = in_namespace;
! set_mangled_name_for_decl (decl);
! current_namespace = saved_namespace;
! }
if (funcdef_flag)
/* Make the init_value nonzero so pushdecl knows this is not
*************** grokdeclarator (declarator, declspecs, d
*** 11029,11034 ****
--- 11037,11043 ----
tree t = NULL_TREE;
if (decl && DECL_NAME (decl))
{
+ tree saved_namespace = current_namespace;
if (template_class_depth (current_class_type) == 0)
{
decl
*************** grokdeclarator (declarator, declspecs, d
*** 11039,11047 ****
--- 11048,11065 ----
return error_mark_node;
}
+ /* If we have an explicit global_scope for the
+ friend we still have no DECL_CONTEXT on it
+ (since global_namespace is represented by 0).
+ pushdecl will then think it has to set the context,
+ based on current_namespace. */
+
+ if (in_namespace)
+ current_namespace = in_namespace;
t = do_friend (ctype, declarator, decl,
last_function_parms, flags, quals,
funcdef_flag);
+ current_namespace = saved_namespace;
}
if (t && funcdef_flag)
return t;