Skip to content

Commit b7aacc1

Browse files
fix codegen for template operator (#682)
* fix codegen for template operator do not specify the template arguments explicitly Co-authored-by: Vassil Vassilev <[email protected]> --------- Co-authored-by: Vassil Vassilev <[email protected]>
1 parent e3c6373 commit b7aacc1

File tree

2 files changed

+43
-12
lines changed

2 files changed

+43
-12
lines changed

lib/CppInterOp/CppInterOp.cpp

Lines changed: 5 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2146,23 +2146,14 @@ void make_narg_call(const FunctionDecl* FD, const std::string& return_type,
21462146
PP.SuppressElaboration = true;
21472147
FD->getNameForDiagnostic(stream, PP,
21482148
/*Qualified=*/false);
2149-
2150-
// insert space between template argument list and the function name
2151-
// this is require if the function is `operator<`
2152-
// `operator<<type1, type2, ...>` is invalid syntax
2153-
// whereas `operator< <type1, type2, ...>` is valid
2154-
std::string simple_name = FD->getNameAsString();
2155-
size_t idx = complete_name.find(simple_name, 0) + simple_name.size();
2156-
std::string name_without_template_args = complete_name.substr(0, idx);
2157-
std::string template_args = complete_name.substr(idx);
2158-
name = name_without_template_args +
2159-
(template_args.empty() ? "" : " " + template_args);
2149+
name = complete_name;
21602150

21612151
// If a template has consecutive parameter packs, then it is impossible to
21622152
// use the explicit name in the wrapper, since the type deduction is what
21632153
// determines the split of the packs. Instead, we'll revert to the
21642154
// non-templated function name and hope that the type casts in the wrapper
21652155
// will suffice.
2156+
std::string simple_name = FD->getNameAsString();
21662157
if (FD->isTemplateInstantiation() && FD->getPrimaryTemplate()) {
21672158
const FunctionTemplateDecl* FTDecl =
21682159
llvm::dyn_cast<FunctionTemplateDecl>(FD->getPrimaryTemplate());
@@ -2177,10 +2168,12 @@ void make_narg_call(const FunctionDecl* FD, const std::string& return_type,
21772168
numPacks = 0;
21782169
}
21792170
if (numPacks > 1) {
2180-
name = name_without_template_args;
2171+
name = simple_name;
21812172
}
21822173
}
21832174
}
2175+
if (FD->isOverloadedOperator())
2176+
name = simple_name;
21842177
}
21852178
if (op_flag || N <= 1)
21862179
callbuf << name;

unittests/CppInterOp/FunctionReflectionTest.cpp

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2030,6 +2030,44 @@ TEST(FunctionReflectionTest, GetFunctionCallWrapper) {
20302030

20312031
auto consume_callable = Cpp::MakeFunctionCallable(consume);
20322032
EXPECT_EQ(consume_callable.getKind(), Cpp::JitCall::kGenericCall);
2033+
2034+
Cpp::Declare(R"(
2035+
template<typename T1, typename T2>
2036+
struct Product {};
2037+
2038+
template<typename T>
2039+
struct KlassProduct {
2040+
template<typename O>
2041+
const Product<T, O>
2042+
operator*(const KlassProduct<O> &other) const { return Product<T, O>(); }
2043+
2044+
template<typename TT, typename O>
2045+
const Product<TT, O>
2046+
operator*(const KlassProduct<O> &other) const { return Product<TT, O>(); }
2047+
};
2048+
)");
2049+
2050+
Cpp::TCppScope_t KlassProduct = Cpp::GetNamed("KlassProduct");
2051+
EXPECT_TRUE(KlassProduct);
2052+
2053+
Cpp::TCppScope_t KlassProduct_int =
2054+
Cpp::InstantiateTemplate(KlassProduct, &TAI, 1);
2055+
EXPECT_TRUE(KlassProduct_int);
2056+
TAI = Cpp::TemplateArgInfo(Cpp::GetType("float"));
2057+
Cpp::TCppScope_t KlassProduct_float =
2058+
Cpp::InstantiateTemplate(KlassProduct, &TAI, 1);
2059+
EXPECT_TRUE(KlassProduct_float);
2060+
2061+
operators.clear();
2062+
Cpp::GetOperator(KlassProduct_int, Cpp::OP_Star, operators);
2063+
EXPECT_EQ(operators.size(), 2);
2064+
2065+
op = Cpp::BestOverloadFunctionMatch(
2066+
operators, {}, {{Cpp::GetTypeFromScope(KlassProduct_float)}});
2067+
EXPECT_TRUE(op);
2068+
2069+
auto op_callable = Cpp::MakeFunctionCallable(op);
2070+
EXPECT_EQ(op_callable.getKind(), Cpp::JitCall::kGenericCall);
20332071
}
20342072

20352073
TEST(FunctionReflectionTest, IsConstMethod) {

0 commit comments

Comments
 (0)