forked from OSchip/llvm-project
When we're substituting into a function parameter pack and expect to
get a function parameter pack (but don't due to weird substitutions), complain. Fixes the last bit of PR11848. llvm-svn: 148960
This commit is contained in:
parent
f7bf3db070
commit
0dd22bc4d6
|
@ -5100,7 +5100,8 @@ public:
|
|||
ParmVarDecl *SubstParmVarDecl(ParmVarDecl *D,
|
||||
const MultiLevelTemplateArgumentList &TemplateArgs,
|
||||
int indexAdjustment,
|
||||
llvm::Optional<unsigned> NumExpansions);
|
||||
llvm::Optional<unsigned> NumExpansions,
|
||||
bool ExpectParameterPack);
|
||||
bool SubstParmTypes(SourceLocation Loc,
|
||||
ParmVarDecl **Params, unsigned NumParams,
|
||||
const MultiLevelTemplateArgumentList &TemplateArgs,
|
||||
|
|
|
@ -778,7 +778,8 @@ namespace {
|
|||
FunctionProtoTypeLoc TL);
|
||||
ParmVarDecl *TransformFunctionTypeParam(ParmVarDecl *OldParm,
|
||||
int indexAdjustment,
|
||||
llvm::Optional<unsigned> NumExpansions);
|
||||
llvm::Optional<unsigned> NumExpansions,
|
||||
bool ExpectParameterPack);
|
||||
|
||||
/// \brief Transforms a template type parameter type by performing
|
||||
/// substitution of the corresponding template type argument.
|
||||
|
@ -1194,9 +1195,10 @@ QualType TemplateInstantiator::TransformFunctionProtoType(TypeLocBuilder &TLB,
|
|||
ParmVarDecl *
|
||||
TemplateInstantiator::TransformFunctionTypeParam(ParmVarDecl *OldParm,
|
||||
int indexAdjustment,
|
||||
llvm::Optional<unsigned> NumExpansions) {
|
||||
llvm::Optional<unsigned> NumExpansions,
|
||||
bool ExpectParameterPack) {
|
||||
return SemaRef.SubstParmVarDecl(OldParm, TemplateArgs, indexAdjustment,
|
||||
NumExpansions);
|
||||
NumExpansions, ExpectParameterPack);
|
||||
}
|
||||
|
||||
QualType
|
||||
|
@ -1450,7 +1452,8 @@ TypeSourceInfo *Sema::SubstFunctionDeclType(TypeSourceInfo *T,
|
|||
ParmVarDecl *Sema::SubstParmVarDecl(ParmVarDecl *OldParm,
|
||||
const MultiLevelTemplateArgumentList &TemplateArgs,
|
||||
int indexAdjustment,
|
||||
llvm::Optional<unsigned> NumExpansions) {
|
||||
llvm::Optional<unsigned> NumExpansions,
|
||||
bool ExpectParameterPack) {
|
||||
TypeSourceInfo *OldDI = OldParm->getTypeSourceInfo();
|
||||
TypeSourceInfo *NewDI = 0;
|
||||
|
||||
|
@ -1471,7 +1474,16 @@ ParmVarDecl *Sema::SubstParmVarDecl(ParmVarDecl *OldParm,
|
|||
// Therefore, make its type a pack expansion type.
|
||||
NewDI = CheckPackExpansion(NewDI, ExpansionTL.getEllipsisLoc(),
|
||||
NumExpansions);
|
||||
}
|
||||
} else if (ExpectParameterPack) {
|
||||
// We expected to get a parameter pack but didn't (because the type
|
||||
// itself is not a pack expansion type), so complain. This can occur when
|
||||
// the substitution goes through an alias template that "loses" the
|
||||
// pack expansion.
|
||||
Diag(OldParm->getLocation(),
|
||||
diag::err_function_parameter_pack_without_parameter_packs)
|
||||
<< NewDI->getType();
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
NewDI = SubstType(OldDI, TemplateArgs, OldParm->getLocation(),
|
||||
OldParm->getDeclName());
|
||||
|
@ -1506,9 +1518,7 @@ ParmVarDecl *Sema::SubstParmVarDecl(ParmVarDecl *OldParm,
|
|||
NewParm->setUninstantiatedDefaultArg(Arg);
|
||||
|
||||
NewParm->setHasInheritedDefaultArg(OldParm->hasInheritedDefaultArg());
|
||||
|
||||
// FIXME: When OldParm is a parameter pack and NewParm is not a parameter
|
||||
// pack, we actually have a set of instantiated locations. Maintain this set!
|
||||
|
||||
if (OldParm->isParameterPack() && !NewParm->isParameterPack()) {
|
||||
// Add the new parameter to the instantiated parameter pack.
|
||||
CurrentInstantiationScope->InstantiatedLocalPackArg(OldParm, NewParm);
|
||||
|
|
|
@ -1601,7 +1601,8 @@ Decl *TemplateDeclInstantiator::VisitCXXConversionDecl(CXXConversionDecl *D) {
|
|||
|
||||
ParmVarDecl *TemplateDeclInstantiator::VisitParmVarDecl(ParmVarDecl *D) {
|
||||
return SemaRef.SubstParmVarDecl(D, TemplateArgs, /*indexAdjustment*/ 0,
|
||||
llvm::Optional<unsigned>());
|
||||
llvm::Optional<unsigned>(),
|
||||
/*ExpectParameterPack=*/false);
|
||||
}
|
||||
|
||||
Decl *TemplateDeclInstantiator::VisitTemplateTypeParmDecl(
|
||||
|
|
|
@ -530,7 +530,8 @@ public:
|
|||
/// scope index; can be negative
|
||||
ParmVarDecl *TransformFunctionTypeParam(ParmVarDecl *OldParm,
|
||||
int indexAdjustment,
|
||||
llvm::Optional<unsigned> NumExpansions);
|
||||
llvm::Optional<unsigned> NumExpansions,
|
||||
bool ExpectParameterPack);
|
||||
|
||||
QualType TransformReferenceType(TypeLocBuilder &TLB, ReferenceTypeLoc TL);
|
||||
|
||||
|
@ -3814,12 +3815,14 @@ template<typename Derived>
|
|||
ParmVarDecl *
|
||||
TreeTransform<Derived>::TransformFunctionTypeParam(ParmVarDecl *OldParm,
|
||||
int indexAdjustment,
|
||||
llvm::Optional<unsigned> NumExpansions) {
|
||||
llvm::Optional<unsigned> NumExpansions,
|
||||
bool ExpectParameterPack) {
|
||||
TypeSourceInfo *OldDI = OldParm->getTypeSourceInfo();
|
||||
TypeSourceInfo *NewDI = 0;
|
||||
|
||||
if (NumExpansions && isa<PackExpansionType>(OldDI->getType())) {
|
||||
// If we're substituting into a pack expansion type and we know the
|
||||
// length we want to expand to, just substitute for the pattern.
|
||||
TypeLoc OldTL = OldDI->getTypeLoc();
|
||||
PackExpansionTypeLoc OldExpansionTL = cast<PackExpansionTypeLoc>(OldTL);
|
||||
|
||||
|
@ -3916,7 +3919,8 @@ bool TreeTransform<Derived>::
|
|||
ParmVarDecl *NewParm
|
||||
= getDerived().TransformFunctionTypeParam(OldParm,
|
||||
indexAdjustment++,
|
||||
OrigNumExpansions);
|
||||
OrigNumExpansions,
|
||||
/*ExpectParameterPack=*/false);
|
||||
if (!NewParm)
|
||||
return true;
|
||||
|
||||
|
@ -3932,7 +3936,8 @@ bool TreeTransform<Derived>::
|
|||
ParmVarDecl *NewParm
|
||||
= getDerived().TransformFunctionTypeParam(OldParm,
|
||||
indexAdjustment++,
|
||||
OrigNumExpansions);
|
||||
OrigNumExpansions,
|
||||
/*ExpectParameterPack=*/false);
|
||||
if (!NewParm)
|
||||
return true;
|
||||
|
||||
|
@ -3956,11 +3961,13 @@ bool TreeTransform<Derived>::
|
|||
Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), -1);
|
||||
NewParm = getDerived().TransformFunctionTypeParam(OldParm,
|
||||
indexAdjustment,
|
||||
NumExpansions);
|
||||
NumExpansions,
|
||||
/*ExpectParameterPack=*/true);
|
||||
} else {
|
||||
NewParm = getDerived().TransformFunctionTypeParam(OldParm,
|
||||
indexAdjustment,
|
||||
llvm::Optional<unsigned>());
|
||||
llvm::Optional<unsigned>(),
|
||||
/*ExpectParameterPack=*/false);
|
||||
}
|
||||
|
||||
if (!NewParm)
|
||||
|
|
|
@ -85,7 +85,7 @@ namespace PR11848 {
|
|||
template<typename T>
|
||||
struct Hidden1 {
|
||||
template<typename ...Ts>
|
||||
Hidden1(typename T::template U<Ts> ...ts);
|
||||
Hidden1(typename T::template U<Ts> ...ts); // expected-error{{type 'typename Hide::U<Ts>' (aka 'int') of function parameter pack does not contain any unexpanded parameter packs}}
|
||||
};
|
||||
|
||||
template<typename T, typename ...Ts>
|
||||
|
@ -97,7 +97,6 @@ namespace PR11848 {
|
|||
template<typename T> using U = int;
|
||||
};
|
||||
|
||||
// FIXME: This case crashes clang at the moment.
|
||||
//Hidden1<Hide> h1;
|
||||
Hidden1<Hide> h1; // expected-note{{in instantiation of template class 'PR11848::Hidden1<PR11848::Hide>' requested here}}
|
||||
Hidden2<Hide, double, char> h2(1, 2);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue