Skip to content

Commit beca517

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

File tree

1 file changed

+35
-3
lines changed

1 file changed

+35
-3
lines changed

lib/SIL/IR/TypeLowering.cpp

Lines changed: 35 additions & 3 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())
@@ -4255,6 +4279,11 @@ TypeConverter::getLoweredLocalCaptures(SILDeclRef fn) {
42554279
SmallVector<CapturedValue, 4> localCaptures;
42564280
captureInfo.getLocalCaptures(localCaptures);
42574281
for (auto capture : localCaptures) {
4282+
if (capture.isPackElement()) {
4283+
recordCapture(capture);
4284+
continue;
4285+
}
4286+
42584287
// If the capture is of another local function, grab its transitive
42594288
// captures instead.
42604289
if (auto capturedFn = getAnyFunctionRefFromCapture(capture)) {
@@ -4449,7 +4478,10 @@ TypeConverter::getLoweredLocalCaptures(SILDeclRef fn) {
44494478
collectConstantCaptures(fn);
44504479

44514480
SmallVector<CapturedValue, 4> resultingCaptures;
4452-
for (auto capturePair : captures) {
4481+
for (auto capturePair : varCaptures) {
4482+
resultingCaptures.push_back(capturePair.second);
4483+
}
4484+
for (auto capturePair : packElementCaptures) {
44534485
resultingCaptures.push_back(capturePair.second);
44544486
}
44554487

@@ -4468,7 +4500,7 @@ TypeConverter::getLoweredLocalCaptures(SILDeclRef fn) {
44684500
resultingCaptures.push_back(*selfCapture);
44694501
}
44704502

4471-
// Cache the uniqued set of transitive captures.
4503+
// Cache the result.
44724504
CaptureInfo info(Context, resultingCaptures,
44734505
capturesDynamicSelf, capturesOpaqueValue,
44744506
capturesGenericParams, genericEnv.getArrayRef());

0 commit comments

Comments
 (0)