@@ -4219,7 +4219,10 @@ TypeConverter::getLoweredLocalCaptures(SILDeclRef fn) {
4219
4219
4220
4220
// Recursively collect transitive captures from captured local functions.
4221
4221
llvm::DenseSet<AnyFunctionRef> visitedFunctions;
4222
- llvm::MapVector<ValueDecl*,CapturedValue> captures;
4222
+
4223
+ // FIXME: CapturedValue should just be a hash key
4224
+ llvm::MapVector<VarDecl *, CapturedValue> varCaptures;
4225
+ llvm::MapVector<PackElementExpr *, CapturedValue> packElementCaptures;
4223
4226
4224
4227
// If there is a capture of 'self' with dynamic 'Self' type, it goes last so
4225
4228
// that IRGen can pass dynamic 'Self' metadata.
@@ -4236,6 +4239,27 @@ TypeConverter::getLoweredLocalCaptures(SILDeclRef fn) {
4236
4239
std::function<void (AnyFunctionRef)> collectFunctionCaptures;
4237
4240
std::function<void (SILDeclRef)> collectConstantCaptures;
4238
4241
4242
+ auto recordCapture = [&](CapturedValue capture) {
4243
+ if (auto *expr = capture.getPackElement ()) {
4244
+ auto existing = packElementCaptures.find (expr);
4245
+ if (existing != packElementCaptures.end ()) {
4246
+ existing->second = existing->second .mergeFlags (capture.getFlags ());
4247
+ } else {
4248
+ packElementCaptures.insert (std::pair<PackElementExpr *, CapturedValue>(
4249
+ expr, capture));
4250
+ }
4251
+ } else {
4252
+ VarDecl *value = cast<VarDecl>(capture.getDecl ());
4253
+ auto existing = varCaptures.find (value);
4254
+ if (existing != varCaptures.end ()) {
4255
+ existing->second = existing->second .mergeFlags (capture.getFlags ());
4256
+ } else {
4257
+ varCaptures.insert (std::pair<VarDecl *, CapturedValue>(
4258
+ value, capture));
4259
+ }
4260
+ }
4261
+ };
4262
+
4239
4263
collectCaptures = [&](CaptureInfo captureInfo, DeclContext *dc) {
4240
4264
assert (captureInfo.hasBeenComputed ());
4241
4265
if (captureInfo.hasGenericParamCaptures ())
@@ -4252,9 +4276,15 @@ TypeConverter::getLoweredLocalCaptures(SILDeclRef fn) {
4252
4276
genericEnv.insert (env);
4253
4277
}
4254
4278
4255
- SmallVector<CapturedValue, 4 > localCaptures;
4256
- captureInfo.getLocalCaptures (localCaptures);
4257
- for (auto capture : localCaptures) {
4279
+ for (auto capture : captureInfo.getCaptures ()) {
4280
+ if (capture.isPackElement ()) {
4281
+ recordCapture (capture);
4282
+ continue ;
4283
+ }
4284
+
4285
+ if (!capture.isLocalCapture ())
4286
+ continue ;
4287
+
4258
4288
// If the capture is of another local function, grab its transitive
4259
4289
// captures instead.
4260
4290
if (auto capturedFn = getAnyFunctionRefFromCapture (capture)) {
@@ -4386,13 +4416,7 @@ TypeConverter::getLoweredLocalCaptures(SILDeclRef fn) {
4386
4416
}
4387
4417
4388
4418
// Collect non-function captures.
4389
- ValueDecl *value = capture.getDecl ();
4390
- auto existing = captures.find (value);
4391
- if (existing != captures.end ()) {
4392
- existing->second = existing->second .mergeFlags (capture);
4393
- } else {
4394
- captures.insert (std::pair<ValueDecl *, CapturedValue>(value, capture));
4395
- }
4419
+ recordCapture (capture);
4396
4420
}
4397
4421
};
4398
4422
@@ -4449,7 +4473,10 @@ TypeConverter::getLoweredLocalCaptures(SILDeclRef fn) {
4449
4473
collectConstantCaptures (fn);
4450
4474
4451
4475
SmallVector<CapturedValue, 4 > resultingCaptures;
4452
- for (auto capturePair : captures) {
4476
+ for (auto capturePair : varCaptures) {
4477
+ resultingCaptures.push_back (capturePair.second );
4478
+ }
4479
+ for (auto capturePair : packElementCaptures) {
4453
4480
resultingCaptures.push_back (capturePair.second );
4454
4481
}
4455
4482
@@ -4468,7 +4495,7 @@ TypeConverter::getLoweredLocalCaptures(SILDeclRef fn) {
4468
4495
resultingCaptures.push_back (*selfCapture);
4469
4496
}
4470
4497
4471
- // Cache the uniqued set of transitive captures .
4498
+ // Cache the result .
4472
4499
CaptureInfo info (Context, resultingCaptures,
4473
4500
capturesDynamicSelf, capturesOpaqueValue,
4474
4501
capturesGenericParams, genericEnv.getArrayRef ());
0 commit comments