Skip to content

Commit

Permalink
Add variadic support for templates
Browse files Browse the repository at this point in the history
  • Loading branch information
aaronj0 committed Dec 4, 2024
1 parent 111d0e5 commit 3603d06
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 4 deletions.
15 changes: 11 additions & 4 deletions lib/Interpreter/CppInterOp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3023,10 +3023,17 @@ namespace Cpp {
ArrayRef<TemplateArgument> TemplateArgs, 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(),

Check warning on line 3029 in lib/Interpreter/CppInterOp.cpp

View check run for this annotation

Codecov / codecov/patch

lib/Interpreter/CppInterOp.cpp#L3028-L3029

Added lines #L3028 - L3029 were not covered by tests
SourceLocation()));
}
} else {
TLI.addArgument(
S.getTrivialTemplateArgumentLoc(TA, QualType(), SourceLocation()));
}
}
return InstantiateTemplate(TemplateD, TLI, S);
}

Expand Down
28 changes: 28 additions & 0 deletions unittests/CppInterOp/FunctionReflectionTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -589,6 +589,34 @@ TEST(FunctionReflectionTest, InstantiateTemplateMethod) {
EXPECT_TRUE(TA1.getAsType()->isIntegerType());
}

TEST(FunctionReflectionTest, InstantiateVariadicFunctionTemplate) {
std::vector<Decl*> Decls;
std::string code = R"(
template<typename... Args> void VariadicFnTemplate(Args... args) {}
)";

GetAllTopLevelDecls(code, Decls);
ASTContext& C = Interp->getCI()->getASTContext();

// Example instantiation with int and double
std::vector<Cpp::TemplateArgInfo> args1 = {C.IntTy.getAsOpaquePtr(),
C.DoubleTy.getAsOpaquePtr()};
auto Instance1 = Cpp::InstantiateTemplate(Decls[0], args1.data(),
/*type_size*/ args1.size());
// EXPECT_TRUE(isa<FunctionTemplateDecl>((Decl*)Instance1));
FunctionDecl* FD = cast<FunctionDecl>((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<Decl*> Decls;
std::string code = R"(
Expand Down

0 comments on commit 3603d06

Please sign in to comment.