Skip to content

Commit 2ef2734

Browse files
committed
Add variadic support for templates
1 parent 12e6e69 commit 2ef2734

File tree

2 files changed

+39
-4
lines changed

2 files changed

+39
-4
lines changed

lib/Interpreter/CppInterOp.cpp

+11-4
Original file line numberDiff line numberDiff line change
@@ -2971,10 +2971,17 @@ namespace Cpp {
29712971
Sema& S) {
29722972
// Create a list of template arguments.
29732973
TemplateArgumentListInfo TLI{};
2974-
for (auto TA : TemplateArgs)
2975-
TLI.addArgument(S.getTrivialTemplateArgumentLoc(TA,QualType(),
2976-
SourceLocation()));
2977-
2974+
for (auto TA : TemplateArgs) {
2975+
if (TA.getKind() == TemplateArgument::ArgKind::Pack) {
2976+
for (auto PTA : TA.getPackAsArray()) {
2977+
TLI.addArgument(S.getTrivialTemplateArgumentLoc(PTA, QualType(),
2978+
SourceLocation()));
2979+
}
2980+
} else {
2981+
TLI.addArgument(
2982+
S.getTrivialTemplateArgumentLoc(TA, QualType(), SourceLocation()));
2983+
}
2984+
}
29782985
return InstantiateTemplate(TemplateD, TLI, S);
29792986
}
29802987

unittests/CppInterOp/FunctionReflectionTest.cpp

+28
Original file line numberDiff line numberDiff line change
@@ -589,6 +589,34 @@ TEST(FunctionReflectionTest, InstantiateTemplateMethod) {
589589
EXPECT_TRUE(TA1.getAsType()->isIntegerType());
590590
}
591591

592+
TEST(FunctionReflectionTest, InstantiateVariadicFunctionTemplate) {
593+
std::vector<Decl*> Decls;
594+
std::string code = R"(
595+
template<typename... Args> void VariadicFnTemplate(Args... args) {}
596+
)";
597+
598+
GetAllTopLevelDecls(code, Decls);
599+
ASTContext& C = Interp->getCI()->getASTContext();
600+
601+
// Example instantiation with int and double
602+
std::vector<Cpp::TemplateArgInfo> args1 = {C.IntTy.getAsOpaquePtr(),
603+
C.DoubleTy.getAsOpaquePtr()};
604+
auto Instance1 = Cpp::InstantiateTemplate(Decls[0], args1.data(),
605+
/*type_size*/ args1.size());
606+
// EXPECT_TRUE(isa<FunctionTemplateDecl>((Decl*)Instance1));
607+
FunctionDecl* FD = cast<FunctionDecl>((Decl*)Instance1);
608+
FunctionDecl* FnTD1 = FD->getTemplateInstantiationPattern();
609+
EXPECT_TRUE(FnTD1->isThisDeclarationADefinition());
610+
// TemplateArgument TA1 = FD->getTemplateSpecializationArgs()->get(0);
611+
612+
// // Validate the first argument is of integer type
613+
// EXPECT_TRUE(TA1.getAsType()->isIntegerType());
614+
615+
// // Validate the second argument is of double type
616+
// TemplateArgument TA2 = FD->getTemplateSpecializationArgs()->get(1);
617+
// EXPECT_TRUE(TA2.getAsType()->isFloatingType());
618+
}
619+
592620
TEST(FunctionReflectionTest, BestTemplateFunctionMatch) {
593621
std::vector<Decl*> Decls;
594622
std::string code = R"(

0 commit comments

Comments
 (0)