Skip to content

Commit c849ba4

Browse files
fix look up of shadow constructor (#689)
* fix look up of shadow constructor shadow constructor need to be reconstructed for the base classes * Update lib/CppInterOp/CppInterOp.cpp Co-authored-by: Vassil Vassilev <[email protected]> --------- Co-authored-by: Vassil Vassilev <[email protected]>
1 parent e8c9c41 commit c849ba4

File tree

2 files changed

+74
-10
lines changed

2 files changed

+74
-10
lines changed

lib/CppInterOp/CppInterOp.cpp

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -854,9 +854,30 @@ static void GetClassDecls(TCppScope_t klass,
854854
for (Decl* DI : CXXRD->decls()) {
855855
if (auto* MD = dyn_cast<DeclType>(DI))
856856
methods.push_back(MD);
857-
else if (auto* USD = dyn_cast<UsingShadowDecl>(DI))
858-
if (auto* MD = dyn_cast<DeclType>(USD->getTargetDecl()))
857+
else if (auto* USD = dyn_cast<UsingShadowDecl>(DI)) {
858+
auto* MD = dyn_cast<DeclType>(USD->getTargetDecl());
859+
if (!MD)
860+
continue;
861+
862+
auto* CUSD = dyn_cast<ConstructorUsingShadowDecl>(DI);
863+
if (!CUSD) {
864+
methods.push_back(MD);
865+
continue;
866+
}
867+
868+
auto* CXXCD = dyn_cast_or_null<CXXConstructorDecl>(CUSD->getTargetDecl());
869+
if (!CXXCD) {
859870
methods.push_back(MD);
871+
continue;
872+
}
873+
if (CXXCD->isDeleted())
874+
continue;
875+
876+
// Result is appended to the decls, i.e. CXXRD, iterator
877+
// non-shadowed decl will be push_back later
878+
// methods.push_back(Result);
879+
getSema().findInheritingConstructor(SourceLocation(), CXXCD, CUSD);
880+
}
860881
}
861882
}
862883

unittests/CppInterOp/FunctionReflectionTest.cpp

Lines changed: 51 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -95,14 +95,14 @@ TEST(FunctionReflectionTest, GetClassMethods) {
9595
Cpp::GetClassMethods(Decls[4], methods3);
9696

9797
EXPECT_EQ(methods3.size(), 9);
98-
EXPECT_EQ(get_method_name(methods3[0]), "B::B(int n)");
99-
EXPECT_EQ(get_method_name(methods3[1]), "inline constexpr B::B(const B &)");
100-
EXPECT_EQ(get_method_name(methods3[3]), "inline C::C()");
101-
EXPECT_EQ(get_method_name(methods3[4]), "inline constexpr C::C(const C &)");
102-
EXPECT_EQ(get_method_name(methods3[5]), "inline constexpr C::C(C &&)");
103-
EXPECT_EQ(get_method_name(methods3[6]), "inline C &C::operator=(const C &)");
104-
EXPECT_EQ(get_method_name(methods3[7]), "inline C &C::operator=(C &&)");
105-
EXPECT_EQ(get_method_name(methods3[8]), "inline C::~C()");
98+
EXPECT_EQ(get_method_name(methods3[0]), "inline C::C()");
99+
EXPECT_EQ(get_method_name(methods3[1]), "inline constexpr C::C(const C &)");
100+
EXPECT_EQ(get_method_name(methods3[2]), "inline constexpr C::C(C &&)");
101+
EXPECT_EQ(get_method_name(methods3[3]), "inline C &C::operator=(const C &)");
102+
EXPECT_EQ(get_method_name(methods3[4]), "inline C &C::operator=(C &&)");
103+
EXPECT_EQ(get_method_name(methods3[5]), "inline C::~C()");
104+
EXPECT_EQ(get_method_name(methods3[6]), "inline C::B(int)");
105+
EXPECT_EQ(get_method_name(methods3[7]), "inline constexpr C::B(const B &)");
106106

107107
// Should not crash.
108108
std::vector<Cpp::TCppFunction_t> methods4;
@@ -113,6 +113,49 @@ TEST(FunctionReflectionTest, GetClassMethods) {
113113
Cpp::GetClassMethods(nullptr, methods5);
114114
EXPECT_EQ(methods5.size(), 0);
115115

116+
Decls.clear();
117+
code = R"(
118+
struct T {
119+
template<typename Tmpl>
120+
T(Tmpl x) : n(x) {}
121+
T(const T&) = delete;
122+
T(T&&) = delete;
123+
void fn() {}
124+
int n;
125+
};
126+
127+
struct TT: public T {
128+
using T::T;
129+
using T::fn;
130+
};
131+
)";
132+
133+
GetAllTopLevelDecls(code, Decls);
134+
EXPECT_EQ(Decls.size(), 2);
135+
136+
std::vector<Cpp::TCppFunction_t> templ_methods1;
137+
Cpp::GetClassMethods(Decls[0], templ_methods1);
138+
EXPECT_EQ(templ_methods1.size(), 5);
139+
EXPECT_EQ(get_method_name(templ_methods1[0]), "T::T(const T &) = delete");
140+
EXPECT_EQ(get_method_name(templ_methods1[1]), "T::T(T &&) = delete");
141+
EXPECT_EQ(get_method_name(templ_methods1[2]), "void T::fn()");
142+
EXPECT_EQ(get_method_name(templ_methods1[3]),
143+
"inline T &T::operator=(const T &)");
144+
EXPECT_EQ(get_method_name(templ_methods1[4]), "inline T::~T()");
145+
146+
std::vector<Cpp::TCppFunction_t> templ_methods2;
147+
Cpp::GetClassMethods(Decls[1], templ_methods2);
148+
EXPECT_EQ(templ_methods2.size(), 7);
149+
EXPECT_EQ(get_method_name(templ_methods2[0]), "void T::fn()");
150+
EXPECT_EQ(get_method_name(templ_methods2[1]), "inline TT::TT()");
151+
EXPECT_EQ(get_method_name(templ_methods2[2]), "inline TT::TT(const TT &)");
152+
EXPECT_EQ(get_method_name(templ_methods2[3]), "inline TT::TT(TT &&)");
153+
EXPECT_EQ(get_method_name(templ_methods2[4]),
154+
"inline TT &TT::operator=(const TT &)");
155+
EXPECT_EQ(get_method_name(templ_methods2[5]),
156+
"inline TT &TT::operator=(TT &&)");
157+
EXPECT_EQ(get_method_name(templ_methods2[6]), "inline TT::~TT()");
158+
116159
// C API
117160
auto* I = clang_createInterpreterFromRawPtr(Cpp::GetInterpreter());
118161
auto C_API_SHIM = [&](Cpp::TCppFunction_t method) {

0 commit comments

Comments
 (0)