https://github.com/ricejasonf updated 
https://github.com/llvm/llvm-project/pull/125394

>From a323e058b2c8adf97f7f9a55a9187f74de9b8d17 Mon Sep 17 00:00:00 2001
From: Jason Rice <ricejas...@gmail.com>
Date: Sun, 2 Feb 2025 00:52:47 -0800
Subject: [PATCH 1/3] [Clang][P1061] Consolidate ResolvedUnexpandedPackExpr
 into FunctionParmPackExpr

---
 clang/include/clang/AST/DeclCXX.h             | 28 +++++--------
 clang/include/clang/AST/ExprCXX.h             | 21 +++++-----
 clang/include/clang/Sema/Template.h           |  2 +-
 clang/lib/AST/DeclCXX.cpp                     |  9 +++--
 clang/lib/AST/ExprCXX.cpp                     | 14 +++----
 clang/lib/Sema/SemaDeclCXX.cpp                | 26 ++++++------
 clang/lib/Sema/SemaExpr.cpp                   |  6 +--
 clang/lib/Sema/SemaTemplateInstantiate.cpp    | 30 +++++---------
 .../lib/Sema/SemaTemplateInstantiateDecl.cpp  | 40 +++++++------------
 clang/lib/Sema/SemaTemplateVariadic.cpp       | 32 +++++----------
 clang/lib/Serialization/ASTReaderStmt.cpp     |  6 +--
 clang/test/AST/ast-dump-binding-pack.cpp      | 13 ++----
 clang/test/SemaCXX/cxx2c-binding-pack.cpp     | 11 +++++
 13 files changed, 103 insertions(+), 135 deletions(-)

