aboutsummaryrefslogtreecommitdiff
path: root/lib/Sema
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Sema')
-rw-r--r--lib/Sema/SemaTemplateInstantiate.cpp10
-rw-r--r--lib/Sema/SemaTemplateInstantiateDecl.cpp13
-rw-r--r--lib/Sema/SemaTemplateVariadic.cpp30
-rw-r--r--lib/Sema/SemaType.cpp4
-rw-r--r--lib/Sema/TreeTransform.h63
5 files changed, 75 insertions, 45 deletions
diff --git a/lib/Sema/SemaTemplateInstantiate.cpp b/lib/Sema/SemaTemplateInstantiate.cpp
index 629dc58958..c181a568b5 100644
--- a/lib/Sema/SemaTemplateInstantiate.cpp
+++ b/lib/Sema/SemaTemplateInstantiate.cpp
@@ -622,7 +622,7 @@ namespace {
unsigned NumUnexpanded,
bool &ShouldExpand,
bool &RetainExpansion,
- unsigned &NumExpansions) {
+ llvm::Optional<unsigned> &NumExpansions) {
return getSema().CheckParameterPacksForExpansion(EllipsisLoc,
PatternRange, Unexpanded,
NumUnexpanded,
@@ -1260,7 +1260,9 @@ ParmVarDecl *Sema::SubstParmVarDecl(ParmVarDecl *OldParm,
// We still have unexpanded parameter packs, which means that
// our function parameter is still a function parameter pack.
// Therefore, make its type a pack expansion type.
- NewDI = CheckPackExpansion(NewDI, ExpansionTL.getEllipsisLoc());
+ // FIXME: Variadic templates num expansions.
+ NewDI = CheckPackExpansion(NewDI, ExpansionTL.getEllipsisLoc(),
+ llvm::Optional<unsigned>());
}
} else {
NewDI = SubstType(OldDI, TemplateArgs, OldParm->getLocation(),
@@ -1360,7 +1362,7 @@ Sema::SubstBaseSpecifiers(CXXRecordDecl *Instantiation,
Unexpanded);
bool ShouldExpand = false;
bool RetainExpansion = false;
- unsigned NumExpansions = 0;
+ llvm::Optional<unsigned> NumExpansions;
if (CheckParameterPacksForExpansion(Base->getEllipsisLoc(),
Base->getSourceRange(),
Unexpanded.data(), Unexpanded.size(),
@@ -1373,7 +1375,7 @@ Sema::SubstBaseSpecifiers(CXXRecordDecl *Instantiation,
// If we should expand this pack expansion now, do so.
if (ShouldExpand) {
- for (unsigned I = 0; I != NumExpansions; ++I) {
+ for (unsigned I = 0; I != *NumExpansions; ++I) {
Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(*this, I);
TypeSourceInfo *BaseTypeLoc = SubstType(Base->getTypeSourceInfo(),
diff --git a/lib/Sema/SemaTemplateInstantiateDecl.cpp b/lib/Sema/SemaTemplateInstantiateDecl.cpp
index a18bfbafc0..6b5713a2fa 100644
--- a/lib/Sema/SemaTemplateInstantiateDecl.cpp
+++ b/lib/Sema/SemaTemplateInstantiateDecl.cpp
@@ -1977,7 +1977,8 @@ TemplateDeclInstantiator::InitFunctionInstantiation(FunctionDecl *New,
bool Expand = false;
bool RetainExpansion = false;
- unsigned NumExpansions = 0;
+ llvm::Optional<unsigned> NumExpansions
+ = PackExpansion->getNumExpansions();
if (SemaRef.CheckParameterPacksForExpansion(New->getLocation(),
SourceRange(),
Unexpanded.data(),
@@ -1990,7 +1991,8 @@ TemplateDeclInstantiator::InitFunctionInstantiation(FunctionDecl *New,
if (!Expand) {
// We can't expand this pack expansion into separate arguments yet;
- // just substitute into the argument pack.
+ // just substitute into the pattern and create a new pack expansion
+ // type.
Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(SemaRef, -1);
QualType T = SemaRef.SubstType(PackExpansion->getPattern(),
TemplateArgs,
@@ -1998,13 +2000,14 @@ TemplateDeclInstantiator::InitFunctionInstantiation(FunctionDecl *New,
if (T.isNull())
break;
+ T = SemaRef.Context.getPackExpansionType(T, NumExpansions);
Exceptions.push_back(T);
continue;
}
// Substitute into the pack expansion pattern for each template
bool Invalid = false;
- for (unsigned ArgIdx = 0; ArgIdx != NumExpansions; ++ArgIdx) {
+ for (unsigned ArgIdx = 0; ArgIdx != *NumExpansions; ++ArgIdx) {
Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(SemaRef, ArgIdx);
QualType T = SemaRef.SubstType(PackExpansion->getPattern(),
@@ -2384,7 +2387,7 @@ Sema::InstantiateMemInitializers(CXXConstructorDecl *New,
collectUnexpandedParameterPacks(BaseTL, Unexpanded);
bool ShouldExpand = false;
bool RetainExpansion = false;
- unsigned NumExpansions = 0;
+ llvm::Optional<unsigned> NumExpansions;
if (CheckParameterPacksForExpansion(Init->getEllipsisLoc(),
BaseTL.getSourceRange(),
Unexpanded.data(),
@@ -2399,7 +2402,7 @@ Sema::InstantiateMemInitializers(CXXConstructorDecl *New,
assert(ShouldExpand && "Partial instantiation of base initializer?");
// Loop over all of the arguments in the argument pack(s),
- for (unsigned I = 0; I != NumExpansions; ++I) {
+ for (unsigned I = 0; I != *NumExpansions; ++I) {
Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(*this, I);
// Instantiate the initializer.
diff --git a/lib/Sema/SemaTemplateVariadic.cpp b/lib/Sema/SemaTemplateVariadic.cpp
index dc5013c25d..899b58e558 100644
--- a/lib/Sema/SemaTemplateVariadic.cpp
+++ b/lib/Sema/SemaTemplateVariadic.cpp
@@ -368,7 +368,8 @@ TypeResult Sema::ActOnPackExpansion(ParsedType Type,
if (!TSInfo)
return true;
- TypeSourceInfo *TSResult = CheckPackExpansion(TSInfo, EllipsisLoc);
+ TypeSourceInfo *TSResult = CheckPackExpansion(TSInfo, EllipsisLoc,
+ llvm::Optional<unsigned>());
if (!TSResult)
return true;
@@ -376,11 +377,12 @@ TypeResult Sema::ActOnPackExpansion(ParsedType Type,
}
TypeSourceInfo *Sema::CheckPackExpansion(TypeSourceInfo *Pattern,
- SourceLocation EllipsisLoc) {
+ SourceLocation EllipsisLoc,
+ llvm::Optional<unsigned> NumExpansions) {
// Create the pack expansion type and source-location information.
QualType Result = CheckPackExpansion(Pattern->getType(),
Pattern->getTypeLoc().getSourceRange(),
- EllipsisLoc);
+ EllipsisLoc, NumExpansions);
if (Result.isNull())
return 0;
@@ -397,7 +399,8 @@ TypeSourceInfo *Sema::CheckPackExpansion(TypeSourceInfo *Pattern,
QualType Sema::CheckPackExpansion(QualType Pattern,
SourceRange PatternRange,
- SourceLocation EllipsisLoc) {
+ SourceLocation EllipsisLoc,
+ llvm::Optional<unsigned> NumExpansions) {
// C++0x [temp.variadic]p5:
// The pattern of a pack expansion shall name one or more
// parameter packs that are not expanded by a nested pack
@@ -408,7 +411,7 @@ QualType Sema::CheckPackExpansion(QualType Pattern,
return QualType();
}
- return Context.getPackExpansionType(Pattern);
+ return Context.getPackExpansionType(Pattern, NumExpansions);
}
ExprResult Sema::ActOnPackExpansion(Expr *Pattern, SourceLocation EllipsisLoc) {
@@ -450,7 +453,7 @@ bool Sema::CheckParameterPacksForExpansion(SourceLocation EllipsisLoc,
const MultiLevelTemplateArgumentList &TemplateArgs,
bool &ShouldExpand,
bool &RetainExpansion,
- unsigned &NumExpansions) {
+ llvm::Optional<unsigned> &NumExpansions) {
ShouldExpand = true;
RetainExpansion = false;
std::pair<IdentifierInfo *, SourceLocation> FirstPack;
@@ -527,7 +530,7 @@ bool Sema::CheckParameterPacksForExpansion(SourceLocation EllipsisLoc,
RetainExpansion = true;
}
- if (!HaveFirstPack) {
+ if (!NumExpansions) {
// The is the first pack we've seen for which we have an argument.
// Record it.
NumExpansions = NewPackSize;
@@ -537,13 +540,18 @@ bool Sema::CheckParameterPacksForExpansion(SourceLocation EllipsisLoc,
continue;
}
- if (NewPackSize != NumExpansions) {
+ if (NewPackSize != *NumExpansions) {
// C++0x [temp.variadic]p5:
// All of the parameter packs expanded by a pack expansion shall have
// the same number of arguments specified.
- Diag(EllipsisLoc, diag::err_pack_expansion_length_conflict)
- << FirstPack.first << Name << NumExpansions << NewPackSize
- << SourceRange(FirstPack.second) << SourceRange(Unexpanded[I].second);
+ if (HaveFirstPack)
+ Diag(EllipsisLoc, diag::err_pack_expansion_length_conflict)
+ << FirstPack.first << Name << *NumExpansions << NewPackSize
+ << SourceRange(FirstPack.second) << SourceRange(Unexpanded[I].second);
+ else
+ Diag(EllipsisLoc, diag::err_pack_expansion_length_conflict_multilevel)
+ << Name << *NumExpansions << NewPackSize
+ << SourceRange(Unexpanded[I].second);
return true;
}
}
diff --git a/lib/Sema/SemaType.cpp b/lib/Sema/SemaType.cpp
index ada8a1d8a2..e843ca5fca 100644
--- a/lib/Sema/SemaType.cpp
+++ b/lib/Sema/SemaType.cpp
@@ -1927,7 +1927,7 @@ TypeSourceInfo *Sema::GetTypeForDeclarator(Declarator &D, Scope *S,
<< T << D.getSourceRange();
D.setEllipsisLoc(SourceLocation());
} else {
- T = Context.getPackExpansionType(T);
+ T = Context.getPackExpansionType(T, llvm::Optional<unsigned>());
}
break;
@@ -1941,7 +1941,7 @@ TypeSourceInfo *Sema::GetTypeForDeclarator(Declarator &D, Scope *S,
// parameter packs in the type of the non-type template parameter, then
// it expands those parameter packs.
if (T->containsUnexpandedParameterPack())
- T = Context.getPackExpansionType(T);
+ T = Context.getPackExpansionType(T, llvm::Optional<unsigned>());
else if (!getLangOptions().CPlusPlus0x)
Diag(D.getEllipsisLoc(), diag::err_variadic_templates);
break;
diff --git a/lib/Sema/TreeTransform.h b/lib/Sema/TreeTransform.h
index 4127d5045a..f2496c2f1a 100644
--- a/lib/Sema/TreeTransform.h
+++ b/lib/Sema/TreeTransform.h
@@ -227,8 +227,12 @@ public:
/// C++0x [temp.arg.explicit]p9.
///
/// \param NumExpansions The number of separate arguments that will be in
- /// the expanded form of the corresponding pack expansion. Must be set when
- /// \c ShouldExpand is \c true.
+ /// the expanded form of the corresponding pack expansion. This is both an
+ /// input and an output parameter, which can be set by the caller if the
+ /// number of expansions is known a priori (e.g., due to a prior substitution)
+ /// and will be set by the callee when the number of expansions is known.
+ /// The callee must set this value when \c ShouldExpand is \c true; it may
+ /// set this value in other cases.
///
/// \returns true if an error occurred (e.g., because the parameter packs
/// are to be instantiated with arguments of different lengths), false
@@ -240,7 +244,7 @@ public:
unsigned NumUnexpanded,
bool &ShouldExpand,
bool &RetainExpansion,
- unsigned &NumExpansions) {
+ llvm::Optional<unsigned> &NumExpansions) {
ShouldExpand = false;
return false;
}
@@ -814,8 +818,10 @@ public:
/// Subclasses may override this routine to provide different behavior.
QualType RebuildPackExpansionType(QualType Pattern,
SourceRange PatternRange,
- SourceLocation EllipsisLoc) {
- return getSema().CheckPackExpansion(Pattern, PatternRange, EllipsisLoc);
+ SourceLocation EllipsisLoc,
+ llvm::Optional<unsigned> NumExpansions) {
+ return getSema().CheckPackExpansion(Pattern, PatternRange, EllipsisLoc,
+ NumExpansions);
}
/// \brief Build a new nested-name-specifier given the prefix and an
@@ -2165,7 +2171,8 @@ public:
/// for a template argument. Subclasses may override this routine to provide
/// different behavior.
TemplateArgumentLoc RebuildPackExpansion(TemplateArgumentLoc Pattern,
- SourceLocation EllipsisLoc) {
+ SourceLocation EllipsisLoc,
+ llvm::Optional<unsigned> NumExpansions) {
switch (Pattern.getArgument().getKind()) {
case TemplateArgument::Expression: {
ExprResult Result
@@ -2195,7 +2202,8 @@ public:
case TemplateArgument::Type:
if (TypeSourceInfo *Expansion
= getSema().CheckPackExpansion(Pattern.getTypeSourceInfo(),
- EllipsisLoc))
+ EllipsisLoc,
+ NumExpansions))
return TemplateArgumentLoc(TemplateArgument(Expansion->getType()),
Expansion);
break;
@@ -2300,7 +2308,7 @@ bool TreeTransform<Derived>::TransformExprs(Expr **Inputs,
// be expanded.
bool Expand = true;
bool RetainExpansion = false;
- unsigned NumExpansions = 0;
+ llvm::Optional<unsigned> NumExpansions;
if (getDerived().TryExpandParameterPacks(Expansion->getEllipsisLoc(),
Pattern->getSourceRange(),
Unexpanded.data(),
@@ -2318,6 +2326,7 @@ bool TreeTransform<Derived>::TransformExprs(Expr **Inputs,
if (OutPattern.isInvalid())
return true;
+ // FIXME: Variadic templates NumExpansions
ExprResult Out = getDerived().RebuildPackExpansion(OutPattern.get(),
Expansion->getEllipsisLoc());
if (Out.isInvalid())
@@ -2331,7 +2340,7 @@ bool TreeTransform<Derived>::TransformExprs(Expr **Inputs,
// The transform has determined that we should perform an elementwise
// expansion of the pattern. Do so.
- for (unsigned I = 0; I != NumExpansions; ++I) {
+ for (unsigned I = 0; I != *NumExpansions; ++I) {
Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), I);
ExprResult Out = getDerived().TransformExpr(Pattern);
if (Out.isInvalid())
@@ -2817,8 +2826,10 @@ bool TreeTransform<Derived>::TransformTemplateArguments(InputIterator First,
// We have a pack expansion, for which we will be substituting into
// the pattern.
SourceLocation Ellipsis;
+ llvm::Optional<unsigned> OrigNumExpansions;
TemplateArgumentLoc Pattern
- = In.getPackExpansionPattern(Ellipsis, getSema().Context);
+ = In.getPackExpansionPattern(Ellipsis, OrigNumExpansions,
+ getSema().Context);
llvm::SmallVector<UnexpandedParameterPack, 2> Unexpanded;
getSema().collectUnexpandedParameterPacks(Pattern, Unexpanded);
@@ -2828,7 +2839,7 @@ bool TreeTransform<Derived>::TransformTemplateArguments(InputIterator First,
// be expanded.
bool Expand = true;
bool RetainExpansion = false;
- unsigned NumExpansions = 0;
+ llvm::Optional<unsigned> NumExpansions = OrigNumExpansions;
if (getDerived().TryExpandParameterPacks(Ellipsis,
Pattern.getSourceRange(),
Unexpanded.data(),
@@ -2847,7 +2858,8 @@ bool TreeTransform<Derived>::TransformTemplateArguments(InputIterator First,
if (getDerived().TransformTemplateArgument(Pattern, OutPattern))
return true;
- Out = getDerived().RebuildPackExpansion(OutPattern, Ellipsis);
+ Out = getDerived().RebuildPackExpansion(OutPattern, Ellipsis,
+ NumExpansions);
if (Out.getArgument().isNull())
return true;
@@ -2857,14 +2869,15 @@ bool TreeTransform<Derived>::TransformTemplateArguments(InputIterator First,
// The transform has determined that we should perform an elementwise
// expansion of the pattern. Do so.
- for (unsigned I = 0; I != NumExpansions; ++I) {
+ for (unsigned I = 0; I != *NumExpansions; ++I) {
Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), I);
if (getDerived().TransformTemplateArgument(Pattern, Out))
return true;
if (Out.getArgument().containsUnexpandedParameterPack()) {
- Out = getDerived().RebuildPackExpansion(Out, Ellipsis);
+ Out = getDerived().RebuildPackExpansion(Out, Ellipsis,
+ OrigNumExpansions);
if (Out.getArgument().isNull())
return true;
}
@@ -2880,7 +2893,8 @@ bool TreeTransform<Derived>::TransformTemplateArguments(InputIterator First,
if (getDerived().TransformTemplateArgument(Pattern, Out))
return true;
- Out = getDerived().RebuildPackExpansion(Out, Ellipsis);
+ Out = getDerived().RebuildPackExpansion(Out, Ellipsis,
+ OrigNumExpansions);
if (Out.getArgument().isNull())
return true;
@@ -3497,7 +3511,7 @@ bool TreeTransform<Derived>::
// Determine whether we should expand the parameter packs.
bool ShouldExpand = false;
bool RetainExpansion = false;
- unsigned NumExpansions = 0;
+ llvm::Optional<unsigned> NumExpansions;
if (getDerived().TryExpandParameterPacks(ExpansionTL.getEllipsisLoc(),
Pattern.getSourceRange(),
Unexpanded.data(),
@@ -3512,7 +3526,7 @@ bool TreeTransform<Derived>::
// Expand the function parameter pack into multiple, separate
// parameters.
getDerived().ExpandingFunctionParameterPack(OldParm);
- for (unsigned I = 0; I != NumExpansions; ++I) {
+ for (unsigned I = 0; I != *NumExpansions; ++I) {
Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), I);
ParmVarDecl *NewParm
= getDerived().TransformFunctionTypeParam(OldParm);
@@ -3546,6 +3560,7 @@ bool TreeTransform<Derived>::
// expansion.
}
+ // FIXME: Variadic templates num expansions
Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), -1);
ParmVarDecl *NewParm = getDerived().TransformFunctionTypeParam(OldParm);
if (!NewParm)
@@ -3561,6 +3576,7 @@ bool TreeTransform<Derived>::
// declaration for this parameter.
QualType OldType = ParamTypes[i];
bool IsPackExpansion = false;
+ llvm::Optional<unsigned> NumExpansions;
if (const PackExpansionType *Expansion
= dyn_cast<PackExpansionType>(OldType)) {
// We have a function parameter pack that may need to be expanded.
@@ -3571,7 +3587,6 @@ bool TreeTransform<Derived>::
// Determine whether we should expand the parameter packs.
bool ShouldExpand = false;
bool RetainExpansion = false;
- unsigned NumExpansions = 0;
if (getDerived().TryExpandParameterPacks(Loc, SourceRange(),
Unexpanded.data(),
Unexpanded.size(),
@@ -3584,7 +3599,7 @@ bool TreeTransform<Derived>::
if (ShouldExpand) {
// Expand the function parameter pack into multiple, separate
// parameters.
- for (unsigned I = 0; I != NumExpansions; ++I) {
+ for (unsigned I = 0; I != *NumExpansions; ++I) {
Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), I);
QualType NewType = getDerived().TransformType(Pattern);
if (NewType.isNull())
@@ -3624,7 +3639,8 @@ bool TreeTransform<Derived>::
return true;
if (IsPackExpansion)
- NewType = getSema().Context.getPackExpansionType(NewType);
+ NewType = getSema().Context.getPackExpansionType(NewType,
+ NumExpansions);
OutParamTypes.push_back(NewType);
if (PVars)
@@ -4259,7 +4275,8 @@ QualType TreeTransform<Derived>::TransformPackExpansionType(TypeLocBuilder &TLB,
Pattern != TL.getPatternLoc().getType()) {
Result = getDerived().RebuildPackExpansionType(Pattern,
TL.getPatternLoc().getSourceRange(),
- TL.getEllipsisLoc());
+ TL.getEllipsisLoc(),
+ TL.getTypePtr()->getNumExpansions());
if (Result.isNull())
return QualType();
}
@@ -6818,7 +6835,7 @@ TreeTransform<Derived>::TransformSizeOfPackExpr(SizeOfPackExpr *E) {
UnexpandedParameterPack Unexpanded(E->getPack(), E->getPackLoc());
bool ShouldExpand = false;
bool RetainExpansion = false;
- unsigned NumExpansions = 0;
+ llvm::Optional<unsigned> NumExpansions;
if (getDerived().TryExpandParameterPacks(E->getOperatorLoc(), E->getPackLoc(),
&Unexpanded, 1,
ShouldExpand, RetainExpansion,
@@ -6832,7 +6849,7 @@ TreeTransform<Derived>::TransformSizeOfPackExpr(SizeOfPackExpr *E) {
// that stores that length.
return getDerived().RebuildSizeOfPackExpr(E->getOperatorLoc(), E->getPack(),
E->getPackLoc(), E->getRParenLoc(),
- NumExpansions);
+ *NumExpansions);
}
template<typename Derived>