Skip to content

Commit 2e5e702

Browse files
sudo-pandavgvassilev
authored andcommitted
Support using shadow declarations.
1 parent ba5a505 commit 2e5e702

File tree

2 files changed

+65
-17
lines changed

2 files changed

+65
-17
lines changed

lib/Interpreter/CppInterOp.cpp

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -573,25 +573,28 @@ namespace Cpp {
573573
// avoid copies.
574574
std::vector<TCppFunction_t> GetClassMethods(TCppSema_t sema,
575575
TCppScope_t klass) {
576-
auto *D = (clang::Decl *)klass;
577-
auto *S = (Sema *)sema;
578576

579577
if (!klass)
580578
return {};
581579

582-
if (auto *TD = llvm::dyn_cast<TypedefNameDecl>(D))
580+
auto *D = (clang::Decl *) klass;
581+
auto *S = (Sema *)sema;
582+
583+
if (auto *TD = dyn_cast<TypedefNameDecl>(D))
583584
D = GetScopeFromType(TD->getUnderlyingType());
584585

585-
if (auto *CXXRD = llvm::dyn_cast_or_null<CXXRecordDecl>(D)) {
586+
std::vector<TCppFunction_t> methods;
587+
if (auto *CXXRD = dyn_cast_or_null<CXXRecordDecl>(D)) {
586588
S->ForceDeclarationOfImplicitMembers(CXXRD);
587-
std::vector<TCppFunction_t> methods;
588-
for (auto it = CXXRD->method_begin(), end = CXXRD->method_end();
589-
it != end; it++) {
590-
methods.push_back((TCppFunction_t)*it);
589+
for (Decl* DI : CXXRD->decls()) {
590+
if (auto* MD = dyn_cast<CXXMethodDecl>(DI))
591+
methods.push_back(MD);
592+
else if (auto* USD = dyn_cast<UsingShadowDecl>(DI))
593+
if (auto* MD = dyn_cast<CXXMethodDecl>(USD->getTargetDecl()))
594+
methods.push_back(MD);
591595
}
592-
return methods;
593596
}
594-
return {};
597+
return methods;
595598
}
596599

597600
bool HasDefaultConstructor(TCppScope_t scope) {

unittests/CppInterOp/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 = Cpp::GetClassMethods(S, Decls[0]);
3646

3747
auto get_method_name = [](Cpp::TCppFunction_t method) {
38-
return Cpp::GetQualifiedName(method);
48+
return Cpp::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 = Cpp::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 = Cpp::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 = Cpp::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 = Cpp::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 = Cpp::GetClassMethods(S, Decls[4]);
98+
EXPECT_EQ(methods4.size(), 0);
5499
}
55100

56101
TEST(FunctionReflectionTest, ConstructorInGetClassMethods) {

0 commit comments

Comments
 (0)