diff options
author | Nathan Sidwell <nathan@acm.org> | 2017-11-01 14:03:27 +0000 |
---|---|---|
committer | Nathan Sidwell <nathan@gcc.gnu.org> | 2017-11-01 14:03:27 +0000 |
commit | d6dd9d7f8efcf92c5c70a9e91e99a9719b31cd51 (patch) | |
tree | 46fe2615cfcde921d2e8142f94bf117cca7fcf43 /gcc/cp/lex.c | |
parent | 0299d48bad088eccb76cf71de064dbc047b8cf62 (diff) | |
download | gcc-d6dd9d7f8efcf92c5c70a9e91e99a9719b31cd51.zip gcc-d6dd9d7f8efcf92c5c70a9e91e99a9719b31cd51.tar.gz gcc-d6dd9d7f8efcf92c5c70a9e91e99a9719b31cd51.tar.bz2 |
[C++ PATCH] overloaded operator fns [6/N]
https://gcc.gnu.org/ml/gcc-patches/2017-11/msg00018.html
* cp-tree.h (IDENTIFIER_CP_INDEX): Define.
(enum ovl_op_flags): Add OVL_OP_FLAG_AMBIARY.
(enum ovl_op_code): New.
(struct ovl_op_info): Add ovl_op_code field.
(ovl_op_info): Size by OVL_OP_MAX.
(ovl_op_mapping, ovl_op_alternate): Declare.
(OVL_OP_INFO): Adjust for mapping array.
(IDENTIFIER_OVL_OP_INFO): New.
* decl.c (ambi_op_p, unary_op_p): Delete.
(grok_op_properties): Use IDENTIFIER_OVL_OP_INFO and
ovl_op_alternate.
* lex.c (ovl_op_info): Adjust and static initialize.
(ovl_op_mappings, ovl_op_alternate): Define.
(init_operators): Iterate over ovl_op_info array and init mappings
& alternate arrays.
* mangle.c (write_unqualified_id): Use IDENTIFIER_OVL_OP_INFO.
* operators.def (DEF_OPERATOR): Remove KIND parm.
(DEF_SIMPLE_OPERATOR): Delete.
(OPERATOR_TRANSITION): Expand if defined.
From-SVN: r254310
Diffstat (limited to 'gcc/cp/lex.c')
-rw-r--r-- | gcc/cp/lex.c | 98 |
1 files changed, 81 insertions, 17 deletions
diff --git a/gcc/cp/lex.c b/gcc/cp/lex.c index af081f4..7754145 100644 --- a/gcc/cp/lex.c +++ b/gcc/cp/lex.c @@ -77,7 +77,20 @@ cxx_finish (void) c_common_finish (); } -ovl_op_info_t ovl_op_info[2][MAX_TREE_CODES]; +ovl_op_info_t ovl_op_info[2][OVL_OP_MAX] = + { + { + {NULL_TREE, NULL, NULL, ERROR_MARK, OVL_OP_ERROR_MARK, 0}, + {NULL_TREE, NULL, NULL, NOP_EXPR, OVL_OP_NOP_EXPR, 0}, +#define DEF_OPERATOR(NAME, CODE, MANGLING, FLAGS) \ + {NULL_TREE, NAME, MANGLING, CODE, OVL_OP_##CODE, FLAGS}, +#define OPERATOR_TRANSITION }, { \ + {NULL_TREE, NULL, NULL, ERROR_MARK, OVL_OP_ERROR_MARK, 0}, +#include "operators.def" + } + }; +unsigned char ovl_op_mapping[MAX_TREE_CODES]; +unsigned char ovl_op_alternate[OVL_OP_MAX]; /* Get the name of the kind of identifier T. */ @@ -129,26 +142,77 @@ set_operator_ident (ovl_op_info_t *ptr) return ident; } +/* Initialize data structures that keep track of operator names. */ + static void init_operators (void) { - tree identifier; - 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); \ - if (KIND != cik_simple_op || !IDENTIFIER_ANY_OP_P (identifier)) \ - set_identifier_kind (identifier, KIND); \ - } + /* We rely on both these being zero. */ + gcc_checking_assert (!OVL_OP_ERROR_MARK && !ERROR_MARK); -#include "operators.def" -#undef DEF_OPERATOR + /* This loop iterates backwards because we need to move the + assignment operators down to their correct slots. I.e. morally + equivalent to an overlapping memmove where dest > src. Slot + zero is for error_mark, so hae no operator. */ + for (unsigned ix = OVL_OP_MAX; --ix;) + { + ovl_op_info_t *op_ptr = &ovl_op_info[false][ix]; + + if (op_ptr->name) + { + /* Make sure it fits in lang_decl_fn::operator_code. */ + gcc_checking_assert (op_ptr->ovl_op_code < (1 << 6)); + tree ident = set_operator_ident (op_ptr); + if (unsigned index = IDENTIFIER_CP_INDEX (ident)) + { + ovl_op_info_t *bin_ptr = &ovl_op_info[false][index]; + + /* They should only differ in unary/binary ness. */ + gcc_checking_assert ((op_ptr->flags ^ bin_ptr->flags) + == OVL_OP_FLAG_AMBIARY); + bin_ptr->flags |= op_ptr->flags; + ovl_op_alternate[index] = ix; + } + else + { + IDENTIFIER_CP_INDEX (ident) = ix; + set_identifier_kind (ident, + op_ptr->flags & OVL_OP_FLAG_ALLOC + ? cik_newdel_op : cik_simple_op); + } + } + if (op_ptr->tree_code) + { + gcc_checking_assert (op_ptr->ovl_op_code == ix + && !ovl_op_mapping[op_ptr->tree_code]); + ovl_op_mapping[op_ptr->tree_code] = op_ptr->ovl_op_code; + } + + ovl_op_info_t *as_ptr = &ovl_op_info[true][ix]; + if (as_ptr->name) + { + /* These will be placed at the start of the array, move to + the correct slot and initialize. */ + if (as_ptr->ovl_op_code != ix) + { + ovl_op_info_t *dst_ptr = &ovl_op_info[true][as_ptr->ovl_op_code]; + gcc_assert (as_ptr->ovl_op_code > ix && !dst_ptr->tree_code); + memcpy (dst_ptr, as_ptr, sizeof (*dst_ptr)); + memset (as_ptr, 0, sizeof (*as_ptr)); + as_ptr = dst_ptr; + } + + tree ident = set_operator_ident (as_ptr); + gcc_checking_assert (!IDENTIFIER_CP_INDEX (ident)); + IDENTIFIER_CP_INDEX (ident) = as_ptr->ovl_op_code; + set_identifier_kind (ident, cik_assign_op); + + gcc_checking_assert (!ovl_op_mapping[as_ptr->tree_code] + || (ovl_op_mapping[as_ptr->tree_code] + == as_ptr->ovl_op_code)); + ovl_op_mapping[as_ptr->tree_code] = as_ptr->ovl_op_code; + } + } } /* Initialize the reserved words. */ |