diff --git a/lib/Interpreter/CppInterOp.cpp b/lib/Interpreter/CppInterOp.cpp index ddf6b2467..7cdfcfec3 100755 --- a/lib/Interpreter/CppInterOp.cpp +++ b/lib/Interpreter/CppInterOp.cpp @@ -1862,10 +1862,22 @@ namespace Cpp { { std::string name; { - llvm::raw_string_ostream stream(name); + std::string complete_name; + llvm::raw_string_ostream stream(complete_name); FD->getNameForDiagnostic(stream, FD->getASTContext().getPrintingPolicy(), /*Qualified=*/false); + + // insert space between template argument list and the function name + // this is require if the function is `operator<` + // `operator<` is invalid syntax + // whereas `operator< ` is valid + std::string simple_name = FD->getNameAsString(); + size_t idx = complete_name.find(simple_name, 0) + simple_name.size(); + std::string name_without_template_args = complete_name.substr(0, idx); + std::string template_args = complete_name.substr(idx); + name = name_without_template_args + + (template_args.empty() ? "" : " " + template_args); } callbuf << name; } diff --git a/unittests/CppInterOp/FunctionReflectionTest.cpp b/unittests/CppInterOp/FunctionReflectionTest.cpp index 55263b791..1c576fbe7 100644 --- a/unittests/CppInterOp/FunctionReflectionTest.cpp +++ b/unittests/CppInterOp/FunctionReflectionTest.cpp @@ -1043,6 +1043,34 @@ TEST(FunctionReflectionTest, GetFunctionCallWrapper) { FCI_f.Invoke(&res, {nullptr, 0}); EXPECT_TRUE(res); #endif + + // templated operators + Interp->process(R"( + class TOperator{ + public: + template + bool operator<(T t) { return true; } + }; + )"); + Cpp::TCppScope_t TOperator = Cpp::GetNamed("TOperator"); + + auto* TOperatorCtor = Cpp::GetDefaultConstructor(TOperator); + auto FCI_TOperatorCtor = Cpp::MakeFunctionCallable(TOperatorCtor); + void* toperator = nullptr; + FCI_TOperatorCtor.Invoke((void*)&toperator); + + EXPECT_TRUE(toperator); + std::vector operators; + Cpp::GetOperator(TOperator, Cpp::OP_Less, operators); + EXPECT_EQ(operators.size(), 1); + + Cpp::TCppScope_t op_templated = operators[0]; + auto TAI = Cpp::TemplateArgInfo(Cpp::GetType("int")); + Cpp::TCppScope_t op = Cpp::InstantiateTemplate(op_templated, &TAI, 1); + auto FCI_op = Cpp::MakeFunctionCallable(op); + bool boolean = false; + FCI_op.Invoke((void*)&boolean, {args, /*args_size=*/1}, object); + EXPECT_TRUE(boolean); } TEST(FunctionReflectionTest, IsConstMethod) {