summaryrefslogtreecommitdiffstats
path: root/clang/lib/Sema/TreeTransform.h
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib/Sema/TreeTransform.h')
-rw-r--r--clang/lib/Sema/TreeTransform.h84
1 files changed, 77 insertions, 7 deletions
diff --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h
index e2bfb05088b..7eee4441740 100644
--- a/clang/lib/Sema/TreeTransform.h
+++ b/clang/lib/Sema/TreeTransform.h
@@ -89,6 +89,23 @@ using namespace sema;
/// (\c getBaseLocation(), \c getBaseEntity()).
template<typename Derived>
class TreeTransform {
+ /// \brief Private RAII object that helps us forget and then re-remember
+ /// the template argument corresponding to a partially-substituted parameter
+ /// pack.
+ class ForgetPartiallySubstitutedPackRAII {
+ Derived &Self;
+ TemplateArgument Old;
+
+ public:
+ ForgetPartiallySubstitutedPackRAII(Derived &Self) : Self(Self) {
+ Old = Self.ForgetPartiallySubstitutedPack();
+ }
+
+ ~ForgetPartiallySubstitutedPackRAII() {
+ Self.RememberPartiallySubstitutedPack(Old);
+ }
+ };
+
protected:
Sema &SemaRef;
@@ -204,6 +221,11 @@ public:
/// expand the corresponding pack expansions into separate arguments. When
/// set, \c NumExpansions must also be set.
///
+ /// \param RetainExpansion Whether the caller should add an unexpanded
+ /// pack expansion after all of the expanded arguments. This is used
+ /// when extending explicitly-specified template argument packs per
+ /// 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.
@@ -217,11 +239,28 @@ public:
const UnexpandedParameterPack *Unexpanded,
unsigned NumUnexpanded,
bool &ShouldExpand,
+ bool &RetainExpansion,
unsigned &NumExpansions) {
ShouldExpand = false;
return false;
}
+ /// \brief "Forget" about the partially-substituted pack template argument,
+ /// when performing an instantiation that must preserve the parameter pack
+ /// use.
+ ///
+ /// This routine is meant to be overridden by the template instantiator.
+ TemplateArgument ForgetPartiallySubstitutedPack() {
+ return TemplateArgument();
+ }
+
+ /// \brief "Remember" the partially-substituted pack template argument
+ /// after performing an instantiation that must preserve the parameter pack
+ /// use.
+ ///
+ /// This routine is meant to be overridden by the template instantiator.
+ void RememberPartiallySubstitutedPack(TemplateArgument Arg) { }
+
/// \brief Note to the derived class when a function parameter pack is
/// being expanded.
void ExpandingFunctionParameterPack(ParmVarDecl *Pack) { }
@@ -2250,12 +2289,14 @@ bool TreeTransform<Derived>::TransformExprs(Expr **Inputs,
// Determine whether the set of unexpanded parameter packs can and should
// be expanded.
bool Expand = true;
+ bool RetainExpansion = false;
unsigned NumExpansions = 0;
if (getDerived().TryExpandParameterPacks(Expansion->getEllipsisLoc(),
Pattern->getSourceRange(),
Unexpanded.data(),
Unexpanded.size(),
- Expand, NumExpansions))
+ Expand, RetainExpansion,
+ NumExpansions))
return true;
if (!Expand) {
@@ -2770,12 +2811,15 @@ bool TreeTransform<Derived>::TransformTemplateArguments(InputIterator First,
// Determine whether the set of unexpanded parameter packs can and should
// be expanded.
bool Expand = true;
+ bool RetainExpansion = false;
unsigned NumExpansions = 0;
if (getDerived().TryExpandParameterPacks(Ellipsis,
Pattern.getSourceRange(),
Unexpanded.data(),
Unexpanded.size(),
- Expand, NumExpansions))
+ Expand,
+ RetainExpansion,
+ NumExpansions))
return true;
if (!Expand) {
@@ -2806,6 +2850,8 @@ bool TreeTransform<Derived>::TransformTemplateArguments(InputIterator First,
Outputs.addArgument(Out);
}
+ // FIXME: Variadic templates retain expansion!
+
continue;
}
@@ -3415,12 +3461,15 @@ bool TreeTransform<Derived>::
// Determine whether we should expand the parameter packs.
bool ShouldExpand = false;
+ bool RetainExpansion = false;
unsigned NumExpansions = 0;
if (getDerived().TryExpandParameterPacks(ExpansionTL.getEllipsisLoc(),
Pattern.getSourceRange(),
Unexpanded.data(),
Unexpanded.size(),
- ShouldExpand, NumExpansions)) {
+ ShouldExpand,
+ RetainExpansion,
+ NumExpansions)) {
return true;
}
@@ -3439,7 +3488,21 @@ bool TreeTransform<Derived>::
if (PVars)
PVars->push_back(NewParm);
}
-
+
+ // If we're supposed to retain a pack expansion, do so by temporarily
+ // forgetting the partially-substituted parameter pack.
+ if (RetainExpansion) {
+ ForgetPartiallySubstitutedPackRAII Forget(getDerived());
+ ParmVarDecl *NewParm
+ = getDerived().TransformFunctionTypeParam(OldParm);
+ if (!NewParm)
+ return true;
+
+ OutParamTypes.push_back(NewParm->getType());
+ if (PVars)
+ PVars->push_back(NewParm);
+ }
+
// We're done with the pack expansion.
continue;
}
@@ -3472,11 +3535,14 @@ 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(),
- ShouldExpand, NumExpansions)) {
+ ShouldExpand,
+ RetainExpansion,
+ NumExpansions)) {
return true;
}
@@ -3498,6 +3564,8 @@ bool TreeTransform<Derived>::
continue;
}
+ // FIXME: Variadic templates retain pack expansion!
+
// We'll substitute the parameter now without expanding the pack
// expansion.
OldType = Expansion->getPattern();
@@ -6674,13 +6742,15 @@ TreeTransform<Derived>::TransformSizeOfPackExpr(SizeOfPackExpr *E) {
// so
UnexpandedParameterPack Unexpanded(E->getPack(), E->getPackLoc());
bool ShouldExpand = false;
+ bool RetainExpansion = false;
unsigned NumExpansions = 0;
if (getDerived().TryExpandParameterPacks(E->getOperatorLoc(), E->getPackLoc(),
&Unexpanded, 1,
- ShouldExpand, NumExpansions))
+ ShouldExpand, RetainExpansion,
+ NumExpansions))
return ExprError();
- if (!ShouldExpand)
+ if (!ShouldExpand || RetainExpansion)
return SemaRef.Owned(E);
// We now know the length of the parameter pack, so build a new expression
OpenPOWER on IntegriCloud