@@ -846,6 +846,62 @@ TEST(FunctionReflectionTest, GetClassTemplatedMethods_VariadicsAndOthers) {
846846            " void MyClass::staticVariadic(T t, Args ...args)" 
847847}
848848
849+ TEST (FunctionReflectionTest, InstantiateVariadicFunction) {
850+   std::vector<Decl*> Decls;
851+   std::string code = R"( 
852+     class MyClass {}; 
853+ 
854+     template<typename... Args> 
855+     void VariadicFn(Args... args) {} 
856+ 
857+     template<typename... Args> 
858+     void VariadicFnExtended(int fixedParam, Args... args) {} 
859+   )"  ;
860+ 
861+   GetAllTopLevelDecls (code, Decls);
862+   ASTContext& C = Interp->getCI ()->getASTContext ();
863+ 
864+   std::vector<Cpp::TemplateArgInfo> args1 = {C.DoubleTy .getAsOpaquePtr (), C.IntTy .getAsOpaquePtr ()};
865+   auto  Instance1 = Cpp::InstantiateTemplate (Decls[1 ], args1.data (),
866+                                             /* type_size*/ size ());
867+   EXPECT_TRUE (Cpp::IsTemplatedFunction (Instance1));
868+   EXPECT_EQ (Cpp::GetFunctionSignature (Instance1), " template<> void VariadicFn<<double, int>>(double args, int args)" 
869+ 
870+   FunctionDecl* FD = cast<FunctionDecl>((Decl*)Instance1);
871+   FunctionDecl* FnTD1 = FD->getTemplateInstantiationPattern ();
872+   EXPECT_TRUE (FnTD1->isThisDeclarationADefinition ());
873+   EXPECT_EQ (FD->getNumParams (), 2 );
874+ 
875+   const  TemplateArgumentList* TA1 = FD->getTemplateSpecializationArgs ();
876+   llvm::ArrayRef<TemplateArgument> Args = TA1->get (0 ).getPackAsArray ();
877+   EXPECT_EQ (Args.size (), 2 );
878+   EXPECT_TRUE (Args[0 ].getAsType ()->isFloatingType ());
879+   EXPECT_TRUE (Args[1 ].getAsType ()->isIntegerType ());
880+ 
881+   //  handle to MyClass type
882+   auto  MyClassType = Cpp::GetTypeFromScope (Decls[0 ]);
883+   std::vector<Cpp::TemplateArgInfo> args2 = {MyClassType, C.DoubleTy .getAsOpaquePtr ()};
884+ 
885+   //  instantiate VariadicFnExtended
886+   auto  Instance2 = Cpp::InstantiateTemplate (Decls[2 ], args2.data (), args2.size ());
887+   EXPECT_TRUE (Cpp::IsTemplatedFunction (Instance2));
888+ 
889+   FunctionDecl* FD2 = cast<FunctionDecl>((Decl*)Instance2);
890+   FunctionDecl* FnTD2 = FD2->getTemplateInstantiationPattern ();
891+   EXPECT_TRUE (FnTD2->isThisDeclarationADefinition ());
892+ 
893+   //  VariadicFnExtended has one fixed param + 2 elements in TemplateArgument pack
894+   EXPECT_EQ (FD2->getNumParams (), 3 );
895+ 
896+   const  TemplateArgumentList* TA2 = FD2->getTemplateSpecializationArgs ();
897+   llvm::ArrayRef<TemplateArgument> PackArgs2 = TA2->get (0 ).getPackAsArray ();
898+   EXPECT_EQ (PackArgs2.size (), 2 );
899+ 
900+   EXPECT_TRUE (PackArgs2[0 ].getAsType ()->isRecordType ()); //  MyClass
901+   EXPECT_TRUE (PackArgs2[1 ].getAsType ()->isFloatingType ()); //  double
902+   EXPECT_EQ (Cpp::GetFunctionSignature (Instance2), " template<> void VariadicFnExtended<<MyClass, double>>(int fixedParam, MyClass args, double args)" 
903+ }
904+ 
849905TEST (FunctionReflectionTest, BestOverloadFunctionMatch1) {
850906  std::vector<Decl*> Decls;
851907  std::string code = R"( 
0 commit comments