This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

PR 8700



This patch fixes PR 8700.


Tested on i686-pc-linux-gnu, applied on the mainline and on the
branch.

(It turns out that some of my recent patch mails have been dropped on
the floor by the mailing lists; the Red Hat 8.0 upgrade program
apparently changed my sendmail configuration that makes the mailing
lists drop mail, even without bouncing it back to me. Unfortunately, I neither have the mails nor the old configuration. Oh, well...)


--
Mark Mitchell                   mark at codesourcery dot com
CodeSourcery, LLC               http://www.codesourcery.com

2003-03-11 Mark Mitchell <mark at codesourcery dot com>

	PR c++/8700
	* call.c (convert_class_to_reference): Adjust usage of
	splice_viable.
	(any_viable): Remove.
	(splice_viable): Combine with any_viable.
	(print_z_candidates): Avoid printing duplicates.
	(build_user_type_conversion_1): Adjust usage of splice_viable.
	(build_new_function_call): Likewise.
	(build_operator_new_call): Likewise.
	(build_object_call): Likewise.
	(build_conditional_expr): Likewise.
	(build_new_op): Likewise.
	(build_new_method_call): Likewise.
	(joust): Remove spurious comment.
	* cp-tree.h (DECL_FRIENDLIST): Correct documentation.
	* decl2.c (arg_assoc_class): Simplify.
	* friend.c (add_friend): Likewise.

Index: call.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/call.c,v
retrieving revision 1.366
diff -c -5 -p -r1.366 call.c
*** call.c 11 Mar 2003 02:37:13 -0000 1.366
--- call.c 11 Mar 2003 08:26:51 -0000
*************** static void op_error (enum tree_code, en
*** 56,67 ****
static tree build_object_call (tree, tree);
static tree resolve_args (tree);
static struct z_candidate *build_user_type_conversion_1 (tree, tree, int);
static void print_z_candidates (struct z_candidate *);
static tree build_this (tree);
! static struct z_candidate *splice_viable (struct z_candidate *);
! static bool any_viable (struct z_candidate *);
static bool any_strictly_viable (struct z_candidate *);
static struct z_candidate *add_template_candidate
(struct z_candidate **, tree, tree, tree, tree, tree,
tree, tree, int, unification_kind_t);
static struct z_candidate *add_template_candidate_real
--- 56,66 ----
static tree build_object_call (tree, tree);
static tree resolve_args (tree);
static struct z_candidate *build_user_type_conversion_1 (tree, tree, int);
static void print_z_candidates (struct z_candidate *);
static tree build_this (tree);
! static struct z_candidate *splice_viable (struct z_candidate *, bool, bool *);
static bool any_strictly_viable (struct z_candidate *);
static struct z_candidate *add_template_candidate
(struct z_candidate **, tree, tree, tree, tree, tree,
tree, tree, int, unification_kind_t);
static struct z_candidate *add_template_candidate_real
*************** convert_class_to_reference (tree t, tree
*** 956,965 ****
--- 955,965 ----
tree arglist;
tree conv;
tree reference_type;
struct z_candidate *candidates;
struct z_candidate *cand;
+ bool any_viable_p;


   conversions = lookup_conversions (s);
   if (!conversions)
     return NULL_TREE;

*************** convert_class_to_reference (tree t, tree
*** 1051,1066 ****
 			  NULL_TREE)));
 	}
       conversions = TREE_CHAIN (conversions);
     }

   /* If none of the conversion functions worked out, let our caller
      know.  */
!   if (!any_viable (candidates))
     return NULL_TREE;
!
!   candidates = splice_viable (candidates);
   cand = tourney (candidates);
   if (!cand)
     return NULL_TREE;

   /* Now that we know that this is the function we're going to use fix
--- 1051,1066 ----
 			  NULL_TREE)));
 	}
       conversions = TREE_CHAIN (conversions);
     }

+   candidates = splice_viable (candidates, pedantic, &any_viable_p);
   /* If none of the conversion functions worked out, let our caller
      know.  */
!   if (!any_viable_p)
     return NULL_TREE;
