@@ -235,21 +235,25 @@ static const char * const GenericParamNames[] = {
235235};
236236
237237static GenericTypeParamDecl*
238- createGenericParam (ASTContext &ctx, const char *name, unsigned index) {
238+ createGenericParam (ASTContext &ctx, const char *name, unsigned index,
239+ bool isParameterPack = false ) {
239240 ModuleDecl *M = ctx.TheBuiltinModule ;
240241 Identifier ident = ctx.getIdentifier (name);
241242 return GenericTypeParamDecl::createImplicit (
242- &M->getMainFile (FileUnitKind::Builtin), ident, /* depth*/ 0 , index);
243+ &M->getMainFile (FileUnitKind::Builtin), ident, /* depth*/ 0 , index,
244+ isParameterPack);
243245}
244246
245247// / Create a generic parameter list with multiple generic parameters.
246248static GenericParamList *getGenericParams (ASTContext &ctx,
247- unsigned numParameters) {
249+ unsigned numParameters,
250+ bool areParameterPacks = false ) {
248251 assert (numParameters <= std::size (GenericParamNames));
249252
250253 SmallVector<GenericTypeParamDecl *, 2 > genericParams;
251254 for (unsigned i = 0 ; i != numParameters; ++i)
252- genericParams.push_back (createGenericParam (ctx, GenericParamNames[i], i));
255+ genericParams.push_back (createGenericParam (ctx, GenericParamNames[i], i,
256+ areParameterPacks));
253257
254258 auto paramList = GenericParamList::create (ctx, SourceLoc (), genericParams,
255259 SourceLoc ());
@@ -678,9 +682,11 @@ namespace {
678682
679683 public:
680684 BuiltinFunctionBuilder (ASTContext &ctx, unsigned numGenericParams = 1 ,
681- bool wantsAdditionalAnyObjectRequirement = false )
685+ bool wantsAdditionalAnyObjectRequirement = false ,
686+ bool areParametersPacks = false )
682687 : Context(ctx) {
683- TheGenericParamList = getGenericParams (ctx, numGenericParams);
688+ TheGenericParamList = getGenericParams (ctx, numGenericParams,
689+ areParametersPacks);
684690 if (wantsAdditionalAnyObjectRequirement) {
685691 Requirement req (RequirementKind::Conformance,
686692 TheGenericParamList->getParams ()[0 ]->getInterfaceType (),
@@ -750,7 +756,7 @@ namespace {
750756 unsigned Index;
751757 Type build (BuiltinFunctionBuilder &builder) const {
752758 return builder.TheGenericParamList ->getParams ()[Index]
753- ->getDeclaredInterfaceType ();
759+ ->getDeclaredInterfaceType ();
754760 }
755761 };
756762 struct LambdaGenerator {
@@ -767,6 +773,16 @@ namespace {
767773 return MetatypeType::get (Object.build (builder), Repr);
768774 }
769775 };
776+ template <class T >
777+ struct PackExpansionGenerator {
778+ T Object;
779+ Type build (BuiltinFunctionBuilder &builder) const {
780+ auto patternTy = Object.build (builder);
781+ SmallVector<Type, 2 > packs;
782+ patternTy->getTypeParameterPacks (packs);
783+ return PackExpansionType::get (patternTy, packs[0 ]);
784+ }
785+ };
770786 };
771787} // end anonymous namespace
772788
@@ -814,6 +830,12 @@ makeMetatype(const T &object,
814830 return { object, repr };
815831}
816832
833+ template <class T >
834+ static BuiltinFunctionBuilder::PackExpansionGenerator<T>
835+ makePackExpansion (const T &object) {
836+ return { object };
837+ }
838+
817839// / Create a function with type <T> T -> ().
818840static ValueDecl *getRefCountingOperation (ASTContext &ctx, Identifier id) {
819841 return getBuiltinFunction (ctx, id, _thin,
@@ -1934,6 +1956,18 @@ static ValueDecl *getHopToActor(ASTContext &ctx, Identifier id) {
19341956 return builder.build (id);
19351957}
19361958
1959+ static ValueDecl *getPackLength (ASTContext &ctx, Identifier id) {
1960+ BuiltinFunctionBuilder builder (ctx, /* genericParamCount */ 1 ,
1961+ /* anyObject */ false ,
1962+ /* areParametersPack */ true );
1963+
1964+ auto paramTy = makeMetatype (makeTuple (makePackExpansion (makeGenericParam ())));
1965+ builder.addParameter (paramTy);
1966+ builder.setResult (makeConcrete (BuiltinIntegerType::getWordType (ctx)));
1967+
1968+ return builder.build (id);
1969+ }
1970+
19371971// / An array of the overloaded builtin kinds.
19381972static const OverloadedBuiltinKind OverloadedBuiltinKinds[] = {
19391973 OverloadedBuiltinKind::None,
@@ -2975,6 +3009,9 @@ ValueDecl *swift::getBuiltinValueDecl(ASTContext &Context, Identifier Id) {
29753009
29763010 case BuiltinValueKind::AutoDiffAllocateSubcontextWithType:
29773011 return getAutoDiffAllocateSubcontext (Context, Id);
3012+
3013+ case BuiltinValueKind::PackLength:
3014+ return getPackLength (Context, Id);
29783015 }
29793016
29803017 llvm_unreachable (" bad builtin value!" );
0 commit comments