Skip to content

Commit b726957

Browse files
committed
[tests] Provide unittest/example for API dispatch mechanism
to be followed up with a section in docs
1 parent 1ddf97d commit b726957

File tree

2 files changed

+70
-0
lines changed

2 files changed

+70
-0
lines changed

unittests/CppInterOp/CMakeLists.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,9 @@ endif()
8080
set_source_files_properties(InterpreterTest.cpp PROPERTIES COMPILE_DEFINITIONS
8181
"LLVM_BINARY_DIR=\"${LLVM_BINARY_DIR}\""
8282
)
83+
set_source_files_properties(DispatchAPITest.cpp PROPERTIES COMPILE_DEFINITIONS
84+
"CPPINTEROP_LIB_DIR=\"${CMAKE_BINARY_DIR}/lib/libclangCppInterOp.so\""
85+
)
8386
export_executable_symbols(CppInterOpTests)
8487

8588
unset(LLVM_LINK_COMPONENTS)
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
#include "Utils.h"
2+
3+
#include "CppInterOp/CppInterOpDispatch.h"
4+
5+
#include "gtest/gtest.h"
6+
7+
#include <dlfcn.h>
8+
9+
using namespace TestUtils;
10+
using namespace llvm;
11+
using namespace clang;
12+
13+
static void* dlGetProcAddress(const char* name) {
14+
static void* handle = dlopen(CPPINTEROP_LIB_DIR, RTLD_LAZY | RTLD_LOCAL);
15+
EXPECT_NE(handle, nullptr) << "Failed to open library: " << dlerror();
16+
if (!handle)
17+
return nullptr;
18+
static void* gpa = dlsym(handle, "CppGetProcAddress");
19+
EXPECT_NE(gpa, nullptr) << "Failed to find GetProcAddress: " << dlerror();
20+
return reinterpret_cast<void* (*)(const char*)>(gpa)(name);
21+
}
22+
23+
TEST(DispatchAPITestTest, IsClassSymbolLookup) {
24+
CppAPIType::IsClass IsClassFn =
25+
reinterpret_cast<CppAPIType::IsClass>(dlGetProcAddress("IsClass"));
26+
ASSERT_NE(IsClassFn, nullptr) << "failed to locate symbol: " << dlerror();
27+
std::vector<Decl*> Decls;
28+
GetAllTopLevelDecls("namespace N {} class C{}; int I;", Decls);
29+
EXPECT_FALSE(IsClassFn(Decls[0]));
30+
EXPECT_TRUE(IsClassFn(Decls[1]));
31+
EXPECT_FALSE(IsClassFn(Decls[2]));
32+
}
33+
34+
TEST(DispatchAPITestTest, Demangle) {
35+
36+
std::string code = R"(
37+
int add(int x, int y) { return x + y; }
38+
int add(double x, double y) { return x + y; }
39+
)";
40+
41+
std::vector<Decl*> Decls;
42+
GetAllTopLevelDecls(code, Decls);
43+
EXPECT_EQ(Decls.size(), 2);
44+
45+
auto Add_int = clang::GlobalDecl(static_cast<clang::NamedDecl*>(Decls[0]));
46+
auto Add_double = clang::GlobalDecl(static_cast<clang::NamedDecl*>(Decls[1]));
47+
48+
std::string mangled_add_int;
49+
std::string mangled_add_double;
50+
compat::maybeMangleDeclName(Add_int, mangled_add_int);
51+
compat::maybeMangleDeclName(Add_double, mangled_add_double);
52+
53+
// CppAPIType:: gives us the specific function pointer types
54+
CppAPIType::Demangle DemangleFn =
55+
reinterpret_cast<CppAPIType::Demangle>(dlGetProcAddress("Demangle"));
56+
CppAPIType::GetQualifiedCompleteName GetQualifiedCompleteNameFn =
57+
reinterpret_cast<CppAPIType::GetQualifiedCompleteName>(
58+
dlGetProcAddress("GetQualifiedCompleteName"));
59+
60+
std::string demangled_add_int = DemangleFn(mangled_add_int);
61+
std::string demangled_add_double = DemangleFn(mangled_add_double);
62+
63+
EXPECT_NE(demangled_add_int.find(GetQualifiedCompleteNameFn(Decls[0])),
64+
std::string::npos);
65+
EXPECT_NE(demangled_add_double.find(GetQualifiedCompleteNameFn(Decls[1])),
66+
std::string::npos);
67+
}

0 commit comments

Comments
 (0)