================ @@ -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