config-lang.in: Add semantics.c to gtfiles.
authorKriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
Tue, 14 Jan 2003 13:40:53 +0000 (13:40 +0000)
committerKriang Lerdsuwanakij <lerdsuwa@gcc.gnu.org>
Tue, 14 Jan 2003 13:40:53 +0000 (13:40 +0000)
* config-lang.in: Add semantics.c to gtfiles.
* cp-tree.h (flagged_type_tree_s): Remove lookups field.
(saved_scope): Likewise.
(type_lookups): Remove.
(deferred_access): New structure.
(type_access_control): Remove.
(save_type_access_control): Likewise.
(reset_type_access_control): Likewise.
(decl_type_access_control): Likewise.
(push_deferring_access_checks): Declare.
(resume_deferring_access_checks): Likewise.
(stop_deferring_access_checks): Likewise.
(pop_deferring_access_checks): Likewise.
(get_deferred_access_checks): Likewise.
(pop_to_parent_deferring_access_checks): Likewise.
(perform_deferred_access_checks): Likewise.
(perform_or_defer_access_check): Likewise.
* decl.c (make_typename_type): Use perform_or_defer_access_check.
(make_unbound_class_template): Likewise.
(grokdeclarator): Don't call decl_type_access_control.
* parser.c (cp_parser_context): Remove deferred_access_checks
and deferring_access_checks_p fields.
(cp_parser_context_new): Adjust.
(cp_parser): Remove access_checks_lists.
(cp_parser_defer_access_check): Remove.
(cp_parser_start_deferring_access_checks): Remove.
(cp_parser_stop_deferring_access_checks): Remove.
(cp_parser_perform_deferred_access_checks): Remove.
(cp_parser_nested_name_specifier_opt): Use new deferred access
functions.
(cp_parser_simple_declaration): Likewise.
(cp_parser_template_id): Likewise.
(cp_parser_function_definition): Likewise.
(cp_parser_class_specifier): Likewise.
(cp_parser_lookup_name): Likewise.
(cp_parser_single_declaration): Likewise.
(cp_parser_pre_parsed_nested_name_specifier): Likewise.
(cp_parser_parse_tentatively): Likewise.
(cp_parser_parse_definitely): Likewise.
(yyparse): Likewise.
(cp_parser_init_declarator): Remove access_checks parameter.
Use new deferred access functions.
(cp_parser_function_definition_from_specifiers_and_declarator):
Likewise.
(cp_parser_class_head): Remove deferring_access_checks_p and
saved_access_checks parameters.  Use new deferred access functions.
(cp_parser_member_specification_opt): Don't call
reset_type_access_control.
* search.c (type_access_control): Remove.
* semantics.c: Include "gt-cp-semantics.h".
(deferred_type_access_control): Remove.
(deferred_access_stack): New variable.
(deferred_access_free_list): Likewise.
(push_deferring_access_checks): New function.
(resume_deferring_access_checks): Likewise.
(stop_deferring_access_checks): Likewise.
(pop_deferring_access_checks): Likewise.
(get_deferred_access_checks): Likewise.
(pop_to_parent_deferring_access_checks): Likewise.
(perform_deferred_access_checks): New function, adapted from
cp_parser_perform_deferred_access_checks.
(perform_or_defer_access_check): New function, adapted from
cp_parser_defer_access_check.
(current_type_lookups): Remove.
(deferred_type_access_control): Likewise.
(decl_type_access_control): Likewise.
(save_type_access_control): Likewise.
(reset_type_access_control): Likewise.
(begin_function_definition): Adjust.
(begin_class_definiton): Likewise.

From-SVN: r61283

gcc/cp/ChangeLog
gcc/cp/config-lang.in
gcc/cp/cp-tree.h
gcc/cp/decl.c
gcc/cp/parser.c
gcc/cp/search.c
gcc/cp/semantics.c

index b209ca4..aad06b7 100644 (file)
@@ -1,3 +1,76 @@
+2003-01-14  Kriang Lerdsuwanakij  <lerdsuwa@users.sourceforge.net>
+
+       * config-lang.in: Add semantics.c to gtfiles.
+       * cp-tree.h (flagged_type_tree_s): Remove lookups field.
+       (saved_scope): Likewise.
+       (type_lookups): Remove.
+       (deferred_access): New structure.
+       (type_access_control): Remove.
+       (save_type_access_control): Likewise.
+       (reset_type_access_control): Likewise.
+       (decl_type_access_control): Likewise.
+       (push_deferring_access_checks): Declare.
+       (resume_deferring_access_checks): Likewise.
+       (stop_deferring_access_checks): Likewise.
+       (pop_deferring_access_checks): Likewise.
+       (get_deferred_access_checks): Likewise.
+       (pop_to_parent_deferring_access_checks): Likewise.
+       (perform_deferred_access_checks): Likewise.
+       (perform_or_defer_access_check): Likewise.
+       * decl.c (make_typename_type): Use perform_or_defer_access_check.
+       (make_unbound_class_template): Likewise.
+       (grokdeclarator): Don't call decl_type_access_control.
+       * parser.c (cp_parser_context): Remove deferred_access_checks
+       and deferring_access_checks_p fields.
+       (cp_parser_context_new): Adjust.
+       (cp_parser): Remove access_checks_lists.
+       (cp_parser_defer_access_check): Remove.
+       (cp_parser_start_deferring_access_checks): Remove.
+       (cp_parser_stop_deferring_access_checks): Remove.
+       (cp_parser_perform_deferred_access_checks): Remove.
+       (cp_parser_nested_name_specifier_opt): Use new deferred access
+       functions.
+       (cp_parser_simple_declaration): Likewise.
+       (cp_parser_template_id): Likewise.
+       (cp_parser_function_definition): Likewise.
+       (cp_parser_class_specifier): Likewise.
+       (cp_parser_lookup_name): Likewise.
+       (cp_parser_single_declaration): Likewise.
+       (cp_parser_pre_parsed_nested_name_specifier): Likewise.
+       (cp_parser_parse_tentatively): Likewise.
+       (cp_parser_parse_definitely): Likewise.
+       (yyparse): Likewise.
+       (cp_parser_init_declarator): Remove access_checks parameter.
+       Use new deferred access functions.
+       (cp_parser_function_definition_from_specifiers_and_declarator):
+       Likewise.
+       (cp_parser_class_head): Remove deferring_access_checks_p and
+       saved_access_checks parameters.  Use new deferred access functions.
+       (cp_parser_member_specification_opt): Don't call
+       reset_type_access_control.
+       * search.c (type_access_control): Remove.
+       * semantics.c: Include "gt-cp-semantics.h".
+       (deferred_type_access_control): Remove.
+       (deferred_access_stack): New variable.
+       (deferred_access_free_list): Likewise.
+       (push_deferring_access_checks): New function.
+       (resume_deferring_access_checks): Likewise.
+       (stop_deferring_access_checks): Likewise.
+       (pop_deferring_access_checks): Likewise.
+       (get_deferred_access_checks): Likewise.
+       (pop_to_parent_deferring_access_checks): Likewise.
+       (perform_deferred_access_checks): New function, adapted from
+       cp_parser_perform_deferred_access_checks.
+       (perform_or_defer_access_check): New function, adapted from
+       cp_parser_defer_access_check.
+       (current_type_lookups): Remove.
+       (deferred_type_access_control): Likewise.
+       (decl_type_access_control): Likewise.
+       (save_type_access_control): Likewise.
+       (reset_type_access_control): Likewise.
+       (begin_function_definition): Adjust.
+       (begin_class_definiton): Likewise.
+
 2003-01-13  Jason Merrill  <jason@redhat.com>
 
        PR c++/8748
