From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 58501 invoked by alias); 31 Oct 2017 20:08:18 -0000 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Received: (qmail 58488 invoked by uid 89); 31 Oct 2017 20:08:17 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-10.6 required=5.0 tests=BAYES_00,FREEMAIL_FROM,GIT_PATCH_2,GIT_PATCH_3,KAM_ASCII_DIVIDERS,RCVD_IN_DNSWL_NONE,RCVD_IN_SORBS_SPAM,SPF_PASS autolearn=ham version=3.3.2 spammy= X-HELO: mail-yw0-f181.google.com Received: from mail-yw0-f181.google.com (HELO mail-yw0-f181.google.com) (209.85.161.181) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Tue, 31 Oct 2017 20:08:15 +0000 Received: by mail-yw0-f181.google.com with SMTP id t71so167108ywc.3 for ; Tue, 31 Oct 2017 13:08:15 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:sender:subject:from:to:references:message-id :date:user-agent:mime-version:in-reply-to:content-language; bh=qs5pu9Mf9I7GQV5H08w8OHynVA9J/YMrT4BAdgMpEuc=; b=IU/G1Wh6Vy9CdgxsAb+BzhixuC7n+lTtp9WKp6vhObkH9+NXZPqonAUTqIYE9KeyPV qnodzd4wtDolcRK+lPgWsUT3qBVyqHCac2w4w2dNhpELSSTztxx06kG0UI48WOpy/xC0 Tmyoz/gzAVcrCeE5p/8pnwGWDmYECqYCwZaa5r0DTI16CguHdqSieob/XUjWpxw2yTBv YygWyDfdme+Y6REhRixREoDIZo4U7+ie/LGk2XFGXVEczBPTxTHnZOaIFlXTAOdOpHM+ iKiiPbX45+zzNczKB1SgWpgBkgAd/J7hocp6qwbjUZPrvRg2gNBMYpoEgSHEc8Dn4piC uJng== X-Gm-Message-State: AMCzsaV4hHBjj+I5bjMgICs7f47EQTgcZA5t9HBWqHnN227E/+AEPnrr olw2DW72Uo9An3jpv+G7vyA= X-Google-Smtp-Source: ABhQp+QASye+ivZ2R8BRJ+oz4YhlaWSLV/euHWocwJ8gibTeN8PJ8bTGVgXA7d6KkkgseeR2+qXC2w== X-Received: by 10.37.209.78 with SMTP id i75mr2177750ybg.75.1509480493795; Tue, 31 Oct 2017 13:08:13 -0700 (PDT) Received: from ?IPv6:2620:10d:c0a3:20fb:7500:e7fb:4a6f:2254? ([2620:10d:c091:200::3:68fe]) by smtp.googlemail.com with ESMTPSA id w199sm991883yww.10.2017.10.31.13.08.12 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 31 Oct 2017 13:08:12 -0700 (PDT) Subject: [C++ PATCH] overloaded operator fns [5/N] From: Nathan Sidwell To: GCC Patches References: <40b48778-5335-2398-3dd5-e59f68b8f052@acm.org> <006c8467-dde6-1605-243c-f8d033ab4e49@acm.org> Message-ID: Date: Tue, 31 Oct 2017 20:20:00 -0000 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:52.0) Gecko/20100101 Thunderbird/52.4.0 MIME-Version: 1.0 In-Reply-To: <006c8467-dde6-1605-243c-f8d033ab4e49@acm.org> Content-Type: multipart/mixed; boundary="------------3E2A2E6CEFEF5E7AA6A3C4C5" X-SW-Source: 2017-10/txt/msg02369.txt.bz2 This is a multi-part message in MIME format. --------------3E2A2E6CEFEF5E7AA6A3C4C5 Content-Type: text/plain; charset=utf-8; format=flowed Content-Transfer-Encoding: 7bit Content-length: 496 This patch replaces the separate operator_name_info & assignment_operator_name_info arrays with a single 2D ovl_op_info array. I also add a tree_code field to the renamed ovl_op_info_t, which although in this instance is simply a 1:1 mapping to the array index, will morph soon as the indices will not be by tree_code. Although this tweaks the array scanning, the ultimate aim is that that scanning goes away, and a simple indirection gets us to what we want. nathan -- Nathan Sidwell --------------3E2A2E6CEFEF5E7AA6A3C4C5 Content-Type: text/x-patch; name="op-ident-5.diff" Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename="op-ident-5.diff" Content-length: 8787 2017-10-31 Nathan Sidwell * cp-tree.h (struct operator_name_info_t): Rename to ... (struct ovl_op_info_t): ... here. Add tree_code field. (operator_name_info, assignment_operator_name_info): Delete. (ovl_op_info): Declare. (OVL_OP_INFO): Adjust. * decl.c (grok_op_properties): Use ovl_op_flags. * lex.c (operator_name_info, assignment_operator_name_info): Delete. (ovl_op_info): Define. (set_operator_ident): Adjust. (init_operators): Set tree_code. * mangle.c (write_unqualified_id): Adjust operator array scan. Index: cp-tree.h =================================================================== --- cp-tree.h (revision 254271) +++ cp-tree.h (working copy) @@ -5485,29 +5485,26 @@ enum ovl_op_flags OVL_OP_FLAG_VEC = 2 /* vector new or delete */ }; -struct GTY(()) operator_name_info_t { +struct GTY(()) ovl_op_info_t { /* The IDENTIFIER_NODE for the operator. */ tree identifier; /* The name of the operator. */ const char *name; /* The mangled name of the operator. */ const char *mangled_name; + /* The tree code. */ + enum tree_code tree_code : 16; /* The ovl_op_flags of the operator */ unsigned flags : 8; }; -/* A mapping from tree codes to operator name information. */ -extern GTY(()) operator_name_info_t operator_name_info - [(int) MAX_TREE_CODES]; -/* Similar, but for assignment operators. */ -extern GTY(()) operator_name_info_t assignment_operator_name_info - [(int) MAX_TREE_CODES]; +/* Overloaded operator info indexed by ass_op_p & tree_code. */ +extern GTY(()) ovl_op_info_t ovl_op_info[2][MAX_TREE_CODES]; /* Given an ass_op_p boolean and a tree code, return a pointer to its overloaded operator info. */ #define OVL_OP_INFO(IS_ASS_P, TREE_CODE) \ - (((IS_ASS_P) ? assignment_operator_name_info : operator_name_info) \ - + (TREE_CODE)) + (&ovl_op_info[(IS_ASS_P) != 0][(TREE_CODE)]) /* A type-qualifier, or bitmask therefore, using the TYPE_QUAL constants. */ Index: decl.c =================================================================== --- decl.c (revision 254267) +++ decl.c (working copy) @@ -12898,8 +12898,8 @@ unary_op_p (enum tree_code code) || code == TYPE_EXPR); } -/* DECL is a declaration for an overloaded operator. If COMPLAIN is true, - errors are issued for invalid declarations. */ +/* DECL is a declaration for an overloaded or conversion operator. If + COMPLAIN is true, errors are issued for invalid declarations. */ bool grok_op_properties (tree decl, bool complain) @@ -12912,52 +12912,54 @@ grok_op_properties (tree decl, bool comp if (class_type && !CLASS_TYPE_P (class_type)) class_type = NULL_TREE; - enum tree_code operator_code = ERROR_MARK; + tree_code operator_code = ERROR_MARK; + unsigned op_flags = OVL_OP_FLAG_NONE; if (IDENTIFIER_CONV_OP_P (name)) - operator_code = TYPE_EXPR; + { + /* Conversion operators are TYPE_EXPR for the purposes of this + function. */ + operator_code = TYPE_EXPR; + op_flags = OVL_OP_FLAG_UNARY; + } else { /* It'd be nice to hang something else of the identifier to find CODE more directly. */ bool assign_op = IDENTIFIER_ASSIGN_OP_P (name); - const operator_name_info_t *oni - = (assign_op ? assignment_operator_name_info : operator_name_info); - + const ovl_op_info_t *ovl_op = OVL_OP_INFO (assign_op, 0); if (false) ; -#define DEF_OPERATOR(NAME, CODE, MANGLING, ARITY, KIND) \ - else if (assign_op == (KIND == cik_assign_op) \ - && oni[int (CODE)].identifier == name) \ +#define DEF_OPERATOR(NAME, CODE, MANGLING, FLAGS, KIND) \ + else if (ovl_op[CODE].identifier == name) \ operator_code = (CODE); #include "operators.def" #undef DEF_OPERATOR else gcc_unreachable (); - } - while (0); - gcc_assert (operator_code != MAX_TREE_CODES); - DECL_OVERLOADED_OPERATOR_CODE (decl) = operator_code; + gcc_assert (operator_code != ERROR_MARK); + op_flags = ovl_op[operator_code].flags; + DECL_OVERLOADED_OPERATOR_CODE (decl) = operator_code; + } - if (operator_code == NEW_EXPR || operator_code == VEC_NEW_EXPR - || operator_code == DELETE_EXPR || operator_code == VEC_DELETE_EXPR) + if (op_flags & OVL_OP_FLAG_ALLOC) { /* operator new and operator delete are quite special. */ if (class_type) - switch (operator_code) + switch (op_flags) { - case NEW_EXPR: + case OVL_OP_FLAG_ALLOC: TYPE_HAS_NEW_OPERATOR (class_type) = 1; break; - case DELETE_EXPR: + case OVL_OP_FLAG_ALLOC | OVL_OP_FLAG_DELETE: TYPE_GETS_DELETE (class_type) |= 1; break; - case VEC_NEW_EXPR: + case OVL_OP_FLAG_ALLOC | OVL_OP_FLAG_VEC: TYPE_HAS_ARRAY_NEW_OPERATOR (class_type) = 1; break; - case VEC_DELETE_EXPR: + case OVL_OP_FLAG_ALLOC | OVL_OP_FLAG_DELETE | OVL_OP_FLAG_VEC: TYPE_GETS_DELETE (class_type) |= 2; break; @@ -12987,12 +12989,12 @@ grok_op_properties (tree decl, bool comp } } - if (operator_code == DELETE_EXPR || operator_code == VEC_DELETE_EXPR) + if (op_flags & OVL_OP_FLAG_DELETE) TREE_TYPE (decl) = coerce_delete_type (TREE_TYPE (decl)); else { - TREE_TYPE (decl) = coerce_new_type (TREE_TYPE (decl)); DECL_IS_OPERATOR_NEW (decl) = 1; + TREE_TYPE (decl) = coerce_new_type (TREE_TYPE (decl)); } return true; @@ -13043,9 +13045,9 @@ grok_op_properties (tree decl, bool comp } } - /* There are no restrictions on the arguments to an overloaded - "operator ()". */ if (operator_code == CALL_EXPR) + /* There are no further restrictions on the arguments to an overloaded + "operator ()". */ return true; if (operator_code == COND_EXPR) Index: lex.c =================================================================== --- lex.c (revision 254276) +++ lex.c (working copy) @@ -77,10 +77,7 @@ cxx_finish (void) c_common_finish (); } -/* A mapping from tree codes to operator name information. */ -operator_name_info_t operator_name_info[(int) MAX_TREE_CODES]; -/* Similar, but for assignment operators. */ -operator_name_info_t assignment_operator_name_info[(int) MAX_TREE_CODES]; +ovl_op_info_t ovl_op_info[2][MAX_TREE_CODES]; /* Get the name of the kind of identifier T. */ @@ -117,7 +114,7 @@ set_identifier_kind (tree id, cp_identif operator PTR describes. */ static tree -set_operator_ident (operator_name_info_t *ptr) +set_operator_ident (ovl_op_info_t *ptr) { char buffer[32]; size_t len = snprintf (buffer, sizeof (buffer), "operator%s%s", @@ -136,12 +133,13 @@ static void init_operators (void) { tree identifier; - operator_name_info_t *oni; + ovl_op_info_t *oni; #define DEF_OPERATOR(NAME, CODE, MANGLING, FLAGS, KIND) \ oni = OVL_OP_INFO (KIND == cik_assign_op, CODE); \ oni->name = NAME; \ oni->mangled_name = MANGLING; \ + oni->tree_code = CODE; \ oni->flags = FLAGS; \ if (NAME) { \ identifier = set_operator_ident (oni); \ Index: mangle.c =================================================================== --- mangle.c (revision 254271) +++ mangle.c (working copy) @@ -1265,32 +1265,29 @@ write_unqualified_id (tree identifier) write_conversion_operator_name (TREE_TYPE (identifier)); else if (IDENTIFIER_ANY_OP_P (identifier)) { - int i; const char *mangled_name = NULL; + bool assop = IDENTIFIER_ASSIGN_OP_P (identifier); /* Unfortunately, there is no easy way to go from the name of the operator back to the corresponding tree code. */ - for (i = 0; i < MAX_TREE_CODES; ++i) - if (operator_name_info[i].identifier == identifier) - { - /* The ABI says that we prefer binary operator - names to unary operator names. */ - if (operator_name_info[i].flags == OVL_OP_FLAG_BINARY) - { - mangled_name = operator_name_info[i].mangled_name; - break; - } - else if (!mangled_name) - mangled_name = operator_name_info[i].mangled_name; - } - else if (assignment_operator_name_info[i].identifier - == identifier) - { - mangled_name - = assignment_operator_name_info[i].mangled_name; - break; - } + for (unsigned i = 0; i < MAX_TREE_CODES; ++i) + { + const ovl_op_info_t *ovl_op = OVL_OP_INFO (assop, i); + + if (ovl_op->identifier == identifier) + { + /* The ABI says that we prefer binary operator + names to unary operator names. */ + if (ovl_op->flags == OVL_OP_FLAG_BINARY) + { + mangled_name = ovl_op->mangled_name; + break; + } + else if (!mangled_name) + mangled_name = ovl_op->mangled_name; + } + } write_string (mangled_name); } else if (UDLIT_OPER_P (identifier)) --------------3E2A2E6CEFEF5E7AA6A3C4C5--