From patchwork Thu Apr 21 15:04:47 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Nathan Froyd X-Patchwork-Id: 92421 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) by ozlabs.org (Postfix) with SMTP id 01C67B7022 for ; Fri, 22 Apr 2011 01:05:26 +1000 (EST) Received: (qmail 9043 invoked by alias); 21 Apr 2011 15:05:23 -0000 Received: (qmail 9015 invoked by uid 22791); 21 Apr 2011 15:05:18 -0000 X-SWARE-Spam-Status: No, hits=-1.7 required=5.0 tests=AWL, BAYES_00, T_RP_MATCHES_RCVD X-Spam-Check-By: sourceware.org Received: from mail.codesourcery.com (HELO mail.codesourcery.com) (38.113.113.100) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Thu, 21 Apr 2011 15:05:00 +0000 Received: (qmail 12343 invoked from network); 21 Apr 2011 15:04:56 -0000 Received: from unknown (HELO codesourcery.com) (froydnj@127.0.0.2) by mail.codesourcery.com with ESMTPA; 21 Apr 2011 15:04:56 -0000 Date: Thu, 21 Apr 2011 11:04:47 -0400 From: Nathan Froyd To: gcc-patches@gcc.gnu.org Subject: [PATCH] centralize builtin function type building Message-ID: <20110421150445.GA2039@nightcrawler> MIME-Version: 1.0 Content-Disposition: inline User-Agent: Mutt/1.5.20 (2009-06-14) X-IsSubscribed: yes Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@gcc.gnu.org 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. 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);