When instantiating a deduction guide, transform its name.

Otherwise it will serve as a deduction guide for the wrong class template.

llvm-svn: 321297
This commit is contained in:
Richard Smith 2017-12-21 19:43:39 +00:00
parent 614f3702d9
commit 4fa14515ac
2 changed files with 20 additions and 3 deletions

View File

@ -1587,9 +1587,10 @@ static QualType adjustFunctionTypeForInstantiation(ASTContext &Context,
} }
/// Normal class members are of more specific types and therefore /// 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 /// 1) instantiating function templates
/// 2) substituting friend declarations /// 2) substituting friend declarations
/// 3) substituting deduction guide declarations for nested class templates
Decl *TemplateDeclInstantiator::VisitFunctionDecl(FunctionDecl *D, Decl *TemplateDeclInstantiator::VisitFunctionDecl(FunctionDecl *D,
TemplateParameterList *TemplateParams) { TemplateParameterList *TemplateParams) {
// Check whether there is already a function template specialization for // Check whether there is already a function template specialization for
@ -1650,16 +1651,19 @@ Decl *TemplateDeclInstantiator::VisitFunctionDecl(FunctionDecl *D,
TemplateArgs); TemplateArgs);
} }
DeclarationNameInfo NameInfo
= SemaRef.SubstDeclarationNameInfo(D->getNameInfo(), TemplateArgs);
FunctionDecl *Function; FunctionDecl *Function;
if (auto *DGuide = dyn_cast<CXXDeductionGuideDecl>(D)) { if (auto *DGuide = dyn_cast<CXXDeductionGuideDecl>(D)) {
Function = CXXDeductionGuideDecl::Create( Function = CXXDeductionGuideDecl::Create(
SemaRef.Context, DC, D->getInnerLocStart(), DGuide->isExplicit(), SemaRef.Context, DC, D->getInnerLocStart(), DGuide->isExplicit(),
D->getNameInfo(), T, TInfo, D->getSourceRange().getEnd()); NameInfo, T, TInfo, D->getSourceRange().getEnd());
if (DGuide->isCopyDeductionCandidate()) if (DGuide->isCopyDeductionCandidate())
cast<CXXDeductionGuideDecl>(Function)->setIsCopyDeductionCandidate(); cast<CXXDeductionGuideDecl>(Function)->setIsCopyDeductionCandidate();
} else { } else {
Function = FunctionDecl::Create( 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->getCanonicalDecl()->getStorageClass(), D->isInlineSpecified(),
D->hasWrittenPrototype(), D->isConstexpr()); D->hasWrittenPrototype(), D->isConstexpr());
Function->setRangeEnd(D->getSourceRange().getEnd()); Function->setRangeEnd(D->getSourceRange().getEnd());

View File

@ -0,0 +1,13 @@
// RUN: %clang_cc1 -std=c++17 -verify %s
// expected-no-diagnostics
template<typename T> struct A {
template<typename U> struct B {
B(...);
};
template<typename U> B(U) -> B<U>;
};
A<void>::B b = 123;
using T = decltype(b);
using T = A<void>::B<int>;