Skip to content

Commit 6155f34

Browse files
committed
Add tests for variadic function instantiations
1 parent 27847e4 commit 6155f34

File tree

1 file changed

+56
-0
lines changed

1 file changed

+56
-0
lines changed

unittests/CppInterOp/FunctionReflectionTest.cpp

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -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*/ args1.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+
849905
TEST(FunctionReflectionTest, BestOverloadFunctionMatch1) {
850906
std::vector<Decl*> Decls;
851907
std::string code = R"(

0 commit comments

Comments
 (0)