diff --git a/clang/include/clang/AST/DeclCXX.h 
b/clang/include/clang/AST/DeclCXX.h
index 766821b4fb25cb5..1c630d616903550 100644
--- a/clang/include/clang/AST/DeclCXX.h
+++ b/clang/include/clang/AST/DeclCXX.h
@@ -4194,8 +4194,8 @@ class BindingDecl : public ValueDecl {
   /// decomposition declaration, and when the initializer is type-dependent.
   Expr *getBinding() const { return Binding; }
 
-  // Get the array of Exprs when the binding represents a pack.
-  llvm::ArrayRef<Expr *> getBindingPackExprs() const;
+  // Get the array of nested BindingDecls when the binding represents a pack.
+  llvm::ArrayRef<BindingDecl *> getBindingPackDecls() const;
 
   /// Get the decomposition declaration that this binding represents a
   /// decomposition of.
@@ -4246,10 +4246,8 @@ class DecompositionDecl final
     for (auto *B : Bindings) {
       B->setDecomposedDecl(this);
       if (B->isParameterPack() && B->getBinding()) {
-        for (Expr *E : B->getBindingPackExprs()) {
-          auto *DRE = cast<DeclRefExpr>(E);
-          auto *NestedB = cast<BindingDecl>(DRE->getDecl());
-          NestedB->setDecomposedDecl(this);
+        for (BindingDecl *NestedBD : B->getBindingPackDecls()) {
+          NestedBD->setDecomposedDecl(this);
         }
       }
     }
@@ -4278,25 +4276,21 @@ class DecompositionDecl final
   // Provide a flattened range to visit each binding.
   auto flat_bindings() const {
     llvm::ArrayRef<BindingDecl *> Bindings = bindings();
-    llvm::ArrayRef<Expr *> PackExprs;
+    llvm::ArrayRef<BindingDecl *> PackBindings;
 
     // Split the bindings into subranges split by the pack.
-    auto S1 = Bindings.take_until(
+    auto BeforePackBindings = Bindings.take_until(
         [](BindingDecl *BD) { return BD->isParameterPack(); });
 
-    Bindings = Bindings.drop_front(S1.size());
+    Bindings = Bindings.drop_front(BeforePackBindings.size());
     if (!Bindings.empty()) {
-      PackExprs = Bindings.front()->getBindingPackExprs();
+      PackBindings = Bindings.front()->getBindingPackDecls();
       Bindings = Bindings.drop_front();
     }
 
-    auto S2 = llvm::map_range(PackExprs, [](Expr *E) {
-      auto *DRE = cast<DeclRefExpr>(E);
-      return cast<BindingDecl>(DRE->getDecl());
-    });
-
-    return llvm::concat<BindingDecl *>(std::move(S1), std::move(S2),
-                                       std::move(Bindings));
+    return llvm::concat<BindingDecl *const>(std::move(BeforePackBindings),
+                                            std::move(PackBindings),
+                                            std::move(Bindings));
   }
 
   void printName(raw_ostream &OS, const PrintingPolicy &Policy) const override;
diff --git a/clang/include/clang/AST/ExprCXX.h 
b/clang/include/clang/AST/ExprCXX.h
index 0b6c8cfb163c958..2b23fa51c6232b2 100644
--- a/clang/include/clang/AST/ExprCXX.h
+++ b/clang/include/clang/AST/ExprCXX.h
@@ -4649,13 +4649,13 @@ class SubstNonTypeTemplateParmPackExpr : public Expr {
 /// \endcode
 class FunctionParmPackExpr final
     : public Expr,
-      private llvm::TrailingObjects<FunctionParmPackExpr, VarDecl *> {
+      private llvm::TrailingObjects<FunctionParmPackExpr, ValueDecl *> {
   friend class ASTReader;
   friend class ASTStmtReader;
   friend TrailingObjects;
 
   /// The function parameter pack which was referenced.
-  VarDecl *ParamPack;
+  ValueDecl *ParamPack;
 
   /// The location of the function parameter pack reference.
   SourceLocation NameLoc;
@@ -4663,35 +4663,34 @@ class FunctionParmPackExpr final
   /// The number of expansions of this pack.
   unsigned NumParameters;
 
-  FunctionParmPackExpr(QualType T, VarDecl *ParamPack,
-                       SourceLocation NameLoc, unsigned NumParams,
-                       VarDecl *const *Params);
+  FunctionParmPackExpr(QualType T, ValueDecl *ParamPack, SourceLocation 
NameLoc,
+                       unsigned NumParams, ValueDecl *const *Params);
 
 public:
   static FunctionParmPackExpr *Create(const ASTContext &Context, QualType T,
-                                      VarDecl *ParamPack,
+                                      ValueDecl *ParamPack,
                                       SourceLocation NameLoc,
-                                      ArrayRef<VarDecl *> Params);
+                                      ArrayRef<ValueDecl *> Params);
   static FunctionParmPackExpr *CreateEmpty(const ASTContext &Context,
                                            unsigned NumParams);
 
   /// Get the parameter pack which this expression refers to.
-  VarDecl *getParameterPack() const { return ParamPack; }
+  ValueDecl *getParameterPack() const { return ParamPack; }
 
   /// Get the location of the parameter pack.
   SourceLocation getParameterPackLocation() const { return NameLoc; }
 
   /// Iterators over the parameters which the parameter pack expanded
   /// into.
-  using iterator = VarDecl * const *;
-  iterator begin() const { return getTrailingObjects<VarDecl *>(); }
+  using iterator = ValueDecl *const *;
+  iterator begin() const { return getTrailingObjects<ValueDecl *>(); }
   iterator end() const { return begin() + NumParameters; }
 
   /// Get the number of parameters in this parameter pack.
   unsigned getNumExpansions() const { return NumParameters; }
 
   /// Get an expansion of the parameter pack by index.
-  VarDecl *getExpansion(unsigned I) const { return begin()[I]; }
+  ValueDecl *getExpansion(unsigned I) const { return begin()[I]; }
 
   SourceLocation getBeginLoc() const LLVM_READONLY { return NameLoc; }
   SourceLocation getEndLoc() const LLVM_READONLY { return NameLoc; }
diff --git a/clang/include/clang/Sema/Template.h 
b/clang/include/clang/Sema/Template.h
index 4206bd50b13dd6e..647c4cfa341e183 100644
--- a/clang/include/clang/Sema/Template.h
+++ b/clang/include/clang/Sema/Template.h
@@ -365,7 +365,7 @@ enum class TemplateSubstitutionKind : char {
   class LocalInstantiationScope {
   public:
     /// A set of declarations.
-    using DeclArgumentPack = SmallVector<VarDecl *, 4>;
+    using DeclArgumentPack = SmallVector<ValueDecl *, 4>;
 
   private:
     /// Reference to the semantic analysis that is performing
diff --git a/clang/lib/AST/DeclCXX.cpp b/clang/lib/AST/DeclCXX.cpp
index e394e0515e59938..91be7c8ccfaaea6 100644
--- a/clang/lib/AST/DeclCXX.cpp
+++ b/clang/lib/AST/DeclCXX.cpp
@@ -3492,10 +3492,13 @@ VarDecl *BindingDecl::getHoldingVar() const {
   return VD;
 }
 
-llvm::ArrayRef<Expr *> BindingDecl::getBindingPackExprs() const {
+llvm::ArrayRef<BindingDecl *> BindingDecl::getBindingPackDecls() const {
   assert(Binding && "expecting a pack expr");
-  auto *RP = cast<ResolvedUnexpandedPackExpr>(Binding);
-  return RP->getExprs();
+  auto *FP = cast<FunctionParmPackExpr>(Binding);
+  ValueDecl *const *First = FP->getNumExpansions() > 0 ? FP->begin() : nullptr;
+  assert((!First || isa<BindingDecl>(*First)) && "expecting a BindingDecl");
+  return llvm::ArrayRef<BindingDecl *>((BindingDecl *const *)First,
+                                       FP->getNumExpansions());
 }
 
 void DecompositionDecl::anchor() {}
diff --git a/clang/lib/AST/ExprCXX.cpp b/clang/lib/AST/ExprCXX.cpp
index d900af895b42a68..d69542cdfc8068e 100644
--- a/clang/lib/AST/ExprCXX.cpp
+++ b/clang/lib/AST/ExprCXX.cpp
@@ -1779,31 +1779,31 @@ TemplateArgument 
SubstNonTypeTemplateParmPackExpr::getArgumentPack() const {
   return TemplateArgument(llvm::ArrayRef(Arguments, NumArguments));
 }
 
-FunctionParmPackExpr::FunctionParmPackExpr(QualType T, VarDecl *ParamPack,
+FunctionParmPackExpr::FunctionParmPackExpr(QualType T, ValueDecl *ParamPack,
                                            SourceLocation NameLoc,
                                            unsigned NumParams,
-                                           VarDecl *const *Params)
+                                           ValueDecl *const *Params)
     : Expr(FunctionParmPackExprClass, T, VK_LValue, OK_Ordinary),
       ParamPack(ParamPack), NameLoc(NameLoc), NumParameters(NumParams) {
   if (Params)
     std::uninitialized_copy(Params, Params + NumParams,
-                            getTrailingObjects<VarDecl *>());
+                            getTrailingObjects<ValueDecl *>());
   setDependence(ExprDependence::TypeValueInstantiation |
                 ExprDependence::UnexpandedPack);
 }
 
 FunctionParmPackExpr *
 FunctionParmPackExpr::Create(const ASTContext &Context, QualType T,
-                             VarDecl *ParamPack, SourceLocation NameLoc,
-                             ArrayRef<VarDecl *> Params) {
-  return new (Context.Allocate(totalSizeToAlloc<VarDecl *>(Params.size())))
+                             ValueDecl *ParamPack, SourceLocation NameLoc,
+                             ArrayRef<ValueDecl *> Params) {
+  return new (Context.Allocate(totalSizeToAlloc<ValueDecl *>(Params.size())))
       FunctionParmPackExpr(T, ParamPack, NameLoc, Params.size(), 
Params.data());
 }
 
 FunctionParmPackExpr *
 FunctionParmPackExpr::CreateEmpty(const ASTContext &Context,
                                   unsigned NumParams) {
-  return new (Context.Allocate(totalSizeToAlloc<VarDecl *>(NumParams)))
+  return new (Context.Allocate(totalSizeToAlloc<ValueDecl *>(NumParams)))
       FunctionParmPackExpr(QualType(), nullptr, SourceLocation(), 0, nullptr);
 }
 
diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp
index 0cf02fe6407c24c..c38a7ab97d70fd0 100644
--- a/clang/lib/Sema/SemaDeclCXX.cpp
+++ b/clang/lib/Sema/SemaDeclCXX.cpp
@@ -980,24 +980,24 @@ static bool CheckBindingsCount(Sema &S, DecompositionDecl 
*DD,
   if (IsValid && HasPack) {
     // Create the pack expr and assign it to the binding.
     unsigned PackSize = MemberCount - Bindings.size() + 1;
-    QualType PackType = S.Context.getPackExpansionType(
-        S.Context.DependentTy, std::nullopt, /*ExpectsPackInType=*/false);
-    BindingDecl *BD = (*BindingWithPackItr);
-    auto *RP = ResolvedUnexpandedPackExpr::Create(S.Context, DD->getBeginLoc(),
-                                                  DecompType, PackSize);
-    BD->setDecomposedDecl(DD);
-    BD->setBinding(PackType, RP);
 
     BindingDecl *BPack = *BindingWithPackItr;
+    BPack->setDecomposedDecl(DD);
+    SmallVector<ValueDecl *, 8> NestedBDs(PackSize);
     // Create the nested BindingDecls.
-    for (Expr *&E : RP->getExprs()) {
-      auto *NestedBD = BindingDecl::Create(S.Context, BPack->getDeclContext(),
-                                           BPack->getLocation(),
-                                           BPack->getIdentifier(), QualType());
+    for (ValueDecl *&VD : NestedBDs) {
+      BindingDecl *NestedBD = BindingDecl::Create(
+          S.Context, BPack->getDeclContext(), BPack->getLocation(),
+          BPack->getIdentifier(), QualType());
       NestedBD->setDecomposedDecl(DD);
-      E = S.BuildDeclRefExpr(NestedBD, S.Context.DependentTy, VK_LValue,
-                             BPack->getLocation());
+      VD = NestedBD;
     }
+
+    QualType PackType = S.Context.getPackExpansionType(
+        S.Context.DependentTy, PackSize, /*ExpectsPackInType=*/false);
+    auto *PackExpr = FunctionParmPackExpr::Create(
+        S.Context, PackType, BPack, BPack->getBeginLoc(), NestedBDs);
+    BPack->setBinding(PackType, PackExpr);
   }
 
   if (IsValid)
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index 95c985e049060c7..90937161bb8c72d 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -19430,7 +19430,7 @@ static ExprResult 
rebuildPotentialResultsAsNonOdrUsed(Sema &S, Expr *E,
     auto *FPPE = cast<FunctionParmPackExpr>(E);
     // If any of the declarations in the pack is odr-used, then the expression
     // as a whole constitutes an odr-use.
-    for (VarDecl *D : *FPPE)
+    for (ValueDecl *D : *FPPE)
       if (IsPotentialResultOdrUsed(D))
         return ExprEmpty();
 
@@ -19705,7 +19705,7 @@ void Sema::CleanupVarDeclMarking() {
       MarkVarDeclODRUsed(cast<VarDecl>(ME->getMemberDecl()), 
ME->getMemberLoc(),
                          *this);
     } else if (auto *FP = dyn_cast<FunctionParmPackExpr>(E)) {
-      for (VarDecl *VD : *FP)
+      for (ValueDecl *VD : *FP)
         MarkVarDeclODRUsed(VD, FP->getParameterPackLocation(), *this);
     } else {
       llvm_unreachable("Unexpected expression");
@@ -20081,7 +20081,7 @@ void Sema::MarkMemberReferenced(MemberExpr *E) {
 }
 
 void Sema::MarkFunctionParmPackReferenced(FunctionParmPackExpr *E) {
-  for (VarDecl *VD : *E)
+  for (ValueDecl *VD : *E)
     MarkExprReferenced(*this, E->getParameterPackLocation(), VD, E, true,
                        RefsMinusAssignments);
 }
diff --git a/clang/lib/Sema/SemaTemplateInstantiate.cpp 
b/clang/lib/Sema/SemaTemplateInstantiate.cpp
index dc3bfa97eff399b..8eeafee1f3f522a 100644
--- a/clang/lib/Sema/SemaTemplateInstantiate.cpp
+++ b/clang/lib/Sema/SemaTemplateInstantiate.cpp
@@ -1574,10 +1574,10 @@ namespace {
                                            SubstNonTypeTemplateParmExpr *E);
 
     /// Rebuild a DeclRefExpr for a VarDecl reference.
-    ExprResult RebuildVarDeclRefExpr(VarDecl *PD, SourceLocation Loc);
+    ExprResult RebuildVarDeclRefExpr(ValueDecl *PD, SourceLocation Loc);
 
     /// Transform a reference to a function or init-capture parameter pack.
-    ExprResult TransformFunctionParmPackRefExpr(DeclRefExpr *E, VarDecl *PD);
+    ExprResult TransformFunctionParmPackRefExpr(DeclRefExpr *E, ValueDecl *PD);
 
     /// Transform a FunctionParmPackExpr which was built when we couldn't
     /// expand a function parameter pack reference which refers to an expanded
@@ -2389,7 +2389,7 @@ 
TemplateInstantiator::TransformSubstNonTypeTemplateParmExpr(
                                          SugaredConverted, E->getPackIndex());
 }
 
-ExprResult TemplateInstantiator::RebuildVarDeclRefExpr(VarDecl *PD,
+ExprResult TemplateInstantiator::RebuildVarDeclRefExpr(ValueDecl *PD,
                                                        SourceLocation Loc) {
   DeclarationNameInfo NameInfo(PD->getDeclName(), Loc);
   return getSema().BuildDeclarationNameExpr(CXXScopeSpec(), NameInfo, PD);
@@ -2399,8 +2399,8 @@ ExprResult
 TemplateInstantiator::TransformFunctionParmPackExpr(FunctionParmPackExpr *E) {
   if (getSema().ArgumentPackSubstitutionIndex != -1) {
     // We can expand this parameter pack now.
-    VarDecl *D = E->getExpansion(getSema().ArgumentPackSubstitutionIndex);
-    VarDecl *VD = cast_or_null<VarDecl>(TransformDecl(E->getExprLoc(), D));
+    ValueDecl *D = E->getExpansion(getSema().ArgumentPackSubstitutionIndex);
+    ValueDecl *VD = cast_or_null<ValueDecl>(TransformDecl(E->getExprLoc(), D));
     if (!VD)
       return ExprError();
     return RebuildVarDeclRefExpr(VD, E->getExprLoc());
@@ -2412,11 +2412,11 @@ 
TemplateInstantiator::TransformFunctionParmPackExpr(FunctionParmPackExpr *E) {
 
   // Transform each of the parameter expansions into the corresponding
   // parameters in the instantiation of the function decl.
-  SmallVector<VarDecl *, 8> Vars;
+  SmallVector<ValueDecl *, 8> Vars;
   Vars.reserve(E->getNumExpansions());
   for (FunctionParmPackExpr::iterator I = E->begin(), End = E->end();
        I != End; ++I) {
-    VarDecl *D = cast_or_null<VarDecl>(TransformDecl(E->getExprLoc(), *I));
+    ValueDecl *D = cast_or_null<ValueDecl>(TransformDecl(E->getExprLoc(), *I));
     if (!D)
       return ExprError();
     Vars.push_back(D);
@@ -2431,7 +2431,7 @@ 
TemplateInstantiator::TransformFunctionParmPackExpr(FunctionParmPackExpr *E) {
 
 ExprResult
 TemplateInstantiator::TransformFunctionParmPackRefExpr(DeclRefExpr *E,
-                                                       VarDecl *PD) {
+                                                       ValueDecl *PD) {
   typedef LocalInstantiationScope::DeclArgumentPack DeclArgumentPack;
   llvm::PointerUnion<Decl *, DeclArgumentPack *> *Found
     = getSema().CurrentInstantiationScope->findInstantiationOf(PD);
@@ -2457,7 +2457,8 @@ 
TemplateInstantiator::TransformFunctionParmPackRefExpr(DeclRefExpr *E,
   }
 
   // We have either an unexpanded pack or a specific expansion.
-  return RebuildVarDeclRefExpr(cast<VarDecl>(TransformedDecl), 
E->getExprLoc());
+  return RebuildVarDeclRefExpr(cast<ValueDecl>(TransformedDecl),
+                               E->getExprLoc());
 }
 
 ExprResult
@@ -2479,15 +2480,6 @@ TemplateInstantiator::TransformDeclRefExpr(DeclRefExpr 
*E) {
     if (PD->isParameterPack())
       return TransformFunctionParmPackRefExpr(E, PD);
 
-  if (BindingDecl *BD = dyn_cast<BindingDecl>(D); BD && BD->isParameterPack()) 
{
-    BD = cast_or_null<BindingDecl>(TransformDecl(BD->getLocation(), BD));
-    if (!BD)
-      return ExprError();
-    if (auto *RP =
-            dyn_cast_if_present<ResolvedUnexpandedPackExpr>(BD->getBinding()))
-      return TransformResolvedUnexpandedPackExpr(RP);
-  }
-
   return inherited::TransformDeclRefExpr(E);
 }
 
@@ -4683,7 +4675,7 @@ void LocalInstantiationScope::InstantiatedLocal(const 
Decl *D, Decl *Inst) {
 #endif
     Stored = Inst;
   } else if (DeclArgumentPack *Pack = dyn_cast<DeclArgumentPack *>(Stored)) {
-    Pack->push_back(cast<VarDecl>(Inst));
+    Pack->push_back(cast<ValueDecl>(Inst));
   } else {
     assert(cast<Decl *>(Stored) == Inst && "Already instantiated this local");
   }
diff --git a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp 
b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
index 4855e8a23689cef..5081a37e7c0f814 100644
--- a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
+++ b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
@@ -1178,13 +1178,13 @@ Decl 
*TemplateDeclInstantiator::VisitDecompositionDecl(DecompositionDecl *D) {
   // Transform the bindings first.
   // The transformed DD will have all of the concrete BindingDecls.
   SmallVector<BindingDecl*, 16> NewBindings;
-  ResolvedUnexpandedPackExpr *OldResolvedPack = nullptr;
+  BindingDecl *OldBindingPack = nullptr;
   for (auto *OldBD : D->bindings()) {
     Expr *BindingExpr = OldBD->getBinding();
-    if (auto *RP =
-            dyn_cast_if_present<ResolvedUnexpandedPackExpr>(BindingExpr)) {
-      assert(!OldResolvedPack && "no more than one pack is allowed");
-      OldResolvedPack = RP;
+    if (isa_and_nonnull<FunctionParmPackExpr>(BindingExpr)) {
+      // We have a resolved pack.
+      assert(!OldBindingPack && "no more than one pack is allowed");
+      OldBindingPack = OldBD;
     }
     NewBindings.push_back(cast<BindingDecl>(VisitBindingDecl(OldBD)));
   }
@@ -1197,25 +1197,17 @@ Decl 
*TemplateDeclInstantiator::VisitDecompositionDecl(DecompositionDecl *D) {
     for (auto *NewBD : NewBindings)
       NewBD->setInvalidDecl();
 
-  if (OldResolvedPack) {
-    // Mark the holding vars (if any) in the pack as instantiated since
-    // they are created implicitly.
+  if (OldBindingPack) {
+    // Mark the bindings in the pack as instantiated.
     auto Bindings = NewDD->bindings();
-    auto BPack = llvm::find_if(
+    auto NewBindingPack = *llvm::find_if(
         Bindings, [](BindingDecl *D) -> bool { return D->isParameterPack(); });
-    auto *NewResolvedPack =
-        cast<ResolvedUnexpandedPackExpr>((*BPack)->getBinding());
-    auto OldExprs = OldResolvedPack->getExprs();
-    auto NewExprs = NewResolvedPack->getExprs();
-    assert(OldExprs.size() == NewExprs.size());
-    for (unsigned I = 0; I < OldResolvedPack->getNumExprs(); I++) {
-      DeclRefExpr *OldDRE = cast<DeclRefExpr>(OldExprs[I]);
-      BindingDecl *OldNestedBD = cast<BindingDecl>(OldDRE->getDecl());
-      DeclRefExpr *NewDRE = cast<DeclRefExpr>(NewExprs[I]);
-      BindingDecl *NewNestedBD = cast<BindingDecl>(NewDRE->getDecl());
-      SemaRef.CurrentInstantiationScope->InstantiatedLocal(OldNestedBD,
-                                                           NewNestedBD);
-    }
+    auto OldDecls = OldBindingPack->getBindingPackDecls();
+    auto NewDecls = NewBindingPack->getBindingPackDecls();
+    assert(OldDecls.size() == NewDecls.size());
+    for (unsigned I = 0; I < OldDecls.size(); I++)
+      SemaRef.CurrentInstantiationScope->InstantiatedLocal(OldDecls[I],
+                                                           NewDecls[I]);
   }
 
   return NewDD;
@@ -6257,9 +6249,7 @@ NamedDecl *Sema::FindInstantiatedDecl(SourceLocation Loc, 
NamedDecl *D,
           if (auto *BD = dyn_cast<BindingDecl>(FD);
               BD && BD->isParameterPack() &&
               ArgumentPackSubstitutionIndex != -1) {
-            auto *DRE = cast<DeclRefExpr>(
-                BD->getBindingPackExprs()[ArgumentPackSubstitutionIndex]);
-            return cast<NamedDecl>(DRE->getDecl());
+            return BD->getBindingPackDecls()[ArgumentPackSubstitutionIndex];
           }
           return cast<NamedDecl>(FD);
         }
diff --git a/clang/lib/Sema/SemaTemplateVariadic.cpp 
b/clang/lib/Sema/SemaTemplateVariadic.cpp
index 3c56794722dcc74..b2088ae8394ab3c 100644
--- a/clang/lib/Sema/SemaTemplateVariadic.cpp
+++ b/clang/lib/Sema/SemaTemplateVariadic.cpp
@@ -50,13 +50,8 @@ class CollectUnexpandedParameterPacksVisitor
         auto *FTD = FD ? FD->getDescribedFunctionTemplate() : nullptr;
         if (FTD && FTD->getTemplateParameters()->getDepth() >= DepthLimit)
           return;
-      } else if (auto *BD = dyn_cast<BindingDecl>(ND)) {
-        Expr *E = BD->getBinding();
-        if (auto *RP = cast_if_present<ResolvedUnexpandedPackExpr>(E)) {
-          addUnexpanded(RP);
-          return;
-        }
-      } else if (getDepthAndIndex(ND).first >= DepthLimit) {
+      } else if (ND->isTemplateParameterPack() &&
+                 getDepthAndIndex(ND).first >= DepthLimit) {
         return;
       }
 
@@ -782,16 +777,13 @@ bool Sema::CheckParameterPacksForExpansion(
     unsigned Depth = 0, Index = 0;
     IdentifierInfo *Name;
     bool IsVarDeclPack = false;
-    ResolvedUnexpandedPackExpr *ResolvedPack = nullptr;
+    FunctionParmPackExpr *BindingPack = nullptr;
 
     if (const TemplateTypeParmType *TTP =
             ParmPack.first.dyn_cast<const TemplateTypeParmType *>()) {
       Depth = TTP->getDepth();
       Index = TTP->getIndex();
       Name = TTP->getIdentifier();
-    } else if (auto *RP =
-                   ParmPack.first.dyn_cast<ResolvedUnexpandedPackExpr *>()) {
-      ResolvedPack = RP;
     } else {
       NamedDecl *ND = cast<NamedDecl *>(ParmPack.first);
       if (isa<VarDecl>(ND))
@@ -802,8 +794,8 @@ bool Sema::CheckParameterPacksForExpansion(
             CurrentInstantiationScope->findInstantiationOf(ND);
         Decl *B = cast<Decl *>(*Instantiation);
         Expr *BindingExpr = cast<BindingDecl>(B)->getBinding();
-        ResolvedPack = 
cast_if_present<ResolvedUnexpandedPackExpr>(BindingExpr);
-        if (!ResolvedPack) {
+        BindingPack = cast_if_present<FunctionParmPackExpr>(BindingExpr);
+        if (!BindingPack) {
           ShouldExpand = false;
           continue;
         }
@@ -829,8 +821,8 @@ bool Sema::CheckParameterPacksForExpansion(
         ShouldExpand = false;
         continue;
       }
-    } else if (ResolvedPack) {
-      NewPackSize = ResolvedPack->getNumExprs();
+    } else if (BindingPack) {
+      NewPackSize = BindingPack->getNumExpansions();
     } else {
       // 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
@@ -867,7 +859,7 @@ bool Sema::CheckParameterPacksForExpansion(
     //   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 && !ResolvedPack && CurrentInstantiationScope) {
+    if (!IsVarDeclPack && CurrentInstantiationScope) {
       if (NamedDecl *PartialPack =
               CurrentInstantiationScope->getPartiallySubstitutedPack()) {
         unsigned PartialDepth, PartialIndex;
@@ -973,12 +965,6 @@ std::optional<unsigned> 
Sema::getNumArgumentsInExpansionFromUnexpanded(
             Unexpanded[I].first.dyn_cast<const TemplateTypeParmType *>()) {
       Depth = TTP->getDepth();
       Index = TTP->getIndex();
-    } else if (auto *PE = Unexpanded[I]
-                              .first.dyn_cast<ResolvedUnexpandedPackExpr *>()) 
{
-      unsigned Size = PE->getNumExprs();
-      assert((!Result || *Result == Size) && "inconsistent pack sizes");
-      Result = Size;
-      continue;
     } else {
       NamedDecl *ND = cast<NamedDecl *>(Unexpanded[I].first);
       if (isa<VarDecl>(ND)) {
@@ -1360,7 +1346,7 @@ std::optional<unsigned> 
Sema::getFullyPackExpandedSize(TemplateArgument Arg) {
             dyn_cast<SubstNonTypeTemplateParmPackExpr>(Arg.getAsExpr()))
       Pack = Subst->getArgumentPack();
     else if (auto *Subst = dyn_cast<FunctionParmPackExpr>(Arg.getAsExpr()))  {
-      for (VarDecl *PD : *Subst)
+      for (ValueDecl *PD : *Subst)
         if (PD->isParameterPack())
           return std::nullopt;
       return Subst->getNumExpansions();
diff --git a/clang/lib/Serialization/ASTReaderStmt.cpp 
b/clang/lib/Serialization/ASTReaderStmt.cpp
index b15eca87993a5b3..3ca4ee312828416 100644
--- a/clang/lib/Serialization/ASTReaderStmt.cpp
+++ b/clang/lib/Serialization/ASTReaderStmt.cpp
@@ -2249,11 +2249,11 @@ void 
ASTStmtReader::VisitSubstNonTypeTemplateParmPackExpr(
 void ASTStmtReader::VisitFunctionParmPackExpr(FunctionParmPackExpr *E) {
   VisitExpr(E);
   E->NumParameters = Record.readInt();
-  E->ParamPack = readDeclAs<ParmVarDecl>();
+  E->ParamPack = readDeclAs<ValueDecl>();
   E->NameLoc = readSourceLocation();
-  auto **Parms = E->getTrailingObjects<VarDecl *>();
+  auto **Parms = E->getTrailingObjects<ValueDecl *>();
   for (unsigned i = 0, n = E->NumParameters; i != n; ++i)
-    Parms[i] = readDeclAs<VarDecl>();
+    Parms[i] = readDeclAs<ValueDecl>();
 }
 
 void ASTStmtReader::VisitMaterializeTemporaryExpr(MaterializeTemporaryExpr *E) 
{
diff --git a/clang/test/AST/ast-dump-binding-pack.cpp 
b/clang/test/AST/ast-dump-binding-pack.cpp
index 81c75a1268730f2..c4a353ae72a1bd9 100644
--- a/clang/test/AST/ast-dump-binding-pack.cpp
+++ b/clang/test/AST/ast-dump-binding-pack.cpp
@@ -22,10 +22,7 @@ void foo() {
 // CHECK-NEXT: IntegerLiteral {{.*}} 'int' 0
 // CHECK-NOT: BindingDecl
 // CHECK-LABEL: BindingDecl {{.*}} binding_rest
-// CHECK-NEXT: ResolvedUnexpandedPackExpr
-// CHECK-NEXT: DeclRefExpr {{.*}} lvalue Binding {{.*}} 'binding_rest'
-// CHECK-NEXT: DeclRefExpr {{.*}} lvalue Binding {{.*}} 'binding_rest'
-// CHECK-NOT: BindingDecl
+// CHECK-NEXT: FunctionParmPackExpr
 // CHECK-LABEL: BindingDecl {{.*}} binding_4
 // CHECK-NEXT: ArraySubscriptExpr
 // CHECK-NEXT: ImplicitCastExpr {{.*}}
@@ -47,9 +44,7 @@ void bar() {
 // CHECK-LABEL: FunctionTemplateDecl {{.*}} bar
 // CHECK-NOT: BindingDecl
 // CHECK-LABEL: BindingDecl {{.*}} empty_binding_pack
-// CHECK-NEXT: ResolvedUnexpandedPackExpr
-// CHECK-NOT: DeclRefExpr {{.*}} 'empty_binding_pack'
-// CHECK-NOT: BindingDecl
+// CHECK-NEXT: FunctionParmPackExpr
 // CHECK: DeclStmt
 
 struct int_pair { int x; int y; };
@@ -67,8 +62,6 @@ void(*f)() = baz<int_pair>;
 // CHECK: BindingDecl {{.*}} binding_2
 // CHECK-NOT: BindingDecl
 // CHECK-LABEL: BindingDecl {{.*}} empty_binding_pack
-// CHECK-NEXT: ResolvedUnexpandedPackExpr
-// CHECK-NOT: DeclRefExpr {{.*}} 'empty_binding_pack'
-// CHECK-NOT: BindingDecl
+// CHECK-NEXT: FunctionParmPackExpr
 // CHECK: DeclStmt
 #endif
diff --git a/clang/test/SemaCXX/cxx2c-binding-pack.cpp 
b/clang/test/SemaCXX/cxx2c-binding-pack.cpp
index 5ca249f52b3d8ef..7506e3d28e9fce6 100644
--- a/clang/test/SemaCXX/cxx2c-binding-pack.cpp
+++ b/clang/test/SemaCXX/cxx2c-binding-pack.cpp
@@ -59,6 +59,7 @@ template <typename T>
 void decompose_struct() {
   T obj{1, 2, 3, 6};
   auto [x, ...rest, y] = obj;
+  static_assert(sizeof...(rest) == 2);
 
   auto [...empty] = type_<int>{};
   static_assert(sizeof...(empty) == 0);
@@ -124,6 +125,14 @@ void lambda_capture() {
   [&x...] { (void)sum(x...); }();
 }
 
+struct S2 {
+    int a, b, c;
+};
+
+auto X = [] <typename = void> () {
+    auto [...pack] = S2{};
+};
+
 int main() {
   decompose_array<int>();
   decompose_tuple<fake_tuple>();
@@ -133,6 +142,8 @@ int main() {
   lambda_capture<int[5]>();
   lambda_capture<fake_tuple>();
   lambda_capture<my_struct>();
+  X();
+
 }
 
 // P1061R10 Stuff

>From 96b0096b17eedf5c0b863bdaed75f8668e2370c1 Mon Sep 17 00:00:00 2001
From: Jason Rice <ricejas...@gmail.com>
Date: Sun, 2 Feb 2025 01:04:06 -0800
Subject: [PATCH 2/3] [Clang][P1061] Remove ResolvedUnexpandedPackExpr

---
 clang/include/clang/AST/ExprCXX.h             | 53 -------------------
 clang/include/clang/AST/RecursiveASTVisitor.h |  1 -
 clang/include/clang/Basic/StmtNodes.td        |  1 -
 clang/include/clang/Sema/Sema.h               |  3 +-
 .../include/clang/Serialization/ASTBitCodes.h |  1 -
 clang/lib/AST/Expr.cpp                        |  1 -
 clang/lib/AST/ExprCXX.cpp                     | 49 -----------------
 clang/lib/AST/ExprClassification.cpp          |  7 ---
 clang/lib/AST/ExprConstant.cpp                |  1 -
 clang/lib/AST/ItaniumMangle.cpp               |  3 +-
 clang/lib/AST/StmtPrinter.cpp                 |  9 ----
 clang/lib/AST/StmtProfile.cpp                 |  4 --
 clang/lib/Sema/SemaExceptionSpec.cpp          |  1 -
 clang/lib/Sema/SemaTemplateInstantiate.cpp    | 17 ------
 clang/lib/Sema/SemaTemplateVariadic.cpp       | 16 +-----
 clang/lib/Sema/TreeTransform.h                | 25 ---------
 clang/lib/Serialization/ASTReaderStmt.cpp     | 16 ------
 clang/lib/Serialization/ASTWriter.cpp         |  1 -
 clang/lib/Serialization/ASTWriterStmt.cpp     | 10 ----
 clang/lib/StaticAnalyzer/Core/ExprEngine.cpp  |  1 -
 clang/tools/libclang/CXCursor.cpp             |  1 -
 21 files changed, 3 insertions(+), 218 deletions(-)

diff --git a/clang/include/clang/AST/ExprCXX.h 
b/clang/include/clang/AST/ExprCXX.h
index 2b23fa51c6232b2..f6cf48cb66b801a 100644
--- a/clang/include/clang/AST/ExprCXX.h
+++ b/clang/include/clang/AST/ExprCXX.h
@@ -5318,59 +5318,6 @@ class BuiltinBitCastExpr final
   }
 };
 
-// Represents an unexpanded pack where the list of expressions are
-// known. These are used when structured bindings introduce a pack.
-class ResolvedUnexpandedPackExpr final
-    : public Expr,
-      private llvm::TrailingObjects<ResolvedUnexpandedPackExpr, Expr *> {
-  friend class ASTStmtReader;
-  friend class ASTStmtWriter;
-  friend TrailingObjects;
-
-  SourceLocation BeginLoc;
-  unsigned NumExprs;
-
-  ResolvedUnexpandedPackExpr(SourceLocation BL, QualType QT, unsigned 
NumExprs);
-
-public:
-  static ResolvedUnexpandedPackExpr *CreateDeserialized(ASTContext &C,
-                                                        unsigned NumExprs);
-  static ResolvedUnexpandedPackExpr *
-  Create(ASTContext &C, SourceLocation BeginLoc, QualType T, unsigned 
NumExprs);
-  static ResolvedUnexpandedPackExpr *Create(ASTContext &C,
-                                            SourceLocation BeginLoc, QualType 
T,
-                                            llvm::ArrayRef<Expr *> Exprs);
-
-  unsigned getNumExprs() const { return NumExprs; }
-
-  llvm::MutableArrayRef<Expr *> getExprs() {
-    return {getTrailingObjects<Expr *>(), NumExprs};
-  }
-
-  llvm::ArrayRef<Expr *> getExprs() const {
-    return {getTrailingObjects<Expr *>(), NumExprs};
-  }
-
-  Expr *getExpansion(unsigned Idx) { return getExprs()[Idx]; }
-  Expr *getExpansion(unsigned Idx) const { return getExprs()[Idx]; }
-
-  // Iterators
-  child_range children() {
-    return child_range((Stmt **)getTrailingObjects<Expr *>(),
-                       (Stmt **)getTrailingObjects<Expr *>() + getNumExprs());
-  }
-
-  SourceLocation getBeginLoc() const LLVM_READONLY { return BeginLoc; }
-  SourceLocation getEndLoc() const LLVM_READONLY { return BeginLoc; }
-
-  // Returns the resolved pack of a decl or nullptr
-  static ResolvedUnexpandedPackExpr *getFromDecl(Decl *);
-
-  static bool classof(const Stmt *T) {
-    return T->getStmtClass() == ResolvedUnexpandedPackExprClass;
-  }
-};
-
 } // namespace clang
 
 #endif // LLVM_CLANG_AST_EXPRCXX_H
diff --git a/clang/include/clang/AST/RecursiveASTVisitor.h 
b/clang/include/clang/AST/RecursiveASTVisitor.h
index 5f4c39b9cbdb75d..c4a1d03f1b3d107 100644
--- a/clang/include/clang/AST/RecursiveASTVisitor.h
+++ b/clang/include/clang/AST/RecursiveASTVisitor.h
@@ -2950,7 +2950,6 @@ DEF_TRAVERSE_STMT(FunctionParmPackExpr, {})
 DEF_TRAVERSE_STMT(CXXFoldExpr, {})
 DEF_TRAVERSE_STMT(AtomicExpr, {})
 DEF_TRAVERSE_STMT(CXXParenListInitExpr, {})
-DEF_TRAVERSE_STMT(ResolvedUnexpandedPackExpr, {})
 
 DEF_TRAVERSE_STMT(MaterializeTemporaryExpr, {
   if (S->getLifetimeExtendedTemporaryDecl()) {
diff --git a/clang/include/clang/Basic/StmtNodes.td 
b/clang/include/clang/Basic/StmtNodes.td
index 2fea05e322c7547..53fc77bbbcecc11 100644
--- a/clang/include/clang/Basic/StmtNodes.td
+++ b/clang/include/clang/Basic/StmtNodes.td
@@ -163,7 +163,6 @@ def MaterializeTemporaryExpr : StmtNode<Expr>;
 def LambdaExpr : StmtNode<Expr>;
 def CXXFoldExpr : StmtNode<Expr>;
 def CXXParenListInitExpr: StmtNode<Expr>;
-def ResolvedUnexpandedPackExpr : StmtNode<Expr>;
 
 // C++ Coroutines expressions
 def CoroutineSuspendExpr : StmtNode<Expr, 1>;
diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index 472a0e25adc9752..c6cc13eb13d441d 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -232,8 +232,7 @@ void threadSafetyCleanup(BeforeSet *Cache);
 
 // FIXME: No way to easily map from TemplateTypeParmTypes to
 // TemplateTypeParmDecls, so we have this horrible PointerUnion.
-typedef std::pair<llvm::PointerUnion<const TemplateTypeParmType *, NamedDecl *,
-                                     ResolvedUnexpandedPackExpr *>,
+typedef std::pair<llvm::PointerUnion<const TemplateTypeParmType *, NamedDecl 
*>,
                   SourceLocation>
     UnexpandedParameterPack;
 
diff --git a/clang/include/clang/Serialization/ASTBitCodes.h 
b/clang/include/clang/Serialization/ASTBitCodes.h
index 7656add0b6884cc..1b56ed2c9776b5e 100644
--- a/clang/include/clang/Serialization/ASTBitCodes.h
+++ b/clang/include/clang/Serialization/ASTBitCodes.h
@@ -1908,7 +1908,6 @@ enum StmtCode {
   EXPR_PACK_EXPANSION,                    // PackExpansionExpr
   EXPR_PACK_INDEXING,                     // PackIndexingExpr
   EXPR_SIZEOF_PACK,                       // SizeOfPackExpr
-  EXPR_RESOLVED_UNEXPANDED_PACK,          // ResolvedUnexpandedPackExpr
   EXPR_SUBST_NON_TYPE_TEMPLATE_PARM,      // SubstNonTypeTemplateParmExpr
   EXPR_SUBST_NON_TYPE_TEMPLATE_PARM_PACK, // SubstNonTypeTemplateParmPackExpr
   EXPR_FUNCTION_PARM_PACK,                // FunctionParmPackExpr
diff --git a/clang/lib/AST/Expr.cpp b/clang/lib/AST/Expr.cpp
index 4fc62919fde94bf..06b04914426737c 100644
--- a/clang/lib/AST/Expr.cpp
+++ b/clang/lib/AST/Expr.cpp
@@ -3659,7 +3659,6 @@ bool Expr::HasSideEffects(const ASTContext &Ctx,
   case PackIndexingExprClass:
   case HLSLOutArgExprClass:
   case OpenACCAsteriskSizeExprClass:
-  case ResolvedUnexpandedPackExprClass:
     // These never have a side-effect.
     return false;
 
diff --git a/clang/lib/AST/ExprCXX.cpp b/clang/lib/AST/ExprCXX.cpp
index d69542cdfc8068e..c8d61e2cf3f26cb 100644
--- a/clang/lib/AST/ExprCXX.cpp
+++ b/clang/lib/AST/ExprCXX.cpp
@@ -1965,52 +1965,3 @@ CXXFoldExpr::CXXFoldExpr(QualType T, 
UnresolvedLookupExpr *Callee,
   SubExprs[SubExpr::RHS] = RHS;
   setDependence(computeDependence(this));
 }
-
-ResolvedUnexpandedPackExpr::ResolvedUnexpandedPackExpr(SourceLocation BL,
-                                                       QualType QT,
-                                                       unsigned NumExprs)
-    : Expr(ResolvedUnexpandedPackExprClass, QT, VK_PRValue, OK_Ordinary),
-      BeginLoc(BL), NumExprs(NumExprs) {
-  // C++ [temp.dep.expr]p3
-  // An id-expression is type-dependent if it is
-  //    - associated by name lookup with a pack
-  setDependence(ExprDependence::TypeValueInstantiation |
-                ExprDependence::UnexpandedPack);
-}
-
-ResolvedUnexpandedPackExpr *
-ResolvedUnexpandedPackExpr::CreateDeserialized(ASTContext &Ctx,
-                                               unsigned NumExprs) {
-  void *Mem = Ctx.Allocate(totalSizeToAlloc<Expr *>(NumExprs),
-                           alignof(ResolvedUnexpandedPackExpr));
-  return new (Mem)
-      ResolvedUnexpandedPackExpr(SourceLocation(), QualType(), NumExprs);
-}
-
-ResolvedUnexpandedPackExpr *
-ResolvedUnexpandedPackExpr::Create(ASTContext &Ctx, SourceLocation BL,
-                                   QualType T, unsigned NumExprs) {
-  void *Mem = Ctx.Allocate(totalSizeToAlloc<Expr *>(NumExprs),
-                           alignof(ResolvedUnexpandedPackExpr));
-  ResolvedUnexpandedPackExpr *New =
-      new (Mem) ResolvedUnexpandedPackExpr(BL, T, NumExprs);
-
-  auto Exprs = New->getExprs();
-  std::uninitialized_fill(Exprs.begin(), Exprs.end(), nullptr);
-
-  return New;
-}
-
-ResolvedUnexpandedPackExpr *
-ResolvedUnexpandedPackExpr::Create(ASTContext &Ctx, SourceLocation BL,
-                                   QualType T, ArrayRef<Expr *> Exprs) {
-  auto *New = Create(Ctx, BL, T, Exprs.size());
-  std::uninitialized_copy(Exprs.begin(), Exprs.end(), New->getExprs().begin());
-  return New;
-}
-
-ResolvedUnexpandedPackExpr *ResolvedUnexpandedPackExpr::getFromDecl(Decl *D) {
-  if (auto *BD = dyn_cast<BindingDecl>(D))
-    return dyn_cast_if_present<ResolvedUnexpandedPackExpr>(BD->getBinding());
-  return nullptr;
-}
diff --git a/clang/lib/AST/ExprClassification.cpp 
b/clang/lib/AST/ExprClassification.cpp
index 5225c3ca773ad4f..3f37d06cc8f3a06 100644
--- a/clang/lib/AST/ExprClassification.cpp
+++ b/clang/lib/AST/ExprClassification.cpp
@@ -451,13 +451,6 @@ static Cl::Kinds ClassifyInternal(ASTContext &Ctx, const 
Expr *E) {
   case Expr::PackExpansionExprClass:
     return ClassifyInternal(Ctx, cast<PackExpansionExpr>(E)->getPattern());
 
-  case Expr::ResolvedUnexpandedPackExprClass: {
-    if (cast<ResolvedUnexpandedPackExpr>(E)->getNumExprs() > 0)
-      return ClassifyInternal(
-          Ctx, cast<ResolvedUnexpandedPackExpr>(E)->getExpansion(0));
-    return Cl::CL_LValue;
-  }
-
   case Expr::MaterializeTemporaryExprClass:
     return cast<MaterializeTemporaryExpr>(E)->isBoundToLvalueReference()
               ? Cl::CL_LValue
diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp
index 37019b5235f5610..7d1074cc4d08e02 100644
--- a/clang/lib/AST/ExprConstant.cpp
+++ b/clang/lib/AST/ExprConstant.cpp
@@ -17253,7 +17253,6 @@ static ICEDiag CheckICE(const Expr* E, const ASTContext 
&Ctx) {
   case Expr::SYCLUniqueStableNameExprClass:
   case Expr::CXXParenListInitExprClass:
   case Expr::HLSLOutArgExprClass:
-  case Expr::ResolvedUnexpandedPackExprClass:
     return ICEDiag(IK_NotICE, E->getBeginLoc());
 
   case Expr::InitListExprClass: {
diff --git a/clang/lib/AST/ItaniumMangle.cpp b/clang/lib/AST/ItaniumMangle.cpp
index e5eb22eae7dd139..4a090118c3d7b39 100644
--- a/clang/lib/AST/ItaniumMangle.cpp
+++ b/clang/lib/AST/ItaniumMangle.cpp
@@ -4932,8 +4932,7 @@ void CXXNameMangler::mangleExpression(const Expr *E, 
unsigned Arity,
   case Expr::AtomicExprClass:
   case Expr::SourceLocExprClass:
   case Expr::EmbedExprClass:
-  case Expr::BuiltinBitCastExprClass:
-  case Expr::ResolvedUnexpandedPackExprClass: {
+  case Expr::BuiltinBitCastExprClass: {
     NotPrimaryExpr();
     if (!NullOut) {
       // As bad as this diagnostic is, it's better than crashing.
diff --git a/clang/lib/AST/StmtPrinter.cpp b/clang/lib/AST/StmtPrinter.cpp
index d523abfe312848f..8c93596562663f5 100644
--- a/clang/lib/AST/StmtPrinter.cpp
+++ b/clang/lib/AST/StmtPrinter.cpp
@@ -2595,15 +2595,6 @@ void StmtPrinter::VisitPackIndexingExpr(PackIndexingExpr 
*E) {
   OS << "]";
 }
 
-void StmtPrinter::VisitResolvedUnexpandedPackExpr(
-    ResolvedUnexpandedPackExpr *E) {
-  OS << "<<resolved pack(";
-  llvm::interleave(
-      E->getExprs().begin(), E->getExprs().end(),
-      [this](auto *X) { PrintExpr(X); }, [this] { OS << ", "; });
-  OS << ")>>";
-}
-
 void StmtPrinter::VisitSubstNonTypeTemplateParmPackExpr(
                                        SubstNonTypeTemplateParmPackExpr *Node) 
{
   OS << *Node->getParameterPack();
diff --git a/clang/lib/AST/StmtProfile.cpp b/clang/lib/AST/StmtProfile.cpp
index 84985fcb20ff9ee..5d1f370cac19f3a 100644
--- a/clang/lib/AST/StmtProfile.cpp
+++ b/clang/lib/AST/StmtProfile.cpp
@@ -2280,10 +2280,6 @@ void StmtProfiler::VisitSizeOfPackExpr(const 
SizeOfPackExpr *S) {
     ID.AddInteger(0);
   }
 }
-void StmtProfiler::VisitResolvedUnexpandedPackExpr(
-    const ResolvedUnexpandedPackExpr *S) {
-  VisitExpr(S);
-}
 
 void StmtProfiler::VisitPackIndexingExpr(const PackIndexingExpr *E) {
   VisitExpr(E);
diff --git a/clang/lib/Sema/SemaExceptionSpec.cpp 
b/clang/lib/Sema/SemaExceptionSpec.cpp
index 7b08a066d3cc1b2..13f632b91053a97 100644
--- a/clang/lib/Sema/SemaExceptionSpec.cpp
+++ b/clang/lib/Sema/SemaExceptionSpec.cpp
@@ -1286,7 +1286,6 @@ CanThrowResult Sema::canThrow(const Stmt *S) {
   case Expr::ConvertVectorExprClass:
   case Expr::VAArgExprClass:
   case Expr::CXXParenListInitExprClass:
-  case Expr::ResolvedUnexpandedPackExprClass:
     return canSubStmtsThrow(*this, S);
 
   case Expr::CompoundLiteralExprClass:
diff --git a/clang/lib/Sema/SemaTemplateInstantiate.cpp 
b/clang/lib/Sema/SemaTemplateInstantiate.cpp
index 8eeafee1f3f522a..aeafd7a6e9276a3 100644
--- a/clang/lib/Sema/SemaTemplateInstantiate.cpp
+++ b/clang/lib/Sema/SemaTemplateInstantiate.cpp
@@ -1584,10 +1584,6 @@ namespace {
     /// pack.
     ExprResult TransformFunctionParmPackExpr(FunctionParmPackExpr *E);
 
-    // Transform a ResolvedUnexpandedPackExpr
-    ExprResult
-    TransformResolvedUnexpandedPackExpr(ResolvedUnexpandedPackExpr *E);
-
     QualType TransformFunctionProtoType(TypeLocBuilder &TLB,
                                         FunctionProtoTypeLoc TL) {
       // Call the base version; it will forward to our overridden version 
below.
@@ -2644,19 +2640,6 @@ 
TemplateInstantiator::TransformTemplateTypeParmType(TypeLocBuilder &TLB,
   return Result;
 }
 
-ExprResult TemplateInstantiator::TransformResolvedUnexpandedPackExpr(
-    ResolvedUnexpandedPackExpr *E) {
-  if (getSema().ArgumentPackSubstitutionIndex != -1) {
-    assert(static_cast<unsigned>(getSema().ArgumentPackSubstitutionIndex) <
-               E->getNumExprs() &&
-           "ArgumentPackSubstitutionIndex is out of range");
-    return TransformExpr(
-        E->getExpansion(getSema().ArgumentPackSubstitutionIndex));
-  }
-
-  return inherited::TransformResolvedUnexpandedPackExpr(E);
-}
-
 QualType TemplateInstantiator::TransformSubstTemplateTypeParmPackType(
     TypeLocBuilder &TLB, SubstTemplateTypeParmPackTypeLoc TL,
     bool SuppressObjCLifetime) {
diff --git a/clang/lib/Sema/SemaTemplateVariadic.cpp 
b/clang/lib/Sema/SemaTemplateVariadic.cpp
index b2088ae8394ab3c..fad00f7648848bb 100644
--- a/clang/lib/Sema/SemaTemplateVariadic.cpp
+++ b/clang/lib/Sema/SemaTemplateVariadic.cpp
@@ -64,10 +64,6 @@ class CollectUnexpandedParameterPacksVisitor
         Unexpanded.push_back({T, Loc});
     }
 
-    void addUnexpanded(ResolvedUnexpandedPackExpr *E) {
-      Unexpanded.push_back({E, E->getBeginLoc()});
-    }
-
   public:
     explicit CollectUnexpandedParameterPacksVisitor(
         SmallVectorImpl<UnexpandedParameterPack> &Unexpanded)
@@ -110,12 +106,6 @@ class CollectUnexpandedParameterPacksVisitor
       return true;
     }
 
-    bool
-    VisitResolvedUnexpandedPackExpr(ResolvedUnexpandedPackExpr *E) override {
-      addUnexpanded(E);
-      return true;
-    }
-
     /// Record occurrences of template template parameter packs.
     bool TraverseTemplateName(TemplateName Template) override {
       if (auto *TTP = dyn_cast_or_null<TemplateTemplateParmDecl>(
@@ -1193,12 +1183,8 @@ ExprResult Sema::ActOnSizeofParameterPackExpr(Scope *S,
 
   MarkAnyDeclReferenced(OpLoc, ParameterPack, true);
 
-  std::optional<unsigned> Length;
-  if (auto *RP = ResolvedUnexpandedPackExpr::getFromDecl(ParameterPack))
-    Length = RP->getNumExprs();
-
   return SizeOfPackExpr::Create(Context, OpLoc, ParameterPack, NameLoc,
-                                RParenLoc, Length);
+                                RParenLoc);
 }
 
 static bool isParameterPack(Expr *PackExpression) {
diff --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h
index 808b56448e1ea6e..20a5314cad461c0 100644
--- a/clang/lib/Sema/TreeTransform.h
+++ b/clang/lib/Sema/TreeTransform.h
@@ -3680,13 +3680,6 @@ class TreeTransform {
                                            FullySubstituted);
   }
 
-  ExprResult RebuildResolvedUnexpandedPackExpr(SourceLocation BeginLoc,
-                                               QualType T,
-                                               ArrayRef<Expr *> Exprs) {
-    return ResolvedUnexpandedPackExpr::Create(SemaRef.Context, BeginLoc, T,
-                                              Exprs);
-  }
-
   /// Build a new expression representing a call to a source location
   ///  builtin.
   ///
@@ -16133,24 +16126,6 @@ 
TreeTransform<Derived>::TransformFunctionParmPackExpr(FunctionParmPackExpr *E) {
   return E;
 }
 
-template <typename Derived>
-ExprResult TreeTransform<Derived>::TransformResolvedUnexpandedPackExpr(
-    ResolvedUnexpandedPackExpr *E) {
-  bool ArgumentChanged = false;
-  SmallVector<Expr *, 12> NewExprs;
-  if (TransformExprs(E->getExprs().begin(), E->getNumExprs(),
-                     /*IsCall=*/false, NewExprs, &ArgumentChanged))
-    return ExprError();
-
-  if (!AlwaysRebuild() && !ArgumentChanged)
-    return E;
-
-  // NOTE: The type is just a superficial PackExpansionType
-  //       that needs no substitution.
-  return RebuildResolvedUnexpandedPackExpr(E->getBeginLoc(), E->getType(),
-                                           NewExprs);
-}
-
 template<typename Derived>
 ExprResult
 TreeTransform<Derived>::TransformMaterializeTemporaryExpr(
diff --git a/clang/lib/Serialization/ASTReaderStmt.cpp 
b/clang/lib/Serialization/ASTReaderStmt.cpp
index 3ca4ee312828416..beb439e3acfef71 100644
--- a/clang/lib/Serialization/ASTReaderStmt.cpp
+++ b/clang/lib/Serialization/ASTReaderStmt.cpp
@@ -2208,16 +2208,6 @@ void 
ASTStmtReader::VisitPackIndexingExpr(PackIndexingExpr *E) {
     Exprs[I] = Record.readExpr();
 }
 
-void ASTStmtReader::VisitResolvedUnexpandedPackExpr(
-    ResolvedUnexpandedPackExpr *E) {
-  VisitExpr(E);
-  E->NumExprs = Record.readInt();
-  E->BeginLoc = readSourceLocation();
-  auto **Exprs = E->getTrailingObjects<Expr *>();
-  for (unsigned I = 0; I < E->NumExprs; ++I)
-    Exprs[I] = Record.readExpr();
-}
-
 void ASTStmtReader::VisitSubstNonTypeTemplateParmExpr(
                                               SubstNonTypeTemplateParmExpr *E) 
{
   VisitExpr(E);
@@ -4301,12 +4291,6 @@ Stmt *ASTReader::ReadStmtFromStream(ModuleFile &F) {
           /*TransformedExprs=*/Record[ASTStmtReader::NumExprFields]);
       break;
 
-    case EXPR_RESOLVED_UNEXPANDED_PACK:
-      S = ResolvedUnexpandedPackExpr::CreateDeserialized(
-          Context,
-          /*NumExprs=*/Record[ASTStmtReader::NumExprFields]);
-      break;
-
     case EXPR_SUBST_NON_TYPE_TEMPLATE_PARM:
       S = new (Context) SubstNonTypeTemplateParmExpr(Empty);
       break;
diff --git a/clang/lib/Serialization/ASTWriter.cpp 
b/clang/lib/Serialization/ASTWriter.cpp
index ef8ee5bc94d0ec6..9e70183758870c2 100644
--- a/clang/lib/Serialization/ASTWriter.cpp
+++ b/clang/lib/Serialization/ASTWriter.cpp
@@ -874,7 +874,6 @@ static void AddStmtsExprs(llvm::BitstreamWriter &Stream,
   RECORD(EXPR_PACK_EXPANSION);
   RECORD(EXPR_SIZEOF_PACK);
   RECORD(EXPR_PACK_INDEXING);
-  RECORD(EXPR_RESOLVED_UNEXPANDED_PACK);
   RECORD(EXPR_SUBST_NON_TYPE_TEMPLATE_PARM);
   RECORD(EXPR_SUBST_NON_TYPE_TEMPLATE_PARM_PACK);
   RECORD(EXPR_FUNCTION_PARM_PACK);
diff --git a/clang/lib/Serialization/ASTWriterStmt.cpp 
b/clang/lib/Serialization/ASTWriterStmt.cpp
index e6701c586e022e7..2daf8393b1819a6 100644
--- a/clang/lib/Serialization/ASTWriterStmt.cpp
+++ b/clang/lib/Serialization/ASTWriterStmt.cpp
@@ -2210,16 +2210,6 @@ void 
ASTStmtWriter::VisitPackIndexingExpr(PackIndexingExpr *E) {
   Code = serialization::EXPR_PACK_INDEXING;
 }
 
-void ASTStmtWriter::VisitResolvedUnexpandedPackExpr(
-    ResolvedUnexpandedPackExpr *E) {
-  VisitExpr(E);
-  Record.push_back(E->getNumExprs());
-  Record.AddSourceLocation(E->getBeginLoc());
-  for (Expr *Sub : E->getExprs())
-    Record.AddStmt(Sub);
-  Code = serialization::EXPR_RESOLVED_UNEXPANDED_PACK;
-}
-
 void ASTStmtWriter::VisitSubstNonTypeTemplateParmExpr(
                                               SubstNonTypeTemplateParmExpr *E) 
{
   VisitExpr(E);
diff --git a/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp 
b/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp
index 5851f7d5eb024c4..6eeb3d58881ae73 100644
--- a/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp
+++ b/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp
@@ -1743,7 +1743,6 @@ void ExprEngine::Visit(const Stmt *S, ExplodedNode *Pred,
     case Stmt::DependentCoawaitExprClass:
     case Stmt::CoreturnStmtClass:
     case Stmt::CoyieldExprClass:
-    case Stmt::ResolvedUnexpandedPackExprClass:
     case Stmt::SEHTryStmtClass:
     case Stmt::SEHExceptStmtClass:
     case Stmt::SEHLeaveStmtClass:
diff --git a/clang/tools/libclang/CXCursor.cpp 
b/clang/tools/libclang/CXCursor.cpp
index 60c740311e940b6..b9f0b089e41b006 100644
--- a/clang/tools/libclang/CXCursor.cpp
+++ b/clang/tools/libclang/CXCursor.cpp
@@ -338,7 +338,6 @@ CXCursor cxcursor::MakeCXCursor(const Stmt *S, const Decl 
*Parent,
   case Stmt::EmbedExprClass:
   case Stmt::HLSLOutArgExprClass:
   case Stmt::OpenACCAsteriskSizeExprClass:
-  case Stmt::ResolvedUnexpandedPackExprClass:
     K = CXCursor_UnexposedExpr;
     break;
 

>From f6a77d47361ac43c8bb02a031bbbfbe4299030d0 Mon Sep 17 00:00:00 2001
From: Jason Rice <ricejas...@gmail.com>
Date: Tue, 4 Feb 2025 03:54:49 -0800
Subject: [PATCH 3/3] [Clang][P1061] Remove unnecessary autos

---
 clang/include/clang/AST/DeclCXX.h              | 2 +-
 clang/lib/Sema/SemaTemplateInstantiateDecl.cpp | 8 +++++---
 2 files changed, 6 insertions(+), 4 deletions(-)

diff --git a/clang/include/clang/AST/DeclCXX.h 
b/clang/include/clang/AST/DeclCXX.h
index 1c630d616903550..266b93a64a39087 100644
--- a/clang/include/clang/AST/DeclCXX.h
+++ b/clang/include/clang/AST/DeclCXX.h
@@ -4279,7 +4279,7 @@ class DecompositionDecl final
     llvm::ArrayRef<BindingDecl *> PackBindings;
 
     // Split the bindings into subranges split by the pack.
-    auto BeforePackBindings = Bindings.take_until(
+    llvm::ArrayRef<BindingDecl *> BeforePackBindings = Bindings.take_until(
         [](BindingDecl *BD) { return BD->isParameterPack(); });
 
     Bindings = Bindings.drop_front(BeforePackBindings.size());
diff --git a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp 
b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
index 5081a37e7c0f814..2152d3e650573c0 100644
--- a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
+++ b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
@@ -1200,10 +1200,12 @@ Decl 
*TemplateDeclInstantiator::VisitDecompositionDecl(DecompositionDecl *D) {
   if (OldBindingPack) {
     // Mark the bindings in the pack as instantiated.
     auto Bindings = NewDD->bindings();
-    auto NewBindingPack = *llvm::find_if(
+    BindingDecl *NewBindingPack = *llvm::find_if(
         Bindings, [](BindingDecl *D) -> bool { return D->isParameterPack(); });
-    auto OldDecls = OldBindingPack->getBindingPackDecls();
-    auto NewDecls = NewBindingPack->getBindingPackDecls();
+    llvm::ArrayRef<BindingDecl *> OldDecls =
+        OldBindingPack->getBindingPackDecls();
+    llvm::ArrayRef<BindingDecl *> NewDecls =
+        NewBindingPack->getBindingPackDecls();
     assert(OldDecls.size() == NewDecls.size());
     for (unsigned I = 0; I < OldDecls.size(); I++)
       SemaRef.CurrentInstantiationScope->InstantiatedLocal(OldDecls[I],

_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to