From: Nathan Sidwell Date: Tue, 31 Oct 2017 20:08:51 +0000 (+0000) Subject: [C++ PATCH] overloaded operator fns [5/N] X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=881c969cf6797917ad69ea7bf4c47888890125ff;p=gcc.git [C++ PATCH] overloaded operator fns [5/N] https://gcc.gnu.org/ml/gcc-patches/2017-10/ * 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. From-SVN: r254279 --- diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index edc806edf8e..191fa111f6a 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,5 +1,18 @@ 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. + * lex.c (init_operators): Allow NULL operator name. Don't add special cases. * operators.def: Use NULL for mangling only operators. Move to diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index c74a1860ec4..257c8776f0e 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -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. */ diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index 82d9326ac5b..d60b8dd775a 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -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 complain) 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 complain) } } - 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 complain) } } - /* 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) diff --git a/gcc/cp/lex.c b/gcc/cp/lex.c index fed44a16429..af081f4d024 100644 --- a/gcc/cp/lex.c +++ b/gcc/cp/lex.c @@ -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_identifier_kind kind) 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); \ diff --git a/gcc/cp/mangle.c b/gcc/cp/mangle.c index b745576cd33..7feb889e9aa 100644 --- a/gcc/cp/mangle.c +++ b/gcc/cp/mangle.c @@ -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))