[clang] [Clang][P1061] Add stuctured binding packs (PR #121417)
via cfe-commits
cfe-commits at lists.llvm.org
Sun Jan 5 06:53:50 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
----------------
cor3ntin wrote:
TrailingObjects are contiguous.
I am indeed wondering if we lose anything by creating Ns binding here, instead of one binding that wraps a `ResolvedUnexpandedPackExpr` that wraps a reference to a nested BindingDecl
(we would indeed most certainly have to track the pattern somewhere if we go that route)
I'm still thinking about it, maybe @zyn0217 and @erichkeane have opinionsd
https://github.com/llvm/llvm-project/pull/121417
More information about the cfe-commits
mailing list