================
@@ -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
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to