16
16
17
17
#include " GenExistential.h"
18
18
19
+ #include " TypeLayout.h"
19
20
#include " swift/AST/ASTContext.h"
20
21
#include " swift/AST/Decl.h"
21
22
#include " swift/AST/ExistentialLayout.h"
28
29
#include " llvm/IR/DerivedTypes.h"
29
30
#include " llvm/IR/Function.h"
30
31
#include " llvm/IR/Module.h"
32
+ #include " llvm/Support/ErrorHandling.h"
31
33
#include " llvm/Support/raw_ostream.h"
32
34
33
35
#include " BitPatternBuilder.h"
@@ -683,7 +685,16 @@ namespace {
683
685
IsOptional (isOptional) {} \
684
686
TypeLayoutEntry *buildTypeLayoutEntry (IRGenModule &IGM, \
685
687
SILType T) const override { \
686
- return IGM.typeLayoutCache .getOrCreateScalarEntry (*this , T); \
688
+ ScalarKind kind; \
689
+ switch (Refcounting) { \
690
+ case ReferenceCounting::Native: kind = ScalarKind::NativeStrongReference; break ; \
691
+ case ReferenceCounting::ObjC: kind = ScalarKind::ObjCReference; break ; \
692
+ case ReferenceCounting::Block: kind = ScalarKind::BlockReference; break ; \
693
+ case ReferenceCounting::Unknown: kind = ScalarKind::UnknownReference; break ; \
694
+ case ReferenceCounting::Bridge: kind = ScalarKind::BridgeReference; break ; \
695
+ case ReferenceCounting::Error: kind = ScalarKind::ErrorReference; break ; \
696
+ } \
697
+ return IGM.typeLayoutCache .getOrCreateScalarEntry (*this , T, kind); \
687
698
} \
688
699
void emitValueAssignWithCopy (IRGenFunction &IGF, \
689
700
Address dest, Address src) const { \
@@ -731,7 +742,16 @@ namespace {
731
742
} \
732
743
TypeLayoutEntry *buildTypeLayoutEntry (IRGenModule &IGM, \
733
744
SILType T) const override { \
734
- return IGM.typeLayoutCache .getOrCreateScalarEntry (*this , T); \
745
+ ScalarKind kind; \
746
+ switch (Refcounting) { \
747
+ case ReferenceCounting::Native: kind = ScalarKind::NativeStrongReference; break ; \
748
+ case ReferenceCounting::ObjC: kind = ScalarKind::ObjCReference; break ; \
749
+ case ReferenceCounting::Block: kind = ScalarKind::BlockReference; break ; \
750
+ case ReferenceCounting::Unknown: kind = ScalarKind::UnknownReference; break ; \
751
+ case ReferenceCounting::Bridge: kind = ScalarKind::BridgeReference; break ; \
752
+ case ReferenceCounting::Error: kind = ScalarKind::ErrorReference; break ; \
753
+ } \
754
+ return IGM.typeLayoutCache .getOrCreateScalarEntry (*this , T, kind); \
735
755
} \
736
756
llvm::Type *getValueType () const { \
737
757
return ValueType; \
@@ -778,7 +798,7 @@ namespace {
778
798
spareBits, align, IsPOD, IsFixedSize) {} \
779
799
TypeLayoutEntry *buildTypeLayoutEntry (IRGenModule &IGM, \
780
800
SILType T) const override { \
781
- return IGM.typeLayoutCache .getOrCreateScalarEntry (*this , T); \
801
+ return IGM.typeLayoutCache .getOrCreateScalarEntry (*this , T, ScalarKind::POD ); \
782
802
} \
783
803
const LoadableTypeInfo & \
784
804
getValueTypeInfoForExtraInhabitants (IRGenModule &IGM) const { \
@@ -847,7 +867,8 @@ class OpaqueExistentialTypeInfo final :
847
867
848
868
TypeLayoutEntry *buildTypeLayoutEntry (IRGenModule &IGM,
849
869
SILType T) const override {
850
- return IGM.typeLayoutCache .getOrCreateScalarEntry (*this , T);
870
+ return IGM.typeLayoutCache .getOrCreateScalarEntry (
871
+ *this , T, ScalarKind::ExistentialReference);
851
872
}
852
873
853
874
Address projectWitnessTable (IRGenFunction &IGF, Address obj,
@@ -995,7 +1016,21 @@ class ClassExistentialTypeInfo final
995
1016
996
1017
TypeLayoutEntry *buildTypeLayoutEntry (IRGenModule &IGM,
997
1018
SILType T) const override {
998
- return IGM.typeLayoutCache .getOrCreateScalarEntry (*this , T);
1019
+ ScalarKind kind;
1020
+ switch (Refcounting) {
1021
+ case ReferenceCounting::Native:
1022
+ kind = ScalarKind::NativeStrongReference;
1023
+ break ;
1024
+ case ReferenceCounting::ObjC:
1025
+ kind = ScalarKind::ObjCReference;
1026
+ break ;
1027
+ case ReferenceCounting::Unknown:
1028
+ kind = ScalarKind::UnknownReference;
1029
+ break ;
1030
+ default :
1031
+ llvm_unreachable (" Unsupported refcounting style" );
1032
+ }
1033
+ return IGM.typeLayoutCache .getOrCreateScalarEntry (*this , T, kind);
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