@@ -154,24 +154,21 @@ namespace {
154154 // The subclass should implement:
155155 // // Trivial, fixed-layout, and non-address-only.
156156 // RetTy handleTrivial(CanType);
157+ // RetTy handleTrivial(CanType. RecursiveProperties properties);
157158 // // A reference type.
158159 // RetTy handleReference(CanType);
159160 // // Non-trivial and address-only.
160161 // RetTy handleAddressOnly(CanType, RecursiveProperties properties);
161162 // and, if it doesn't override handleTupleType,
162163 // // An aggregate type that's non-trivial.
163- // RetTy handleNonTrivialAggregate(CanType, IsFixedABI_t fixed );
164+ // RetTy handleNonTrivialAggregate(CanType, RecursiveProperties properties );
164165 //
165166 // Alternatively, it can just implement:
166167 // RetTy handle(CanType, RecursiveProperties properties);
167168
168169 // / Handle a trivial, fixed-size, loadable type.
169- RetTy handleTrivial (CanType type) {
170- return asImpl ().handle (type, RecursiveProperties ());
171- }
172-
173- RetTy handleReference (CanType type) {
174- return asImpl ().handle (type, RecursiveProperties::forReference ());
170+ RetTy handleTrivial (CanType type, RecursiveProperties properties) {
171+ return asImpl ().handle (type, properties);
175172 }
176173
177174 RetTy handleAddressOnly (CanType type, RecursiveProperties properties) {
@@ -183,6 +180,13 @@ namespace {
183180 return asImpl ().handle (type, properties);
184181 }
185182
183+ RetTy handleTrivial (CanType type) {
184+ return asImpl ().handleTrivial (type, RecursiveProperties::forTrivial ());
185+ }
186+ RetTy handleReference (CanType type) {
187+ return asImpl ().handle (type, RecursiveProperties::forReference ());
188+ }
189+
186190#define IMPL (TYPE, LOWERING ) \
187191 RetTy visit##TYPE##Type(Can##TYPE##Type type) { \
188192 return asImpl ().handle ##LOWERING (type); \
@@ -207,7 +211,7 @@ namespace {
207211 RetTy visitBuiltinUnsafeValueBufferType (
208212 CanBuiltinUnsafeValueBufferType type) {
209213 return asImpl ().handleAddressOnly (type, {IsNotTrivial, IsFixedABI,
210- IsAddressOnly});
214+ IsAddressOnly, IsNotResilient });
211215 }
212216
213217 RetTy visitAnyFunctionType (CanAnyFunctionType type) {
@@ -305,7 +309,8 @@ namespace {
305309 RetTy visit##Name##StorageType(Can##Name##StorageType type) { \
306310 return asImpl ().handleAddressOnly (type, {IsNotTrivial, \
307311 IsFixedABI, \
308- IsAddressOnly}); \
312+ IsAddressOnly, \
313+ IsNotResilient}); \
309314 }
310315#define ALWAYS_LOADABLE_CHECKED_REF_STORAGE (Name, ...) \
311316 RetTy visit##Name##StorageType(Can##Name##StorageType type) { \
@@ -318,7 +323,8 @@ namespace {
318323 RetTy visitAddressOnly##Name##StorageType(Can##Name##StorageType type) { \
319324 return asImpl ().handleAddressOnly (type, {IsNotTrivial, \
320325 IsFixedABI, \
321- IsAddressOnly}); \
326+ IsAddressOnly, \
327+ IsNotResilient}); \
322328 } \
323329 RetTy visit##Name##StorageType(Can##Name##StorageType type) { \
324330 auto referentType = type->getReferentType (); \
@@ -349,8 +355,9 @@ namespace {
349355 }
350356
351357 if (LayoutInfo->isAddressOnlyTrivial ()) {
352- return asImpl ().handleAddressOnly (type,
353- {IsTrivial, IsNotFixedABI, IsAddressOnly});
358+ auto properties = RecursiveProperties::forTrivial ();
359+ properties.setAddressOnly ();
360+ return asImpl ().handleAddressOnly (type, properties);
354361 }
355362
356363 if (LayoutInfo->isRefCounted ())
@@ -368,7 +375,8 @@ namespace {
368375 case ExistentialRepresentation::Opaque:
369376 return asImpl ().handleAddressOnly (type, {IsNotTrivial,
370377 IsFixedABI,
371- IsAddressOnly});
378+ IsAddressOnly,
379+ IsNotResilient});
372380 // Class-constrained and boxed existentials are refcounted.
373381 case ExistentialRepresentation::Class:
374382 case ExistentialRepresentation::Boxed:
@@ -418,8 +426,10 @@ namespace {
418426
419427 RetTy visitSILBlockStorageType (CanSILBlockStorageType type) {
420428 // Should not be loaded.
421- return asImpl ().handleAddressOnly (type, {IsNotTrivial, IsFixedABI,
422- IsAddressOnly});
429+ return asImpl ().handleAddressOnly (type, {IsNotTrivial,
430+ IsFixedABI,
431+ IsAddressOnly,
432+ IsNotResilient});
423433 }
424434
425435 RetTy visitSILBoxType (CanSILBoxType type) {
@@ -547,9 +557,14 @@ namespace {
547557 // / A class for trivial, fixed-layout, loadable types.
548558 class TrivialTypeLowering final : public LoadableTypeLowering {
549559 public:
550- TrivialTypeLowering (SILType type, ResilienceExpansion forExpansion)
551- : LoadableTypeLowering(type, {IsTrivial, IsFixedABI, IsNotAddressOnly},
552- IsNotReferenceCounted, forExpansion) {}
560+ TrivialTypeLowering (SILType type, RecursiveProperties properties,
561+ ResilienceExpansion forExpansion)
562+ : LoadableTypeLowering(type, properties, IsNotReferenceCounted,
563+ forExpansion) {
564+ assert (properties.isFixedABI ());
565+ assert (properties.isTrivial ());
566+ assert (!properties.isAddressOnly ());
567+ }
553568
554569 SILValue emitLoadOfCopy (SILBuilder &B, SILLocation loc, SILValue addr,
555570 IsTake_t isTake) const override {
@@ -610,14 +625,6 @@ namespace {
610625
611626 class NonTrivialLoadableTypeLowering : public LoadableTypeLowering {
612627 public:
613- NonTrivialLoadableTypeLowering (SILType type,
614- IsReferenceCounted_t isRefCounted,
615- ResilienceExpansion forExpansion)
616- : NonTrivialLoadableTypeLowering(type,
617- {IsNotTrivial, IsFixedABI, IsNotAddressOnly},
618- isRefCounted, forExpansion) {}
619-
620- // / This constructor is necessary because of opaque-values.
621628 NonTrivialLoadableTypeLowering (SILType type,
622629 RecursiveProperties properties,
623630 IsReferenceCounted_t isRefCounted,
@@ -713,9 +720,11 @@ namespace {
713720 const = 0;
714721
715722 public:
716- LoadableAggTypeLowering (CanType type, ResilienceExpansion forExpansion)
723+ LoadableAggTypeLowering (CanType type, RecursiveProperties properties,
724+ ResilienceExpansion forExpansion)
717725 : NonTrivialLoadableTypeLowering(SILType::getPrimitiveObjectType(type),
718- IsNotReferenceCounted, forExpansion) {
726+ properties, IsNotReferenceCounted,
727+ forExpansion) {
719728 }
720729
721730 virtual SILValue rebuildAggregate (SILBuilder &B, SILLocation loc,
@@ -830,8 +839,9 @@ namespace {
830839 class LoadableTupleTypeLowering final
831840 : public LoadableAggTypeLowering<LoadableTupleTypeLowering, unsigned > {
832841 public:
833- LoadableTupleTypeLowering (CanType type, ResilienceExpansion forExpansion)
834- : LoadableAggTypeLowering(type, forExpansion) {}
842+ LoadableTupleTypeLowering (CanType type, RecursiveProperties properties,
843+ ResilienceExpansion forExpansion)
844+ : LoadableAggTypeLowering(type, properties, forExpansion) {}
835845
836846 SILValue emitRValueProject (SILBuilder &B, SILLocation loc,
837847 SILValue tupleValue, unsigned index,
@@ -866,8 +876,9 @@ namespace {
866876 class LoadableStructTypeLowering final
867877 : public LoadableAggTypeLowering<LoadableStructTypeLowering, VarDecl*> {
868878 public:
869- LoadableStructTypeLowering (CanType type, ResilienceExpansion forExpansion)
870- : LoadableAggTypeLowering(type, forExpansion) {}
879+ LoadableStructTypeLowering (CanType type, RecursiveProperties properties,
880+ ResilienceExpansion forExpansion)
881+ : LoadableAggTypeLowering(type, properties, forExpansion) {}
871882
872883 SILValue emitRValueProject (SILBuilder &B, SILLocation loc,
873884 SILValue structValue, VarDecl *field,
@@ -899,8 +910,10 @@ namespace {
899910 // / A lowering for loadable but non-trivial enum types.
900911 class LoadableEnumTypeLowering final : public NonTrivialLoadableTypeLowering {
901912 public:
902- LoadableEnumTypeLowering (CanType type, ResilienceExpansion forExpansion)
913+ LoadableEnumTypeLowering (CanType type, RecursiveProperties properties,
914+ ResilienceExpansion forExpansion)
903915 : NonTrivialLoadableTypeLowering(SILType::getPrimitiveObjectType(type),
916+ properties,
904917 IsNotReferenceCounted,
905918 forExpansion) {}
906919
@@ -1021,8 +1034,9 @@ namespace {
10211034 AddressOnlyTypeLowering (SILType type, RecursiveProperties properties,
10221035 ResilienceExpansion forExpansion)
10231036 : TypeLowering(type, properties, IsNotReferenceCounted,
1024- forExpansion)
1025- {}
1037+ forExpansion) {
1038+ assert (properties.isAddressOnly ());
1039+ }
10261040
10271041 void emitCopyInto (SILBuilder &B, SILLocation loc,
10281042 SILValue src, SILValue dest, IsTake_t isTake,
@@ -1092,7 +1106,8 @@ namespace {
10921106 UnsafeValueBufferTypeLowering (SILType type,
10931107 ResilienceExpansion forExpansion)
10941108 : AddressOnlyTypeLowering(type,
1095- {IsNotTrivial, IsFixedABI, IsAddressOnly},
1109+ {IsNotTrivial, IsFixedABI,
1110+ IsAddressOnly, IsNotResilient},
10961111 forExpansion) {}
10971112
10981113 void emitCopyInto (SILBuilder &B, SILLocation loc,
@@ -1168,8 +1183,14 @@ namespace {
11681183 TC (TC), Dependent(Dependent) {}
11691184
11701185 TypeLowering *handleTrivial (CanType type) {
1186+ return handleTrivial (type, RecursiveProperties::forTrivial ());
1187+ }
1188+
1189+ TypeLowering *handleTrivial (CanType type,
1190+ RecursiveProperties properties) {
11711191 auto silType = SILType::getPrimitiveObjectType (type);
1172- return new (TC, Dependent) TrivialTypeLowering (silType, Expansion);
1192+ return new (TC, Dependent) TrivialTypeLowering (silType, properties,
1193+ Expansion);
11731194 }
11741195
11751196 TypeLowering *handleReference (CanType type) {
@@ -1223,16 +1244,37 @@ namespace {
12231244 properties);
12241245 }
12251246
1247+ bool handleResilience (CanType type, NominalTypeDecl *D,
1248+ RecursiveProperties &properties) {
1249+ if (D->isResilient ()) {
1250+ // If the type is resilient and defined in our module, make a note of
1251+ // that, since our lowering now depends on the resilience expansion.
1252+ bool sameModule = (D->getModuleContext () == M.getSwiftModule ());
1253+ if (sameModule)
1254+ properties.addSubobject (RecursiveProperties::forResilient ());
1255+
1256+ // If the type is in a different module, or if we're using a minimal
1257+ // expansion, the type is address only and completely opaque to us.
1258+ //
1259+ // Note: if the type is in a different module, the lowering does
1260+ // not depend on the resilience expansion, so we do not need to set
1261+ // the isResilent() flag above.
1262+ if (!sameModule || Expansion == ResilienceExpansion::Minimal) {
1263+ properties.addSubobject (RecursiveProperties::forOpaque ());
1264+ return true ;
1265+ }
1266+ }
1267+
1268+ return false ;
1269+ }
1270+
12261271 TypeLowering *visitAnyStructType (CanType structType, StructDecl *D) {
1272+ RecursiveProperties properties;
12271273
1228- // For now, if the type does not have a fixed layout in all resilience
1229- // domains, we will treat it as address-only in SIL.
1230- if (D->isResilient (M.getSwiftModule (), Expansion))
1231- return handleAddressOnly (structType,
1232- RecursiveProperties::forResilient ());
1274+ if (handleResilience (structType, D, properties))
1275+ return handleAddressOnly (structType, properties);
12331276
12341277 // Classify the type according to its stored properties.
1235- RecursiveProperties properties;
12361278 for (auto field : D->getStoredProperties ()) {
12371279 auto substFieldType =
12381280 structType->getTypeOfMember (D->getModuleContext (), field, nullptr );
@@ -1245,22 +1287,24 @@ namespace {
12451287 }
12461288
12471289 TypeLowering *visitAnyEnumType (CanType enumType, EnumDecl *D) {
1248- // For now, if the type does not have a fixed layout in all resilience
1249- // domains, we will treat it as address-only in SIL.
1250- if (D-> isResilient (M. getSwiftModule (), Expansion ))
1251- return handleAddressOnly (enumType, RecursiveProperties::forResilient () );
1290+ RecursiveProperties properties;
1291+
1292+ if (handleResilience (enumType, D, properties ))
1293+ return handleAddressOnly (enumType, properties );
12521294
12531295 // If the whole enum is indirect, we lower it as if all payload
12541296 // cases were indirect. This means a fixed-layout indirect enum
12551297 // is always loadable and nontrivial. A resilient indirect enum
12561298 // is still address only, because we don't know how many bits
1257- // are used for the discriminator.
1299+ // are used for the discriminator, and new non-indirect cases
1300+ // may be added resiliently later.
12581301 if (D->isIndirect ()) {
1259- return new (TC, Dependent) LoadableEnumTypeLowering (enumType, Expansion);
1302+ properties.setNonTrivial ();
1303+ return new (TC, Dependent) LoadableEnumTypeLowering (enumType, properties,
1304+ Expansion);
12601305 }
12611306
12621307 // Accumulate the properties of all direct payloads.
1263- RecursiveProperties properties;
12641308 for (auto elt : D->getAllElements ()) {
12651309 // No-payload elements do not affect any recursive properties.
12661310 if (!elt->hasAssociatedValues ())
@@ -1292,9 +1336,9 @@ namespace {
12921336 }
12931337 assert (props.isFixedABI ());
12941338 if (props.isTrivial ()) {
1295- return handleTrivial (type);
1339+ return handleTrivial (type, props );
12961340 }
1297- return new (TC, Dependent) LoadableLoweringClass (type, Expansion);
1341+ return new (TC, Dependent) LoadableLoweringClass (type, props, Expansion);
12981342 }
12991343 };
13001344} // end anonymous namespace
@@ -1664,6 +1708,9 @@ getTypeLoweringForExpansion(TypeKey key,
16641708 if (!lowering->isResilient ()) {
16651709 // Don't try to refine the lowering for other resilience expansions if
16661710 // we don't expect to get a different lowering anyway.
1711+ //
1712+ // See LowerType::handleResilience() for the gory details; we only
1713+ // set this flag if the type is resilient *and* inside our module.
16671714 return lowering;
16681715 }
16691716
0 commit comments