On Thu, Apr 21, 2011 at 5:04 PM, Nathan Froyd <froy...@codesourcery.com> wrote:
> This patch does two things:
>
> - centralizes some infrastructure for defining builtin function types
>  for frontends by providing a common function that
>  DEF_FUNCTION_TYPE_FOO macros can call; and
>
> - in order to do that well, it also introduces
>  build{,_varargs}_function_type_array for cases when
>  build_function_type_list's interface doesn't work so well.
>
> build_function_type_list could have been used instead, but it would lose
> the error_mark_node handling provided in the C/C++/Ada/LTO frontends.
> This new interface will be necessary for eliminating other uses of
> build_function_type anyway.
>
> It would have been easier to move all of the builtin-types stuff into
> the middle-end, but Fortran doesn't use builtin-types.def.  Even if it
> did, I suppose it's possible that some new front-end could have its own
> set of builtin types, so I'm leaving things as they are.

But this is what should be done, at least for all builtins in the
BUILT_IN_NORMAL category.  ISTR Fortran was once running into
the issue of assigning different DECL_FUNCTION_CODE numbers to
those builtins than other languages, breaking LTO.

So, it would be indeed nice to have a central middle-end place to
instantiate those builtins and their required types.  I'm not sure how
far we are from that and am too lazy to look right now ...

Richard.

