public inbox for gcc@gcc.gnu.org
 help / color / mirror / Atom feed
From: Jason Merrill <jason@redhat.com>
To: Richard Henderson <rth@redhat.com>
Cc: Mark Mitchell <mark@codesourcery.com>,
	gcc@gcc.gnu.org, gcc-patches@gcc.gnu.org
Subject: PATCH Re: Simplifying TARGET_EXPR
Date: Fri, 26 Jul 2002 14:51:00 -0000	[thread overview]
Message-ID: <wvladof8r5b.fsf_-_@prospero.cambridge.redhat.com> (raw)
In-Reply-To: <20020720135854.C16252@redhat.com> (Richard Henderson's message of "Sat, 20 Jul 2002 13:58:54 -0700")

[-- Attachment #1: Type: text/plain, Size: 1558 bytes --]

>>>>> "Richard" == Richard Henderson <rth@redhat.com> writes:

> Given that the front end has to know about the semantics of copying
> objects and how that affects parameter passing anyway, perhaps the
> front end should modify the type of the parameter at the same time.
> Perhaps a REFERENCE_TYPE with DECL_ARTIFICIAL set?  Then an ADDR_EXPR
> would match up nicely.

It occurred to me that we already have DECL_ARG_TYPE for handling this sort
of thing.  This patch sets DECL_ARG_TYPE to a REFERENCE_TYPE if we want to
pass by invisible reference for frontend-specific reasons.  These semantics
are handled by three new functions in cp/call.c; the rest of the patch is
telling other bits of code to use them.

Tested i686-pc-linux-gnu.  I'll check this in soon if nobody complains.

2002-07-25  Jason Merrill  <jason@redhat.com>

	* function.c (assign_parms): Handle frontend-directed pass by
	invisible reference.
cp/
	* call.c (build_over_call): Likewise.
	(cp_convert_parm_for_inlining): New fn.
        (convert_for_arg_passing): New fn.
        (convert_default_arg, build_over_call): Use it.
	(type_passed_as): New fn.
	* pt.c (tsubst_decl): Use it.
	* decl2.c (cp_build_parm_decl): New fn.
	(build_artificial_parm): Use it.
	(start_static_storage_duration_function): Likewise.
	* decl.c (start_cleanup_fn, grokdeclarater): Likewise.
	(grokparms): Don't mess with DECL_ARG_TYPE.
	* typeck.c (convert_arguments): Use convert_for_arg_passing.
	* cp-lang.c (LANG_HOOKS_TREE_INLINING_CONVERT_PARM_FOR_INLINING):
	Define.
	* cp-tree.h: Declare new fns.
	

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: Type: text/x-patch, Size: 12744 bytes --]

*** ./cp/pt.c.~1~	Wed Jul 24 12:40:22 2002
--- ./cp/pt.c	Wed Jul 24 12:35:50 2002
*************** tsubst_decl (t, args, type, complain)
*** 6023,6032 ****
  				     complain, in_decl);
  
  	DECL_CONTEXT (r) = NULL_TREE;
! 	if (!DECL_TEMPLATE_PARM_P (r) && PROMOTE_PROTOTYPES
! 	    && INTEGRAL_TYPE_P (type)
! 	    && TYPE_PRECISION (type) < TYPE_PRECISION (integer_type_node))
! 	  DECL_ARG_TYPE (r) = integer_type_node;
  	if (TREE_CHAIN (t))
  	  TREE_CHAIN (r) = tsubst (TREE_CHAIN (t), args,
  				   complain, TREE_CHAIN (t));
--- 6023,6031 ----
  				     complain, in_decl);
  
  	DECL_CONTEXT (r) = NULL_TREE;
! 
! 	if (!DECL_TEMPLATE_PARM_P (r))
! 	  DECL_ARG_TYPE (r) = type_passed_as (type);
  	if (TREE_CHAIN (t))
  	  TREE_CHAIN (r) = tsubst (TREE_CHAIN (t), args,
  				   complain, TREE_CHAIN (t));
