diff options
author | Douglas Gregor <dgregor@apple.com> | 2010-04-18 17:37:40 +0000 |
---|---|---|
committer | Douglas Gregor <dgregor@apple.com> | 2010-04-18 17:37:40 +0000 |
commit | c1c9df77c098a651b56db3052ed174a47cbde5b6 (patch) | |
tree | c64cb94e36326f7b3938c83cbc45c00bb03d6550 | |
parent | d13ada13cb570ff9c0123ed267e2a7abfe662d23 (diff) |
C++ [namespace.memdef]p3 only applies when the friend is not named via
a qualified name. We weren't checking for an empty
nested-name-specifier when dealing with friend class templates
(although we were checking in the other places where we deal with this
paragraph). Fixes a Boost.Serialization showstopper.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@101724 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | lib/Sema/SemaTemplate.cpp | 32 | ||||
-rw-r--r-- | test/CXX/dcl.dcl/basic.namespace/namespace.def/namespace.memdef/p3.cpp | 12 |
2 files changed, 29 insertions, 15 deletions
diff --git a/lib/Sema/SemaTemplate.cpp b/lib/Sema/SemaTemplate.cpp index fbe331b6b2..a239a41e4e 100644 --- a/lib/Sema/SemaTemplate.cpp +++ b/lib/Sema/SemaTemplate.cpp @@ -801,22 +801,24 @@ Sema::CheckClassTemplate(Scope *S, unsigned TagSpec, TagUseKind TUK, // declared as a friend, and when the name of the friend class or // function is neither a qualified name nor a template-id, scopes outside // the innermost enclosing namespace scope are not considered. - DeclContext *OutermostContext = CurContext; - while (!OutermostContext->isFileContext()) - OutermostContext = OutermostContext->getLookupParent(); - - if (PrevDecl && - (OutermostContext->Equals(PrevDecl->getDeclContext()) || - OutermostContext->Encloses(PrevDecl->getDeclContext()))) { - SemanticContext = PrevDecl->getDeclContext(); - } else { - // Declarations in outer scopes don't matter. However, the outermost - // context we computed is the semantic context for our new - // declaration. - PrevDecl = PrevClassTemplate = 0; - SemanticContext = OutermostContext; + if (!SS.isSet()) { + DeclContext *OutermostContext = CurContext; + while (!OutermostContext->isFileContext()) + OutermostContext = OutermostContext->getLookupParent(); + + if (PrevDecl && + (OutermostContext->Equals(PrevDecl->getDeclContext()) || + OutermostContext->Encloses(PrevDecl->getDeclContext()))) { + SemanticContext = PrevDecl->getDeclContext(); + } else { + // Declarations in outer scopes don't matter. However, the outermost + // context we computed is the semantic context for our new + // declaration. + PrevDecl = PrevClassTemplate = 0; + SemanticContext = OutermostContext; + } } - + if (CurContext->isDependentContext()) { // If this is a dependent context, we don't want to link the friend // class template to the template in scope, because that would perform diff --git a/test/CXX/dcl.dcl/basic.namespace/namespace.def/namespace.memdef/p3.cpp b/test/CXX/dcl.dcl/basic.namespace/namespace.def/namespace.memdef/p3.cpp index a5f314dac2..ddcbe785a7 100644 --- a/test/CXX/dcl.dcl/basic.namespace/namespace.def/namespace.memdef/p3.cpp +++ b/test/CXX/dcl.dcl/basic.namespace/namespace.def/namespace.memdef/p3.cpp @@ -53,4 +53,16 @@ struct Y { friend union X1; }; +namespace N { + namespace M { + template<typename T> class X; + } +} + +namespace N3 { + class Y { + template<typename T> friend class N::M::X; + }; +} + // FIXME: Woefully inadequate for testing |