don't use build_function_type in the ObjC/C++ frontends
authorNathan Froyd <froydnj@codesourcery.com>
Fri, 6 May 2011 01:37:00 +0000 (01:37 +0000)
committerNathan Froyd <froydnj@gcc.gnu.org>
Fri, 6 May 2011 01:37:00 +0000 (01:37 +0000)
don't use build_function_type in the ObjC/C++ frontends
* objc-runtime-shared-support.h (get_arg_type_list): Delete.
(build_function_type_for_method): Declare.
* objc-runtime-hooks.h (struct _objc_runtime_hooks_r): Change
type of get_arg_type_base_list field.
* objc-act.h (OBJC_VOID_AT_END): Delete.
* objc-act.c (get_arg_type_list): Delete.
(build_function_type_for_method): New function.
(objc_decl_method_attributes): Call build_function_type_for_method.
(really_start_method): Likewise.
* objc-gnu-runtime-abi-01.c
(gnu_runtime_abi_01_get_type_arg_list_base): Change prototype and
adjust function accordingly.  Update header comment.
(build_objc_method_call): Call build_function_type_for_method.
* objc-next-runtime-abi-01.c
(next_runtime_abi_01_get_type_arg_list_base): Change prototype and
adjust function accordingly.  Update header comment.
(build_objc_method_call): Call build_function_type_for_method.
* objc-next-runtime-abi-02.c
(next_runtime_abi_02_get_type_arg_list_base): Change prototype and
adjust function accordingly.  Update header comment.
(objc_copy_to_temp_side_effect_params): Take fntype instead of a
typelist.  Use function_args_iterator for traversing fntype.
(build_v2_build_objc_method_call): Adjust call to it.
Call build_function_type_for_method

From-SVN: r173465

gcc/objc/ChangeLog
gcc/objc/objc-act.c
gcc/objc/objc-act.h
gcc/objc/objc-gnu-runtime-abi-01.c
gcc/objc/objc-next-runtime-abi-01.c
gcc/objc/objc-next-runtime-abi-02.c
gcc/objc/objc-runtime-hooks.h
gcc/objc/objc-runtime-shared-support.h

index 8706175d2779272d03ec09a82a06d8c830b91905..04ef7f74a627fb79b39e7bc5f56237a3dd0e965c 100644 (file)
@@ -1,3 +1,30 @@
+2011-05-05  Nathan Froyd  <froydnj@codesourcery.com>
+
+       * objc-runtime-shared-support.h (get_arg_type_list): Delete.
+       (build_function_type_for_method): Declare.
+       * objc-runtime-hooks.h (struct _objc_runtime_hooks_r): Change
+       type of get_arg_type_base_list field.
+       * objc-act.h (OBJC_VOID_AT_END): Delete.
+       * objc-act.c (get_arg_type_list): Delete.
+       (build_function_type_for_method): New function.
+       (objc_decl_method_attributes): Call build_function_type_for_method.
+       (really_start_method): Likewise.
+       * objc-gnu-runtime-abi-01.c
+       (gnu_runtime_abi_01_get_type_arg_list_base): Change prototype and
+       adjust function accordingly.  Update header comment.
+       (build_objc_method_call): Call build_function_type_for_method.
+       * objc-next-runtime-abi-01.c
+       (next_runtime_abi_01_get_type_arg_list_base): Change prototype and
+       adjust function accordingly.  Update header comment.
+       (build_objc_method_call): Call build_function_type_for_method.
+       * objc-next-runtime-abi-02.c
+       (next_runtime_abi_02_get_type_arg_list_base): Change prototype and
+       adjust function accordingly.  Update header comment.
+       (objc_copy_to_temp_side_effect_params): Take fntype instead of a
+       typelist.  Use function_args_iterator for traversing fntype.
+       (build_v2_build_objc_method_call): Adjust call to it.
+       Call build_function_type_for_method
+
 2011-05-05  Joseph Myers  <joseph@codesourcery.com>
 
        * objc-act.c (objc_start_method_definition): Add parameter expr.
