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/decl.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/decl.c')
-rw-r--r-- | gcc/cp/decl.c | 143 |
1 files changed, 42 insertions, 101 deletions
diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index d60b8dd..f43c960 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -65,8 +65,6 @@ static const char *redeclaration_error_message (tree, tree); static int decl_jump_unsafe (tree); static void require_complete_types_for_parms (tree); -static bool ambi_op_p (enum tree_code); -static bool unary_op_p (enum tree_code); static void push_local_name (tree); static tree grok_reference_init (tree, tree, tree, int); static tree grokvardecl (tree, tree, tree, const cp_decl_specifier_seq *, @@ -12874,30 +12872,6 @@ grok_ctor_properties (const_tree ctype, const_tree decl) return true; } -/* An operator with this code is unary, but can also be binary. */ - -static bool -ambi_op_p (enum tree_code code) -{ - return (code == INDIRECT_REF - || code == ADDR_EXPR - || code == UNARY_PLUS_EXPR - || code == NEGATE_EXPR - || code == PREINCREMENT_EXPR - || code == PREDECREMENT_EXPR); -} - -/* An operator with this name can only be unary. */ - -static bool -unary_op_p (enum tree_code code) -{ - return (code == TRUTH_NOT_EXPR - || code == BIT_NOT_EXPR - || code == COMPONENT_REF - || code == TYPE_EXPR); -} - /* DECL is a declaration for an overloaded or conversion operator. If COMPLAIN is true, errors are issued for invalid declarations. */ @@ -12905,15 +12879,15 @@ bool grok_op_properties (tree decl, bool complain) { tree argtypes = TYPE_ARG_TYPES (TREE_TYPE (decl)); - int methodp = (TREE_CODE (TREE_TYPE (decl)) == METHOD_TYPE); + bool methodp = TREE_CODE (TREE_TYPE (decl)) == METHOD_TYPE; tree name = DECL_NAME (decl); tree class_type = DECL_CONTEXT (decl); if (class_type && !CLASS_TYPE_P (class_type)) class_type = NULL_TREE; - tree_code operator_code = ERROR_MARK; - unsigned op_flags = OVL_OP_FLAG_NONE; + tree_code operator_code; + unsigned op_flags; if (IDENTIFIER_CONV_OP_P (name)) { /* Conversion operators are TYPE_EXPR for the purposes of this @@ -12923,21 +12897,11 @@ grok_op_properties (tree decl, bool complain) } 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 ovl_op_info_t *ovl_op = OVL_OP_INFO (assign_op, 0); - if (false) - ; -#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 (); - gcc_assert (operator_code != ERROR_MARK); - op_flags = ovl_op[operator_code].flags; + const ovl_op_info_t *ovl_op = IDENTIFIER_OVL_OP_INFO (name); + + operator_code = ovl_op->tree_code; + op_flags = ovl_op->flags; + gcc_checking_assert (operator_code != ERROR_MARK); DECL_OVERLOADED_OPERATOR_CODE (decl) = operator_code; } @@ -13071,70 +13035,43 @@ grok_op_properties (tree decl, bool complain) } /* Verify correct number of arguments. */ - if (ambi_op_p (operator_code)) + switch (op_flags) { + case OVL_OP_FLAG_AMBIARY: if (arity == 1) - /* We pick the one-argument operator codes by default, so - we don't have to change anything. */ - ; - else if (arity == 2) { - /* If we thought this was a unary operator, we now know - it to be a binary operator. */ - switch (operator_code) - { - case INDIRECT_REF: - operator_code = MULT_EXPR; - break; - - case ADDR_EXPR: - operator_code = BIT_AND_EXPR; - break; - - case UNARY_PLUS_EXPR: - operator_code = PLUS_EXPR; - break; - - case NEGATE_EXPR: - operator_code = MINUS_EXPR; - break; - - case PREINCREMENT_EXPR: - operator_code = POSTINCREMENT_EXPR; - break; - - case PREDECREMENT_EXPR: - operator_code = POSTDECREMENT_EXPR; - break; - - default: - gcc_unreachable (); - } - + /* We have a unary instance of an ambi-ary op. Remap to the + unary one. */ + unsigned alt = ovl_op_alternate[ovl_op_mapping [operator_code]]; + const ovl_op_info_t *ovl_op = &ovl_op_info[false][alt]; + gcc_checking_assert (ovl_op->flags == OVL_OP_FLAG_UNARY); + operator_code = ovl_op->tree_code; DECL_OVERLOADED_OPERATOR_CODE (decl) = operator_code; - - if ((operator_code == POSTINCREMENT_EXPR - || operator_code == POSTDECREMENT_EXPR) - && ! processing_template_decl - && ! same_type_p (TREE_VALUE (TREE_CHAIN (argtypes)), integer_type_node)) - { - error (methodp - ? G_("postfix %qD must have %<int%> as its argument") - : G_("postfix %qD must have %<int%> as its second argument"), - decl); - return false; - } } - else + else if (arity != 2) { + /* This was an ambiguous operator but is invalid. */ error (methodp ? G_("%qD must have either zero or one argument") : G_("%qD must have either one or two arguments"), decl); return false; } - } - else if (unary_op_p (operator_code)) - { + else if ((operator_code == POSTINCREMENT_EXPR + || operator_code == POSTDECREMENT_EXPR) + && ! processing_template_decl + /* x++ and x--'s second argument must be an int. */ + && ! same_type_p (TREE_VALUE (TREE_CHAIN (argtypes)), + integer_type_node)) + { + error (methodp + ? G_("postfix %qD must have %<int%> as its argument") + : G_("postfix %qD must have %<int%> as its second argument"), + decl); + return false; + } + break; + + case OVL_OP_FLAG_UNARY: if (arity != 1) { error (methodp @@ -13142,9 +13079,9 @@ grok_op_properties (tree decl, bool complain) : G_("%qD must have exactly one argument"), decl); return false; } - } - else - { + break; + + case OVL_OP_FLAG_BINARY: if (arity != 2) { error (methodp @@ -13152,8 +13089,12 @@ grok_op_properties (tree decl, bool complain) : G_("%qD must have exactly two arguments"), decl); return false; } + break; + + default: + gcc_unreachable (); } - + /* There can be no default arguments. */ for (tree arg = argtypes; arg != void_list_node; arg = TREE_CHAIN (arg)) if (TREE_PURPOSE (arg)) |