@@ -661,51 +661,52 @@ namespace {
661
661
return Super::getFixedExtraInhabitantMask (IGM); \
662
662
} \
663
663
}
664
- #define NEVER_LOADABLE_CHECKED_REF_STORAGE (Name, name, ...) \
665
- class AddressOnly ##Name##ClassExistentialTypeInfo final : \
666
- public AddressOnlyClassExistentialTypeInfoBase< \
667
- AddressOnly##Name##ClassExistentialTypeInfo, \
668
- FixedTypeInfo> { \
669
- bool IsOptional; \
670
- public: \
671
- AddressOnly##Name##ClassExistentialTypeInfo( \
672
- ArrayRef<const ProtocolDecl *> protocols, \
673
- llvm::Type *ty, \
674
- SpareBitVector &&spareBits, \
675
- Size size, Alignment align, \
676
- ReferenceCounting refcounting, \
677
- bool isOptional) \
678
- : AddressOnlyClassExistentialTypeInfoBase(protocols, refcounting, \
679
- ty, size, std::move(spareBits), \
680
- align, IsNotPOD, \
681
- IsNotBitwiseTakable, \
682
- IsFixedSize), \
683
- IsOptional (isOptional) {} \
684
- TypeLayoutEntry *buildTypeLayoutEntry (IRGenModule &IGM, \
685
- SILType T) const override { \
686
- return IGM.typeLayoutCache .getOrCreateScalarEntry (*this , T); \
687
- } \
688
- void emitValueAssignWithCopy (IRGenFunction &IGF, \
689
- Address dest, Address src) const { \
690
- IGF.emit ##Name##CopyAssign (dest, src, Refcounting); \
691
- } \
692
- void emitValueInitializeWithCopy (IRGenFunction &IGF, \
693
- Address dest, Address src) const { \
694
- IGF.emit ##Name##CopyInit (dest, src, Refcounting); \
695
- } \
696
- void emitValueAssignWithTake (IRGenFunction &IGF, \
697
- Address dest, Address src) const { \
698
- IGF.emit ##Name##TakeAssign (dest, src, Refcounting); \
699
- } \
700
- void emitValueInitializeWithTake (IRGenFunction &IGF, \
701
- Address dest, Address src) const { \
702
- IGF.emit ##Name##TakeInit (dest, src, Refcounting); \
703
- } \
704
- void emitValueDestroy (IRGenFunction &IGF, Address addr) const { \
705
- IGF.emit ##Name##Destroy (addr, Refcounting); \
706
- } \
707
- StringRef getStructNameSuffix () const { return " ." #name " ref" ; } \
708
- REF_STORAGE_HELPER (Name, FixedTypeInfo) \
664
+ #define NEVER_LOADABLE_CHECKED_REF_STORAGE (Name, name, ...) \
665
+ class AddressOnly ##Name##ClassExistentialTypeInfo final \
666
+ : public AddressOnlyClassExistentialTypeInfoBase< \
667
+ AddressOnly##Name##ClassExistentialTypeInfo, FixedTypeInfo> { \
668
+ bool IsOptional; \
669
+ \
670
+ public: \
671
+ AddressOnly##Name##ClassExistentialTypeInfo( \
672
+ ArrayRef<const ProtocolDecl *> protocols, llvm::Type *ty, \
673
+ SpareBitVector &&spareBits, Size size, Alignment align, \
674
+ ReferenceCounting refcounting, bool isOptional) \
675
+ : AddressOnlyClassExistentialTypeInfoBase( \
676
+ protocols, refcounting, ty, size, std::move(spareBits), align, \
677
+ IsNotPOD, IsNotBitwiseTakable, IsFixedSize), \
678
+ IsOptional (isOptional) {} \
679
+ TypeLayoutEntry *buildTypeLayoutEntry (IRGenModule &IGM, \
680
+ SILType T) const override { \
681
+ if (Refcounting == ReferenceCounting::Native) { \
682
+ return IGM.typeLayoutCache .getOrCreateScalarEntry ( \
683
+ *this , T, ScalarKind::Native##Name##Reference); \
684
+ } else { \
685
+ return IGM.typeLayoutCache .getOrCreateScalarEntry ( \
686
+ *this , T, ScalarKind::Unknown##Name##Reference); \
687
+ } \
688
+ } \
689
+ void emitValueAssignWithCopy (IRGenFunction &IGF, Address dest, \
690
+ Address src) const { \
691
+ IGF.emit ##Name##CopyAssign (dest, src, Refcounting); \
692
+ } \
693
+ void emitValueInitializeWithCopy (IRGenFunction &IGF, Address dest, \
694
+ Address src) const { \
695
+ IGF.emit ##Name##CopyInit (dest, src, Refcounting); \
696
+ } \
697
+ void emitValueAssignWithTake (IRGenFunction &IGF, Address dest, \
698
+ Address src) const { \
699
+ IGF.emit ##Name##TakeAssign (dest, src, Refcounting); \
700
+ } \
701
+ void emitValueInitializeWithTake (IRGenFunction &IGF, Address dest, \
702
+ Address src) const { \
703
+ IGF.emit ##Name##TakeInit (dest, src, Refcounting); \
704
+ } \
705
+ void emitValueDestroy (IRGenFunction &IGF, Address addr) const { \
706
+ IGF.emit ##Name##Destroy (addr, Refcounting); \
707
+ } \
708
+ StringRef getStructNameSuffix () const { return " ." #name " ref" ; } \
709
+ REF_STORAGE_HELPER (Name, FixedTypeInfo) \
709
710
};
710
711
#define ALWAYS_LOADABLE_CHECKED_REF_STORAGE (Name, ...) \
711
712
class Loadable ##Name##ClassExistentialTypeInfo final \
@@ -731,7 +732,16 @@ namespace {
731
732
} \
732
733
TypeLayoutEntry *buildTypeLayoutEntry (IRGenModule &IGM, \
733
734
SILType T) const override { \
734
- return IGM.typeLayoutCache .getOrCreateScalarEntry (*this , T); \
735
+ ScalarKind kind; \
736
+ switch (Refcounting) { \
737
+ case ReferenceCounting::Native: kind = ScalarKind::NativeStrongReference; break ; \
738
+ case ReferenceCounting::ObjC: kind = ScalarKind::ObjCReference; break ; \
739
+ case ReferenceCounting::Block: kind = ScalarKind::BlockReference; break ; \
740
+ case ReferenceCounting::Unknown: kind = ScalarKind::UnknownReference; break ; \
741
+ case ReferenceCounting::Bridge: kind = ScalarKind::BridgeReference; break ; \
742
+ case ReferenceCounting::Error: kind = ScalarKind::ErrorReference; break ; \
743
+ } \
744
+ return IGM.typeLayoutCache .getOrCreateScalarEntry (*this , T, kind); \
735
745
} \
736
746
llvm::Type *getValueType () const { \
737
747
return ValueType; \
@@ -778,7 +788,7 @@ namespace {
778
788
spareBits, align, IsPOD, IsFixedSize) {} \
779
789
TypeLayoutEntry *buildTypeLayoutEntry (IRGenModule &IGM, \
780
790
SILType T) const override { \
781
- return IGM.typeLayoutCache .getOrCreateScalarEntry (*this , T); \
791
+ return IGM.typeLayoutCache .getOrCreateScalarEntry (*this , T, ScalarKind::POD ); \
782
792
} \
783
793
const LoadableTypeInfo & \
784
794
getValueTypeInfoForExtraInhabitants (IRGenModule &IGM) const { \
@@ -847,7 +857,8 @@ class OpaqueExistentialTypeInfo final :
847
857
848
858
TypeLayoutEntry *buildTypeLayoutEntry (IRGenModule &IGM,
849
859
SILType T) const override {
850
- return IGM.typeLayoutCache .getOrCreateScalarEntry (*this , T);
860
+ return IGM.typeLayoutCache .getOrCreateScalarEntry (
861
+ *this , T, ScalarKind::ExistentialReference);
851
862
}
852
863
853
864
Address projectWitnessTable (IRGenFunction &IGF, Address obj,
@@ -995,7 +1006,31 @@ class ClassExistentialTypeInfo final
995
1006
996
1007
TypeLayoutEntry *buildTypeLayoutEntry (IRGenModule &IGM,
997
1008
SILType T) const override {
998
- return IGM.typeLayoutCache .getOrCreateScalarEntry (*this , T);
1009
+ // We can't create an objc typeinfo by itself, so don't destructure if we
1010
+ // have one
1011
+ if (Refcounting == ReferenceCounting::ObjC) {
1012
+ return IGM.typeLayoutCache .getOrCreateTypeInfoBasedEntry (*this , T);
1013
+ }
1014
+
1015
+ // / The storage type of a class existential is a struct containing
1016
+ // / a refcounted pointer to the class instance value followed by
1017
+ // / witness table pointers for each conformed-to protocol.
1018
+ std::vector<TypeLayoutEntry *> alignedGroup;
1019
+ const TypeInfo &typeinfo = Refcounting == ReferenceCounting::Native
1020
+ ? IGM.getNativeObjectTypeInfo ()
1021
+ : IGM.getUnknownObjectTypeInfo ();
1022
+
1023
+ alignedGroup.push_back (IGM.typeLayoutCache .getOrCreateScalarEntry (
1024
+ typeinfo, T, refcountingToScalarKind (Refcounting)));
1025
+ for (unsigned i = 0 ; i < getNumStoredProtocols (); i++) {
1026
+ alignedGroup.push_back (IGM.typeLayoutCache .getOrCreateScalarEntry (
1027
+ IGM.getWitnessTablePtrTypeInfo (),
1028
+ SILType::getBuiltinIntegerType (IGM.getPointerSize ().getValue (),
1029
+ IGM.Context ),
1030
+ ScalarKind::POD));
1031
+ }
1032
+
1033
+ return IGM.typeLayoutCache .getOrCreateAlignedGroupEntry (alignedGroup, 0 );
999
1034
}
1000
1035
1001
1036
// / Given an explosion with multiple pointer elements in them, pack them
@@ -1327,7 +1362,8 @@ class ExistentialMetatypeTypeInfo final
1327
1362
1328
1363
TypeLayoutEntry *buildTypeLayoutEntry (IRGenModule &IGM,
1329
1364
SILType T) const override {
1330
- return IGM.typeLayoutCache .getOrCreateScalarEntry (*this , T);
1365
+ return IGM.typeLayoutCache .getOrCreateScalarEntry (*this , T,
1366
+ ScalarKind::POD);
1331
1367
}
1332
1368
1333
1369
void emitValueRetain (IRGenFunction &IGF, llvm::Value *value,
@@ -1353,17 +1389,27 @@ class ErrorExistentialTypeInfo : public HeapTypeInfo<ErrorExistentialTypeInfo>
1353
1389
ReferenceCounting Refcounting;
1354
1390
1355
1391
public:
1356
- ErrorExistentialTypeInfo (llvm::PointerType *storage,
1357
- Size size, SpareBitVector spareBits,
1358
- Alignment align,
1392
+ ErrorExistentialTypeInfo (llvm::PointerType *storage, Size size,
1393
+ SpareBitVector spareBits, Alignment align,
1359
1394
const ProtocolDecl *errorProto,
1360
1395
ReferenceCounting refcounting)
1361
- : HeapTypeInfo(storage, size, spareBits, align), ErrorProto(errorProto ),
1362
- Refcounting (refcounting) {}
1396
+ : HeapTypeInfo(refcounting, storage, size, spareBits, align),
1397
+ ErrorProto (errorProto), Refcounting(refcounting) {}
1363
1398
1364
1399
TypeLayoutEntry *buildTypeLayoutEntry (IRGenModule &IGM,
1365
1400
SILType T) const override {
1366
- return IGM.typeLayoutCache .getOrCreateScalarEntry (*this , T);
1401
+ ScalarKind kind;
1402
+ switch (Refcounting) {
1403
+ case ReferenceCounting::Native:
1404
+ kind = ScalarKind::NativeStrongReference;
1405
+ break ;
1406
+ case ReferenceCounting::Error:
1407
+ kind = ScalarKind::ErrorReference;
1408
+ break ;
1409
+ default :
1410
+ llvm_unreachable (" unsupported refcounting type" );
1411
+ }
1412
+ return IGM.typeLayoutCache .getOrCreateScalarEntry (*this , T, kind);
1367
1413
}
1368
1414
1369
1415
ReferenceCounting getReferenceCounting () const {
@@ -2246,6 +2292,25 @@ void irgen::emitDeallocateBoxedOpaqueExistentialBuffer(
2246
2292
return ;
2247
2293
}
2248
2294
2295
+ void irgen::emitDestroyBoxedOpaqueExistentialBuffer (
2296
+ IRGenFunction &IGF, SILType existentialType, Address existentialContainer) {
2297
+
2298
+ // Project to the existential buffer in the existential container.
2299
+ auto &existentialTI =
2300
+ IGF.getTypeInfo (existentialType).as <OpaqueExistentialTypeInfo>();
2301
+ OpaqueExistentialLayout existLayout = existentialTI.getLayout ();
2302
+
2303
+ auto *deallocateFun =
2304
+ getDestroyBoxedOpaqueExistentialBufferFunction (IGF.IGM , existLayout);
2305
+ auto *bufferAddr = IGF.Builder .CreateBitCast (
2306
+ existentialContainer.getAddress (),
2307
+ IGF.IGM .getExistentialPtrTy (existLayout.getNumTables ()));
2308
+ auto *call = IGF.Builder .CreateCall (deallocateFun, {bufferAddr});
2309
+ call->setCallingConv (IGF.IGM .DefaultCC );
2310
+ call->setDoesNotThrow ();
2311
+ return ;
2312
+ }
2313
+
2249
2314
static llvm::Constant *
2250
2315
getProjectBoxedOpaqueExistentialFunction (IRGenFunction &IGF,
2251
2316
OpenedExistentialAccess accessKind,
0 commit comments