diff --git a/lib/CppInterOp/CppInterOp.cpp b/lib/CppInterOp/CppInterOp.cpp index a8bf9c064..3e82beb23 100755 --- a/lib/CppInterOp/CppInterOp.cpp +++ b/lib/CppInterOp/CppInterOp.cpp @@ -854,9 +854,30 @@ static void GetClassDecls(TCppScope_t klass, for (Decl* DI : CXXRD->decls()) { if (auto* MD = dyn_cast(DI)) methods.push_back(MD); - else if (auto* USD = dyn_cast(DI)) - if (auto* MD = dyn_cast(USD->getTargetDecl())) + else if (auto* USD = dyn_cast(DI)) { + auto* MD = dyn_cast(USD->getTargetDecl()); + if (!MD) + continue; + + auto* CUSD = dyn_cast(DI); + if (!CUSD) { + methods.push_back(MD); + continue; + } + + auto* CXXCD = dyn_cast_or_null(CUSD->getTargetDecl()); + if (!CXXCD) { methods.push_back(MD); + continue; + } + if (CXXCD->isDeleted()) + continue; + + // Result is appended to the decls, i.e. CXXRD, iterator + // non-shadowed decl will be push_back later + // methods.push_back(Result); + getSema().findInheritingConstructor(SourceLocation(), CXXCD, CUSD); + } } } diff --git a/unittests/CppInterOp/FunctionReflectionTest.cpp b/unittests/CppInterOp/FunctionReflectionTest.cpp index a2c85ca8b..355b0666b 100644 --- a/unittests/CppInterOp/FunctionReflectionTest.cpp +++ b/unittests/CppInterOp/FunctionReflectionTest.cpp @@ -95,14 +95,14 @@ TEST(FunctionReflectionTest, GetClassMethods) { Cpp::GetClassMethods(Decls[4], methods3); EXPECT_EQ(methods3.size(), 9); - EXPECT_EQ(get_method_name(methods3[0]), "B::B(int n)"); - EXPECT_EQ(get_method_name(methods3[1]), "inline constexpr B::B(const B &)"); - EXPECT_EQ(get_method_name(methods3[3]), "inline C::C()"); - EXPECT_EQ(get_method_name(methods3[4]), "inline constexpr C::C(const C &)"); - EXPECT_EQ(get_method_name(methods3[5]), "inline constexpr C::C(C &&)"); - EXPECT_EQ(get_method_name(methods3[6]), "inline C &C::operator=(const C &)"); - EXPECT_EQ(get_method_name(methods3[7]), "inline C &C::operator=(C &&)"); - EXPECT_EQ(get_method_name(methods3[8]), "inline C::~C()"); + EXPECT_EQ(get_method_name(methods3[0]), "inline C::C()"); + EXPECT_EQ(get_method_name(methods3[1]), "inline constexpr C::C(const C &)"); + EXPECT_EQ(get_method_name(methods3[2]), "inline constexpr C::C(C &&)"); + EXPECT_EQ(get_method_name(methods3[3]), "inline C &C::operator=(const C &)"); + EXPECT_EQ(get_method_name(methods3[4]), "inline C &C::operator=(C &&)"); + EXPECT_EQ(get_method_name(methods3[5]), "inline C::~C()"); + EXPECT_EQ(get_method_name(methods3[6]), "inline C::B(int)"); + EXPECT_EQ(get_method_name(methods3[7]), "inline constexpr C::B(const B &)"); // Should not crash. std::vector methods4; @@ -113,6 +113,49 @@ TEST(FunctionReflectionTest, GetClassMethods) { Cpp::GetClassMethods(nullptr, methods5); EXPECT_EQ(methods5.size(), 0); + Decls.clear(); + code = R"( + struct T { + template + T(Tmpl x) : n(x) {} + T(const T&) = delete; + T(T&&) = delete; + void fn() {} + int n; + }; + + struct TT: public T { + using T::T; + using T::fn; + }; + )"; + + GetAllTopLevelDecls(code, Decls); + EXPECT_EQ(Decls.size(), 2); + + std::vector templ_methods1; + Cpp::GetClassMethods(Decls[0], templ_methods1); + EXPECT_EQ(templ_methods1.size(), 5); + EXPECT_EQ(get_method_name(templ_methods1[0]), "T::T(const T &) = delete"); + EXPECT_EQ(get_method_name(templ_methods1[1]), "T::T(T &&) = delete"); + EXPECT_EQ(get_method_name(templ_methods1[2]), "void T::fn()"); + EXPECT_EQ(get_method_name(templ_methods1[3]), + "inline T &T::operator=(const T &)"); + EXPECT_EQ(get_method_name(templ_methods1[4]), "inline T::~T()"); + + std::vector templ_methods2; + Cpp::GetClassMethods(Decls[1], templ_methods2); + EXPECT_EQ(templ_methods2.size(), 7); + EXPECT_EQ(get_method_name(templ_methods2[0]), "void T::fn()"); + EXPECT_EQ(get_method_name(templ_methods2[1]), "inline TT::TT()"); + EXPECT_EQ(get_method_name(templ_methods2[2]), "inline TT::TT(const TT &)"); + EXPECT_EQ(get_method_name(templ_methods2[3]), "inline TT::TT(TT &&)"); + EXPECT_EQ(get_method_name(templ_methods2[4]), + "inline TT &TT::operator=(const TT &)"); + EXPECT_EQ(get_method_name(templ_methods2[5]), + "inline TT &TT::operator=(TT &&)"); + EXPECT_EQ(get_method_name(templ_methods2[6]), "inline TT::~TT()"); + // C API auto* I = clang_createInterpreterFromRawPtr(Cpp::GetInterpreter()); auto C_API_SHIM = [&](Cpp::TCppFunction_t method) {