From: Kriang Lerdsuwanakij Date: Sun, 13 Jul 2003 15:20:58 +0000 (+0000) Subject: pt.c (push_access_scope_real): Remove. X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=2b907f5c4554c076038913e7c721ea8d6a8dcb31;p=gcc.git pt.c (push_access_scope_real): Remove. * pt.c (push_access_scope_real): Remove. (push_access_scope): Move code from push_access_scope_real. (pop_access_scope): Don't check for TEMPLATE_DECL. (instantiate_template): Defer access checking during template substitution. (regenerate_decl_from_template): Tidy. From-SVN: r69291 --- diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 281f21684e7..b275e8090d0 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,12 @@ +2003-07-13 Kriang Lerdsuwanakij + + * pt.c (push_access_scope_real): Remove. + (push_access_scope): Move code from push_access_scope_real. + (pop_access_scope): Don't check for TEMPLATE_DECL. + (instantiate_template): Defer access checking during template + substitution. + (regenerate_decl_from_template): Tidy. + 2003-07-11 Nathanael Nerode PR c++/11437 diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index b9c64acea4f..d7c56a2d557 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -88,7 +88,6 @@ static htab_t local_specializations; #define GTB_IGNORE_TYPE 2 /* We don't need to try to unify the current type with the desired type. */ -static void push_access_scope_real (tree, tree, tree); static void push_access_scope (tree); static void pop_access_scope (tree); static int resolve_overloaded_unification (tree, tree, tree, tree, @@ -173,49 +172,22 @@ static tree tsubst_copy (tree, tree, tsubst_flags_t, tree); /* Make the current scope suitable for access checking when we are processing T. T can be FUNCTION_DECL for instantiated function - template, TEMPLATE_DECL for uninstantiated one, or VAR_DECL for - static member variable (need by instantiate_decl). ARGS is the - template argument for TEMPLATE_DECL. If CONTEXT is not NULL_TREE, - this is used instead of the context of T. */ + template, or VAR_DECL for static member variable (need by + instantiate_decl). */ static void -push_access_scope_real (tree t, tree args, tree context) +push_access_scope (tree t) { - if (TREE_CODE (t) == FUNCTION_DECL || DECL_FUNCTION_TEMPLATE_P (t)) - { - /* When we are processing specialization `foo' for code like - - template typename U::Inner foo (); - class Outer { - struct Inner {}; - friend Outer::Inner foo (); - }; - - `T' is a TEMPLATE_DECL, but `Outer' is only a friend of one of - its specialization. We can get the FUNCTION_DECL with the right - information because this specialization has already been - registered by the friend declaration above. */ - - if (DECL_FUNCTION_TEMPLATE_P (t) && args) - { - tree full_args = tsubst_template_arg_vector - (DECL_TI_ARGS (DECL_TEMPLATE_RESULT (t)), args, tf_none); - tree spec = NULL_TREE; - if (full_args != error_mark_node) - spec = retrieve_specialization (t, full_args); - if (spec) - t = spec; - } - } + my_friendly_assert (TREE_CODE (t) == FUNCTION_DECL + || TREE_CODE (t) == VAR_DECL, + 0); - if (!context) - context = DECL_CONTEXT (t); - if (context && TYPE_P (context)) - push_nested_class (context); + if (DECL_CLASS_SCOPE_P (t)) + push_nested_class (DECL_CONTEXT (t)); else push_to_top_level (); - if (TREE_CODE (t) == FUNCTION_DECL || DECL_FUNCTION_TEMPLATE_P (t)) + if (TREE_CODE (t) == FUNCTION_DECL) { saved_access_scope = tree_cons (NULL_TREE, current_function_decl, saved_access_scope); @@ -223,21 +195,13 @@ push_access_scope_real (tree t, tree args, tree context) } } -/* Like push_access_scope_real, but always uses DECL_CONTEXT. */ - -static void -push_access_scope (tree t) -{ - push_access_scope_real (t, NULL_TREE, NULL_TREE); -} - /* Restore the scope set up by push_access_scope. T is the node we are processing. */ static void pop_access_scope (tree t) { - if (TREE_CODE (t) == FUNCTION_DECL || DECL_FUNCTION_TEMPLATE_P (t)) + if (TREE_CODE (t) == FUNCTION_DECL) { current_function_decl = TREE_VALUE (saved_access_scope); saved_access_scope = TREE_CHAIN (saved_access_scope); @@ -8509,18 +8473,23 @@ instantiate_template (tree tmpl, tree targ_ptr, tsubst_flags_t complain) complain)) return error_mark_node; - /* Make sure that we can see identifiers, and compute access - correctly. The desired FUNCTION_DECL for FNDECL may or may not be - created earlier. Let push_access_scope_real figure that out. */ - push_access_scope_real - (gen_tmpl, targ_ptr, tsubst (DECL_CONTEXT (gen_tmpl), targ_ptr, - complain, gen_tmpl)); + /* We are building a FUNCTION_DECL, during which the access of its + parameters and return types have to be checked. However this + FUNCTION_DECL which is the desired context for access checking + is not built yet. We solve this chicken-and-egg problem by + deferring all checks until we have the FUNCTION_DECL. */ + push_deferring_access_checks (dk_deferred); /* substitute template parameters */ fndecl = tsubst (DECL_TEMPLATE_RESULT (gen_tmpl), targ_ptr, complain, gen_tmpl); - pop_access_scope (gen_tmpl); + /* Now we know the specialization, compute access previously + deferred. */ + push_access_scope (fndecl); + perform_deferred_access_checks (); + pop_access_scope (fndecl); + pop_deferring_access_checks (); /* The DECL_TI_TEMPLATE should always be the immediate parent template, not the most general template. */ @@ -10618,7 +10587,6 @@ regenerate_decl_from_template (tree decl, tree tmpl) instantiation of a specialization, which it isn't: it's a full instantiation. */ gen_tmpl = most_general_template (tmpl); - push_access_scope_real (gen_tmpl, args, DECL_CONTEXT (decl)); unregistered = unregister_specialization (decl, gen_tmpl); /* If the DECL was not unregistered then something peculiar is @@ -10626,6 +10594,10 @@ regenerate_decl_from_template (tree decl, tree tmpl) register_specialization for it. */ my_friendly_assert (unregistered, 0); + /* Make sure that we can see identifiers, and compute access + correctly. */ + push_access_scope (decl); + /* Do the substitution to get the new declaration. */ new_decl = tsubst (code_pattern, args, tf_error, NULL_TREE);