@@ -931,6 +931,38 @@ static llvm::Constant *getEnumTagFunction(IRGenModule &IGM,
931
931
}
932
932
}
933
933
934
+ static llvm::Constant *
935
+ getDestructiveInjectEnumTagFunction (IRGenModule &IGM,
936
+ const EnumTypeLayoutEntry *typeLayoutEntry,
937
+ GenericSignature genericSig) {
938
+ if ((!typeLayoutEntry->layoutString (IGM, genericSig) &&
939
+ !isRuntimeInstatiatedLayoutString (IGM, typeLayoutEntry)) ||
940
+ typeLayoutEntry->isSingleton ()) {
941
+ return nullptr ;
942
+ } else if (!typeLayoutEntry->isFixedSize (IGM)) {
943
+ if (typeLayoutEntry->isMultiPayloadEnum ()) {
944
+ return nullptr ;
945
+ } else {
946
+ return IGM.getSinglePayloadEnumGenericDestructiveInjectEnumTagFn ();
947
+ }
948
+ } else if (typeLayoutEntry->isMultiPayloadEnum ()) {
949
+ return nullptr ;
950
+ } else {
951
+ auto &payloadTI = **(typeLayoutEntry->cases [0 ]->getFixedTypeInfo ());
952
+ auto mask = payloadTI.getFixedExtraInhabitantMask (IGM);
953
+ auto tzCount = mask.countTrailingZeros ();
954
+ auto shiftedMask = mask.lshr (tzCount);
955
+ auto toCount = shiftedMask.countTrailingOnes ();
956
+ if (payloadTI.mayHaveExtraInhabitants (IGM) &&
957
+ (mask.countPopulation () > 64 || toCount != mask.countPopulation () ||
958
+ (tzCount % toCount != 0 ))) {
959
+ return nullptr ;
960
+ } else {
961
+ return nullptr ;
962
+ }
963
+ }
964
+ }
965
+
934
966
static bool
935
967
valueWitnessRequiresCopyability (ValueWitness index) {
936
968
switch (index) {
@@ -1189,8 +1221,31 @@ addValueWitness(IRGenModule &IGM, ConstantStructBuilder &B, ValueWitness index,
1189
1221
}
1190
1222
goto standard;
1191
1223
}
1224
+ case ValueWitness::DestructiveInjectEnumTag: {
1225
+ assert (concreteType.getEnumOrBoundGenericEnum ());
1226
+ if (IGM.Context .LangOpts .hasFeature (Feature::LayoutStringValueWitnesses) &&
1227
+ IGM.getOptions ().EnableLayoutStringValueWitnesses ) {
1228
+ auto ty = boundGenericCharacteristics
1229
+ ? boundGenericCharacteristics->concreteType
1230
+ : concreteType;
1231
+ auto &typeInfo = boundGenericCharacteristics
1232
+ ? *boundGenericCharacteristics->TI
1233
+ : concreteTI;
1234
+ if (auto *typeLayoutEntry = typeInfo.buildTypeLayoutEntry (
1235
+ IGM, ty, /* useStructLayouts*/ true )) {
1236
+ if (auto *enumLayoutEntry = typeLayoutEntry->getAsEnum ()) {
1237
+ auto genericSig = concreteType.getNominalOrBoundGenericNominal ()
1238
+ ->getGenericSignature ();
1239
+ if (auto *fn = getDestructiveInjectEnumTagFunction (
1240
+ IGM, enumLayoutEntry, genericSig)) {
1241
+ return addFunction (fn);
1242
+ }
1243
+ }
1244
+ }
1245
+ }
1246
+ goto standard;
1247
+ }
1192
1248
case ValueWitness::DestructiveProjectEnumData:
1193
- case ValueWitness::DestructiveInjectEnumTag:
1194
1249
assert (concreteType.getEnumOrBoundGenericEnum ());
1195
1250
goto standard;
1196
1251
}
0 commit comments