*** ./cp/call.c.~1~	Wed Jul 24 12:40:22 2002
--- ./cp/call.c	Wed Jul 24 17:10:12 2002
*************** convert_default_arg (type, arg, fn, parm
*** 4128,4142 ****
  
        arg = convert_for_initialization (0, type, arg, LOOKUP_NORMAL,
  					"default argument", fn, parmnum);
!       if (PROMOTE_PROTOTYPES
! 	  && INTEGRAL_TYPE_P (type)
! 	  && (TYPE_PRECISION (type) < TYPE_PRECISION (integer_type_node)))
! 	arg = default_conversion (arg);
      }
  
    return arg;
  }
  
  /* Subroutine of the various build_*_call functions.  Overload resolution
     has chosen a winning candidate CAND; build up a CALL_EXPR accordingly.
     ARGS is a TREE_LIST of the unconverted arguments to the call.  FLAGS is a
--- 4128,4191 ----
  
        arg = convert_for_initialization (0, type, arg, LOOKUP_NORMAL,
  					"default argument", fn, parmnum);
!       arg = convert_for_arg_passing (type, arg);
      }
  
    return arg;
  }
  
+ /* Returns the type which will really be used for passing an argument of
+    type TYPE.  */
+ 
+ tree
+ type_passed_as (type)
+      tree type;
+ {
+   /* Pass classes with copy ctors by invisible reference.  */
+   if (TREE_ADDRESSABLE (type))
+     type = build_reference_type (type);
+   else if (PROMOTE_PROTOTYPES
+ 	   && INTEGRAL_TYPE_P (type)
+ 	   && TYPE_PRECISION (type) < TYPE_PRECISION (integer_type_node))
+     type = integer_type_node;
+ 
+   return type;
+ }
+ 
+ /* Actually perform the appropriate conversion.  */
+ 
+ tree
+ convert_for_arg_passing (type, val)
+      tree type, val;
+ {
+   /* Pass classes with copy ctors by invisible reference.  */
+   if (TREE_ADDRESSABLE (type))
+     val = build1 (ADDR_EXPR, build_reference_type (type), val);
+   else if (PROMOTE_PROTOTYPES
+ 	   && INTEGRAL_TYPE_P (type)
+ 	   && TYPE_PRECISION (type) < TYPE_PRECISION (integer_type_node))
+     val = default_conversion (val);
+   return val;
+ }
+ 
+ /* Convert VALUE for assignment into inlined parameter PARM.  */
+ 
+ tree
+ cp_convert_parm_for_inlining (parm, value, fn)
+      tree parm, value;
+      tree fn ATTRIBUTE_UNUSED;
+ {
+   /* When inlining, we don't need to mess with invisible references, so
+      undo the ADDR_EXPR.  */
+   if (TREE_ADDRESSABLE (TREE_TYPE (parm)))
+     {
+       if (TREE_TYPE (value) != build_reference_type (TREE_TYPE (parm)))
+ 	abort ();
+       value = build_indirect_ref (value, NULL);
+     }
+   return value;
+ }
+ 
  /* Subroutine of the various build_*_call functions.  Overload resolution
     has chosen a winning candidate CAND; build up a CALL_EXPR accordingly.
     ARGS is a TREE_LIST of the unconverted arguments to the call.  FLAGS is a
*************** build_over_call (cand, args, flags)
*** 4222,4231 ****
        val = convert_like_with_context
  	(conv, TREE_VALUE (arg), fn, i - is_method);
  
!       if (PROMOTE_PROTOTYPES
! 	  && INTEGRAL_TYPE_P (type)
! 	  && (TYPE_PRECISION (type) < TYPE_PRECISION (integer_type_node)))
! 	val = default_conversion (val);
        converted_args = tree_cons (NULL_TREE, val, converted_args);
      }
  
--- 4271,4277 ----
        val = convert_like_with_context
  	(conv, TREE_VALUE (arg), fn, i - is_method);
  
!       val = convert_for_arg_passing (type, val);
        converted_args = tree_cons (NULL_TREE, val, converted_args);
      }
  
*** ./cp/decl.c.~1~	Wed Jul 24 12:40:22 2002
--- ./cp/decl.c	Wed Jul 24 12:35:46 2002
*************** start_cleanup_fn ()
*** 8518,8526 ****
      {
        tree parmdecl;
  
!       parmdecl = build_decl (PARM_DECL, NULL_TREE, ptr_type_node);
        DECL_CONTEXT (parmdecl) = fndecl;
-       DECL_ARG_TYPE (parmdecl) = ptr_type_node;
        TREE_USED (parmdecl) = 1;
        DECL_ARGUMENTS (fndecl) = parmdecl;
      }
--- 8518,8525 ----
      {
        tree parmdecl;
  
!       parmdecl = cp_build_parm_decl (NULL_TREE, ptr_type_node);
        DECL_CONTEXT (parmdecl) = fndecl;
        TREE_USED (parmdecl) = 1;
        DECL_ARGUMENTS (fndecl) = parmdecl;
      }
*************** grokdeclarator (declarator, declspecs, d
*** 11366,11372 ****
  
        for (args = TYPE_ARG_TYPES (type); args; args = TREE_CHAIN (args))
  	{
! 	  tree decl = build_decl (PARM_DECL, NULL_TREE, TREE_VALUE (args));
  
  	  TREE_CHAIN (decl) = decls;
  	  decls = decl;
--- 11365,11371 ----
  
        for (args = TYPE_ARG_TYPES (type); args; args = TREE_CHAIN (args))
  	{
! 	  tree decl = cp_build_parm_decl (NULL_TREE, TREE_VALUE (args));
  
  	  TREE_CHAIN (decl) = decls;
  	  decls = decl;
*************** friend declaration requires class-key, i
*** 11510,11526 ****
  
      if (decl_context == PARM)
        {
! 	decl = build_decl (PARM_DECL, declarator, type);
  
  	bad_specifiers (decl, "parameter", virtualp, quals != NULL_TREE,
  			inlinep, friendp, raises != NULL_TREE);
- 
- 	/* Compute the type actually passed in the parmlist,
- 	   for the case where there is no prototype.
- 	   (For example, shorts and chars are passed as ints.)
- 	   When there is a prototype, this is overridden later.  */
- 
- 	DECL_ARG_TYPE (decl) = type_promotes_to (type);
        }
      else if (decl_context == FIELD)
        {
--- 11509,11518 ----
  
      if (decl_context == PARM)
        {
! 	decl = cp_build_parm_decl (declarator, type);
  
  	bad_specifiers (decl, "parameter", virtualp, quals != NULL_TREE,
  			inlinep, friendp, raises != NULL_TREE);
        }
      else if (decl_context == FIELD)
        {
*************** grokparms (first_parm)
*** 12206,12216 ****
  			  decl, ptr ? "pointer" : "reference", t);
  	    }
  
