PR32673: Don't wrap parameter packs in SubstTemplateTypeParmPackType nodes when forming implicit deduction guides.

Doing so thwarts template type deduction. Instead, substitute the pack directly
by picking "slice 0" of the resulting expansion.

llvm-svn: 300805
This commit is contained in:
Richard Smith 2017-04-20 01:15:31 +00:00
parent a90474544e
commit 479ba8ee0e
3 changed files with 56 additions and 6 deletions

View File

@ -1544,7 +1544,11 @@ class DependentSizedArrayTypeLoc :
public InheritingConcreteTypeLoc<ArrayTypeLoc,
DependentSizedArrayTypeLoc,
DependentSizedArrayType> {
public:
void initializeLocal(ASTContext &Context, SourceLocation Loc) {
ArrayTypeLoc::initializeLocal(Context, Loc);
setSizeExpr(getTypePtr()->getSizeExpr());
}
};
class VariableArrayTypeLoc :

View File

@ -1636,11 +1636,22 @@ private:
transformFunctionTypeParam(ParmVarDecl *OldParam,
MultiLevelTemplateArgumentList &Args) {
TypeSourceInfo *OldDI = OldParam->getTypeSourceInfo();
TypeSourceInfo *NewDI =
Args.getNumLevels()
? SemaRef.SubstType(OldDI, Args, OldParam->getLocation(),
OldParam->getDeclName())
: OldDI;
TypeSourceInfo *NewDI;
if (!Args.getNumLevels())
NewDI = OldDI;
else if (auto PackTL = OldDI->getTypeLoc().getAs<PackExpansionTypeLoc>()) {
// Expand out the one and only element in each inner pack.
Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(SemaRef, 0);
NewDI =
SemaRef.SubstType(PackTL.getPatternLoc(), Args,
OldParam->getLocation(), OldParam->getDeclName());
if (!NewDI) return nullptr;
NewDI =
SemaRef.CheckPackExpansion(NewDI, PackTL.getEllipsisLoc(),
PackTL.getTypePtr()->getNumExpansions());
} else
NewDI = SemaRef.SubstType(OldDI, Args, OldParam->getLocation(),
OldParam->getDeclName());
if (!NewDI)
return nullptr;

View File

@ -213,3 +213,38 @@ namespace transform_params {
};
D d(Y<0, 1, 2>{});
}
namespace variadic {
int arr3[3], arr4[4];
// PR32673
template<typename T> struct A {
template<typename ...U> A(T, U...);
};
A a(1, 2, 3);
template<typename T> struct B {
template<int ...N> B(T, int (&...r)[N]);
};
B b(1, arr3, arr4);
template<typename T> struct C {
template<template<typename> typename ...U> C(T, U<int>...);
};
C c(1, a, b);
template<typename ...U> struct X {
template<typename T> X(T, U...);
};
X x(1, 2, 3);
template<int ...N> struct Y {
template<typename T> Y(T, int (&...r)[N]);
};
Y y(1, arr3, arr4);
template<template<typename> typename ...U> struct Z {
template<typename T> Z(T, U<int>...);
};
Z z(1, a, b);
}