@@ -4175,31 +4175,32 @@ class BindingDecl : public ValueDecl {
41754175 // / binding).
41764176 Expr *Binding = nullptr ;
41774177
4178- BindingDecl (DeclContext *DC, SourceLocation IdLoc, IdentifierInfo *Id)
4179- : ValueDecl(Decl::Binding, DC, IdLoc, Id, QualType()) {}
4178+ BindingDecl (DeclContext *DC, SourceLocation IdLoc, IdentifierInfo *Id,
4179+ QualType T)
4180+ : ValueDecl(Decl::Binding, DC, IdLoc, Id, T) {}
41804181
41814182 void anchor () override ;
41824183
41834184public:
41844185 friend class ASTDeclReader ;
41854186
41864187 static BindingDecl *Create (ASTContext &C, DeclContext *DC,
4187- SourceLocation IdLoc, IdentifierInfo *Id);
4188+ SourceLocation IdLoc, IdentifierInfo *Id,
4189+ QualType T);
41884190 static BindingDecl *CreateDeserialized (ASTContext &C, GlobalDeclID ID);
41894191
41904192 // / Get the expression to which this declaration is bound. This may be null
41914193 // / in two different cases: while parsing the initializer for the
41924194 // / decomposition declaration, and when the initializer is type-dependent.
41934195 Expr *getBinding () const { return Binding; }
41944196
4197+ // Get the array of Exprs when the binding represents a pack.
4198+ llvm::ArrayRef<Expr *> getBindingPackExprs () const ;
4199+
41954200 // / Get the decomposition declaration that this binding represents a
41964201 // / decomposition of.
41974202 ValueDecl *getDecomposedDecl () const { return Decomp; }
41984203
4199- // / Get the variable (if any) that holds the value of evaluating the binding.
4200- // / Only present for user-defined bindings for tuple-like types.
4201- VarDecl *getHoldingVar () const ;
4202-
42034204 // / Set the binding for this BindingDecl, along with its declared type (which
42044205 // / should be a possibly-cv-qualified form of the type of the binding, or a
42054206 // / reference to such a type).
@@ -4211,6 +4212,10 @@ class BindingDecl : public ValueDecl {
42114212 // / Set the decomposed variable for this BindingDecl.
42124213 void setDecomposedDecl (ValueDecl *Decomposed) { Decomp = Decomposed; }
42134214
4215+ // / Get the variable (if any) that holds the value of evaluating the binding.
4216+ // / Only present for user-defined bindings for tuple-like types.
4217+ VarDecl *getHoldingVar () const ;
4218+
42144219 static bool classof (const Decl *D) { return classofKind (D->getKind ()); }
42154220 static bool classofKind (Kind K) { return K == Decl::Binding; }
42164221};
@@ -4238,8 +4243,16 @@ class DecompositionDecl final
42384243 NumBindings (Bindings.size()) {
42394244 std::uninitialized_copy (Bindings.begin (), Bindings.end (),
42404245 getTrailingObjects<BindingDecl *>());
4241- for (auto *B : Bindings)
4246+ for (auto *B : Bindings) {
42424247 B->setDecomposedDecl (this );
4248+ if (B->isParameterPack () && B->getBinding ()) {
4249+ for (Expr *E : B->getBindingPackExprs ()) {
4250+ auto *DRE = cast<DeclRefExpr>(E);
4251+ auto *NestedB = cast<BindingDecl>(DRE->getDecl ());
4252+ NestedB->setDecomposedDecl (this );
4253+ }
4254+ }
4255+ }
42434256 }
42444257
42454258 void anchor () override ;
@@ -4257,8 +4270,33 @@ class DecompositionDecl final
42574270 static DecompositionDecl *CreateDeserialized (ASTContext &C, GlobalDeclID ID,
42584271 unsigned NumBindings);
42594272
4260- ArrayRef<BindingDecl *> bindings () const {
4261- return llvm::ArrayRef (getTrailingObjects<BindingDecl *>(), NumBindings);
4273+ // Provide the range of bindings which may have a nested pack.
4274+ llvm::ArrayRef<BindingDecl *> bindings () const {
4275+ return {getTrailingObjects<BindingDecl *>(), NumBindings};
4276+ }
4277+
4278+ // Provide a flattened range to visit each binding.
4279+ auto flat_bindings () const {
4280+ llvm::ArrayRef<BindingDecl *> Bindings = bindings ();
4281+ llvm::ArrayRef<Expr *> PackExprs;
4282+
4283+ // Split the bindings into subranges split by the pack.
4284+ auto S1 = Bindings.take_until (
4285+ [](BindingDecl *BD) { return BD->isParameterPack (); });
4286+
4287+ Bindings = Bindings.drop_front (S1.size ());
4288+ if (!Bindings.empty ()) {
4289+ PackExprs = Bindings.front ()->getBindingPackExprs ();
4290+ Bindings = Bindings.drop_front ();
4291+ }
4292+
4293+ auto S2 = llvm::map_range (PackExprs, [](Expr *E) {
4294+ auto *DRE = cast<DeclRefExpr>(E);
4295+ return cast<BindingDecl>(DRE->getDecl ());
4296+ });
4297+
4298+ return llvm::concat<BindingDecl *>(std::move (S1), std::move (S2),
4299+ std::move (Bindings));
42624300 }
42634301
42644302 void printName (raw_ostream &OS, const PrintingPolicy &Policy) const override ;
0 commit comments