Skip to content

Commit 10a4181

Browse files
fix MakeFunctionCallable for dealing with public typedef to private type
1 parent 508823a commit 10a4181

File tree

2 files changed

+61
-5
lines changed

2 files changed

+61
-5
lines changed

lib/Interpreter/CppInterOp.cpp

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1600,7 +1600,12 @@ namespace Cpp {
16001600
PrintingPolicy Policy) {
16011601
//TODO: Implement cling desugaring from utils::AST
16021602
// cling::utils::Transform::GetPartiallyDesugaredType()
1603-
QT = QT.getDesugaredType(C);
1603+
if (!QT->isTypedefNameType() || QT->isBuiltinType())
1604+
QT = QT.getDesugaredType(C);
1605+
#if CLANG_VERSION_MAJOR > 16
1606+
Policy.SuppressElaboration = true;
1607+
#endif
1608+
Policy.FullyQualifiedName = true;
16041609
QT.getAsStringInternal(type_name, Policy);
16051610
}
16061611

@@ -1652,13 +1657,13 @@ namespace Cpp {
16521657
return;
16531658
} else if (QT->isPointerType()) {
16541659
isPointer = true;
1655-
QT = cast<clang::PointerType>(QT)->getPointeeType();
1660+
QT = cast<clang::PointerType>(QT.getCanonicalType())->getPointeeType();
16561661
} else if (QT->isReferenceType()) {
16571662
if (QT->isRValueReferenceType())
16581663
refType = kRValueReference;
16591664
else
16601665
refType = kLValueReference;
1661-
QT = cast<ReferenceType>(QT)->getPointeeType();
1666+
QT = cast<ReferenceType>(QT.getCanonicalType())->getPointeeType();
16621667
}
16631668
// Fall through for the array type to deal with reference/pointer ro array
16641669
// type.
@@ -1911,7 +1916,7 @@ namespace Cpp {
19111916
make_narg_ctor_with_return(FD, N, class_name, buf, indent_level);
19121917
return;
19131918
}
1914-
QualType QT = FD->getReturnType().getCanonicalType();
1919+
QualType QT = FD->getReturnType();
19151920
if (QT->isVoidType()) {
19161921
std::ostringstream typedefbuf;
19171922
std::ostringstream callbuf;

unittests/CppInterOp/FunctionReflectionTest.cpp

Lines changed: 52 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
#include "Utils.h"
22

33
#include "clang/AST/ASTContext.h"
4-
#include "clang/Interpreter/CppInterOp.h"
4+
#include "clang/Basic/Version.h"
55
#include "clang/Frontend/CompilerInstance.h"
6+
#include "clang/Interpreter/CppInterOp.h"
67
#include "clang/Sema/Sema.h"
78

89
#include "gtest/gtest.h"
@@ -974,6 +975,56 @@ TEST(FunctionReflectionTest, GetFunctionCallWrapper) {
974975

975976
FCI_Add.Invoke(&result, {args, /*args_size=*/2});
976977
EXPECT_EQ(result, a + b);
978+
979+
// call with pointers
980+
Interp->process(R"(
981+
void set_5(int *out) {
982+
*out = 5;
983+
}
984+
)");
985+
986+
Cpp::TCppScope_t set_5 = Cpp::GetNamed("set_5");
987+
EXPECT_TRUE(set_5);
988+
989+
Cpp::JitCall set_5_f = Cpp::MakeFunctionCallable(set_5);
990+
EXPECT_EQ(set_5_f.getKind(), Cpp::JitCall::kGenericCall);
991+
992+
int* bp = &b;
993+
void* set_5_args[1] = {(void*)&bp};
994+
set_5_f.Invoke(nullptr, {set_5_args, 1});
995+
EXPECT_EQ(b, 5);
996+
997+
#if CLANG_VERSION_MAJOR > 16
998+
// typedef resolution testing
999+
// supported for clang version >16 only
1000+
Interp->process(R"(
1001+
class TypedefToPrivateClass {
1002+
private:
1003+
class PC {
1004+
public:
1005+
int m_val = 4;
1006+
};
1007+
1008+
public:
1009+
typedef PC PP;
1010+
static PP f() { return PC(); }
1011+
};
1012+
)");
1013+
1014+
Cpp::TCppScope_t TypedefToPrivateClass =
1015+
Cpp::GetNamed("TypedefToPrivateClass");
1016+
EXPECT_TRUE(TypedefToPrivateClass);
1017+
1018+
Cpp::TCppScope_t f = Cpp::GetNamed("f", TypedefToPrivateClass);
1019+
EXPECT_TRUE(f);
1020+
1021+
Cpp::JitCall FCI_f = Cpp::MakeFunctionCallable(f);
1022+
EXPECT_EQ(FCI_f.getKind(), Cpp::JitCall::kGenericCall);
1023+
1024+
void* res = nullptr;
1025+
FCI_f.Invoke(&res, {nullptr, 0});
1026+
EXPECT_TRUE(res);
1027+
#endif
9771028
}
9781029

9791030
TEST(FunctionReflectionTest, IsConstMethod) {

0 commit comments

Comments
 (0)