c++: Replace tag_scope with TAG_how
authorNathan Sidwell <nathan@acm.org>
Fri, 25 Sep 2020 17:24:09 +0000 (10:24 -0700)
committerNathan Sidwell <nathan@acm.org>
Fri, 25 Sep 2020 17:28:19 +0000 (10:28 -0700)
I always found tag_scope confusing, as it is not a scope, but a
direction of how to lookup or insert an elaborated type tag.  This
replaces it with a enum class TAG_how.  I also add a new value,
HIDDEN_FRIEND, to distinguish the two cases of innermost-non-class
insertion that we currently conflate.  Also renamed
'lookup_type_scope' to 'lookup_elaborated_type', because again, we're
not providing a scope to lookup in.

gcc/cp/
* name-lookup.h (enum tag_scope): Replace with ...
(enum class TAG_how): ... this.  Add HIDDEN_FRIEND value.
(lookup_type_scope): Replace with ...
(lookup_elaborated_type): ... this.
(pushtag): Use TAG_how, not tag_scope.
* cp-tree.h (xref_tag): Parameter is TAG_how, not tag_scope.
* decl.c (lookup_and_check_tag): Likewise.  Adjust.
(xref_tag_1, xref_tag): Likewise. adjust.
(start_enum): Adjust lookup_and_check_tag call.
* name-lookup.c (lookup_type_scope_1): Rename to ...
(lookup_elaborated_type_1) ... here. Use TAG_how, not tag_scope.
(lookup_type_scope): Rename to ...
(lookup_elaborated_type): ... here.  Use TAG_how, not tag_scope.
(do_pushtag): Use TAG_how, not tag_scope.  Adjust.
(pushtag): Likewise.
* parser.c (cp_parser_elaborated_type_specifier): Adjust.
(cp_parser_class_head): Likewise.
gcc/objcp/
* objcp-decl.c (objcp_start_struct): Use TAG_how not tag_scope.
(objcp_xref_tag): Likewise.

gcc/cp/cp-tree.h
gcc/cp/decl.c
gcc/cp/name-lookup.c
gcc/cp/name-lookup.h
gcc/cp/parser.c
gcc/objcp/objcp-decl.c

index bd78f00..321bb95 100644 (file)
@@ -6507,7 +6507,7 @@ extern void grok_special_member_properties        (tree);
 extern bool grok_ctor_properties               (const_tree, const_tree);
 extern bool grok_op_properties                 (tree, bool);
 extern tree xref_tag                           (tag_types, tree,
-                                                tag_scope = ts_current,
+                                                TAG_how = TAG_how::CURRENT_ONLY,
                                                 bool tpl_header_p = false);
 extern void xref_basetypes                     (tree, tree);
 extern tree start_enum                         (tree, tree, tree, tree, bool, bool *);
index 1709dd9..b481bbd 100644 (file)
@@ -75,7 +75,7 @@ static void record_unknown_type (tree, const char *);
 static int member_function_or_else (tree, tree, enum overload_flags);
 static tree local_variable_p_walkfn (tree *, int *, void *);
 static const char *tag_name (enum tag_types);
-static tree lookup_and_check_tag (enum tag_types, tree, tag_scope, bool);
+static tree lookup_and_check_tag (enum tag_types, tree, TAG_how, bool);
 static void maybe_deduce_size_from_array_init (tree, tree);
 static void layout_var_decl (tree);
 static tree check_initializer (tree, tree, int, vec<tree, va_gc> **);
