@@ -663,6 +663,15 @@ namespace {
663663 metadata);
664664 }
665665
666+ void initializeMetadataWithLayoutString (IRGenFunction &IGF,
667+ llvm::Value *metadata,
668+ bool isVWTMutable,
669+ SILType T,
670+ MetadataDependencyCollector *collector) const override {
671+ // Not yet supported on this type, so forward to regular method
672+ initializeMetadata (IGF, metadata, isVWTMutable, T, collector);
673+ }
674+
666675 bool mayHaveExtraInhabitants (IRGenModule &IGM) const override {
667676 // FIXME: Hold off on registering extra inhabitants for dynamic enums
668677 // until initializeMetadata handles them.
@@ -964,6 +973,15 @@ namespace {
964973 // witness table initialization.
965974 }
966975
976+ void initializeMetadataWithLayoutString (IRGenFunction &IGF,
977+ llvm::Value *metadata,
978+ bool isVWTMutable,
979+ SILType T,
980+ MetadataDependencyCollector *collector) const override {
981+ // No-payload enums are always fixed-size so never need dynamic value
982+ // witness table initialization.
983+ }
984+
967985 // / \group Required for SingleScalarTypeInfo
968986
969987 llvm::Type *getScalarType () const {
@@ -3189,6 +3207,15 @@ namespace {
31893207 {metadata, flags, payloadLayout, emptyCasesVal});
31903208 }
31913209
3210+ void initializeMetadataWithLayoutString (IRGenFunction &IGF,
3211+ llvm::Value *metadata,
3212+ bool isVWTMutable,
3213+ SILType T,
3214+ MetadataDependencyCollector *collector) const override {
3215+ // Not yet supported on this type, so forward to regular method
3216+ initializeMetadata (IGF, metadata, isVWTMutable, T, collector);
3217+ }
3218+
31923219 // / \group Extra inhabitants
31933220
31943221 // Extra inhabitants from the payload that we didn't use for our empty cases
@@ -5259,6 +5286,36 @@ namespace {
52595286 return firstAddr;
52605287 }
52615288
5289+ llvm::Value *emitPayloadMetadataArray (IRGenFunction &IGF, SILType T,
5290+ MetadataDependencyCollector *collector) const {
5291+ auto numPayloads = ElementsWithPayload.size ();
5292+ auto metadataBufferTy = llvm::ArrayType::get (IGM.TypeMetadataPtrTy ,
5293+ numPayloads);
5294+ auto metadataBuffer = IGF.createAlloca (metadataBufferTy,
5295+ IGM.getPointerAlignment (),
5296+ " payload_types" );
5297+ llvm::Value *firstAddr = nullptr ;
5298+ for (unsigned i = 0 ; i < numPayloads; ++i) {
5299+ auto &elt = ElementsWithPayload[i];
5300+ Address eltAddr = IGF.Builder .CreateStructGEP (metadataBuffer, i,
5301+ IGM.getPointerSize () * i);
5302+ if (i == 0 ) firstAddr = eltAddr.getAddress ();
5303+
5304+ auto payloadTy =
5305+ T.getEnumElementType (elt.decl , IGF.getSILModule (),
5306+ IGF.IGM .getMaximalTypeExpansionContext ());
5307+
5308+ auto request = DynamicMetadataRequest::getNonBlocking (
5309+ MetadataState::LayoutComplete, collector);
5310+ auto metadata = IGF.emitTypeMetadataRefForLayout (payloadTy, request);
5311+
5312+ IGF.Builder .CreateStore (metadata, eltAddr);
5313+ }
5314+ assert (firstAddr && " Expected firstAddr to be assigned to" );
5315+
5316+ return firstAddr;
5317+ }
5318+
52625319 void initializeMetadata (IRGenFunction &IGF,
52635320 llvm::Value *metadata,
52645321 bool isVWTMutable,
@@ -5278,6 +5335,25 @@ namespace {
52785335 {metadata, flags, numPayloadsVal, payloadLayoutArray});
52795336 }
52805337
5338+ void initializeMetadataWithLayoutString (IRGenFunction &IGF,
5339+ llvm::Value *metadata,
5340+ bool isVWTMutable,
5341+ SILType T,
5342+ MetadataDependencyCollector *collector) const override {
5343+ // Fixed-size enums don't need dynamic metadata initialization.
5344+ if (TIK >= Fixed) return ;
5345+
5346+ // Ask the runtime to set up the metadata record for a dynamic enum.
5347+ auto payloadLayoutArray = emitPayloadMetadataArray (IGF, T, collector);
5348+ auto numPayloadsVal = llvm::ConstantInt::get (IGM.SizeTy ,
5349+ ElementsWithPayload.size ());
5350+
5351+ auto flags = emitEnumLayoutFlags (IGM, isVWTMutable);
5352+ IGF.Builder .CreateCall (
5353+ IGM.getInitEnumMetadataMultiPayloadWithLayoutStringFunctionPointer (),
5354+ {metadata, flags, numPayloadsVal, payloadLayoutArray});
5355+ }
5356+
52815357 // / \group Extra inhabitants
52825358
52835359 // If we didn't use all of the available tag bit representations, offer
@@ -5959,6 +6035,14 @@ namespace {
59596035 llvm_unreachable (" resilient enums cannot be defined" );
59606036 }
59616037
6038+ void initializeMetadataWithLayoutString (IRGenFunction &IGF,
6039+ llvm::Value *metadata,
6040+ bool isVWTMutable,
6041+ SILType T,
6042+ MetadataDependencyCollector *collector) const override {
6043+ llvm_unreachable (" resilient enums cannot be defined" );
6044+ }
6045+
59626046 // / \group Extra inhabitants
59636047
59646048 bool mayHaveExtraInhabitants (IRGenModule &) const override {
0 commit comments