name-lookup.h (lookup_field_1): Delete.
authorNathan Sidwell <nathan@acm.org>
Wed, 6 Sep 2017 15:32:46 +0000 (15:32 +0000)
committerNathan Sidwell <nathan@gcc.gnu.org>
Wed, 6 Sep 2017 15:32:46 +0000 (15:32 +0000)
* name-lookup.h (lookup_field_1): Delete.
(get_class_binding_direct, get_class_binding): Add type_or_fns arg.
* name-lookup.c (lookup_field_1): make static
(method_vec_binary_search, method_vec_linear_search): New.  Broken
out of ...
(get_class_binding_direct): ... here.  Add TYPE_OR_FNS argument.
Do complete search of this level.
(get_class_binding): Adjust.
* decl.c (reshape_init_class): Call get_class_binding.
* search.c (lookup_field_r): Move field searching into
get_class_binding_direct.

From-SVN: r251808

gcc/cp/ChangeLog
gcc/cp/decl.c
gcc/cp/name-lookup.c
gcc/cp/name-lookup.h
gcc/cp/search.c

index a48237235ba5e79474ca7f6e6b9c1799ccd57ad2..c1546308f7cc19b21a9622343b64af305c4745f0 100644 (file)
@@ -1,5 +1,17 @@
 2017-09-06  Nathan Sidwell  <nathan@acm.org>
 
+       * name-lookup.h (lookup_field_1): Delete.
+       (get_class_binding_direct, get_class_binding): Add type_or_fns arg.
+       * name-lookup.c (lookup_field_1): make static
+       (method_vec_binary_search, method_vec_linear_search): New.  Broken
+       out of ...
+       (get_class_binding_direct): ... here.  Add TYPE_OR_FNS argument.
+       Do complete search of this level.
+       (get_class_binding): Adjust.
+       * decl.c (reshape_init_class): Call get_class_binding.
+       * search.c (lookup_field_r): Move field searching into
+       get_class_binding_direct.
+
        * class.c (warn_hidden): Don't barf on non-functions.
        * decl2.c (check_classfn): Likewise.  Check template match earlier.
 
