Message ID | 20110421150445.GA2039@nightcrawler |
---|---|
State | New |
Headers | show |
On Thu, Apr 21, 2011 at 5:04 PM, Nathan Froyd <froydnj@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); >
On Thu, Apr 21, 2011 at 05:36:42PM +0200, Richard Guenther wrote: > On Thu, Apr 21, 2011 at 5:04 PM, Nathan Froyd <froydnj@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 ... I agree that it is desirable that the backend builtin index not overlap with the standard builtin index (and front end builtin index). I was starting to look at this, when I learned Kenneth Zadeck was working on a more comprehensive solution for backend builtin types. Obviously all 3 of our efforts should be merged into one goal.
On Thu, Apr 21, 2011 at 05:36:42PM +0200, Richard Guenther wrote: > On Thu, Apr 21, 2011 at 5:04 PM, Nathan Froyd <froydnj@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. > > > > 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 ... I agree that it would be better to have a central middle-end place for this; I'm not entirely sure why Fortran opts to use a separate set of types; AFAICS, it's a strict subset. Fortran folks...? The question of decls is something different and unrelated to this patch, IMHO. Is the patch OK as-is, or should I work on merging the types into the middle-end in addition? -Nathan
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);