Conversion operators kept on single overload set
authorNathan Sidwell <nathan@acm.org>
Thu, 24 Aug 2017 18:39:41 +0000 (18:39 +0000)
committerNathan Sidwell <nathan@gcc.gnu.org>
Thu, 24 Aug 2017 18:39:41 +0000 (18:39 +0000)
Conversion operators kept on single overload set
* class.c (add_method): Keep all conv-ops on one slot.
* name-lookup.c (lookup_conversion_operator): Pull the desired
conv op out of overload set.
* search.c (lookup_conversions_r): Lose template/non-template
distinction.
(lookup_conversions): Likewise.

From-SVN: r251340

gcc/cp/ChangeLog
gcc/cp/class.c
gcc/cp/name-lookup.c
gcc/cp/search.c

index 5d2a3c6..92ecf91 100644 (file)
@@ -1,3 +1,13 @@
+2017-08-24  Nathan Sidwell  <nathan@acm.org>
+
+       Conversion operators kept on single overload set
+       * class.c (add_method): Keep all conv-ops on one slot.
+       * name-lookup.c (lookup_conversion_operator): Pull the desired
+       conv op out of overload set.
+       * search.c (lookup_conversions_r): Lose template/non-template
+       distinction.
+       (lookup_conversions): Likewise.
+
 2017-08-23  Nathan Sidwell  <nathan@acm.org>
 
        * cp-tree.h (lookup_field_1, lookup_fnfields_slot,
index 78a9b5f..a08ce89 100644 (file)
@@ -1014,30 +1014,16 @@ modify_vtable_entry (tree t,
 bool
 add_method (tree type, tree method, bool via_using)
 {
-  unsigned slot;
-  bool template_conv_p = false;
-  bool conv_p;
-  vec<tree, va_gc> *method_vec;
-  bool complete_p;
-  bool insert_p = false;
-  tree current_fns;
-
   if (method == error_mark_node)
     return false;
 
-  complete_p = COMPLETE_TYPE_P (type);
-  conv_p = DECL_CONV_FN_P (method);
-  if (conv_p)
-    template_conv_p = (TREE_CODE (method) == TEMPLATE_DECL
-                      && DECL_TEMPLATE_CONV_FN_P (method));
+  bool complete_p = COMPLETE_TYPE_P (type);
+  bool conv_p = DECL_CONV_FN_P (method);
 
-  method_vec = CLASSTYPE_METHOD_VEC (type);
+  vec<tree, va_gc> *method_vec = CLASSTYPE_METHOD_VEC (type);
   if (!method_vec)
     {
-      /* Make a new method vector.  We start with 8 entries.  We must
-        allocate at least two (for constructors and destructors), and
-        we're going to end up with an assignment operator at some
-        point as well.  */
+      /* Make a new method vector.  We start with 8 entries.  */
       vec_alloc (method_vec, 8);
       CLASSTYPE_METHOD_VEC (type) = method_vec;
     }
@@ -1045,24 +1031,22 @@ add_method (tree type, tree method, bool via_using)
   /* Maintain TYPE_HAS_USER_CONSTRUCTOR, etc.  */
   grok_special_member_properties (method);
 
+  bool insert_p = true;
+  unsigned slot;
   tree m;
 
-  insert_p = true;
   /* See if we already have an entry with this name.  */
   for (slot = CLASSTYPE_FIRST_CONVERSION_SLOT;
        vec_safe_iterate (method_vec, slot, &m);
        ++slot)
     {
       m = OVL_FIRST (m);
-      if (template_conv_p)
+      if (conv_p)
        {
-         if (TREE_CODE (m) == TEMPLATE_DECL
-             && DECL_TEMPLATE_CONV_FN_P (m))
+         if (DECL_CONV_FN_P (m))
            insert_p = false;
          break;
        }
-      if (conv_p && !DECL_CONV_FN_P (m))
-       break;
       if (DECL_NAME (m) == DECL_NAME (method))
        {
          insert_p = false;
@@ -1073,7 +1057,8 @@ add_method (tree type, tree method, bool via_using)
          && DECL_NAME (m) > DECL_NAME (method))
        break;
     }
-  current_fns = insert_p ? NULL_TREE : (*method_vec)[slot];
+  tree current_fns = insert_p ? NULL_TREE : (*method_vec)[slot];
+  gcc_assert (!DECL_EXTERN_C_P (method));
 
   /* Check to see if we've already got this method.  */
   for (ovl_iterator iter (current_fns); iter; ++iter)
@@ -1216,8 +1201,7 @@ add_method (tree type, tree method, bool via_using)
     }
 
   /* A class should never have more than one destructor.  */
-  if (current_fns && DECL_MAYBE_IN_CHARGE_DESTRUCTOR_P (method))
-    return false;
+  gcc_assert (!current_fns || !DECL_DESTRUCTOR_P (method));
 
   current_fns = ovl_insert (method, current_fns, via_using);
 
index 12c507e..3d69e1d 100644 (file)
@@ -1096,34 +1096,31 @@ lookup_arg_dependent (tree name, tree fns, vec<tree, va_gc> *args)
 static tree
 lookup_conversion_operator (tree class_type, tree type)
 {
-  tree tpls = NULL_TREE;
+  tree convs = NULL_TREE;
 
   if (TYPE_HAS_CONVERSION (class_type))
     {
-      tree fns;
+      tree fns = NULL_TREE;
+      tree tpls = NULL_TREE;
       vec<tree, va_gc> *methods = CLASSTYPE_METHOD_VEC (class_type);
 
-      for (int i = CLASSTYPE_FIRST_CONVERSION_SLOT;
-          vec_safe_iterate (methods, i, &fns); ++i)
+      vec_safe_iterate (methods, CLASSTYPE_FIRST_CONVERSION_SLOT, &fns);
+      if (fns && !DECL_CONV_FN_P (OVL_FIRST (fns)))
+       fns = NULL_TREE;
+      for (ovl_iterator iter (fns); iter; ++iter)
        {
-         /* All the conversion operators come near the beginning of
-            the class.  Therefore, if FN is not a conversion
-            operator, there is no matching conversion operator in
-            CLASS_TYPE.  */
-         tree fn = OVL_FIRST (fns);
-         if (!DECL_CONV_FN_P (fn))
-           break;
+         if (same_type_p (DECL_CONV_FN_TYPE (*iter), type))
+           convs = lookup_add (*iter, convs);
 
-         if (TREE_CODE (fn) == TEMPLATE_DECL)
-           /* All the templated conversion functions are on the same
-              slot, so remember it.  */
-           tpls = fns;
-         else if (same_type_p (DECL_CONV_FN_TYPE (fn), type))
-           return fns;
+         if (TREE_CODE (*iter) == TEMPLATE_DECL)
+           tpls = lookup_add (*iter, tpls);
        }
+
+      if (!convs)
+       convs = tpls;
     }
 
-  return tpls;
+  return convs;
 }
 
 /* TYPE is a class type. Return the member functions in the method
index 9e15b02..31f4dd6 100644 (file)
@@ -38,8 +38,7 @@ static tree dfs_dcast_hint_post (tree, void *);
 static tree dfs_debug_mark (tree, void *);
 static int check_hidden_convs (tree, int, int, tree, tree, tree);
 static tree split_conversions (tree, tree, tree, tree);
-static int lookup_conversions_r (tree, int, int,
-                                tree, tree, tree, tree, tree *, tree *);
+static int lookup_conversions_r (tree, int, int, tree, tree, tree *);
 static int look_for_overrides_r (tree, tree);
 static tree lookup_field_r (tree, void *);
 static tree dfs_accessible_post (tree, void *);
@@ -2333,14 +2332,13 @@ split_conversions (tree my_convs, tree parent_convs,
 }
 
 /* Worker for lookup_conversions.  Lookup conversion functions in
-   BINFO and its children.  VIRTUAL_DEPTH is nonzero, if BINFO is in
-   a morally virtual base, and VIRTUALNESS is nonzero, if we've
-   encountered virtual bases already in the tree walk.  PARENT_CONVS &
-   PARENT_TPL_CONVS are lists of list of conversions within parent
-   binfos.  OTHER_CONVS and OTHER_TPL_CONVS are conversions found
-   elsewhere in the tree.  Return the conversions found within this
-   portion of the graph in CONVS and TPL_CONVS.  Return nonzero is we
-   encountered virtualness.  We keep template and non-template
+   BINFO and its children.  VIRTUAL_DEPTH is nonzero, if BINFO is in a
+   morally virtual base, and VIRTUALNESS is nonzero, if we've
+   encountered virtual bases already in the tree walk.  PARENT_CONVS
+   is a list of conversions within parent binfos.  OTHER_CONVS are
+   conversions found elsewhere in the tree.  Return the conversions
+   found within this portion of the graph in CONVS.  Return nonzero if
+   we encountered virtualness.  We keep template and non-template
    conversions separate, to avoid unnecessary type comparisons.
 
    The located conversion functions are held in lists of lists.  The
@@ -2353,26 +2351,17 @@ split_conversions (tree my_convs, tree parent_convs,
    is the converted-to type.  */
 
 static int
-lookup_conversions_r (tree binfo,
-                     int virtual_depth, int virtualness,
-                     tree parent_convs, tree parent_tpl_convs,
-                     tree other_convs, tree other_tpl_convs,
-                     tree *convs, tree *tpl_convs)
+lookup_conversions_r (tree binfo, int virtual_depth, int virtualness,
+                     tree parent_convs, tree other_convs, tree *convs)
 {
   int my_virtualness = 0;
   tree my_convs = NULL_TREE;
-  tree my_tpl_convs = NULL_TREE;
   tree child_convs = NULL_TREE;
-  tree child_tpl_convs = NULL_TREE;
-  unsigned i;
-  tree base_binfo;
-  vec<tree, va_gc> *method_vec = CLASSTYPE_METHOD_VEC (BINFO_TYPE (binfo));
-  tree conv;
 
   /* If we have no conversion operators, then don't look.  */
   if (!TYPE_HAS_CONVERSION (BINFO_TYPE (binfo)))
     {
-      *convs = *tpl_convs = NULL_TREE;
+      *convs = NULL_TREE;
 
       return 0;
     }
@@ -2381,60 +2370,32 @@ lookup_conversions_r (tree binfo,
     virtual_depth++;
 
   /* First, locate the unhidden ones at this level.  */
-  for (i = CLASSTYPE_FIRST_CONVERSION_SLOT;
-       vec_safe_iterate (method_vec, i, &conv);
-       ++i)
-    {
-      tree cur = OVL_FIRST (conv);
-
-      if (!DECL_CONV_FN_P (cur))
-       break;
+  vec<tree, va_gc> *method_vec = CLASSTYPE_METHOD_VEC (BINFO_TYPE (binfo));
+  tree conv = NULL_TREE;
+  vec_safe_iterate (method_vec, CLASSTYPE_FIRST_CONVERSION_SLOT, &conv);
+  if (conv && !DECL_CONV_FN_P (OVL_FIRST (conv)))
+    conv = NULL_TREE;
 
-      if (TREE_CODE (cur) == TEMPLATE_DECL)
-       /* Only template conversions can be overloaded, and we must
-          flatten them out and check each one individually.  */
-       for (ovl_iterator iter (conv); iter; ++iter)
-         {
-           tree tpl = *iter;
-           tree type = DECL_CONV_FN_TYPE (tpl);
+  for (ovl_iterator iter (conv); iter; ++iter)
+    {
+      tree fn = *iter;
+      tree type = DECL_CONV_FN_TYPE (fn);
 
-           if (check_hidden_convs (binfo, virtual_depth, virtualness,
-                                   type, parent_tpl_convs, other_tpl_convs))
-             {
-               my_tpl_convs = tree_cons (binfo, tpl, my_tpl_convs);
-               TREE_TYPE (my_tpl_convs) = type;
-               if (virtual_depth)
-                 {
-                   TREE_STATIC (my_tpl_convs) = 1;
-                   my_virtualness = 1;
-                 }
-             }
-         }
-      else
+      if (TREE_CODE (fn) != TEMPLATE_DECL && type_uses_auto (type))
        {
-         tree name = DECL_NAME (cur);
+         mark_used (fn);
+         type = DECL_CONV_FN_TYPE (fn);
+       }
 
-         if (!IDENTIFIER_MARKED (name))
+      if (check_hidden_convs (binfo, virtual_depth, virtualness,
+                             type, parent_convs, other_convs))
+       {
+         my_convs = tree_cons (binfo, fn, my_convs);
+         TREE_TYPE (my_convs) = type;
+         if (virtual_depth)
            {
-             tree type = DECL_CONV_FN_TYPE (cur);
-             if (type_uses_auto (type))
-               {
-                 mark_used (cur);
-                 type = DECL_CONV_FN_TYPE (cur);
-               }
-
-             if (check_hidden_convs (binfo, virtual_depth, virtualness,
-                                     type, parent_convs, other_convs))
-               {
-                 my_convs = tree_cons (binfo, conv, my_convs);
-                 TREE_TYPE (my_convs) = type;
-                 if (virtual_depth)
-                   {
-                     TREE_STATIC (my_convs) = 1;
-                     my_virtualness = 1;
-                   }
-                 IDENTIFIER_MARKED (name) = 1;
-               }
+             TREE_STATIC (my_convs) = 1;
+             my_virtualness = 1;
            }
        }
     }
@@ -2446,41 +2407,27 @@ lookup_conversions_r (tree binfo,
        TREE_STATIC (parent_convs) = 1;
     }
 
-  if (my_tpl_convs)
-    {
-      parent_tpl_convs = tree_cons (binfo, my_tpl_convs, parent_tpl_convs);
-      if (virtual_depth)
-       TREE_STATIC (parent_tpl_convs) = 1;
-    }
-
   child_convs = other_convs;
-  child_tpl_convs = other_tpl_convs;
 
   /* Now iterate over each base, looking for more conversions.  */
+  unsigned i;
+  tree base_binfo;
   for (i = 0; BINFO_BASE_ITERATE (binfo, i, base_binfo); i++)
     {
-      tree base_convs, base_tpl_convs;
+      tree base_convs;
       unsigned base_virtualness;
 
       base_virtualness = lookup_conversions_r (base_binfo,
                                               virtual_depth, virtualness,
-                                              parent_convs, parent_tpl_convs,
-                                              child_convs, child_tpl_convs,
-                                              &base_convs, &base_tpl_convs);
+                                              parent_convs, child_convs,
+                                              &base_convs);
       if (base_virtualness)
        my_virtualness = virtualness = 1;
       child_convs = chainon (base_convs, child_convs);
-      child_tpl_convs = chainon (base_tpl_convs, child_tpl_convs);
     }
 
-  /* Unmark the conversions found at this level  */
-  for (conv = my_convs; conv; conv = TREE_CHAIN (conv))
-    IDENTIFIER_MARKED (OVL_NAME (TREE_VALUE (conv))) = 0;
-
   *convs = split_conversions (my_convs, parent_convs,
                              child_convs, other_convs);
-  *tpl_convs = split_conversions (my_tpl_convs, parent_tpl_convs,
-                                 child_tpl_convs, other_tpl_convs);
 
   return my_virtualness;
 }
@@ -2497,17 +2444,16 @@ lookup_conversions_r (tree binfo,
 tree
 lookup_conversions (tree type)
 {
-  tree convs, tpl_convs;
-  tree list = NULL_TREE;
+  tree convs;
 
   complete_type (type);
   if (!CLASS_TYPE_P (type) || !TYPE_BINFO (type))
     return NULL_TREE;
 
-  lookup_conversions_r (TYPE_BINFO (type), 0, 0,
-                       NULL_TREE, NULL_TREE, NULL_TREE, NULL_TREE,
-                       &convs, &tpl_convs);
+  lookup_conversions_r (TYPE_BINFO (type), 0, 0, NULL_TREE, NULL_TREE, &convs);
 
+  tree list = NULL_TREE;
+  
   /* Flatten the list-of-lists */
   for (; convs; convs = TREE_CHAIN (convs))
     {
@@ -2522,19 +2468,6 @@ lookup_conversions (tree type)
        }
     }
 
-  for (; tpl_convs; tpl_convs = TREE_CHAIN (tpl_convs))
-    {
-      tree probe, next;
-
-      for (probe = TREE_VALUE (tpl_convs); probe; probe = next)
-       {
-         next = TREE_CHAIN (probe);
-
-         TREE_CHAIN (probe) = list;
-         list = probe;
-       }
-    }
-
   return list;
 }