Skip to content

Commit e6e9b6e

Browse files
authored
Merge pull request swiftlang#32887 from slavapestov/fixed-layout-protocols
AST: Allow @_fixed_layout protocols
2 parents e9c3157 + 4a47190 commit e6e9b6e

File tree

5 files changed

+61
-4
lines changed

5 files changed

+61
-4
lines changed

include/swift/AST/Attr.def

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -244,7 +244,7 @@ SIMPLE_DECL_ATTR(nonobjc, NonObjC,
244244
ABIStableToAdd | ABIStableToRemove | APIStableToAdd | APIStableToRemove,
245245
30)
246246
SIMPLE_DECL_ATTR(_fixed_layout, FixedLayout,
247-
OnVar | OnClass | OnStruct |
247+
OnVar | OnClass | OnStruct | OnProtocol |
248248
UserInaccessible | ABIBreakingToAdd | ABIBreakingToRemove |
249249
APIStableToAdd | APIStableToRemove,
250250
31)

lib/IRGen/GenMeta.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -612,7 +612,7 @@ namespace {
612612
ProtocolDescriptorBuilder(IRGenModule &IGM, ProtocolDecl *Proto,
613613
SILDefaultWitnessTable *defaultWitnesses)
614614
: super(IGM), Proto(Proto), DefaultWitnesses(defaultWitnesses),
615-
Resilient(IGM.isResilient(Proto, ResilienceExpansion::Minimal)) {}
615+
Resilient(IGM.getSwiftModule()->isResilient()) {}
616616

617617
void layout() {
618618
super::layout();

lib/TBDGen/TBDGen.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -968,13 +968,14 @@ void TBDGenVisitor::visitProtocolDecl(ProtocolDecl *PD) {
968968
struct WitnessVisitor : public SILWitnessVisitor<WitnessVisitor> {
969969
TBDGenVisitor &TBD;
970970
ProtocolDecl *PD;
971+
bool Resilient;
971972

972973
public:
973974
WitnessVisitor(TBDGenVisitor &TBD, ProtocolDecl *PD)
974-
: TBD(TBD), PD(PD) {}
975+
: TBD(TBD), PD(PD), Resilient(PD->getParentModule()->isResilient()) {}
975976

976977
void addMethod(SILDeclRef declRef) {
977-
if (PD->isResilient()) {
978+
if (Resilient) {
978979
TBD.addDispatchThunk(declRef);
979980
TBD.addMethodDescriptor(declRef);
980981
}

test/IRGen/frozen_protocols.swift

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
// RUN: %empty-directory(%t)
2+
// RUN: %target-swift-frontend -emit-module -enable-library-evolution -emit-module-path=%t/resilient_protocol.swiftmodule -module-name=resilient_protocol %S/../Inputs/resilient_protocol.swift
3+
// RUN: %target-swift-frontend -I %t -emit-ir -enable-library-evolution %s | %FileCheck %s -DINT=i%target-ptrsize
4+
// RUN: %target-swift-frontend -I %t -emit-ir -enable-library-evolution -O %s
5+
6+
import resilient_protocol
7+
8+
@_fixed_layout public protocol FrozenProtocol {
9+
func protocolMethod()
10+
}
11+
12+
public func callOtherProtocolMethod<T : OtherFrozenProtocol>(_ t: T) {
13+
t.protocolMethod()
14+
}
15+
16+
public struct ConformsToFrozenProtocol : FrozenProtocol {
17+
public func protocolMethod() {}
18+
}
19+
20+
// CHECK-LABEL: @"$s16frozen_protocols24ConformsToFrozenProtocolVAA0eF0AAMc" = {{(dllexport )?}}{{(protected )?}}constant %swift.protocol_conformance_descriptor
21+
22+
// -- the protocol
23+
// CHECK-SAME: @"$s16frozen_protocols14FrozenProtocolMp"
24+
25+
// -- the conforming type
26+
// CHECK-SAME: @"$s16frozen_protocols24ConformsToFrozenProtocolVMn"
27+
28+
// -- the witness table
29+
// CHECK-SAME: @"$s16frozen_protocols24ConformsToFrozenProtocolVAA0eF0AAWP"
30+
31+
// -- flags
32+
// CHECK-SAME: i32 0
33+
// CHECK-SAME: }
34+
35+
// @_fixed_layout protocols still emit protocol requirement descriptors though,
36+
// which allows for a protocol to be retroactively declared as @_fixed_layout
37+
// CHECK-LABEL: @"$s16frozen_protocols14FrozenProtocolP14protocolMethodyyFTq" = {{(dllexport )?}}{{(protected )?}}alias %swift.protocol_requirement
38+
39+
// Requirements in @_fixed_layout protocols are called by direct witness
40+
// table lookup
41+
42+
// CHECK-LABEL: define{{( dllexport)?}}{{( protected)?}} swiftcc void @"$s16frozen_protocols23callOtherProtocolMethodyyx18resilient_protocol0d6FrozenE0RzlF"(%swift.opaque* noalias nocapture %0, %swift.type* %T, i8** %T.OtherFrozenProtocol)
43+
// CHECK: [[ADDR:%.*]] = getelementptr inbounds i8*, i8** %T.OtherFrozenProtocol, i32 1
44+
// CHECK: [[FN:%.*]] = load i8*, i8** [[ADDR]]
45+
// CHECK: [[CAST:%.*]] = bitcast i8* [[FN]] to void (%swift.opaque*, %swift.type*, i8**)*
46+
// CHECK: call swiftcc void %3(%swift.opaque* noalias nocapture swiftself %0, %swift.type* %T, i8** %T.OtherFrozenProtocol)
47+
// CHECK: ret void
48+
49+
// @_fixed_layout protocols still emit method dispatch thunks though, which
50+
// allows for a protocol to be retroactively declared as @_fixed_layout
51+
// CHECK-LABEL: define{{( dllexport)?}}{{( protected)?}} swiftcc void @"$s16frozen_protocols14FrozenProtocolP14protocolMethodyyFTj"(
52+

test/Inputs/resilient_protocol.swift

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,3 +40,7 @@ public protocol ProtocolWithAssocTypeDefaults {
4040
public protocol ResilientSelfDefault : ResilientBaseProtocol {
4141
associatedtype AssocType: ResilientBaseProtocol = Self
4242
}
43+
44+
@_fixed_layout public protocol OtherFrozenProtocol {
45+
func protocolMethod()
46+
}

0 commit comments

Comments
 (0)