- 	  DECL_ARG_TYPE (decl) = TREE_TYPE (decl);
- 	  if (PROMOTE_PROTOTYPES
- 	      && INTEGRAL_TYPE_P (type)
- 	      && TYPE_PRECISION (type) < TYPE_PRECISION (integer_type_node))
- 	    DECL_ARG_TYPE (decl) = integer_type_node;
  	  if (!any_error && init)
  	    init = check_default_argument (decl, init);
  	  else
--- 12198,12203 ----
*** ./cp/cp-lang.c.~1~	Wed Jul 24 12:40:22 2002
--- ./cp/cp-lang.c	Tue Jul 23 17:53:41 2002
*************** static bool cxx_warn_unused_global_decl 
*** 120,125 ****
--- 120,128 ----
  #undef LANG_HOOKS_TREE_INLINING_COPY_RES_DECL_FOR_INLINING
  #define LANG_HOOKS_TREE_INLINING_COPY_RES_DECL_FOR_INLINING \
    cp_copy_res_decl_for_inlining
+ #undef LANG_HOOKS_TREE_INLINING_CONVERT_PARM_FOR_INLINING
+ #define LANG_HOOKS_TREE_INLINING_CONVERT_PARM_FOR_INLINING \
+   cp_convert_parm_for_inlining
  #undef LANG_HOOKS_TREE_INLINING_ANON_AGGR_TYPE_P
  #define LANG_HOOKS_TREE_INLINING_ANON_AGGR_TYPE_P anon_aggr_type_p
  #undef LANG_HOOKS_TREE_INLINING_START_INLINING
