diff options
author | Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net> | 2005-03-14 14:51:25 +0000 |
---|---|---|
committer | Kriang Lerdsuwanakij <lerdsuwa@gcc.gnu.org> | 2005-03-14 14:51:25 +0000 |
commit | 5a24482e72fb06ef2e93050cdb056002f99bb226 (patch) | |
tree | ebe96dca1d08f5e123696a21d05cb1a03baaae0f /gcc/cp/name-lookup.c | |
parent | 184107932d56261a7786e3086212cfa32db6acd0 (diff) | |
download | gcc-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.c | 26 |
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) |