Commit 881c969c by Nathan Sidwell Committed by Nathan Sidwell

[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
parent c6762423
2017-10-31 Nathan Sidwell <nathan@acm.org> 2017-10-31 Nathan Sidwell <nathan@acm.org>
* 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 * lex.c (init_operators): Allow NULL operator name. Don't add
special cases. special cases.
* operators.def: Use NULL for mangling only operators. Move to * operators.def: Use NULL for mangling only operators. Move to
......
...@@ -5485,29 +5485,26 @@ enum ovl_op_flags ...@@ -5485,29 +5485,26 @@ enum ovl_op_flags
OVL_OP_FLAG_VEC = 2 /* vector new or delete */ 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. */ /* The IDENTIFIER_NODE for the operator. */
tree identifier; tree identifier;
/* The name of the operator. */ /* The name of the operator. */
const char *name; const char *name;
/* The mangled name of the operator. */ /* The mangled name of the operator. */
const char *mangled_name; const char *mangled_name;
/* The tree code. */
enum tree_code tree_code : 16;
/* The ovl_op_flags of the operator */ /* The ovl_op_flags of the operator */
unsigned flags : 8; unsigned flags : 8;
}; };
/* A mapping from tree codes to operator name information. */ /* Overloaded operator info indexed by ass_op_p & tree_code. */
extern GTY(()) operator_name_info_t operator_name_info extern GTY(()) ovl_op_info_t ovl_op_info[2][MAX_TREE_CODES];
[(int) MAX_TREE_CODES];
/* Similar, but for assignment operators. */
extern GTY(()) operator_name_info_t assignment_operator_name_info
[(int) MAX_TREE_CODES];
/* Given an ass_op_p boolean and a tree code, return a pointer to its /* Given an ass_op_p boolean and a tree code, return a pointer to its
overloaded operator info. */ overloaded operator info. */
#define OVL_OP_INFO(IS_ASS_P, TREE_CODE) \ #define OVL_OP_INFO(IS_ASS_P, TREE_CODE) \
(((IS_ASS_P) ? assignment_operator_name_info : operator_name_info) \ (&ovl_op_info[(IS_ASS_P) != 0][(TREE_CODE)])
+ (TREE_CODE))
/* A type-qualifier, or bitmask therefore, using the TYPE_QUAL /* A type-qualifier, or bitmask therefore, using the TYPE_QUAL
constants. */ constants. */
......
...@@ -12898,8 +12898,8 @@ unary_op_p (enum tree_code code) ...@@ -12898,8 +12898,8 @@ unary_op_p (enum tree_code code)
|| code == TYPE_EXPR); || code == TYPE_EXPR);
} }
/* DECL is a declaration for an overloaded operator. If COMPLAIN is true, /* DECL is a declaration for an overloaded or conversion operator. If
errors are issued for invalid declarations. */ COMPLAIN is true, errors are issued for invalid declarations. */
bool bool
grok_op_properties (tree decl, bool complain) grok_op_properties (tree decl, bool complain)
...@@ -12912,52 +12912,54 @@ 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)) if (class_type && !CLASS_TYPE_P (class_type))
class_type = NULL_TREE; 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)) 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 else
{ {
/* It'd be nice to hang something else of the identifier to /* It'd be nice to hang something else of the identifier to
find CODE more directly. */ find CODE more directly. */
bool assign_op = IDENTIFIER_ASSIGN_OP_P (name); bool assign_op = IDENTIFIER_ASSIGN_OP_P (name);
const operator_name_info_t *oni const ovl_op_info_t *ovl_op = OVL_OP_INFO (assign_op, 0);
= (assign_op ? assignment_operator_name_info : operator_name_info);
if (false) if (false)
; ;
#define DEF_OPERATOR(NAME, CODE, MANGLING, ARITY, KIND) \ #define DEF_OPERATOR(NAME, CODE, MANGLING, FLAGS, KIND) \
else if (assign_op == (KIND == cik_assign_op) \ else if (ovl_op[CODE].identifier == name) \
&& oni[int (CODE)].identifier == name) \
operator_code = (CODE); operator_code = (CODE);
#include "operators.def" #include "operators.def"
#undef DEF_OPERATOR #undef DEF_OPERATOR
else else
gcc_unreachable (); gcc_unreachable ();
} gcc_assert (operator_code != ERROR_MARK);
while (0); op_flags = ovl_op[operator_code].flags;
gcc_assert (operator_code != MAX_TREE_CODES); DECL_OVERLOADED_OPERATOR_CODE (decl) = operator_code;
DECL_OVERLOADED_OPERATOR_CODE (decl) = operator_code; }
if (operator_code == NEW_EXPR || operator_code == VEC_NEW_EXPR if (op_flags & OVL_OP_FLAG_ALLOC)
|| operator_code == DELETE_EXPR || operator_code == VEC_DELETE_EXPR)
{ {
/* operator new and operator delete are quite special. */ /* operator new and operator delete are quite special. */
if (class_type) if (class_type)
switch (operator_code) switch (op_flags)
{ {
case NEW_EXPR: case OVL_OP_FLAG_ALLOC:
TYPE_HAS_NEW_OPERATOR (class_type) = 1; TYPE_HAS_NEW_OPERATOR (class_type) = 1;
break; break;
case DELETE_EXPR: case OVL_OP_FLAG_ALLOC | OVL_OP_FLAG_DELETE:
TYPE_GETS_DELETE (class_type) |= 1; TYPE_GETS_DELETE (class_type) |= 1;
break; break;
case VEC_NEW_EXPR: case OVL_OP_FLAG_ALLOC | OVL_OP_FLAG_VEC:
TYPE_HAS_ARRAY_NEW_OPERATOR (class_type) = 1; TYPE_HAS_ARRAY_NEW_OPERATOR (class_type) = 1;
break; break;
case VEC_DELETE_EXPR: case OVL_OP_FLAG_ALLOC | OVL_OP_FLAG_DELETE | OVL_OP_FLAG_VEC:
TYPE_GETS_DELETE (class_type) |= 2; TYPE_GETS_DELETE (class_type) |= 2;
break; break;
...@@ -12987,12 +12989,12 @@ grok_op_properties (tree decl, bool complain) ...@@ -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)); TREE_TYPE (decl) = coerce_delete_type (TREE_TYPE (decl));
else else
{ {
TREE_TYPE (decl) = coerce_new_type (TREE_TYPE (decl));
DECL_IS_OPERATOR_NEW (decl) = 1; DECL_IS_OPERATOR_NEW (decl) = 1;
TREE_TYPE (decl) = coerce_new_type (TREE_TYPE (decl));
} }
return true; return true;
...@@ -13043,9 +13045,9 @@ grok_op_properties (tree decl, bool complain) ...@@ -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) if (operator_code == CALL_EXPR)
/* There are no further restrictions on the arguments to an overloaded
"operator ()". */
return true; return true;
if (operator_code == COND_EXPR) if (operator_code == COND_EXPR)
......
...@@ -77,10 +77,7 @@ cxx_finish (void) ...@@ -77,10 +77,7 @@ cxx_finish (void)
c_common_finish (); c_common_finish ();
} }
/* A mapping from tree codes to operator name information. */ ovl_op_info_t ovl_op_info[2][MAX_TREE_CODES];
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];
/* Get the name of the kind of identifier T. */ /* Get the name of the kind of identifier T. */
...@@ -117,7 +114,7 @@ set_identifier_kind (tree id, cp_identifier_kind kind) ...@@ -117,7 +114,7 @@ set_identifier_kind (tree id, cp_identifier_kind kind)
operator PTR describes. */ operator PTR describes. */
static tree static tree
set_operator_ident (operator_name_info_t *ptr) set_operator_ident (ovl_op_info_t *ptr)
{ {
char buffer[32]; char buffer[32];
size_t len = snprintf (buffer, sizeof (buffer), "operator%s%s", size_t len = snprintf (buffer, sizeof (buffer), "operator%s%s",
...@@ -136,12 +133,13 @@ static void ...@@ -136,12 +133,13 @@ static void
init_operators (void) init_operators (void)
{ {
tree identifier; tree identifier;
operator_name_info_t *oni; ovl_op_info_t *oni;
#define DEF_OPERATOR(NAME, CODE, MANGLING, FLAGS, KIND) \ #define DEF_OPERATOR(NAME, CODE, MANGLING, FLAGS, KIND) \
oni = OVL_OP_INFO (KIND == cik_assign_op, CODE); \ oni = OVL_OP_INFO (KIND == cik_assign_op, CODE); \
oni->name = NAME; \ oni->name = NAME; \
oni->mangled_name = MANGLING; \ oni->mangled_name = MANGLING; \
oni->tree_code = CODE; \
oni->flags = FLAGS; \ oni->flags = FLAGS; \
if (NAME) { \ if (NAME) { \
identifier = set_operator_ident (oni); \ identifier = set_operator_ident (oni); \
......
...@@ -1265,32 +1265,29 @@ write_unqualified_id (tree identifier) ...@@ -1265,32 +1265,29 @@ write_unqualified_id (tree identifier)
write_conversion_operator_name (TREE_TYPE (identifier)); write_conversion_operator_name (TREE_TYPE (identifier));
else if (IDENTIFIER_ANY_OP_P (identifier)) else if (IDENTIFIER_ANY_OP_P (identifier))
{ {
int i;
const char *mangled_name = NULL; const char *mangled_name = NULL;
bool assop = IDENTIFIER_ASSIGN_OP_P (identifier);
/* Unfortunately, there is no easy way to go from the /* Unfortunately, there is no easy way to go from the
name of the operator back to the corresponding tree name of the operator back to the corresponding tree
code. */ code. */
for (i = 0; i < MAX_TREE_CODES; ++i) for (unsigned i = 0; i < MAX_TREE_CODES; ++i)
if (operator_name_info[i].identifier == identifier) {
{ const ovl_op_info_t *ovl_op = OVL_OP_INFO (assop, i);
/* The ABI says that we prefer binary operator
names to unary operator names. */ if (ovl_op->identifier == identifier)
if (operator_name_info[i].flags == OVL_OP_FLAG_BINARY) {
{ /* The ABI says that we prefer binary operator
mangled_name = operator_name_info[i].mangled_name; names to unary operator names. */
break; if (ovl_op->flags == OVL_OP_FLAG_BINARY)
} {
else if (!mangled_name) mangled_name = ovl_op->mangled_name;
mangled_name = operator_name_info[i].mangled_name; break;
} }
else if (assignment_operator_name_info[i].identifier else if (!mangled_name)
== identifier) mangled_name = ovl_op->mangled_name;
{ }
mangled_name }
= assignment_operator_name_info[i].mangled_name;
break;
}
write_string (mangled_name); write_string (mangled_name);
} }
else if (UDLIT_OPER_P (identifier)) else if (UDLIT_OPER_P (identifier))
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment