[clang] [Clang][P1061] Add stuctured binding packs (PR #121417)

Jason Rice via cfe-commits cfe-commits at lists.llvm.org
Fri Jan 3 15:03:45 PST 2025


================
@@ -951,28 +959,130 @@ Sema::ActOnDecompositionDeclarator(Scope *S, Declarator &D,
   return New;
 }
 
+namespace {
+// CheckBindingsCount
+//  - Checks the arity of the structured bindings
+//  - Creates the resolved pack expr if there is
+//    one
+bool CheckBindingsCount(Sema &S, DecompositionDecl *DD, QualType DecompType,
+                        ArrayRef<BindingDecl *> Bindings,
+                        unsigned MemberCount) {
+  auto BindingWithPackItr =
+      std::find_if(Bindings.begin(), Bindings.end(),
+                   [](BindingDecl *D) -> bool { return D->isParameterPack(); });
+  bool HasPack = BindingWithPackItr != Bindings.end();
+  bool IsValid;
+  if (!HasPack) {
+    IsValid = Bindings.size() == MemberCount;
+  } else {
+    // there may not be more members than non-pack bindings
+    IsValid = MemberCount >= Bindings.size() - 1;
+  }
+
+  if (IsValid && HasPack) {
+    TemplateTypeParmDecl *DummyTemplateParam = TemplateTypeParmDecl::Create(
+        S.Context, S.Context.getTranslationUnitDecl(),
+        /*KeyLoc*/ SourceLocation(), /*NameLoc*/ SourceLocation(),
+        /*TemplateDepth*/ 0, /*AutoParameterPosition*/ 0,
+        /*Identifier*/ nullptr, false, /*IsParameterPack*/ true);
+
+    // create the pack expr and assign it to the binding
+    unsigned PackSize = MemberCount - Bindings.size() + 1;
+    QualType PackType = S.Context.getPackExpansionType(
+        QualType(DummyTemplateParam->getTypeForDecl(), 0), PackSize);
+    (*BindingWithPackItr)
+        ->setBinding(PackType,
+                     ResolvedUnexpandedPackExpr::Create(
+                         S.Context, DD->getBeginLoc(), DecompType, PackSize));
+  }
+
+  if (IsValid)
+    return false;
+
+  S.Diag(DD->getLocation(), diag::err_decomp_decl_wrong_number_bindings)
+      << DecompType << (unsigned)Bindings.size() << MemberCount << MemberCount
+      << (MemberCount < Bindings.size());
+  return true;
+}
+
+// BindingInitWalker
+//  - This implements a forward iterating flattened view
+//    of structured bindings that may have a nested pack.
+//    It allows the user to set the init expr for either the
+//    BindingDecl or its ResolvedUnexpandedPackExpr
----------------
ricejasonf wrote:

Do you mean that we should not have BindingDecls as TrailingObjects for the DecompositionDecl? I started doing something like this and it did mean that we would have a contiguous array of bindings. We would have to store a pointer to the BindingDecl that represents a pack to transform it. (I kind of started to do this and then abandoned it.)

https://github.com/llvm/llvm-project/pull/121417


More information about the cfe-commits mailing list