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]

revised PATCH: CALL_EXPR representation changes, part 6/9 (C++ front end)


2007-02-14  Sandra Loosemore  <sandra@codesourcery.com>
	    Brooks Moses  <brooks.moses@codesourcery.com>
	    Lee Millward  <lee.millward@codesourcery.com>

	* cp-tree.def (AGGR_INIT_EXPR): Adjust documentation.
	Change class to tcc_vl_exp.

	* call.c (build_call): Use build_call_list instead 
	of build3. 
	(build_over_call): Likewise.
	(build_new_method_call): Use build_min_non_dep_call_list 
	instead of build_min_non_dep.

	* error.c (dump_call_expr_args): New function.
	(dump_aggr_init_expr_args): New function.
	(dump_expr) <AGGR_INIT_EXPR, CALL_EXPR, INDIRECT_REF>: Use them. 
	Update to use new CALL_EXPR and AGGR_INIT_EXPR accessor macros.

	* cvt.c (convert_to_void): Use build_call_array instead
	of build3; use new AGGR_INIT_EXPR accessor macros.

	* mangle.c (write_expression): Use TREE_OPERAND_LENGTH
	instead of TREE_CODE_LENGTH.

	* dump.c (cp_dump_tree) <AGGR_INIT_EXPR>: Update to use new
	AGGR_INIT_EXPR accessor macros.

	* cp-gimplify.c (cp_gimplify_init_expr): Use 
	AGGR_INIT_EXPR_SLOT to set the slot operand.

	* cp-tree.h (AGGR_INIT_EXPR_FN): New macro.
	(AGGR_INIT_EXPR_SLOT): New macro.
	(AGGR_INIT_EXPR_ARG): New macro.
	(aggr_init_expr_nargs): New macro.
	(AGGR_INIT_EXPR_ARGP): New macro.
	(aggr_init_expr_arg_iterator): New.
	(init_aggr_init_expr_arg_iterator): New.
	(next_aggr_init_expr_arg): New.
	(first_aggr_init_expr_arg): New.
	(more_aggr_init_expr_args_p): New.
	(FOR_EACH_AGGR_INIT_EXPR_ARG): New.
	(stabilize_aggr_init): New declaration.
	(build_min_nt_call_list): Likewise.
	(build_min_non_dep_call_list): Likewise.

	* tree.c (process_aggr_init_operands): New function.
	(build_aggr_init_array) New function.
	(build_cplus_new): Update to use new CALL_EXPR and
	AGGR_INIT_EXPR accessor macros. Replace use of build3 with
	build_aggr_init_array.
	(build_min_nt_call_list): New function.
	(build_min_non_dep_call_list) Likewise.
	(build_min_nt): Assert input code parameter is not a variable
	length expression class.
	(build_min, build_min_non_dep): Likewise.
	(cp_tree_equal) <CALL_EXPR>: Iterate through the arguments
	to check for equality instead of recursing. Handle tcc_vl_exp
	tree code classes.
	(stabilize_call): Update to only handle CALL_EXPRs, not 
	AGGR_INIT_EXPRs; use new CALL_EXPR accessor macros.
	(stabilize_aggr_init): New function.
	(stabilize_init): Use it.

	* cxx-pretty-print.c (pp_cxx_postfix_expression)
	<AGGR_INIT_EXPR, CALL_EXPR>: Update to use new CALL_EXPR and
	AGGR_INIT_EXPR accessor macros and argument iterators.
	
	* pt.c (tsubst_copy) <CALL_EXPR>: Replace build_nt with
	build_vl_exp. Iterate through the operands, recursively 
	processing each one.
	(tsubst_copy_and_build) <CALL_EXPR>: Update to use new
	CALL_EXPR accessor macros.
	(value_dependent_expression_p) <default>: Handle tcc_vl_exp
	tree code classes. Use TREE_OPERAND_LENGTH instead of 
	TREE_CODE_LENGTH.

	* semantics.c (finish_call_expr): Use build_nt_call_list
	instead of build_nt.
	(simplify_aggr_init_expr): Update to use new AGGR_INIT_EXPR 
	accessor macros. Use build_call_array to construct the 
	CALL_EXPR node instead of build3
	
	* decl2.c (build_offset_ref_call_from_tree): Use 
	buil_nt_call_list and build_min_non_dep_call_list instead
	of build_min_nt and build_min_non_dep.

	* parser.c (cp_parser_postfix_expression) <CPP_OPEN_PAREN>:
	Use build_min_nt_call_list instead of build_min_nt.
Index: gcc/cp/cp-tree.def
===================================================================
*** gcc/cp/cp-tree.def	(revision 121818)
--- gcc/cp/cp-tree.def	(working copy)
*************** DEFTREECODE (MEMBER_REF, "member_ref", t
*** 74,83 ****
     operator converts to.  Operand is expression to be converted.  */
  DEFTREECODE (TYPE_EXPR, "type_expr", tcc_expression, 1)
  
! /* For AGGR_INIT_EXPR, operand 0 is function which performs initialization,
!    operand 1 is argument list to initialization function,
!    and operand 2 is the slot which was allocated for this expression.  */
! DEFTREECODE (AGGR_INIT_EXPR, "aggr_init_expr", tcc_expression, 3)
  
  /* A throw expression.  operand 0 is the expression, if there was one,
     else it is NULL_TREE.  */
--- 74,85 ----
     operator converts to.  Operand is expression to be converted.  */
  DEFTREECODE (TYPE_EXPR, "type_expr", tcc_expression, 1)
  
! /* AGGR_INIT_EXPRs have a variably-sized representation similar to
!    that of CALL_EXPRs.  Operand 0 is an INTEGER_CST node containing the
!    operand count, operand 1 is the function which performs initialization,
!    operand 2 is the slot which was allocated for this expression, and
!    the remaining operands are the arguments to the initialization function.  */
! DEFTREECODE (AGGR_INIT_EXPR, "aggr_init_expr", tcc_vl_exp, 3)
  
  /* A throw expression.  operand 0 is the expression, if there was one,
     else it is NULL_TREE.  */
Index: gcc/cp/call.c
===================================================================
*** gcc/cp/call.c	(revision 121818)
--- gcc/cp/call.c	(working copy)
*************** build_call (tree function, tree parms)
*** 336,342 ****
  				     TREE_VALUE (tmp), t);
  	}
  
!   function = build3 (CALL_EXPR, result_type, function, parms, NULL_TREE);
    TREE_HAS_CONSTRUCTOR (function) = is_constructor;
    TREE_NOTHROW (function) = nothrow;
  
--- 336,342 ----
  				     TREE_VALUE (tmp), t);
  	}
  
!   function = build_call_list (result_type, function, parms);
    TREE_HAS_CONSTRUCTOR (function) = is_constructor;
    TREE_NOTHROW (function) = nothrow;
  
