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 *,
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. */
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
}
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;
}
}
/* 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
: G_("%qD must have exactly one argument"), decl);
return false;
}
- }
- else
- {
+ break;
+
+ case OVL_OP_FLAG_BINARY:
if (arity != 2)
{
error (methodp
: 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))
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. */
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. */
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