From b026a007908c91968a58685370f98217bc484b64 Mon Sep 17 00:00:00 2001 From: Emil Dotchevski Date: Wed, 21 Aug 2024 09:59:26 -0700 Subject: [PATCH] Improved demangling for prettier verbose_diagnostic_info printing --- include/boost/leaf/common.hpp | 4 +- include/boost/leaf/detail/demangle.hpp | 80 +++++++++++++++++++------- include/boost/leaf/detail/print.hpp | 8 +-- include/boost/leaf/error.hpp | 2 +- test/diagnostic_info_test1.cpp | 3 +- 5 files changed, 68 insertions(+), 29 deletions(-) diff --git a/include/boost/leaf/common.hpp b/include/boost/leaf/common.hpp index 55ae517a..284a302f 100644 --- a/include/boost/leaf/common.hpp +++ b/include/boost/leaf/common.hpp @@ -57,7 +57,7 @@ struct BOOST_LEAF_SYMBOL_VISIBLE e_errno template friend std::ostream & operator<<(std::basic_ostream & os, e_errno const & err) { - return os << type() << ": " << err.value << ", \"" << std::strerror(err.value) << '"'; + return print_type_str(os) << err.value << ", \"" << std::strerror(err.value) << '"'; } }; @@ -101,7 +101,7 @@ namespace windows *--z = 0; if( z[-1] == '\r' ) *--z = 0; - return os << type() << ": " << err.value << ", \"" << (LPCSTR)mb.p << '"'; + return print_type_str(os) << err.value << ", \"" << (LPCSTR)mb.p << '"'; } return os; } diff --git a/include/boost/leaf/detail/demangle.hpp b/include/boost/leaf/detail/demangle.hpp index 096276f8..f1ded0c0 100644 --- a/include/boost/leaf/detail/demangle.hpp +++ b/include/boost/leaf/detail/demangle.hpp @@ -17,6 +17,7 @@ #include +#include #include namespace boost { namespace leaf { @@ -24,37 +25,74 @@ namespace boost { namespace leaf { namespace leaf_detail { template - BOOST_LEAF_CONSTEXPR inline char const * check_prefix( char const * t, char const (&prefix)[N] ) + BOOST_LEAF_CONSTEXPR inline int check_prefix(char const * t, char const (&prefix)[N]) noexcept { - return std::strncmp(t,prefix,sizeof(prefix)-1)==0 ? t+sizeof(prefix)-1 : t; + return std::strncmp(t, prefix, sizeof(prefix)-1) == 0 ? sizeof(prefix) - 1 : 0; } } template -inline char const * type() +inline char const * type_str() { - using leaf_detail::check_prefix; - char const * t = -#ifdef __FUNCSIG__ - __FUNCSIG__; -#else - __PRETTY_FUNCTION__; -#endif #if defined(__clang__) - BOOST_LEAF_ASSERT(check_prefix(t,"const char *boost::leaf::type() ")==t+32); - return t+32; + BOOST_LEAF_ASSERT(leaf_detail::check_prefix(__PRETTY_FUNCTION__, "const char *boost::leaf::type_str() [Name = ") == 44); + return __PRETTY_FUNCTION__ + 44; #elif defined(__GNUC__) - BOOST_LEAF_ASSERT(check_prefix(t,"const char* boost::leaf::type() ")==t+32); - return t+32; + BOOST_LEAF_ASSERT(leaf_detail::check_prefix(__PRETTY_FUNCTION__, "const char* boost::leaf::type_str() [with Name = ") == 49); + return __PRETTY_FUNCTION__ + 49; +#elif defined _MSC_VER + if( char const * p = std::strstr(__FUNCSIG__, "boost::leaf::type_str<") ) + return p + 22; + else + return __FUNCSIG__; #else - char const * clang_style = check_prefix(t,"const char *boost::leaf::type() "); - if( clang_style!=t ) - return clang_style; - char const * gcc_style = check_prefix(t,"const char* boost::leaf::type() "); - if( gcc_style!=t ) - return gcc_style; + if( int clang_style = leaf_detail::check_prefix(__PRETTY_FUNCTION__, "const char *boost::leaf::type_str() [Name = ") ) + return __PRETTY_FUNCTION__ + clang_style; + else if( int gcc_style = leaf_detail::check_prefix(__PRETTY_FUNCTION__, "const char* boost::leaf::type_str() [with Name = ") ) + return __PRETTY_FUNCTION__ + gcc_style; + else + return __PRETTY_FUNCTION__; #endif - return t; +} + +template +inline std::ostream & print_type_str(std::basic_ostream & os) +{ + if( char const * t = type_str() ) + { + char const * end = std::strchr(t, 0); +#if defined(__clang__) || defined(__GNUC__) + BOOST_LEAF_ASSERT(end != t); + BOOST_LEAF_ASSERT(end[-1] == ']'); + return os.write(t, end - t - 1) << ": "; +#elif defined(_MSC_VER) + BOOST_LEAF_ASSERT(end - t > 7); + BOOST_LEAF_ASSERT(std::memcmp(end - 7, ">(void)", 7) == 0); + if( *t == 's' ) + { + BOOST_LEAF_ASSERT(std::memcmp(t + 1, "truct ", 6) == 0); + t += 7; + } + else if( *t == 'c' ) + { + BOOST_LEAF_ASSERT(std::memcmp(t + 1, "lass ", 5) == 0); + t += 6; + } + else if( *t == 'e' ) + { + BOOST_LEAF_ASSERT(std::memcmp(t + 1, "num ", 4) == 0); + t += 5; + } + return os.write(t, end - t - 7) << ": "; +#else + if( end != t && end[-1] == ']') + return os.write(t, end - t - 1) << ": "; + else + return os << t << ": "; +#endif + } + else + return os << "no name: "; } } } diff --git a/include/boost/leaf/detail/print.hpp b/include/boost/leaf/detail/print.hpp index eb05b30e..c0e29d5f 100644 --- a/include/boost/leaf/detail/print.hpp +++ b/include/boost/leaf/detail/print.hpp @@ -70,7 +70,7 @@ namespace leaf_detail template static void print( std::basic_ostream & os, Wrapper const & x ) { - os << type() << ": " << x.value; + print_type_str(os) << x.value; } }; @@ -82,7 +82,7 @@ namespace leaf_detail template static void print( std::basic_ostream & os, Wrapper const & ex ) { - os << type() << ": std::exception::what(): " << ex.what(); + print_type_str(os) << "std::exception::what(): " << ex.what(); } }; @@ -94,7 +94,7 @@ namespace leaf_detail template static void print( std::basic_ostream & os, Wrapper const & ) { - os << type() << ": {not printable}"; + print_type_str(os) << "{not printable}"; } }; @@ -106,7 +106,7 @@ namespace leaf_detail template static void print( std::basic_ostream & os, Wrapper const & w ) { - os << type() << ": " << static_cast::type>(w); + print_type_str(os) << static_cast::type>(w); } }; diff --git a/include/boost/leaf/error.hpp b/include/boost/leaf/error.hpp index 3b976736..cf0b6e01 100644 --- a/include/boost/leaf/error.hpp +++ b/include/boost/leaf/error.hpp @@ -77,7 +77,7 @@ struct BOOST_LEAF_SYMBOL_VISIBLE e_source_location template friend std::ostream & operator<<( std::basic_ostream & os, e_source_location const & x ) { - return os << leaf::type() << ": " << x.file << '(' << x.line << ") in function " << x.function; + return leaf::print_type_str(os) << x.file << '(' << x.line << ") in function " << x.function; } }; diff --git a/test/diagnostic_info_test1.cpp b/test/diagnostic_info_test1.cpp index 20bb058b..44028bf8 100644 --- a/test/diagnostic_info_test1.cpp +++ b/test/diagnostic_info_test1.cpp @@ -73,8 +73,9 @@ struct printable_info_non_printable_payload } }; -struct non_printable_info_printable_payload +class non_printable_info_printable_payload { +public: printable_payload value; };