Skip to content

Commit 3b0e773

Browse files
committed
AddressLowering: support typed throws
Out of SILGen, we'll get the non-indirect SSA for throwing the error. AddressLowering then converts a `throw` into `throw_addr` to match the function convention. Similarly, a try_apply gets rewritten to pass the error address to the error successor block. resolves rdar://158171053
1 parent 00ecc6c commit 3b0e773

File tree

3 files changed

+236
-64
lines changed

3 files changed

+236
-64
lines changed

include/swift/SIL/ApplySite.h

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -790,6 +790,25 @@ class FullApplySite : public ApplySite {
790790
llvm_unreachable("Covered switch isn't covered?!");
791791
}
792792

793+
// For a direct error result, as a result of an @error convention, if any.
794+
SILValue getDirectErrorResult() const {
795+
switch (getKind()) {
796+
case FullApplySiteKind::ApplyInst:
797+
case FullApplySiteKind::BeginApplyInst:
798+
return SILValue();
799+
case FullApplySiteKind::TryApplyInst: {
800+
if (getNumIndirectSILErrorResults())
801+
return SILValue(); // Not a direct @error convention.
802+
803+
auto *errBlock = cast<TryApplyInst>(getInstruction())->getErrorBB();
804+
assert(errBlock->getNumArguments() == 1 &&
805+
"Expected this try_apply to have a single direct error result");
806+
return errBlock->getArgument(0);
807+
}
808+
}
809+
llvm_unreachable("Covered switch isn't covered?!");
810+
}
811+
793812
unsigned getNumIndirectSILResults() const {
794813
return getSubstCalleeConv().getNumIndirectSILResults();
795814
}

include/swift/SIL/SILFunctionConventions.h

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,15 @@ class SILModuleConventions {
101101

102102
SILModule &getModule() const { return *M; }
103103

104+
/// Is the current convention to represent address-only types in their final,
105+
/// lowered form of a raw address?
106+
///
107+
/// Otherwise, address-only types are instead represented opaquely as SSA
108+
/// values, until the mandatory SIL pass AddressLowering has run.
109+
///
110+
/// See the -enable-sil-opaque-values flag.
111+
///
112+
/// \returns true iff address-only types are represented as raw addresses
104113
bool useLoweredAddresses() const { return loweredAddresses; }
105114

106115
bool isTypeIndirectForIndirectParamConvention(CanType paramTy) {
@@ -261,9 +270,20 @@ class SILFunctionConventions {
261270
}
262271

263272
bool isArgumentIndexOfIndirectErrorResult(unsigned idx) {
264-
unsigned indirectResults = getNumIndirectSILResults();
265-
return idx >= indirectResults &&
266-
idx < indirectResults + getNumIndirectSILErrorResults();
273+
if (auto errorIdx = getArgumentIndexOfIndirectErrorResult())
274+
return idx == *errorIdx;
275+
276+
return false;
277+
}
278+
279+
std::optional<unsigned> getArgumentIndexOfIndirectErrorResult() {
280+
unsigned hasIndirectErrorResult = getNumIndirectSILErrorResults();
281+
if (!hasIndirectErrorResult)
282+
return std::nullopt;
283+
284+
assert(hasIndirectErrorResult == 1);
285+
// Error index is the first one after the indirect return results, if any.
286+
return getNumIndirectSILResults();
267287
}
268288

269289
unsigned getNumAutoDiffSemanticResults() const {

0 commit comments

Comments
 (0)