Skip to content

Commit 9e42858

Browse files
committed
Add ConstructorUsingShadowDecl overload support
1 parent 66875a5 commit 9e42858

1 file changed

Lines changed: 32 additions & 10 deletions

File tree

lib/CppInterOp/CppInterOp.cpp

Lines changed: 32 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
#include "clang/AST/QualTypeNames.h"
2929
#include "clang/AST/RawCommentList.h"
3030
#include "clang/AST/RecordLayout.h"
31+
#include "clang/AST/RecursiveASTVisitor.h"
3132
#include "clang/AST/Stmt.h"
3233
#include "clang/AST/Type.h"
3334
#include "clang/Basic/DiagnosticSema.h"
@@ -44,7 +45,6 @@
4445
#include "clang/Sema/Ownership.h"
4546
#include "clang/Sema/Redeclaration.h"
4647
#include "clang/Sema/Sema.h"
47-
#include "clang/AST/RecursiveASTVisitor.h"
4848
#include "clang/Sema/TemplateDeduction.h"
4949

5050
#include "llvm/ADT/SmallString.h"
@@ -1693,6 +1693,23 @@ BestOverloadMatch(const std::vector<TCppScope_t>& candidates,
16931693
for (TCppScope_t F : candidates) {
16941694
Decl* D = (Decl*)F;
16951695

1696+
// Unwrap ConstructorUsingShadowDecl (from `using Base::Base;`)
1697+
// to get the inherited constructor and add it in the derived class context.
1698+
if (auto* Shadow = dyn_cast<ConstructorUsingShadowDecl>(D)) {
1699+
CXXConstructorDecl* CD =
1700+
dyn_cast<CXXConstructorDecl>(Shadow->getTargetDecl());
1701+
if (!CD)
1702+
continue;
1703+
// Use the shadow's access (which reflects the using-decl's access),
1704+
// not the base constructor's access.
1705+
DeclAccessPair found = DeclAccessPair::make(CD, Shadow->getAccess());
1706+
// Pass the derived class as the object type so Sema checks the right
1707+
// conversion sequences.
1708+
QualType DerivedTy = S.Context.getCanonicalTagType(Shadow->getParent());
1709+
S.AddOverloadCandidate(CD, found, non_member_args, candSet);
1710+
continue;
1711+
}
1712+
16961713
if (auto* MD = dyn_cast<CXXMethodDecl>(D)) {
16971714
if (!register_member(MD, dyn_cast<FunctionTemplateDecl>(MD)))
16981715
continue;
@@ -2842,7 +2859,7 @@ TCppType_t GetTypeFromScope(TCppScope_t klass) {
28422859
namespace {
28432860
static unsigned long long gWrapperSerial = 0LL;
28442861

2845-
static std::string generate_wrapper_name(char const *prefix) {
2862+
static std::string generate_wrapper_name(char const* prefix) {
28462863
std::ostringstream nm;
28472864
nm << prefix << gWrapperSerial++;
28482865
return nm.str();
@@ -4994,7 +5011,8 @@ static std::string PrepareStructorWrapper(const Decl* D,
49945011
}
49955012

49965013
template <WrapperKind K = WrapperKind::Jit>
4997-
static auto make_dtor_wrapper(compat::Interpreter& interp, const Decl* D, const std::string &wrapper_name) {
5014+
static auto make_dtor_wrapper(compat::Interpreter& interp, const Decl* D,
5015+
const std::string& wrapper_name) {
49985016
// Make a code string that follows this pattern:
49995017
//
50005018
// void
@@ -5068,22 +5086,25 @@ CPPINTEROP_API JitCall MakeFunctionCallable(TInterp_t I,
50685086
// FIXME: Unify with make_wrapper.
50695087
if (const auto* Dtor = dyn_cast<CXXDestructorDecl>(D)) {
50705088
auto wrapper_name = generate_wrapper_name("dtor");
5071-
if (auto Wrapper = make_dtor_wrapper(*interp, Dtor->getParent(), wrapper_name))
5089+
if (auto Wrapper =
5090+
make_dtor_wrapper(*interp, Dtor->getParent(), wrapper_name))
50725091
return {JitCall::kDestructorCall, Wrapper, Dtor};
50735092
// FIXME: else error we failed to compile the wrapper.
50745093
return {};
50755094
}
50765095

50775096
if (const auto* Ctor = dyn_cast<CXXConstructorDecl>(D)) {
50785097
auto wrapper_name = generate_wrapper_name("ctor");
5079-
if (auto Wrapper = make_wrapper<WrapperKind::Jit>(*interp, cast<FunctionDecl>(D), {}, wrapper_name))
5098+
if (auto Wrapper = make_wrapper<WrapperKind::Jit>(
5099+
*interp, cast<FunctionDecl>(D), {}, wrapper_name))
50805100
return {JitCall::kConstructorCall, Wrapper, Ctor};
50815101
// FIXME: else error we failed to compile the wrapper.
50825102
return {};
50835103
}
50845104

50855105
auto wrapper_name = generate_wrapper_name("function");
5086-
if (auto Wrapper = make_wrapper<WrapperKind::Jit>(*interp, cast<FunctionDecl>(D), {}, wrapper_name)) {
5106+
if (auto Wrapper = make_wrapper<WrapperKind::Jit>(
5107+
*interp, cast<FunctionDecl>(D), {}, wrapper_name)) {
50875108
return {JitCall::kGenericCall, Wrapper, cast<FunctionDecl>(D)};
50885109
}
50895110
// FIXME: else error we failed to compile the wrapper.
@@ -5481,9 +5502,9 @@ CreateInterpreter(const std::vector<const char*>& Args /*={}*/,
54815502
#ifdef CPPINTEROP_USE_CLING
54825503
auto I = new compat::Interpreter(ClingArgv.size(), &ClingArgv[0]);
54835504
#else
5484-
auto Interp =
5485-
compat::Interpreter::create(static_cast<int>(ClingArgv.size()),
5486-
ClingArgv.data(), nullptr, {}, nullptr, true, VFS, CM);
5505+
auto Interp = compat::Interpreter::create(static_cast<int>(ClingArgv.size()),
5506+
ClingArgv.data(), nullptr, {},
5507+
nullptr, true, VFS, CM);
54875508
if (!Interp)
54885509
return nullptr;
54895510
auto* I = Interp.release();
@@ -6330,7 +6351,8 @@ TCppObject_t Construct(TCppScope_t scope, void* arena /*=nullptr*/,
63306351

63316352
bool Destruct(compat::Interpreter& interp, TCppObject_t This, const Decl* Class,
63326353
bool withFree, TCppIndex_t nary) {
6333-
if (auto wrapper = make_dtor_wrapper(interp, Class, generate_wrapper_name("dtor"))) {
6354+
if (auto wrapper =
6355+
make_dtor_wrapper(interp, Class, generate_wrapper_name("dtor"))) {
63346356
(*wrapper)(This, nary, withFree);
63356357
return true;
63366358
}

0 commit comments

Comments
 (0)