From 94125305c873c04a5548cef401c9c2fa1b0fa7af Mon Sep 17 00:00:00 2001 From: maximusron Date: Thu, 19 Sep 2024 12:26:34 +0200 Subject: [PATCH] Add variadic support for templates --- lib/Interpreter/CppInterOp.cpp | 15 +++++++--- .../CppInterOp/FunctionReflectionTest.cpp | 28 +++++++++++++++++++ 2 files changed, 39 insertions(+), 4 deletions(-) diff --git a/lib/Interpreter/CppInterOp.cpp b/lib/Interpreter/CppInterOp.cpp index 96aab802..fb431a36 100644 --- a/lib/Interpreter/CppInterOp.cpp +++ b/lib/Interpreter/CppInterOp.cpp @@ -2927,10 +2927,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 5b76e100..72b03932 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"(