*************** build_over_call (struct z_candidate *can
*** 4732,4738 ****
        tree expr;
        tree return_type;
        return_type = TREE_TYPE (TREE_TYPE (fn));
!       expr = build3 (CALL_EXPR, return_type, fn, args, NULL_TREE);
        if (TREE_THIS_VOLATILE (fn) && cfun)
  	current_function_returns_abnormally = 1;
        if (!VOID_TYPE_P (return_type))
--- 4732,4738 ----
        tree expr;
        tree return_type;
        return_type = TREE_TYPE (TREE_TYPE (fn));
!       expr = build_call_list (return_type, fn, args);
        if (TREE_THIS_VOLATILE (fn) && cfun)
  	current_function_returns_abnormally = 1;
        if (!VOID_TYPE_P (return_type))
*************** build_java_interface_fn_ref (tree fn, tr
*** 5114,5120 ****
    lookup_fn = build1 (ADDR_EXPR,
  		      build_pointer_type (TREE_TYPE (java_iface_lookup_fn)),
  		      java_iface_lookup_fn);
!   return build3 (CALL_EXPR, ptr_type_node, lookup_fn, lookup_args, NULL_TREE);
  }
  
  /* Returns the value to use for the in-charge parameter when making a
--- 5114,5120 ----
    lookup_fn = build1 (ADDR_EXPR,
  		      build_pointer_type (TREE_TYPE (java_iface_lookup_fn)),
  		      java_iface_lookup_fn);
!   return build_call_list (ptr_type_node, lookup_fn, lookup_args);
  }
  
  /* Returns the value to use for the in-charge parameter when making a
*************** build_new_method_call (tree instance, tr
*** 5525,5534 ****
      }
  
    if (processing_template_decl && call != error_mark_node)
!     call = (build_min_non_dep
! 	    (CALL_EXPR, call,
  	     build_min_nt (COMPONENT_REF, orig_instance, orig_fns, NULL_TREE),
! 	     orig_args, NULL_TREE));
  
   /* Free all the conversions we allocated.  */
    obstack_free (&conversion_obstack, p);
--- 5525,5534 ----
      }
  
    if (processing_template_decl && call != error_mark_node)
!     call = (build_min_non_dep_call_list
! 	    (call,
  	     build_min_nt (COMPONENT_REF, orig_instance, orig_fns, NULL_TREE),
! 	     orig_args));
  
   /* Free all the conversions we allocated.  */
    obstack_free (&conversion_obstack, p);
Index: gcc/cp/error.c
===================================================================
*** gcc/cp/error.c	(revision 121818)
--- gcc/cp/error.c	(working copy)
*************** static void dump_aggr_type (tree, int);
*** 66,71 ****
--- 66,73 ----
  static void dump_type_prefix (tree, int);
  static void dump_type_suffix (tree, int);
  static void dump_function_name (tree, int);
+ static void dump_call_expr_args (tree, int, bool);
+ static void dump_aggr_init_expr_args (tree, int, bool);
  static void dump_expr_list (tree, int);
  static void dump_global_iord (tree);
  static void dump_parameters (tree, int);
*************** dump_template_parms (tree info, int prim
*** 1265,1270 ****
--- 1267,1321 ----
    pp_cxx_end_template_argument_list (cxx_pp);
  }
  
+ /* Print out the arguments of CALL_EXPR T as a parenthesized list using
+    flags FLAGS.  Skip over the first argument if SKIPFIRST is true.  */
+ 
+ static void
+ dump_call_expr_args (tree t, int flags, bool skipfirst)
+ {
+   tree arg;
+   call_expr_arg_iterator iter;
+   
+   pp_cxx_left_paren (cxx_pp);
+   FOR_EACH_CALL_EXPR_ARG (arg, iter, t)
+     {
+       if (skipfirst)
+ 	skipfirst = false;
+       else
+ 	{
+ 	  dump_expr (arg, flags | TFF_EXPR_IN_PARENS);
+ 	  if (more_call_expr_args_p (&iter))
+ 	    pp_separate_with_comma (cxx_pp);
+ 	}
+     }
+   pp_cxx_right_paren (cxx_pp);
+ }
+ 
+ /* Print out the arguments of AGGR_INIT_EXPR T as a parenthesized list
+    using flags FLAGS.  Skip over the first argument if SKIPFIRST is
+    true.  */
+ 
+ static void
+ dump_aggr_init_expr_args (tree t, int flags, bool skipfirst)
+ {
+   tree arg;
+   aggr_init_expr_arg_iterator iter;
+   
+   pp_cxx_left_paren (cxx_pp);
+   FOR_EACH_AGGR_INIT_EXPR_ARG (arg, iter, t)
+     {
+       if (skipfirst)
+ 	skipfirst = false;
+       else
+ 	{
+ 	  dump_expr (arg, flags | TFF_EXPR_IN_PARENS);
+ 	  if (more_aggr_init_expr_args_p (&iter))
+ 	    pp_separate_with_comma (cxx_pp);
+ 	}
+     }
+   pp_cxx_right_paren (cxx_pp);
+ }
+ 
  /* Print out a list of initializers (subr of dump_expr).  */
  
  static void
