Skip to content

Commit 6953a06

Browse files
sudo-pandavgvassilev
authored andcommitted
Support using shadow declarations.
1 parent 1001856 commit 6953a06

File tree

2 files changed

+65
-17
lines changed

2 files changed

+65
-17
lines changed

lib/Interpreter/InterOp.cpp

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -578,25 +578,28 @@ namespace InterOp {
578578
// avoid copies.
579579
std::vector<TCppFunction_t> GetClassMethods(TCppSema_t sema, TCppScope_t klass)
580580
{
581-
auto *D = (clang::Decl *) klass;
582-
auto *S = (Sema *) sema;
583581

584582
if (!klass)
585583
return {};
586584

587-
if (auto *TD = llvm::dyn_cast<TypedefNameDecl>(D))
585+
auto *D = (clang::Decl *) klass;
586+
auto *S = (Sema *) sema;
587+
588+
if (auto *TD = dyn_cast<TypedefNameDecl>(D))
588589
D = GetScopeFromType(TD->getUnderlyingType());
589590

590-
if (auto *CXXRD = llvm::dyn_cast_or_null<CXXRecordDecl>(D)) {
591+
std::vector<TCppFunction_t> methods;
592+
if (auto *CXXRD = dyn_cast_or_null<CXXRecordDecl>(D)) {
591593
S->ForceDeclarationOfImplicitMembers(CXXRD);
592-
std::vector<TCppFunction_t> methods;
593-
for (auto it = CXXRD->method_begin(), end = CXXRD->method_end();
594-
it != end; it++) {
595-
methods.push_back((TCppFunction_t) *it);
594+
for (Decl* DI : CXXRD->decls()) {
595+
if (auto* MD = dyn_cast<CXXMethodDecl>(DI))
596+
methods.push_back(MD);
597+
else if (auto* USD = dyn_cast<UsingShadowDecl>(DI))
598+
if (auto* MD = dyn_cast<CXXMethodDecl>(USD->getTargetDecl()))
599+
methods.push_back(MD);
596600
}
597-
return methods;
598601
}
599-
return {};
602+
return methods;
600603
}
601604

602605
bool HasDefaultConstructor(TCppScope_t scope) {

unittests/InterOp/FunctionReflectionTest.cpp

Lines changed: 52 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -28,21 +28,40 @@ TEST(FunctionReflectionTest, GetClassMethods) {
2828
};
2929
3030
typedef A shadow_A;
31+
class B {
32+
public:
33+
B(int n) : b{n} {}
34+
int b;
35+
};
36+
37+
class C: public B {
38+
public:
39+
using B::B;
40+
};
41+
using MyInt = int;
3142
)";
3243

3344
GetAllTopLevelDecls(code, Decls);
3445
Sema *S = &Interp->getCI()->getSema();
35-
auto methods0 = InterOp::GetClassMethods(S, Decls[0]);
3646

3747
auto get_method_name = [](InterOp::TCppFunction_t method) {
38-
return InterOp::GetQualifiedName(method);
48+
return InterOp::GetFunctionSignature(method);
3949
};
4050

41-
EXPECT_EQ(get_method_name(methods0[0]), "A::f1");
42-
EXPECT_EQ(get_method_name(methods0[1]), "A::f2");
43-
EXPECT_EQ(get_method_name(methods0[2]), "A::f3");
44-
EXPECT_EQ(get_method_name(methods0[3]), "A::f4");
45-
EXPECT_EQ(get_method_name(methods0[4]), "A::f5");
51+
auto methods0 = InterOp::GetClassMethods(S, Decls[0]);
52+
53+
EXPECT_EQ(methods0.size(), 11);
54+
EXPECT_EQ(get_method_name(methods0[0]), "int A::f1(int a, int b)");
55+
EXPECT_EQ(get_method_name(methods0[1]), "const A *A::f2() const");
56+
EXPECT_EQ(get_method_name(methods0[2]), "int A::f3()");
57+
EXPECT_EQ(get_method_name(methods0[3]), "void A::f4()");
58+
EXPECT_EQ(get_method_name(methods0[4]), "int A::f5(int i)");
59+
EXPECT_EQ(get_method_name(methods0[5]), "inline constexpr A::A()");
60+
EXPECT_EQ(get_method_name(methods0[6]), "inline constexpr A::A(const A &)");
61+
EXPECT_EQ(get_method_name(methods0[7]), "inline constexpr A &A::operator=(const A &)");
62+
EXPECT_EQ(get_method_name(methods0[8]), "inline constexpr A::A(A &&)");
63+
EXPECT_EQ(get_method_name(methods0[9]), "inline constexpr A &A::operator=(A &&)");
64+
EXPECT_EQ(get_method_name(methods0[10]), "inline A::~A()");
4665

4766
auto methods1 = InterOp::GetClassMethods(S, Decls[1]);
4867
EXPECT_EQ(methods0.size(), methods1.size());
@@ -51,6 +70,32 @@ TEST(FunctionReflectionTest, GetClassMethods) {
5170
EXPECT_EQ(methods0[2], methods1[2]);
5271
EXPECT_EQ(methods0[3], methods1[3]);
5372
EXPECT_EQ(methods0[4], methods1[4]);
73+
74+
auto methods2 = InterOp::GetClassMethods(S, Decls[2]);
75+
76+
EXPECT_EQ(methods2.size(), 6);
77+
EXPECT_EQ(get_method_name(methods2[0]), "B::B(int n)");
78+
EXPECT_EQ(get_method_name(methods2[1]), "inline constexpr B::B(const B &)");
79+
EXPECT_EQ(get_method_name(methods2[2]), "inline constexpr B::B(B &&)");
80+
EXPECT_EQ(get_method_name(methods2[3]), "inline B::~B()");
81+
EXPECT_EQ(get_method_name(methods2[4]), "inline B &B::operator=(const B &)");
82+
EXPECT_EQ(get_method_name(methods2[5]), "inline B &B::operator=(B &&)");
83+
84+
auto methods3 = InterOp::GetClassMethods(S, Decls[3]);
85+
86+
EXPECT_EQ(methods3.size(), 9);
87+
EXPECT_EQ(get_method_name(methods3[0]), "B::B(int n)");
88+
EXPECT_EQ(get_method_name(methods3[1]), "inline constexpr B::B(const B &)");
89+
EXPECT_EQ(get_method_name(methods3[3]), "inline C::C()");
90+
EXPECT_EQ(get_method_name(methods3[4]), "inline constexpr C::C(const C &)");
91+
EXPECT_EQ(get_method_name(methods3[5]), "inline constexpr C::C(C &&)");
92+
EXPECT_EQ(get_method_name(methods3[6]), "inline C &C::operator=(const C &)");
93+
EXPECT_EQ(get_method_name(methods3[7]), "inline C &C::operator=(C &&)");
94+
EXPECT_EQ(get_method_name(methods3[8]), "inline C::~C()");
95+
96+
// Should not crash.
97+
auto methods4 = InterOp::GetClassMethods(S, Decls[4]);
98+
EXPECT_EQ(methods4.size(), 0);
5499
}
55100

56101
TEST(FunctionReflectionTest, ConstructorInGetClassMethods) {

0 commit comments

Comments
 (0)