Skip to content

Commit 5d513ca

Browse files
Add DemangleSymbol function
1 parent f49ed08 commit 5d513ca

File tree

3 files changed

+53
-0
lines changed

3 files changed

+53
-0
lines changed

include/clang/Interpreter/CppInterOp.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -185,6 +185,9 @@ namespace Cpp {
185185
///\returns the version string information of the library.
186186
CPPINTEROP_API std::string GetVersion();
187187

188+
///\returns the demangled representation of the given mangled_name
189+
CPPINTEROP_API std::string DemangleSymbol(const std::string& mangled_name);
190+
188191
/// Enables or disables the debugging printouts on stderr.
189192
/// Debugging output can be enabled also by the environment variable
190193
/// CPPINTEROP_EXTRA_INTERPRETER_ARGS. For example,

lib/Interpreter/CppInterOp.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131

3232
#include "llvm/ADT/SmallVector.h"
3333
#include "llvm/ADT/StringRef.h"
34+
#include "llvm/Demangle/Demangle.h"
3435
#include "llvm/Support/Casting.h"
3536
#include "llvm/Support/Debug.h"
3637
#include "llvm/Support/raw_os_ostream.h"
@@ -155,6 +156,13 @@ namespace Cpp {
155156
return fullVersion + "[" + clang::getClangFullVersion() + "])\n";
156157
}
157158

159+
std::string DemangleSymbol(const std::string& mangled_name) {
160+
char* demangle = itaniumDemangle(mangled_name);
161+
std::string res(demangle);
162+
std::free(demangle);
163+
return res;
164+
}
165+
158166
void EnableDebugOutput(bool value/* =true*/) {
159167
llvm::DebugFlag = value;
160168
}

unittests/CppInterOp/ScopeReflectionTest.cpp

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,48 @@ using namespace TestUtils;
1717
using namespace llvm;
1818
using namespace clang;
1919

20+
TEST(ScopeReflectionTest, DemangleSymbol) {
21+
std::string code = R"(
22+
class C { public: virtual ~C() {} };
23+
namespace scope {
24+
class C { public: virtual ~C() {} };
25+
}
26+
void *get_c() { return new C; }
27+
void *get_scope_c() { return new scope::C; }
28+
)";
29+
30+
EXPECT_EQ(Cpp::Declare(code.c_str()), 0);
31+
32+
Cpp::TCppScope_t get_c = Cpp::GetNamed("get_c");
33+
Cpp::TCppScope_t get_scope_c = Cpp::GetNamed("get_scope_c");
34+
Cpp::TCppScope_t C = Cpp::GetNamed("C");
35+
Cpp::TCppScope_t scope_C = Cpp::GetNamed("C", Cpp::GetNamed("scope"));
36+
37+
auto get_c_callable = Cpp::MakeFunctionCallable(get_c);
38+
EXPECT_TRUE(get_c_callable.getKind() == Cpp::JitCall::kGenericCall);
39+
void* c = nullptr;
40+
get_c_callable.Invoke(&c);
41+
EXPECT_TRUE(c);
42+
43+
auto get_scope_c_callable = Cpp::MakeFunctionCallable(get_scope_c);
44+
EXPECT_TRUE(get_scope_c_callable.getKind() == Cpp::JitCall::kGenericCall);
45+
void* scope_c = nullptr;
46+
get_scope_c_callable.Invoke(&scope_c);
47+
EXPECT_TRUE(scope_c);
48+
49+
struct DynamicType {
50+
// Helper class to enable typeid on any address
51+
// Used in code similar to:
52+
// typeid(*(DynamicType*)void_ptr);
53+
virtual ~DynamicType() {}
54+
};
55+
56+
EXPECT_EQ(Cpp::DemangleSymbol(typeid(*(DynamicType*)c).name()),
57+
Cpp::GetQualifiedCompleteName(C));
58+
EXPECT_EQ(Cpp::DemangleSymbol(typeid(*(DynamicType*)scope_c).name()),
59+
Cpp::GetQualifiedCompleteName(scope_C));
60+
}
61+
2062
TEST(ScopeReflectionTest, IsAggregate) {
2163
std::vector<Decl *> Decls;
2264
std::string code = R"(

0 commit comments

Comments
 (0)