@@ -1942,6 +1942,10 @@ namespace {
19421942 ConformanceDescription Description;
19431943 ConformanceFlags Flags;
19441944
1945+ using PlaceholderPosition =
1946+ ConstantAggregateBuilderBase::PlaceholderPosition;
1947+ Optional<PlaceholderPosition> FlagsPP;
1948+
19451949 public:
19461950 ProtocolConformanceDescriptorBuilder (
19471951 IRGenModule &IGM,
@@ -1960,6 +1964,11 @@ namespace {
19601964 addResilientWitnesses ();
19611965 addGenericWitnessTable ();
19621966
1967+ // We fill the flags last, since we continue filling them in
1968+ // after the call to addFlags() deposits the placeholder.
1969+ B.fillPlaceholderWithInt (*FlagsPP, IGM.Int32Ty ,
1970+ Flags.getIntValue ());
1971+
19631972 B.suggestType (IGM.ProtocolConformanceDescriptorTy );
19641973 }
19651974
@@ -1981,13 +1990,6 @@ namespace {
19811990 }
19821991
19831992 void addWitnessTable () {
1984- // Note the number of conditional requirements.
1985- unsigned numConditional = 0 ;
1986- if (auto normal = dyn_cast<NormalProtocolConformance>(Conformance)) {
1987- numConditional = normal->getConditionalRequirements ().size ();
1988- }
1989- Flags = Flags.withNumConditionalRequirements (numConditional);
1990-
19911993 // Relative reference to the witness table.
19921994 B.addRelativeAddressOrNull (Description.pattern );
19931995 }
@@ -2001,13 +2003,9 @@ namespace {
20012003 Flags = Flags.withIsRetroactive (false )
20022004 .withIsSynthesizedNonUnique (false );
20032005 }
2004- Flags = Flags.withHasResilientWitnesses (
2005- !Description.resilientWitnesses .empty ());
2006- Flags =
2007- Flags.withHasGenericWitnessTable (Description.requiresSpecialization );
20082006
2009- // Add the flags.
2010- B. addInt32 (Flags. getIntValue () );
2007+ // Add a placeholder for the flags.
2008+ FlagsPP = B. addPlaceholderWithSize (IGM. Int32Ty );
20112009 }
20122010
20132011 void addContext () {
@@ -2025,19 +2023,42 @@ namespace {
20252023
20262024 void addConditionalRequirements () {
20272025 auto normal = dyn_cast<NormalProtocolConformance>(Conformance);
2028- if (!normal || normal-> getConditionalRequirements (). empty () )
2026+ if (!normal)
20292027 return ;
20302028
2031- auto nominal = normal->getType ()->getAnyNominal ();
2032- irgen::addGenericRequirements (IGM, B,
2033- nominal->getGenericSignatureOfContext (),
2034- normal->getConditionalRequirements ());
2029+ auto condReqs = normal->getConditionalRequirements ();
2030+ if (condReqs.empty ())
2031+ return ;
2032+
2033+ Flags = Flags.withNumConditionalRequirements (condReqs.size ());
2034+
2035+ auto nominal = normal->getDeclContext ()->getSelfNominalTypeDecl ();
2036+ auto sig = nominal->getGenericSignatureOfContext ();
2037+ auto metadata = irgen::addGenericRequirements (IGM, B, sig, condReqs);
2038+
2039+ Flags = Flags.withNumConditionalPackDescriptors (
2040+ metadata.GenericPackArguments .size ());
2041+
2042+ // Collect the shape classes from the nominal type's generic signature.
2043+ sig->forEachParam ([&](GenericTypeParamType *param, bool canonical) {
2044+ if (canonical && param->isParameterPack ()) {
2045+ auto reducedShape = sig->getReducedShape (param)->getCanonicalType ();
2046+ if (reducedShape->isEqual (param))
2047+ metadata.ShapeClasses .push_back (reducedShape);
2048+ }
2049+ });
2050+
2051+ irgen::addGenericPackShapeDescriptors (
2052+ IGM, B, metadata.ShapeClasses ,
2053+ metadata.GenericPackArguments );
20352054 }
20362055
20372056 void addResilientWitnesses () {
20382057 if (Description.resilientWitnesses .empty ())
20392058 return ;
20402059
2060+ Flags = Flags.withHasResilientWitnesses (true );
2061+
20412062 // TargetResilientWitnessesHeader
20422063 ArrayRef<llvm::Constant *> witnesses = Description.resilientWitnesses ;
20432064 B.addInt32 (witnesses.size ());
@@ -2098,6 +2119,8 @@ namespace {
20982119 if (!Description.requiresSpecialization )
20992120 return ;
21002121
2122+ Flags = Flags.withHasGenericWitnessTable (true );
2123+
21012124 // WitnessTableSizeInWords
21022125 B.addInt (IGM.Int16Ty , Description.witnessTableSize );
21032126 // WitnessTablePrivateSizeInWordsAndRequiresInstantiation
0 commit comments