aboutsummaryrefslogtreecommitdiff
path: root/gcc/cp/name-lookup.c
diff options
context:
space:
mode:
authorKriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>2005-03-14 14:51:25 +0000
committerKriang Lerdsuwanakij <lerdsuwa@gcc.gnu.org>2005-03-14 14:51:25 +0000
commit5a24482e72fb06ef2e93050cdb056002f99bb226 (patch)
treeebe96dca1d08f5e123696a21d05cb1a03baaae0f /gcc/cp/name-lookup.c
parent184107932d56261a7786e3086212cfa32db6acd0 (diff)
downloadgcc-5a24482e72fb06ef2e93050cdb056002f99bb226.zip
gcc-5a24482e72fb06ef2e93050cdb056002f99bb226.tar.gz
gcc-5a24482e72fb06ef2e93050cdb056002f99bb226.tar.bz2
re PR c++/4403 (incorrect class becomes a friend in template)
PR c++/4403 PR c++/9783, DR433 * name-lookup.c (pushtag): Skip template parameter scope when scope is ts_global. Don't push tag into template parameter scope. * pt.c (instantiate_class_template): Reorder friend class template substitution to handle non-dependent friend class that hasn't been previously declared. * g++.dg/template/friend34.C: New test. * g++.dg/template/friend35.C: Likewise. * g++.old-deja/g++.pt/inherit2.C: Remove XFAIL's. From-SVN: r96432
Diffstat (limited to 'gcc/cp/name-lookup.c')
-rw-r--r--gcc/cp/name-lookup.c26
1 files changed, 17 insertions, 9 deletions
diff --git a/gcc/cp/name-lookup.c b/gcc/cp/name-lookup.c
index 4a5429c..fda7d34 100644
--- a/gcc/cp/name-lookup.c
+++ b/gcc/cp/name-lookup.c
@@ -4571,10 +4571,19 @@ maybe_process_template_type_declaration (tree type, int is_friend,
return decl;
}
-/* Push a tag name NAME for struct/class/union/enum type TYPE.
- Normally put it into the inner-most non-sk_cleanup scope,
- but if GLOBALIZE is true, put it in the inner-most non-class scope.
- The latter is needed for implicit declarations.
+/* Push a tag name NAME for struct/class/union/enum type TYPE. In case
+ that the NAME is a class template, the tag is processed but not pushed.
+
+ The pushed scope depend on the SCOPE parameter:
+ - When SCOPE is TS_CURRENT, put it into the inner-most non-sk_cleanup
+ scope.
+ - When SCOPE is TS_GLOBAL, put it in the inner-most non-class and
+ non-template-parameter scope. This case is needed for forward
+ declarations.
+ - When SCOPE is TS_WITHIN_ENCLOSING_NON_CLASS, this is similar to
+ TS_GLOBAL case except that names within template-parameter scopes
+ are not pushed at all.
+
Returns TYPE upon success and ERROR_MARK_NODE otherwise. */
tree
@@ -4590,10 +4599,9 @@ pushtag (tree name, tree type, tag_scope scope)
/* Neither are the scopes used to hold template parameters
for an explicit specialization. For an ordinary template
declaration, these scopes are not scopes from the point of
- view of the language -- but we need a place to stash
- things that will go in the containing namespace when the
- template is instantiated. */
- || (b->kind == sk_template_parms && b->explicit_spec_p)
+ view of the language. */
+ || (b->kind == sk_template_parms
+ && (b->explicit_spec_p || scope == ts_global))
|| (b->kind == sk_class
&& (scope != ts_current
/* We may be defining a new type in the initializer
@@ -4666,7 +4674,7 @@ pushtag (tree name, tree type, tag_scope scope)
else
pushdecl_class_level (d);
}
- else
+ else if (b->kind != sk_template_parms)
d = pushdecl_with_scope (d, b);
if (d == error_mark_node)