diff --git a/unittests/CppInterOp/FunctionReflectionTest.cpp b/unittests/CppInterOp/FunctionReflectionTest.cpp index 96dd45477..ec09e359d 100644 --- a/unittests/CppInterOp/FunctionReflectionTest.cpp +++ b/unittests/CppInterOp/FunctionReflectionTest.cpp @@ -973,6 +973,56 @@ TYPED_TEST(CppInterOpTest, FunctionReflectionTestInstantiateVariadicFunction) { "fixedParam, MyClass args, double args)"); } +TYPED_TEST(CppInterOpTest, FunctionReflectionTestBestOverloadFunctionMatch0) { + // make sure templates are not instantiated multiple times + std::vector Decls; + std::string code = R"( + template + void Tfn(T1& t1, T2& t2) {} + )"; + GetAllTopLevelDecls(code, Decls); + EXPECT_EQ(Decls.size(), 1); + + std::vector candidates; + candidates.reserve(Decls.size()); + for (auto* i : Decls) + candidates.push_back(i); + + ASTContext& C = Interp->getCI()->getASTContext(); + + std::vector args0 = { + C.getLValueReferenceType(C.DoubleTy).getAsOpaquePtr(), + C.getLValueReferenceType(C.IntTy).getAsOpaquePtr(), + }; + + std::vector explicit_args0; + std::vector explicit_args1 = { + C.DoubleTy.getAsOpaquePtr()}; + std::vector explicit_args2 = { + C.DoubleTy.getAsOpaquePtr(), + C.IntTy.getAsOpaquePtr(), + }; + + Cpp::TCppScope_t fn0 = + Cpp::BestOverloadFunctionMatch(candidates, explicit_args0, args0); + EXPECT_TRUE(fn0); + + Cpp::TCppScope_t fn = + Cpp::BestOverloadFunctionMatch(candidates, explicit_args1, args0); + EXPECT_EQ(fn, fn0); + + fn = Cpp::BestOverloadFunctionMatch(candidates, explicit_args2, args0); + EXPECT_EQ(fn, fn0); + + fn = Cpp::InstantiateTemplate(Decls[0], explicit_args1.data(), + explicit_args1.size()); + EXPECT_EQ(fn, fn0); + + fn = Cpp::InstantiateTemplate(Decls[0], explicit_args2.data(), + explicit_args2.size()); + EXPECT_EQ(fn, fn0); +} + TYPED_TEST(CppInterOpTest, FunctionReflectionTestBestOverloadFunctionMatch1) { std::vector Decls; std::string code = R"(