@@ -414,6 +414,8 @@ namespace {
414414 unsigned NumParams = 0 ;
415415 unsigned NumRequirements = 0 ;
416416 unsigned NumGenericKeyArguments = 0 ;
417+ SmallVector<CanType, 2 > ShapeClasses;
418+ SmallVector<GenericPackArgument, 2 > GenericPackArguments;
417419
418420 GenericSignatureHeaderBuilder (IRGenModule &IGM,
419421 ConstantStructBuilder &builder)
@@ -422,13 +424,26 @@ namespace {
422424 NumGenericKeyArgumentsPP(builder.addPlaceholderWithSize(IGM.Int16Ty)),
423425 FlagsPP(builder.addPlaceholderWithSize(IGM.Int16Ty)) {}
424426
425- void adjustAfterRequirements (const GenericRequirementsMetadata &info) {
427+ void add (const GenericArgumentMetadata &info) {
428+ ShapeClasses.append (info.ShapeClasses .begin (),
429+ info.ShapeClasses .end ());
430+
426431 NumParams += info.NumParams ;
427432 NumRequirements += info.NumRequirements ;
433+
434+ for (auto pack : info.GenericPackArguments ) {
435+ // Compute the final index.
436+ pack.Index += NumGenericKeyArguments + ShapeClasses.size ();
437+ GenericPackArguments.push_back (pack);
438+ }
439+
428440 NumGenericKeyArguments += info.NumGenericKeyArguments ;
429441 }
430442
431443 void finish (IRGenModule &IGM, ConstantStructBuilder &b) {
444+ assert (GenericPackArguments.empty () == ShapeClasses.empty () &&
445+ " Can't have one without the other" );
446+
432447 assert (NumParams <= UINT16_MAX && " way too generic" );
433448 b.fillPlaceholderWithInt (NumParamsPP, IGM.Int16Ty , NumParams);
434449
@@ -438,9 +453,9 @@ namespace {
438453
439454 assert (NumGenericKeyArguments <= UINT16_MAX && " way too generic" );
440455 b.fillPlaceholderWithInt (NumGenericKeyArgumentsPP, IGM.Int16Ty ,
441- NumGenericKeyArguments);
456+ NumGenericKeyArguments + ShapeClasses. size () );
442457
443- bool hasTypePacks = false ;
458+ bool hasTypePacks = !GenericPackArguments. empty () ;
444459 GenericContextDescriptorFlags flags (hasTypePacks);
445460 b.fillPlaceholderWithInt (FlagsPP, IGM.Int16Ty ,
446461 flags.getIntValue ());
@@ -495,6 +510,7 @@ namespace {
495510 asImpl ().addGenericParametersHeader ();
496511 asImpl ().addGenericParameters ();
497512 asImpl ().addGenericRequirements ();
513+ asImpl ().addGenericPackShapeDescriptors ();
498514 asImpl ().finishGenericParameters ();
499515 }
500516
@@ -512,7 +528,7 @@ namespace {
512528 /* implicit=*/ false );
513529 assert (metadata.NumParams == metadata.NumParamsEmitted &&
514530 " We can't use implicit GenericParamDescriptors here" );
515- SignatureHeader->adjustAfterRequirements (metadata);
531+ SignatureHeader->add (metadata);
516532
517533 // Pad the structure up to four bytes for the following requirements.
518534 addPaddingAfterGenericParamDescriptors (IGM, B,
@@ -524,13 +540,49 @@ namespace {
524540 irgen::addGenericRequirements (IGM, B,
525541 asImpl ().getGenericSignature (),
526542 asImpl ().getGenericSignature ().getRequirements ());
527- SignatureHeader->adjustAfterRequirements (metadata);
543+ SignatureHeader->add (metadata);
528544 }
529545
530546 void finishGenericParameters () {
531547 SignatureHeader->finish (IGM, B);
532548 }
533549
550+ void addGenericPackShapeDescriptors () {
551+ const auto &shapes = SignatureHeader->ShapeClasses ;
552+ const auto &packArgs = SignatureHeader->GenericPackArguments ;
553+ assert (shapes.empty () == packArgs.empty () &&
554+ " Can't have one without the other" );
555+
556+ // If we don't have any pack arguments, there is nothing to emit.
557+ if (packArgs.empty ())
558+ return ;
559+
560+ // Emit the GenericPackShapeHeader first.
561+
562+ // NumPacks
563+ B.addInt (IGM.Int16Ty , packArgs.size ());
564+
565+ // NumShapes
566+ B.addInt (IGM.Int16Ty , shapes.size ());
567+
568+ // Emit each GenericPackShapeDescriptor collected previously.
569+ for (const auto &packArg : packArgs) {
570+ // Kind
571+ B.addInt (IGM.Int16Ty , uint16_t (packArg.Kind ));
572+
573+ // Index
574+ B.addInt (IGM.Int16Ty , packArg.Index );
575+
576+ // ShapeClass
577+ auto found = std::find (shapes.begin (), shapes.end (), packArg.ReducedShape );
578+ assert (found != shapes.end ());
579+ B.addInt (IGM.Int16Ty , found - shapes.begin ());
580+
581+ // Unused
582+ B.addInt (IGM.Int16Ty , 0 );
583+ }
584+ }
585+
534586 uint8_t getVersion () {
535587 return 0 ;
536588 }
@@ -6061,7 +6113,9 @@ void IRGenModule::emitProtocolDecl(ProtocolDecl *protocol) {
60616113
60626114static GenericParamDescriptor
60636115getGenericParamDescriptor (GenericTypeParamType *param, bool canonical) {
6064- return GenericParamDescriptor (GenericParamKind::Type,
6116+ return GenericParamDescriptor (param->isParameterPack ()
6117+ ? GenericParamKind::TypePack
6118+ : GenericParamKind::Type,
60656119 /* key argument*/ canonical);
60666120}
60676121
@@ -6077,13 +6131,13 @@ static bool canUseImplicitGenericParamDescriptors(CanGenericSignature sig) {
60776131 return allImplicit && count <= MaxNumImplicitGenericParamDescriptors;
60786132}
60796133
6080- GenericRequirementsMetadata
6134+ GenericArgumentMetadata
60816135irgen::addGenericParameters (IRGenModule &IGM, ConstantStructBuilder &B,
60826136 GenericSignature sig, bool implicit) {
60836137 assert (sig);
60846138 auto canSig = sig.getCanonicalSignature ();
60856139
6086- GenericRequirementsMetadata metadata;
6140+ GenericArgumentMetadata metadata;
60876141
60886142 canSig->forEachParam ([&](GenericTypeParamType *param, bool canonical) {
60896143 // Currently, there are only type parameters. The parameter is a key
@@ -6098,6 +6152,19 @@ irgen::addGenericParameters(IRGenModule &IGM, ConstantStructBuilder &B,
60986152
60996153 ++metadata.NumParams ;
61006154
6155+ // Only key arguments count toward NumGenericPackArguments.
6156+ if (descriptor.hasKeyArgument () &&
6157+ descriptor.getKind () == GenericParamKind::TypePack) {
6158+ auto reducedShape = canSig->getReducedShape (param)->getCanonicalType ();
6159+ metadata.GenericPackArguments .emplace_back (
6160+ GenericPackKind::Metadata,
6161+ metadata.NumGenericKeyArguments ,
6162+ reducedShape);
6163+
6164+ if (reducedShape->isEqual (param))
6165+ metadata.ShapeClasses .push_back (reducedShape);
6166+ }
6167+
61016168 if (descriptor.hasKeyArgument ())
61026169 ++metadata.NumGenericKeyArguments ;
61036170 });
@@ -6121,11 +6188,21 @@ static void addRelativeAddressOfTypeRef(IRGenModule &IGM,
61216188
61226189// / Add a generic requirement to the given constant struct builder.
61236190static void addGenericRequirement (IRGenModule &IGM, ConstantStructBuilder &B,
6124- GenericRequirementsMetadata &metadata,
6191+ GenericArgumentMetadata &metadata,
61256192 GenericSignature sig,
61266193 GenericRequirementFlags flags,
61276194 Type paramType,
61286195 llvm::function_ref<void ()> addReference) {
6196+ // Only key arguments (ie, conformance requirements) count toward
6197+ // NumGenericPackArguments.
6198+ if (flags.hasKeyArgument () && flags.isPackRequirement ()) {
6199+ assert (flags.getKind () == GenericRequirementKind::Protocol);
6200+ metadata.GenericPackArguments .emplace_back (
6201+ GenericPackKind::WitnessTable,
6202+ metadata.NumGenericKeyArguments ,
6203+ sig->getReducedShape (paramType)->getCanonicalType ());
6204+ }
6205+
61296206 if (flags.hasKeyArgument ())
61306207 ++metadata.NumGenericKeyArguments ;
61316208
@@ -6134,13 +6211,13 @@ static void addGenericRequirement(IRGenModule &IGM, ConstantStructBuilder &B,
61346211 addReference ();
61356212}
61366213
6137- GenericRequirementsMetadata irgen::addGenericRequirements (
6214+ GenericArgumentMetadata irgen::addGenericRequirements (
61386215 IRGenModule &IGM, ConstantStructBuilder &B,
61396216 GenericSignature sig,
61406217 ArrayRef<Requirement> requirements) {
61416218 assert (sig);
61426219
6143- GenericRequirementsMetadata metadata;
6220+ GenericArgumentMetadata metadata;
61446221 for (auto &requirement : requirements) {
61456222 auto kind = requirement.getKind ();
61466223 bool isPackRequirement = requirement.getFirstType ()->isParameterPack ();
@@ -6504,7 +6581,7 @@ irgen::emitExtendedExistentialTypeShape(IRGenModule &IGM,
65046581 GenericSignatureHeaderBuilder &header,
65056582 bool implicit) {
65066583 auto info = irgen::addGenericParameters (IGM, b, sig, implicit);
6507- header.adjustAfterRequirements (info);
6584+ header.add (info);
65086585 totalParamDescriptors += info.NumParamsEmitted ;
65096586 };
65106587 addParamDescriptors (reqSig, reqHeader, flags.hasImplicitReqSigParams ());
@@ -6516,7 +6593,7 @@ irgen::emitExtendedExistentialTypeShape(IRGenModule &IGM,
65166593 auto addRequirementDescriptors = [&](CanGenericSignature sig,
65176594 GenericSignatureHeaderBuilder &header) {
65186595 auto info = addGenericRequirements (IGM, b, sig, sig.getRequirements ());
6519- header.adjustAfterRequirements (info);
6596+ header.add (info);
65206597 header.finish (IGM, b);
65216598 };
65226599
@@ -6526,6 +6603,15 @@ irgen::emitExtendedExistentialTypeShape(IRGenModule &IGM,
65266603 addRequirementDescriptors (genSig, *genHeader);
65276604 }
65286605
6606+ // The 'Self' parameter in an existential is not variadic
6607+ assert (reqHeader.GenericPackArguments .empty () &&
6608+ " Generic parameter packs should not ever appear here" );
6609+
6610+ // You can have a superclass with a generic parameter pack in a composition,
6611+ // like `C<each T> & P<Int>`
6612+ assert (genHeader->GenericPackArguments .empty () &&
6613+ " Generic parameter packs not supported here yet" );
6614+
65296615 return b.finishAndCreateFuture ();
65306616 }, [&](llvm::GlobalVariable *var) {
65316617 var->setConstant (true );
0 commit comments