index 655445b9c8e110d0a9cd1a24835912ab71fe4741..6f3a348f9fdf5f3a06909f3ce73d0498b995c4e3 100644 (file)
@@ -5746,7 +5746,7 @@ reshape_init_class (tree type, reshape_iter *d, bool first_initializer_p,
            /* We already reshaped this.  */
            gcc_assert (d->cur->index == field);
          else if (TREE_CODE (d->cur->index) == IDENTIFIER_NODE)
-           field = lookup_field_1 (type, d->cur->index, /*want_type=*/false);
+           field = get_class_binding (type, d->cur->index, false);
          else
            {
              if (complain & tf_error)
index ccfb630e4dd2d2a3e2beb020bf591bf939c21a0f..7549edd1dbac49c32953d1021cf0c79c6caf956d 100644 (file)
@@ -1113,79 +1113,54 @@ extract_conversion_operator (tree fns, tree type)
   return convs;
 }
 
-/* TYPE is a class type. Return the member functions in the method
-   vector with name NAME.  Does not lazily declare implicitly-declared
-   member functions.  */
+/* Binary search of (ordered) METHOD_VEC for NAME.  */
 
-tree
-get_class_binding_direct (tree type, tree name)
+static tree
+method_vec_binary_search (vec<tree, va_gc> *method_vec, tree name)
 {
-  vec<tree, va_gc> *method_vec = CLASSTYPE_METHOD_VEC (type);
-  if (!method_vec)
-    return NULL_TREE;
-
-  /* Conversion operators can only be found by the marker conversion
-     operator name.  */
-  bool conv_op = IDENTIFIER_CONV_OP_P (name);
-  tree lookup = conv_op ? conv_op_identifier : name;
-  tree val = NULL_TREE;
-  tree fns;
-
-  /* If the type is complete, use binary search.  */
-  if (COMPLETE_TYPE_P (type))
+  for (unsigned lo = 0, hi = method_vec->length (); lo < hi;)
     {
-      int lo = 0;
-      int hi = method_vec->length ();
-      while (lo < hi)
-       {
-         int i = (lo + hi) / 2;
+      unsigned mid = (lo + hi) / 2;
+      tree binding = (*method_vec)[mid];
+      tree binding_name = OVL_NAME (binding);
 
-         fns = (*method_vec)[i];
-         tree fn_name = OVL_NAME (fns);
-         if (fn_name > lookup)
-           hi = i;
-         else if (fn_name < lookup)
-           lo = i + 1;
-         else
-           {
-             val = fns;
-             break;
-           }
-       }
+      if (binding_name > name)
+       hi = mid;
+      else if (binding_name < name)
+       lo = mid + 1;
+      else
+       return binding;
     }
-  else
-    for (int i = 0; vec_safe_iterate (method_vec, i, &fns); ++i)
-      /* We can get a NULL binding during insertion of a new
-        method name, because the identifier_binding machinery
-        performs a lookup.  If we find such a NULL slot, that's
-        the thing we were looking for, so we might as well bail
-        out immediately.  */
-      if (!fns)
-       break;
-      else if (OVL_NAME (fns) == lookup)
-       {
-         val = fns;
-         break;
-       }
 
-  /* Extract the conversion operators asked for, unless the general
-     conversion operator was requested.   */
-  if (val && conv_op)
-    {
-      gcc_checking_assert (OVL_FUNCTION (val) == conv_op_marker);
-      val = OVL_CHAIN (val);
-      if (tree type = TREE_TYPE (name))
-       val = extract_conversion_operator (val, type);
-    }
+  return NULL_TREE;
+}
 
-  return val;
+/* Linear search of (unordered) METHOD_VEC for NAME.  */
+
+static tree
+method_vec_linear_search (vec<tree, va_gc> *method_vec, tree name)
+{
+  for (int ix = method_vec->length (); ix--;)
+    /* We can get a NULL binding during insertion of a new method
+       name, because the identifier_binding machinery performs a
+       lookup.  If we find such a NULL slot, that's the thing we were
+       looking for, so we might as well bail out immediately.  */
+    if (tree binding = (*method_vec)[ix])
+      {
+       if (OVL_NAME (binding) == name)
+         return binding;
+      }
+    else
+      break;
+
+  return NULL_TREE;
 }
 
 /* Do a 1-level search for NAME as a member of TYPE.  The caller must
    figure out whether it can access this field.  (Since it is only one
    level, this is reasonable.)  */
 
-tree
+static tree
 lookup_field_1 (tree type, tree name, bool want_type)
 {
   tree field;
@@ -1281,11 +1256,62 @@ lookup_field_1 (tree type, tree name, bool want_type)
   return NULL_TREE;
 }
 
-/* TYPE is a class type. Return the overloads in
-   the method vector with name NAME.  Lazily create ctors etc.  */
+/* Look for NAME as an immediate member of KLASS (including
+   anon-members or unscoped enum member).  TYPE_OR_FNS is zero for
+   regular search.  >0 to get a type binding (if there is one) and <0
+   if you want (just) the member function binding.
+
+   Use this if you do not want lazy member creation.  */
+
+tree
+get_class_binding_direct (tree klass, tree name, int type_or_fns)
+{
+  gcc_checking_assert (RECORD_OR_UNION_TYPE_P (klass));
+
+  /* Conversion operators can only be found by the marker conversion
+     operator name.  */
+  bool conv_op = IDENTIFIER_CONV_OP_P (name);
+  tree lookup = conv_op ? conv_op_identifier : name;
+  tree val = NULL_TREE;
+
+  if (type_or_fns > 0)
+    /* User wants type.  Don't look in method_vec.  */;
+  else if (vec<tree, va_gc> *method_vec = CLASSTYPE_METHOD_VEC (klass))
+    {
+      if (COMPLETE_TYPE_P (klass))
+       val = method_vec_binary_search (method_vec, lookup);
+      else
+       val = method_vec_linear_search (method_vec, lookup);
+    }
+
+  if (type_or_fns < 0)
+    /* User wants functions.  Don't look for a field. */;
+  else if (!val || (TREE_CODE (val) == OVERLOAD && OVL_USING_P (val)))
+    /* Dependent using declarations are a 'field', make sure we
+       return that even if we saw an overload already.  */
+    if (tree field_val = lookup_field_1 (klass, lookup, type_or_fns > 0))
+      if (!val || TREE_CODE (field_val) == USING_DECL)
+       val = field_val;
+
+  /* Extract the conversion operators asked for, unless the general
+     conversion operator was requested.   */
+  if (val && conv_op)
+    {
+      gcc_checking_assert (OVL_FUNCTION (val) == conv_op_marker);
+      val = OVL_CHAIN (val);
+      if (tree type = TREE_TYPE (name))
+       val = extract_conversion_operator (val, type);
+    }
+
+  return val;
+}
+
+/* Look for NAME's binding in exactly KLASS.  See
+   get_class_binding_direct for argument description.  Does lazy
+   special function creation as necessary.  */
 
 tree
-get_class_binding (tree type, tree name)
+get_class_binding (tree type, tree name, int type_or_fns)
 {
   type = complete_type (type);
 
@@ -1314,7 +1340,7 @@ get_class_binding (tree type, tree name)
        }
     }
 