*************** dump_expr (tree t, int flags)
*** 1387,1394 ****
        {
  	tree fn = NULL_TREE;
  
! 	if (TREE_CODE (TREE_OPERAND (t, 0)) == ADDR_EXPR)
! 	  fn = TREE_OPERAND (TREE_OPERAND (t, 0), 0);
  
  	if (fn && TREE_CODE (fn) == FUNCTION_DECL)
  	  {
--- 1438,1445 ----
        {
  	tree fn = NULL_TREE;
  
! 	if (TREE_CODE (AGGR_INIT_EXPR_FN (t)) == ADDR_EXPR)
! 	  fn = TREE_OPERAND (AGGR_INIT_EXPR_FN (t), 0);
  
  	if (fn && TREE_CODE (fn) == FUNCTION_DECL)
  	  {
*************** dump_expr (tree t, int flags)
*** 1398,1415 ****
  	      dump_decl (fn, 0);
  	  }
  	else
! 	  dump_expr (TREE_OPERAND (t, 0), 0);
        }
!       pp_cxx_left_paren (cxx_pp);
!       if (TREE_OPERAND (t, 1))
! 	dump_expr_list (TREE_CHAIN (TREE_OPERAND (t, 1)), flags);
!       pp_cxx_right_paren (cxx_pp);
        break;
  
      case CALL_EXPR:
        {
! 	tree fn = TREE_OPERAND (t, 0);
! 	tree args = TREE_OPERAND (t, 1);
  
  	if (TREE_CODE (fn) == ADDR_EXPR)
  	  fn = TREE_OPERAND (fn, 0);
--- 1449,1463 ----
  	      dump_decl (fn, 0);
  	  }
  	else
! 	  dump_expr (AGGR_INIT_EXPR_FN (t), 0);
        }
!       dump_aggr_init_expr_args (t, flags, false);
        break;
  
      case CALL_EXPR:
        {
! 	tree fn = CALL_EXPR_FN (t);
! 	bool skipfirst = false;
  
  	if (TREE_CODE (fn) == ADDR_EXPR)
  	  fn = TREE_OPERAND (fn, 0);
*************** dump_expr (tree t, int flags)
*** 1420,1426 ****
  
  	if (TREE_TYPE (fn) != NULL_TREE && NEXT_CODE (fn) == METHOD_TYPE)
  	  {
! 	    tree ob = TREE_VALUE (args);
  	    if (TREE_CODE (ob) == ADDR_EXPR)
  	      {
  		dump_expr (TREE_OPERAND (ob, 0), flags | TFF_EXPR_IN_PARENS);
--- 1468,1474 ----
  
  	if (TREE_TYPE (fn) != NULL_TREE && NEXT_CODE (fn) == METHOD_TYPE)
  	  {
! 	    tree ob = CALL_EXPR_ARG (t, 0);
  	    if (TREE_CODE (ob) == ADDR_EXPR)
  	      {
  		dump_expr (TREE_OPERAND (ob, 0), flags | TFF_EXPR_IN_PARENS);
*************** dump_expr (tree t, int flags)
*** 1432,1443 ****
  		dump_expr (ob, flags | TFF_EXPR_IN_PARENS);
  		pp_arrow (cxx_pp);
  	      }
! 	    args = TREE_CHAIN (args);
  	  }
  	dump_expr (fn, flags | TFF_EXPR_IN_PARENS);
! 	pp_cxx_left_paren (cxx_pp);
! 	dump_expr_list (args, flags);
! 	pp_cxx_right_paren (cxx_pp);
        }
        break;
  
--- 1480,1489 ----
  		dump_expr (ob, flags | TFF_EXPR_IN_PARENS);
  		pp_arrow (cxx_pp);
  	      }
! 	    skipfirst = true;
  	  }
  	dump_expr (fn, flags | TFF_EXPR_IN_PARENS);
! 	dump_call_expr_args (t, flags, skipfirst);
        }
        break;
  
