Skip to content

Commit 79933ec

Browse files
sudo-pandavgvassilev
authored andcommitted
Add support for extern func in ns in CallFunc
1 parent 379ef35 commit 79933ec

File tree

2 files changed

+39
-9
lines changed

2 files changed

+39
-9
lines changed

lib/Interpreter/CppInterOp.cpp

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1273,6 +1273,15 @@ namespace Cpp {
12731273
callbuf << ")";
12741274
}
12751275

1276+
const DeclContext* get_non_transparent_decl_context(const FunctionDecl* FD) {
1277+
auto *DC = FD->getDeclContext();
1278+
while (DC->isTransparentContext()) {
1279+
DC = DC->getParent();
1280+
assert(DC && "All transparent contexts should have a parent!");
1281+
}
1282+
return DC;
1283+
}
1284+
12761285
void make_narg_call(const FunctionDecl* FD, const std::string& return_type,
12771286
const unsigned N, std::ostringstream& typedefbuf,
12781287
std::ostringstream& callbuf,
@@ -1335,8 +1344,8 @@ namespace Cpp {
13351344
callbuf << "((const " << class_name << "*)obj)->";
13361345
else
13371346
callbuf << "((" << class_name << "*)obj)->";
1338-
} else if (const NamedDecl *ND =
1339-
dyn_cast<NamedDecl>(FD->getDeclContext())) {
1347+
} else if (const NamedDecl* ND =
1348+
dyn_cast<NamedDecl>(get_non_transparent_decl_context(FD))) {
13401349
// This is a namespace member.
13411350
(void)ND;
13421351
callbuf << class_name << "::";
@@ -1609,7 +1618,7 @@ namespace Cpp {
16091618
// Get the class or namespace name.
16101619
//
16111620
std::string class_name;
1612-
const clang::DeclContext *DC = FD->getDeclContext();
1621+
const clang::DeclContext* DC = get_non_transparent_decl_context(FD);
16131622
if (const TypeDecl* TD = dyn_cast<TypeDecl>(DC)) {
16141623
// This is a class, struct, or union member.
16151624
QualType QT(TD->getTypeForDecl(), 0);

unittests/CppInterOp/FunctionReflectionTest.cpp

Lines changed: 27 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -524,25 +524,46 @@ TEST(FunctionReflectionTest, GetFunctionCallWrapper) {
524524
void f2(std::string &s) { printf("%s", s.c_str()); };
525525
)");
526526

527+
Interp->process(R"(
528+
namespace NS {
529+
int f3() { return 3; }
530+
531+
extern "C" int f4() { return 4; }
532+
}
533+
)");
534+
527535
Sema *S = &Interp->getCI()->getSema();
528536

529-
Cpp::CallFuncWrapper_t wrapper0 =
537+
Cpp::CallFuncWrapper_t wrapper1 =
530538
Cpp::GetFunctionCallWrapper((Cpp::TInterp_t)Interp.get(), Decls[0]);
531-
Cpp::CallFuncWrapper_t wrapper1 = Cpp::GetFunctionCallWrapper(
539+
Cpp::CallFuncWrapper_t wrapper2 = Cpp::GetFunctionCallWrapper(
532540
(Cpp::TInterp_t)Interp.get(), Cpp::GetNamed(S, "f2"));
533-
int i = 9, ret;
541+
Cpp::CallFuncWrapper_t wrapper3 = Cpp::GetFunctionCallWrapper(
542+
(Cpp::TInterp_t)Interp.get(),
543+
Cpp::GetNamed(S, "f3", Cpp::GetNamed(S, "NS")));
544+
Cpp::CallFuncWrapper_t wrapper4 = Cpp::GetFunctionCallWrapper(
545+
(Cpp::TInterp_t)Interp.get(),
546+
Cpp::GetNamed(S, "f4", Cpp::GetNamed(S, "NS")));
547+
548+
int i = 9, ret1, ret3, ret4;
534549
std::string s("Hello World!\n");
535550
void *args0[1] = { (void *) &i };
536551
void *args1[1] = { (void *) &s };
537552

538-
wrapper0(0, 1, args0, &ret);
553+
wrapper1(0, 1, args0, &ret1);
539554

540555
testing::internal::CaptureStdout();
541-
wrapper1(0, 1, args1, 0);
556+
wrapper2(0, 1, args1, 0);
542557
std::string output = testing::internal::GetCapturedStdout();
543558

544-
EXPECT_EQ(ret, i * i);
559+
wrapper3(0, 0, 0, &ret3);
560+
561+
wrapper4(0, 0, 0, &ret4);
562+
563+
EXPECT_EQ(ret1, i * i);
545564
EXPECT_EQ(output, s);
565+
EXPECT_EQ(ret3, 3);
566+
EXPECT_EQ(ret4, 4);
546567
}
547568

548569
TEST(FunctionReflectionTest, IsConstMethod) {

0 commit comments

Comments
 (0)