@@ -4175,31 +4175,32 @@ class BindingDecl : public ValueDecl {
4175
4175
// / binding).
4176
4176
Expr *Binding = nullptr ;
4177
4177
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) {}
4180
4181
4181
4182
void anchor () override ;
4182
4183
4183
4184
public:
4184
4185
friend class ASTDeclReader ;
4185
4186
4186
4187
static BindingDecl *Create (ASTContext &C, DeclContext *DC,
4187
- SourceLocation IdLoc, IdentifierInfo *Id);
4188
+ SourceLocation IdLoc, IdentifierInfo *Id,
4189
+ QualType T);
4188
4190
static BindingDecl *CreateDeserialized (ASTContext &C, GlobalDeclID ID);
4189
4191
4190
4192
// / Get the expression to which this declaration is bound. This may be null
4191
4193
// / in two different cases: while parsing the initializer for the
4192
4194
// / decomposition declaration, and when the initializer is type-dependent.
4193
4195
Expr *getBinding () const { return Binding; }
4194
4196
4197
+ // Get the array of Exprs when the binding represents a pack.
4198
+ llvm::ArrayRef<Expr *> getBindingPackExprs () const ;
4199
+
4195
4200
// / Get the decomposition declaration that this binding represents a
4196
4201
// / decomposition of.
4197
4202
ValueDecl *getDecomposedDecl () const { return Decomp; }
4198
4203
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
-
4203
4204
// / Set the binding for this BindingDecl, along with its declared type (which
4204
4205
// / should be a possibly-cv-qualified form of the type of the binding, or a
4205
4206
// / reference to such a type).
@@ -4211,6 +4212,10 @@ class BindingDecl : public ValueDecl {
4211
4212
// / Set the decomposed variable for this BindingDecl.
4212
4213
void setDecomposedDecl (ValueDecl *Decomposed) { Decomp = Decomposed; }
4213
4214
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
+
4214
4219
static bool classof (const Decl *D) { return classofKind (D->getKind ()); }
4215
4220
static bool classofKind (Kind K) { return K == Decl::Binding; }
4216
4221
};
@@ -4238,8 +4243,16 @@ class DecompositionDecl final
4238
4243
NumBindings (Bindings.size()) {
4239
4244
std::uninitialized_copy (Bindings.begin (), Bindings.end (),
4240
4245
getTrailingObjects<BindingDecl *>());
4241
- for (auto *B : Bindings)
4246
+ for (auto *B : Bindings) {
4242
4247
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
+ }
4243
4256
}
4244
4257
4245
4258
void anchor () override ;
@@ -4257,8 +4270,33 @@ class DecompositionDecl final
4257
4270
static DecompositionDecl *CreateDeserialized (ASTContext &C, GlobalDeclID ID,
4258
4271
unsigned NumBindings);
4259
4272
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));
4262
4300
}
4263
4301
4264
4302
void printName (raw_ostream &OS, const PrintingPolicy &Policy) const override ;
0 commit comments