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

Jason Rice via cfe-commits cfe-commits at lists.llvm.org
Sat Jan 18 08:47:57 PST 2025


================
@@ -951,28 +959,124 @@ Sema::ActOnDecompositionDeclarator(Scope *S, Declarator &D,
   return New;
 }
 
+// CheckBindingsCount
+//  - Checks the arity of the structured bindings
+//  - Creates the resolved pack expr if there is
+//    one
+static 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) {
+    // 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);
+    BD->setBinding(PackType,
+                   ResolvedUnexpandedPackExpr::Create(
+                       S.Context, DD->getBeginLoc(), DecompType, PackSize));
----------------
ricejasonf wrote:

What is IF? (initializer first?)

I have gone down this rabbit hole a couple of times. The initializer for a variable is built differently based on the context. For instance, range based for loops defer building the initializer (for whatever reason idk,) but it all happens in the call to VisitVarDecl which builds the new DecompositionDecl. I do not know what it would take to rip all of that out of there.

See https://github.com/ricejasonf/llvm-project/blob/ricejasonf/p1061r9/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp#L1193
and
https://github.com/ricejasonf/llvm-project/blob/ricejasonf/p1061r9/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp#L1224

The above attempt was building the initializer just to get the number of bindings and discarding it which felt like a waste.

Forgive me, IF I am misunderstanding what you are saying here. :rofl: 

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


More information about the cfe-commits mailing list