*** ./cp/cp-tree.h.~1~	Wed Jul 24 12:40:22 2002
--- ./cp/cp-tree.h	Wed Jul 24 17:09:43 2002
*************** extern tree convert_default_arg         
*** 3683,3688 ****
--- 3683,3691 ----
  extern tree convert_arg_to_ellipsis             PARAMS ((tree));
  extern tree build_x_va_arg                      PARAMS ((tree, tree));
  extern tree cxx_type_promotes_to		PARAMS ((tree));
+ extern tree type_passed_as                      PARAMS ((tree));
+ extern tree convert_for_arg_passing             PARAMS ((tree, tree));
+ extern tree cp_convert_parm_for_inlining        PARAMS ((tree, tree, tree));
  extern int is_properly_derived_from             PARAMS ((tree, tree));
  extern tree initialize_reference                PARAMS ((tree, tree));
  extern tree strip_top_quals                     PARAMS ((tree));
*************** extern void mark_used				PARAMS ((tree))
*** 3962,3967 ****
--- 3965,3971 ----
  extern tree handle_class_head			(enum tag_types, tree, tree, tree, int, int *);
  extern tree lookup_arg_dependent                PARAMS ((tree, tree, tree));
  extern void finish_static_data_member_decl      PARAMS ((tree, tree, tree, int));
+ extern tree cp_build_parm_decl                  PARAMS ((tree, tree));
  extern tree build_artificial_parm               PARAMS ((tree, tree));
  extern tree get_guard                           PARAMS ((tree));
  extern tree get_guard_cond                      PARAMS ((tree));
*** ./cp/decl2.c.~1~	Wed Jul 24 12:40:22 2002
--- ./cp/decl2.c	Wed Jul 24 12:35:47 2002
*************** grok_x_components (specs)
*** 808,813 ****
--- 808,826 ----
    finish_member_declaration (build_decl (FIELD_DECL, NULL_TREE, t)); 
  }
  
+ /* Build a PARM_DECL with NAME and TYPE, and set DECL_ARG_TYPE
+    appropriately.  */
+ 
+ tree
+ cp_build_parm_decl (name, type)
+      tree name;
+      tree type;
+ {
+   tree parm = build_decl (PARM_DECL, name, type);
+   DECL_ARG_TYPE (parm) = type_passed_as (type);
+   return parm;
+ }
+ 
  /* Returns a PARM_DECL for a parameter of the indicated TYPE, with the
     indicated NAME.  */
  
*************** build_artificial_parm (name, type)
*** 816,829 ****
       tree name;
       tree type;
  {
!   tree parm;
! 
!   parm = build_decl (PARM_DECL, name, type);
    DECL_ARTIFICIAL (parm) = 1;
    /* All our artificial parms are implicitly `const'; they cannot be
       assigned to.  */
    TREE_READONLY (parm) = 1;
-   DECL_ARG_TYPE (parm) = type;
    return parm;
  }
  
--- 829,839 ----
       tree name;
       tree type;
  {
!   tree parm = cp_build_parm_decl (name, type);
    DECL_ARTIFICIAL (parm) = 1;
    /* All our artificial parms are implicitly `const'; they cannot be
       assigned to.  */
    TREE_READONLY (parm) = 1;
    return parm;
  }
  