@@ -14862,11 +14862,10 @@ check_elaborated_type_specifier (enum tag_types tag_code,
 
 static tree
 lookup_and_check_tag (enum tag_types tag_code, tree name,
-                     tag_scope scope, bool template_header_p)
+                     TAG_how how, bool template_header_p)
 {
-  tree t;
   tree decl;
-  if (scope == ts_global)
+  if (how == TAG_how::GLOBAL)
     {
       /* First try ordinary name lookup, ignoring hidden class name
         injected via friend declaration.  */
@@ -14879,16 +14878,16 @@ lookup_and_check_tag (enum tag_types tag_code, tree name,
         If we find one, that name will be made visible rather than
         creating a new tag.  */
       if (!decl)
-       decl = lookup_type_scope (name, ts_within_enclosing_non_class);
+       decl = lookup_elaborated_type (name, TAG_how::INNERMOST_NON_CLASS);
     }
   else
-    decl = lookup_type_scope (name, scope);
+    decl = lookup_elaborated_type (name, how);
 
   if (decl
       && (DECL_CLASS_TEMPLATE_P (decl)
-         /* If scope is ts_current we're defining a class, so ignore a
-            template template parameter.  */
-         || (scope != ts_current
+         /* If scope is TAG_how::CURRENT_ONLY we're defining a class,
+            so ignore a template template parameter.  */
+         || (how != TAG_how::CURRENT_ONLY
              && DECL_TEMPLATE_TEMPLATE_PARM_P (decl))))
     decl = DECL_TEMPLATE_RESULT (decl);
 
@@ -14898,11 +14897,10 @@ lookup_and_check_tag (enum tag_types tag_code, tree name,
           class C {
             class C {};
           };  */
-      if (scope == ts_current && DECL_SELF_REFERENCE_P (decl))
+      if (how == TAG_how::CURRENT_ONLY && DECL_SELF_REFERENCE_P (decl))
        {
          error ("%qD has the same name as the class in which it is "
-                "declared",
-                decl);
+                "declared", decl);
          return error_mark_node;
        }
 
@@ -14922,10 +14920,10 @@ lookup_and_check_tag (enum tag_types tag_code, tree name,
             class C *c2;               // DECL_SELF_REFERENCE_P is true
           };  */
 
-      t = check_elaborated_type_specifier (tag_code,
-                                          decl,
-                                          template_header_p
-                                          | DECL_SELF_REFERENCE_P (decl));
+      tree t = check_elaborated_type_specifier (tag_code,
+                                               decl,
+                                               template_header_p
+                                               | DECL_SELF_REFERENCE_P (decl));
       if (template_header_p && t && CLASS_TYPE_P (t)
          && (!CLASSTYPE_TEMPLATE_INFO (t)
              || (!PRIMARY_TEMPLATE_P (CLASSTYPE_TI_TEMPLATE (t)))))
@@ -14969,7 +14967,7 @@ lookup_and_check_tag (enum tag_types tag_code, tree name,
 
 static tree
 xref_tag_1 (enum tag_types tag_code, tree name,
-            tag_scope scope, bool template_header_p)
+            TAG_how how, bool template_header_p)
 {
   enum tree_code code;
   tree context = NULL_TREE;
@@ -14996,22 +14994,22 @@ xref_tag_1 (enum tag_types tag_code, tree name,
      make type node and push name.  Name lookup is not required.  */
   tree t = NULL_TREE;
   if (!IDENTIFIER_ANON_P (name))
-    t = lookup_and_check_tag  (tag_code, name, scope, template_header_p);
+    t = lookup_and_check_tag  (tag_code, name, how, template_header_p);
 
   if (t == error_mark_node)
     return error_mark_node;
 
-  if (scope != ts_current && t && current_class_type
+  if (how != TAG_how::CURRENT_ONLY && t && current_class_type
       && template_class_depth (current_class_type)
       && template_header_p)
     {
       if (TREE_CODE (t) == TEMPLATE_TEMPLATE_PARM)
        return t;
 
-      /* Since SCOPE is not TS_CURRENT, we are not looking at a
-        definition of this tag.  Since, in addition, we are currently
-        processing a (member) template declaration of a template
-        class, we must be very careful; consider:
+      /* Since HOW is not TAG_how::CURRENT_ONLY, we are not looking at
+        a definition of this tag.  Since, in addition, we are
+        currently processing a (member) template declaration of a
+        template class, we must be very careful; consider:
 
           template <class X> struct S1
 
@@ -15057,7 +15055,7 @@ xref_tag_1 (enum tag_types tag_code, tree name,
        /* Mark it as a lambda type right now.  Our caller will
           correct the value.  */
        CLASSTYPE_LAMBDA_EXPR (t) = error_mark_node;
-      t = pushtag (name, t, scope);
+      t = pushtag (name, t, how);
     }
   else
     {
@@ -15083,7 +15081,7 @@ xref_tag_1 (enum tag_types tag_code, tree name,
          return error_mark_node;
        }
 
-      if (scope != ts_within_enclosing_non_class && TYPE_HIDDEN_P (t))
+      if (how != TAG_how::HIDDEN_FRIEND && TYPE_HIDDEN_P (t))
        {
          /* This is no longer an invisible friend.  Make it
             visible.  */
@@ -15108,12 +15106,10 @@ xref_tag_1 (enum tag_types tag_code, tree name,
 
 tree
 xref_tag (enum tag_types tag_code, tree name,
-          tag_scope scope, bool template_header_p)
+         TAG_how how, bool template_header_p)
 {
-  tree ret;
-  bool subtime;
-  subtime = timevar_cond_start (TV_NAME_LOOKUP);
-  ret = xref_tag_1 (tag_code, name, scope, template_header_p);
+  bool subtime = timevar_cond_start (TV_NAME_LOOKUP);
+  tree ret = xref_tag_1 (tag_code, name, how, template_header_p);
   timevar_cond_stop (TV_NAME_LOOKUP, subtime);
   return ret;
 }
@@ -15412,7 +15408,7 @@ start_enum (tree name, tree enumtype, tree underlying_type,
      forward reference.  */
   if (!enumtype)
     enumtype = lookup_and_check_tag (enum_type, name,
-                                    /*tag_scope=*/ts_current,
+                                    /*tag_scope=*/TAG_how::CURRENT_ONLY,
                                     /*template_header_p=*/false);
 
   /* In case of a template_decl, the only check that should be deferred
index dbc6cc3..0115a4b 100644 (file)
@@ -6583,22 +6583,20 @@ lookup_name (tree name)
 }
 
 /* Look up NAME for type used in elaborated name specifier in
-   the scopes given by SCOPE.  SCOPE can be either TS_CURRENT or
-   TS_WITHIN_ENCLOSING_NON_CLASS.  Although not implied by the
-   name, more scopes are checked if cleanup or template parameter
-   scope is encountered.
+   the scopes given by HOW.
 
    Unlike lookup_name_1, we make sure that NAME is actually
    declared in the desired scope, not from inheritance, nor using
    directive.  For using declaration, there is DR138 still waiting
    to be resolved.  Hidden name coming from an earlier friend
-   declaration is also returned.
+   declaration is also returned, and will be made visible unless HOW
+   is TAG_how::HIDDEN_FRIEND.
 
    A TYPE_DECL best matching the NAME is returned.  Catching error
    and issuing diagnostics are caller's responsibility.  */
 
 static tree
-lookup_type_scope_1 (tree name, tag_scope scope)
+lookup_elaborated_type_1 (tree name, TAG_how how)
 {
   cp_binding_level *b = current_binding_level;
 
@@ -6613,28 +6611,28 @@ lookup_type_scope_1 (tree name, tag_scope scope)
          if (!(b->kind == sk_cleanup
                || b->kind == sk_template_parms
                || b->kind == sk_function_parms
-               || (b->kind == sk_class
-                   && scope == ts_within_enclosing_non_class)))
+               || (b->kind == sk_class && how != TAG_how::CURRENT_ONLY)))
            return NULL_TREE;
 
        /* Check if this is the kind of thing we're looking for.  If
-          SCOPE is TS_CURRENT, also make sure it doesn't come from
-          base class.  For ITER->VALUE, we can simply use
-          INHERITED_VALUE_BINDING_P.  For ITER->TYPE, we have to
-          use our own check.
+          HOW is TAG_how::CURRENT_ONLY, also make sure it doesn't
+          come from base class.  For ITER->VALUE, we can simply use
+          INHERITED_VALUE_BINDING_P.  For ITER->TYPE, we have to use
+          our own check.
 
           We check ITER->TYPE before ITER->VALUE in order to handle
             typedef struct C {} C;
           correctly.  */
+
        if (tree type = iter->type)
          if (qualify_lookup (type, LOOK_want::TYPE)
-             && (scope != ts_current
+             && (how != TAG_how::CURRENT_ONLY
                  || LOCAL_BINDING_P (iter)
                  || DECL_CONTEXT (type) == iter->scope->this_entity))
            return type;
 
        if (qualify_lookup (iter->value, LOOK_want::TYPE)
-           && (scope != ts_current
+           && (how != TAG_how::CURRENT_ONLY
                || !INHERITED_VALUE_BINDING_P (iter)))
          return iter->value;
       }
@@ -6644,8 +6642,7 @@ lookup_type_scope_1 (tree name, tag_scope scope)
     if (!(b->kind == sk_cleanup
          || b->kind == sk_template_parms
          || b->kind == sk_function_parms
-         || (b->kind == sk_class
-             && scope == ts_within_enclosing_non_class)))
+         || (b->kind == sk_class && how != TAG_how::CURRENT_ONLY)))
       return NULL_TREE;
 
   /* Look in the innermost namespace.  */
@@ -6664,15 +6661,14 @@ lookup_type_scope_1 (tree name, tag_scope scope)
 
   return NULL_TREE;
 }
+
 /* Wrapper for lookup_type_scope_1.  */
 
 tree
-lookup_type_scope (tree name, tag_scope scope)
+lookup_elaborated_type (tree name, TAG_how how)
 {
-  tree ret;
   bool subtime = timevar_cond_start (TV_NAME_LOOKUP);
-  ret = lookup_type_scope_1 (name, scope);
+  tree ret = lookup_elaborated_type_1 (name, how);
   timevar_cond_stop (TV_NAME_LOOKUP, subtime);
   return ret;
 }
@@ -6782,7 +6778,7 @@ maybe_process_template_type_declaration (tree type, int is_friend,
    Returns TYPE upon success and ERROR_MARK_NODE otherwise.  */
 
 static tree
-do_pushtag (tree name, tree type, tag_scope scope)
+do_pushtag (tree name, tree type, TAG_how how)
 {
   tree decl;
 
@@ -6799,10 +6795,9 @@ do_pushtag (tree name, tree type, tag_scope scope)
             declaration, these scopes are not scopes from the point of
             view of the language.  */
          || (b->kind == sk_template_parms
-             && (b->explicit_spec_p || scope == ts_global)))
+             && (b->explicit_spec_p || how == TAG_how::GLOBAL)))
        b = b->level_chain;
-      else if (b->kind == sk_class
-              && scope != ts_current)
+      else if (b->kind == sk_class && how != TAG_how::CURRENT_ONLY)
        {
          b = b->level_chain;
          if (b->kind == sk_template_parms)
@@ -6836,7 +6831,7 @@ do_pushtag (tree name, tree type, tag_scope scope)
                               : TYPE_P (cs) ? cs == current_class_type
                               : cs == current_namespace);
 
-         if (scope == ts_current
+         if (how == TAG_how::CURRENT_ONLY
              || (cs && TREE_CODE (cs) == FUNCTION_DECL))
            context = cs;
          else if (cs && TYPE_P (cs))
@@ -6856,18 +6851,19 @@ do_pushtag (tree name, tree type, tag_scope scope)
 
       tdef = create_implicit_typedef (name, type);
       DECL_CONTEXT (tdef) = FROB_CONTEXT (context);
-      if (scope == ts_within_enclosing_non_class)
+      bool is_friend = how == TAG_how::HIDDEN_FRIEND;
+      if (is_friend)
        {
+         // FIXME: can go away
          /* This is a friend.  Make this TYPE_DECL node hidden from
             ordinary name lookup.  Its corresponding TEMPLATE_DECL
-            will be marked in push_template_decl_real.  */
+            will be marked in push_template_decl.  */
          retrofit_lang_decl (tdef);
          DECL_ANTICIPATED (tdef) = 1;
          DECL_FRIEND_P (tdef) = 1;
        }
 
-      decl = maybe_process_template_type_declaration
-       (type, scope == ts_within_enclosing_non_class, b);
+      decl = maybe_process_template_type_declaration (type, is_friend, b);
       if (decl == error_mark_node)
        return decl;
 
@@ -6888,7 +6884,8 @@ do_pushtag (tree name, tree type, tag_scope scope)
        }
       else if (b->kind != sk_template_parms)
        {
-         decl = do_pushdecl_with_scope (decl, b, /*is_friend=*/false);
+         decl = do_pushdecl_with_scope
+           (decl, b, /*hiding=*/(how == TAG_how::HIDDEN_FRIEND));
          if (decl == error_mark_node)
            return decl;
 
@@ -6954,11 +6951,10 @@ do_pushtag (tree name, tree type, tag_scope scope)
 /* Wrapper for do_pushtag.  */
 
 tree
-pushtag (tree name, tree type, tag_scope scope)
+pushtag (tree name, tree type, TAG_how how)
 {
-  tree ret;
   bool subtime = timevar_cond_start (TV_NAME_LOOKUP);
-  ret = do_pushtag (name, type, scope);
+  tree ret = do_pushtag (name, type, how);
   timevar_cond_stop (TV_NAME_LOOKUP, subtime);
   return ret;
 }
index 76ec8f2..82f4d51 100644 (file)
@@ -124,22 +124,6 @@ enum scope_kind {
   sk_omp            /* An OpenMP structured block.  */
 };
 
-/* The scope where the class/struct/union/enum tag applies.  */
-enum tag_scope {
-  ts_current = 0,      /* Current scope only.  This is for the
-                            class-key identifier;
-                          case mentioned in [basic.lookup.elab]/2,
-                          or the class/enum definition
-                            class-key identifier { ... };  */
-  ts_global = 1,       /* All scopes.  This is the 3.4.1
-                          [basic.lookup.unqual] lookup mentioned
-                          in [basic.lookup.elab]/2.  */
-  ts_within_enclosing_non_class = 2,   /* Search within enclosing non-class
-                                          only, for friend class lookup
-                                          according to [namespace.memdef]/3
-                                          and [class.friend]/9.  */
-};
-
 struct GTY(()) cp_class_binding {
   cxx_binding *base;
   /* The bound name.  */
@@ -326,7 +310,19 @@ inline tree lookup_name (tree name, LOOK_want want)
   return lookup_name (name, LOOK_where::ALL, want);
 }
 
-extern tree lookup_type_scope (tree, tag_scope);
+enum class TAG_how
+{
+  CURRENT_ONLY = 0, // Look and insert only in current scope
+
+  GLOBAL = 1, // Unqualified lookup, innermost-non-class insertion
+
+  INNERMOST_NON_CLASS = 2, // Look and insert only into
+                          // innermost-non-class
+
+  HIDDEN_FRIEND = 3, // As INNERMOST_NON_CLASS, but hide it
+};
+
+extern tree lookup_elaborated_type (tree, TAG_how);
 extern tree get_namespace_binding (tree ns, tree id);
 extern void set_global_binding (tree decl);
 inline tree get_global_binding (tree id)
@@ -371,7 +367,7 @@ extern tree pushdecl (tree, bool is_friend = false);
 extern tree pushdecl_outermost_localscope (tree);
 extern tree pushdecl_top_level (tree, bool is_friend = false);
 extern tree pushdecl_top_level_and_finish (tree, tree);
-extern tree pushtag (tree, tree, tag_scope = ts_current);
+extern tree pushtag (tree, tree, TAG_how = TAG_how::CURRENT_ONLY);
 extern int push_namespace (tree, bool make_inline = false);
 extern void pop_namespace (void);
 extern void push_nested_namespace (tree);
index ccfae78..8905833 100644 (file)
@@ -19057,21 +19057,20 @@ cp_parser_elaborated_type_specifier (cp_parser* parser,
             definition of a new type; a new type can only be declared in a
             declaration context.  */
 
-         tag_scope ts;
-         bool template_p;
+         TAG_how how;
 
          if (is_friend)
            /* Friends have special name lookup rules.  */
-           ts = ts_within_enclosing_non_class;
+           how = TAG_how::HIDDEN_FRIEND;
          else if (is_declaration
                   && cp_lexer_next_token_is (parser->lexer,
                                              CPP_SEMICOLON))
            /* This is a `class-key identifier ;' */
-           ts = ts_current;
+           how = TAG_how::CURRENT_ONLY;
          else
-           ts = ts_global;
+           how = TAG_how::GLOBAL;
 
-         template_p =
+         bool template_p =
            (template_parm_lists_apply
             && (cp_parser_next_token_starts_class_definition_p (parser)
                 || cp_lexer_next_token_is (parser->lexer, CPP_SEMICOLON)));
@@ -19084,7 +19083,8 @@ cp_parser_elaborated_type_specifier (cp_parser* parser,
                                                       token->location,
                                                       /*declarator=*/NULL))
            return error_mark_node;
-         type = xref_tag (tag_type, identifier, ts, template_p);
+
+         type = xref_tag (tag_type, identifier, how, template_p);
        }
     }
 
@@ -24708,10 +24708,10 @@ cp_parser_class_head (cp_parser* parser,
       /* If the class was unnamed, create a dummy name.  */
       if (!id)
        id = make_anon_name ();
-      tag_scope tag_scope = (parser->in_type_id_in_expr_p
-                            ? ts_within_enclosing_non_class
-                            : ts_current);
-      type = xref_tag (class_key, id, tag_scope,
+      TAG_how how = (parser->in_type_id_in_expr_p
+                    ? TAG_how::INNERMOST_NON_CLASS
+                    : TAG_how::CURRENT_ONLY);
+      type = xref_tag (class_key, id, how,
                       parser->num_template_parameter_lists);
     }
 
index 087b5d5..c6c4ee5 100644 (file)
@@ -41,7 +41,7 @@ objcp_start_struct (location_t loc ATTRIBUTE_UNUSED,
   if (!name)
     name = make_anon_name ();
 
-  s = xref_tag (record_type, name, ts_global);
+  s = xref_tag (record_type, name, TAG_how::GLOBAL);
   CLASSTYPE_DECLARED_CLASS (s) = 0;  /* this is a 'struct', not a 'class'.  */
   xref_basetypes (s, NULL_TREE);     /* no base classes here!  */
 
@@ -84,7 +84,7 @@ objcp_finish_function (void)
 tree
 objcp_xref_tag (enum tree_code code ATTRIBUTE_UNUSED, tree name)
 {
-  return xref_tag (record_type, name, ts_global);
+  return xref_tag (record_type, name, TAG_how::GLOBAL);
 }
 
 int