From 1b398205267ea69f35230eea50e0225db22ebb7e Mon Sep 17 00:00:00 2001 From: Douglas Gregor Date: Wed, 29 Sep 2010 17:58:28 +0000 Subject: [PATCH] Fix handling of dependent nested namespace specifiers in UsingDecls during template instantiation, from Martin Vejnar! git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@115051 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Sema/SemaTemplateInstantiateDecl.cpp | 24 ++++++++++++++++---- test/SemaTemplate/instantiate-using-decl.cpp | 19 ++++++++++++++++ 2 files changed, 39 insertions(+), 4 deletions(-) diff --git a/lib/Sema/SemaTemplateInstantiateDecl.cpp b/lib/Sema/SemaTemplateInstantiateDecl.cpp index d87629151e..d0df7fae75 100644 --- a/lib/Sema/SemaTemplateInstantiateDecl.cpp +++ b/lib/Sema/SemaTemplateInstantiateDecl.cpp @@ -1558,8 +1558,24 @@ Decl *TemplateDeclInstantiator::VisitUsingDirectiveDecl(UsingDirectiveDecl *D) { } Decl *TemplateDeclInstantiator::VisitUsingDecl(UsingDecl *D) { - // The nested name specifier is non-dependent, so no transformation - // is required. The same holds for the name info. + + // The nested name specifier may be dependent, for example + // template struct t { + // struct s1 { T f1(); }; + // struct s2 : s1 { using s1::f1; }; + // }; + // template struct t; + // Here, in using s1::f1, s1 refers to t::s1; + // we need to substitute for t::s1. + NestedNameSpecifier *NNS = + SemaRef.SubstNestedNameSpecifier(D->getTargetNestedNameDecl(), + D->getNestedNameRange(), + TemplateArgs); + if (!NNS) + return 0; + + // The name info is non-dependent, so no transformation + // is required. DeclarationNameInfo NameInfo = D->getNameInfo(); // We only need to do redeclaration lookups if we're in a class @@ -1573,12 +1589,12 @@ Decl *TemplateDeclInstantiator::VisitUsingDecl(UsingDecl *D) { UsingDecl *NewUD = UsingDecl::Create(SemaRef.Context, Owner, D->getNestedNameRange(), D->getUsingLocation(), - D->getTargetNestedNameDecl(), + NNS, NameInfo, D->isTypeName()); CXXScopeSpec SS; - SS.setScopeRep(D->getTargetNestedNameDecl()); + SS.setScopeRep(NNS); SS.setRange(D->getNestedNameRange()); if (CheckRedeclaration) { diff --git a/test/SemaTemplate/instantiate-using-decl.cpp b/test/SemaTemplate/instantiate-using-decl.cpp index 257904490d..1bfcb7a865 100644 --- a/test/SemaTemplate/instantiate-using-decl.cpp +++ b/test/SemaTemplate/instantiate-using-decl.cpp @@ -61,3 +61,22 @@ namespace test2 { template void bar(char *); } + +namespace test3 { + template struct t { + struct s1 { + T f1() const; + }; + struct s2 : s1 { + using s1::f1; + T f1() const; + }; + }; + + void f2() + { + t::s2 a; + t::s2 const & b = a; + b.f1(); + } +} -- 2.40.0