index 66db7ea..d230bc6 100644 (file)
@@ -34,4 +34,4 @@ stagestuff="g++\$(exeext) g++-cross\$(exeext) cc1plus\$(exeext)"
 
 target_libs="${libstdcxx_version} target-gperf"
 
-gtfiles="\$(srcdir)/cp/cp-tree.h \$(srcdir)/cp/decl.h \$(srcdir)/cp/lex.h \$(srcdir)/cp/call.c \$(srcdir)/cp/decl.c \$(srcdir)/cp/decl2.c \$(srcdir)/cp/pt.c \$(srcdir)/cp/repo.c \$(srcdir)/cp/tree.c \$(srcdir)/cp/parser.c \$(srcdir)/c-common.c \$(srcdir)/c-common.h \$(srcdir)/c-pragma.c"
+gtfiles="\$(srcdir)/cp/cp-tree.h \$(srcdir)/cp/decl.h \$(srcdir)/cp/lex.h \$(srcdir)/cp/call.c \$(srcdir)/cp/decl.c \$(srcdir)/cp/decl2.c \$(srcdir)/cp/pt.c \$(srcdir)/cp/repo.c \$(srcdir)/cp/semantics.c \$(srcdir)/cp/tree.c \$(srcdir)/cp/parser.c \$(srcdir)/c-common.c \$(srcdir)/c-common.h \$(srcdir)/c-pragma.c"
index 313b124..612fd56 100644 (file)
@@ -257,7 +257,6 @@ typedef struct flagged_type_tree_s GTY(())
 {
   tree t;
   int new_type_flag;
-  tree lookups;
 } flagged_type_tree;
 
 typedef struct template_parm_index_s GTY(())
@@ -784,7 +783,6 @@ struct saved_scope GTY(())
   tree x_previous_class_type;
   tree x_previous_class_values;
   tree x_saved_tree;
-  tree lookups;
   tree last_parms;
 
   HOST_WIDE_INT x_processing_template_decl;
@@ -851,8 +849,6 @@ struct saved_scope GTY(())
 
 /* A list of private types mentioned, for deferred access checking.  */
 
-#define type_lookups scope_chain->lookups
-
 extern GTY(()) struct saved_scope *scope_chain;
 
 /* Global state pertinent to the current function.  */
@@ -3197,6 +3193,32 @@ extern GTY(()) tree anonymous_namespace_name;
    function, two inside the body of a function in a local class, etc.)  */
 extern int function_depth;
 
+typedef struct deferred_access GTY(())
+{
+  /* A TREE_LIST representing name-lookups for which we have deferred
+     checking access controls.  We cannot check the accessibility of
+     names used in a decl-specifier-seq until we know what is being
+     declared because code like:
+
+       class A { 
+         class B {};
+         B* f();
+       }
+
+       A::B* A::f() { return 0; }
+
+     is valid, even though `A::B' is not generally accessible.  
+
+     The TREE_PURPOSE of each node is the scope used to qualify the
+     name being looked up; the TREE_VALUE is the DECL to which the
+     name was resolved.  */
+  tree deferred_access_checks;
+  /* TRUE iff we are deferring access checks.  */
+  bool deferring_access_checks_p;
+  /* The next deferred access data in stack or linked-list.  */
+  struct deferred_access *next;
+} deferred_access;
+
 /* in pt.c  */
 
 /* These values are used for the `STRICT' parameter to type_unification and
@@ -4097,7 +4119,6 @@ extern tree lookup_base (tree, tree, base_access, base_kind *);
 extern int types_overlap_p                     (tree, tree);
 extern tree get_vbase                          (tree, tree);
 extern tree get_dynamic_cast_base_type          (tree, tree);
-extern void type_access_control                        (tree, tree);
 extern int accessible_p                         (tree, tree);
 extern tree lookup_field                       (tree, tree, int, int);
 extern int lookup_fnfields_1                    (tree, tree);
@@ -4147,6 +4168,14 @@ extern tree build_baselink                      (tree, tree, tree, tree);
 extern tree adjust_result_of_qualified_name_lookup
                                                 (tree, tree, tree);
 /* in semantics.c */
+extern void push_deferring_access_checks       (bool defer_p);
+extern void resume_deferring_access_checks     (void);
+extern void stop_deferring_access_checks       (void);
+extern void pop_deferring_access_checks                (void);
+extern tree get_deferred_access_checks         (void);
+extern void pop_to_parent_deferring_access_checks      (void);
+extern void perform_deferred_access_checks     (void);
+extern void perform_or_defer_access_check      (tree, tree);
 extern void init_cp_semantics                   (void);
 extern tree finish_expr_stmt                    (tree);
 extern tree begin_if_stmt                       (void);
@@ -4207,9 +4236,6 @@ extern tree finish_pseudo_destructor_expr       (tree, tree, tree);
 extern tree finish_unary_op_expr                (enum tree_code, tree);
 extern tree finish_compound_literal             (tree, tree);
 extern tree finish_fname                        (tree);
-extern void save_type_access_control           (tree);
-extern void reset_type_access_control           (void);
-extern void decl_type_access_control           (tree);
 extern int begin_function_definition            (tree, tree, tree);
 extern tree begin_constructor_declarator        (tree, tree);
 extern tree finish_declarator                   (tree, tree, tree, tree, int);
index dd0e69a..42bbdc8 100644 (file)
@@ -5544,7 +5544,7 @@ make_typename_type (tree context, tree name, tsubst_flags_t complain)
          if (complain & tf_error)
            {
              if (complain & tf_parsing)
-               type_access_control (context, tmpl);
+               perform_or_defer_access_check (context, tmpl);
              else
                enforce_access (context, tmpl);
            }
@@ -5579,7 +5579,7 @@ make_typename_type (tree context, tree name, tsubst_flags_t complain)
              if (complain & tf_error)
                {
                  if (complain & tf_parsing)
-                   type_access_control (context, t);
+                   perform_or_defer_access_check (context, t);
                  else
                    enforce_access (context, t);
                }
@@ -5651,7 +5651,7 @@ make_unbound_class_template (tree context, tree name, tsubst_flags_t complain)
       if (complain & tf_error)
        {
          if (complain & tf_parsing)
-           type_access_control (context, tmpl);
+           perform_or_defer_access_check (context, tmpl);
          else
            enforce_access (context, tmpl);
        }
