@@ -152,7 +152,10 @@ enum class LoweredTypeKind {
152
152
AggWithReference,
153
153
154
154
// / Non-trivial and not loadable.
155
- AddressOnly
155
+ AddressOnly,
156
+
157
+ // / Trivial and not loadable.
158
+ TrivialAddressOnly
156
159
};
157
160
158
161
static LoweredTypeKind classifyType (CanType type, SILModule &M,
@@ -178,6 +181,7 @@ namespace {
178
181
// RetTy handleAddressOnly(CanType);
179
182
// RetTy handleReference(CanType);
180
183
// RetTy handleTrivial(CanType);
184
+ // RetTy handleTrivialAddressOnly(CanType);
181
185
// In addition, if it does not override visitTupleType
182
186
// and visitAnyStructType, it should also implement:
183
187
// RetTy handleAggWithReference(CanType);
@@ -317,9 +321,22 @@ namespace {
317
321
RetTy visitArchetypeType (CanArchetypeType type) {
318
322
if (type->requiresClass ()) {
319
323
return asImpl ().handleReference (type);
320
- } else {
321
- return asImpl ().handleAddressOnly (type);
322
324
}
325
+
326
+ auto LayoutInfo = type->getLayoutConstraint ();
327
+ if (LayoutInfo) {
328
+ if (LayoutInfo->isFixedSizeTrivial ()) {
329
+ return asImpl ().handleTrivial (type);
330
+ }
331
+
332
+ if (LayoutInfo->isAddressOnlyTrivial ()) {
333
+ return asImpl ().handleTrivialAddressOnly (type);
334
+ }
335
+
336
+ if (LayoutInfo->isRefCountedObject ())
337
+ return asImpl ().handleReference (type);
338
+ }
339
+ return asImpl ().handleAddressOnly (type);
323
340
}
324
341
325
342
RetTy visitExistentialType (CanType type) {
@@ -371,6 +388,8 @@ namespace {
371
388
switch (classifyType (eltType, M, Sig, Expansion)) {
372
389
case LoweredTypeKind::Trivial:
373
390
continue ;
391
+ case LoweredTypeKind::TrivialAddressOnly:
392
+ return asImpl ().handleTrivialAddressOnly (type);
374
393
case LoweredTypeKind::AddressOnly:
375
394
return asImpl ().handleAddressOnly (type);
376
395
case LoweredTypeKind::Reference:
@@ -414,9 +433,16 @@ namespace {
414
433
LoweredTypeKind handleAggWithReference (CanType type) {
415
434
return LoweredTypeKind::AggWithReference;
416
435
}
417
- LoweredTypeKind handleTrivial (CanType type) {
436
+ LoweredTypeKind
437
+ handleTrivial (CanType type) {
418
438
return LoweredTypeKind::Trivial;
419
439
}
440
+
441
+ LoweredTypeKind
442
+ handleTrivialAddressOnly (CanType type) {
443
+ return LoweredTypeKind::TrivialAddressOnly;
444
+ }
445
+
420
446
LoweredTypeKind handleAddressOnly (CanType type) {
421
447
return LoweredTypeKind::AddressOnly;
422
448
}
@@ -1134,6 +1160,71 @@ namespace {
1134
1160
}
1135
1161
};
1136
1162
1163
+ // / A class for trivial, address-only types.
1164
+ class AddressOnlyTrivialTypeLowering : public TypeLowering {
1165
+ public:
1166
+ AddressOnlyTrivialTypeLowering (SILType type)
1167
+ : TypeLowering(type, IsTrivial, IsAddressOnly, IsNotReferenceCounted)
1168
+ {}
1169
+
1170
+ void emitCopyInto (SILBuilder &B, SILLocation loc,
1171
+ SILValue src, SILValue dest, IsTake_t isTake,
1172
+ IsInitialization_t isInit) const override {
1173
+ B.createCopyAddr (loc, src, dest, isTake, isInit);
1174
+ }
1175
+
1176
+ SILValue emitLoadOfCopy (SILBuilder &B, SILLocation loc,
1177
+ SILValue addr, IsTake_t isTake) const override {
1178
+ llvm_unreachable (" calling emitLoadOfCopy on non-loadable type" );
1179
+ }
1180
+
1181
+ void emitStoreOfCopy (SILBuilder &B, SILLocation loc,
1182
+ SILValue newValue, SILValue addr,
1183
+ IsInitialization_t isInit) const override {
1184
+ llvm_unreachable (" calling emitStoreOfCopy on non-loadable type" );
1185
+ }
1186
+
1187
+ void emitStore (SILBuilder &B, SILLocation loc, SILValue value,
1188
+ SILValue addr, StoreOwnershipQualifier qual) const override {
1189
+ llvm_unreachable (" calling emitStore on non-loadable type" );
1190
+ }
1191
+
1192
+ SILValue emitLoad (SILBuilder &B, SILLocation loc, SILValue addr,
1193
+ LoadOwnershipQualifier qual) const override {
1194
+ llvm_unreachable (" calling emitLoad on non-loadable type" );
1195
+ }
1196
+
1197
+ void emitDestroyAddress (SILBuilder &B, SILLocation loc,
1198
+ SILValue addr) const override {
1199
+ }
1200
+
1201
+ void emitDestroyRValue (SILBuilder &B, SILLocation loc,
1202
+ SILValue value) const override {
1203
+ }
1204
+
1205
+ SILValue emitCopyValue (SILBuilder &B, SILLocation loc,
1206
+ SILValue value) const override {
1207
+ llvm_unreachable (" type is not loadable!" );
1208
+ }
1209
+
1210
+ SILValue emitLoweredCopyValue (SILBuilder &B, SILLocation loc,
1211
+ SILValue value,
1212
+ LoweringStyle style) const override {
1213
+ llvm_unreachable (" type is not loadable!" );
1214
+ }
1215
+
1216
+ void emitDestroyValue (SILBuilder &B, SILLocation loc,
1217
+ SILValue value) const override {
1218
+ llvm_unreachable (" type is not loadable!" );
1219
+ }
1220
+
1221
+ void emitLoweredDestroyValue (SILBuilder &B, SILLocation loc, SILValue value,
1222
+ LoweringStyle style) const override {
1223
+ llvm_unreachable (" type is not loadable!" );
1224
+ }
1225
+ };
1226
+
1227
+
1137
1228
// / Build the appropriate TypeLowering subclass for the given type,
1138
1229
// / which is assumed to already have been lowered.
1139
1230
class LowerType
@@ -1147,11 +1238,18 @@ namespace {
1147
1238
: TypeClassifierBase(TC.M, Sig, Expansion),
1148
1239
TC (TC), Dependent(Dependent) {}
1149
1240
1150
- const TypeLowering *handleTrivial (CanType type) {
1241
+ const TypeLowering *
1242
+ handleTrivial (CanType type) {
1151
1243
auto silType = SILType::getPrimitiveObjectType (type);
1152
1244
return new (TC, Dependent) TrivialTypeLowering (silType);
1153
1245
}
1154
-
1246
+
1247
+ const TypeLowering *
1248
+ handleTrivialAddressOnly (CanType type) {
1249
+ auto silType = SILType::getPrimitiveObjectType (type);
1250
+ return new (TC, Dependent) AddressOnlyTrivialTypeLowering (silType);
1251
+ }
1252
+
1155
1253
const TypeLowering *handleReference (CanType type) {
1156
1254
auto silType = SILType::getPrimitiveObjectType (type);
1157
1255
return new (TC, Dependent) ReferenceTypeLowering (silType);
@@ -1208,6 +1306,7 @@ namespace {
1208
1306
structType->getTypeOfMember (D->getModuleContext (), field, nullptr );
1209
1307
switch (classifyType (substFieldType->getCanonicalType (),
1210
1308
M, Sig, Expansion)) {
1309
+ case LoweredTypeKind::TrivialAddressOnly:
1211
1310
case LoweredTypeKind::AddressOnly:
1212
1311
return handleAddressOnly (structType);
1213
1312
case LoweredTypeKind::AggWithReference:
@@ -1260,6 +1359,7 @@ namespace {
1260
1359
->getCanonicalType ();
1261
1360
1262
1361
switch (classifyType (substEltType, M, Sig, Expansion)) {
1362
+ case LoweredTypeKind::TrivialAddressOnly:
1263
1363
case LoweredTypeKind::AddressOnly:
1264
1364
return handleAddressOnly (enumType);
1265
1365
case LoweredTypeKind::AggWithReference:
0 commit comments