Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 20 additions & 11 deletions lib/Interpreter/CppInterOp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1963,8 +1963,14 @@ namespace Cpp {
// Same applies with member methods which seem to cause parse failures
// even when we supply the object parameter. Therefore we only use it in
// cases where we know it works and set this variable to true when we do.

// true if not a overloaded operators or the overloaded operator is call
// operator
bool op_flag = !FD->isOverloadedOperator() ||
FD->getOverloadedOperator() == clang::OO_Call;

bool ShouldCastFunction =
!isa<CXXMethodDecl>(FD) && N == FD->getNumParams();
!isa<CXXMethodDecl>(FD) && N == FD->getNumParams() && op_flag;
if (ShouldCastFunction) {
callbuf << "(";
callbuf << "(";
Expand Down Expand Up @@ -2003,11 +2009,13 @@ namespace Cpp {
callbuf << "((const " << class_name << "*)obj)->";
else
callbuf << "((" << class_name << "*)obj)->";
} else if (const NamedDecl* ND =
dyn_cast<NamedDecl>(get_non_transparent_decl_context(FD))) {

if (op_flag)
callbuf << class_name << "::";
} else if (isa<NamedDecl>(get_non_transparent_decl_context(FD))) {
// This is a namespace member.
(void)ND;
callbuf << class_name << "::";
if (op_flag || N <= 1)
callbuf << class_name << "::";
}
// callbuf << fMethod->Name() << "(";
{
Expand All @@ -2030,7 +2038,8 @@ namespace Cpp {
name = name_without_template_args +
(template_args.empty() ? "" : " " + template_args);
}
callbuf << name;
if (op_flag || N <= 1)
callbuf << name;
}
if (ShouldCastFunction)
callbuf << ")";
Expand All @@ -2047,12 +2056,12 @@ namespace Cpp {
isPointer, indent_level, true);

if (i) {
callbuf << ',';
if (i % 2) {
callbuf << ' ';
if (op_flag) {
callbuf << ", ";
} else {
callbuf << "\n";
indent(callbuf, indent_level + 1);
callbuf << ' '
<< Cpp::getOperatorSpelling(FD->getOverloadedOperator())
<< ' ';
}
}

Expand Down
44 changes: 42 additions & 2 deletions unittests/CppInterOp/FunctionReflectionTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1381,7 +1381,7 @@ TEST(FunctionReflectionTest, GetFunctionAddress) {
#ifdef EMSCRIPTEN
#if CLANG_VERSION_MAJOR < 20
GTEST_SKIP() << "Test fails for Emscipten builds";
#endif
#endif
#endif
if (llvm::sys::RunningOnValgrind())
GTEST_SKIP() << "XFAIL due to Valgrind report";
Expand Down Expand Up @@ -1684,6 +1684,46 @@ TEST(FunctionReflectionTest, GetFunctionCallWrapper) {
bool boolean = false;
FCI_op.Invoke((void*)&boolean, {args, /*args_size=*/1}, toperator);
EXPECT_TRUE(boolean);

Interp->process(R"(
namespace N1 {

template <typename... _Tn> struct Klass3 {
using type = int;
};

namespace N2 {
template <typename T1, typename T2> class Klass1 {};

template <typename T1, typename T2> class Klass2 {};

template <typename T1, typename T2, typename T3, typename T4>
constexpr Klass2<
T1, typename Klass3<T2, Klass1<T3, T4>>::type>
operator+(const Klass2<T1, T2> &__lhs,
const Klass1<T3, T4> &__rhs) {
typedef Klass1<T3, T4> __T1;
typedef typename Klass3<T2, __T1>::type __ct;
typedef Klass2<T1, __ct> __T2;
return {};
}
} // namespace N2
} // namespace N1

N1::N2::Klass2<int, double> K1;
N1::N2::Klass1<char, float> K2;
)");

Cpp::TCppType_t K1 = Cpp::GetTypeFromScope(Cpp::GetNamed("K1"));
Cpp::TCppType_t K2 = Cpp::GetTypeFromScope(Cpp::GetNamed("K2"));
operators.clear();
Cpp::GetOperator(Cpp::GetScope("N2", Cpp::GetScope("N1")), Cpp::OP_Plus,
operators);
EXPECT_EQ(operators.size(), 1);
Cpp::TCppFunction_t kop =
Cpp::BestOverloadFunctionMatch(operators, {}, {K1, K2});
auto chrono_op_fn_callable = Cpp::MakeFunctionCallable(kop);
EXPECT_EQ(chrono_op_fn_callable.getKind(), Cpp::JitCall::kGenericCall);
}

TEST(FunctionReflectionTest, IsConstMethod) {
Expand Down Expand Up @@ -1992,4 +2032,4 @@ TEST(FunctionReflectionTest, UndoTest) {
EXPECT_EQ(ret, 1);
#endif
#endif
}
}
Loading