@@ -9854,7 +9854,6 @@ grokdeclarator (tree declarator,
 
                decl = start_decl (declarator, declspecs, 1,
                                   attributes, NULL_TREE);
-               decl_type_access_control (decl);
                if (decl)
                  {
                    /* Look for __unused__ attribute */
@@ -11407,8 +11406,6 @@ grokdeclarator (tree declarator,
          /* Only try to do this stuff if we didn't already give up.  */
          if (type != integer_type_node)
            {
-             decl_type_access_control (TYPE_NAME (type));
-
              /* A friendly class?  */
              if (current_class_type)
                make_friend_class (current_class_type, TYPE_MAIN_VARIANT (type));
index 21d5d21..68997ad 100644 (file)
@@ -1194,26 +1194,6 @@ typedef struct cp_parser_context GTY (())
      scope given by OBJECT_TYPE (the type of `x' or `*x') and also in
      the context of the containing expression.  */
   tree object_type;
-  /* A TREE_LIST representing name-lookups for which we have deferred
-     checking access controls.  We cannot check the accessibility of
-     names used in a decl-specifier-seq until we know what is being
-     declared because code like:
-
-       class A { 
-         class B {};
-         B* f();
-       }
-
-       A::B* A::f() { return 0; }
-
-     is valid, even though `A::B' is not generally accessible.  
-
-     The TREE_PURPOSE of each node is the scope used to qualify the
-     name being looked up; the TREE_VALUE is the DECL to which the
-     name was resolved.  */
-  tree deferred_access_checks;
-  /* TRUE iff we are deferring access checks.  */
-  bool deferring_access_checks_p;
   /* The next parsing context in the stack.  */
   struct cp_parser_context *next;
 } cp_parser_context;
@@ -1260,10 +1240,6 @@ cp_parser_context_new (next)
       /* If, in the NEXT context, we are parsing an `x->' or `x.'
         expression, then we are parsing one in this context, too.  */
       context->object_type = next->object_type;
-      /* We are deferring access checks here if we were in the NEXT
-        context.  */
-      context->deferring_access_checks_p 
-       = next->deferring_access_checks_p;
       /* Thread the stack.  */
       context->next = next;
     }
@@ -1367,10 +1343,6 @@ typedef struct cp_parser GTY(())
   /* The number of template parameter lists that apply directly to the
      current declaration.  */
   unsigned num_template_parameter_lists;
-
-  /* List of access checks lists, used to prevent GC collection while
-     they are in use.  */
-  tree access_checks_lists;
 } cp_parser;
 
 /* The type of a function that parses some kind of expression  */
@@ -1562,7 +1534,7 @@ static void cp_parser_linkage_specification
 /* Declarators [gram.dcl.decl] */
 
 static tree cp_parser_init_declarator
-  PARAMS ((cp_parser *, tree, tree, tree, bool, bool, bool *));
+  PARAMS ((cp_parser *, tree, tree, bool, bool, bool *));
 static tree cp_parser_declarator
   PARAMS ((cp_parser *, cp_parser_declarator_kind, bool *));
 static tree cp_parser_direct_declarator
@@ -1606,7 +1578,7 @@ static tree cp_parser_class_name
 static tree cp_parser_class_specifier
   PARAMS ((cp_parser *));
 static tree cp_parser_class_head
-  PARAMS ((cp_parser *, bool *, bool *, tree *));
+  PARAMS ((cp_parser *, bool *));
 static enum tag_types cp_parser_class_key
   PARAMS ((cp_parser *));
 static void cp_parser_member_specification_opt
@@ -1731,7 +1703,7 @@ static tree cp_parser_global_scope_opt
 static bool cp_parser_constructor_declarator_p
   (cp_parser *, bool);
 static tree cp_parser_function_definition_from_specifiers_and_declarator
-  PARAMS ((cp_parser *, tree, tree, tree, tree));
+  PARAMS ((cp_parser *, tree, tree, tree));
 static tree cp_parser_function_definition_after_declarator
   PARAMS ((cp_parser *, bool));
 static void cp_parser_template_declaration_after_export
@@ -1818,14 +1790,6 @@ static bool cp_parser_dependent_template_id_p
   (tree, tree);
 static bool cp_parser_dependent_template_p
   (tree);
-static void cp_parser_defer_access_check
-  (cp_parser *, tree, tree);
-static void cp_parser_start_deferring_access_checks
-  (cp_parser *);
-static tree cp_parser_stop_deferring_access_checks
-  PARAMS ((cp_parser *));
-static void cp_parser_perform_deferred_access_checks
-  PARAMS ((tree));
 static tree cp_parser_scope_through_which_access_occurs
   (tree, tree, tree);
 
@@ -2134,79 +2098,6 @@ cp_parser_dependent_template_p (tree tmpl)
   return false;
 }
 
-/* Defer checking the accessibility of DECL, when looked up in
-   CLASS_TYPE.  */
-
-static void
-cp_parser_defer_access_check (cp_parser *parser, 
-                             tree class_type,
-                             tree decl)
-{
-  tree check;
-
-  /* If we are not supposed to defer access checks, just check now.  */
-  if (!parser->context->deferring_access_checks_p)
-    {
-      enforce_access (class_type, decl);
-      return;
-    }
-
-  /* See if we are already going to perform this check.  */
-  for (check = parser->context->deferred_access_checks;
-       check;
-       check = TREE_CHAIN (check))
-    if (TREE_VALUE (check) == decl
-       && same_type_p (TREE_PURPOSE (check), class_type))
-      return;
-  /* If not, record the check.  */
-  parser->context->deferred_access_checks
-    = tree_cons (class_type, decl, parser->context->deferred_access_checks);
-}
-
-/* Start deferring access control checks.  */
-
-static void
-cp_parser_start_deferring_access_checks (cp_parser *parser)
-{
-  parser->context->deferring_access_checks_p = true;
-}
-
-/* Stop deferring access control checks.  Returns a TREE_LIST
-   representing the deferred checks.  The TREE_PURPOSE of each node is
-   the type through which the access occurred; the TREE_VALUE is the
-   declaration named.  */
-
-static tree
-cp_parser_stop_deferring_access_checks (parser)
-     cp_parser *parser;
-{
-  tree access_checks;
-
-  parser->context->deferring_access_checks_p = false;
-  access_checks = parser->context->deferred_access_checks;
-  parser->context->deferred_access_checks = NULL_TREE;
-
-  return access_checks;
-}
-
-/* Perform the deferred ACCESS_CHECKS, whose representation is as
-   documented with cp_parser_stop_deferrring_access_checks.  */
-
-static void
-cp_parser_perform_deferred_access_checks (access_checks)
-     tree access_checks;
-{
-  tree deferred_check;
-
-  /* Look through all the deferred checks.  */
-  for (deferred_check = access_checks;
-       deferred_check;
-       deferred_check = TREE_CHAIN (deferred_check))
-    /* Check access.  */
-    enforce_access (TREE_PURPOSE (deferred_check), 
-                   TREE_VALUE (deferred_check));
-}
-
 /* Returns the scope through which DECL is being accessed, or
    NULL_TREE if DECL is not a member.  If OBJECT_TYPE is non-NULL, we
    have just seen `x->' or `x.' and OBJECT_TYPE is the type of `*x',
@@ -3487,11 +3378,12 @@ cp_parser_nested_name_specifier_opt (cp_parser *parser,
       start = cp_lexer_token_difference (parser->lexer,
                                         parser->lexer->first_token,
                                         token);
-      access_check = parser->context->deferred_access_checks;
     }
   else
     start = -1;
 
+  push_deferring_access_checks (true);
+
   while (true)
     {
       tree new_scope;
@@ -3633,6 +3525,10 @@ cp_parser_nested_name_specifier_opt (cp_parser *parser,
        complete_type (parser->scope);
     }
 
+  /* Retrieve any deferred checks.  Do not pop this access checks yet
+     so the memory will not be reclaimed during token replacing below.  */
+  access_check = get_deferred_access_checks ();
+
   /* If parsing tentatively, replace the sequence of tokens that makes
      up the nested-name-specifier with a CPP_NESTED_NAME_SPECIFIER
      token.  That way, should we re-parse the token stream, we will
@@ -3640,28 +3536,12 @@ cp_parser_nested_name_specifier_opt (cp_parser *parser,
      we issue duplicate error messages.  */
   if (success && start >= 0)
     {
-      tree c;
-
       /* Find the token that corresponds to the start of the
         template-id.  */
       token = cp_lexer_advance_token (parser->lexer, 
                                      parser->lexer->first_token,
                                      start);
 
-      /* Remember the access checks associated with this
-        nested-name-specifier.  */
-      c = parser->context->deferred_access_checks;
-      if (c == access_check)
-       access_check = NULL_TREE;
-      else
-       {
-         while (TREE_CHAIN (c) != access_check)
-           c = TREE_CHAIN (c);
-         access_check = parser->context->deferred_access_checks;
-         parser->context->deferred_access_checks = TREE_CHAIN (c);
-         TREE_CHAIN (c) = NULL_TREE;
-       }
-
       /* Reset the contents of the START token.  */
       token->type = CPP_NESTED_NAME_SPECIFIER;
       token->value = build_tree_list (access_check, parser->scope);
@@ -3671,6 +3551,7 @@ cp_parser_nested_name_specifier_opt (cp_parser *parser,
       cp_lexer_purge_tokens_after (parser->lexer, token);
     }
 
+  pop_deferring_access_checks ();
   return success ? parser->scope : NULL_TREE;
 }
 
@@ -6748,14 +6629,14 @@ cp_parser_simple_declaration (parser, function_definition_allowed_p)
 {
   tree decl_specifiers;
   tree attributes;
-  tree access_checks;
   bool declares_class_or_enum;
   bool saw_declarator;
 
   /* Defer access checks until we know what is being declared; the
      checks for names appearing in the decl-specifier-seq should be
      done as if we were in the scope of the thing being declared.  */
-  cp_parser_start_deferring_access_checks (parser);
+  push_deferring_access_checks (true);
+
   /* Parse the decl-specifier-seq.  We have to keep track of whether
      or not the decl-specifier-seq declares a named class or
      enumeration type, since that is the only case in which the
@@ -6773,11 +6654,7 @@ cp_parser_simple_declaration (parser, function_definition_allowed_p)
                                    &attributes,
                                    &declares_class_or_enum);
   /* We no longer need to defer access checks.  */
-  access_checks = cp_parser_stop_deferring_access_checks (parser);
-
-  /* Prevent access checks from being reclaimed by GC.  */
-  parser->access_checks_lists = tree_cons (NULL_TREE, access_checks,
-                                          parser->access_checks_lists);
+  stop_deferring_access_checks ();
 
   /* Keep going until we hit the `;' at the end of the simple
      declaration.  */
@@ -6791,7 +6668,6 @@ cp_parser_simple_declaration (parser, function_definition_allowed_p)
       saw_declarator = true;
       /* Parse the init-declarator.  */
       cp_parser_init_declarator (parser, decl_specifiers, attributes,
-                                access_checks,
                                 function_definition_allowed_p,
                                 /*member_p=*/false,
                                 &function_definition_p);
@@ -6809,9 +6685,7 @@ cp_parser_simple_declaration (parser, function_definition_allowed_p)
          /* Otherwise, we're done with the list of declarators.  */
          else
            {
-             /* Discard access checks no longer in use. */
-             parser->access_checks_lists
-               = TREE_CHAIN (parser->access_checks_lists);
+             pop_deferring_access_checks ();
              return;
            }
        }
@@ -6829,9 +6703,7 @@ cp_parser_simple_declaration (parser, function_definition_allowed_p)
          cp_parser_error (parser, "expected `,' or `;'");
          /* Skip tokens until we reach the end of the statement.  */
          cp_parser_skip_to_end_of_statement (parser);
-         /* Discard access checks no longer in use.  */
-          parser->access_checks_lists
-           = TREE_CHAIN (parser->access_checks_lists);
+         pop_deferring_access_checks ();
          return;
        }
       /* After the first time around, a function-definition is not
@@ -6851,18 +6723,17 @@ cp_parser_simple_declaration (parser, function_definition_allowed_p)
       if (cp_parser_declares_only_class_p (parser))
        shadow_tag (decl_specifiers);
       /* Perform any deferred access checks.  */
