Skip to content

Commit c0e15fc

Browse files
committed
SIL: Update getLoweredLocalCaptures() for PackElementExpr captures
1 parent 8679d34 commit c0e15fc

File tree

1 file changed

+40
-13
lines changed

1 file changed

+40
-13
lines changed

lib/SIL/IR/TypeLowering.cpp

Lines changed: 40 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -4219,7 +4219,10 @@ TypeConverter::getLoweredLocalCaptures(SILDeclRef fn) {
42194219

42204220
// Recursively collect transitive captures from captured local functions.
42214221
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;
42234226

42244227
// If there is a capture of 'self' with dynamic 'Self' type, it goes last so
42254228
// that IRGen can pass dynamic 'Self' metadata.
@@ -4236,6 +4239,27 @@ TypeConverter::getLoweredLocalCaptures(SILDeclRef fn) {
42364239
std::function<void (AnyFunctionRef)> collectFunctionCaptures;
42374240
std::function<void (SILDeclRef)> collectConstantCaptures;
42384241

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+
42394263
collectCaptures = [&](CaptureInfo captureInfo, DeclContext *dc) {
42404264
assert(captureInfo.hasBeenComputed());
42414265
if (captureInfo.hasGenericParamCaptures())
@@ -4252,9 +4276,15 @@ TypeConverter::getLoweredLocalCaptures(SILDeclRef fn) {
42524276
genericEnv.insert(env);
42534277
}
42544278

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+
42584288
// If the capture is of another local function, grab its transitive
42594289
// captures instead.
42604290
if (auto capturedFn = getAnyFunctionRefFromCapture(capture)) {
@@ -4386,13 +4416,7 @@ TypeConverter::getLoweredLocalCaptures(SILDeclRef fn) {
43864416
}
43874417

43884418
// 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);
43964420
}
43974421
};
43984422

@@ -4449,7 +4473,10 @@ TypeConverter::getLoweredLocalCaptures(SILDeclRef fn) {
44494473
collectConstantCaptures(fn);
44504474

44514475
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) {
44534480
resultingCaptures.push_back(capturePair.second);
44544481
}
44554482

@@ -4468,7 +4495,7 @@ TypeConverter::getLoweredLocalCaptures(SILDeclRef fn) {
44684495
resultingCaptures.push_back(*selfCapture);
44694496
}
44704497

4471-
// Cache the uniqued set of transitive captures.
4498+
// Cache the result.
44724499
CaptureInfo info(Context, resultingCaptures,
44734500
capturesDynamicSelf, capturesOpaqueValue,
44744501
capturesGenericParams, genericEnv.getArrayRef());

0 commit comments

Comments
 (0)