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

Reply via email to