-      cp_parser_perform_deferred_access_checks (access_checks);
+      perform_deferred_access_checks ();
     }
 
+  pop_deferring_access_checks ();
+
   /* Consume the `;'.  */
   cp_parser_require (parser, CPP_SEMICOLON, "`;'");
 
   /* Mark all the classes that appeared in the decl-specifier-seq as
      having received a `;'.  */
   note_list_got_semicolon (decl_specifiers);
-
-  /* Discard access checks no longer in use.  */
-  parser->access_checks_lists = TREE_CHAIN (parser->access_checks_lists);
 }
 
 /* Parse a decl-specifier-seq.
@@ -8127,9 +7998,8 @@ cp_parser_template_id (cp_parser *parser,
       value = cp_lexer_consume_token (parser->lexer)->value;
       /* Perform any access checks that were deferred.  */
       for (check = TREE_PURPOSE (value); check; check = TREE_CHAIN (check))
-       cp_parser_defer_access_check (parser, 
-                                     TREE_PURPOSE (check),
-                                     TREE_VALUE (check));
+       perform_or_defer_access_check (TREE_PURPOSE (check),
+                                      TREE_VALUE (check));
       /* Return the stored value.  */
       return TREE_VALUE (value);
     }
@@ -8152,20 +8022,27 @@ cp_parser_template_id (cp_parser *parser,
       start_of_id = cp_lexer_token_difference (parser->lexer,
                                               parser->lexer->first_token,
                                               next_token);
-      access_check = parser->context->deferred_access_checks;
     }
   else
     start_of_id = -1;
 
+  push_deferring_access_checks (true);
+
   /* Parse the template-name.  */
   template = cp_parser_template_name (parser, template_keyword_p,
                                      check_dependency_p);
   if (template == error_mark_node)
-    return error_mark_node;
+    {
+      pop_deferring_access_checks ();
+      return error_mark_node;
+    }
 
   /* Look for the `<' that starts the template-argument-list.  */
   if (!cp_parser_require (parser, CPP_LESS, "`<'"))
-    return error_mark_node;
+    {
+      pop_deferring_access_checks ();
+      return error_mark_node;
+    }
 
   /* [temp.names]
 
@@ -8216,6 +8093,10 @@ cp_parser_template_id (cp_parser *parser,
       template_id = lookup_template_function (template, arguments);
     }
   
+  /* Retrieve any deferred checks.  Do not pop this access checks yet
+     so the memory will not be reclaimed during token replacing below.  */
+  access_check = get_deferred_access_checks ();
+
   /* If parsing tentatively, replace the sequence of tokens that makes
      up the template-id with a CPP_TEMPLATE_ID token.  That way,
      should we re-parse the token stream, we will not have to repeat
@@ -8225,7 +8106,6 @@ cp_parser_template_id (cp_parser *parser,
   if (start_of_id >= 0)
     {
       cp_token *token;
-      tree c;
 
       /* Find the token that corresponds to the start of the
         template-id.  */
@@ -8233,20 +8113,6 @@ cp_parser_template_id (cp_parser *parser,
                                      parser->lexer->first_token,
                                      start_of_id);
 