index 46cfc554b61443bbcd27285b4c823af016c0c235..7e69b0dbf59f08d736f5c4abd4f4a092e9f1354e 100644 (file)
@@ -5043,8 +5043,9 @@ objc_decl_method_attributes (tree *node, tree attributes, int flags)
         (by setting TREE_DEPRECATED and TREE_THIS_VOLATILE) so there
         is nothing to do.  */
       tree saved_type = TREE_TYPE (*node);
-      TREE_TYPE (*node) = build_function_type
-       (TREE_VALUE (saved_type), get_arg_type_list (*node, METHOD_REF, 0));
+      TREE_TYPE (*node)
+       = build_function_type_for_method (TREE_VALUE (saved_type), *node,
+                                         METHOD_REF, 0);
       decl_attributes (node, filtered_attributes, flags);
       METHOD_TYPE_ATTRIBUTES (*node) = TYPE_ATTRIBUTES (TREE_TYPE (*node));
       TREE_TYPE (*node) = saved_type;
@@ -5057,60 +5058,66 @@ objc_method_decl (enum tree_code opcode)
   return opcode == INSTANCE_METHOD_DECL || opcode == CLASS_METHOD_DECL;
 }
 
-/* Used by `build_objc_method_call'.  Return an argument list for
-   method METH.  CONTEXT is either METHOD_DEF or METHOD_REF, saying
-   whether we are trying to define a method or call one.  SUPERFLAG
-   says this is for a send to super; this makes a difference for the
-   NeXT calling sequence in which the lookup and the method call are
-   done together.  If METH is null, user-defined arguments (i.e.,
-   beyond self and _cmd) shall be represented by `...'.  */
+/* Return a function type for METHOD with RETURN_TYPE.  CONTEXT is
+   either METHOD_DEF or METHOD_REF, indicating whether we are defining a
+   method or calling one.  SUPER_FLAG indicates whether this is a send
+   to super; this makes a difference for the NeXT calling sequence in
+   which the lookup and the method call are done together.  If METHOD is
+   NULL, user-defined arguments (i.e., beyond self and _cmd) shall be
+   represented as varargs.  */
 
 tree
-get_arg_type_list (tree meth, int context, int superflag)
+build_function_type_for_method (tree return_type, tree method,
+                               int context, bool super_flag)
 {
-  tree arglist, akey;
+  VEC(tree,gc) *argtypes = make_tree_vector ();
+  tree t, ftype;
+  bool is_varargs = false;
 
-  /* Receiver & _cmd types are runtime-dependent.  */
-  arglist = (*runtime.get_arg_type_list_base) (meth, context, superflag);
+  (*runtime.get_arg_type_list_base) (&argtypes, method, context, super_flag);
 
-  /* No actual method prototype given -- assume that remaining arguments
-     are `...'.  */
-  if (!meth)
-    return arglist;
+  /* No actual method prototype given; remaining args passed as varargs.  */
+  if (method == NULL_TREE)
+    {
+      is_varargs = true;
+      goto build_ftype;
+    }
 
-  /* Build a list of argument types.  */
-  for (akey = METHOD_SEL_ARGS (meth); akey; akey = DECL_CHAIN (akey))
+  for (t = METHOD_SEL_ARGS (method); t; t = DECL_CHAIN (t))
     {
-      tree arg_type = TREE_VALUE (TREE_TYPE (akey));
+      tree arg_type = TREE_VALUE (TREE_TYPE (t));
 
-      /* Decay argument types for the underlying C function as appropriate.  */
+      /* Decay argument types for the underlying C function as
+         appropriate.  */
       arg_type = objc_decay_parm_type (arg_type);
 
-      chainon (arglist, build_tree_list (NULL_TREE, arg_type));
+      VEC_safe_push (tree, gc, argtypes, arg_type);
     }
 
-  if (METHOD_ADD_ARGS (meth))
+  if (METHOD_ADD_ARGS (method))
     {
-      for (akey = TREE_CHAIN (METHOD_ADD_ARGS (meth));
-          akey; akey = TREE_CHAIN (akey))
+      for (t = TREE_CHAIN (METHOD_ADD_ARGS (method));
+          t; t = TREE_CHAIN (t))
        {
-         tree arg_type = TREE_TYPE (TREE_VALUE (akey));
+         tree arg_type = TREE_TYPE (TREE_VALUE (t));
 
          arg_type = objc_decay_parm_type (arg_type);
 
-         chainon (arglist, build_tree_list (NULL_TREE, arg_type));
+         VEC_safe_push (tree, gc, argtypes, arg_type);
        }
 
-      if (!METHOD_ADD_ARGS_ELLIPSIS_P (meth))
-       goto lack_of_ellipsis;
+      if (METHOD_ADD_ARGS_ELLIPSIS_P (method))
+       is_varargs = true;
     }
+
+ build_ftype:
+  if (is_varargs)
+    ftype = build_varargs_function_type_vec (return_type, argtypes);
   else
-    {
-     lack_of_ellipsis:
-      chainon (arglist, OBJC_VOID_AT_END);
-    }
+    ftype = build_function_type_vec (return_type, argtypes);
 
-  return arglist;
+  release_tree_vector (argtypes);
+  return ftype;
 }
 
 static tree
