[clang] [clang-tools-extra] [Clang] Add builtins that deduplicate and sort types (PR #106730)
Younan Zhang via cfe-commits
cfe-commits at lists.llvm.org
Wed May 14 01:22:26 PDT 2025
================
@@ -5054,95 +5089,128 @@ bool TreeTransform<Derived>::TransformTemplateArguments(
}
if (In.getArgument().isPackExpansion()) {
- // We have a pack expansion, for which we will be substituting into
- // the pattern.
- SourceLocation Ellipsis;
- UnsignedOrNone OrigNumExpansions = std::nullopt;
- TemplateArgumentLoc Pattern
- = getSema().getTemplateArgumentPackExpansionPattern(
- In, Ellipsis, OrigNumExpansions);
-
- 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;
- bool RetainExpansion = false;
- UnsignedOrNone NumExpansions = OrigNumExpansions;
- if (getDerived().TryExpandParameterPacks(Ellipsis,
- Pattern.getSourceRange(),
- Unexpanded,
- Expand,
- RetainExpansion,
- NumExpansions))
+ if (ExpandTemplateArgument(In, Outputs, Uneval, true))
return true;
+ continue;
+ }
- if (!Expand) {
- // The transform has determined that we should perform a simple
- // transformation on the pack expansion, producing another pack
- // expansion.
- TemplateArgumentLoc OutPattern;
- Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), std::nullopt);
- if (getDerived().TransformTemplateArgument(Pattern, OutPattern, Uneval))
- return true;
+ // The simple case:
+ if (getDerived().TransformTemplateArgument(In, Out, Uneval))
+ return true;
- Out = getDerived().RebuildPackExpansion(OutPattern, Ellipsis,
- NumExpansions);
- if (Out.getArgument().isNull())
- return true;
+ Outputs.addArgument(Out);
+ }
- Outputs.addArgument(Out);
- continue;
- }
+ return false;
+}
- // The transform has determined that we should perform an elementwise
- // expansion of the pattern. Do so.
- for (unsigned I = 0; I != *NumExpansions; ++I) {
- Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), I);
+template <typename Derived>
+bool TreeTransform<Derived>::ExpandTemplateArgument(
+ TemplateArgumentLoc In, TemplateArgumentListInfo &Outputs, bool Uneval,
+ bool TryExpandingSubstPacks) {
+ assert(In.getArgument().isPackExpansion());
+ // We have a pack expansion, for which we will be substituting into the
+ // pattern.
+ SourceLocation Ellipsis;
+ UnsignedOrNone OrigNumExpansions = std::nullopt;
+ TemplateArgumentLoc Pattern =
+ getSema().getTemplateArgumentPackExpansionPattern(In, Ellipsis,
+ OrigNumExpansions);
- if (getDerived().TransformTemplateArgument(Pattern, Out, Uneval))
- return true;
+ SmallVector<UnexpandedParameterPack, 2> Unexpanded;
+ getSema().collectUnexpandedParameterPacks(Pattern, Unexpanded);
+ if (!TryExpandingSubstPacks) {
+ // Only do something if there is an opportunity for late expansion.
+ bool SawPackTypes = llvm::any_of(Unexpanded, [](UnexpandedParameterPack P) {
+ return P.first.dyn_cast<const SubstBuiltinTemplatePackType *>();
+ });
+ if (!SawPackTypes) {
+ Outputs.addArgument(In);
+ return false;
+ }
+ }
+ assert(!Unexpanded.empty() && "Pack expansion without parameter packs?");
- if (Out.getArgument().containsUnexpandedParameterPack()) {
- Out = getDerived().RebuildPackExpansion(Out, Ellipsis,
- OrigNumExpansions);
- if (Out.getArgument().isNull())
- return true;
- }
+ // Determine whether the set of unexpanded parameter packs can and should
+ // be expanded.
+ bool Expand = true;
+ bool RetainExpansion = false;
+ UnsignedOrNone NumExpansions = OrigNumExpansions;
+ if (getDerived().TryExpandParameterPacks(Ellipsis, Pattern.getSourceRange(),
+ Unexpanded, Expand, RetainExpansion,
+ NumExpansions))
+ return true;
- Outputs.addArgument(Out);
- }
+ TemplateArgumentLoc Out;
+ if (!Expand) {
+ // No opportunity for late expansion, return as is.
+ if (!TryExpandingSubstPacks) {
+ Outputs.addArgument(In);
+ 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;
- // If we're supposed to retain a pack expansion, do so by temporarily
- // forgetting the partially-substituted parameter pack.
- if (RetainExpansion) {
- ForgetPartiallySubstitutedPackRAII Forget(getDerived());
+ Out =
+ getDerived().RebuildPackExpansion(OutPattern, Ellipsis, NumExpansions);
+ if (Out.getArgument().isNull())
+ return true;
+ SubstIndex.reset();
+
+ // Some packs only know their lengths after substitution. We might be able
+ // to expand those here.
+ if (TryExpandingSubstPacks &&
+ OutPattern.getArgument().containsUnexpandedParameterPack()) {
----------------
zyn0217 wrote:
So this branch is used when rebuilding a substituted `dedup` node. E.g. for `Ts = <int, int, int, float>`, we're, at this point, having `dedup<int, int, int, float>...` plus a canonical `SubstBuiltinTemplatePackType` which is used to mark it as an unexpanded pack.
This feels a bit peculiar to me because we're trying to inline node-specific logic (?) into what's supposed to be a generic expansion handler.
https://github.com/llvm/llvm-project/pull/106730
More information about the cfe-commits
mailing list