-      /* Remember the access checks associated with this
-        nested-name-specifier.  */
-      c = parser->context->deferred_access_checks;
-      if (c == access_check)
-       access_check = NULL_TREE;
-      else
-       {
-         while (TREE_CHAIN (c) != access_check)
-           c = TREE_CHAIN (c);
-         access_check = parser->context->deferred_access_checks;
-         parser->context->deferred_access_checks = TREE_CHAIN (c);
-         TREE_CHAIN (c) = NULL_TREE;
-       }
-
       /* Reset the contents of the START_OF_ID token.  */
       token->type = CPP_TEMPLATE_ID;
       token->value = build_tree_list (access_check, template_id);
@@ -8255,6 +8121,7 @@ cp_parser_template_id (cp_parser *parser,
       cp_lexer_purge_tokens_after (parser->lexer, token);
     }
 
+  pop_deferring_access_checks ();
   return template_id;
 }
 
@@ -9724,10 +9591,9 @@ cp_parser_asm_definition (parser)
      declarator asm-specification [opt] attributes [opt] initializer [opt]
 
    The DECL_SPECIFIERS and PREFIX_ATTRIBUTES apply to this declarator.
-   Returns a reprsentation of the entity declared.  The ACCESS_CHECKS
-   represent deferred access checks from the decl-specifier-seq.  If
-   MEMBER_P is TRUE, then this declarator appears in a class scope.
-   The new DECL created by this declarator is returned.
+   Returns a reprsentation of the entity declared.  If MEMBER_P is TRUE,
+   then this declarator appears in a class scope.  The new DECL created
+   by this declarator is returned.
 
    If FUNCTION_DEFINITION_ALLOWED_P then we handle the declarator and
    for a function-definition here as well.  If the declarator is a
@@ -9742,14 +9608,12 @@ static tree
 cp_parser_init_declarator (parser, 
                           decl_specifiers, 
                           prefix_attributes,
-                          access_checks,
                           function_definition_allowed_p,
                           member_p,
                           function_definition_p)
      cp_parser *parser;
      tree decl_specifiers;
      tree prefix_attributes;
-     tree access_checks;
      bool function_definition_allowed_p;
      bool member_p;
      bool *function_definition_p;
@@ -9761,7 +9625,6 @@ cp_parser_init_declarator (parser,
   tree initializer;
   tree decl = NULL_TREE;
   tree scope;
-  tree declarator_access_checks;
   bool is_initialized;
   bool is_parenthesized_init;
   bool ctor_dtor_or_conv_p;
@@ -9775,29 +9638,19 @@ cp_parser_init_declarator (parser,
   /* Defer access checks while parsing the declarator; we cannot know
      what names are accessible until we know what is being 
      declared.  */
-  cp_parser_start_deferring_access_checks (parser);
+  resume_deferring_access_checks ();
+
   /* Parse the declarator.  */
   declarator 
     = cp_parser_declarator (parser, CP_PARSER_DECLARATOR_NAMED,
                            &ctor_dtor_or_conv_p);
   /* Gather up the deferred checks.  */
-  declarator_access_checks 
-    = cp_parser_stop_deferring_access_checks (parser);
-
-  /* Prevent the access checks from being reclaimed by GC.  */
-  parser->access_checks_lists
-    = tree_cons (NULL_TREE, declarator_access_checks,
-                parser->access_checks_lists);
+  stop_deferring_access_checks ();
 
   /* If the DECLARATOR was erroneous, there's no need to go
      further.  */
   if (declarator == error_mark_node)
-    {
-      /* Discard access checks no longer in use.  */
-      parser->access_checks_lists
-       = TREE_CHAIN (parser->access_checks_lists);
-      return error_mark_node;
-    }
+    return error_mark_node;
 
   /* Figure out what scope the entity declared by the DECLARATOR is
      located in.  `grokdeclarator' sometimes changes the scope, so
@@ -9831,15 +9684,10 @@ cp_parser_init_declarator (parser,
             error message.  */
          cp_parser_error (parser,
                           "a function-definition is not allowed here");
-         /* Discard access checks no longer in use.  */
-         parser->access_checks_lists
-           = TREE_CHAIN (parser->access_checks_lists);
          return error_mark_node;
        }
       else
        {
-         tree *ac;
-
          /* Neither attributes nor an asm-specification are allowed
             on a function-definition.  */
          if (asm_specification)
@@ -9849,23 +9697,9 @@ cp_parser_init_declarator (parser,
          /* This is a function-definition.  */
          *function_definition_p = true;
 
-         /* Thread the access checks together.  */
-         ac = &access_checks;
-         while (*ac)
-           ac = &TREE_CHAIN (*ac);
-         *ac = declarator_access_checks;
-
          /* Parse the function definition.  */
          decl = (cp_parser_function_definition_from_specifiers_and_declarator
-                 (parser, decl_specifiers, prefix_attributes, declarator,
-                  access_checks));
-
-         /* Pull the access-checks apart again.  */
-         *ac = NULL_TREE;
-
-         /* Discard access checks no longer in use.  */
-          parser->access_checks_lists
-            = TREE_CHAIN (parser->access_checks_lists);
+                 (parser, decl_specifiers, prefix_attributes, declarator));
 
          return decl;
        }
@@ -9883,9 +9717,6 @@ cp_parser_init_declarator (parser,
     {
       cp_parser_error (parser, 
                       "expected constructor, destructor, or type conversion");
-      /* Discard access checks no longer in use.  */
-      parser->access_checks_lists
-       = TREE_CHAIN (parser->access_checks_lists);
       return error_mark_node;
     }
 
@@ -9899,9 +9730,6 @@ cp_parser_init_declarator (parser,
       && token->type != CPP_SEMICOLON)
     {
       cp_parser_error (parser, "expected init-declarator");
-      /* Discard access checks no longer in use.  */
-      parser->access_checks_lists
-        = TREE_CHAIN (parser->access_checks_lists);
       return error_mark_node;
     }
 
@@ -9916,12 +9744,7 @@ cp_parser_init_declarator (parser,
   /* Check that the number of template-parameter-lists is OK.  */
   if (!cp_parser_check_declarator_template_parameters (parser, 
                                                       declarator))
-    {
-      /* Discard access checks no longer in use.  */
-      parser->access_checks_lists
-        = TREE_CHAIN (parser->access_checks_lists);
-      return error_mark_node;
-    }
+    return error_mark_node;
 
   /* Enter the newly declared entry in the symbol table.  If we're
      processing a declaration in a class-specifier, we wait until
@@ -9962,10 +9785,9 @@ cp_parser_init_declarator (parser,
          current_function_decl = decl;
        }
        
-      /* Perform the access control checks for the decl-specifiers.  */
-      cp_parser_perform_deferred_access_checks (access_checks);
-      /* And for the declarator.  */
-      cp_parser_perform_deferred_access_checks (declarator_access_checks);
+      /* Perform the access control checks for the declarator and the
+        the decl-specifiers.  */
+      perform_deferred_access_checks ();
 
       /* Restore the saved value.  */
       if (TREE_CODE (decl) == FUNCTION_DECL)
@@ -10017,10 +9839,6 @@ cp_parser_init_declarator (parser,
                    ((is_parenthesized_init || !is_initialized)
                     ? 0 : LOOKUP_ONLYCONVERTING));
 
-  /* Discard access checks no longer in use.  */
-  parser->access_checks_lists
-    = TREE_CHAIN (parser->access_checks_lists);
-
   return decl;
 }
 
@@ -11167,7 +10985,6 @@ cp_parser_function_definition (parser, friend_p)
   tree attributes;
   tree declarator;
   tree fn;
-  tree access_checks;
   cp_token *token;
   bool declares_class_or_enum;
   bool member_p;
@@ -11198,8 +11015,8 @@ cp_parser_function_definition (parser, friend_p)
      function is being defined.  There is no need to do this for the
      definition of member functions; we cannot be defining a member
      from another class.  */
-  if (!member_p)
-    cp_parser_start_deferring_access_checks (parser);
+  push_deferring_access_checks (!member_p);
+
   /* Parse the decl-specifier-seq.  */
   decl_specifiers 
     = cp_parser_decl_specifier_seq (parser,
@@ -11215,10 +11032,7 @@ cp_parser_function_definition (parser, friend_p)
                                     /*ctor_dtor_or_conv_p=*/NULL);
 
   /* Gather up any access checks that occurred.  */
-  if (!member_p)
-    access_checks = cp_parser_stop_deferring_access_checks (parser);
-  else
-    access_checks = NULL_TREE;
+  stop_deferring_access_checks ();
 
   /* If something has already gone wrong, we may as well stop now.  */
   if (declarator == error_mark_node)
@@ -11227,6 +11041,7 @@ cp_parser_function_definition (parser, friend_p)
         like a function-definition, to a `;' in the hopes of finding
         a sensible place from which to continue parsing.  */
       cp_parser_skip_to_end_of_block_or_statement (parser);
+      pop_deferring_access_checks ();
       return error_mark_node;
     }
 
@@ -11241,6 +11056,7 @@ cp_parser_function_definition (parser, friend_p)
       /* Skip to the next `;'.  */
       cp_parser_skip_to_end_of_block_or_statement (parser);
 
+      pop_deferring_access_checks ();
       return error_mark_node;
     }
 
@@ -11269,6 +11085,7 @@ cp_parser_function_definition (parser, friend_p)
          if (cp_parser_token_starts_function_definition_p 
              (cp_lexer_peek_token (parser->lexer)))
            cp_parser_skip_to_end_of_block_or_statement (parser);
+         pop_deferring_access_checks ();
          return error_mark_node;
        }
 
