Skip to content

Commit

Permalink
Improved demangling for prettier verbose_diagnostic_info printing
Browse files Browse the repository at this point in the history
  • Loading branch information
zajo committed Aug 21, 2024
1 parent 144cd1d commit b026a00
Show file tree
Hide file tree
Showing 5 changed files with 68 additions and 29 deletions.
4 changes: 2 additions & 2 deletions include/boost/leaf/common.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ struct BOOST_LEAF_SYMBOL_VISIBLE e_errno
template <class CharT, class Traits>
friend std::ostream & operator<<(std::basic_ostream<CharT, Traits> & os, e_errno const & err)
{
return os << type<e_errno>() << ": " << err.value << ", \"" << std::strerror(err.value) << '"';
return print_type_str<e_errno>(os) << err.value << ", \"" << std::strerror(err.value) << '"';
}
};

Expand Down Expand Up @@ -101,7 +101,7 @@ namespace windows
*--z = 0;
if( z[-1] == '\r' )
*--z = 0;
return os << type<e_LastError>() << ": " << err.value << ", \"" << (LPCSTR)mb.p << '"';
return print_type_str<e_LastError>(os) << err.value << ", \"" << (LPCSTR)mb.p << '"';
}
return os;
}
Expand Down
80 changes: 59 additions & 21 deletions include/boost/leaf/detail/demangle.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,44 +17,82 @@

#include <boost/leaf/config.hpp>

#include <iosfwd>
#include <cstring>

namespace boost { namespace leaf {

namespace leaf_detail
{
template <int N>
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 <class Name>
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 <class Name, class CharT, class Traits>
inline std::ostream & print_type_str(std::basic_ostream<CharT, Traits> & os)
{
if( char const * t = type_str<Name>() )
{
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: ";
}

} }
Expand Down
8 changes: 4 additions & 4 deletions include/boost/leaf/detail/print.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ namespace leaf_detail
template <class CharT, class Traits>
static void print( std::basic_ostream<CharT, Traits> & os, Wrapper const & x )
{
os << type<Wrapper>() << ": " << x.value;
print_type_str<Wrapper>(os) << x.value;
}
};

Expand All @@ -82,7 +82,7 @@ namespace leaf_detail
template <class CharT, class Traits>
static void print( std::basic_ostream<CharT, Traits> & os, Wrapper const & ex )
{
os << type<Wrapper>() << ": std::exception::what(): " << ex.what();
print_type_str<Wrapper>(os) << "std::exception::what(): " << ex.what();
}
};

Expand All @@ -94,7 +94,7 @@ namespace leaf_detail
template <class CharT, class Traits>
static void print( std::basic_ostream<CharT, Traits> & os, Wrapper const & )
{
os << type<Wrapper>() << ": {not printable}";
print_type_str<Wrapper>(os) << "{not printable}";
}
};

Expand All @@ -106,7 +106,7 @@ namespace leaf_detail
template <class CharT, class Traits>
static void print( std::basic_ostream<CharT, Traits> & os, Wrapper const & w )
{
os << type<Wrapper>() << ": " << static_cast<typename std::underlying_type<Wrapper>::type>(w);
print_type_str<Wrapper>(os) << static_cast<typename std::underlying_type<Wrapper>::type>(w);
}
};

Expand Down
2 changes: 1 addition & 1 deletion include/boost/leaf/error.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ struct BOOST_LEAF_SYMBOL_VISIBLE e_source_location
template <class CharT, class Traits>
friend std::ostream & operator<<( std::basic_ostream<CharT, Traits> & os, e_source_location const & x )
{
return os << leaf::type<e_source_location>() << ": " << x.file << '(' << x.line << ") in function " << x.function;
return leaf::print_type_str<e_source_location>(os) << x.file << '(' << x.line << ") in function " << x.function;
}
};

Expand Down
3 changes: 2 additions & 1 deletion test/diagnostic_info_test1.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
};

Expand Down

0 comments on commit b026a00

Please sign in to comment.