From 4fa14515aca80a81ffd07ec51fa66bca539d8e07 Mon Sep 17 00:00:00 2001 From: Richard Smith Date: Thu, 21 Dec 2017 19:43:39 +0000 Subject: [PATCH] When instantiating a deduction guide, transform its name. Otherwise it will serve as a deduction guide for the wrong class template. llvm-svn: 321297 --- clang/lib/Sema/SemaTemplateInstantiateDecl.cpp | 10 +++++++--- clang/test/SemaTemplate/nested-deduction-guides.cpp | 13 +++++++++++++ 2 files changed, 20 insertions(+), 3 deletions(-) create mode 100644 clang/test/SemaTemplate/nested-deduction-guides.cpp diff --git a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp index b926e573ade6..1deb8638756b 100644 --- a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp +++ b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp @@ -1587,9 +1587,10 @@ static QualType adjustFunctionTypeForInstantiation(ASTContext &Context, } /// Normal class members are of more specific types and therefore -/// don't make it here. This function serves two purposes: +/// don't make it here. This function serves three purposes: /// 1) instantiating function templates /// 2) substituting friend declarations +/// 3) substituting deduction guide declarations for nested class templates Decl *TemplateDeclInstantiator::VisitFunctionDecl(FunctionDecl *D, TemplateParameterList *TemplateParams) { // Check whether there is already a function template specialization for @@ -1650,16 +1651,19 @@ Decl *TemplateDeclInstantiator::VisitFunctionDecl(FunctionDecl *D, TemplateArgs); } + DeclarationNameInfo NameInfo + = SemaRef.SubstDeclarationNameInfo(D->getNameInfo(), TemplateArgs); + FunctionDecl *Function; if (auto *DGuide = dyn_cast(D)) { Function = CXXDeductionGuideDecl::Create( SemaRef.Context, DC, D->getInnerLocStart(), DGuide->isExplicit(), - D->getNameInfo(), T, TInfo, D->getSourceRange().getEnd()); + NameInfo, T, TInfo, D->getSourceRange().getEnd()); if (DGuide->isCopyDeductionCandidate()) cast(Function)->setIsCopyDeductionCandidate(); } else { Function = FunctionDecl::Create( - SemaRef.Context, DC, D->getInnerLocStart(), D->getNameInfo(), T, TInfo, + SemaRef.Context, DC, D->getInnerLocStart(), NameInfo, T, TInfo, D->getCanonicalDecl()->getStorageClass(), D->isInlineSpecified(), D->hasWrittenPrototype(), D->isConstexpr()); Function->setRangeEnd(D->getSourceRange().getEnd()); diff --git a/clang/test/SemaTemplate/nested-deduction-guides.cpp b/clang/test/SemaTemplate/nested-deduction-guides.cpp new file mode 100644 index 000000000000..2c5dda456a13 --- /dev/null +++ b/clang/test/SemaTemplate/nested-deduction-guides.cpp @@ -0,0 +1,13 @@ +// RUN: %clang_cc1 -std=c++17 -verify %s +// expected-no-diagnostics + +template struct A { + template struct B { + B(...); + }; + template B(U) -> B; +}; +A::B b = 123; + +using T = decltype(b); +using T = A::B;