!
   cand = tourney (candidates);
   if (!cand)
     return NULL_TREE;

   /* Now that we know that this is the function we're going to use fix
*************** add_template_conv_candidate (struct z_ca
*** 2371,2388 ****
     add_template_candidate_real (candidates, tmpl, NULL_TREE, NULL_TREE,
 				 arglist, return_type, access_path,
 				 conversion_path, 0, obj, DEDUCE_CONV);
 }


! static bool ! any_viable (struct z_candidate *cands) ! { ! for (; cands; cands = cands->next) ! if (pedantic ? cands->viable == 1 : cands->viable) ! return true; ! return false; }

 static bool
 any_strictly_viable (struct z_candidate *cands)
 {
--- 2371,2416 ----
     add_template_candidate_real (candidates, tmpl, NULL_TREE, NULL_TREE,
 				 arglist, return_type, access_path,
 				 conversion_path, 0, obj, DEDUCE_CONV);
 }

+ /* The CANDS are the set of candidates that were considered for
+    overload resolution.  Return the set of viable candidates.  If none
+    of the candidates were viable, set *ANY_VIABLE_P to true.  STRICT_P
+    is true if a candidate should be considered viable only if it is
+    strictly viable.  */

! static struct z_candidate*
! splice_viable (struct z_candidate *cands,
! 	       bool strict_p,
! 	       bool *any_viable_p)
! {
!   struct z_candidate *viable;
!   struct z_candidate **last_viable;
!   struct z_candidate **cand;
!
!   viable = NULL;
!   last_viable = &viable;
!   *any_viable_p = false;
!
!   cand = &cands;
!   while (*cand)
!     {
!       struct z_candidate *c = *cand;
!       if (strict_p ? c->viable == 1 : c->viable)
! 	{
! 	  *last_viable = c;
! 	  *cand = c->next;
! 	  c->next = NULL;
! 	  last_viable = &c->next;
! 	  *any_viable_p = true;
! 	}
!       else
! 	cand = &c->next;
!     }
!
!   return viable ? viable : cands;
 }

 static bool
 any_strictly_viable (struct z_candidate *cands)
 {
*************** any_strictly_viable (struct z_candidate
*** 2390,2426 ****
     if (cands->viable == 1)
       return true;
   return false;
 }

- static struct z_candidate *
- splice_viable (struct z_candidate *cands)
- {
-   struct z_candidate **p = &cands;
-
-   for (; *p; )
-     {
-       if (pedantic ? (*p)->viable == 1 : (*p)->viable)
- 	p = &((*p)->next);
-       else
- 	*p = (*p)->next;
-     }
-
-   return cands;
- }
-
 static tree
 build_this (tree obj)
 {
   /* Fix this to work on non-lvalues.  */
   return build_unary_op (ADDR_EXPR, obj, 0);
 }

 static void
 print_z_candidates (struct z_candidate *candidates)
 {
!   const char *str = "candidates are:";
   for (; candidates; candidates = candidates->next)
     {
       if (TREE_CODE (candidates->fn) == IDENTIFIER_NODE)
 	{
 	  if (TREE_VEC_LENGTH (candidates->convs) == 3)
--- 2418,2477 ----
     if (cands->viable == 1)
       return true;
   return false;
 }

 static tree
 build_this (tree obj)
 {
   /* Fix this to work on non-lvalues.  */
   return build_unary_op (ADDR_EXPR, obj, 0);
 }

+ /* Returns true iff functions are equivalent. Equivalent functions are
+    not '==' only if one is a function-local extern function or if
+    both are extern "C".  */
+
+ static inline int
+ equal_functions (tree fn1, tree fn2)
+ {
+   if (DECL_LOCAL_FUNCTION_P (fn1) || DECL_LOCAL_FUNCTION_P (fn2)
+       || DECL_EXTERN_C_FUNCTION_P (fn1))
+     return decls_match (fn1, fn2);
+   return fn1 == fn2;
+ }
+
 static void
 print_z_candidates (struct z_candidate *candidates)
 {
!   const char *str;
!   struct z_candidate *cand1;
!   struct z_candidate **cand2;
!
!   /* There may be duplicates in the set of candidates.  We put off
!      checking this condition as long as possible, since we have no way
!      to eliminate duplicates from a set of functions in less than n^2
!      time.  Now we are about to emit an error message, so it is more
!      permissible to go slowly.  */
!   for (cand1 = candidates; cand1; cand1 = cand1->next)
!     {
!       tree fn = cand1->fn;
!       /* Skip builtin candidates and conversion functions.  */
!       if (TREE_CODE (fn) != FUNCTION_DECL)
! 	continue;
!       cand2 = &cand1->next;
!       while (*cand2)
! 	{
! 	  if (TREE_CODE ((*cand2)->fn) == FUNCTION_DECL
! 	      && equal_functions (fn, (*cand2)->fn))
! 	    *cand2 = (*cand2)->next;
! 	  else
! 	    cand2 = &(*cand2)->next;
! 	}
!     }
!
!   str = "candidates are:";
   for (; candidates; candidates = candidates->next)
     {
       if (TREE_CODE (candidates->fn) == IDENTIFIER_NODE)
 	{
 	  if (TREE_VEC_LENGTH (candidates->convs) == 3)
*************** build_user_type_conversion_1 (tree totyp
*** 2485,2494 ****
--- 2536,2546 ----
 {
   struct z_candidate *candidates, *cand;
   tree fromtype = TREE_TYPE (expr);
   tree ctors = NULL_TREE, convs = NULL_TREE;
   tree args = NULL_TREE;
+   bool any_viable_p;

   /* We represent conversion within a hierarchy using RVALUE_CONV and
      BASE_CONV, as specified by [over.best.ics]; these become plain
      constructor calls, as specified in [dcl.init].  */
   my_friendly_assert (!IS_AGGR_TYPE (fromtype) || !IS_AGGR_TYPE (totype)
*************** build_user_type_conversion_1 (tree totyp
*** 2600,2615 ****
 		cand->viable = -1;
 	    }
 	}
     }

!   if (! any_viable (candidates))
     return 0;

-   candidates = splice_viable (candidates);
   cand = tourney (candidates);
-
   if (cand == 0)
     {
       if (flags & LOOKUP_COMPLAIN)
 	{
 	  error ("conversion from `%T' to `%T' is ambiguous",
--- 2652,2666 ----
 		cand->viable = -1;
 	    }
 	}
     }

!   candidates = splice_viable (candidates, pedantic, &any_viable_p);
!   if (!any_viable_p)
     return 0;

   cand = tourney (candidates);
   if (cand == 0)
     {
       if (flags & LOOKUP_COMPLAIN)
 	{
 	  error ("conversion from `%T' to `%T' is ambiguous",
*************** perform_overload_resolution (tree fn,
*** 2800,2818 ****
 		  /*conversion_path=*/NULL_TREE,
 		  /*access_path=*/NULL_TREE,
 		  LOOKUP_NORMAL,
 		  candidates);

!   if (! any_viable (*candidates))
!     {
!       *any_viable_p = false;
!       return NULL;
!     }

-   *candidates = splice_viable (*candidates);
   cand = tourney (*candidates);
-
   return cand;
 }

 /* Return an expression for a call to FN (a namespace-scope function,
    or a static member function) with the ARGS.  */
--- 2851,2865 ----
 		  /*conversion_path=*/NULL_TREE,
 		  /*access_path=*/NULL_TREE,
 		  LOOKUP_NORMAL,
 		  candidates);

!   *candidates = splice_viable (*candidates, pedantic, any_viable_p);
!   if (!*any_viable_p)
!     return NULL;

   cand = tourney (*candidates);
   return cand;
 }

 /* Return an expression for a call to FN (a namespace-scope function,
    or a static member function) with the ARGS.  */
*************** build_new_function_call (tree fn, tree a
*** 2838,2848 ****
       if (!any_viable_p)
 	error ("no matching function for call to `%D(%A)'",
 	       DECL_NAME (OVL_CURRENT (fn)), args);
       else
 	error ("call of overloaded `%D(%A)' is ambiguous",
! 	       DECL_NAME (OVL_FUNCTION (fn)), args);
       if (candidates)
 	print_z_candidates (candidates);
       return error_mark_node;
     }

--- 2885,2895 ----
       if (!any_viable_p)
 	error ("no matching function for call to `%D(%A)'",
 	       DECL_NAME (OVL_CURRENT (fn)), args);
       else
 	error ("call of overloaded `%D(%A)' is ambiguous",
! 	       DECL_NAME (OVL_CURRENT (fn)), args);
       if (candidates)
 	print_z_candidates (candidates);
       return error_mark_node;
     }

*************** build_operator_new_call (tree fnname, tr
*** 2882,2892 ****
       if (!any_viable_p)
 	error ("no matching function for call to `%D(%A)'",
 	       DECL_NAME (OVL_CURRENT (fns)), args);
       else
 	error ("call of overlopaded `%D(%A)' is ambiguous",
! 	       DECL_NAME (OVL_FUNCTION (fns)), args);
       if (candidates)
 	print_z_candidates (candidates);
       return error_mark_node;
     }

--- 2929,2939 ----
       if (!any_viable_p)
 	error ("no matching function for call to `%D(%A)'",
 	       DECL_NAME (OVL_CURRENT (fns)), args);
       else
 	error ("call of overlopaded `%D(%A)' is ambiguous",
! 	       DECL_NAME (OVL_CURRENT (fns)), args);
       if (candidates)
 	print_z_candidates (candidates);
       return error_mark_node;
     }

*************** static tree
*** 2941,2950 ****
--- 2988,2998 ----
 build_object_call (tree obj, tree args)
 {
   struct z_candidate *candidates = 0, *cand;
   tree fns, convs, mem_args = NULL_TREE;
   tree type = TREE_TYPE (obj);
+   bool any_viable_p;

   if (TYPE_PTRMEMFUNC_P (type))
     {
       /* It's no good looking for an overloaded operator() on a
 	 pointer-to-member-function.  */
*************** build_object_call (tree obj, tree args)
*** 3009,3028 ****
 				  /*conversion_path=*/NULL_TREE,
 				  /*access_path=*/NULL_TREE);
 	  }
     }

!   if (! any_viable (candidates))
     {
       error ("no match for call to `(%T) (%A)'", TREE_TYPE (obj), args);
       print_z_candidates (candidates);
       return error_mark_node;
     }

-   candidates = splice_viable (candidates);
   cand = tourney (candidates);
-
   if (cand == 0)
     {
       error ("call of `(%T) (%A)' is ambiguous", TREE_TYPE (obj), args);
       print_z_candidates (candidates);
       return error_mark_node;
--- 3057,3075 ----
 				  /*conversion_path=*/NULL_TREE,
 				  /*access_path=*/NULL_TREE);
 	  }
     }

!   candidates = splice_viable (candidates, pedantic, &any_viable_p);
!   if (!any_viable_p)
     {
       error ("no match for call to `(%T) (%A)'", TREE_TYPE (obj), args);
       print_z_candidates (candidates);
       return error_mark_node;
     }

   cand = tourney (candidates);
   if (cand == 0)
     {
       error ("call of `(%T) (%A)' is ambiguous", TREE_TYPE (obj), args);
       print_z_candidates (candidates);
       return error_mark_node;
*************** build_conditional_expr (tree arg1, tree
*** 3300,3309 ****
--- 3347,3357 ----
   if (!same_type_p (arg2_type, arg3_type)
       && (CLASS_TYPE_P (arg2_type) || CLASS_TYPE_P (arg3_type)))
     {
       tree args[3];
       tree conv;
+       bool any_viable_p;

       /* Rearrange the arguments so that add_builtin_candidate only has
 	 to know about two args.  In build_builtin_candidates, the
 	 arguments are unscrambled.  */
       args[0] = arg2;
*************** build_conditional_expr (tree arg1, tree
*** 3318,3334 ****

/* [expr.cond]

 	 If the overload resolution fails, the program is
 	 ill-formed.  */
!       if (!any_viable (candidates))
 	{
 	  op_error (COND_EXPR, NOP_EXPR, arg1, arg2, arg3, "no match");
 	  print_z_candidates (candidates);
 	  return error_mark_node;
 	}
-       candidates = splice_viable (candidates);
       cand = tourney (candidates);
       if (!cand)
 	{
 	  op_error (COND_EXPR, NOP_EXPR, arg1, arg2, arg3, "no match");
 	  print_z_candidates (candidates);
--- 3366,3382 ----

/* [expr.cond]

 	 If the overload resolution fails, the program is
 	 ill-formed.  */
!       candidates = splice_viable (candidates, pedantic, &any_viable_p);
!       if (!any_viable_p)
 	{
 	  op_error (COND_EXPR, NOP_EXPR, arg1, arg2, arg3, "no match");
 	  print_z_candidates (candidates);
 	  return error_mark_node;
 	}
       cand = tourney (candidates);
       if (!cand)
 	{
 	  op_error (COND_EXPR, NOP_EXPR, arg1, arg2, arg3, "no match");
 	  print_z_candidates (candidates);
*************** build_new_op (enum tree_code code, int f
*** 3563,3573 ****
   struct z_candidate *candidates = 0, *cand;
   tree arglist, fnname;
   tree args[3];
   enum tree_code code2 = NOP_EXPR;
   tree conv;
!   bool viable_candidates;

   if (error_operand_p (arg1)
       || error_operand_p (arg2)
       || error_operand_p (arg3))
     return error_mark_node;
--- 3611,3622 ----
   struct z_candidate *candidates = 0, *cand;
   tree arglist, fnname;
   tree args[3];
   enum tree_code code2 = NOP_EXPR;
   tree conv;
!   bool strict_p;
!   bool any_viable_p;

   if (error_operand_p (arg1)
       || error_operand_p (arg2)
       || error_operand_p (arg3))
     return error_mark_node;
*************** build_new_op (enum tree_code code, int f
*** 3673,3691 ****
 	 [over.match.oper]/3.  We don't want non-strict matches
 	 because exact matches are always possible with built-in
 	 operators.  The built-in candidate set for COMPONENT_REF
 	 would be empty too, but since there are no such built-in
 	 operators, we accept non-strict matches for them.  */
!       viable_candidates = any_strictly_viable (candidates);
       break;

     default:
!       viable_candidates = any_viable (candidates);
       break;
     }

!   if (! viable_candidates)
     {
       switch (code)
 	{
 	case POSTINCREMENT_EXPR:
 	case POSTDECREMENT_EXPR:
--- 3722,3741 ----
 	 [over.match.oper]/3.  We don't want non-strict matches
 	 because exact matches are always possible with built-in
 	 operators.  The built-in candidate set for COMPONENT_REF
 	 would be empty too, but since there are no such built-in
 	 operators, we accept non-strict matches for them.  */
!       strict_p = true;
       break;

     default:
!       strict_p = pedantic;
       break;
     }

!   candidates = splice_viable (candidates, strict_p, &any_viable_p);
!   if (!any_viable_p)
     {
       switch (code)
 	{
 	case POSTINCREMENT_EXPR:
 	case POSTDECREMENT_EXPR:
*************** build_new_op (enum tree_code code, int f
*** 3715,3727 ****
 	  op_error (code, code2, arg1, arg2, arg3, "no match");
 	  print_z_candidates (candidates);
 	}
       return error_mark_node;
     }
-   candidates = splice_viable (candidates);
-   cand = tourney (candidates);

   if (cand == 0)
     {
       if (flags & LOOKUP_COMPLAIN)
 	{
 	  op_error (code, code2, arg1, arg2, arg3, "ambiguous overload");
--- 3765,3776 ----
 	  op_error (code, code2, arg1, arg2, arg3, "no match");
 	  print_z_candidates (candidates);
 	}
       return error_mark_node;
     }

+   cand = tourney (candidates);
   if (cand == 0)
     {
       if (flags & LOOKUP_COMPLAIN)
 	{
 	  op_error (code, code2, arg1, arg2, arg3, "ambiguous overload");
*************** build_new_method_call (tree instance, tr
*** 4883,4892 ****
--- 4932,4942 ----
   tree user_args;
   tree call;
   tree fn;
   tree class_type;
   int template_only = 0;
+   bool any_viable_p;

my_friendly_assert (instance != NULL_TREE, 20020729);

   if (error_operand_p (instance)
       || error_operand_p (fns)
*************** build_new_method_call (tree instance, tr
*** 4999,5009 ****
 				access_binfo,
 				conversion_path,
 				flags);
     }

!   if (! any_viable (candidates))
     {
       /* XXX will LOOKUP_SPECULATIVELY be needed when this is done?  */
       if (flags & LOOKUP_SPECULATIVELY)
 	return NULL_TREE;
       if (!COMPLETE_TYPE_P (basetype))
--- 5049,5060 ----
 				access_binfo,
 				conversion_path,
 				flags);
     }

!   candidates = splice_viable (candidates, pedantic, &any_viable_p);
!   if (!any_viable_p)
     {
       /* XXX will LOOKUP_SPECULATIVELY be needed when this is done?  */
       if (flags & LOOKUP_SPECULATIVELY)
 	return NULL_TREE;
       if (!COMPLETE_TYPE_P (basetype))
*************** build_new_method_call (tree instance, tr
*** 5021,5033 ****
 	    free (pretty_name);
 	}
       print_z_candidates (candidates);
       return error_mark_node;
     }
-   candidates = splice_viable (candidates);
-   cand = tourney (candidates);

   if (cand == 0)
     {
       char *pretty_name;
       bool free_p;

--- 5072,5083 ----
 	    free (pretty_name);
 	}
       print_z_candidates (candidates);
       return error_mark_node;
     }

+   cand = tourney (candidates);
   if (cand == 0)
     {
       char *pretty_name;
       bool free_p;

*************** add_warning (struct z_candidate *winner,
*** 5553,5575 ****
   winner->warnings = tree_cons (NULL_TREE,
 				build_zc_wrapper (loser),
 				winner->warnings);
 }

- /* Returns true iff functions are equivalent. Equivalent functions are
-    not '==' only if one is a function-local extern function or if
-    both are extern "C".  */
-
- static inline int
- equal_functions (tree fn1, tree fn2)
- {
-   if (DECL_LOCAL_FUNCTION_P (fn1) || DECL_LOCAL_FUNCTION_P (fn2)
-       || DECL_EXTERN_C_FUNCTION_P (fn1))
-     return decls_match (fn1, fn2);
-   return fn1 == fn2;
- }
-
 /* Compare two candidates for overloading as described in
    [over.match.best].  Return values:

       1: cand1 is better than cand2
      -1: cand2 is better than cand1
--- 5603,5612 ----
*************** joust (struct z_candidate *cand1, struct
*** 5746,5756 ****
 	    arguments has no effect on the partial ordering of function
 	    templates.  */
          TREE_VEC_LENGTH (cand1->convs)
 	 - (DECL_NONSTATIC_MEMBER_FUNCTION_P (cand1->fn)
 	    - DECL_CONSTRUCTOR_P (cand1->fn)));
-       /* HERE */
       if (winner)
         return winner;
     }

/* or, if not that,
--- 5783,5792 ----
*************** joust (struct z_candidate *cand1, struct
*** 5803,5813 ****
/* If the two functions are the same (this can happen with declarations
in multiple scopes and arg-dependent lookup), arbitrarily choose one. */
if (DECL_P (cand1->fn) && DECL_P (cand2->fn)
&& equal_functions (cand1->fn, cand2->fn))
return 1;
!
tweak:


/* Extension: If the worst conversion for one candidate is worse than the
worst conversion for the other, take the first. */
if (!pedantic)
--- 5839,5849 ----
/* If the two functions are the same (this can happen with declarations
in multiple scopes and arg-dependent lookup), arbitrarily choose one. */
if (DECL_P (cand1->fn) && DECL_P (cand2->fn)
&& equal_functions (cand1->fn, cand2->fn))
return 1;
!
tweak:


/* Extension: If the worst conversion for one candidate is worse than the
worst conversion for the other, take the first. */
if (!pedantic)
Index: cp-tree.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/cp-tree.h,v
retrieving revision 1.823
diff -c -5 -p -r1.823 cp-tree.h
*** cp-tree.h 11 Mar 2003 02:37:13 -0000 1.823
--- cp-tree.h 11 Mar 2003 08:26:52 -0000
*************** struct lang_decl GTY(())
*** 2655,2672 ****
/* C++: all of these are overloaded! These apply only to TYPE_DECLs. */


/* The format of each node in the DECL_FRIENDLIST is as follows:

    The TREE_PURPOSE will be the name of a function, i.e., an
!    IDENTIFIER_NODE.  The TREE_VALUE will be itself a TREE_LIST, the
!    list of functions with that name which are friends.  The
!    TREE_PURPOSE of each node in this sublist will be error_mark_node,
!    if the function was declared a friend individually, in which case
!    the TREE_VALUE will be the function_decl.  If, however, all
!    functions with a given name in a class were declared to be friends,
!    the TREE_PUROSE will be the class type, and the TREE_VALUE will be
!    NULL_TREE.  */
 #define DECL_FRIENDLIST(NODE)		(DECL_INITIAL (NODE))
 #define FRIEND_NAME(LIST) (TREE_PURPOSE (LIST))
 #define FRIEND_DECLS(LIST) (TREE_VALUE (LIST))

 /* The DECL_ACCESS, if non-NULL, is a TREE_LIST.  The TREE_PURPOSE of
--- 2655,2666 ----
 /* C++: all of these are overloaded!  These apply only to TYPE_DECLs.  */

/* The format of each node in the DECL_FRIENDLIST is as follows:

    The TREE_PURPOSE will be the name of a function, i.e., an
!    IDENTIFIER_NODE.  The TREE_VALUE will be itself a TREE_LIST, whose
!    TREE_VALUEs are friends with the given name.  */
 #define DECL_FRIENDLIST(NODE)		(DECL_INITIAL (NODE))
 #define FRIEND_NAME(LIST) (TREE_PURPOSE (LIST))
 #define FRIEND_DECLS(LIST) (TREE_VALUE (LIST))

 /* The DECL_ACCESS, if non-NULL, is a TREE_LIST.  The TREE_PURPOSE of
Index: decl2.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/decl2.c,v
retrieving revision 1.602
diff -c -5 -p -r1.602 decl2.c
*** decl2.c	10 Mar 2003 21:10:37 -0000	1.602
--- decl2.c	11 Mar 2003 08:26:53 -0000
*************** arg_assoc_class (struct arg_lookup *k, t
*** 3924,3940 ****
       return true;

   /* Process friends.  */
   for (list = DECL_FRIENDLIST (TYPE_MAIN_DECL (type)); list;
        list = TREE_CHAIN (list))
!     if (k->name == TREE_PURPOSE (list))
!       for (friends = TREE_VALUE (list); friends;
 	   friends = TREE_CHAIN (friends))
 	/* Only interested in global functions with potentially hidden
            (i.e. unqualified) declarations.  */
! 	if (TREE_PURPOSE (friends) == error_mark_node && TREE_VALUE (friends)
! 	    && decl_namespace (TREE_VALUE (friends)) == context)
 	  if (add_function (k, TREE_VALUE (friends)))
 	    return true;

   /* Process template arguments.  */
   if (CLASSTYPE_TEMPLATE_INFO (type))
--- 3924,3939 ----
       return true;

   /* Process friends.  */
   for (list = DECL_FRIENDLIST (TYPE_MAIN_DECL (type)); list;
        list = TREE_CHAIN (list))
!     if (k->name == FRIEND_NAME (list))
!       for (friends = FRIEND_DECLS (list); friends;
 	   friends = TREE_CHAIN (friends))
 	/* Only interested in global functions with potentially hidden
            (i.e. unqualified) declarations.  */
! 	if (decl_namespace (TREE_VALUE (friends)) == context)
 	  if (add_function (k, TREE_VALUE (friends)))
 	    return true;

   /* Process template arguments.  */
   if (CLASSTYPE_TEMPLATE_INFO (type))
Index: friend.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/friend.c,v
retrieving revision 1.81
diff -c -5 -p -r1.81 friend.c
*** friend.c	2 Jan 2003 11:39:46 -0000	1.81
--- friend.c	11 Mar 2003 08:26:53 -0000
*************** add_friend (type, decl)
*** 163,183 ****
 		}
 	    }

maybe_add_class_template_decl_list (type, decl, /*friend_p=*/1);

! 	  TREE_VALUE (list) = tree_cons (error_mark_node, decl,
 					 TREE_VALUE (list));
 	  return;
 	}
       list = TREE_CHAIN (list);
     }

maybe_add_class_template_decl_list (type, decl, /*friend_p=*/1);

DECL_FRIENDLIST (typedecl)
! = tree_cons (DECL_NAME (decl), build_tree_list (error_mark_node, decl),
DECL_FRIENDLIST (typedecl));
if (!uses_template_parms (type))
DECL_BEFRIENDING_CLASSES (decl)
= tree_cons (NULL_TREE, type,
DECL_BEFRIENDING_CLASSES (decl));
--- 163,183 ----
}
}


maybe_add_class_template_decl_list (type, decl, /*friend_p=*/1);

! 	  TREE_VALUE (list) = tree_cons (NULL_TREE, decl,
 					 TREE_VALUE (list));
 	  return;
 	}
       list = TREE_CHAIN (list);
     }

maybe_add_class_template_decl_list (type, decl, /*friend_p=*/1);

   DECL_FRIENDLIST (typedecl)
!     = tree_cons (DECL_NAME (decl), build_tree_list (NULL_TREE, decl),
 		 DECL_FRIENDLIST (typedecl));
   if (!uses_template_parms (type))
     DECL_BEFRIENDING_CLASSES (decl)
       = tree_cons (NULL_TREE, type,
 		   DECL_BEFRIENDING_CLASSES (decl));



Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]