Skip to content

Commit 067c867

Browse files
author
Joe Shajrawi
committed
Add inital support of Address-only enums under opaque values mode
1 parent 01b5b6a commit 067c867

File tree

3 files changed

+52
-3
lines changed

3 files changed

+52
-3
lines changed

lib/SILGen/SILGenApply.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3307,7 +3307,7 @@ ManagedValue SILGenFunction::emitInjectEnum(SILLocation loc,
33073307

33083308
// Easy case -- no payload
33093309
if (!payload) {
3310-
if (enumTy.isLoadable(SGM.M)) {
3310+
if (enumTy.isLoadable(SGM.M) || !silConv.useLoweredAddresses()) {
33113311
return emitManagedRValueWithCleanup(
33123312
B.createEnum(loc, SILValue(), element,
33133313
enumTy.getObjectType()));

lib/SILGen/SILGenConstructor.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -376,7 +376,7 @@ void SILGenFunction::emitEnumConstructor(EnumElementDecl *element) {
376376

377377
// Emit the indirect return slot.
378378
std::unique_ptr<Initialization> dest;
379-
if (enumTI.isAddressOnly()) {
379+
if (enumTI.isAddressOnly() && silConv.useLoweredAddresses()) {
380380
auto &AC = getASTContext();
381381
auto VD = new (AC) ParamDecl(/*IsLet*/ false, SourceLoc(), SourceLoc(),
382382
AC.getIdentifier("$return_value"),
@@ -418,7 +418,7 @@ void SILGenFunction::emitEnumConstructor(EnumElementDecl *element) {
418418
scope.pop();
419419
B.createReturn(ReturnLoc, emitEmptyTuple(Loc));
420420
} else {
421-
assert(enumTI.isLoadable());
421+
assert(enumTI.isLoadable() || !silConv.useLoweredAddresses());
422422
SILValue result = mv.forward(*this);
423423
scope.pop();
424424
B.createReturn(ReturnLoc, result);

test/SILGen/opaque_values_silgen.swift

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,29 @@ struct Box<T> {
1414
let t: T
1515
}
1616

17+
protocol EmptyP {}
18+
19+
struct AddressOnlyStruct : EmptyP {}
20+
1721
func s010_hasVarArg(_ args: Any...) {}
1822

23+
// Tests Address only enums's construction
24+
// CHECK-LABEL: sil shared [transparent] @_T020opaque_values_silgen15AddressOnlyEnumO4mereAcA6EmptyP_pcACmF : $@convention(method) (@in EmptyP, @thin AddressOnlyEnum.Type) -> @out AddressOnlyEnum {
25+
// CHECK: bb0([[ARG0:%.*]] : $EmptyP, [[ARG1:%.*]] : $@thin AddressOnlyEnum.Type):
26+
// CHECK: [[RETVAL:%.*]] = enum $AddressOnlyEnum, #AddressOnlyEnum.mere!enumelt.1, [[ARG0]] : $EmptyP
27+
// CHECK: return [[RETVAL]] : $AddressOnlyEnum
28+
// CHECK-LABEL: } // end sil function '_T020opaque_values_silgen15AddressOnlyEnumO4mereAcA6EmptyP_pcACmF'
29+
// CHECK-LABEL: sil shared [transparent] [thunk] @_T020opaque_values_silgen15AddressOnlyEnumO4mereAcA6EmptyP_pcACmFTc : $@convention(thin) (@thin AddressOnlyEnum.Type) -> @owned @callee_owned (@in EmptyP) -> @out AddressOnlyEnum {
30+
// CHECK: bb0([[ARG:%.*]] : $@thin AddressOnlyEnum.Type):
31+
// CHECK: [[RETVAL:%.*]] = partial_apply {{.*}}([[ARG]]) : $@convention(method) (@in EmptyP, @thin AddressOnlyEnum.Type) -> @out AddressOnlyEnum
32+
// CHECK: return [[RETVAL]] : $@callee_owned (@in EmptyP) -> @out AddressOnlyEnum
33+
// CHECK-LABEL: } // end sil function '_T020opaque_values_silgen15AddressOnlyEnumO4mereAcA6EmptyP_pcACmFTc'
34+
enum AddressOnlyEnum {
35+
case nought
36+
case mere(EmptyP)
37+
case phantom(AddressOnlyStruct)
38+
}
39+
1940
// Test that we still use addresses when dealing with array initialization
2041
// ---
2142
// CHECK-LABEL: sil @_T020opaque_values_silgen21s020_______callVarArgyyF : $@convention(thin) () -> () {
@@ -411,6 +432,34 @@ func s250_________testBoxT() {
411432
let _ = Box(t: 42)
412433
}
413434

435+
// Tests Address only enums
436+
// ---
437+
// CHECK-LABEL: sil hidden @_T020opaque_values_silgen21s260_______AOnly_enumyAA17AddressOnlyStructVF : $@convention(thin) (AddressOnlyStruct) -> () {
438+
// CHECK: bb0([[ARG:%.*]] : $AddressOnlyStruct):
439+
// CHECK: [[MTYPE1:%.*]] = metatype $@thin AddressOnlyEnum.Type
440+
// CHECK: [[APPLY1:%.*]] = apply {{.*}}([[MTYPE1]]) : $@convention(thin) (@thin AddressOnlyEnum.Type) -> @owned @callee_owned (@in EmptyP) -> @out AddressOnlyEnum
441+
// CHECK: destroy_value [[APPLY1]]
442+
// CHECK: [[MTYPE2:%.*]] = metatype $@thin AddressOnlyEnum.Type
443+
// CHECK: [[ENUM1:%.*]] = enum $AddressOnlyEnum, #AddressOnlyEnum.nought!enumelt
444+
// CHECK: [[MTYPE3:%.*]] = metatype $@thin AddressOnlyEnum.Type
445+
// CHECK: [[INIT_OPAQUE:%.*]] = init_existential_opaque [[ARG]] : $AddressOnlyStruct, $AddressOnlyStruct, $EmptyP
446+
// CHECK: [[ENUM2:%.*]] = enum $AddressOnlyEnum, #AddressOnlyEnum.mere!enumelt.1, [[INIT_OPAQUE]] : $EmptyP
447+
// CHECK: destroy_value [[ENUM2]]
448+
// CHECK: [[MTYPE4:%.*]] = metatype $@thin AddressOnlyEnum.Type
449+
// CHECK: [[ENUM3:%.*]] = enum $AddressOnlyEnum, #AddressOnlyEnum.phantom!enumelt.1, [[ARG]] : $AddressOnlyStruct
450+
// CHECK: return %{{.*}} : $()
451+
// CHECK-LABEL: } // end sil function '_T020opaque_values_silgen21s260_______AOnly_enumyAA17AddressOnlyStructVF'
452+
func s260_______AOnly_enum(_ s: AddressOnlyStruct) {
453+
_ = AddressOnlyEnum.mere
454+
455+
_ = AddressOnlyEnum.nought
456+
457+
_ = AddressOnlyEnum.mere(s)
458+
459+
_ = AddressOnlyEnum.phantom(s)
460+
}
461+
462+
414463
// Tests conditional value casts and correspondingly generated reabstraction thunk, with <T> types
415464
// ---
416465
// CHECK-LABEL: sil hidden @_T020opaque_values_silgen21s999_____condTFromAnyyyp_xtlF : $@convention(thin) <T> (@in Any, @in T) -> () {

0 commit comments

Comments
 (0)