[c++]: Unconfuse lookup_name_real API a bit
authorNathan Sidwell <nathan@acm.org>
Thu, 13 Aug 2020 17:59:00 +0000 (10:59 -0700)
committerNathan Sidwell <nathan@acm.org>
Thu, 13 Aug 2020 18:16:42 +0000 (11:16 -0700)
The API for lookup_name_real is really confusing.  This addresses the part
where we have NONCLASS to say DON'T search class scopes, and BLOCK_P to say
DO search block scopes.  I've added a single bitmask to explicitly say which
scopes to search.  I used an enum class so one can't accidentally misorder
it.  It's also reordered so we don't mix it up with the parameters that say
what kind of thing we're looking for.

gcc/cp/
* name-lookup.h (enum class LOOK_where): New.
(operator|, operator&): Overloads for it.
(lookup_name_real): Replace NONCLASS & BLOCK_P parms with WHERE.
* name-lookup.c (identifier_type_value_w): Adjust
lookup_name_real call.
(lookup_name_real_1): Replace NONCLASS and BLOCK_P parameters
with WHERE bitmask. Don't search namespaces if not asked to.
(lookup_name_real): Adjust lookup_name_real_1 call.
(lookup_name_nonclass, lookup_name)
(lookup_name_prefer_type): Likewise.
* call.c (build_operator_new_call)
(add_operator_candidates): Adjust lookup_name_real calls.
* parser.c (cp_parser_lookup_name): Likewise.
* pt.c (tsubst_friend_class, lookup_init_capture_pack)
(tsubst_expr): Likewise.
* semantics.c (capture_decltype): Likewise.
libcc1/
* libcp1plugin.cc (plugin_build_dependent_expr): Likewise.

gcc/cp/call.c
gcc/cp/name-lookup.c
gcc/cp/name-lookup.h
gcc/cp/parser.c
gcc/cp/pt.c
gcc/cp/semantics.c
libcc1/libcp1plugin.cc

