From 259571e27e513cfaf691cc7447e09b31a47d5438 Mon Sep 17 00:00:00 2001 From: Douglas Gregor Date: Fri, 30 Oct 2009 22:42:42 +0000 Subject: [PATCH] When a friend is declared in a dependent context, don't even try to match it up with a declaration in the outer scope. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@85628 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Sema/SemaTemplate.cpp | 10 +++++++++- lib/Sema/SemaTemplateInstantiateDecl.cpp | 5 +++-- test/SemaTemplate/friend-template.cpp | 19 +++++++++++++++++++ 3 files changed, 31 insertions(+), 3 deletions(-) diff --git a/lib/Sema/SemaTemplate.cpp b/lib/Sema/SemaTemplate.cpp index fb5eef2760..f7a22d2eb0 100644 --- a/lib/Sema/SemaTemplate.cpp +++ b/lib/Sema/SemaTemplate.cpp @@ -613,11 +613,19 @@ Sema::CheckClassTemplate(Scope *S, unsigned TagSpec, TagUseKind TUK, SemanticContext = PrevDecl->getDeclContext(); } else { // Declarations in outer scopes don't matter. However, the outermost - // context we computed is the semntic context for our new + // context we computed is the semantic context for our new // declaration. PrevDecl = 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 + // checking of the template parameter lists that can't be performed + // until the outer context is instantiated. + PrevDecl = 0; + } } else if (PrevDecl && !isDeclInScope(PrevDecl, SemanticContext, S)) PrevDecl = 0; diff --git a/lib/Sema/SemaTemplateInstantiateDecl.cpp b/lib/Sema/SemaTemplateInstantiateDecl.cpp index f511eb15d2..f8f2217464 100644 --- a/lib/Sema/SemaTemplateInstantiateDecl.cpp +++ b/lib/Sema/SemaTemplateInstantiateDecl.cpp @@ -434,9 +434,10 @@ Decl *TemplateDeclInstantiator::VisitClassTemplateDecl(ClassTemplateDecl *D) { // Trigger creation of the type for the instantiation. SemaRef.Context.getTypeDeclType(RecordInst); - // We're done with friends now. - if (Inst->getFriendObjectKind()) + // Finish handling of friends. + if (Inst->getFriendObjectKind()) { return Inst; + } Owner->addDecl(Inst); diff --git a/test/SemaTemplate/friend-template.cpp b/test/SemaTemplate/friend-template.cpp index dc277f4657..84a8e899db 100644 --- a/test/SemaTemplate/friend-template.cpp +++ b/test/SemaTemplate/friend-template.cpp @@ -72,3 +72,22 @@ class Foo { }; Foo foo; + +template +struct X2a; + +template +struct X2b; + +template +class X3 { + template + friend struct X2a; + + template + friend struct X2b; +}; + +X3 x3i; // okay + +X3 x3l; // FIXME: should cause an instantiation-time failure -- 2.40.0