if (Out.isInvalid())
return true;
+ // FIXME: Can this happen? We should not try to expand the pack
+ // in this case.
if (Out.get()->containsUnexpandedParameterPack()) {
- Out = RebuildPackExpansion(Out.get(), Expansion->getEllipsisLoc(),
- OrigNumExpansions);
+ Out = getDerived().RebuildPackExpansion(
+ Out.get(), Expansion->getEllipsisLoc(), OrigNumExpansions);
if (Out.isInvalid())
return true;
}
Outputs.push_back(Out.get());
}
+ // If we're supposed to retain a pack expansion, do so by temporarily
+ // forgetting the partially-substituted parameter pack.
+ if (RetainExpansion) {
+ ForgetPartiallySubstitutedPackRAII Forget(getDerived());
+
+ ExprResult Out = getDerived().TransformExpr(Pattern);
+ if (Out.isInvalid())
+ return true;
+
+ Out = getDerived().RebuildPackExpansion(
+ Out.get(), Expansion->getEllipsisLoc(), OrigNumExpansions);
+ if (Out.isInvalid())
+ return true;
+
+ Outputs.push_back(Out.get());
+ }
+
continue;
}
// Capture the transformed variable.
getSema().tryCaptureVariable(CapturedVar, C->getLocation(), Kind);
}
+
+ // FIXME: Retain a pack expansion if RetainExpansion is true.
+
continue;
}
// If any unexpanded parameter packs remain, we still have a
// pack expansion.
+ // FIXME: Can this really happen?
if (Key.get()->containsUnexpandedParameterPack() ||
Value.get()->containsUnexpandedParameterPack())
Element.EllipsisLoc = OrigElement.EllipsisLoc;
Elements.push_back(Element);
}
+ // FIXME: Retain a pack expansion if RetainExpansion is true.
+
// We've finished with this pack expansion.
continue;
}
f<char, short, int>(a); // expected-error {{no matching function}}
}
}
+
+namespace RetainExprPacks {
+ int f(int a, int b, int c);
+ template<typename ...Ts> struct X {};
+ template<typename ...Ts> int g(X<Ts...>, decltype(f(Ts()...)));
+ int n = g<int, int>(X<int, int, int>(), 0);
+}