*************** start_static_storage_duration_function (
*** 2866,2881 ****
    VARRAY_PUSH_TREE (ssdf_decls, ssdf_decl);
  
    /* Create the argument list.  */
!   initialize_p_decl = build_decl (PARM_DECL,
! 				  get_identifier (INITIALIZE_P_IDENTIFIER),
! 				  integer_type_node);
    DECL_CONTEXT (initialize_p_decl) = ssdf_decl;
-   DECL_ARG_TYPE (initialize_p_decl) = integer_type_node;
    TREE_USED (initialize_p_decl) = 1;
!   priority_decl = build_decl (PARM_DECL, get_identifier (PRIORITY_IDENTIFIER),
! 			      integer_type_node);
    DECL_CONTEXT (priority_decl) = ssdf_decl;
-   DECL_ARG_TYPE (priority_decl) = integer_type_node;
    TREE_USED (priority_decl) = 1;
  
    TREE_CHAIN (initialize_p_decl) = priority_decl;
--- 2876,2888 ----
    VARRAY_PUSH_TREE (ssdf_decls, ssdf_decl);
  
    /* Create the argument list.  */
!   initialize_p_decl = cp_build_parm_decl
!     (get_identifier (INITIALIZE_P_IDENTIFIER), integer_type_node);
    DECL_CONTEXT (initialize_p_decl) = ssdf_decl;
    TREE_USED (initialize_p_decl) = 1;
!   priority_decl = cp_build_parm_decl
!     (get_identifier (PRIORITY_IDENTIFIER), integer_type_node);
    DECL_CONTEXT (priority_decl) = ssdf_decl;
    TREE_USED (priority_decl) = 1;
  
    TREE_CHAIN (initialize_p_decl) = priority_decl;
*** ./cp/typeck.c.~1~	Wed Jul 24 12:40:22 2002
--- ./cp/typeck.c	Wed Jul 24 17:04:54 2002
*************** convert_arguments (typelist, values, fnd
*** 3145,3155 ****
  	      parmval = convert_for_initialization
  		(NULL_TREE, type, val, flags,
  		 "argument passing", fndecl, i);
! 	      if (PROMOTE_PROTOTYPES
! 		  && INTEGRAL_TYPE_P (type)
! 		  && (TYPE_PRECISION (type)
! 		      < TYPE_PRECISION (integer_type_node)))
! 		parmval = default_conversion (parmval);
  	    }
  
  	  if (parmval == error_mark_node)
--- 3145,3151 ----
  	      parmval = convert_for_initialization
  		(NULL_TREE, type, val, flags,
  		 "argument passing", fndecl, i);
! 	      parmval = convert_for_arg_passing (type, parmval);
  	    }
  
  	  if (parmval == error_mark_node)
*** ./function.c.~1~	Wed Jul 24 12:40:22 2002
--- ./function.c	Wed Jul 24 12:35:18 2002
*************** assign_parms (fndecl)
*** 4425,4430 ****
--- 4425,4439 ----
  	  passed_pointer = 1;
  	  passed_mode = nominal_mode = Pmode;
  	}
+       /* See if the frontend wants to pass this by invisible reference.  */
+       else if (passed_type != nominal_type
+ 	       && POINTER_TYPE_P (passed_type)
+ 	       && TREE_TYPE (passed_type) == nominal_type)
+ 	{
+ 	  nominal_type = passed_type;
+ 	  passed_pointer = 1;
+ 	  passed_mode = nominal_mode = Pmode;
+ 	}
  
        promoted_mode = passed_mode;
  

  reply	other threads:[~2002-07-26 10:04 UTC|newest]

Thread overview: 14+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2002-07-20 18:54 [tree-ssa] " Jason Merrill
2002-07-21  0:41 ` Richard Henderson
2002-07-26 14:51   ` Jason Merrill [this message]
2002-07-21 17:32 ` Mark Mitchell
2002-07-21 18:04   ` Gabriel Dos Reis
2002-07-21 18:14     ` Mark Mitchell
2002-07-21 20:39       ` Gabriel Dos Reis
2002-07-22  8:32         ` Michael Matz
2002-07-22 12:02           ` Gabriel Dos Reis
2002-07-24  3:22           ` Mark Mitchell
2002-07-22 12:33       ` Nathan Sidwell
2002-07-22 12:53         ` Gabriel Dos Reis
2002-07-22 13:10         ` Jason Merrill
2002-07-21 22:35   ` Jason Merrill

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=wvladof8r5b.fsf_-_@prospero.cambridge.redhat.com \
    --to=jason@redhat.com \
    --cc=gcc-patches@gcc.gnu.org \
    --cc=gcc@gcc.gnu.org \
    --cc=mark@codesourcery.com \
    --cc=rth@redhat.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).