From 667f38ef154ee90c4d98cfb24fcc811c001b8632 Mon Sep 17 00:00:00 2001 From: Vipul Cariappa Date: Fri, 20 Dec 2024 15:41:34 +0530 Subject: [PATCH] fix `MakeFunctionCallable` for dealing with public typedef to private type --- lib/Interpreter/CppInterOp.cpp | 13 +++-- .../CppInterOp/FunctionReflectionTest.cpp | 47 +++++++++++++++++++ 2 files changed, 56 insertions(+), 4 deletions(-) diff --git a/lib/Interpreter/CppInterOp.cpp b/lib/Interpreter/CppInterOp.cpp index eaef806be..d285ef9a1 100644 --- a/lib/Interpreter/CppInterOp.cpp +++ b/lib/Interpreter/CppInterOp.cpp @@ -1600,7 +1600,12 @@ namespace Cpp { PrintingPolicy Policy) { //TODO: Implement cling desugaring from utils::AST // cling::utils::Transform::GetPartiallyDesugaredType() - QT = QT.getDesugaredType(C); + if (!QT->isTypedefNameType() || QT->isBuiltinType()) + QT = QT.getDesugaredType(C); +#if CLANG_VERSION_MAJOR > 16 + Policy.SuppressElaboration = true; +#endif + Policy.FullyQualifiedName = true; QT.getAsStringInternal(type_name, Policy); } @@ -1652,13 +1657,13 @@ namespace Cpp { return; } else if (QT->isPointerType()) { isPointer = true; - QT = cast(QT)->getPointeeType(); + QT = cast(QT.getCanonicalType())->getPointeeType(); } else if (QT->isReferenceType()) { if (QT->isRValueReferenceType()) refType = kRValueReference; else refType = kLValueReference; - QT = cast(QT)->getPointeeType(); + QT = cast(QT.getCanonicalType())->getPointeeType(); } // Fall through for the array type to deal with reference/pointer ro array // type. @@ -1911,7 +1916,7 @@ namespace Cpp { make_narg_ctor_with_return(FD, N, class_name, buf, indent_level); return; } - QualType QT = FD->getReturnType().getCanonicalType(); + QualType QT = FD->getReturnType(); if (QT->isVoidType()) { std::ostringstream typedefbuf; std::ostringstream callbuf; diff --git a/unittests/CppInterOp/FunctionReflectionTest.cpp b/unittests/CppInterOp/FunctionReflectionTest.cpp index bd1483dea..247cd3f78 100644 --- a/unittests/CppInterOp/FunctionReflectionTest.cpp +++ b/unittests/CppInterOp/FunctionReflectionTest.cpp @@ -974,6 +974,53 @@ TEST(FunctionReflectionTest, GetFunctionCallWrapper) { FCI_Add.Invoke(&result, {args, /*args_size=*/2}); EXPECT_EQ(result, a + b); + + // call with pointers + Interp->process(R"( + void set_5(int *out) { + *out = 5; + } + )"); + + Cpp::TCppScope_t set_5 = Cpp::GetNamed("set_5"); + EXPECT_TRUE(set_5); + + Cpp::JitCall set_5_f = Cpp::MakeFunctionCallable(set_5); + EXPECT_EQ(set_5_f.getKind(), Cpp::JitCall::kGenericCall); + + int* bp = &b; + void* set_5_args[1] = {(void*)&bp}; + set_5_f.Invoke(nullptr, {set_5_args, 1}); + EXPECT_EQ(b, 5); + + // typedef resolution testing + Interp->process(R"( + class TypedefToPrivateClass { + private: + class PC { + public: + int m_val = 4; + }; + + public: + typedef PC PP; + static PP f() { return PC(); } + }; + )"); + + Cpp::TCppScope_t TypedefToPrivateClass = + Cpp::GetNamed("TypedefToPrivateClass"); + EXPECT_TRUE(TypedefToPrivateClass); + + Cpp::TCppScope_t f = Cpp::GetNamed("f", TypedefToPrivateClass); + EXPECT_TRUE(f); + + Cpp::JitCall FCI_f = Cpp::MakeFunctionCallable(f); + EXPECT_EQ(FCI_f.getKind(), Cpp::JitCall::kGenericCall); + + void* res = nullptr; + FCI_f.Invoke(&res, {nullptr, 0}); + EXPECT_TRUE(res); } TEST(FunctionReflectionTest, IsConstMethod) {