@@ -659,7 +659,15 @@ namespace {
659
659
void consume (IRGenFunction &IGF, Explosion &src,
660
660
Atomicity atomicity,
661
661
SILType T) const override {
662
- if (tryEmitConsumeUsingDeinit (IGF, src, T)) {
662
+ if (ElementsAreABIAccessible &&
663
+ tryEmitConsumeUsingDeinit (IGF, src, T)) {
664
+ return ;
665
+ }
666
+
667
+ if (!ElementsAreABIAccessible) {
668
+ auto temporary = TI->allocateStack (IGF, T, " deinit.arg" ).getAddress ();
669
+ cast<LoadableTypeInfo>(TI)->initialize (IGF, src, temporary, /* outlined*/ false );
670
+ emitDestroyCall (IGF, T, temporary);
663
671
return ;
664
672
}
665
673
@@ -674,10 +682,11 @@ namespace {
674
682
675
683
void destroy (IRGenFunction &IGF, Address addr, SILType T,
676
684
bool isOutlined) const override {
677
- if (tryEmitDestroyUsingDeinit (IGF, addr, T)) {
685
+ if (ElementsAreABIAccessible &&
686
+ tryEmitDestroyUsingDeinit (IGF, addr, T)) {
678
687
return ;
679
688
}
680
-
689
+
681
690
if (getSingleton () &&
682
691
!getSingleton ()->isTriviallyDestroyable (ResilienceExpansion::Maximal)) {
683
692
if (!ElementsAreABIAccessible) {
@@ -1986,6 +1995,7 @@ namespace {
1986
1995
1987
1996
// If the payload is TriviallyDestroyable, then we can use TriviallyDestroyable value semantics.
1988
1997
auto &payloadTI = *ElementsWithPayload[0 ].ti ;
1998
+
1989
1999
if (!payloadTI.isABIAccessible ()) {
1990
2000
CopyDestroyKind = ABIInaccessible;
1991
2001
} else if (payloadTI.isTriviallyDestroyable (ResilienceExpansion::Maximal)) {
@@ -2848,9 +2858,18 @@ namespace {
2848
2858
2849
2859
void consume (IRGenFunction &IGF, Explosion &src,
2850
2860
Atomicity atomicity, SILType T) const override {
2851
- if (tryEmitConsumeUsingDeinit (IGF, src, T)) {
2861
+ if (ElementsAreABIAccessible &&
2862
+ tryEmitConsumeUsingDeinit (IGF, src, T)) {
2852
2863
return ;
2853
2864
}
2865
+
2866
+ if (!ElementsAreABIAccessible) {
2867
+ auto temporary = TI->allocateStack (IGF, T, " deinit.arg" ).getAddress ();
2868
+ cast<LoadableTypeInfo>(TI)->initialize (IGF, src, temporary, /* outlined*/ false );
2869
+ emitDestroyCall (IGF, T, temporary);
2870
+ return ;
2871
+ }
2872
+
2854
2873
assert (TIK >= Loadable);
2855
2874
2856
2875
switch (CopyDestroyKind) {
@@ -2968,7 +2987,8 @@ namespace {
2968
2987
2969
2988
void destroy (IRGenFunction &IGF, Address addr, SILType T,
2970
2989
bool isOutlined) const override {
2971
- if (tryEmitDestroyUsingDeinit (IGF, addr, T)) {
2990
+ if (ElementsAreABIAccessible &&
2991
+ tryEmitDestroyUsingDeinit (IGF, addr, T)) {
2972
2992
return ;
2973
2993
}
2974
2994
@@ -4879,9 +4899,18 @@ namespace {
4879
4899
4880
4900
void consume (IRGenFunction &IGF, Explosion &src,
4881
4901
Atomicity atomicity, SILType T) const override {
4882
- if (tryEmitConsumeUsingDeinit (IGF, src, T)) {
4902
+ if (ElementsAreABIAccessible &&
4903
+ tryEmitConsumeUsingDeinit (IGF, src, T)) {
4883
4904
return ;
4884
4905
}
4906
+
4907
+ if (!ElementsAreABIAccessible) {
4908
+ auto temporary = TI->allocateStack (IGF, T, " deinit.arg" ).getAddress ();
4909
+ cast<LoadableTypeInfo>(TI)->initialize (IGF, src, temporary, /* outlined*/ false );
4910
+ emitDestroyCall (IGF, T, temporary);
4911
+ return ;
4912
+ }
4913
+
4885
4914
assert (TIK >= Loadable);
4886
4915
switch (CopyDestroyKind) {
4887
4916
case TriviallyDestroyable:
@@ -5230,7 +5259,8 @@ namespace {
5230
5259
5231
5260
void destroy (IRGenFunction &IGF, Address addr, SILType T,
5232
5261
bool isOutlined) const override {
5233
- if (tryEmitDestroyUsingDeinit (IGF, addr, T)) {
5262
+ if (ElementsAreABIAccessible &&
5263
+ tryEmitDestroyUsingDeinit (IGF, addr, T)) {
5234
5264
return ;
5235
5265
}
5236
5266
@@ -6407,7 +6437,6 @@ EnumImplStrategy::get(TypeConverter &TC, SILType type, EnumDecl *theEnum) {
6407
6437
// fixed-size from this resilience scope.
6408
6438
ResilienceExpansion layoutScope =
6409
6439
TC.IGM .getResilienceExpansionForLayout (theEnum);
6410
-
6411
6440
for (auto elt : theEnum->getAllElements ()) {
6412
6441
++numElements;
6413
6442
@@ -6652,8 +6681,6 @@ namespace {
6652
6681
public:
6653
6682
using EnumTypeInfoBase<Base>::Strategy;
6654
6683
6655
- // / \group Methods delegated to the EnumImplStrategy
6656
-
6657
6684
unsigned getFixedExtraInhabitantCount (IRGenModule &IGM) const override {
6658
6685
return Strategy.getFixedExtraInhabitantCount (IGM);
6659
6686
}
@@ -6693,10 +6720,11 @@ namespace {
6693
6720
IsTriviallyDestroyable_t isTriviallyDestroyable,
6694
6721
IsBitwiseTakable_t isBT,
6695
6722
IsCopyable_t copyable,
6696
- IsFixedSize_t alwaysFixedSize)
6723
+ IsFixedSize_t alwaysFixedSize,
6724
+ IsABIAccessible_t isABIAccessible)
6697
6725
: FixedEnumTypeInfoBase(strategy, T, S, std::move(SB), A,
6698
6726
isTriviallyDestroyable, isBT, copyable,
6699
- alwaysFixedSize) {}
6727
+ alwaysFixedSize, isABIAccessible ) {}
6700
6728
};
6701
6729
6702
6730
// / TypeInfo for loadable enum types.
@@ -6708,10 +6736,11 @@ namespace {
6708
6736
Alignment A,
6709
6737
IsTriviallyDestroyable_t isTriviallyDestroyable,
6710
6738
IsCopyable_t copyable,
6711
- IsFixedSize_t alwaysFixedSize)
6739
+ IsFixedSize_t alwaysFixedSize,
6740
+ IsABIAccessible_t isABIAccessible)
6712
6741
: FixedEnumTypeInfoBase(strategy, T, S, std::move(SB), A,
6713
6742
isTriviallyDestroyable, copyable,
6714
- alwaysFixedSize) {}
6743
+ alwaysFixedSize, isABIAccessible ) {}
6715
6744
6716
6745
void addToAggLowering (IRGenModule &IGM, SwiftAggLowering &lowering,
6717
6746
Size offset) const override {
@@ -6821,7 +6850,8 @@ EnumImplStrategy::getFixedEnumTypeInfo(llvm::StructType *T, Size S,
6821
6850
Alignment A,
6822
6851
IsTriviallyDestroyable_t isTriviallyDestroyable,
6823
6852
IsBitwiseTakable_t isBT,
6824
- IsCopyable_t isCopyable) {
6853
+ IsCopyable_t isCopyable,
6854
+ IsABIAccessible_t abiAccessible) {
6825
6855
TypeInfo *mutableTI;
6826
6856
switch (TIK) {
6827
6857
case Opaque:
@@ -6831,14 +6861,16 @@ EnumImplStrategy::getFixedEnumTypeInfo(llvm::StructType *T, Size S,
6831
6861
isTriviallyDestroyable,
6832
6862
isBT,
6833
6863
isCopyable,
6834
- AlwaysFixedSize);
6864
+ AlwaysFixedSize,
6865
+ abiAccessible);
6835
6866
break ;
6836
6867
case Loadable:
6837
6868
assert (isBT && " loadable enum not bitwise takable?!" );
6838
6869
mutableTI = new LoadableEnumTypeInfo (*this , T, S, std::move (SB), A,
6839
6870
isTriviallyDestroyable,
6840
6871
isCopyable,
6841
- AlwaysFixedSize);
6872
+ AlwaysFixedSize,
6873
+ abiAccessible);
6842
6874
break ;
6843
6875
}
6844
6876
TI = mutableTI;
@@ -6859,7 +6891,8 @@ SingletonEnumImplStrategy::completeEnumTypeLayout(TypeConverter &TC,
6859
6891
alignment,
6860
6892
TriviallyDestroyable,
6861
6893
Copyable,
6862
- AlwaysFixedSize));
6894
+ AlwaysFixedSize,
6895
+ IsABIAccessible));
6863
6896
} else {
6864
6897
const TypeInfo &eltTI = *getSingleton ();
6865
6898
@@ -6886,13 +6919,19 @@ SingletonEnumImplStrategy::completeEnumTypeLayout(TypeConverter &TC,
6886
6919
auto alignment = fixedEltTI.getFixedAlignment ();
6887
6920
applyLayoutAttributes (TC.IGM , theEnum, /* fixed*/ true , alignment);
6888
6921
6922
+ IsABIAccessible_t isABIAccessible = IsABIAccessible;
6923
+ if (Type.getASTType ()->isNoncopyable () &&
6924
+ !IGM.getSILModule ().isTypeMetadataAccessible (Type.getASTType ()))
6925
+ isABIAccessible = IsNotABIAccessible;
6926
+
6889
6927
return getFixedEnumTypeInfo (enumTy,
6890
6928
fixedEltTI.getFixedSize (),
6891
6929
fixedEltTI.getSpareBits (),
6892
6930
alignment,
6893
6931
TriviallyDestroyable,
6894
6932
BitwiseTakable,
6895
- Copyable);
6933
+ Copyable,
6934
+ isABIAccessible);
6896
6935
}
6897
6936
}
6898
6937
}
@@ -6927,7 +6966,8 @@ NoPayloadEnumImplStrategy::completeEnumTypeLayout(TypeConverter &TC,
6927
6966
alignment,
6928
6967
TriviallyDestroyable,
6929
6968
Copyable,
6930
- AlwaysFixedSize));
6969
+ AlwaysFixedSize,
6970
+ IsABIAccessible));
6931
6971
}
6932
6972
6933
6973
TypeInfo *
@@ -6976,7 +7016,8 @@ CCompatibleEnumImplStrategy::completeEnumTypeLayout(TypeConverter &TC,
6976
7016
alignment,
6977
7017
IsTriviallyDestroyable,
6978
7018
IsCopyable,
6979
- IsFixedSize));
7019
+ IsFixedSize,
7020
+ IsABIAccessible));
6980
7021
}
6981
7022
6982
7023
TypeInfo *SinglePayloadEnumImplStrategy::completeFixedLayout (
@@ -7044,11 +7085,18 @@ TypeInfo *SinglePayloadEnumImplStrategy::completeFixedLayout(
7044
7085
? IsNotTriviallyDestroyable : IsTriviallyDestroyable;
7045
7086
auto copyable = !theEnum->canBeCopyable ()
7046
7087
? IsNotCopyable : IsCopyable;
7088
+
7089
+ IsABIAccessible_t isABIAccessible = IsABIAccessible;
7090
+ if (Type.getASTType ()->isNoncopyable () &&
7091
+ !IGM.getSILModule ().isTypeMetadataAccessible (Type.getASTType ()))
7092
+ isABIAccessible = IsNotABIAccessible;
7093
+
7047
7094
getFixedEnumTypeInfo (
7048
7095
enumTy, Size (sizeWithTag), spareBits.build (), alignment,
7049
7096
deinit & payloadTI.isTriviallyDestroyable (ResilienceExpansion::Maximal),
7050
7097
payloadTI.isBitwiseTakable (ResilienceExpansion::Maximal),
7051
- copyable);
7098
+ copyable, isABIAccessible);
7099
+
7052
7100
if (TIK >= Loadable && CopyDestroyKind == Normal) {
7053
7101
computePayloadTypesAndTagType (TC.IGM , *TI, PayloadTypesAndTagType);
7054
7102
loweredType = Type;
@@ -7255,9 +7303,15 @@ MultiPayloadEnumImplStrategy::completeFixedLayout(TypeConverter &TC,
7255
7303
7256
7304
applyLayoutAttributes (TC.IGM , theEnum, /* fixed*/ true , worstAlignment);
7257
7305
7306
+ IsABIAccessible_t isABIAccessible = IsABIAccessible;
7307
+ if (Type.getASTType ()->isNoncopyable () &&
7308
+ !IGM.getSILModule ().isTypeMetadataAccessible (Type.getASTType ()))
7309
+ isABIAccessible = IsNotABIAccessible;
7310
+
7258
7311
getFixedEnumTypeInfo (enumTy, Size (sizeWithTag), std::move (spareBits),
7259
7312
worstAlignment, isTriviallyDestroyable, isBT,
7260
- isCopyable);
7313
+ isCopyable, isABIAccessible);
7314
+
7261
7315
if (TIK >= Loadable &&
7262
7316
(CopyDestroyKind == Normal || CopyDestroyKind == BitwiseTakable)) {
7263
7317
computePayloadTypesAndTagType (TC.IGM , *TI, PayloadTypesAndTagType);
0 commit comments