2017-11-01 Nathan Sidwell * 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. Index: cp-tree.h =================================================================== --- cp-tree.h (revision 254279) +++ cp-tree.h (working copy) @@ -1072,6 +1072,11 @@ enum cp_identifier_kind { & IDENTIFIER_KIND_BIT_1 (NODE) \ & IDENTIFIER_KIND_BIT_0 (NODE)) +/* Access a C++-specific index for identifier NODE. + Used to optimize operator mappings etc. */ +#define IDENTIFIER_CP_INDEX(NODE) \ + (IDENTIFIER_NODE_CHECK(NODE)->base.u.bits.address_space) + /* In a RECORD_TYPE or UNION_TYPE, nonzero if any component is read-only. */ #define C_TYPE_FIELDS_READONLY(TYPE) \ (LANG_TYPE_CLASS_CHECK (TYPE)->fields_readonly) @@ -5477,12 +5482,25 @@ extern void init_reswords (void); /* Various flags for the overloaded operator information. */ enum ovl_op_flags { - OVL_OP_FLAG_NONE = 0, - OVL_OP_FLAG_UNARY = 1, - OVL_OP_FLAG_BINARY = 2, - OVL_OP_FLAG_ALLOC = 4, /* operator new or delete */ - OVL_OP_FLAG_DELETE = 1, /* operator delete */ - OVL_OP_FLAG_VEC = 2 /* vector new or delete */ + OVL_OP_FLAG_NONE = 0, /* Don't care. */ + OVL_OP_FLAG_UNARY = 1, /* Is unary. */ + OVL_OP_FLAG_BINARY = 2, /* Is binary. */ + OVL_OP_FLAG_AMBIARY = 3, /* May be unary or binary. */ + OVL_OP_FLAG_ALLOC = 4, /* operator new or delete. */ + OVL_OP_FLAG_DELETE = 1, /* operator delete. */ + OVL_OP_FLAG_VEC = 2 /* vector new or delete. */ + }; + +/* Compressed operator codes. Order is determined by operators.def + and does not match that of tree_codes. */ +enum ovl_op_code + { + OVL_OP_ERROR_MARK, + OVL_OP_NOP_EXPR, +#define DEF_OPERATOR(NAME, CODE, MANGLING, FLAGS) OVL_OP_##CODE, +#define DEF_ASSN_OPERATOR(NAME, CODE, MANGLING) /* NOTHING */ +#include "operators.def" + OVL_OP_MAX }; struct GTY(()) ovl_op_info_t { @@ -5492,19 +5510,29 @@ struct GTY(()) ovl_op_info_t { const char *name; /* The mangled name of the operator. */ const char *mangled_name; - /* The tree code. */ + /* The (regular) tree code. */ enum tree_code tree_code : 16; + /* The (compressed) operator code. */ + enum ovl_op_code ovl_op_code : 8; /* The ovl_op_flags of the operator */ unsigned flags : 8; }; -/* Overloaded operator info indexed by ass_op_p & tree_code. */ -extern GTY(()) ovl_op_info_t ovl_op_info[2][MAX_TREE_CODES]; +/* Overloaded operator info indexed by ass_op_p & ovl_op_code. */ +extern GTY(()) ovl_op_info_t ovl_op_info[2][OVL_OP_MAX]; +/* Mapping from tree_codes to ovl_op_codes. */ +extern GTY(()) unsigned char ovl_op_mapping[MAX_TREE_CODES]; +/* Mapping for ambi-ary operators from the binary to the unary. */ +extern GTY(()) unsigned char ovl_op_alternate[OVL_OP_MAX]; /* 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) \ - (&ovl_op_info[(IS_ASS_P) != 0][(TREE_CODE)]) + (&ovl_op_info[(IS_ASS_P) != 0][ovl_op_mapping[(TREE_CODE)]]) +/* Overloaded operator info for an identifier for which + IDENTIFIER_ANY_OP_P is true. */ +#define IDENTIFIER_OVL_OP_INFO(NODE) \ + (&ovl_op_info[IDENTIFIER_ASSIGN_OP_P (NODE)][IDENTIFIER_CP_INDEX (NODE)]) /* A type-qualifier, or bitmask therefore, using the TYPE_QUAL constants. */ Index: decl.c =================================================================== --- decl.c (revision 254279) +++ decl.c (working copy) @@ -65,8 +65,6 @@ static const char *redeclaration_error_m 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, 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 comp } 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 comp } /* 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 % as its argument") - : G_("postfix %qD must have % 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 % as its argument") + : G_("postfix %qD must have % 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 comp : 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 comp : 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)) Index: lex.c =================================================================== --- lex.c (revision 254279) +++ lex.c (working copy) @@ -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; + /* We rely on both these being zero. */ + gcc_checking_assert (!OVL_OP_ERROR_MARK && !ERROR_MARK); -#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); \ - } - -#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. */ Index: mangle.c =================================================================== --- mangle.c (revision 254279) +++ mangle.c (working copy) @@ -1265,30 +1265,8 @@ write_unqualified_id (tree identifier) write_conversion_operator_name (TREE_TYPE (identifier)); else if (IDENTIFIER_ANY_OP_P (identifier)) { - 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 (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); + const ovl_op_info_t *ovl_op = IDENTIFIER_OVL_OP_INFO (identifier); + write_string (ovl_op->mangled_name); } else if (UDLIT_OPER_P (identifier)) write_literal_operator_name (identifier); Index: operators.def =================================================================== --- operators.def (revision 254279) +++ operators.def (working copy) @@ -50,110 +50,109 @@ along with GCC; see the file COPYING3. ovl_op_flags bits. Postincrement and postdecrement operators are marked as binary. - ASSN_P - - A boolean value. If nonzero, this is an assignment operator. - Before including this file, you should define DEF_OPERATOR to take these arguments. There is code (such as in grok_op_properties) that depends on the - order the operators are presented in this file. In particular, - unary operators must precede binary operators. */ - -/* Use DEF_SIMPLE_OPERATOR to define a non-assignment operator. Its - arguments are as for DEF_OPERATOR, but there is no need to provide - an ASSIGNMENT_P argument; it is always zero. */ - -#define DEF_SIMPLE_OPERATOR(NAME, CODE, MANGLING, FLAGS) \ - DEF_OPERATOR(NAME, CODE, MANGLING, FLAGS, cik_simple_op) + order the operators are presented in this file. Unary_ops must + preceed a matching binary op (i.e. '+'). Assignment operators must + be last, after OPERATOR_TRANSITION. */ /* Use DEF_ASSN_OPERATOR to define an assignment operator. Its arguments are as for DEF_OPERATOR, but there is no need to provide - an ASSIGNMENT_P argument; it is always one. */ + FLAGS (OVL_OP_FLAG_BINARY). */ -#define DEF_ASSN_OPERATOR(NAME, CODE, MANGLING, FLAGS) \ - DEF_OPERATOR(NAME, CODE, MANGLING, FLAGS, cik_assign_op) +#ifndef DEF_ASSN_OPERATOR +#define DEF_ASSN_OPERATOR(NAME, CODE, MANGLING) \ + DEF_OPERATOR(NAME, CODE, MANGLING, OVL_OP_FLAG_BINARY) +#endif -/* Memory allocation operators. */ -DEF_OPERATOR ("new", NEW_EXPR, "nw", OVL_OP_FLAG_ALLOC, cik_newdel_op) +/* Memory allocation operators. ARITY has special meaning. */ +DEF_OPERATOR ("new", NEW_EXPR, "nw", OVL_OP_FLAG_ALLOC) DEF_OPERATOR ("new []", VEC_NEW_EXPR, "na", - OVL_OP_FLAG_ALLOC | OVL_OP_FLAG_VEC, cik_newdel_op) + OVL_OP_FLAG_ALLOC | OVL_OP_FLAG_VEC) DEF_OPERATOR ("delete", DELETE_EXPR, "dl", - OVL_OP_FLAG_ALLOC | OVL_OP_FLAG_DELETE, cik_newdel_op) + OVL_OP_FLAG_ALLOC | OVL_OP_FLAG_DELETE) DEF_OPERATOR ("delete []", VEC_DELETE_EXPR, "da", - OVL_OP_FLAG_ALLOC | OVL_OP_FLAG_DELETE | OVL_OP_FLAG_VEC, - cik_newdel_op) + OVL_OP_FLAG_ALLOC | OVL_OP_FLAG_DELETE | OVL_OP_FLAG_VEC) /* Unary operators. */ -DEF_SIMPLE_OPERATOR ("+", UNARY_PLUS_EXPR, "ps", OVL_OP_FLAG_UNARY) -DEF_SIMPLE_OPERATOR ("-", NEGATE_EXPR, "ng", OVL_OP_FLAG_UNARY) -DEF_SIMPLE_OPERATOR ("&", ADDR_EXPR, "ad", OVL_OP_FLAG_UNARY) -DEF_SIMPLE_OPERATOR ("*", INDIRECT_REF, "de", OVL_OP_FLAG_UNARY) -DEF_SIMPLE_OPERATOR ("~", BIT_NOT_EXPR, "co", OVL_OP_FLAG_UNARY) -DEF_SIMPLE_OPERATOR ("!", TRUTH_NOT_EXPR, "nt", OVL_OP_FLAG_UNARY) -DEF_SIMPLE_OPERATOR ("++", PREINCREMENT_EXPR, "pp", OVL_OP_FLAG_UNARY) -DEF_SIMPLE_OPERATOR ("--", PREDECREMENT_EXPR, "mm", OVL_OP_FLAG_UNARY) -DEF_SIMPLE_OPERATOR ("sizeof", SIZEOF_EXPR, "sz", OVL_OP_FLAG_UNARY) +DEF_OPERATOR ("+", UNARY_PLUS_EXPR, "ps", OVL_OP_FLAG_UNARY) +DEF_OPERATOR ("-", NEGATE_EXPR, "ng", OVL_OP_FLAG_UNARY) +DEF_OPERATOR ("&", ADDR_EXPR, "ad", OVL_OP_FLAG_UNARY) +DEF_OPERATOR ("*", INDIRECT_REF, "de", OVL_OP_FLAG_UNARY) +DEF_OPERATOR ("~", BIT_NOT_EXPR, "co", OVL_OP_FLAG_UNARY) +DEF_OPERATOR ("!", TRUTH_NOT_EXPR, "nt", OVL_OP_FLAG_UNARY) +DEF_OPERATOR ("++", PREINCREMENT_EXPR, "pp", OVL_OP_FLAG_UNARY) +DEF_OPERATOR ("--", PREDECREMENT_EXPR, "mm", OVL_OP_FLAG_UNARY) +DEF_OPERATOR ("->", COMPONENT_REF, "pt", OVL_OP_FLAG_UNARY) +DEF_OPERATOR ("sizeof", SIZEOF_EXPR, "sz", OVL_OP_FLAG_UNARY) + /* These are extensions. */ -DEF_SIMPLE_OPERATOR ("alignof", ALIGNOF_EXPR, "az", OVL_OP_FLAG_UNARY) -DEF_SIMPLE_OPERATOR ("__imag__", IMAGPART_EXPR, "v18__imag__", OVL_OP_FLAG_UNARY) -DEF_SIMPLE_OPERATOR ("__real__", REALPART_EXPR, "v18__real__", OVL_OP_FLAG_UNARY) +DEF_OPERATOR ("alignof", ALIGNOF_EXPR, "az", OVL_OP_FLAG_UNARY) +DEF_OPERATOR ("__imag__", IMAGPART_EXPR, "v18__imag__", OVL_OP_FLAG_UNARY) +DEF_OPERATOR ("__real__", REALPART_EXPR, "v18__real__", OVL_OP_FLAG_UNARY) /* Binary operators. */ -DEF_SIMPLE_OPERATOR ("+", PLUS_EXPR, "pl", OVL_OP_FLAG_BINARY) -DEF_SIMPLE_OPERATOR ("-", MINUS_EXPR, "mi", OVL_OP_FLAG_BINARY) -DEF_SIMPLE_OPERATOR ("*", MULT_EXPR, "ml", OVL_OP_FLAG_BINARY) -DEF_SIMPLE_OPERATOR ("/", TRUNC_DIV_EXPR, "dv", OVL_OP_FLAG_BINARY) -DEF_SIMPLE_OPERATOR ("%", TRUNC_MOD_EXPR, "rm", OVL_OP_FLAG_BINARY) -DEF_SIMPLE_OPERATOR ("&", BIT_AND_EXPR, "an", OVL_OP_FLAG_BINARY) -DEF_SIMPLE_OPERATOR ("|", BIT_IOR_EXPR, "or", OVL_OP_FLAG_BINARY) -DEF_SIMPLE_OPERATOR ("^", BIT_XOR_EXPR, "eo", OVL_OP_FLAG_BINARY) -DEF_SIMPLE_OPERATOR ("<<", LSHIFT_EXPR, "ls", OVL_OP_FLAG_BINARY) -DEF_SIMPLE_OPERATOR (">>", RSHIFT_EXPR, "rs", OVL_OP_FLAG_BINARY) -DEF_SIMPLE_OPERATOR ("==", EQ_EXPR, "eq", OVL_OP_FLAG_BINARY) -DEF_SIMPLE_OPERATOR ("!=", NE_EXPR, "ne", OVL_OP_FLAG_BINARY) -DEF_SIMPLE_OPERATOR ("<", LT_EXPR, "lt", OVL_OP_FLAG_BINARY) -DEF_SIMPLE_OPERATOR (">", GT_EXPR, "gt", OVL_OP_FLAG_BINARY) -DEF_SIMPLE_OPERATOR ("<=", LE_EXPR, "le", OVL_OP_FLAG_BINARY) -DEF_SIMPLE_OPERATOR (">=", GE_EXPR, "ge", OVL_OP_FLAG_BINARY) -DEF_SIMPLE_OPERATOR ("&&", TRUTH_ANDIF_EXPR, "aa", OVL_OP_FLAG_BINARY) -DEF_SIMPLE_OPERATOR ("||", TRUTH_ORIF_EXPR, "oo", OVL_OP_FLAG_BINARY) -DEF_SIMPLE_OPERATOR (",", COMPOUND_EXPR, "cm", OVL_OP_FLAG_BINARY) -DEF_SIMPLE_OPERATOR ("->*", MEMBER_REF, "pm", OVL_OP_FLAG_BINARY) -DEF_SIMPLE_OPERATOR (".*", DOTSTAR_EXPR, "ds", OVL_OP_FLAG_BINARY) -DEF_SIMPLE_OPERATOR ("->", COMPONENT_REF, "pt", OVL_OP_FLAG_BINARY) -DEF_SIMPLE_OPERATOR ("[]", ARRAY_REF, "ix", OVL_OP_FLAG_BINARY) -DEF_SIMPLE_OPERATOR ("++", POSTINCREMENT_EXPR, "pp", OVL_OP_FLAG_BINARY) -DEF_SIMPLE_OPERATOR ("--", POSTDECREMENT_EXPR, "mm", OVL_OP_FLAG_BINARY) +DEF_OPERATOR ("+", PLUS_EXPR, "pl", OVL_OP_FLAG_BINARY) +DEF_OPERATOR ("-", MINUS_EXPR, "mi", OVL_OP_FLAG_BINARY) +DEF_OPERATOR ("*", MULT_EXPR, "ml", OVL_OP_FLAG_BINARY) +DEF_OPERATOR ("/", TRUNC_DIV_EXPR, "dv", OVL_OP_FLAG_BINARY) +DEF_OPERATOR ("%", TRUNC_MOD_EXPR, "rm", OVL_OP_FLAG_BINARY) +DEF_OPERATOR ("&", BIT_AND_EXPR, "an", OVL_OP_FLAG_BINARY) +DEF_OPERATOR ("|", BIT_IOR_EXPR, "or", OVL_OP_FLAG_BINARY) +DEF_OPERATOR ("^", BIT_XOR_EXPR, "eo", OVL_OP_FLAG_BINARY) +DEF_OPERATOR ("<<", LSHIFT_EXPR, "ls", OVL_OP_FLAG_BINARY) +DEF_OPERATOR (">>", RSHIFT_EXPR, "rs", OVL_OP_FLAG_BINARY) +DEF_OPERATOR ("==", EQ_EXPR, "eq", OVL_OP_FLAG_BINARY) +DEF_OPERATOR ("!=", NE_EXPR, "ne", OVL_OP_FLAG_BINARY) +DEF_OPERATOR ("<", LT_EXPR, "lt", OVL_OP_FLAG_BINARY) +DEF_OPERATOR (">", GT_EXPR, "gt", OVL_OP_FLAG_BINARY) +DEF_OPERATOR ("<=", LE_EXPR, "le", OVL_OP_FLAG_BINARY) +DEF_OPERATOR (">=", GE_EXPR, "ge", OVL_OP_FLAG_BINARY) +DEF_OPERATOR ("&&", TRUTH_ANDIF_EXPR, "aa", OVL_OP_FLAG_BINARY) +DEF_OPERATOR ("||", TRUTH_ORIF_EXPR, "oo", OVL_OP_FLAG_BINARY) +DEF_OPERATOR (",", COMPOUND_EXPR, "cm", OVL_OP_FLAG_BINARY) +DEF_OPERATOR ("->*", MEMBER_REF, "pm", OVL_OP_FLAG_BINARY) +DEF_OPERATOR (".*", DOTSTAR_EXPR, "ds", OVL_OP_FLAG_BINARY) +DEF_OPERATOR ("[]", ARRAY_REF, "ix", OVL_OP_FLAG_BINARY) +DEF_OPERATOR ("++", POSTINCREMENT_EXPR, "pp", OVL_OP_FLAG_BINARY) +DEF_OPERATOR ("--", POSTDECREMENT_EXPR, "mm", OVL_OP_FLAG_BINARY) /* Miscellaneous. */ -DEF_SIMPLE_OPERATOR ("?:", COND_EXPR, "qu", OVL_OP_FLAG_NONE) -DEF_SIMPLE_OPERATOR ("()", CALL_EXPR, "cl", OVL_OP_FLAG_NONE) +DEF_OPERATOR ("?:", COND_EXPR, "qu", OVL_OP_FLAG_NONE) +DEF_OPERATOR ("()", CALL_EXPR, "cl", OVL_OP_FLAG_NONE) /* Operators needed for mangling. */ -DEF_SIMPLE_OPERATOR (NULL, CAST_EXPR, "cv", OVL_OP_FLAG_NONE) -DEF_SIMPLE_OPERATOR (NULL, DYNAMIC_CAST_EXPR, "dc", OVL_OP_FLAG_NONE) -DEF_SIMPLE_OPERATOR (NULL, REINTERPRET_CAST_EXPR, "rc", OVL_OP_FLAG_NONE) -DEF_SIMPLE_OPERATOR (NULL, CONST_CAST_EXPR, "cc", OVL_OP_FLAG_NONE) -DEF_SIMPLE_OPERATOR (NULL, STATIC_CAST_EXPR, "sc", OVL_OP_FLAG_NONE) -DEF_SIMPLE_OPERATOR (NULL, SCOPE_REF, "sr", OVL_OP_FLAG_NONE) -DEF_SIMPLE_OPERATOR (NULL, EXPR_PACK_EXPANSION, "sp", OVL_OP_FLAG_NONE) -DEF_SIMPLE_OPERATOR (NULL, UNARY_LEFT_FOLD_EXPR, "fl", OVL_OP_FLAG_NONE) -DEF_SIMPLE_OPERATOR (NULL, UNARY_RIGHT_FOLD_EXPR, "fr", OVL_OP_FLAG_NONE) -DEF_SIMPLE_OPERATOR (NULL, BINARY_LEFT_FOLD_EXPR, "fL", OVL_OP_FLAG_NONE) -DEF_SIMPLE_OPERATOR (NULL, BINARY_RIGHT_FOLD_EXPR, "fR", OVL_OP_FLAG_NONE) +DEF_OPERATOR (NULL, CAST_EXPR, "cv", OVL_OP_FLAG_UNARY) +DEF_OPERATOR (NULL, DYNAMIC_CAST_EXPR, "dc", OVL_OP_FLAG_UNARY) +DEF_OPERATOR (NULL, REINTERPRET_CAST_EXPR, "rc", OVL_OP_FLAG_UNARY) +DEF_OPERATOR (NULL, CONST_CAST_EXPR, "cc", OVL_OP_FLAG_UNARY) +DEF_OPERATOR (NULL, STATIC_CAST_EXPR, "sc", OVL_OP_FLAG_UNARY) +DEF_OPERATOR (NULL, SCOPE_REF, "sr", OVL_OP_FLAG_NONE) +DEF_OPERATOR (NULL, EXPR_PACK_EXPANSION, "sp", OVL_OP_FLAG_NONE) +DEF_OPERATOR (NULL, UNARY_LEFT_FOLD_EXPR, "fl", OVL_OP_FLAG_NONE) +DEF_OPERATOR (NULL, UNARY_RIGHT_FOLD_EXPR, "fr", OVL_OP_FLAG_NONE) +DEF_OPERATOR (NULL, BINARY_LEFT_FOLD_EXPR, "fL", OVL_OP_FLAG_NONE) +DEF_OPERATOR (NULL, BINARY_RIGHT_FOLD_EXPR, "fR", OVL_OP_FLAG_NONE) + +#ifdef OPERATOR_TRANSITION +OPERATOR_TRANSITION +#undef OPERATOR_TRANSITION +#endif /* Assignment operators. */ -DEF_ASSN_OPERATOR ("=", NOP_EXPR, "aS", OVL_OP_FLAG_BINARY) -DEF_ASSN_OPERATOR ("+=", PLUS_EXPR, "pL", OVL_OP_FLAG_BINARY) -DEF_ASSN_OPERATOR ("-=", MINUS_EXPR, "mI", OVL_OP_FLAG_BINARY) -DEF_ASSN_OPERATOR ("*=", MULT_EXPR, "mL", OVL_OP_FLAG_BINARY) -DEF_ASSN_OPERATOR ("/=", TRUNC_DIV_EXPR, "dV", OVL_OP_FLAG_BINARY) -DEF_ASSN_OPERATOR ("%=", TRUNC_MOD_EXPR, "rM", OVL_OP_FLAG_BINARY) -DEF_ASSN_OPERATOR ("&=", BIT_AND_EXPR, "aN", OVL_OP_FLAG_BINARY) -DEF_ASSN_OPERATOR ("|=", BIT_IOR_EXPR, "oR", OVL_OP_FLAG_BINARY) -DEF_ASSN_OPERATOR ("^=", BIT_XOR_EXPR, "eO", OVL_OP_FLAG_BINARY) -DEF_ASSN_OPERATOR ("<<=", LSHIFT_EXPR, "lS", OVL_OP_FLAG_BINARY) -DEF_ASSN_OPERATOR (">>=", RSHIFT_EXPR, "rS", OVL_OP_FLAG_BINARY) +DEF_ASSN_OPERATOR ("=", NOP_EXPR, "aS") +DEF_ASSN_OPERATOR ("+=", PLUS_EXPR, "pL") +DEF_ASSN_OPERATOR ("-=", MINUS_EXPR, "mI") +DEF_ASSN_OPERATOR ("*=", MULT_EXPR, "mL") +DEF_ASSN_OPERATOR ("/=", TRUNC_DIV_EXPR, "dV") +DEF_ASSN_OPERATOR ("%=", TRUNC_MOD_EXPR, "rM") +DEF_ASSN_OPERATOR ("&=", BIT_AND_EXPR, "aN") +DEF_ASSN_OPERATOR ("|=", BIT_IOR_EXPR, "oR") +DEF_ASSN_OPERATOR ("^=", BIT_XOR_EXPR, "eO") +DEF_ASSN_OPERATOR ("<<=", LSHIFT_EXPR, "lS") +DEF_ASSN_OPERATOR (">>=", RSHIFT_EXPR, "rS") +#undef DEF_ASSN_OPERATOR +#undef DEF_OPERATOR