[clang] [clang-tools-extra] [Clang] Add a builtin that deduplicate types into a pack (PR #106730)
Ilya Biryukov via cfe-commits
cfe-commits at lists.llvm.org
Mon Aug 11 10:47:39 PDT 2025
================
@@ -5154,6 +5177,84 @@ bool TreeTransform<Derived>::TransformTemplateArguments(
}
+template <typename Derived>
+bool TreeTransform<Derived>::PreparePackForExpansion(TemplateArgumentLoc In,
+ bool Uneval,
+ TemplateArgumentLoc &Out,
+ UnexpandedInfo &Info) {
+ auto ComputeInfo = [this](TemplateArgumentLoc Arg,
+ bool IsLateExpansionAttempt, UnexpandedInfo &Info,
+ TemplateArgumentLoc &Pattern) {
+ assert(Arg.getArgument().isPackExpansion());
+ // We have a pack expansion, for which we will be substituting into the
+ // pattern.
+ Pattern = getSema().getTemplateArgumentPackExpansionPattern(
+ Arg, Info.Ellipsis, Info.OrigNumExpansions);
+ SmallVector<UnexpandedParameterPack, 2> Unexpanded;
+ getSema().collectUnexpandedParameterPacks(Pattern, Unexpanded);
+ if (IsLateExpansionAttempt) {
+ // Request expansion only when there is an opportunity to expand a pack
+ // that required a substituion first.
+ bool SawPackTypes =
+ llvm::any_of(Unexpanded, [](UnexpandedParameterPack P) {
+ return P.first.dyn_cast<const SubstBuiltinTemplatePackType *>();
+ });
+ if (!SawPackTypes) {
+ Info.Expand = false;
+ return false;
+ }
+ }
+ assert(!Unexpanded.empty() && "Pack expansion without parameter packs?");
+
+ // Determine whether the set of unexpanded parameter packs can and
+ // should be expanded.
+ Info.Expand = true;
+ Info.RetainExpansion = false;
+ Info.NumExpansions = Info.OrigNumExpansions;
+ return getDerived().TryExpandParameterPacks(
+ Info.Ellipsis, Pattern.getSourceRange(), Unexpanded, false, Info.Expand,
+ Info.RetainExpansion, Info.NumExpansions);
+ };
+
+ TemplateArgumentLoc Pattern;
+ if (ComputeInfo(In, false, Info, Pattern))
+ return true;
+
+ if (Info.Expand) {
+ Out = Pattern;
+ return false;
+ }
+
+ // The transform has determined that we should perform a simple
+ // transformation on the pack expansion, producing another pack
+ // expansion.
+ TemplateArgumentLoc OutPattern;
+ std::optional<Sema::ArgPackSubstIndexRAII> SubstIndex(
+ std::in_place, getSema(), std::nullopt);
+ if (getDerived().TransformTemplateArgument(Pattern, OutPattern, Uneval))
+ return true;
+
+ Out = getDerived().RebuildPackExpansion(OutPattern, Info.Ellipsis,
+ Info.NumExpansions);
+ if (Out.getArgument().isNull())
+ return true;
+ SubstIndex.reset();
+
+ if (!OutPattern.getArgument().containsUnexpandedParameterPack())
+ return false;
+
+ // Some packs will learn their length after substitution.
+ // We may need to request their expansion.
----------------
ilya-biryukov wrote:
I wrote a pretty long comment, hope it clarifies things.
PTAL
https://github.com/llvm/llvm-project/pull/106730
More information about the cfe-commits
mailing list