@@ -8700,9 +8707,7 @@ really_start_method (tree method,
   push_lang_context (lang_name_c);
 #endif
 
-  meth_type
-    = build_function_type (ret_type,
-                          get_arg_type_list (method, METHOD_DEF, 0));
+  meth_type = build_function_type_for_method (ret_type, method, METHOD_DEF, 0);
   objc_start_function (method_id, meth_type, NULL_TREE, parmlist);
 
   /* Set self_decl from the first argument.  */
index 30c74c58f71ca912b3324fd1e4c431c3cbf29b64..d31bb7dce2e0521e6bdd6f61ddd903fc52aa4021 100644 (file)
@@ -665,8 +665,6 @@ typedef enum string_section
 #define OBJC_MODIFIER_TRANSIENT                0x00000200
 #define OBJC_MODIFIER_NONE_SPECIFIED   0x80000000
 
-#define OBJC_VOID_AT_END               void_list_node
-
 /* Exception handling constructs.  We begin by having the parser do most
    of the work and passing us blocks.
    This allows us to handle different exceptions implementations.  */
index 863f7d66cdf0e2e917902edf92a0891f6a05877f..d21f2e9a6b598044b89384074a2486c6023e3a2a 100644 (file)
@@ -103,7 +103,8 @@ static tree gnu_runtime_abi_01_get_class_super_ref (location_t, struct imp_entry
 static tree gnu_runtime_abi_01_get_category_super_ref (location_t, struct imp_entry *, bool);
 
 static tree gnu_runtime_abi_01_receiver_is_class_object (tree);
-static tree gnu_runtime_abi_01_get_arg_type_list_base (tree, int, int);
+static void gnu_runtime_abi_01_get_arg_type_list_base (VEC(tree,gc) **, tree,
+                                                      int, int);
 static tree gnu_runtime_abi_01_build_objc_method_call (location_t, tree, tree,
                                                        tree, tree, tree, int);
 
@@ -577,27 +578,28 @@ gnu_runtime_abi_01_get_class_reference (tree ident)
   return build_function_call (input_location, objc_get_class_decl, params);
 }
 
-/* Used by get_arg_type_list.
-   Return the types for receiver & _cmd at the start of a method argument list.
-   context is either METHOD_DEF or METHOD_REF, saying whether we are trying
-   to define a method or call one.  superflag says this is for a send to super.
-   meth may be NULL, in the case that there is no prototype.  */
+/* Used by build_function_type_for_method.  Append the types for
+   receiver & _cmd at the start of a method argument list to ARGTYPES.
+   CONTEXT is either METHOD_DEF or METHOD_REF, saying whether we are
+   trying to define a method or call one.  SUPERFLAG says this is for a
+   send to super.  METH may be NULL, in the case that there is no
+   prototype.  */
 
-static tree
-gnu_runtime_abi_01_get_arg_type_list_base (tree meth, int context,
+static void
+gnu_runtime_abi_01_get_arg_type_list_base (VEC(tree,gc) **argtypes, tree meth,
+                                          int context,
                                           int superflag ATTRIBUTE_UNUSED)
 {
-  tree arglist;
+  tree receiver_type;
 
-  /* Receiver type.  */
   if (context == METHOD_DEF && TREE_CODE (meth) == INSTANCE_METHOD_DECL)
-    arglist = build_tree_list (NULL_TREE, objc_instance_type);
+    receiver_type = objc_instance_type;
   else
-    arglist = build_tree_list (NULL_TREE, objc_object_type);
+    receiver_type = objc_object_type;
 
+  VEC_safe_push (tree, gc, *argtypes, receiver_type);
   /* Selector type - will eventually change to `int'.  */
-  chainon (arglist, build_tree_list (NULL_TREE, objc_selector_type));
-  return arglist;
+  VEC_safe_push (tree, gc, *argtypes, objc_selector_type);
 }
 
 /* Unused for GNU runtime.  */
@@ -672,10 +674,9 @@ build_objc_method_call (location_t loc, int super_flag, tree method_prototype,
     = (method_prototype
        ? TREE_VALUE (TREE_TYPE (method_prototype))
        : objc_object_type);
-
-  tree method_param_types =
-    get_arg_type_list (method_prototype, METHOD_REF, super_flag);
-  tree ftype = build_function_type (ret_type, method_param_types);
+  tree ftype
+    = build_function_type_for_method (ret_type, method_prototype,
+                                     METHOD_REF, super_flag);
   tree sender_cast;
   tree method, t;
 
index 4fb2a38541fe8725490c7d05b167a15501d3846b..d5b795fbb0e78249e2c81585730e7b2d77e070cb 100644 (file)
@@ -123,7 +123,8 @@ static tree next_runtime_abi_01_get_class_super_ref (location_t, struct imp_entr
 static tree next_runtime_abi_01_get_category_super_ref (location_t, struct imp_entry *, bool);
 
 static tree next_runtime_abi_01_receiver_is_class_object (tree);
-static tree next_runtime_abi_01_get_arg_type_list_base (tree, int, int);
+static void next_runtime_abi_01_get_arg_type_list_base (VEC(tree,gc) **, tree,
+                                                       int, int);
 static tree next_runtime_abi_01_build_objc_method_call (location_t, tree, tree,
                                                        tree, tree, tree, int);
 static bool next_runtime_abi_01_setup_const_string_class_decl (void);
@@ -721,28 +722,29 @@ next_runtime_abi_01_get_class_reference (tree ident)
     }
 }
 
-/* Used by get_arg_type_list.
-   Return the types for receiver & _cmd at the start of a method argument list.
-   context is either METHOD_DEF or METHOD_REF, saying whether we are trying
-   to define a method or call one.  superflag says this is for a send to super.
-   meth may be NULL, in the case that there is no prototype.  */
+/* Used by build_function_type_for_method.  Append the types for
+   receiver & _cmd at the start of a method argument list to ARGTYPES.
+   CONTEXT is either METHOD_DEF or METHOD_REF, saying whether we are
+   trying to define a method or call one.  SUPERFLAG says this is for a
+   send to super.  METH may be NULL, in the case that there is no
+   prototype.  */
 
-static tree
-next_runtime_abi_01_get_arg_type_list_base (tree meth, int context, int superflag)
+static void
+next_runtime_abi_01_get_arg_type_list_base (VEC(tree,gc) **argtypes, tree meth,
+                                           int context, int superflag)
 {
-  tree arglist;
+  tree receiver_type;
 
-  /* Receiver type.  */
   if (superflag)
-    arglist = build_tree_list (NULL_TREE, objc_super_type);
+    receiver_type = objc_super_type;
   else if (context == METHOD_DEF && TREE_CODE (meth) == INSTANCE_METHOD_DECL)
-    arglist = build_tree_list (NULL_TREE, objc_instance_type);
+    receiver_type = objc_instance_type;
   else
-    arglist = build_tree_list (NULL_TREE, objc_object_type);
+    receiver_type = objc_object_type;
 
+  VEC_safe_push (tree, gc, *argtypes, receiver_type);
   /* Selector type - will eventually change to `int'.  */
-  chainon (arglist, build_tree_list (NULL_TREE, objc_selector_type));
-  return arglist;
+  VEC_safe_push (tree, gc, *argtypes, objc_selector_type);
 }
 
 static tree
@@ -828,10 +830,8 @@ build_objc_method_call (location_t loc, int super_flag, tree method_prototype,
     = (method_prototype
        ? TREE_VALUE (TREE_TYPE (method_prototype))
        : objc_object_type);
-
-  tree method_param_types =
-    get_arg_type_list (method_prototype, METHOD_REF, super_flag);
-  tree ftype = build_function_type (ret_type, method_param_types);
+  tree ftype = build_function_type_for_method (ret_type, method_prototype,
+                                              METHOD_REF, super_flag);
 
   if (method_prototype && METHOD_TYPE_ATTRIBUTES (method_prototype))
     ftype = build_type_attribute_variant (ftype,
index 90660d75a98f344e560881d221286b89daeef9a5..3d889b0a1166b310139ba3d28e0095e712af0a2d 100644 (file)
@@ -213,7 +213,8 @@ static tree next_runtime_abi_02_get_class_super_ref (location_t, struct imp_entr
 static tree next_runtime_abi_02_get_category_super_ref (location_t, struct imp_entry *, bool);
 
 static tree next_runtime_abi_02_receiver_is_class_object (tree);
-static tree next_runtime_abi_02_get_arg_type_list_base (tree, int, int);
+static void next_runtime_abi_02_get_arg_type_list_base (VEC(tree,gc) **, tree,
+                                                       int, int);
 static tree next_runtime_abi_02_build_objc_method_call (location_t, tree, tree,
                                                        tree, tree, tree, int);
 static bool next_runtime_abi_02_setup_const_string_class_decl (void);
@@ -1098,31 +1099,32 @@ next_runtime_abi_02_get_class_reference (tree ident)
     }
 }
 
-/* Used by get_arg_type_list.
-   Return the types for receiver & _cmd at the start of a method
-   argument list.  context is either METHOD_DEF or METHOD_REF, saying
-   whether we are trying to define a method or call one.  superflag
-   says this is for a send to super.  meth may be NULL, in the case
-   that there is no prototype.  */
+/* Used by build_function_type_for_method.  Append the types for
+   receiver & _cmd at the start of a method argument list to ARGTYPES.
+   CONTEXT is either METHOD_DEF or METHOD_REF, saying whether we are
+   trying to define a method or call one.  SUPERFLAG says this is for a
+   send to super.  METH may be NULL, in the case that there is no
+   prototype.  */
 
-static tree
-next_runtime_abi_02_get_arg_type_list_base (tree meth, int context, int superflag)
+static void
+next_runtime_abi_02_get_arg_type_list_base (VEC(tree,gc) **argtypes, tree meth,
+                                           int context, int superflag)
 {
-  tree arglist;
+  tree receiver_type;
 
-  /* Receiver type.  */
   if (superflag)
-    arglist = build_tree_list (NULL_TREE, objc_super_type);
+    receiver_type = objc_super_type;
   else if (context == METHOD_DEF && TREE_CODE (meth) == INSTANCE_METHOD_DECL)
-    arglist = build_tree_list (NULL_TREE, objc_instance_type);
+    receiver_type = objc_instance_type;
   else
-    arglist = build_tree_list (NULL_TREE, objc_object_type);
+    receiver_type = objc_object_type;
 
+  VEC_safe_push (tree, gc, *argtypes, receiver_type);
   /* Selector type - will eventually change to `int'.  */
-  chainon (arglist, build_tree_list (NULL_TREE,
-                                    (superflag ? objc_v2_super_selector_type
-                                               : objc_v2_selector_type)));
-  return arglist;
+  VEC_safe_push (tree, gc, *argtypes,
+                (superflag
+                 ? objc_v2_super_selector_type
+                 : objc_v2_selector_type));
 }
 
 /* TODO: Merge this with the message refs.  */
@@ -1539,23 +1541,26 @@ next_runtime_abi_02_receiver_is_class_object (tree receiver)
   return NULL_TREE;
 }
 
-/* Assign all arguments in VALUES which have side-effect to a
-   temporary and replaced that argument in VALUES list with the
-   temporary. TYPELIST is the list of argument types. */
+/* Assign all arguments in VALUES which have side-effect to a temporary
+   and replaced that argument in VALUES list with the temporary. The
+   arguments will be passed to a function with FNTYPE.  */
 
 static tree
-objc_copy_to_temp_side_effect_params (tree typelist, tree values)
+objc_copy_to_temp_side_effect_params (tree fntype, tree values)
 {
-  tree valtail, typetail;
+  tree valtail;
+  function_args_iterator iter;
+
   /* Skip over receiver and the &_msf_ref types.  */
-  gcc_assert (TREE_CHAIN (typelist));
-  typetail = TREE_CHAIN (TREE_CHAIN (typelist));
+  function_args_iter_init (&iter, fntype);
+  function_args_iter_next (&iter);
+  function_args_iter_next (&iter);
 
   for (valtail = values; valtail;
-       valtail = TREE_CHAIN (valtail), typetail = TREE_CHAIN (typetail))
+       valtail = TREE_CHAIN (valtail), function_args_iter_next (&iter))
     {
       tree value = TREE_VALUE (valtail);
-      tree type = typetail ? TREE_VALUE (typetail) : NULL_TREE;
+      tree type = function_args_iter_cond (&iter);
       if (type == NULL_TREE)
        break;
       if (!TREE_SIDE_EFFECTS (value))
@@ -1583,10 +1588,8 @@ build_v2_build_objc_method_call (int super_flag, tree method_prototype,
     = (method_prototype
        ? TREE_VALUE (TREE_TYPE (method_prototype))
        : objc_object_type);
-  tree method_param_types = get_arg_type_list (method_prototype,
+  tree ftype = build_function_type_for_method (ret_type, method_prototype,
                                               METHOD_REF, super_flag);
-
-  tree ftype = build_function_type (ret_type, method_param_types);
   tree sender_cast;
 
   if (method_prototype && METHOD_TYPE_ATTRIBUTES (method_prototype))
@@ -1596,7 +1599,7 @@ build_v2_build_objc_method_call (int super_flag, tree method_prototype,
   sender_cast = build_pointer_type (ftype);
 
   if (check_for_nil)
-    method_params = objc_copy_to_temp_side_effect_params (method_param_types,
+    method_params = objc_copy_to_temp_side_effect_params (ftype,
                                                          method_params);
 
   /* Get &message_ref_t.messenger.  */
index d2606ff0d9814c58d0b994f14dcefcfdd5fece36..9145681bfa9dcbba853562db2d87c74759ad7ce9 100644 (file)
@@ -75,7 +75,7 @@ typedef struct _objc_runtime_hooks_r
   /* Receiver is class Object, check runtime-specific.  */
   tree (*receiver_is_class_object) (tree);
   /* Get the start of a method argument type list (receiver, _cmd).  */
-  tree (*get_arg_type_list_base) (tree, int, int);
+  void (*get_arg_type_list_base) (VEC(tree,gc) **, tree, int, int);
   /* Build method call.  */
   tree (*build_objc_method_call) (location_t, tree, tree, tree, tree, tree, int);
 
index c948cfdba989ed90ec930e68f445e64c4aa2de7a..bb0e5711df0924428c7effe5c8cd138ee152f1a5 100644 (file)
@@ -49,7 +49,8 @@ extern void objc_start_function (tree, tree, tree, struct c_arg_info *);
 extern struct c_arg_info *objc_get_parm_info (int, tree);
 #endif
 extern void objc_push_parm (tree);
-extern tree get_arg_type_list (tree, int, int);
+
+extern tree build_function_type_for_method (tree, tree, int, bool);
 
 /* Stuff that should be migrated to shared support (or some v1-only file).  */
 extern void build_super_template (void);