*************** dump_expr (tree t, int flags)
*** 1581,1590 ****
  	{
  	  t = TREE_OPERAND (t, 0);
  	  gcc_assert (TREE_CODE (t) == CALL_EXPR);
! 	  dump_expr (TREE_OPERAND (t, 0), flags | TFF_EXPR_IN_PARENS);
! 	  pp_cxx_left_paren (cxx_pp);
! 	  dump_expr_list (TREE_CHAIN (TREE_OPERAND (t, 1)), flags);
! 	  pp_cxx_right_paren (cxx_pp);
  	}
        else
  	{
--- 1627,1634 ----
  	{
  	  t = TREE_OPERAND (t, 0);
  	  gcc_assert (TREE_CODE (t) == CALL_EXPR);
! 	  dump_expr (CALL_EXPR_FN (t), flags | TFF_EXPR_IN_PARENS);
! 	  dump_call_expr_args (t, flags, true);
  	}
        else
  	{
Index: gcc/cp/cvt.c
===================================================================
*** gcc/cp/cvt.c	(revision 121818)
--- gcc/cp/cvt.c	(working copy)
*************** convert_to_void (tree expr, const char *
*** 902,910 ****
  	  if (TREE_CODE (init) == AGGR_INIT_EXPR
  	      && !AGGR_INIT_VIA_CTOR_P (init))
  	    {
! 	      tree fn = TREE_OPERAND (init, 0);
! 	      expr = build3 (CALL_EXPR, TREE_TYPE (TREE_TYPE (TREE_TYPE (fn))),
! 			     fn, TREE_OPERAND (init, 1), NULL_TREE);
  	    }
  	}
        break;
--- 902,912 ----
  	  if (TREE_CODE (init) == AGGR_INIT_EXPR
  	      && !AGGR_INIT_VIA_CTOR_P (init))
  	    {
! 	      tree fn = AGGR_INIT_EXPR_FN (init);
! 	      expr = build_call_array (TREE_TYPE (TREE_TYPE (TREE_TYPE (fn))),
! 				       fn,
! 				       aggr_init_expr_nargs (init),
! 				       AGGR_INIT_EXPR_ARGP (init));
  	    }
  	}
        break;
Index: gcc/cp/mangle.c
===================================================================
*** gcc/cp/mangle.c	(revision 121818)
--- gcc/cp/mangle.c	(working copy)
*************** write_expression (tree expr)
*** 2206,2212 ****
  	  break;
  
  	default:
! 	  for (i = 0; i < TREE_CODE_LENGTH (code); ++i)
  	    {
  	      tree operand = TREE_OPERAND (expr, i);
  	      /* As a GNU extension, the middle operand of a
--- 2206,2212 ----
  	  break;
  
  	default:
! 	  for (i = 0; i < TREE_OPERAND_LENGTH (expr); ++i)
  	    {
  	      tree operand = TREE_OPERAND (expr, i);
  	      /* As a GNU extension, the middle operand of a
Index: gcc/cp/dump.c
===================================================================
*** gcc/cp/dump.c	(revision 121818)
--- gcc/cp/dump.c	(working copy)
*************** cp_dump_tree (void* dump_info, tree t)
*** 388,397 ****
        break;
  
      case AGGR_INIT_EXPR:
!       dump_int (di, "ctor", AGGR_INIT_VIA_CTOR_P (t));
!       dump_child ("fn", TREE_OPERAND (t, 0));
!       dump_child ("args", TREE_OPERAND (t, 1));
!       dump_child ("decl", TREE_OPERAND (t, 2));
        break;
  
      case HANDLER:
--- 388,408 ----
        break;
  
      case AGGR_INIT_EXPR:
!       {
! 	int i = 0;
! 	tree arg;
! 	aggr_init_expr_arg_iterator iter;
! 	dump_int (di, "ctor", AGGR_INIT_VIA_CTOR_P (t));
! 	dump_child ("fn", AGGR_INIT_EXPR_FN (t));
! 	FOR_EACH_AGGR_INIT_EXPR_ARG (arg, iter, t)
! 	  {
! 	    char buffer[32];
! 	    sprintf (buffer, "%u", i);
! 	    dump_child (buffer, arg);
! 	    i++;
! 	  }
! 	dump_child ("decl", AGGR_INIT_EXPR_SLOT (t));
!       }
        break;
  
      case HANDLER:
Index: gcc/cp/cp-gimplify.c
===================================================================
*** gcc/cp/cp-gimplify.c	(revision 121818)
--- gcc/cp/cp-gimplify.c	(working copy)
*************** cp_gimplify_init_expr (tree *expr_p, tre
*** 410,416 ****
    if (TREE_CODE (sub) == AGGR_INIT_EXPR)
      {
        gimplify_expr (&to, pre_p, post_p, is_gimple_lvalue, fb_lvalue);
!       TREE_OPERAND (sub, 2) = to;
        *expr_p = from;
  
        /* The initialization is now a side-effect, so the container can
--- 410,416 ----
    if (TREE_CODE (sub) == AGGR_INIT_EXPR)
      {
        gimplify_expr (&to, pre_p, post_p, is_gimple_lvalue, fb_lvalue);
!       AGGR_INIT_EXPR_SLOT (sub) = to;
        *expr_p = from;
  
        /* The initialization is now a side-effect, so the container can
Index: gcc/cp/cp-tree.h
===================================================================
*** gcc/cp/cp-tree.h	(revision 121818)
--- gcc/cp/cp-tree.h	(working copy)
*************** extern void decl_shadowed_for_var_insert
*** 2331,2336 ****
--- 2331,2415 ----
  #define AGGR_INIT_VIA_CTOR_P(NODE) \
    TREE_LANG_FLAG_0 (AGGR_INIT_EXPR_CHECK (NODE))
  
+ /* AGGR_INIT_EXPR accessors.  These are equivalent to the CALL_EXPR
+    accessors, except for AGGR_INIT_EXPR_SLOT (which takes the place of
+    CALL_EXPR_STATIC_CHAIN).  */
+ 
+ #define AGGR_INIT_EXPR_FN(NODE) TREE_OPERAND (AGGR_INIT_EXPR_CHECK (NODE), 1)
+ #define AGGR_INIT_EXPR_SLOT(NODE) \
+   TREE_OPERAND (AGGR_INIT_EXPR_CHECK (NODE), 2)
+ #define AGGR_INIT_EXPR_ARG(NODE, I) \
+   TREE_OPERAND (AGGR_INIT_EXPR_CHECK (NODE), (I) + 3)
+ #define aggr_init_expr_nargs(NODE) (VL_EXP_OPERAND_LENGTH(NODE) - 3)
+ 
+ /* AGGR_INIT_EXPR_ARGP returns a pointer to the argument vector for NODE.
+    We can't use &AGGR_INIT_EXPR_ARG (NODE, 0) because that will complain if
+    the argument count is zero when checking is enabled.  Instead, do
+    the pointer arithmetic to advance past the 3 fixed operands in a
+    AGGR_INIT_EXPR.  That produces a valid pointer to just past the end of
+    the operand array, even if it's not valid to dereference it.  */
+ #define AGGR_INIT_EXPR_ARGP(NODE) \
+   (&(TREE_OPERAND (AGGR_INIT_EXPR_CHECK (NODE), 0)) + 3)
+ 
+ /* Abstract iterators for AGGR_INIT_EXPRs.  */
+ 
+ /* Structure containing iterator state.  */
+ typedef struct aggr_init_expr_arg_iterator_d GTY (())
+ {
+   tree t;	/* the aggr_init_expr */
+   int n;	/* argument count */
+   int i;	/* next argument index */
+ } aggr_init_expr_arg_iterator;
+ 
+ /* Initialize the abstract argument list iterator object ITER with the
+    arguments from AGGR_INIT_EXPR node EXP.  */
+ static inline void
+ init_aggr_init_expr_arg_iterator (tree exp,
+ 				       aggr_init_expr_arg_iterator *iter)
+ {
+   iter->t = exp;
+   iter->n = aggr_init_expr_nargs (exp);
+   iter->i = 0;
+ }
+ 
+ /* Return the next argument from abstract argument list iterator object ITER,
+    and advance its state.  Return NULL_TREE if there are no more arguments.  */
+ static inline tree
+ next_aggr_init_expr_arg (aggr_init_expr_arg_iterator *iter)
+ {
+   tree result;
+   if (iter->i >= iter->n)
+     return NULL_TREE;
+   result = AGGR_INIT_EXPR_ARG (iter->t, iter->i);
+   iter->i++;
+   return result;
+ }
+ 
+ /* Initialize the abstract argument list iterator object ITER, then advance
+    past and return the first argument.  Useful in for expressions, e.g.
+      for (arg = first_aggr_init_expr_arg (exp, &iter); arg;
+           arg = next_aggr_init_expr_arg (&iter))   */
+ static inline tree
+ first_aggr_init_expr_arg (tree exp, aggr_init_expr_arg_iterator *iter)
+ {
+   init_aggr_init_expr_arg_iterator (exp, iter);
+   return next_aggr_init_expr_arg (iter);
+ }
+ 
+ /* Test whether there are more arguments in abstract argument list iterator
+    ITER, without changing its state.  */
+ static inline bool
+ more_aggr_init_expr_args_p (const aggr_init_expr_arg_iterator *iter)
+ {
+   return (iter->i < iter->n);
+ }
+ 
+ /* Iterate through each argument ARG of AGGR_INIT_EXPR CALL, using variable
+    ITER (of type aggr_init_expr_arg_iterator) to hold the iteration state.  */
+ #define FOR_EACH_AGGR_INIT_EXPR_ARG(arg, iter, call)			\
+   for ((arg) = first_aggr_init_expr_arg ((call), &(iter)); (arg);	\
+        (arg) = next_aggr_init_expr_arg (&(iter)))
+ 
  /* The TYPE_MAIN_DECL for a class template type is a TYPE_DECL, not a
     TEMPLATE_DECL.  This macro determines whether or not a given class
     type is really a template type, as opposed to an instantiation or
*************** extern void lang_check_failed			(const c
*** 4375,4380 ****
--- 4454,4460 ----
  						 const char *) ATTRIBUTE_NORETURN;
  extern tree stabilize_expr			(tree, tree *);
  extern void stabilize_call			(tree, tree *);
+ extern void stabilize_aggr_init			(tree, tree *);
  extern bool stabilize_init			(tree, tree *);
  extern tree add_stmt_to_compound		(tree, tree);
  extern tree cxx_maybe_build_cleanup		(tree);
*************** extern cp_lvalue_kind real_lvalue_p		(tr
*** 4389,4395 ****
--- 4469,4477 ----
  extern bool builtin_valid_in_constant_expr_p    (tree);
  extern tree build_min				(enum tree_code, tree, ...);
  extern tree build_min_nt			(enum tree_code, ...);
+ extern tree build_min_nt_call_list		(tree, tree);
  extern tree build_min_non_dep			(enum tree_code, tree, ...);
+ extern tree build_min_non_dep_call_list		(tree, tree, tree);
  extern tree build_cplus_new			(tree, tree);
  extern tree get_target_expr			(tree);
  extern tree build_cplus_array_type		(tree, tree);
Index: gcc/cp/tree.c
===================================================================
*** gcc/cp/tree.c	(revision 121818)
--- gcc/cp/tree.c	(working copy)
*************** build_local_temp (tree type)
*** 261,268 ****
    return slot;
  }
  
! /* INIT is a CALL_EXPR which needs info about its target.
!    TYPE is the type that this initialization should appear to have.
  
     Build an encapsulation of the initialization to perform
     and return it so that it can be processed by language-independent
--- 261,315 ----
    return slot;
  }
  
! /* Set various status flags when building an AGGR_INIT_EXPR object T.  */
! 
! static void
! process_aggr_init_operands (tree t)
! {
!   bool side_effects;
! 
!   side_effects = TREE_SIDE_EFFECTS (t);
!   if (!side_effects)
!     {
!       int i, n;
!       n = TREE_OPERAND_LENGTH (t);
!       for (i = 1; i < n; i++)
! 	{
! 	  tree op = TREE_OPERAND (t, i);
! 	  if (op && TREE_SIDE_EFFECTS (op))
! 	    {
! 	      side_effects = 1;
! 	      break;
! 	    }
! 	}
!     }
!   TREE_SIDE_EFFECTS (t) = side_effects;
! }
! 
! /* Build an AGGR_INIT_EXPR of class tcc_vl_exp with the indicated RETURN_TYPE,
!    FN, and SLOT.  NARGS is the number of call arguments which are specified
!    as a tree array ARGS.  */
! 
! static tree
! build_aggr_init_array (tree return_type, tree fn, tree slot, int nargs,
! 		       tree *args)
! {
!   tree t;
!   int i;
! 
!   t = build_vl_exp (AGGR_INIT_EXPR, nargs + 3);
!   TREE_TYPE (t) = return_type;
!   AGGR_INIT_EXPR_FN (t) = fn;
!   AGGR_INIT_EXPR_SLOT (t) = slot;
!   for (i = 0; i < nargs; i++)
!     AGGR_INIT_EXPR_ARG (t, i) = args[i];
!   process_aggr_init_operands (t);
!   return t;
! }
! 
! /* INIT is a CALL_EXPR or AGGR_INIT_EXPR which needs info about its
!    target.  TYPE is the type that this initialization should appear to
!    have.
  
     Build an encapsulation of the initialization to perform
     and return it so that it can be processed by language-independent
*************** build_cplus_new (tree type, tree init)
*** 280,289 ****
       abstract class.  */
    abstract_virtuals_error (NULL_TREE, type);
  
!   if (TREE_CODE (init) != CALL_EXPR && TREE_CODE (init) != AGGR_INIT_EXPR)
      return convert (type, init);
  
-   fn = TREE_OPERAND (init, 0);
    is_ctor = (TREE_CODE (fn) == ADDR_EXPR
  	     && TREE_CODE (TREE_OPERAND (fn, 0)) == FUNCTION_DECL
  	     && DECL_CONSTRUCTOR_P (TREE_OPERAND (fn, 0)));
--- 327,339 ----
       abstract class.  */
    abstract_virtuals_error (NULL_TREE, type);
  
!   if (TREE_CODE (init) == CALL_EXPR)
!     fn = CALL_EXPR_FN (init);
!   else if (TREE_CODE (init) == AGGR_INIT_EXPR)
!     fn = AGGR_INIT_EXPR_FN (init);
!   else
      return convert (type, init);
  
    is_ctor = (TREE_CODE (fn) == ADDR_EXPR
  	     && TREE_CODE (TREE_OPERAND (fn, 0)) == FUNCTION_DECL
  	     && DECL_CONSTRUCTOR_P (TREE_OPERAND (fn, 0)));
*************** build_cplus_new (tree type, tree init)
*** 303,310 ****
       type, don't mess with AGGR_INIT_EXPR.  */
    if (is_ctor || TREE_ADDRESSABLE (type))
      {
!       rval = build3 (AGGR_INIT_EXPR, void_type_node, fn,
! 		     TREE_OPERAND (init, 1), slot);
        TREE_SIDE_EFFECTS (rval) = 1;
        AGGR_INIT_VIA_CTOR_P (rval) = is_ctor;
      }
--- 353,366 ----
       type, don't mess with AGGR_INIT_EXPR.  */
    if (is_ctor || TREE_ADDRESSABLE (type))
      {
!       if (TREE_CODE(init) == CALL_EXPR)
! 	rval = build_aggr_init_array (void_type_node, fn, slot,
! 				      call_expr_nargs (init),
! 				      CALL_EXPR_ARGP (init));
!       else
! 	rval = build_aggr_init_array (void_type_node, fn, slot,
! 				      aggr_init_expr_nargs (init),
! 				      AGGR_INIT_EXPR_ARGP (init));
        TREE_SIDE_EFFECTS (rval) = 1;
        AGGR_INIT_VIA_CTOR_P (rval) = is_ctor;
      }
*************** build_min_nt (enum tree_code code, ...)
*** 1420,1425 ****
--- 1476,1483 ----
    int i;
    va_list p;
  
+   gcc_assert (TREE_CODE_CLASS (code) != tcc_vl_exp);
+ 
    va_start (p, code);
  
    t = make_node (code);
*************** build_min_nt (enum tree_code code, ...)
*** 1435,1440 ****
--- 1493,1507 ----
    return t;
  }
  
+ /* Similar to `build_nt_call_list', but for template definitions of
+    dependent expressions.  */
+ tree
+ build_min_nt_call_list (tree fn, tree arglist)
+ {
+   return build_nt_call_list (fn, arglist);
+ }
+ 
+ 
  /* Similar to `build', but for template definitions.  */
  
  tree
*************** build_min (enum tree_code code, tree tt,
*** 1445,1450 ****
--- 1512,1519 ----
    int i;
    va_list p;
  
+   gcc_assert (TREE_CODE_CLASS (code) != tcc_vl_exp);
+ 
    va_start (p, tt);
  
    t = make_node (code);
*************** build_min_non_dep (enum tree_code code, 
*** 1475,1480 ****
--- 1544,1551 ----
    int i;
    va_list p;
  
+   gcc_assert (TREE_CODE_CLASS (code) != tcc_vl_exp);
+ 
    va_start (p, non_dep);
  
    t = make_node (code);
*************** build_min_non_dep (enum tree_code code, 
*** 1497,1502 ****
--- 1568,1586 ----
    return t;
  }
  
+ /* Similar to `build_call_list', but for template definitions of non-dependent
+    expressions. NON_DEP is the non-dependent expression that has been
+    built.  */
+ 
+ tree
+ build_min_non_dep_call_list (tree non_dep, tree fn, tree arglist)
+ {
+   tree t = build_nt_call_list (fn, arglist);
+   TREE_TYPE (t) = TREE_TYPE (non_dep);
+   TREE_SIDE_EFFECTS (t) = TREE_SIDE_EFFECTS (non_dep);
+   return t;
+ }
+ 
  tree
  get_type_decl (tree t)
  {
*************** cp_tree_equal (tree t1, tree t2)
*** 1615,1623 ****
        return cp_tree_equal (TREE_OPERAND (t1, 0), TREE_OPERAND (t2, 0));
  
      case CALL_EXPR:
!       if (!cp_tree_equal (TREE_OPERAND (t1, 0), TREE_OPERAND (t2, 0)))
! 	return false;
!       return cp_tree_equal (TREE_OPERAND (t1, 1), TREE_OPERAND (t2, 1));
  
      case TARGET_EXPR:
        {
--- 1699,1718 ----
        return cp_tree_equal (TREE_OPERAND (t1, 0), TREE_OPERAND (t2, 0));
  
      case CALL_EXPR:
!       {
! 	tree arg1, arg2;
! 	call_expr_arg_iterator iter1, iter2;
! 	if (!cp_tree_equal (CALL_EXPR_FN (t1), CALL_EXPR_FN (t2)))
! 	  return false;
! 	for (arg1 = first_call_expr_arg (t1, &iter1),
! 	       arg2 = first_call_expr_arg (t2, &iter2);
! 	     arg1 && arg2;
! 	     arg1 = next_call_expr_arg (&iter1),
! 	       arg2 = next_call_expr_arg (&iter2))
! 	  if (!cp_tree_equal (arg1, arg2))
! 	    return false;
! 	return (arg1 || arg2);
!       }
  
      case TARGET_EXPR:
        {
*************** cp_tree_equal (tree t1, tree t2)
*** 1747,1758 ****
      case tcc_binary:
      case tcc_comparison:
      case tcc_expression:
      case tcc_reference:
      case tcc_statement:
        {
! 	int i;
  
! 	for (i = 0; i < TREE_CODE_LENGTH (code1); ++i)
  	  if (!cp_tree_equal (TREE_OPERAND (t1, i), TREE_OPERAND (t2, i)))
  	    return false;
  
--- 1842,1859 ----
      case tcc_binary:
      case tcc_comparison:
      case tcc_expression:
+     case tcc_vl_exp:
      case tcc_reference:
      case tcc_statement:
        {
! 	int i, n;
! 
! 	n = TREE_OPERAND_LENGTH (t1);
! 	if (TREE_CODE_CLASS (code1) == tcc_vl_exp
! 	    && n != TREE_OPERAND_LENGTH (t2))
! 	  return false;
  
! 	for (i = 0; i < n; ++i)
  	  if (!cp_tree_equal (TREE_OPERAND (t1, i), TREE_OPERAND (t2, i)))
  	    return false;
  
*************** void
*** 2442,2462 ****
  stabilize_call (tree call, tree *initp)
  {
    tree inits = NULL_TREE;
!   tree t;
  
    if (call == error_mark_node)
      return;
  
!   gcc_assert (TREE_CODE (call) == CALL_EXPR
! 	      || TREE_CODE (call) == AGGR_INIT_EXPR);
  
!   for (t = TREE_OPERAND (call, 1); t; t = TREE_CHAIN (t))
!     if (TREE_SIDE_EFFECTS (TREE_VALUE (t)))
!       {
! 	tree init;
! 	TREE_VALUE (t) = stabilize_expr (TREE_VALUE (t), &init);
! 	inits = add_stmt_to_compound (inits, init);
!       }
  
    *initp = inits;
  }
--- 2543,2591 ----
  stabilize_call (tree call, tree *initp)
  {
    tree inits = NULL_TREE;
!   int i;
!   int nargs = call_expr_nargs (call);
  
    if (call == error_mark_node)
      return;
  
!   gcc_assert (TREE_CODE (call) == CALL_EXPR);
  
!   for (i = 0; i < nargs; i++)
!     {
!       tree init;
!       CALL_EXPR_ARG (call, i) =
! 	stabilize_expr (CALL_EXPR_ARG (call, i), &init);
!       inits = add_stmt_to_compound (inits, init);
!     }
! 
!   *initp = inits;
! }
! 
! /* Like stabilize_expr, but for an AGGR_INIT_EXPR whose arguments we want
!    to pre-evaluate.  CALL is modified in place to use the pre-evaluated
!    arguments, while, upon return, *INITP contains an expression to
!    compute the arguments.  */
! 
! void
! stabilize_aggr_init (tree call, tree *initp)
! {
!   tree inits = NULL_TREE;
!   int i;
!   int nargs = aggr_init_expr_nargs (call);
! 
!   if (call == error_mark_node)
!     return;
! 
!   gcc_assert (TREE_CODE (call) == AGGR_INIT_EXPR);
! 
!   for (i = 0; i < nargs; i++)
!     {
!       tree init;
!       AGGR_INIT_EXPR_ARG (call, i) =
! 	stabilize_expr (AGGR_INIT_EXPR_ARG (call, i), &init);
!       inits = add_stmt_to_compound (inits, init);
!     }
  
    *initp = inits;
  }
*************** stabilize_init (tree init, tree *initp)
*** 2503,2515 ****
    if (TREE_CODE (t) == COND_EXPR)
      return false;
  
!   if (TREE_CODE (t) == CALL_EXPR
!       || TREE_CODE (t) == AGGR_INIT_EXPR)
      {
        stabilize_call (t, initp);
        return true;
      }
  
    /* The initialization is being performed via a bitwise copy -- and
       the item copied may have side effects.  */
    return TREE_SIDE_EFFECTS (init);
--- 2632,2649 ----
    if (TREE_CODE (t) == COND_EXPR)
      return false;
  
!   if (TREE_CODE (t) == CALL_EXPR)
      {
        stabilize_call (t, initp);
        return true;
      }
  
+   if (TREE_CODE (t) == AGGR_INIT_EXPR)
+     {
+       stabilize_aggr_init (t, initp);
+       return true;
+     }
+ 
    /* The initialization is being performed via a bitwise copy -- and
       the item copied may have side effects.  */
    return TREE_SIDE_EFFECTS (init);
Index: gcc/cp/cxx-pretty-print.c
===================================================================
*** gcc/cp/cxx-pretty-print.c	(revision 121818)
--- gcc/cp/cxx-pretty-print.c	(working copy)
*************** pp_cxx_postfix_expression (cxx_pretty_pr
*** 412,420 ****
      case AGGR_INIT_EXPR:
      case CALL_EXPR:
        {
! 	tree fun = TREE_OPERAND (t, 0);
! 	tree args = TREE_OPERAND (t, 1);
  	tree saved_scope = pp->enclosing_scope;
  
  	if (TREE_CODE (fun) == ADDR_EXPR)
  	  fun = TREE_OPERAND (fun, 0);
--- 412,422 ----
      case AGGR_INIT_EXPR:
      case CALL_EXPR:
        {
! 	tree fun = (code == AGGR_INIT_EXPR ? AGGR_INIT_EXPR_FN (t)
! 					   : CALL_EXPR_FN (t));
  	tree saved_scope = pp->enclosing_scope;
+ 	bool skipfirst = false;
+ 	tree arg;
  
  	if (TREE_CODE (fun) == ADDR_EXPR)
  	  fun = TREE_OPERAND (fun, 0);
*************** pp_cxx_postfix_expression (cxx_pretty_pr
*** 427,435 ****
  	  ;
  	else if (DECL_NONSTATIC_MEMBER_FUNCTION_P (fun))
  	  {
! 	    tree object = code == AGGR_INIT_EXPR && AGGR_INIT_VIA_CTOR_P (t)
! 	      ? TREE_OPERAND (t, 2)
! 	      : TREE_VALUE (args);
  
  	    while (TREE_CODE (object) == NOP_EXPR)
  	      object = TREE_OPERAND (object, 0);
--- 429,439 ----
  	  ;
  	else if (DECL_NONSTATIC_MEMBER_FUNCTION_P (fun))
  	  {
! 	    tree object = (code == AGGR_INIT_EXPR
! 			   ? (AGGR_INIT_VIA_CTOR_P (t)
! 			      ? AGGR_INIT_EXPR_SLOT (t)
! 			      : AGGR_INIT_EXPR_ARG (t, 0))
! 			   : CALL_EXPR_ARG (t, 0));
  
  	    while (TREE_CODE (object) == NOP_EXPR)
  	      object = TREE_OPERAND (object, 0);
*************** pp_cxx_postfix_expression (cxx_pretty_pr
*** 447,464 ****
  		pp_cxx_postfix_expression (pp, object);
  		pp_cxx_arrow (pp);
  	      }
! 	    args = TREE_CHAIN (args);
  	    pp->enclosing_scope = strip_pointer_operator (TREE_TYPE (object));
  	  }
  
  	pp_cxx_postfix_expression (pp, fun);
  	pp->enclosing_scope = saved_scope;
! 	pp_cxx_call_argument_list (pp, args);
        }
        if (code == AGGR_INIT_EXPR && AGGR_INIT_VIA_CTOR_P (t))
  	{
  	  pp_cxx_separate_with (pp, ',');
! 	  pp_cxx_postfix_expression (pp, TREE_OPERAND (t, 2));
  	}
        break;
  
--- 451,499 ----
  		pp_cxx_postfix_expression (pp, object);
  		pp_cxx_arrow (pp);
  	      }
! 	    skipfirst = true;
  	    pp->enclosing_scope = strip_pointer_operator (TREE_TYPE (object));
  	  }
  
  	pp_cxx_postfix_expression (pp, fun);
  	pp->enclosing_scope = saved_scope;
! 	pp_cxx_left_paren (pp);
! 	if (code == AGGR_INIT_EXPR)
! 	  {
! 	    aggr_init_expr_arg_iterator iter;
! 	    FOR_EACH_AGGR_INIT_EXPR_ARG (arg, iter, t)
! 	      {
! 		if (skipfirst)
! 		  skipfirst = false;
! 		else
! 		  {
! 		    pp_cxx_expression (pp, arg);
! 		    if (more_aggr_init_expr_args_p (&iter))
! 		      pp_cxx_separate_with (pp, ',');
! 		  }
! 	      }
! 	  }
! 	else
! 	  {
! 	    call_expr_arg_iterator iter;
! 	    FOR_EACH_CALL_EXPR_ARG (arg, iter, t)
! 	      {
! 		if (skipfirst)
! 		  skipfirst = false;
! 		else
! 		  {
! 		    pp_cxx_expression (pp, arg);
! 		    if (more_call_expr_args_p (&iter))
! 		      pp_cxx_separate_with (pp, ',');
! 		  }
! 	      }
! 	  }
! 	pp_cxx_right_paren (pp);
        }
        if (code == AGGR_INIT_EXPR && AGGR_INIT_VIA_CTOR_P (t))
  	{
  	  pp_cxx_separate_with (pp, ',');
! 	  pp_cxx_postfix_expression (pp, AGGR_INIT_EXPR_SLOT (t));
  	}
        break;
  
Index: gcc/cp/pt.c
===================================================================
*** gcc/cp/pt.c	(revision 121818)
--- gcc/cp/pt.c	(working copy)
*************** tsubst_copy (tree t, tree args, tsubst_f
*** 8347,8358 ****
  	 NULL_TREE, NULL_TREE);
  
      case CALL_EXPR:
!       return build_nt (code,
! 		       tsubst_copy (TREE_OPERAND (t, 0), args,
! 				    complain, in_decl),
! 		       tsubst_copy (TREE_OPERAND (t, 1), args, complain,
! 				    in_decl),
! 		       NULL_TREE);
  
      case COND_EXPR:
      case MODOP_EXPR:
--- 8347,8361 ----
  	 NULL_TREE, NULL_TREE);
  
      case CALL_EXPR:
!       {
! 	int n = VL_EXP_OPERAND_LENGTH (t);
! 	tree result = build_vl_exp (CALL_EXPR, n);
! 	int i;
! 	for (i = 0; i < n; i++)
! 	  TREE_OPERAND (t, i) = tsubst_copy (TREE_OPERAND (t, i), args,
! 					     complain, in_decl);
! 	return result;
!       }
  
      case COND_EXPR:
      case MODOP_EXPR:
*************** tsubst_copy_and_build (tree t,
*** 9268,9274 ****
  	bool qualified_p;
  	bool koenig_p;
  
! 	function = TREE_OPERAND (t, 0);
  	/* When we parsed the expression,  we determined whether or
  	   not Koenig lookup should be performed.  */
  	koenig_p = KOENIG_LOOKUP_P (t);
--- 9271,9277 ----
  	bool qualified_p;
  	bool koenig_p;
  
! 	function = CALL_EXPR_FN (t);
  	/* When we parsed the expression,  we determined whether or
  	   not Koenig lookup should be performed.  */
  	koenig_p = KOENIG_LOOKUP_P (t);
*************** tsubst_copy_and_build (tree t,
*** 9301,9307 ****
  	      qualified_p = true;
  	  }
  
! 	call_args = RECUR (TREE_OPERAND (t, 1));
  
  	/* We do not perform argument-dependent lookup if normal
  	   lookup finds a non-function, in accordance with the
--- 9304,9311 ----
  	      qualified_p = true;
  	  }
  
! 	/* FIXME:  Rewrite this so as not to construct an arglist.  */
! 	call_args = RECUR (CALL_EXPR_ARGS (t));
  
  	/* We do not perform argument-dependent lookup if normal
  	   lookup finds a non-function, in accordance with the
*************** value_dependent_expression_p (tree expre
*** 13057,13065 ****
  		      (TREE_OPERAND (expression, 1))));
  
  	case tcc_expression:
  	  {
  	    int i;
! 	    for (i = 0; i < TREE_CODE_LENGTH (TREE_CODE (expression)); ++i)
  	      /* In some cases, some of the operands may be missing.
  		 (For example, in the case of PREDECREMENT_EXPR, the
  		 amount to increment by may be missing.)  That doesn't
--- 13061,13070 ----
  		      (TREE_OPERAND (expression, 1))));
  
  	case tcc_expression:
+ 	case tcc_vl_exp:
  	  {
  	    int i;
! 	    for (i = 0; i < TREE_OPERAND_LENGTH (expression); ++i)
  	      /* In some cases, some of the operands may be missing.
  		 (For example, in the case of PREDECREMENT_EXPR, the
  		 amount to increment by may be missing.)  That doesn't
Index: gcc/cp/semantics.c
===================================================================
*** gcc/cp/semantics.c	(revision 121818)
--- gcc/cp/semantics.c	(working copy)
*************** finish_call_expr (tree fn, tree args, bo
*** 1789,1795 ****
        if (type_dependent_expression_p (fn)
  	  || any_type_dependent_arguments_p (args))
  	{
! 	  result = build_nt (CALL_EXPR, fn, args, NULL_TREE);
  	  KOENIG_LOOKUP_P (result) = koenig_p;
  	  return result;
  	}
--- 1789,1795 ----
        if (type_dependent_expression_p (fn)
  	  || any_type_dependent_arguments_p (args))
  	{
! 	  result = build_nt_call_list (fn, args);
  	  KOENIG_LOOKUP_P (result) = koenig_p;
  	  return result;
  	}
*************** finish_call_expr (tree fn, tree args, bo
*** 1846,1852 ****
        if (processing_template_decl)
  	{
  	  if (type_dependent_expression_p (object))
! 	    return build_nt (CALL_EXPR, orig_fn, orig_args, NULL_TREE);
  	  object = build_non_dependent_expr (object);
  	}
  
--- 1846,1852 ----
        if (processing_template_decl)
  	{
  	  if (type_dependent_expression_p (object))
! 	    return build_nt_call_list (orig_fn, orig_args);
  	  object = build_non_dependent_expr (object);
  	}
  
*************** finish_call_expr (tree fn, tree args, bo
*** 1890,1897 ****
  
    if (processing_template_decl)
      {
!       result = build3 (CALL_EXPR, TREE_TYPE (result), orig_fn,
! 		       orig_args, NULL_TREE);
        KOENIG_LOOKUP_P (result) = koenig_p;
      }
    return result;
--- 1890,1896 ----
  
    if (processing_template_decl)
      {
!       result = build_call_list (TREE_TYPE (result), orig_fn, orig_args);
        KOENIG_LOOKUP_P (result) = koenig_p;
      }
    return result;
*************** simplify_aggr_init_expr (tree *tp)
*** 2975,2983 ****
    tree aggr_init_expr = *tp;
  
    /* Form an appropriate CALL_EXPR.  */
!   tree fn = TREE_OPERAND (aggr_init_expr, 0);
!   tree args = TREE_OPERAND (aggr_init_expr, 1);
!   tree slot = TREE_OPERAND (aggr_init_expr, 2);
    tree type = TREE_TYPE (slot);
  
    tree call_expr;
--- 2974,2981 ----
    tree aggr_init_expr = *tp;
  
    /* Form an appropriate CALL_EXPR.  */
!   tree fn = AGGR_INIT_EXPR_FN (aggr_init_expr);
!   tree slot = AGGR_INIT_EXPR_SLOT (aggr_init_expr);
    tree type = TREE_TYPE (slot);
  
    tree call_expr;
*************** simplify_aggr_init_expr (tree *tp)
*** 2995,3017 ****
        style = arg;
      }
  
    if (style == ctor)
      {
        /* Replace the first argument to the ctor with the address of the
  	 slot.  */
-       tree addr;
- 
-       args = TREE_CHAIN (args);
        cxx_mark_addressable (slot);
!       addr = build1 (ADDR_EXPR, build_pointer_type (type), slot);
!       args = tree_cons (NULL_TREE, addr, args);
      }
! 
!   call_expr = build3 (CALL_EXPR,
! 		      TREE_TYPE (TREE_TYPE (TREE_TYPE (fn))),
! 		      fn, args, NULL_TREE);
! 
!   if (style == arg)
      {
        /* Just mark it addressable here, and leave the rest to
  	 expand_call{,_inline}.  */
--- 2993,3012 ----
        style = arg;
      }
  
+   call_expr = build_call_array (TREE_TYPE (TREE_TYPE (TREE_TYPE (fn))),
+ 				fn,
+ 				aggr_init_expr_nargs (aggr_init_expr),
+ 				AGGR_INIT_EXPR_ARGP (aggr_init_expr));
+ 
    if (style == ctor)
      {
        /* Replace the first argument to the ctor with the address of the
  	 slot.  */
        cxx_mark_addressable (slot);
!       CALL_EXPR_ARG (call_expr, 0) =
! 	build1 (ADDR_EXPR, build_pointer_type (type), slot);
      }
!   else if (style == arg)
      {
        /* Just mark it addressable here, and leave the rest to
  	 expand_call{,_inline}.  */
Index: gcc/cp/decl2.c
===================================================================
*** gcc/cp/decl2.c	(revision 121818)
--- gcc/cp/decl2.c	(working copy)
*************** build_offset_ref_call_from_tree (tree fn
*** 3401,3407 ****
  		  || TREE_CODE (fn) == MEMBER_REF);
        if (type_dependent_expression_p (fn)
  	  || any_type_dependent_arguments_p (args))
! 	return build_min_nt (CALL_EXPR, fn, args, NULL_TREE);
  
        /* Transform the arguments and add the implicit "this"
  	 parameter.  That must be done before the FN is transformed
--- 3401,3407 ----
  		  || TREE_CODE (fn) == MEMBER_REF);
        if (type_dependent_expression_p (fn)
  	  || any_type_dependent_arguments_p (args))
! 	return build_min_nt_call_list (fn, args);
  
        /* Transform the arguments and add the implicit "this"
  	 parameter.  That must be done before the FN is transformed
*************** build_offset_ref_call_from_tree (tree fn
*** 3431,3437 ****
  
    expr = build_function_call (fn, args);
    if (processing_template_decl && expr != error_mark_node)
!     return build_min_non_dep (CALL_EXPR, expr, orig_fn, orig_args, NULL_TREE);
    return expr;
  }
  
--- 3431,3437 ----
  
    expr = build_function_call (fn, args);
    if (processing_template_decl && expr != error_mark_node)
!     return build_min_non_dep_call_list (expr, orig_fn, orig_args);
    return expr;
  }
  
Index: gcc/cp/parser.c
===================================================================
*** gcc/cp/parser.c	(revision 121818)
--- gcc/cp/parser.c	(working copy)
*************** cp_parser_postfix_expression (cp_parser 
*** 4443,4450 ****
  			|| any_type_dependent_arguments_p (args)))
  		  {
  		    postfix_expression
! 		      = build_min_nt (CALL_EXPR, postfix_expression,
! 				      args, NULL_TREE);
  		    break;
  		  }
  
--- 4443,4449 ----
  			|| any_type_dependent_arguments_p (args)))
  		  {
  		    postfix_expression
! 		      = build_min_nt_call_list (postfix_expression, args);
  		    break;
  		  }
  

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