Skip to content

Commit 9c2bc1f

Browse files
committed
SILGen: Update for PackElementExpr captures
1 parent a6a10a7 commit 9c2bc1f

File tree

4 files changed

+58
-9
lines changed

4 files changed

+58
-9
lines changed

lib/SILGen/SILGenExpr.cpp

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1667,6 +1667,14 @@ RValueEmitter::visitPackExpansionExpr(PackExpansionExpr *E,
16671667

16681668
RValue
16691669
RValueEmitter::visitPackElementExpr(PackElementExpr *E, SGFContext C) {
1670+
// If this is a captured pack element reference, just emit the parameter value
1671+
// that was passed to the closure.
1672+
auto found = SGF.OpaqueValues.find(E);
1673+
if (found != SGF.OpaqueValues.end())
1674+
return RValue(SGF, E, SGF.manageOpaqueValue(found->second, E, C));
1675+
1676+
// Otherwise, we're going to project the address of an element from the pack
1677+
// itself.
16701678
FormalEvaluationScope scope(SGF);
16711679

16721680
LValue lv = SGF.emitLValue(E, SGFAccessKind::OwnedObjectRead);
@@ -5972,9 +5980,9 @@ RValue RValueEmitter::visitMakeTemporarilyEscapableExpr(
59725980
}
59735981

59745982
RValue RValueEmitter::visitOpaqueValueExpr(OpaqueValueExpr *E, SGFContext C) {
5975-
assert(SGF.OpaqueValues.count(E) && "Didn't bind OpaqueValueExpr");
5976-
auto value = SGF.OpaqueValues[E];
5977-
return RValue(SGF, E, SGF.manageOpaqueValue(value, E, C));
5983+
auto found = SGF.OpaqueValues.find(E);
5984+
assert(found != SGF.OpaqueValues.end());
5985+
return RValue(SGF, E, SGF.manageOpaqueValue(found->second, E, C));
59785986
}
59795987

59805988
RValue RValueEmitter::visitPropertyWrapperValuePlaceholderExpr(

lib/SILGen/SILGenFunction.cpp

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -569,10 +569,9 @@ void SILGenFunction::emitCaptures(SILLocation loc,
569569
continue;
570570
}
571571

572-
if (capture.isOpaqueValue()) {
573-
OpaqueValueExpr *opaqueValue = capture.getOpaqueValue();
572+
if (capture.isOpaqueValue() || capture.isPackElement()) {
574573
capturedArgs.push_back(
575-
emitRValueAsSingleValue(opaqueValue).ensurePlusOne(*this, loc));
574+
emitRValueAsSingleValue(capture.getExpr()).ensurePlusOne(*this, loc));
576575
continue;
577576
}
578577

lib/SILGen/SILGenFunction.h

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2185,9 +2185,8 @@ class LLVM_LIBRARY_VISIBILITY SILGenFunction
21852185
emitOpenExistentialExprImpl(e, emitSubExpr);
21862186
}
21872187

2188-
/// Mapping from active opaque value expressions to their values.
2189-
llvm::SmallDenseMap<OpaqueValueExpr *, ManagedValue>
2190-
OpaqueValues;
2188+
/// Mapping from OpaqueValueExpr/PackElementExpr to their values.
2189+
llvm::SmallDenseMap<Expr *, ManagedValue> OpaqueValues;
21912190

21922191
/// A mapping from opaque value expressions to the open-existential
21932192
/// expression that determines them, used while lowering lvalues.

lib/SILGen/SILGenProlog.cpp

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1052,6 +1052,49 @@ static void emitCaptureArguments(SILGenFunction &SGF,
10521052
GenericSignature origGenericSig,
10531053
CapturedValue capture,
10541054
uint16_t ArgNo) {
1055+
if (auto *expr = capture.getPackElement()) {
1056+
SILLocation Loc(expr);
1057+
Loc.markAsPrologue();
1058+
1059+
auto interfaceType = expr->getType()->mapTypeOutOfContext();
1060+
1061+
auto type = SGF.F.mapTypeIntoContext(interfaceType);
1062+
auto &lowering = SGF.getTypeLowering(type);
1063+
SILType ty = lowering.getLoweredType();
1064+
1065+
SILValue arg;
1066+
1067+
auto expansion = SGF.getTypeExpansionContext();
1068+
auto captureKind = SGF.SGM.Types.getDeclCaptureKind(capture, expansion);
1069+
switch (captureKind) {
1070+
case CaptureKind::Constant:
1071+
case CaptureKind::StorageAddress:
1072+
case CaptureKind::Immutable: {
1073+
auto argIndex = SGF.F.begin()->getNumArguments();
1074+
// Non-escaping stored decls are captured as the address of the value.
1075+
auto param = SGF.F.getConventions().getParamInfoForSILArg(argIndex);
1076+
if (SGF.F.getConventions().isSILIndirect(param))
1077+
ty = ty.getAddressType();
1078+
1079+
auto *fArg = SGF.F.begin()->createFunctionArgument(ty, nullptr);
1080+
fArg->setClosureCapture(true);
1081+
1082+
arg = fArg;
1083+
break;
1084+
}
1085+
1086+
case CaptureKind::ImmutableBox:
1087+
case CaptureKind::Box:
1088+
llvm_unreachable("should be impossible");
1089+
}
1090+
1091+
ManagedValue mv = ManagedValue::forBorrowedRValue(arg);
1092+
auto inserted = SGF.OpaqueValues.insert(std::make_pair(expr, mv));
1093+
assert(inserted.second);
1094+
(void) inserted;
1095+
1096+
return;
1097+
}
10551098

10561099
auto *VD = cast<VarDecl>(capture.getDecl());
10571100

0 commit comments

Comments
 (0)