> The new functions can eliminate some of the games that were played with
> the recent backend changes to use build_function_type_list; if this
> patch is approved, I'll make the (currently uncommitted) patches that
> could use build_function_type_array do so.
>
> Bootstrap and testing in progress on x86_64-unknown-linux-gnu.  OK to
> commit if successful?
>
> -Nathan
>
> gcc/ada/
>        * gcc-interface/utils.c (def_fn_type): Delete.
>        (DEF_FUNCTION_TYPE_0, DEF_FUNCTION_TYPE_1): Change to use
>        define_builtin_function_type.
>        (DEF_FUNCTION_TYPE_2, DEF_FUNCTION_TYPE_3, DEF_FUNCTION_TYPE_4):
>        (DEF_FUNCTION_TYPE_5, DEF_FUNCTION_TYPE_6, DEF_FUNCTION_TYPE_7):
>        (DEF_FUNCTION_TYPE_VAR_0, DEF_FUNCTION_TYPE_VAR_1):
>        (DEF_FUNCTION_TYPE_VAR_2, DEF_FUNCTION_TYPE_VAR_3):
>        (DEF_FUNCTION_TYPE_VAR_4, DEF_FUNCTION_TYPE_VAR_5): Likewise.
>
> gcc/c-family/:
>        * c-common.c (def_fn_type): Delete.
>        (DEF_FUNCTION_TYPE_0, DEF_FUNCTION_TYPE_1): Change to use
>        define_builtin_function_type.
>        (DEF_FUNCTION_TYPE_2, DEF_FUNCTION_TYPE_3, DEF_FUNCTION_TYPE_4):
>        (DEF_FUNCTION_TYPE_5, DEF_FUNCTION_TYPE_6, DEF_FUNCTION_TYPE_7):
>        (DEF_FUNCTION_TYPE_VAR_0, DEF_FUNCTION_TYPE_VAR_1):
>        (DEF_FUNCTION_TYPE_VAR_2, DEF_FUNCTION_TYPE_VAR_3):
>        (DEF_FUNCTION_TYPE_VAR_4, DEF_FUNCTION_TYPE_VAR_5): Likewise.
>
> gcc/
>        * tree.h (build_function_type_array): Declare.
>        (build_varargs_function_type_array, define_builtin_function_type):
>        Declare.
>        * tree.c (build_function_type_array_1): Define.
>        (build_function_type_array, build_varargs_function_type_array): Define.
>        (define_builtin_function_type): Define.
>
> gcc/fortran/
>        * f95-lang.c (DEF_FUNCTION_TYPE_0, DEF_FUNCTION_TYPE_1): Change
>        to use define_builtin_function_type.
>        (DEF_FUNCTION_TYPE_2, DEF_FUNCTION_TYPE_3, DEF_FUNCTION_TYPE_4):
>        (DEF_FUNCTION_TYPE_5, DEF_FUNCTION_TYPE_6, DEF_FUNCTION_TYPE_7):
>        (DEF_FUNCTION_TYPE_VAR_0): Likewise.
>
> gcc/lto/
>        * lto-lang.c (def_fn_type): Delete.
>        (DEF_FUNCTION_TYPE_0, DEF_FUNCTION_TYPE_1): Change to use
>        define_builtin_function_type.
>        (DEF_FUNCTION_TYPE_2, DEF_FUNCTION_TYPE_3, DEF_FUNCTION_TYPE_4):
>        (DEF_FUNCTION_TYPE_5, DEF_FUNCTION_TYPE_6, DEF_FUNCTION_TYPE_7):
>        (DEF_FUNCTION_TYPE_VAR_0, DEF_FUNCTION_TYPE_VAR_1):
>        (DEF_FUNCTION_TYPE_VAR_2, DEF_FUNCTION_TYPE_VAR_3):
>        (DEF_FUNCTION_TYPE_VAR_4, DEF_FUNCTION_TYPE_VAR_5): Likewise.
>
> diff --git a/gcc/ada/gcc-interface/utils.c b/gcc/ada/gcc-interface/utils.c
> index 1031ee9..6eb136d 100644
> --- a/gcc/ada/gcc-interface/utils.c
> +++ b/gcc/ada/gcc-interface/utils.c
> @@ -4952,47 +4952,6 @@ typedef enum c_builtin_type builtin_type;
>  /* A temporary array used in communication with def_fn_type.  */
>  static GTY(()) tree builtin_types[(int) BT_LAST + 1];
>
> -/* A helper function for install_builtin_types.  Build function type
> -   for DEF with return type RET and N arguments.  If VAR is true, then the
> -   function should be variadic after those N arguments.
> -
> -   Takes special care not to ICE if any of the types involved are
> -   error_mark_node, which indicates that said type is not in fact available
> -   (see builtin_type_for_size).  In which case the function type as a whole
> -   should be error_mark_node.  */
> -
> -static void
> -def_fn_type (builtin_type def, builtin_type ret, bool var, int n, ...)
> -{
> -  tree args = NULL, t;
> -  va_list list;
> -  int i;
> -
> -  va_start (list, n);
> -  for (i = 0; i < n; ++i)
> -    {
> -      builtin_type a = (builtin_type) va_arg (list, int);
> -      t = builtin_types[a];
> -      if (t == error_mark_node)
> -       goto egress;
> -      args = tree_cons (NULL_TREE, t, args);
> -    }
> -  va_end (list);
> -
> -  args = nreverse (args);
> -  if (!var)
> -    args = chainon (args, void_list_node);
> -
> -  t = builtin_types[ret];
> -  if (t == error_mark_node)
> -    goto egress;
> -  t = build_function_type (t, args);
> -
> - egress:
> -  builtin_types[def] = t;
> -  va_end (list);
> -}
> -
>  /* Build the builtin function types and install them in the builtin_types
>    array for later use in builtin function decls.  */
>
> @@ -5016,35 +4975,35 @@ install_builtin_function_types (void)
>  #define DEF_PRIMITIVE_TYPE(ENUM, VALUE) \
>   builtin_types[ENUM] = VALUE;
>  #define DEF_FUNCTION_TYPE_0(ENUM, RETURN) \
> -  def_fn_type (ENUM, RETURN, 0, 0);
> +  define_builtin_function_type (builtin_types, (int) ENUM, (int) RETURN, 
> false, 0);
>  #define DEF_FUNCTION_TYPE_1(ENUM, RETURN, ARG1) \
> -  def_fn_type (ENUM, RETURN, 0, 1, ARG1);
> +  define_builtin_function_type (builtin_types, (int) ENUM, (int) RETURN, 
> false, 1, (int) ARG1);
>  #define DEF_FUNCTION_TYPE_2(ENUM, RETURN, ARG1, ARG2) \
> -  def_fn_type (ENUM, RETURN, 0, 2, ARG1, ARG2);
> +  define_builtin_function_type (builtin_types, (int) ENUM, (int) RETURN, 
> false, 2, (int) ARG1, (int) ARG2);
>  #define DEF_FUNCTION_TYPE_3(ENUM, RETURN, ARG1, ARG2, ARG3) \
> -  def_fn_type (ENUM, RETURN, 0, 3, ARG1, ARG2, ARG3);
> +  define_builtin_function_type (builtin_types, (int) ENUM, (int) RETURN, 
> false, 3, (int) ARG1, (int) ARG2, (int) ARG3);
>  #define DEF_FUNCTION_TYPE_4(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4) \
> -  def_fn_type (ENUM, RETURN, 0, 4, ARG1, ARG2, ARG3, ARG4);
> +  define_builtin_function_type (builtin_types, (int) ENUM, (int) RETURN, 
> false, 4, (int) ARG1, (int) ARG2, (int) ARG3, (int) ARG4);
>  #define DEF_FUNCTION_TYPE_5(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5)      
>   \
> -  def_fn_type (ENUM, RETURN, 0, 5, ARG1, ARG2, ARG3, ARG4, ARG5);
> +  define_builtin_function_type (builtin_types, (int) ENUM, (int) RETURN, 
> false, 5, (int) ARG1, (int) ARG2, (int) ARG3, (int) ARG4, (int) ARG5);
>  #define DEF_FUNCTION_TYPE_6(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \
>                            ARG6)                                       \
> -  def_fn_type (ENUM, RETURN, 0, 6, ARG1, ARG2, ARG3, ARG4, ARG5, ARG6);
> +  define_builtin_function_type (builtin_types, (int) ENUM, (int) RETURN, 
> false, 6, (int) ARG1, (int) ARG2, (int) ARG3, (int) ARG4, (int) ARG5, (int) 
> ARG6);
>  #define DEF_FUNCTION_TYPE_7(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \
>                            ARG6, ARG7)                                 \
> -  def_fn_type (ENUM, RETURN, 0, 7, ARG1, ARG2, ARG3, ARG4, ARG5, ARG6, ARG7);
> +  define_builtin_function_type (builtin_types, (int) ENUM, (int) RETURN, 
> false, 7, (int) ARG1, (int) ARG2, (int) ARG3, (int) ARG4, (int) ARG5, (int) 
> ARG6, (int) ARG7);
>  #define DEF_FUNCTION_TYPE_VAR_0(ENUM, RETURN) \
> -  def_fn_type (ENUM, RETURN, 1, 0);
> +  define_builtin_function_type (builtin_types, (int) ENUM, (int) RETURN, 
> true, 0);
>  #define DEF_FUNCTION_TYPE_VAR_1(ENUM, RETURN, ARG1) \
> -  def_fn_type (ENUM, RETURN, 1, 1, ARG1);
> +  define_builtin_function_type (builtin_types, (int) ENUM, (int) RETURN, 
> true, 1, (int) ARG1);
>  #define DEF_FUNCTION_TYPE_VAR_2(ENUM, RETURN, ARG1, ARG2) \
> -  def_fn_type (ENUM, RETURN, 1, 2, ARG1, ARG2);
> +  define_builtin_function_type (builtin_types, (int) ENUM, (int) RETURN, 
> true, 2, (int) ARG1, (int) ARG2);
>  #define DEF_FUNCTION_TYPE_VAR_3(ENUM, RETURN, ARG1, ARG2, ARG3) \
> -  def_fn_type (ENUM, RETURN, 1, 3, ARG1, ARG2, ARG3);
> +  define_builtin_function_type (builtin_types, (int) ENUM, (int) RETURN, 
> true, 3, (int) ARG1, (int) ARG2, (int) ARG3);
>  #define DEF_FUNCTION_TYPE_VAR_4(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4) \
> -  def_fn_type (ENUM, RETURN, 1, 4, ARG1, ARG2, ARG3, ARG4);
> +  define_builtin_function_type (builtin_types, (int) ENUM, (int) RETURN, 
> true, 4, (int) ARG1, (int) ARG2, (int) ARG3, (int) ARG4);
>  #define DEF_FUNCTION_TYPE_VAR_5(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5) \
> -  def_fn_type (ENUM, RETURN, 1, 5, ARG1, ARG2, ARG3, ARG4, ARG5);
> +  define_builtin_function_type (builtin_types, (int) ENUM, (int) RETURN, 
> true, 5, (int) ARG1, (int) ARG2, (int) ARG3, (int) ARG4, (int) ARG5);
>  #define DEF_POINTER_TYPE(ENUM, TYPE) \
>   builtin_types[(int) ENUM] = build_pointer_type (builtin_types[(int) TYPE]);
>
> diff --git a/gcc/c-family/c-common.c b/gcc/c-family/c-common.c
> index 752806e..b33630a 100644
> --- a/gcc/c-family/c-common.c
> +++ b/gcc/c-family/c-common.c
> @@ -4399,47 +4399,6 @@ typedef enum c_builtin_type builtin_type;
>    communication with def_fn_type.  */
>  static tree builtin_types[(int) BT_LAST + 1];
>
> -/* A helper function for c_common_nodes_and_builtins.  Build function type
> -   for DEF with return type RET and N arguments.  If VAR is true, then the
> -   function should be variadic after those N arguments.
> -
> -   Takes special care not to ICE if any of the types involved are
> -   error_mark_node, which indicates that said type is not in fact available
> -   (see builtin_type_for_size).  In which case the function type as a whole
> -   should be error_mark_node.  */
> -
> -static void
> -def_fn_type (builtin_type def, builtin_type ret, bool var, int n, ...)
> -{
> -  tree args = NULL, t;
> -  va_list list;
> -  int i;
> -
> -  va_start (list, n);
> -  for (i = 0; i < n; ++i)
> -    {
> -      builtin_type a = (builtin_type) va_arg (list, int);
> -      t = builtin_types[a];
> -      if (t == error_mark_node)
> -       goto egress;
> -      args = tree_cons (NULL_TREE, t, args);
> -    }
> -  va_end (list);
> -
> -  args = nreverse (args);
> -  if (!var)
> -    args = chainon (args, void_list_node);
> -
> -  t = builtin_types[ret];
> -  if (t == error_mark_node)
> -    goto egress;
> -  t = build_function_type (t, args);
> -
> - egress:
> -  builtin_types[def] = t;
> -  va_end (list);
> -}
> -
>  /* Build builtin functions common to both C and C++ language
>    frontends.  */
>
> @@ -4449,35 +4408,35 @@ c_define_builtins (tree va_list_ref_type_node, tree 
> va_list_arg_type_node)
>  #define DEF_PRIMITIVE_TYPE(ENUM, VALUE) \
>   builtin_types[ENUM] = VALUE;
>  #define DEF_FUNCTION_TYPE_0(ENUM, RETURN) \
> -  def_fn_type (ENUM, RETURN, 0, 0);
> +  define_builtin_function_type (builtin_types, (int) ENUM, (int) RETURN, 
> false, 0);
>  #define DEF_FUNCTION_TYPE_1(ENUM, RETURN, ARG1) \
> -  def_fn_type (ENUM, RETURN, 0, 1, ARG1);
> +  define_builtin_function_type (builtin_types, (int) ENUM, (int) RETURN, 
> false, 1, (int) ARG1);
>  #define DEF_FUNCTION_TYPE_2(ENUM, RETURN, ARG1, ARG2) \
> -  def_fn_type (ENUM, RETURN, 0, 2, ARG1, ARG2);
> +  define_builtin_function_type (builtin_types, (int) ENUM, (int) RETURN, 
> false, 2, (int) ARG1, (int) ARG2);
>  #define DEF_FUNCTION_TYPE_3(ENUM, RETURN, ARG1, ARG2, ARG3) \
> -  def_fn_type (ENUM, RETURN, 0, 3, ARG1, ARG2, ARG3);
> +  define_builtin_function_type (builtin_types, (int) ENUM, (int) RETURN, 
> false, 3, (int) ARG1, (int) ARG2, (int) ARG3);
>  #define DEF_FUNCTION_TYPE_4(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4) \
> -  def_fn_type (ENUM, RETURN, 0, 4, ARG1, ARG2, ARG3, ARG4);
> +  define_builtin_function_type (builtin_types, (int) ENUM, (int) RETURN, 
> false, 4, (int) ARG1, (int) ARG2, (int) ARG3, (int) ARG4);
>  #define DEF_FUNCTION_TYPE_5(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5)      
>   \
> -  def_fn_type (ENUM, RETURN, 0, 5, ARG1, ARG2, ARG3, ARG4, ARG5);
> +  define_builtin_function_type (builtin_types, (int) ENUM, (int) RETURN, 
> false, 5, (int) ARG1, (int) ARG2, (int) ARG3, (int) ARG4, (int) ARG5);
>  #define DEF_FUNCTION_TYPE_6(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \
>                            ARG6)                                       \
> -  def_fn_type (ENUM, RETURN, 0, 6, ARG1, ARG2, ARG3, ARG4, ARG5, ARG6);
> +  define_builtin_function_type (builtin_types, (int) ENUM, (int) RETURN, 
> false, 6, (int) ARG1, (int) ARG2, (int) ARG3, (int) ARG4, (int) ARG5, (int) 
> ARG6);
>  #define DEF_FUNCTION_TYPE_7(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \
>                            ARG6, ARG7)                                 \
> -  def_fn_type (ENUM, RETURN, 0, 7, ARG1, ARG2, ARG3, ARG4, ARG5, ARG6, ARG7);
> +  define_builtin_function_type (builtin_types, (int) ENUM, (int) RETURN, 
> false, 7, (int) ARG1, (int) ARG2, (int) ARG3, (int) ARG4, (int) ARG5, (int) 
> ARG6, (int) ARG7);
>  #define DEF_FUNCTION_TYPE_VAR_0(ENUM, RETURN) \
> -  def_fn_type (ENUM, RETURN, 1, 0);
> +  define_builtin_function_type (builtin_types, (int) ENUM, (int) RETURN, 
> true, 0);
>  #define DEF_FUNCTION_TYPE_VAR_1(ENUM, RETURN, ARG1) \
> -  def_fn_type (ENUM, RETURN, 1, 1, ARG1);
> +  define_builtin_function_type (builtin_types, (int) ENUM, (int) RETURN, 
> true, 1, (int) ARG1);
>  #define DEF_FUNCTION_TYPE_VAR_2(ENUM, RETURN, ARG1, ARG2) \
> -  def_fn_type (ENUM, RETURN, 1, 2, ARG1, ARG2);
> +  define_builtin_function_type (builtin_types, (int) ENUM, (int) RETURN, 
> true, 2, (int) ARG1, (int) ARG2);
>  #define DEF_FUNCTION_TYPE_VAR_3(ENUM, RETURN, ARG1, ARG2, ARG3) \
> -  def_fn_type (ENUM, RETURN, 1, 3, ARG1, ARG2, ARG3);
> +  define_builtin_function_type (builtin_types, (int) ENUM, (int) RETURN, 
> true, 3, (int) ARG1, (int) ARG2, (int) ARG3);
>  #define DEF_FUNCTION_TYPE_VAR_4(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4) \
> -  def_fn_type (ENUM, RETURN, 1, 4, ARG1, ARG2, ARG3, ARG4);
> +  define_builtin_function_type (builtin_types, (int) ENUM, (int) RETURN, 
> true, 4, (int) ARG1, (int) ARG2, (int) ARG3, (int) ARG4);
>  #define DEF_FUNCTION_TYPE_VAR_5(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5) \
> -  def_fn_type (ENUM, RETURN, 1, 5, ARG1, ARG2, ARG3, ARG4, ARG5);
> +  define_builtin_function_type (builtin_types, (int) ENUM, (int) RETURN, 
> true, 5, (int) ARG1, (int) ARG2, (int) ARG3, (int) ARG4, (int) ARG5);
>  #define DEF_POINTER_TYPE(ENUM, TYPE) \
>   builtin_types[(int) ENUM] = build_pointer_type (builtin_types[(int) TYPE]);
>
> diff --git a/gcc/fortran/f95-lang.c b/gcc/fortran/f95-lang.c
> index eb38484..71a5365 100644
> --- a/gcc/fortran/f95-lang.c
> +++ b/gcc/fortran/f95-lang.c
> @@ -1024,72 +1024,26 @@ gfc_init_builtin_functions (void)
>
>  #define DEF_PRIMITIVE_TYPE(ENUM, VALUE) \
>   builtin_types[(int) ENUM] = VALUE;
> -#define DEF_FUNCTION_TYPE_0(ENUM, RETURN)                       \
> -  builtin_types[(int) ENUM]                                     \
> -    = build_function_type_list (builtin_types[(int) RETURN],   \
> -                                NULL_TREE);
> -#define DEF_FUNCTION_TYPE_1(ENUM, RETURN, ARG1)                              
>   \
> -  builtin_types[(int) ENUM]                                            \
> -    = build_function_type_list (builtin_types[(int) RETURN],            \
> -                                builtin_types[(int) ARG1],              \
> -                                NULL_TREE);
> -#define DEF_FUNCTION_TYPE_2(ENUM, RETURN, ARG1, ARG2)           \
> -  builtin_types[(int) ENUM]                                     \
> -    = build_function_type_list (builtin_types[(int) RETURN],    \
> -                                builtin_types[(int) ARG1],      \
> -                                builtin_types[(int) ARG2],      \
> -                                NULL_TREE);
> -#define DEF_FUNCTION_TYPE_3(ENUM, RETURN, ARG1, ARG2, ARG3)             \
> -  builtin_types[(int) ENUM]                                             \
> -    = build_function_type_list (builtin_types[(int) RETURN],            \
> -                                builtin_types[(int) ARG1],              \
> -                                builtin_types[(int) ARG2],              \
> -                                builtin_types[(int) ARG3],              \
> -                                NULL_TREE);
> -#define DEF_FUNCTION_TYPE_4(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4)      \
> -  builtin_types[(int) ENUM]                                            \
> -    = build_function_type_list (builtin_types[(int) RETURN],            \
> -                                builtin_types[(int) ARG1],              \
> -                                builtin_types[(int) ARG2],              \
> -                                builtin_types[(int) ARG3],             \
> -                                builtin_types[(int) ARG4],              \
> -                                NULL_TREE);
> +#define DEF_FUNCTION_TYPE_0(ENUM, RETURN) \
> +  define_builtin_function_type (builtin_types, (int) ENUM, (int) RETURN, 
> false, 0);
> +#define DEF_FUNCTION_TYPE_1(ENUM, RETURN, ARG1) \
> +  define_builtin_function_type (builtin_types, (int) ENUM, (int) RETURN, 
> false, 1, (int) ARG1);
> +#define DEF_FUNCTION_TYPE_2(ENUM, RETURN, ARG1, ARG2) \
> +  define_builtin_function_type (builtin_types, (int) ENUM, (int) RETURN, 
> false, 2, (int) ARG1, (int) ARG2);
> +#define DEF_FUNCTION_TYPE_3(ENUM, RETURN, ARG1, ARG2, ARG3) \
> +  define_builtin_function_type (builtin_types, (int) ENUM, (int) RETURN, 
> false, 3, (int) ARG1, (int) ARG2, (int) ARG3);
> +#define DEF_FUNCTION_TYPE_4(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4) \
> +  define_builtin_function_type (builtin_types, (int) ENUM, (int) RETURN, 
> false, 4, (int) ARG1, (int) ARG2, (int) ARG3, (int) ARG4);
>  #define DEF_FUNCTION_TYPE_5(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5)      
>   \
> -  builtin_types[(int) ENUM]                                            \
> -    = build_function_type_list (builtin_types[(int) RETURN],            \
> -                                builtin_types[(int) ARG1],              \
> -                                builtin_types[(int) ARG2],              \
> -                                builtin_types[(int) ARG3],             \
> -                                builtin_types[(int) ARG4],              \
> -                                builtin_types[(int) ARG5],              \
> -                                NULL_TREE);
> +  define_builtin_function_type (builtin_types, (int) ENUM, (int) RETURN, 
> false, 5, (int) ARG1, (int) ARG2, (int) ARG3, (int) ARG4, (int) ARG5);
>  #define DEF_FUNCTION_TYPE_6(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \
>                            ARG6)                                       \
> -  builtin_types[(int) ENUM]                                            \
> -    = build_function_type_list (builtin_types[(int) RETURN],            \
> -                                builtin_types[(int) ARG1],              \
> -                                builtin_types[(int) ARG2],              \
> -                                builtin_types[(int) ARG3],             \
> -                                builtin_types[(int) ARG4],             \
> -                                builtin_types[(int) ARG5],              \
> -                                builtin_types[(int) ARG6],              \
> -                                NULL_TREE);
> +  define_builtin_function_type (builtin_types, (int) ENUM, (int) RETURN, 
> false, 6, (int) ARG1, (int) ARG2, (int) ARG3, (int) ARG4, (int) ARG5, (int) 
> ARG6);
>  #define DEF_FUNCTION_TYPE_7(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \
>                            ARG6, ARG7)                                 \
> -  builtin_types[(int) ENUM]                                            \
> -    = build_function_type_list (builtin_types[(int) RETURN],            \
> -                                builtin_types[(int) ARG1],              \
> -                                builtin_types[(int) ARG2],              \
> -                                builtin_types[(int) ARG3],             \
> -                                builtin_types[(int) ARG4],             \
> -                                builtin_types[(int) ARG5],              \
> -                                builtin_types[(int) ARG6],              \
> -                                builtin_types[(int) ARG7],              \
> -                                NULL_TREE);
> -#define DEF_FUNCTION_TYPE_VAR_0(ENUM, RETURN)                          \
> -  builtin_types[(int) ENUM]                                            \
> -    = build_varargs_function_type_list (builtin_types[(int) RETURN],    \
> -                                        NULL_TREE);
> +  define_builtin_function_type (builtin_types, (int) ENUM, (int) RETURN, 
> false, 7, (int) ARG1, (int) ARG2, (int) ARG3, (int) ARG4, (int) ARG5, (int) 
> ARG6, (int) ARG7);
> +#define DEF_FUNCTION_TYPE_VAR_0(ENUM, RETURN) \
> +  define_builtin_function_type (builtin_types, (int) ENUM, (int) RETURN, 
> true, 0);
>  #define DEF_POINTER_TYPE(ENUM, TYPE)                   \
>   builtin_types[(int) ENUM]                            \
>     = build_pointer_type (builtin_types[(int) TYPE]);
> diff --git a/gcc/lto/lto-lang.c b/gcc/lto/lto-lang.c
> index c65d916..de2eb19 100644
> --- a/gcc/lto/lto-lang.c
> +++ b/gcc/lto/lto-lang.c
> @@ -428,40 +428,6 @@ handle_format_arg_attribute (tree * ARG_UNUSED (node), 
> tree ARG_UNUSED (name),
>  }
>
>
> -/* Cribbed from c-common.c.  */
> -
> -static void
> -def_fn_type (builtin_type def, builtin_type ret, bool var, int n, ...)
> -{
> -  tree args = NULL, t;
> -  va_list list;
> -  int i;
> -
> -  va_start (list, n);
> -  for (i = 0; i < n; ++i)
> -    {
> -      builtin_type a = (builtin_type) va_arg (list, int);
> -      t = builtin_types[a];
> -      if (t == error_mark_node)
> -       goto egress;
> -      args = tree_cons (NULL_TREE, t, args);
> -    }
> -  va_end (list);
> -
> -  args = nreverse (args);
> -  if (!var)
> -    args = chainon (args, void_list_node);
> -
> -  t = builtin_types[ret];
> -  if (t == error_mark_node)
> -    goto egress;
> -  t = build_function_type (t, args);
> -
> - egress:
> -  builtin_types[def] = t;
> -  va_end (list);
> -}
> -
>  /* Used to help initialize the builtin-types.def table.  When a type of
>    the correct size doesn't exist, use error_mark_node instead of NULL.
>    The later results in segfaults even when a decl using the type doesn't
> @@ -539,35 +505,35 @@ lto_define_builtins (tree va_list_ref_type_node 
> ATTRIBUTE_UNUSED,
>  #define DEF_PRIMITIVE_TYPE(ENUM, VALUE) \
>   builtin_types[ENUM] = VALUE;
>  #define DEF_FUNCTION_TYPE_0(ENUM, RETURN) \
> -  def_fn_type (ENUM, RETURN, 0, 0);
> +  define_builtin_function_type (builtin_types, (int) ENUM, (int) RETURN, 
> false, 0);
>  #define DEF_FUNCTION_TYPE_1(ENUM, RETURN, ARG1) \
> -  def_fn_type (ENUM, RETURN, 0, 1, ARG1);
> +  define_builtin_function_type (builtin_types, (int) ENUM, (int) RETURN, 
> false, 1, (int) ARG1);
>  #define DEF_FUNCTION_TYPE_2(ENUM, RETURN, ARG1, ARG2) \
> -  def_fn_type (ENUM, RETURN, 0, 2, ARG1, ARG2);
> +  define_builtin_function_type (builtin_types, (int) ENUM, (int) RETURN, 
> false, 2, (int) ARG1, (int) ARG2);
>  #define DEF_FUNCTION_TYPE_3(ENUM, RETURN, ARG1, ARG2, ARG3) \
> -  def_fn_type (ENUM, RETURN, 0, 3, ARG1, ARG2, ARG3);
> +  define_builtin_function_type (builtin_types, (int) ENUM, (int) RETURN, 
> false, 3, (int) ARG1, (int) ARG2, (int) ARG3);
>  #define DEF_FUNCTION_TYPE_4(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4) \
> -  def_fn_type (ENUM, RETURN, 0, 4, ARG1, ARG2, ARG3, ARG4);
> +  define_builtin_function_type (builtin_types, (int) ENUM, (int) RETURN, 
> false, 4, (int) ARG1, (int) ARG2, (int) ARG3, (int) ARG4);
>  #define DEF_FUNCTION_TYPE_5(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5)      
>   \
> -  def_fn_type (ENUM, RETURN, 0, 5, ARG1, ARG2, ARG3, ARG4, ARG5);
> +  define_builtin_function_type (builtin_types, (int) ENUM, (int) RETURN, 
> false, 5, (int) ARG1, (int) ARG2, (int) ARG3, (int) ARG4, (int) ARG5);
>  #define DEF_FUNCTION_TYPE_6(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \
>                            ARG6)                                       \
> -  def_fn_type (ENUM, RETURN, 0, 6, ARG1, ARG2, ARG3, ARG4, ARG5, ARG6);
> +  define_builtin_function_type (builtin_types, (int) ENUM, (int) RETURN, 
> false, 6, (int) ARG1, (int) ARG2, (int) ARG3, (int) ARG4, (int) ARG5, (int) 
> ARG6);
>  #define DEF_FUNCTION_TYPE_7(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \
>                            ARG6, ARG7)                                 \
> -  def_fn_type (ENUM, RETURN, 0, 7, ARG1, ARG2, ARG3, ARG4, ARG5, ARG6, ARG7);
> +  define_builtin_function_type (builtin_types, (int) ENUM, (int) RETURN, 
> false, 7, (int) ARG1, (int) ARG2, (int) ARG3, (int) ARG4, (int) ARG5, (int) 
> ARG6, (int) ARG7);
>  #define DEF_FUNCTION_TYPE_VAR_0(ENUM, RETURN) \
> -  def_fn_type (ENUM, RETURN, 1, 0);
> +  define_builtin_function_type (builtin_types, (int) ENUM, (int) RETURN, 
> true, 0);
>  #define DEF_FUNCTION_TYPE_VAR_1(ENUM, RETURN, ARG1) \
> -  def_fn_type (ENUM, RETURN, 1, 1, ARG1);
> +  define_builtin_function_type (builtin_types, (int) ENUM, (int) RETURN, 
> true, 1, (int) ARG1);
>  #define DEF_FUNCTION_TYPE_VAR_2(ENUM, RETURN, ARG1, ARG2) \
> -  def_fn_type (ENUM, RETURN, 1, 2, ARG1, ARG2);
> +  define_builtin_function_type (builtin_types, (int) ENUM, (int) RETURN, 
> true, 2, (int) ARG1, (int) ARG2);
>  #define DEF_FUNCTION_TYPE_VAR_3(ENUM, RETURN, ARG1, ARG2, ARG3) \
> -  def_fn_type (ENUM, RETURN, 1, 3, ARG1, ARG2, ARG3);
> +  define_builtin_function_type (builtin_types, (int) ENUM, (int) RETURN, 
> true, 3, (int) ARG1, (int) ARG2, (int) ARG3);
>  #define DEF_FUNCTION_TYPE_VAR_4(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4) \
> -  def_fn_type (ENUM, RETURN, 1, 4, ARG1, ARG2, ARG3, ARG4);
> +  define_builtin_function_type (builtin_types, (int) ENUM, (int) RETURN, 
> true, 4, (int) ARG1, (int) ARG2, (int) ARG3, (int) ARG4);
>  #define DEF_FUNCTION_TYPE_VAR_5(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5) \
> -  def_fn_type (ENUM, RETURN, 1, 5, ARG1, ARG2, ARG3, ARG4, ARG5);
> +  define_builtin_function_type (builtin_types, (int) ENUM, (int) RETURN, 
> true, 5, (int) ARG1, (int) ARG2, (int) ARG3, (int) ARG4, (int) ARG5);
>  #define DEF_POINTER_TYPE(ENUM, TYPE) \
>   builtin_types[(int) ENUM] = build_pointer_type (builtin_types[(int) TYPE]);
>
> diff --git a/gcc/tree.c b/gcc/tree.c
> index d0c18b1..008e6f7 100644
> --- a/gcc/tree.c
> +++ b/gcc/tree.c
> @@ -7631,6 +7631,79 @@ build_varargs_function_type_list (tree return_type, 
> ...)
>   return args;
>  }
>
> +/* Build a function type.  RETURN_TYPE is the type returned by the
> +   function; VAARGS indicates whether the function takes varargs.  The
> +   function takes N named arguments, the types of which are provided in
> +   ARG_TYPES.  */
> +
> +static tree
> +build_function_type_array_1 (bool vaargs, tree return_type, int n,
> +                            tree *arg_types)
> +{
> +  int i;
> +  tree t = vaargs ? NULL_TREE : void_list_node;
> +
> +  for (i = n - 1; i >= 0; i--)
> +    t = tree_cons (NULL_TREE, arg_types[i], t);
> +
> +  return build_function_type (return_type, t);
> +}
> +
> +/* Build a function type.  RETURN_TYPE is the type returned by the
> +   function.  The function takes N named arguments, the types of which
> +   are provided in ARG_TYPES.  */
> +
> +tree
> +build_function_type_array (tree return_type, int n, tree *arg_types)
> +{
> +  return build_function_type_array_1 (false, return_type, n, arg_types);
> +}
> +
> +/* Build a variable argument function type.  RETURN_TYPE is the type
> +   returned by the function.  The function takes N named arguments, the
> +   types of which are provided in ARG_TYPES.  */
> +
> +tree
> +build_varargs_function_type_array (tree return_type, int n, tree *arg_types)
> +{
> +  return build_function_type_array_1 (true, return_type, n, arg_types);
> +}
> +
> +/* Build a function type and store it in BUILTIN_TYPES at FNTYPE_IDX.
> +   RETURN_TYPE_IDX is the index of the return type of the function in
> +   BUILTIN_TYPES.  VAARGS indicates whether the function takes varargs.
> +   The function takes N named arguments, of which indices into
> +   BUILTIN_TYPES are provided as varargs.  */
> +
> +void
> +define_builtin_function_type (tree *builtin_types, int fntype_idx,
> +                             int return_type_idx, bool vaargs,
> +                             int n, ...)
> +{
> +  int i;
> +  va_list list;
> +  tree t, *arg_types = XALLOCAVEC (tree, n);
> +
> +  va_start (list, n);
> +  for (i = 0; i < n; i++)
> +    {
> +      int arg_type_idx = va_arg (list, int);
> +      t = builtin_types[arg_type_idx];
> +      if (t == error_mark_node)
> +       goto egress;
> +      arg_types[i] = t;
> +    }
> +
> +  t = builtin_types[return_type_idx];
> +  if (t == error_mark_node)
> +    goto egress;
> +  t = build_function_type_array_1 (vaargs, t, n, arg_types);
> +
> + egress:
> +  builtin_types[fntype_idx] = t;
> +  va_end (list);
> +}
> +
>  /* Build a METHOD_TYPE for a member of BASETYPE.  The RETTYPE (a TYPE)
>    and ARGTYPES (a TREE_LIST) are the return type and arguments types
>    for the method.  An implicit additional parameter (of type
> diff --git a/gcc/tree.h b/gcc/tree.h
> index 0bc98cd..0e231e9 100644
> --- a/gcc/tree.h
> +++ b/gcc/tree.h
> @@ -4252,6 +4252,9 @@ extern tree build_function_type_list (tree, ...);
>  extern tree build_function_type_skip_args (tree, bitmap);
>  extern tree build_function_decl_skip_args (tree, bitmap);
>  extern tree build_varargs_function_type_list (tree, ...);
> +extern tree build_function_type_array (tree, int, tree *);
> +extern tree build_varargs_function_type_array (tree, int, tree *);
> +extern void define_builtin_function_type (tree *, int, int, bool, int, ...);
>  extern tree build_method_type_directly (tree, tree, tree);
>  extern tree build_method_type (tree, tree);
>  extern tree build_offset_type (tree, tree);
>

Reply via email to