[clang] [Clang][P1061] Add stuctured binding packs (PR #121417)
Jason Rice via cfe-commits
cfe-commits at lists.llvm.org
Mon Jan 6 12:49:01 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:
By contiguous, I mean that we would not nest the BindingDecls. The trade off is the extra references needed would bloat the size of DecompositionDecl. Perhaps that is a concern if there are a ton of them in a program which is why I abandoned the idea. The problem here is that the bindings are created before the init expression so we do not know how many bindings there will be up front in the case of packs. Hence the weird BindingInitWalker stuff as well as the DecompositionDecl::Visit* functions that I added. If you want me to remove those, it will require deferring the allocation of the BindingDecls.
https://github.com/llvm/llvm-project/pull/121417
More information about the cfe-commits
mailing list