aboutsummaryrefslogtreecommitdiff
path: root/lib/Sema/TreeTransform.h
diff options
context:
space:
mode:
authorDouglas Gregor <dgregor@apple.com>2011-01-03 19:31:53 +0000
committerDouglas Gregor <dgregor@apple.com>2011-01-03 19:31:53 +0000
commitdcaa1ca0b475dfa887e1d061678a1e3501288510 (patch)
tree45ea581adb8871c9710f17e18dca1ce2a064e043 /lib/Sema/TreeTransform.h
parentef9d09c4699a2a61d6f28b59b7583b2b28c0a531 (diff)
Implement support for pack expansions in initializer lists and
expression lists. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@122764 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/TreeTransform.h')
-rw-r--r--lib/Sema/TreeTransform.h65
1 files changed, 65 insertions, 0 deletions
diff --git a/lib/Sema/TreeTransform.h b/lib/Sema/TreeTransform.h
index 03f5fc0c9a..9088ae0fef 100644
--- a/lib/Sema/TreeTransform.h
+++ b/lib/Sema/TreeTransform.h
@@ -2103,6 +2103,8 @@ public:
SourceLocation EllipsisLoc) {
switch (Pattern.getArgument().getKind()) {
case TemplateArgument::Expression:
+ // FIXME: We should be able to handle this now!
+
case TemplateArgument::Template:
llvm_unreachable("Unsupported pack expansion of expressions/templates");
@@ -2124,6 +2126,15 @@ public:
return TemplateArgumentLoc();
}
+ /// \brief Build a new expression pack expansion.
+ ///
+ /// By default, performs semantic analysis to build a new pack expansion
+ /// for an expression. Subclasses may override this routine to provide
+ /// different behavior.
+ ExprResult RebuildPackExpansion(Expr *Pattern, SourceLocation EllipsisLoc) {
+ return getSema().ActOnPackExpansion(Pattern, EllipsisLoc);
+ }
+
private:
QualType TransformTypeInObjectScope(QualType T,
QualType ObjectType,
@@ -2200,6 +2211,60 @@ bool TreeTransform<Derived>::TransformExprs(Expr **Inputs,
break;
}
+ if (PackExpansionExpr *Expansion = dyn_cast<PackExpansionExpr>(Inputs[I])) {
+ Expr *Pattern = Expansion->getPattern();
+
+ llvm::SmallVector<UnexpandedParameterPack, 2> Unexpanded;
+ getSema().collectUnexpandedParameterPacks(Pattern, Unexpanded);
+ assert(!Unexpanded.empty() && "Pack expansion without parameter packs?");
+
+ // Determine whether the set of unexpanded parameter packs can and should
+ // be expanded.
+ bool Expand = true;
+ unsigned NumExpansions = 0;
+ if (getDerived().TryExpandParameterPacks(Expansion->getEllipsisLoc(),
+ Pattern->getSourceRange(),
+ Unexpanded.data(),
+ Unexpanded.size(),
+ Expand, NumExpansions))
+ return true;
+
+ if (!Expand) {
+ // The transform has determined that we should perform a simple
+ // transformation on the pack expansion, producing another pack
+ // expansion.
+ Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), -1);
+ ExprResult OutPattern = getDerived().TransformExpr(Pattern);
+ if (OutPattern.isInvalid())
+ return true;
+
+ ExprResult Out = getDerived().RebuildPackExpansion(OutPattern.get(),
+ Expansion->getEllipsisLoc());
+ if (Out.isInvalid())
+ return true;
+
+ if (ArgChanged)
+ *ArgChanged = true;
+ Outputs.push_back(Out.get());
+ continue;
+ }
+
+ // The transform has determined that we should perform an elementwise
+ // expansion of the pattern. Do so.
+ for (unsigned I = 0; I != NumExpansions; ++I) {
+ Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), I);
+ ExprResult Out = getDerived().TransformExpr(Pattern);
+ if (Out.isInvalid())
+ return true;
+
+ if (ArgChanged)
+ *ArgChanged = true;
+ Outputs.push_back(Out.get());
+ }
+
+ continue;
+ }
+
ExprResult Result = getDerived().TransformExpr(Inputs[I]);
if (Result.isInvalid())
return true;