Qualified friends

Martin v. Loewis martin@mira.isdn.cs.tu-berlin.de
Wed Feb 24 14:00:00 GMT 1999


> 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;


More information about the Gcc-patches mailing list