summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorlerdsuwa <lerdsuwa@138bc75d-0d04-0410-961f-82ee72b054a4>2003-07-13 15:20:58 +0000
committerlerdsuwa <lerdsuwa@138bc75d-0d04-0410-961f-82ee72b054a4>2003-07-13 15:20:58 +0000
commit9014db85af3572f0540f9584dde803ae6c4b10f5 (patch)
treece13981dd99c4ce196867c3b0624174f3860282e
parent0c1800a32591696524e7bdc7e6d03dcd990ff348 (diff)
downloadgcc-9014db85af3572f0540f9584dde803ae6c4b10f5.tar.gz
* 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. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@69291 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--gcc/cp/ChangeLog9
-rw-r--r--gcc/cp/pt.c80
2 files changed, 35 insertions, 54 deletions
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 <lerdsuwa@users.sourceforge.net>
+
+ * 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 <neroden@gcc.gnu.org>
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<Outer>' for code like
-
- template <class U> typename U::Inner foo ();
- class Outer {
- struct Inner {};
- friend Outer::Inner foo<Outer> ();
- };
-
- `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);