[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
This commit is contained in:
Nathan Sidwell 2017-10-31 20:08:51 +00:00 committed by Nathan Sidwell
parent c67624232a
commit 881c969cf6
5 changed files with 68 additions and 61 deletions

View file

@ -1,5 +1,18 @@
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
special cases.
* operators.def: Use NULL for mangling only operators. Move to

View file

@ -5485,29 +5485,26 @@ enum ovl_op_flags
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. */
tree identifier;
/* The name of the operator. */
const char *name;
/* The mangled name of the operator. */
const char *mangled_name;
/* The tree code. */
enum tree_code tree_code : 16;
/* The ovl_op_flags of the operator */
unsigned flags : 8;
};
/* A mapping from tree codes to operator name information. */
extern GTY(()) operator_name_info_t operator_name_info
[(int) MAX_TREE_CODES];
/* Similar, but for assignment operators. */
extern GTY(()) operator_name_info_t assignment_operator_name_info
[(int) MAX_TREE_CODES];
/* Overloaded operator info indexed by ass_op_p & tree_code. */
extern GTY(()) ovl_op_info_t ovl_op_info[2][MAX_TREE_CODES];
/* 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) \
(((IS_ASS_P) ? assignment_operator_name_info : operator_name_info) \
+ (TREE_CODE))
(&ovl_op_info[(IS_ASS_P) != 0][(TREE_CODE)])
/* A type-qualifier, or bitmask therefore, using the TYPE_QUAL
constants. */

View file

@ -12898,8 +12898,8 @@ unary_op_p (enum tree_code code)
|| code == TYPE_EXPR);
}
/* DECL is a declaration for an overloaded operator. If COMPLAIN is true,
errors are issued for invalid declarations. */
/* DECL is a declaration for an overloaded or conversion operator. If
COMPLAIN is true, errors are issued for invalid declarations. */
bool
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))
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))
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
{
/* 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 operator_name_info_t *oni
= (assign_op ? assignment_operator_name_info : operator_name_info);
const ovl_op_info_t *ovl_op = OVL_OP_INFO (assign_op, 0);
if (false)
;
#define DEF_OPERATOR(NAME, CODE, MANGLING, ARITY, KIND) \
else if (assign_op == (KIND == cik_assign_op) \
&& oni[int (CODE)].identifier == name) \
#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 ();
}
while (0);
gcc_assert (operator_code != MAX_TREE_CODES);
DECL_OVERLOADED_OPERATOR_CODE (decl) = operator_code;
gcc_assert (operator_code != ERROR_MARK);
op_flags = ovl_op[operator_code].flags;
DECL_OVERLOADED_OPERATOR_CODE (decl) = operator_code;
}
if (operator_code == NEW_EXPR || operator_code == VEC_NEW_EXPR
|| operator_code == DELETE_EXPR || operator_code == VEC_DELETE_EXPR)
if (op_flags & OVL_OP_FLAG_ALLOC)
{
/* operator new and operator delete are quite special. */
if (class_type)
switch (operator_code)
switch (op_flags)
{
case NEW_EXPR:
case OVL_OP_FLAG_ALLOC:
TYPE_HAS_NEW_OPERATOR (class_type) = 1;
break;
case DELETE_EXPR:
case OVL_OP_FLAG_ALLOC | OVL_OP_FLAG_DELETE:
TYPE_GETS_DELETE (class_type) |= 1;
break;
case VEC_NEW_EXPR:
case OVL_OP_FLAG_ALLOC | OVL_OP_FLAG_VEC:
TYPE_HAS_ARRAY_NEW_OPERATOR (class_type) = 1;
break;
case VEC_DELETE_EXPR:
case OVL_OP_FLAG_ALLOC | OVL_OP_FLAG_DELETE | OVL_OP_FLAG_VEC:
TYPE_GETS_DELETE (class_type) |= 2;
break;
@ -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));
else
{
TREE_TYPE (decl) = coerce_new_type (TREE_TYPE (decl));
DECL_IS_OPERATOR_NEW (decl) = 1;
TREE_TYPE (decl) = coerce_new_type (TREE_TYPE (decl));
}
return true;
@ -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)
/* There are no further restrictions on the arguments to an overloaded
"operator ()". */
return true;
if (operator_code == COND_EXPR)

View file

@ -77,10 +77,7 @@ cxx_finish (void)
c_common_finish ();
}
/* A mapping from tree codes to operator name information. */
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];
ovl_op_info_t ovl_op_info[2][MAX_TREE_CODES];
/* Get the name of the kind of identifier T. */
@ -117,7 +114,7 @@ set_identifier_kind (tree id, cp_identifier_kind kind)
operator PTR describes. */
static tree
set_operator_ident (operator_name_info_t *ptr)
set_operator_ident (ovl_op_info_t *ptr)
{
char buffer[32];
size_t len = snprintf (buffer, sizeof (buffer), "operator%s%s",
@ -136,12 +133,13 @@ static void
init_operators (void)
{
tree identifier;
operator_name_info_t *oni;
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); \

View file

@ -1265,32 +1265,29 @@ write_unqualified_id (tree identifier)
write_conversion_operator_name (TREE_TYPE (identifier));
else if (IDENTIFIER_ANY_OP_P (identifier))
{
int i;
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 (i = 0; i < MAX_TREE_CODES; ++i)
if (operator_name_info[i].identifier == identifier)
{
/* The ABI says that we prefer binary operator
names to unary operator names. */
if (operator_name_info[i].flags == OVL_OP_FLAG_BINARY)
{
mangled_name = operator_name_info[i].mangled_name;
break;
}
else if (!mangled_name)
mangled_name = operator_name_info[i].mangled_name;
}
else if (assignment_operator_name_info[i].identifier
== identifier)
{
mangled_name
= assignment_operator_name_info[i].mangled_name;
break;
}
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);
}
else if (UDLIT_OPER_P (identifier))