From 269322e8c2f9fe8c5f7ee0b1624e20e19a49816b Mon Sep 17 00:00:00 2001 From: ryuukk <44361234+ryuukk@users.noreply.github.com> Date: Wed, 6 Mar 2024 16:33:06 +0100 Subject: [PATCH 1/6] Add helper demangle function for 3rd party tools --- druntime/src/core/demangle.d | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/druntime/src/core/demangle.d b/druntime/src/core/demangle.d index 272ee1e1ba4b..3b17c86a767b 100644 --- a/druntime/src/core/demangle.d +++ b/druntime/src/core/demangle.d @@ -3273,3 +3273,13 @@ private struct BufSlice auto getSlice() inout nothrow scope { return buf[from .. to]; } size_t length() const scope { return to - from; } } + +extern(C) export int __d_demangle(const(char*) mangled, char* buffer, size_t bufferLength) +{ + import core.stdc.string: strlen; + if (mangled == null) return 0; + + auto ret = demangle( cast(char[]) mangled[0 .. strlen(mangled)], buffer[0 .. bufferLength] ); + buffer[ret.length] = 0; + return 1; +} From f41d0e915bee695f1479d048da01328777e7684f Mon Sep 17 00:00:00 2001 From: ryuukk <44361234+ryuukk@users.noreply.github.com> Date: Thu, 7 Mar 2024 12:01:22 +0100 Subject: [PATCH 2/6] Return success or failure --- druntime/src/core/demangle.d | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/druntime/src/core/demangle.d b/druntime/src/core/demangle.d index 3b17c86a767b..593ed6933826 100644 --- a/druntime/src/core/demangle.d +++ b/druntime/src/core/demangle.d @@ -3281,5 +3281,5 @@ extern(C) export int __d_demangle(const(char*) mangled, char* buffer, size_t buf auto ret = demangle( cast(char[]) mangled[0 .. strlen(mangled)], buffer[0 .. bufferLength] ); buffer[ret.length] = 0; - return 1; + return ret.ptr != mangled; } From 72ac8f75ccaa840fe271ea65c0ca067ebef53335 Mon Sep 17 00:00:00 2001 From: ryuukk <44361234+ryuukk@users.noreply.github.com> Date: Sat, 9 Mar 2024 10:47:21 +0100 Subject: [PATCH 3/6] Apply review suggestions --- druntime/src/core/demangle.d | 67 ++++++++++++++++++++++++++++++++---- 1 file changed, 61 insertions(+), 6 deletions(-) diff --git a/druntime/src/core/demangle.d b/druntime/src/core/demangle.d index 593ed6933826..de29ef6e1757 100644 --- a/druntime/src/core/demangle.d +++ b/druntime/src/core/demangle.d @@ -3274,12 +3274,67 @@ private struct BufSlice size_t length() const scope { return to - from; } } -extern(C) export int __d_demangle(const(char*) mangled, char* buffer, size_t bufferLength) + + +/** + * Demangles D mangled names. + * + * Params: + * mangled = The string to demangle. + * buffer = A destination buffer. + * bufferLength = The length of the destination buffer. + * + * Returns: + * 1 for success 0 for failure + */ +extern(C) export int d_demangle(const(char*) mangled, char* buffer, size_t bufferLength) { - import core.stdc.string: strlen; - if (mangled == null) return 0; + import core.stdc.string: strlen, memcpy; + if (mangled == null) + return 0; + + auto mangledSlice = mangled[0 .. strlen(mangled)]; + auto demangled = demangle(mangledSlice); + + if (demangled.ptr == null || demangled.ptr == mangled) + return 0; - auto ret = demangle( cast(char[]) mangled[0 .. strlen(mangled)], buffer[0 .. bufferLength] ); - buffer[ret.length] = 0; - return ret.ptr != mangled; + if (demangled.length > bufferLength) + return 0; + + memcpy(buffer, demangled.ptr, demangled.length); + buffer[demangled.length] = 0; + + return 1; +} + + +unittest { + import core.stdc.string: strncmp; + { + char[512] buffer; + + int ok = d_demangle("_D6mangle2CC6memberMFNlZPi", buffer.ptr, buffer.length); + + assert(ok == 1); + assert(strncmp(buffer.ptr, "scope int* mangle.CC.member()", buffer.length) == 0); + } + + { + // test invalid mangled name + char[512] buffer; + + int ok = d_demangle("", buffer.ptr, buffer.length); + + assert(ok == 0); + } + + { + // test failure for buffer too small + char[8] buffer; + + int ok = d_demangle("_D6mangle2CC6memberMFNlZPi", buffer.ptr, buffer.length); + + assert(ok == 0); + } } From 0462b69e1feb63581df2f33bd35fc09f57629711 Mon Sep 17 00:00:00 2001 From: ryuukk <44361234+ryuukk@users.noreply.github.com> Date: Sat, 9 Mar 2024 10:48:54 +0100 Subject: [PATCH 4/6] Remove unnecessary export --- druntime/src/core/demangle.d | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/druntime/src/core/demangle.d b/druntime/src/core/demangle.d index de29ef6e1757..3e4843cab160 100644 --- a/druntime/src/core/demangle.d +++ b/druntime/src/core/demangle.d @@ -3287,7 +3287,7 @@ private struct BufSlice * Returns: * 1 for success 0 for failure */ -extern(C) export int d_demangle(const(char*) mangled, char* buffer, size_t bufferLength) +extern(C) int d_demangle(const(char*) mangled, char* buffer, size_t bufferLength) { import core.stdc.string: strlen, memcpy; if (mangled == null) From a2e1d7e5234ced9be199e7f62e8ebd182e6d14f1 Mon Sep 17 00:00:00 2001 From: ryuukk <44361234+ryuukk@users.noreply.github.com> Date: Sat, 9 Mar 2024 10:57:13 +0100 Subject: [PATCH 5/6] Improve doc --- druntime/src/core/demangle.d | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/druntime/src/core/demangle.d b/druntime/src/core/demangle.d index 3e4843cab160..c9db57ac2f6d 100644 --- a/druntime/src/core/demangle.d +++ b/druntime/src/core/demangle.d @@ -3277,7 +3277,7 @@ private struct BufSlice /** - * Demangles D mangled names. + * C API to demangle D mangled names. * * Params: * mangled = The string to demangle. From fc7421151639af65a465c454f039da5a3418b48d Mon Sep 17 00:00:00 2001 From: ryuukk <44361234+ryuukk@users.noreply.github.com> Date: Sat, 9 Mar 2024 11:00:00 +0100 Subject: [PATCH 6/6] Cleanup --- druntime/src/core/demangle.d | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/druntime/src/core/demangle.d b/druntime/src/core/demangle.d index c9db57ac2f6d..60e14f75e41f 100644 --- a/druntime/src/core/demangle.d +++ b/druntime/src/core/demangle.d @@ -3312,29 +3312,29 @@ extern(C) int d_demangle(const(char*) mangled, char* buffer, size_t bufferLength unittest { import core.stdc.string: strncmp; { - char[512] buffer; + char[512] buffer; - int ok = d_demangle("_D6mangle2CC6memberMFNlZPi", buffer.ptr, buffer.length); + int ok = d_demangle("_D6mangle2CC6memberMFNlZPi", buffer.ptr, buffer.length); - assert(ok == 1); - assert(strncmp(buffer.ptr, "scope int* mangle.CC.member()", buffer.length) == 0); + assert(ok == 1); + assert(strncmp(buffer.ptr, "scope int* mangle.CC.member()", buffer.length) == 0); } - + { // test invalid mangled name - char[512] buffer; + char[512] buffer; - int ok = d_demangle("", buffer.ptr, buffer.length); + int ok = d_demangle("", buffer.ptr, buffer.length); - assert(ok == 0); + assert(ok == 0); } { // test failure for buffer too small - char[8] buffer; + char[8] buffer; - int ok = d_demangle("_D6mangle2CC6memberMFNlZPi", buffer.ptr, buffer.length); + int ok = d_demangle("_D6mangle2CC6memberMFNlZPi", buffer.ptr, buffer.length); - assert(ok == 0); + assert(ok == 0); } }