@@ -11294,6 +11111,7 @@ cp_parser_function_definition (parser, friend_p)
        = tree_cons (NULL_TREE, fn, 
                     TREE_VALUE (parser->unparsed_functions_queues));
 
+      pop_deferring_access_checks ();
       return fn;
     }
 
@@ -11302,11 +11120,14 @@ cp_parser_function_definition (parser, friend_p)
                                                       declarator))
     {
       cp_parser_skip_to_end_of_block_or_statement (parser);
+      pop_deferring_access_checks ();
       return error_mark_node;
     }
 
-  return (cp_parser_function_definition_from_specifiers_and_declarator
-         (parser, decl_specifiers, attributes, declarator, access_checks));
+  fn = cp_parser_function_definition_from_specifiers_and_declarator
+         (parser, decl_specifiers, attributes, declarator);
+  pop_deferring_access_checks ();
+  return fn;
 }
 
 /* Parse a function-body.
@@ -11670,25 +11491,29 @@ cp_parser_class_specifier (parser)
   tree attributes = NULL_TREE;
   int has_trailing_semicolon;
   bool nested_name_specifier_p;
-  bool deferring_access_checks_p;
-  tree saved_access_checks;
   unsigned saved_num_template_parameter_lists;
 
+  push_deferring_access_checks (false);  
+
   /* Parse the class-head.  */
   type = cp_parser_class_head (parser,
-                              &nested_name_specifier_p,
-                              &deferring_access_checks_p,
-                              &saved_access_checks);
+                              &nested_name_specifier_p);
   /* If the class-head was a semantic disaster, skip the entire body
      of the class.  */
   if (!type)
     {
       cp_parser_skip_to_end_of_block_or_statement (parser);
+      pop_deferring_access_checks ();
       return error_mark_node;
     }
+
   /* Look for the `{'.  */
   if (!cp_parser_require (parser, CPP_OPEN_BRACE, "`{'"))
-    return error_mark_node;
+    {
+      pop_deferring_access_checks ();
+      return error_mark_node;
+    }
+
   /* Issue an error message if type-definitions are forbidden here.  */
   cp_parser_check_type_definition (parser);
   /* Remember that we are defining one more class.  */
@@ -11797,11 +11622,7 @@ cp_parser_class_specifier (parser)
     }
 
   /* Put back any saved access checks.  */
-  if (deferring_access_checks_p)
-    {
-      cp_parser_start_deferring_access_checks (parser);
-      parser->context->deferred_access_checks = saved_access_checks;
-    }
+  pop_deferring_access_checks ();
 
   /* Restore the count of active template-parameter-lists.  */
   parser->num_template_parameter_lists
@@ -11827,10 +11648,6 @@ cp_parser_class_specifier (parser)
    Returns the TYPE of the indicated class.  Sets
    *NESTED_NAME_SPECIFIER_P to TRUE iff one of the productions
    involving a nested-name-specifier was used, and FALSE otherwise.
-   Sets *DEFERRING_ACCESS_CHECKS_P to TRUE iff we were deferring
-   access checks before this class-head.  In that case,
-   *SAVED_ACCESS_CHECKS is set to the current list of deferred access
-   checks.  
 
    Returns NULL_TREE if the class-head is syntactically valid, but
    semantically invalid in a way that means we should skip the entire
@@ -11838,13 +11655,9 @@ cp_parser_class_specifier (parser)
 
 static tree
 cp_parser_class_head (parser, 
-                     nested_name_specifier_p,
-                     deferring_access_checks_p,
-                     saved_access_checks)
+                     nested_name_specifier_p)
      cp_parser *parser;
      bool *nested_name_specifier_p;
-     bool *deferring_access_checks_p;
-     tree *saved_access_checks;
 {
   cp_token *token;
   tree nested_name_specifier;
@@ -12004,14 +11817,6 @@ cp_parser_class_head (parser,
        process the class-definition.  */
     return NULL_TREE;
 
-  /* We do not need to defer access checks for entities declared
-     within the class.  But, we do need to save any access checks that
-     are currently deferred and restore them later, in case we are in
-     the middle of something else.  */
-  *deferring_access_checks_p = parser->context->deferring_access_checks_p;
-  if (*deferring_access_checks_p)
-    *saved_access_checks = cp_parser_stop_deferring_access_checks (parser);
-
   /* Look up the type.  */
   if (template_id_p)
     {
@@ -12165,7 +11970,6 @@ cp_parser_member_specification_opt (parser)
          /* Otherwise, the next construction must be a
             member-declaration.  */
          cp_parser_member_declaration (parser);
-         reset_type_access_control ();
        }
     }
 }
@@ -13659,15 +13463,7 @@ cp_parser_lookup_name (cp_parser *parser, tree name, bool check_access,
                                                       object_type,
                                                       parser->scope);
       if (qualifying_type)
-       {
-         /* If we are supposed to defer access checks, just record
-            the information for later.  */
-         if (parser->context->deferring_access_checks_p)
-           cp_parser_defer_access_check (parser, qualifying_type, decl);
-         /* Otherwise, check accessibility now.  */
-         else
-           enforce_access (qualifying_type, decl);
-       }
+       perform_or_defer_access_check (qualifying_type, decl);
     }
 
   return decl;
