[C++ PATCH] overloaded operator fns [5/N]
authorNathan Sidwell <nathan@acm.org>
Tue, 31 Oct 2017 20:08:51 +0000 (20:08 +0000)
committerNathan Sidwell <nathan@gcc.gnu.org>
Tue, 31 Oct 2017 20:08:51 +0000 (20:08 +0000)
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

gcc/cp/ChangeLog
gcc/cp/cp-tree.h
gcc/cp/decl.c
gcc/cp/lex.c
gcc/cp/mangle.c

index edc806edf8ea9ab7268dcdb324994ee2223f202d..191fa111f6a7f095d29900cafcda3df0801adb2e 100644 (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
index c74a1860ec4d477cc99e1c4fe837825bf928b6d7..257c8776f0ee1a217583a1acc8ec003f26e81b5e 100644 (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.  */
index 82d9326ac5b451c9e94dd73b489a61df20f5938a..d60b8dd775a221cfd33464dfe5ac09da565996d8 100644 (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)
index fed44a164298772da72541ef5bfd96311a49c059..af081f4d024dc5e1b9ef834804e024dffb6314dd 100644 (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);                             \
index b745576cd330b783a708f0310a86005c01b4c68d..7feb889e9aad806951566edd33f900bd5a470d38 100644 (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))