================
@@ -749,132 +759,124 @@ ExprResult Sema::CheckPackExpansion(Expr *Pattern, 
SourceLocation EllipsisLoc,
     PackExpansionExpr(Context.DependentTy, Pattern, EllipsisLoc, 
NumExpansions);
 }
 
+static bool IsUnexpandedPackExpansion(const TemplateArgument &TA) {
+  if (!TA.isPackExpansion())
+    return false;
+
+  if (TA.getKind() == TemplateArgument::Type)
+    return !TA.getAsType()->getAs<PackExpansionType>()->getNumExpansions();
+
+  if (TA.getKind() == TemplateArgument::Expression)
+    return !cast<PackExpansionExpr>(TA.getAsExpr())->getNumExpansions();
+
+  return !TA.getNumTemplateExpansions();
+}
+
 bool Sema::CheckParameterPacksForExpansion(
     SourceLocation EllipsisLoc, SourceRange PatternRange,
     ArrayRef<UnexpandedParameterPack> Unexpanded,
     const MultiLevelTemplateArgumentList &TemplateArgs, bool &ShouldExpand,
     bool &RetainExpansion, std::optional<unsigned> &NumExpansions) {
   ShouldExpand = true;
   RetainExpansion = false;
-  std::pair<IdentifierInfo *, SourceLocation> FirstPack;
-  bool HaveFirstPack = false;
-  std::optional<unsigned> NumPartialExpansions;
-  SourceLocation PartiallySubstitutedPackLoc;
-  typedef LocalInstantiationScope::DeclArgumentPack DeclArgumentPack;
+  std::pair<const IdentifierInfo *, SourceLocation> FirstPack;
+  std::optional<std::pair<unsigned, SourceLocation>> PartialExpansion;
+  std::optional<unsigned> CurNumExpansions, CurMaximumOfLeastExpansions;
 
-  for (UnexpandedParameterPack ParmPack : Unexpanded) {
+  for (auto [P, Loc] : Unexpanded) {
     // Compute the depth and index for this parameter pack.
-    unsigned Depth = 0, Index = 0;
-    IdentifierInfo *Name;
-    bool IsVarDeclPack = false;
-    FunctionParmPackExpr *BindingPack = nullptr;
-
-    if (const TemplateTypeParmType *TTP =
-            ParmPack.first.dyn_cast<const TemplateTypeParmType *>()) {
-      Depth = TTP->getDepth();
-      Index = TTP->getIndex();
-      Name = TTP->getIdentifier();
-    } else {
-      NamedDecl *ND = cast<NamedDecl *>(ParmPack.first);
-      if (isa<VarDecl>(ND))
-        IsVarDeclPack = true;
-      else if (isa<BindingDecl>(ND)) {
+    std::optional<std::pair<unsigned, unsigned>> Pos;
+    unsigned NewPackSize, PendingPackExpansionSize = 0;
+    const auto *ND = dyn_cast_if_present<const NamedDecl *>(P);
+    if (ND) {
+      if (isa<VarDecl>(ND)) {
+        auto *DAP = dyn_cast<LocalInstantiationScope::DeclArgumentPack *>(
+            *CurrentInstantiationScope->findInstantiationOf(ND));
+        if (!DAP) {
+          // We can't expand this function parameter pack, so we can't expand
+          // the pack expansion.
+          ShouldExpand = false;
+          continue;
+        }
+        NewPackSize = DAP->size();
+      } else if (isa<BindingDecl>(ND)) {
         // Find the instantiated BindingDecl and check it for a resolved pack.
-        llvm::PointerUnion<Decl *, DeclArgumentPack *> *Instantiation =
-            CurrentInstantiationScope->findInstantiationOf(ND);
+        llvm::PointerUnion<Decl *, LocalInstantiationScope::DeclArgumentPack *>
+            *Instantiation = 
CurrentInstantiationScope->findInstantiationOf(ND);
         Decl *B = cast<Decl *>(*Instantiation);
         Expr *BindingExpr = cast<BindingDecl>(B)->getBinding();
-        BindingPack = cast_if_present<FunctionParmPackExpr>(BindingExpr);
+        auto *BindingPack = cast_if_present<FunctionParmPackExpr>(BindingExpr);
         if (!BindingPack) {
           ShouldExpand = false;
           continue;
         }
+        NewPackSize = BindingPack->getNumExpansions();
       } else
-        std::tie(Depth, Index) = getDepthAndIndex(ND);
-
-      Name = ND->getIdentifier();
+        Pos = getDepthAndIndex(ND);
+    } else if (const auto *TTP = dyn_cast<const TemplateTypeParmType *>(P)) {
+      Pos = {TTP->getDepth(), TTP->getIndex()};
+      ND = TTP->getDecl();
+      // FIXME: We either should have some fallback for canonical TTP, or
+      //        never have canonical TTP here.
+    } else if (const auto *STP =
+                   dyn_cast<const SubstTemplateTypeParmPackType *>(P)) {
+      NewPackSize = STP->getNumArgs();
+      PendingPackExpansionSize = llvm::count_if(
+          STP->getArgumentPack().getPackAsArray(), IsUnexpandedPackExpansion);
+      ND = STP->getReplacedParameter();
+    } else {
+      const auto *SEP = cast<const SubstNonTypeTemplateParmPackExpr *>(P);
+      NewPackSize = SEP->getArgumentPack().pack_size();
+      PendingPackExpansionSize = llvm::count_if(
+          SEP->getArgumentPack().getPackAsArray(), IsUnexpandedPackExpansion);
+      ND = SEP->getParameterPack();
     }
 
-    // Determine the size of this argument pack.
-    unsigned NewPackSize, PendingPackExpansionSize = 0;
-    if (IsVarDeclPack) {
-      // Figure out whether we're instantiating to an argument pack or not.
-      llvm::PointerUnion<Decl *, DeclArgumentPack *> *Instantiation =
-          CurrentInstantiationScope->findInstantiationOf(
-              cast<NamedDecl *>(ParmPack.first));
-      if (isa<DeclArgumentPack *>(*Instantiation)) {
-        // We could expand this function parameter pack.
-        NewPackSize = cast<DeclArgumentPack *>(*Instantiation)->size();
-      } else {
-        // We can't expand this function parameter pack, so we can't expand
-        // the pack expansion.
-        ShouldExpand = false;
-        continue;
-      }
-    } else if (BindingPack) {
-      NewPackSize = BindingPack->getNumExpansions();
-    } else {
+    if (Pos) {
       // If we don't have a template argument at this depth/index, then we
       // cannot expand the pack expansion. Make a note of this, but we still
       // want to check any parameter packs we *do* have arguments for.
-      if (Depth >= TemplateArgs.getNumLevels() ||
-          !TemplateArgs.hasTemplateArgument(Depth, Index)) {
+      if (Pos->first >= TemplateArgs.getNumLevels() ||
+          !TemplateArgs.hasTemplateArgument(Pos->first, Pos->second)) {
         ShouldExpand = false;
         continue;
       }
-
       // Determine the size of the argument pack.
       ArrayRef<TemplateArgument> Pack =
-          TemplateArgs(Depth, Index).getPackAsArray();
+          TemplateArgs(Pos->first, Pos->second).getPackAsArray();
       NewPackSize = Pack.size();
       PendingPackExpansionSize =
-          llvm::count_if(Pack, [](const TemplateArgument &TA) {
-            if (!TA.isPackExpansion())
-              return false;
-
-            if (TA.getKind() == TemplateArgument::Type)
-              return !TA.getAsType()
-                          ->castAs<PackExpansionType>()
-                          ->getNumExpansions();
-
-            if (TA.getKind() == TemplateArgument::Expression)
-              return !cast<PackExpansionExpr>(TA.getAsExpr())
-                          ->getNumExpansions();
-
-            return !TA.getNumTemplateExpansions();
-          });
-    }
-
-    // C++0x [temp.arg.explicit]p9:
-    //   Template argument deduction can extend the sequence of template
-    //   arguments corresponding to a template parameter pack, even when the
-    //   sequence contains explicitly specified template arguments.
-    if (!IsVarDeclPack && CurrentInstantiationScope) {
-      if (NamedDecl *PartialPack =
-              CurrentInstantiationScope->getPartiallySubstitutedPack()) {
-        unsigned PartialDepth, PartialIndex;
-        std::tie(PartialDepth, PartialIndex) = getDepthAndIndex(PartialPack);
-        if (PartialDepth == Depth && PartialIndex == Index) {
+          llvm::count_if(Pack, IsUnexpandedPackExpansion);
+      // C++0x [temp.arg.explicit]p9:
+      //   Template argument deduction can extend the sequence of template
+      //   arguments corresponding to a template parameter pack, even when the
+      //   sequence contains explicitly specified template arguments.
+      if (CurrentInstantiationScope)
+        if (const NamedDecl *PartialPack =
+                CurrentInstantiationScope->getPartiallySubstitutedPack();
+            PartialPack && getDepthAndIndex(PartialPack) == *Pos) {
           RetainExpansion = true;
           // We don't actually know the new pack size yet.
-          NumPartialExpansions = NewPackSize;
-          PartiallySubstitutedPackLoc = ParmPack.second;
+          PartialExpansion = {NewPackSize, Loc};
           continue;
         }
-      }
     }
 
-    if (!NumExpansions) {
+    unsigned LeastNewPackSize = NewPackSize - PendingPackExpansionSize;
+    if (PendingPackExpansionSize)
+      CurMaximumOfLeastExpansions =
+          CurMaximumOfLeastExpansions
+              ? std::max(LeastNewPackSize, *CurMaximumOfLeastExpansions)
+              : LeastNewPackSize;
+
+    // FIXME: Workaround for Canonical TTP.
----------------
cor3ntin wrote:

Can you add more details?

https://github.com/llvm/llvm-project/pull/121044
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to