@@ -14129,19 +13925,18 @@ cp_parser_constructor_declarator_p (cp_parser *parser, bool friend_p)
 }
 
 /* Parse the definition of the function given by the DECL_SPECIFIERS,
-   ATTRIBUTES, and DECLARATOR.  The ACCESS_CHECKS have been deferred;
+   ATTRIBUTES, and DECLARATOR.  The access checks have been deferred;
    they must be performed once we are in the scope of the function.
 
    Returns the function defined.  */
 
 static tree
 cp_parser_function_definition_from_specifiers_and_declarator
-  (parser, decl_specifiers, attributes, declarator, access_checks)
+  (parser, decl_specifiers, attributes, declarator)
      cp_parser *parser;
      tree decl_specifiers;
      tree attributes;
      tree declarator;
-     tree access_checks;
 {
   tree fn;
   bool success_p;
@@ -14155,7 +13950,7 @@ cp_parser_function_definition_from_specifiers_and_declarator
      did not check, check them now.  We must wait until we are in the
      scope of the function to perform the checks, since the function
      might be a friend.  */
-  cp_parser_perform_deferred_access_checks (access_checks);
+  perform_deferred_access_checks ();
 
   if (!success_p)
     {
@@ -14335,13 +14130,13 @@ cp_parser_single_declaration (parser,
   tree decl = NULL_TREE;
   tree decl_specifiers;
   tree attributes;
-  tree access_checks;
 
   /* Parse the dependent declaration.  We don't know yet
      whether it will be a function-definition.  */
   cp_parser_parse_tentatively (parser);
   /* Defer access checks until we know what is being declared.  */
-  cp_parser_start_deferring_access_checks (parser);
+  push_deferring_access_checks (true);
+
   /* Try the `decl-specifier-seq [opt] init-declarator [opt]'
      alternative.  */
   decl_specifiers 
@@ -14351,7 +14146,8 @@ cp_parser_single_declaration (parser,
                                    &declares_class_or_enum);
   /* Gather up the access checks that occurred the
      decl-specifier-seq.  */
-  access_checks = cp_parser_stop_deferring_access_checks (parser);
+  stop_deferring_access_checks ();
+
   /* Check for the declaration of a template class.  */
   if (declares_class_or_enum)
     {
@@ -14377,10 +14173,12 @@ cp_parser_single_declaration (parser,
     decl = cp_parser_init_declarator (parser, 
                                      decl_specifiers,
                                      attributes,
-                                     access_checks,
                                      /*function_definition_allowed_p=*/false,
                                      member_p,
                                      /*function_definition_p=*/NULL);
+
+  pop_deferring_access_checks ();
+
   /* Clear any current qualification; whatever comes next is the start
      of something new.  */
   parser->scope = NULL_TREE;
@@ -14881,9 +14679,7 @@ cp_parser_pre_parsed_nested_name_specifier (cp_parser *parser)
   value = cp_lexer_consume_token (parser->lexer)->value;
   /* Perform any access checks that were deferred.  */
   for (check = TREE_PURPOSE (value); check; check = TREE_CHAIN (check))
-    cp_parser_defer_access_check (parser, 
-                                 TREE_PURPOSE (check),
-                                 TREE_VALUE (check));
+    perform_or_defer_access_check (TREE_PURPOSE (check), TREE_VALUE (check));
   /* Set the scope from the stored value.  */
   parser->scope = TREE_VALUE (value);
   parser->qualifying_scope = TREE_TYPE (value);
@@ -14942,7 +14738,7 @@ cp_parser_parse_tentatively (parser)
   /* In order to avoid repetitive access control error messages,
      access checks are queued up until we are no longer parsing
      tentatively.  */
-  cp_parser_start_deferring_access_checks (parser);
+  push_deferring_access_checks (true);
 }
 
 /* Commit to the currently active tentative parse.  */
@@ -15004,22 +14800,16 @@ cp_parser_parse_definitely (parser)
         already done.  */
       if (context->status != CP_PARSER_STATUS_KIND_COMMITTED)
        cp_lexer_commit_tokens (parser->lexer);
-      if (!parser->context->deferring_access_checks_p)
-       /* If in the parent context we are not deferring checks, then
-          these perform these checks now.  */
-       (cp_parser_perform_deferred_access_checks 
-        (context->deferred_access_checks));
-      else
-       /* Any lookups that were deferred during the tentative parse are
-          still deferred.  */
-       parser->context->deferred_access_checks 
-         = chainon (parser->context->deferred_access_checks,
-                    context->deferred_access_checks);
+
+      pop_to_parent_deferring_access_checks ();
     }
   /* Otherwise, if errors occurred, roll back our state so that things
      are just as they were before we began the tentative parse.  */
   else
-    cp_lexer_rollback_tokens (parser->lexer);
+    {
+      cp_lexer_rollback_tokens (parser->lexer);
+      pop_deferring_access_checks ();
+    }
   /* Add the context to the front of the free list.  */
   context->next = cp_parser_context_free_list;
   cp_parser_context_free_list = context;
@@ -15074,6 +14864,7 @@ yyparse ()
   bool error_occurred;
 
   the_parser = cp_parser_new ();
+  push_deferring_access_checks (false);
   error_occurred = cp_parser_translation_unit (the_parser);
   the_parser = NULL;
   
index 5e9b395..0895a76 100644 (file)
@@ -979,41 +979,6 @@ friend_accessible_p (scope, decl, binfo)
   return 0;
 }
 
-/* Perform access control on TYPE_DECL or TEMPLATE_DECL VAL, which was
-   looked up in TYPE.  This is fairly complex, so here's the design:
-
-   The lang_extdef nonterminal sets type_lookups to NULL_TREE before we
-     start to process a top-level declaration.
-   As we process the decl-specifier-seq for the declaration, any types we
-     see that might need access control are passed to type_access_control,
-     which defers checking by adding them to type_lookups.
-   When we are done with the decl-specifier-seq, we record the lookups we've
-     seen in the lookups field of the typed_declspecs nonterminal.
-   When we process the first declarator, either in parse_decl or
-     begin_function_definition, we call save_type_access_control,
-     which stores the lookups from the decl-specifier-seq in
-     current_type_lookups.
-   As we finish with each declarator, we process everything in type_lookups
-     via decl_type_access_control, which resets type_lookups to the value of
-     current_type_lookups for subsequent declarators.
-   When we enter a function, we set type_lookups to error_mark_node, so all
-     lookups are processed immediately.  */
-
-void
-type_access_control (type, val)
-     tree type, val;
-{
-  if (val == NULL_TREE
-      || (TREE_CODE (val) != TEMPLATE_DECL && TREE_CODE (val) != TYPE_DECL)
-      || ! DECL_CLASS_SCOPE_P (val))
-    return;
-
-  if (type_lookups == error_mark_node)
-    enforce_access (type, val);
-  else if (! accessible_p (type, val))
-    type_lookups = tree_cons (type, val, type_lookups);
-}
-
 /* DECL is a declaration from a base class of TYPE, which was the
    class used to name DECL.  Return nonzero if, in the current
    context, DECL is accessible.  If TYPE is actually a BINFO node,
index 3ed9f2e..e3ae9be 100644 (file)
@@ -52,7 +52,6 @@
 
 static tree maybe_convert_cond PARAMS ((tree));
 static tree simplify_aggr_init_exprs_r PARAMS ((tree *, int *, void *));
-static void deferred_type_access_control PARAMS ((void));
 static void emit_associated_thunks PARAMS ((tree));
 static void genrtl_try_block PARAMS ((tree));
 static void genrtl_eh_spec_block PARAMS ((tree));
@@ -79,6 +78,145 @@ static tree clear_decl_rtl PARAMS ((tree *, int *, void *));
       (SUBSTMT) = (COND);                              \
   } while (0)
 
+/* Data for deferred access checking.  */
+static GTY(()) deferred_access *deferred_access_stack;
+static GTY(()) deferred_access *deferred_access_free_list;
+
+/* Save the current deferred access states and start deferred
+   access checking iff DEFER_P is true.  */
+
+void push_deferring_access_checks (bool deferring_p)
+{
+  deferred_access *d;
+
+  /* Recycle previously used free store if available.  */
+  if (deferred_access_free_list)
+    {
+      d = deferred_access_free_list;
+      deferred_access_free_list = d->next;
+    }
+  else
+    d = (deferred_access *) ggc_alloc (sizeof (deferred_access));
+
+  d->next = deferred_access_stack;
+  d->deferred_access_checks = NULL_TREE;
+  d->deferring_access_checks_p = deferring_p;
+  deferred_access_stack = d;
+}
+
+/* Resume deferring access checks again after we stopped doing
+   this previously.  */
+
+void resume_deferring_access_checks (void)
+{
+  deferred_access_stack->deferring_access_checks_p = true;
+}
+
+/* Stop deferring access checks.  */
+
+void stop_deferring_access_checks (void)
+{
+  deferred_access_stack->deferring_access_checks_p = false;
+}
+
+/* Discard the current deferred access checks and restore the
+   previous states.  */
+
+void pop_deferring_access_checks (void)
+{
+  deferred_access *d = deferred_access_stack;
+  deferred_access_stack = d->next;
+
+  /* Remove references to access checks TREE_LIST.  */
+  d->deferred_access_checks = NULL_TREE;
+
+  /* Store in free list for later use.  */
+  d->next = deferred_access_free_list;
+  deferred_access_free_list = d;
+}
+
+/* Returns a TREE_LIST representing the deferred checks.  
+   The TREE_PURPOSE of each node is the type through which the 
+   access occurred; the TREE_VALUE is the declaration named.
+   */
+
+tree get_deferred_access_checks (void)
+{
+  return deferred_access_stack->deferred_access_checks;
+}
+
+/* Take current deferred checks and combine with the
+   previous states if we also defer checks previously.
+   Otherwise perform checks now.  */
+
+void pop_to_parent_deferring_access_checks (void)
+{
+  tree deferred_check = get_deferred_access_checks ();
+  deferred_access *d1 = deferred_access_stack;
+  deferred_access *d2 = deferred_access_stack->next;
+  deferred_access *d3 = deferred_access_stack->next->next;
+
+  /* Temporary swap the order of the top two states, just to make
+     sure the garbage collector will not reclaim the memory during 
+     processing below.  */
+  deferred_access_stack = d2;
+  d2->next = d1;
+  d1->next = d3;
+
+  for ( ; deferred_check; deferred_check = TREE_CHAIN (deferred_check))
+    /* Perform deferred check if required.  */
+    perform_or_defer_access_check (TREE_PURPOSE (deferred_check), 
+                                  TREE_VALUE (deferred_check));
+
+  deferred_access_stack = d1;
+  d1->next = d2;
+  d2->next = d3;
+  pop_deferring_access_checks ();
+}
+
+/* Perform the deferred access checks.  */
+
+void perform_deferred_access_checks (void)
+{
+  tree deferred_check;
+  for (deferred_check = deferred_access_stack->deferred_access_checks;
+       deferred_check;
+       deferred_check = TREE_CHAIN (deferred_check))
+    /* Check access.  */
+    enforce_access (TREE_PURPOSE (deferred_check), 
+                   TREE_VALUE (deferred_check));
+
+  /* No more deferred checks.  */
+  deferred_access_stack->deferred_access_checks = NULL_TREE;
+}
+
+/* Defer checking the accessibility of DECL, when looked up in
+   CLASS_TYPE.  */
+
+void perform_or_defer_access_check (tree class_type, tree decl)
+{
+  tree check;
+
+  /* If we are not supposed to defer access checks, just check now.  */
+  if (!deferred_access_stack->deferring_access_checks_p)
+    {
+      enforce_access (class_type, decl);
+      return;
+    }
+
+  /* See if we are already going to perform this check.  */
+  for (check = deferred_access_stack->deferred_access_checks;
+       check;
+       check = TREE_CHAIN (check))
+    if (TREE_VALUE (check) == decl
+       && same_type_p (TREE_PURPOSE (check), class_type))
+      return;
+  /* If not, record the check.  */
+  deferred_access_stack->deferred_access_checks
+    = tree_cons (class_type, decl,
+                deferred_access_stack->deferred_access_checks);
+}
+
 /* Returns nonzero if the current statement is a full expression,
    i.e. temporaries created during that statement should be destroyed
    at the end of the statement.  */
@@ -1506,63 +1644,6 @@ finish_fname (tree id)
   return decl;
 }
 
-static tree current_type_lookups;
-
-/* Perform deferred access control for types used in the type of a
-   declaration.  */
-
-static void
-deferred_type_access_control ()
-{
-  tree lookup = type_lookups;
-
-  if (lookup == error_mark_node)
-    return;
-
-  for (; lookup; lookup = TREE_CHAIN (lookup))
-    enforce_access (TREE_PURPOSE (lookup), TREE_VALUE (lookup));
-}
-
-void
-decl_type_access_control (decl)
-     tree decl;
-{
-  tree save_fn;
-
-  if (type_lookups == error_mark_node)
-    return;
-
-  save_fn = current_function_decl;
-
-  if (decl && TREE_CODE (decl) == FUNCTION_DECL)
-    current_function_decl = decl;
-
-  deferred_type_access_control ();
-
-  current_function_decl = save_fn;
-  
-  /* Now strip away the checks for the current declarator; they were
-     added to type_lookups after typed_declspecs saved the copy that
-     ended up in current_type_lookups.  */
-  type_lookups = current_type_lookups;
-}
-
-void
-save_type_access_control (lookups)
-     tree lookups;
-{
-  current_type_lookups = lookups;
-}
-
-/* Reset the deferred access control.  */
-
-void
-reset_type_access_control ()
-{
-  type_lookups = NULL_TREE;
-  current_type_lookups = NULL_TREE;
-}
-
 /* Begin a function definition declared with DECL_SPECS, ATTRIBUTES,
    and DECLARATOR.  Returns nonzero if the function-declaration is
    valid.  */
@@ -1576,9 +1657,6 @@ begin_function_definition (decl_specs, attributes, declarator)
   if (!start_function (decl_specs, declarator, attributes, SF_DEFAULT))
     return 0;
 
-  deferred_type_access_control ();
-  type_lookups = error_mark_node;
-
   /* The things we're about to see are not directly qualified by any
      template headers we've seen thus far.  */
   reset_specialization ();
@@ -1714,10 +1792,6 @@ begin_class_definition (t)
   if (t == error_mark_node)
     return error_mark_node;
 
-  /* Check the bases are accessible.  */
-  decl_type_access_control (TYPE_NAME (t));
-  reset_type_access_control ();
-  
   if (processing_template_parmlist)
     {
       error ("definition of `%#T' inside template parameter list", t);
@@ -2690,3 +2764,5 @@ init_cp_semantics ()
 {
   lang_expand_stmt = cp_expand_stmt;
 }
+
+#include "gt-cp-semantics.h"