Fix a couple of places where we assumed that non-type template parameters are always rvalues.
llvm-svn: 325095
This commit is contained in:
parent
1d76120d9a
commit
f1f20e6802
|
@ -3916,6 +3916,7 @@ class SubstNonTypeTemplateParmPackExpr : public Expr {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
SubstNonTypeTemplateParmPackExpr(QualType T,
|
SubstNonTypeTemplateParmPackExpr(QualType T,
|
||||||
|
ExprValueKind ValueKind,
|
||||||
NonTypeTemplateParmDecl *Param,
|
NonTypeTemplateParmDecl *Param,
|
||||||
SourceLocation NameLoc,
|
SourceLocation NameLoc,
|
||||||
const TemplateArgument &ArgPack);
|
const TemplateArgument &ArgPack);
|
||||||
|
|
|
@ -1330,10 +1330,11 @@ SizeOfPackExpr *SizeOfPackExpr::CreateDeserialized(ASTContext &Context,
|
||||||
|
|
||||||
SubstNonTypeTemplateParmPackExpr::
|
SubstNonTypeTemplateParmPackExpr::
|
||||||
SubstNonTypeTemplateParmPackExpr(QualType T,
|
SubstNonTypeTemplateParmPackExpr(QualType T,
|
||||||
|
ExprValueKind ValueKind,
|
||||||
NonTypeTemplateParmDecl *Param,
|
NonTypeTemplateParmDecl *Param,
|
||||||
SourceLocation NameLoc,
|
SourceLocation NameLoc,
|
||||||
const TemplateArgument &ArgPack)
|
const TemplateArgument &ArgPack)
|
||||||
: Expr(SubstNonTypeTemplateParmPackExprClass, T, VK_RValue, OK_Ordinary,
|
: Expr(SubstNonTypeTemplateParmPackExprClass, T, ValueKind, OK_Ordinary,
|
||||||
true, true, true, true),
|
true, true, true, true),
|
||||||
Param(Param), Arguments(ArgPack.pack_begin()),
|
Param(Param), Arguments(ArgPack.pack_begin()),
|
||||||
NumArguments(ArgPack.pack_size()), NameLoc(NameLoc) {}
|
NumArguments(ArgPack.pack_size()), NameLoc(NameLoc) {}
|
||||||
|
|
|
@ -1212,11 +1212,11 @@ TemplateInstantiator::TransformTemplateParmRefExpr(DeclRefExpr *E,
|
||||||
NTTP->getDeclName());
|
NTTP->getDeclName());
|
||||||
if (TargetType.isNull())
|
if (TargetType.isNull())
|
||||||
return ExprError();
|
return ExprError();
|
||||||
|
|
||||||
return new (SemaRef.Context) SubstNonTypeTemplateParmPackExpr(TargetType,
|
return new (SemaRef.Context) SubstNonTypeTemplateParmPackExpr(
|
||||||
NTTP,
|
TargetType.getNonLValueExprType(SemaRef.Context),
|
||||||
E->getLocation(),
|
TargetType->isReferenceType() ? VK_LValue : VK_RValue, NTTP,
|
||||||
Arg);
|
E->getLocation(), Arg);
|
||||||
}
|
}
|
||||||
|
|
||||||
Arg = getPackSubstitutedTemplateArgument(getSema(), Arg);
|
Arg = getPackSubstitutedTemplateArgument(getSema(), Arg);
|
||||||
|
|
|
@ -11392,8 +11392,10 @@ TreeTransform<Derived>::TransformSizeOfPackExpr(SizeOfPackExpr *E) {
|
||||||
ArgStorage = TemplateArgument(TemplateName(TTPD), None);
|
ArgStorage = TemplateArgument(TemplateName(TTPD), None);
|
||||||
} else {
|
} else {
|
||||||
auto *VD = cast<ValueDecl>(Pack);
|
auto *VD = cast<ValueDecl>(Pack);
|
||||||
ExprResult DRE = getSema().BuildDeclRefExpr(VD, VD->getType(),
|
ExprResult DRE = getSema().BuildDeclRefExpr(
|
||||||
VK_RValue, E->getPackLoc());
|
VD, VD->getType().getNonLValueExprType(getSema().Context),
|
||||||
|
VD->getType()->isReferenceType() ? VK_LValue : VK_RValue,
|
||||||
|
E->getPackLoc());
|
||||||
if (DRE.isInvalid())
|
if (DRE.isInvalid())
|
||||||
return ExprError();
|
return ExprError();
|
||||||
ArgStorage = new (getSema().Context) PackExpansionExpr(
|
ArgStorage = new (getSema().Context) PackExpansionExpr(
|
||||||
|
|
|
@ -161,3 +161,10 @@ class Outer1 {
|
||||||
template <typename T> struct X;
|
template <typename T> struct X;
|
||||||
template <typename T> int X<T>::func() {} // expected-error{{out-of-line definition of 'func' from class 'X<T>' without definition}}
|
template <typename T> int X<T>::func() {} // expected-error{{out-of-line definition of 'func' from class 'X<T>' without definition}}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
namespace RefPack {
|
||||||
|
template<const int &...N> struct A { template<typename ...T> void f(T (&...t)[N]); };
|
||||||
|
constexpr int k = 10;
|
||||||
|
int arr[10];
|
||||||
|
void g() { A<k>().f(arr); }
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,7 @@
|
||||||
|
// RUN: %clang_cc1 -std=c++11 -verify %s
|
||||||
|
// expected-no-diagnostics
|
||||||
|
|
||||||
|
template<int &...Ns> int f() {
|
||||||
|
return sizeof...(Ns);
|
||||||
|
}
|
||||||
|
template int f<>();
|
Loading…
Reference in New Issue