diff --git a/lib/Interpreter/CppInterOp.cpp b/lib/Interpreter/CppInterOp.cpp index d4b1578ea..8c0037ee3 100644 --- a/lib/Interpreter/CppInterOp.cpp +++ b/lib/Interpreter/CppInterOp.cpp @@ -2971,10 +2971,17 @@ namespace Cpp { Sema& S) { // Create a list of template arguments. TemplateArgumentListInfo TLI{}; - for (auto TA : TemplateArgs) - TLI.addArgument(S.getTrivialTemplateArgumentLoc(TA,QualType(), - SourceLocation())); - + for (auto TA : TemplateArgs) { + if (TA.getKind() == TemplateArgument::ArgKind::Pack) { + for (auto PTA : TA.getPackAsArray()) { + TLI.addArgument(S.getTrivialTemplateArgumentLoc(PTA, QualType(), + SourceLocation())); + } + } else { + TLI.addArgument( + S.getTrivialTemplateArgumentLoc(TA, QualType(), SourceLocation())); + } + } return InstantiateTemplate(TemplateD, TLI, S); } diff --git a/unittests/CppInterOp/FunctionReflectionTest.cpp b/unittests/CppInterOp/FunctionReflectionTest.cpp index 5b76e1001..72b03932e 100644 --- a/unittests/CppInterOp/FunctionReflectionTest.cpp +++ b/unittests/CppInterOp/FunctionReflectionTest.cpp @@ -589,6 +589,34 @@ TEST(FunctionReflectionTest, InstantiateTemplateMethod) { EXPECT_TRUE(TA1.getAsType()->isIntegerType()); } +TEST(FunctionReflectionTest, InstantiateVariadicFunctionTemplate) { + std::vector Decls; + std::string code = R"( +template void VariadicFnTemplate(Args... args) {} +)"; + + GetAllTopLevelDecls(code, Decls); + ASTContext& C = Interp->getCI()->getASTContext(); + + // Example instantiation with int and double + std::vector args1 = {C.IntTy.getAsOpaquePtr(), + C.DoubleTy.getAsOpaquePtr()}; + auto Instance1 = Cpp::InstantiateTemplate(Decls[0], args1.data(), + /*type_size*/ args1.size()); + // EXPECT_TRUE(isa((Decl*)Instance1)); + FunctionDecl* FD = cast((Decl*)Instance1); + FunctionDecl* FnTD1 = FD->getTemplateInstantiationPattern(); + EXPECT_TRUE(FnTD1->isThisDeclarationADefinition()); + // TemplateArgument TA1 = FD->getTemplateSpecializationArgs()->get(0); + + // // Validate the first argument is of integer type + // EXPECT_TRUE(TA1.getAsType()->isIntegerType()); + + // // Validate the second argument is of double type + // TemplateArgument TA2 = FD->getTemplateSpecializationArgs()->get(1); + // EXPECT_TRUE(TA2.getAsType()->isFloatingType()); +} + TEST(FunctionReflectionTest, BestTemplateFunctionMatch) { std::vector Decls; std::string code = R"(