-  return get_class_binding_direct (type, name);
+  return get_class_binding_direct (type, name, type_or_fns);
 }
 
 /* Find the slot containing overloads called 'NAME'.  If there is no
index 0051bfcced9369ec1c0b6eea7bc75dbd40d25711..3bc06d7da9847c40115d46baf501acc2e4fa56ec 100644 (file)
@@ -319,9 +319,8 @@ extern void pop_decl_namespace (void);
 extern void do_namespace_alias (tree, tree);
 extern tree do_class_using_decl (tree, tree);
 extern tree lookup_arg_dependent (tree, tree, vec<tree, va_gc> *);
-extern tree lookup_field_1                     (tree, tree, bool);
-extern tree get_class_binding_direct (tree, tree);
-extern tree get_class_binding (tree, tree);
+extern tree get_class_binding_direct (tree, tree, int type_or_fns = -1);
+extern tree get_class_binding (tree, tree, int type_or_fns = -1);
 extern tree *get_method_slot (tree klass, tree name);
 extern void resort_type_method_vec (void *, void *,
                                    gt_pointer_operator, void *);
index 38be467b7c6fc555541a78a9db0a85f82b434688..11e721fc056e0c2970618b59e06ea8ccdfac80bd 100644 (file)
@@ -974,23 +974,7 @@ lookup_field_r (tree binfo, void *data)
       && !BINFO_VIRTUAL_P (binfo))
     return dfs_skip_bases;
 
-  /* First, look for a function.  There can't be a function and a data
-     member with the same name, and if there's a function and a type
-     with the same name, the type is hidden by the function.  */
-  if (!lfi->want_type)
-    nval = get_class_binding (type, lfi->name);
-
-  if (!nval)
-    /* Look for a data member or type.  */
-    nval = lookup_field_1 (type, lfi->name, lfi->want_type);
-  else if (TREE_CODE (nval) == OVERLOAD && OVL_USING_P (nval))
-    {
-      /* If we have both dependent and non-dependent using-declarations, return
-        the dependent one rather than an incomplete list of functions.  */
-      tree dep_using = lookup_field_1 (type, lfi->name, lfi->want_type);
-      if (dep_using && TREE_CODE (dep_using) == USING_DECL)
-       nval = dep_using;
-    }
+  nval = get_class_binding (type, lfi->name, lfi->want_type);
 
   /* If we're looking up a type (as with an elaborated type specifier)
      we ignore all non-types we find.  */