diff options
author | Douglas Gregor <dgregor@apple.com> | 2011-01-03 19:31:53 +0000 |
---|---|---|
committer | Douglas Gregor <dgregor@apple.com> | 2011-01-03 19:31:53 +0000 |
commit | dcaa1ca0b475dfa887e1d061678a1e3501288510 (patch) | |
tree | 45ea581adb8871c9710f17e18dca1ce2a064e043 /lib/Sema/TreeTransform.h | |
parent | ef9d09c4699a2a61d6f28b59b7583b2b28c0a531 (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.h | 65 |
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; |