index f164b211c9f58585f9bc9894f4be74141233b51a..47a368d069da452d08a84622a98e005595b8a269 100644 (file)
@@ -4704,7 +4704,7 @@ build_operator_new_call (tree fnname, vec<tree, va_gc> **args,
        up in the global scope.
 
      we disregard block-scope declarations of "operator new".  */
-  fns = lookup_name_real (fnname, 0, 1, /*block_p=*/false, 0, 0);
+  fns = lookup_name_real (fnname, LOOK_where::NAMESPACE, 0, 0, 0);
   fns = lookup_arg_dependent (fnname, fns, *args);
 
   if (align_arg)
@@ -5982,7 +5982,8 @@ add_operator_candidates (z_candidate **candidates,
      consider.  */
   if (!memonly)
     {
-      tree fns = lookup_name_real (fnname, 0, 1, /*block_p=*/true, 0, 0);
+      tree fns = lookup_name_real (fnname, LOOK_where::BLOCK_NAMESPACE,
+                                  0, 0, 0);
       fns = lookup_arg_dependent (fnname, fns, arglist);
       add_candidates (fns, NULL_TREE, arglist, NULL_TREE,
                      NULL_TREE, false, NULL_TREE, NULL_TREE,
index 9f30d907a0909764fe118f1ca00b4984cb7ccaf6..4fdac9421d16d86c6b183b1ed62f61f2b5aa7716 100644 (file)
@@ -3741,7 +3741,7 @@ identifier_type_value_1 (tree id)
     return REAL_IDENTIFIER_TYPE_VALUE (id);
   /* Have to search for it. It must be on the global level, now.
      Ask lookup_name not to return non-types.  */
-  id = lookup_name_real (id, 2, 1, /*block_p=*/true, 0, 0);
+  id = lookup_name_real (id, LOOK_where::BLOCK_NAMESPACE, 2, 0, 0);
   if (id)
     return TREE_TYPE (id);
   return NULL_TREE;
@@ -6413,10 +6413,16 @@ innermost_non_namespace_value (tree name)
    namespace of variables, functions and typedefs.  Return a ..._DECL
    node of some kind representing its definition if there is only one
    such declaration, or return a TREE_LIST with all the overloaded
-   definitions if there are many, or return 0 if it is undefined.
+   definitions if there are many, or return NULL_TREE if it is undefined.
    Hidden name, either friend declaration or built-in function, are
    not ignored.
 
+   WHERE controls which scopes are considered.  It is a bit mask of
+   LOOKUP_where::BLOCK (look in block scope), LOOKUP_where::CLASS
+   (look in class scopes) & LOOKUP_where::NAMESPACE (look in namespace
+   scopes).  It is an error for no bits to be set.  These scopes are
+   searched from innermost to outermost.
+
    If PREFER_TYPE is > 0, we prefer TYPE_DECLs or namespaces.
    If PREFER_TYPE is > 1, we reject non-type decls (e.g. namespaces).
    Otherwise we prefer non-TYPE_DECLs.
@@ -6425,12 +6431,14 @@ innermost_non_namespace_value (tree name)
    BLOCK_P is false, bindings in block scopes are ignored.  */
 
 static tree
-lookup_name_real_1 (tree name, int prefer_type, int nonclass, bool block_p,
+lookup_name_real_1 (tree name, LOOK_where where, int prefer_type,
                    int namespaces_only, int flags)
 {
   cxx_binding *iter;
   tree val = NULL_TREE;
 
+  gcc_checking_assert (unsigned (where) != 0);
+
   query_oracle (name);
 
   /* Conversion operators are handled specially because ordinary
@@ -6468,17 +6476,19 @@ lookup_name_real_1 (tree name, int prefer_type, int nonclass, bool block_p,
   /* First, look in non-namespace scopes.  */
 
   if (current_class_type == NULL_TREE)
-    nonclass = 1;
+    /* Maybe avoid searching the binding stack at all.  */
+    where = LOOK_where (unsigned (where) & ~unsigned (LOOK_where::CLASS));
 
-  if (block_p || !nonclass)
-    for (iter = outer_binding (name, NULL, !nonclass);
+  if (where & (LOOK_where::BLOCK | LOOK_where::CLASS))
+    for (iter = outer_binding (name, NULL, where & LOOK_where::CLASS);
         iter;
-        iter = outer_binding (name, iter, !nonclass))
+        iter = outer_binding (name, iter, where & LOOK_where::CLASS))
       {
        tree binding;
 
        /* Skip entities we don't want.  */
-       if (LOCAL_BINDING_P (iter) ? !block_p : nonclass)
+       if (!(where & (LOCAL_BINDING_P (iter)
+                      ? LOOK_where::BLOCK : LOOK_where::CLASS)))
          continue;
 
        /* If this is the kind of thing we're looking for, we're done.  */
@@ -6548,7 +6558,7 @@ lookup_name_real_1 (tree name, int prefer_type, int nonclass, bool block_p,
       }
 
   /* Now lookup in namespace scopes.  */
-  if (!val)
+  if (!val && (where & LOOK_where::NAMESPACE))
     {
       name_lookup lookup (name, flags);
       if (lookup.search_unqualified
@@ -6566,12 +6576,12 @@ lookup_name_real_1 (tree name, int prefer_type, int nonclass, bool block_p,
 /* Wrapper for lookup_name_real_1.  */
 
 tree
-lookup_name_real (tree name, int prefer_type, int nonclass, bool block_p,
+lookup_name_real (tree name, LOOK_where where, int prefer_type,
                  int namespaces_only, int flags)
 {
   tree ret;
   bool subtime = timevar_cond_start (TV_NAME_LOOKUP);
-  ret = lookup_name_real_1 (name, prefer_type, nonclass, block_p,
+  ret = lookup_name_real_1 (name, where, prefer_type,
                            namespaces_only, flags);
   timevar_cond_stop (TV_NAME_LOOKUP, subtime);
   return ret;
@@ -6580,19 +6590,20 @@ lookup_name_real (tree name, int prefer_type, int nonclass, bool block_p,
 tree
 lookup_name_nonclass (tree name)
 {
-  return lookup_name_real (name, 0, 1, /*block_p=*/true, 0, 0);
+  return lookup_name_real (name, LOOK_where::BLOCK_NAMESPACE,
+                          0, 0, 0);
 }
 
 tree
 lookup_name (tree name)
 {
-  return lookup_name_real (name, 0, 0, /*block_p=*/true, 0, 0);
+  return lookup_name_real (name, LOOK_where::ALL, 0, 0, 0);
 }
 
 tree
 lookup_name_prefer_type (tree name, int prefer_type)
 {
-  return lookup_name_real (name, prefer_type, 0, /*block_p=*/true, 0, 0);
+  return lookup_name_real (name, LOOK_where::ALL, prefer_type, 0, 0);
 }
 
 /* Look up NAME for type used in elaborated name specifier in
index 9a1859368532d7665545c3c20f7167cd93caad89..4368c14d48cec27d1d9b6d96b981847c3d5e57af 100644 (file)
@@ -278,8 +278,33 @@ extern void push_binding_level (cp_binding_level *);
 extern bool handle_namespace_attrs (tree, tree);
 extern void pushlevel_class (void);
 extern void poplevel_class (void);
+
+/* What kind of scopes name lookup looks in.  An enum class so we
+   don't accidentally mix integers.  */
+enum class LOOK_where
+{
+  BLOCK = 1 << 0,  /* Consider block scopes.  */ 
+  CLASS = 1 << 1,  /* Consider class scopes.  */ 
+  NAMESPACE = 1 << 2,  /* Consider namespace scopes.  */ 
+
+  ALL = BLOCK | CLASS | NAMESPACE,
+  BLOCK_NAMESPACE = BLOCK | NAMESPACE,
+  CLASS_NAMESPACE = CLASS | NAMESPACE,
+};
+constexpr LOOK_where operator| (LOOK_where a, LOOK_where b)
+{
+  return LOOK_where (unsigned (a) | unsigned (b));
+}
+constexpr bool operator& (LOOK_where a, LOOK_where b)
+{
+  return 0 != (unsigned (a) & unsigned (b));
+}
+
 extern tree lookup_name_prefer_type (tree, int);
-extern tree lookup_name_real (tree, int, int, bool, int, int);
+
+
+extern tree lookup_name_real (tree, LOOK_where, int prefer_type,
+                             int namespaces_only, int flags);
 extern tree lookup_type_scope (tree, tag_scope);
 extern tree get_namespace_binding (tree ns, tree id);
 extern void set_global_binding (tree decl);
index 981c625a3cdd5e3623de194f224f42fdc91e831a..2c45a3d6f41b461e2823bd3572987e1c11ee4e5d 100644 (file)
@@ -28459,17 +28459,17 @@ cp_parser_lookup_name (cp_parser *parser, tree name,
       if (!decl)
        /* Look it up in the enclosing context.  DR 141: When looking for a
           template-name after -> or ., only consider class templates.  */
-       decl = lookup_name_real (name, prefer_type_arg (tag_type, is_template),
-                                /*nonclass=*/0,
-                                /*block_p=*/true, is_namespace, 0);
+       decl = lookup_name_real (name, LOOK_where::ALL,
+                                prefer_type_arg (tag_type, is_template),
+                                is_namespace, 0);
       parser->object_scope = object_type;
       parser->qualifying_scope = NULL_TREE;
     }
   else
     {
-      decl = lookup_name_real (name, prefer_type_arg (tag_type),
-                              /*nonclass=*/0,
-                              /*block_p=*/true, is_namespace, 0);
+      decl = lookup_name_real (name, LOOK_where::ALL,
+                              prefer_type_arg (tag_type),
+                              is_namespace, 0);
       parser->qualifying_scope = NULL_TREE;
       parser->object_scope = NULL_TREE;
     }
index cb81d8e9229bb41518d9b8b077c08d85bb6dafd7..5fd16bf781cd8ecebb4063f13c6bfd5960c2b4c0 100644 (file)
@@ -11183,9 +11183,9 @@ tsubst_friend_class (tree friend_tmpl, tree args)
       push_nested_class (context);
     }
 
-  tmpl = lookup_name_real (DECL_NAME (friend_tmpl), /*prefer_type=*/false,
-                          /*non_class=*/false, /*block_p=*/false,
-                          /*namespaces_only=*/false, LOOKUP_HIDDEN);
+  tmpl = lookup_name_real (DECL_NAME (friend_tmpl), LOOK_where::CLASS_NAMESPACE,
+                          /*prefer_type=*/0, /*namespaces_only=*/false,
+                          LOOKUP_HIDDEN);
 
   if (tmpl && DECL_CLASS_TEMPLATE_P (tmpl))
     {
@@ -17835,7 +17835,7 @@ lookup_init_capture_pack (tree decl)
   for (int i = 0; i < len; ++i)
     {
       tree ename = vec ? make_ith_pack_parameter_name (cname, i) : cname;
-      tree elt = lookup_name_real (ename, 0, 0, true, 0, LOOKUP_NORMAL);
+      tree elt = lookup_name_real (ename, LOOK_where::ALL, 0, 0, LOOKUP_NORMAL);
       if (vec)
        TREE_VEC_ELT (vec, i) = elt;
       else
@@ -17940,9 +17940,10 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl,
            tree inst;
            if (!DECL_PACK_P (decl))
              {
-               inst = lookup_name_real (DECL_NAME (decl), /*prefer_type*/0,
-                                        /*nonclass*/1, /*block_p=*/true,
-                                        /*ns_only*/0, LOOKUP_HIDDEN);
+               inst = lookup_name_real (DECL_NAME (decl),
+                                        LOOK_where::BLOCK_NAMESPACE,
+                                        /*prefer_type*/0, /*ns_only*/0,
+                                        LOOKUP_HIDDEN);
                gcc_assert (inst != decl && is_capture_proxy (inst));
              }
            else if (is_normal_capture_proxy (decl))
index 3096fe834336fc86acaece27328136d3f23ddf1e..e979a8b716c6e50d4216789cd0a4eb02734afd6f 100644 (file)
@@ -10322,8 +10322,8 @@ static tree
 capture_decltype (tree decl)
 {
   tree lam = CLASSTYPE_LAMBDA_EXPR (DECL_CONTEXT (current_function_decl));
-  tree cap = lookup_name_real (DECL_NAME (decl), /*type*/0, /*nonclass*/1,
-                              /*block_p=*/true, /*ns*/0, LOOKUP_HIDDEN);
+  tree cap = lookup_name_real (DECL_NAME (decl), LOOK_where::BLOCK_NAMESPACE,
+                              /*type*/0, /*ns*/false, LOOKUP_HIDDEN);
   tree type;
 
   if (cap && is_capture_proxy (cap))
index 01aecf00735f84043fef100b25043837c6af3fc7..24582c74a86daea3d908789170af113cd45cfdd5 100644 (file)
@@ -2652,7 +2652,7 @@ plugin_build_dependent_expr (cc1_plugin::connection *self,
     }
   tree res = identifier;
   if (!scope)
-    res = lookup_name_real (res, 0, 0, true, 0, 0);
+    res = lookup_name_real (res, LOOK_where::BLOCK_NAMESPACE, 0, 0, 0);
   else if (!TYPE_P (scope) || !dependent_scope_p (scope))
     {
       res = lookup_qualified_name (scope, res, false, true);