Skip to content

Commit

Permalink
Improved diagnostics
Browse files Browse the repository at this point in the history
  • Loading branch information
zajo committed Sep 3, 2024
1 parent 907bd6c commit acf0ae1
Show file tree
Hide file tree
Showing 22 changed files with 767 additions and 499 deletions.
12 changes: 12 additions & 0 deletions .vscode/tasks.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,18 @@
"command": "cd ${workspaceRoot} && meson setup -D leaf_boost_examples=true -D leaf_lua_examples=true _bld/debug && meson setup -D leaf_boost_examples=true -D leaf_lua_examples=true -D leaf_hpp=true _bld/debug_leaf_hpp && meson setup -D leaf_boost_examples=true -D leaf_lua_examples=true _bld/release --buildtype release && meson setup -D leaf_boost_examples=true -D leaf_lua_examples=true -D leaf_hpp=true _bld/release_leaf_hpp --buildtype release && meson setup -D leaf_diagnostics=0 -D cpp_eh=none -D b_ndebug=true -D b_lto=true -D leaf_enable_benchmarks=true _bld/benchmark --buildtype release",
"problemMatcher": []
},
{
"label": "Configure Meson build directories (no diagnostics)",
"type": "shell",
"command": "cd ${workspaceRoot} && meson setup -D leaf_diagnostics=0 -D leaf_boost_examples=true -D leaf_lua_examples=true _bld/debug && meson setup -D leaf_diagnostics=0 -D leaf_boost_examples=true -D leaf_lua_examples=true -D leaf_hpp=true _bld/debug_leaf_hpp && meson setup -D leaf_diagnostics=0 -D leaf_boost_examples=true -D leaf_lua_examples=true _bld/release --buildtype release && meson setup -D leaf_diagnostics=0 -D leaf_boost_examples=true -D leaf_lua_examples=true -D leaf_hpp=true _bld/release_leaf_hpp --buildtype release",
"problemMatcher": []
},
{
"label": "Configure Meson build directories (no capture)",
"type": "shell",
"command": "cd ${workspaceRoot} && meson setup -D leaf_capture=0 -D leaf_boost_examples=true -D leaf_lua_examples=true _bld/debug && meson setup -D leaf_capture=0 -D leaf_boost_examples=true -D leaf_lua_examples=true -D leaf_hpp=true _bld/debug_leaf_hpp && meson setup -D leaf_capture=0 -D leaf_boost_examples=true -D leaf_lua_examples=true _bld/release --buildtype release && meson setup -D leaf_capture=0 -D leaf_boost_examples=true -D leaf_lua_examples=true -D leaf_hpp=true _bld/release_leaf_hpp --buildtype release",
"problemMatcher": []
},
{
"label": "Configure Meson build directories (no Boost)",
"type": "shell",
Expand Down
4 changes: 2 additions & 2 deletions include/boost/leaf/common.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,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 << parse_name<e_errno>() << ": " << err.value << ", \"" << std::strerror(err.value) << '"';
return os << err.value << ", \"" << std::strerror(err.value) << '"';
}
};

Expand Down Expand Up @@ -102,7 +102,7 @@ namespace windows
*--z = 0;
if( z[-1] == '\r' )
*--z = 0;
return os << parse_name<e_LastError>() << ": " << err.value << ", \"" << (LPCSTR)mb.p << '"';
return os << err.value << ", \"" << (LPCSTR)mb.p << '"';
}
return os;
}
Expand Down
7 changes: 0 additions & 7 deletions include/boost/leaf/config.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,6 @@

////////////////////////////////////////

#ifdef BOOST_LEAF_DIAGNOSTICS
# warning BOOST_LEAF_DIAGNOSTICS has been renamed to BOOST_LEAF_CFG_DIAGNOSTICS.
# define BOOST_LEAF_CFG_DIAGNOSTICS BOOST_LEAF_DIAGNOSTICS
#endif

////////////////////////////////////////

#ifdef BOOST_LEAF_TLS_FREERTOS

# ifndef BOOST_LEAF_EMBEDDED
Expand Down
43 changes: 25 additions & 18 deletions include/boost/leaf/context.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -136,50 +136,56 @@ namespace leaf_detail

namespace leaf_detail
{
template <int I, class Tuple>
template <int I, class Tup>
struct tuple_for_each
{
BOOST_LEAF_CONSTEXPR static void activate( Tuple & tup ) noexcept
BOOST_LEAF_CONSTEXPR static void activate( Tup & tup ) noexcept
{
static_assert(!std::is_same<error_info, typename std::decay<decltype(std::get<I-1>(tup))>::type>::value, "Bug in LEAF: context type deduction");
tuple_for_each<I-1,Tuple>::activate(tup);
tuple_for_each<I-1,Tup>::activate(tup);
std::get<I-1>(tup).activate();
}

BOOST_LEAF_CONSTEXPR static void deactivate( Tuple & tup ) noexcept
BOOST_LEAF_CONSTEXPR static void deactivate( Tup & tup ) noexcept
{
static_assert(!std::is_same<error_info, typename std::decay<decltype(std::get<I-1>(tup))>::type>::value, "Bug in LEAF: context type deduction");
std::get<I-1>(tup).deactivate();
tuple_for_each<I-1,Tuple>::deactivate(tup);
tuple_for_each<I-1,Tup>::deactivate(tup);
}

BOOST_LEAF_CONSTEXPR static void unload( Tuple & tup, int err_id ) noexcept
BOOST_LEAF_CONSTEXPR static void unload( Tup & tup, int err_id ) noexcept
{
static_assert(!std::is_same<error_info, typename std::decay<decltype(std::get<I-1>(tup))>::type>::value, "Bug in LEAF: context type deduction");
BOOST_LEAF_ASSERT(err_id != 0);
auto & sl = std::get<I-1>(tup);
sl.unload(err_id);
tuple_for_each<I-1,Tuple>::unload(tup, err_id);
tuple_for_each<I-1,Tup>::unload(tup, err_id);
}

template <class CharT, class Traits>
static void print( std::basic_ostream<CharT, Traits> & os, void const * tup, int err_id_to_print )
static void print(std::basic_ostream<CharT, Traits> & os, void const * tup, error_id to_print, char const * & prefix)
{
BOOST_LEAF_ASSERT(tup != nullptr);
tuple_for_each<I-1,Tuple>::print(os, tup, err_id_to_print);
std::get<I-1>(*static_cast<Tuple const *>(tup)).print(os, err_id_to_print);
tuple_for_each<I-1,Tup>::print(os, tup, to_print, prefix);
std::get<I-1>(*static_cast<Tup const *>(tup)).print(os, to_print, prefix);
}
};

template <class Tuple>
struct tuple_for_each<0, Tuple>
template <class Tup>
struct tuple_for_each<0, Tup>
{
BOOST_LEAF_CONSTEXPR static void activate( Tuple & ) noexcept { }
BOOST_LEAF_CONSTEXPR static void deactivate( Tuple & ) noexcept { }
BOOST_LEAF_CONSTEXPR static void unload( Tuple &, int ) noexcept { }
BOOST_LEAF_CONSTEXPR static void activate( Tup & ) noexcept { }
BOOST_LEAF_CONSTEXPR static void deactivate( Tup & ) noexcept { }
BOOST_LEAF_CONSTEXPR static void unload( Tup &, int ) noexcept { }
template <class CharT, class Traits>
BOOST_LEAF_CONSTEXPR static void print( std::basic_ostream<CharT, Traits> &, void const *, int ) { }
BOOST_LEAF_CONSTEXPR static void print(std::basic_ostream<CharT, Traits> &, void const *, error_id, char const * &) { }
};

template <class Tup, class CharT, class Traits>
BOOST_LEAF_CONSTEXPR void print_tuple_contents(std::basic_ostream<CharT, Traits> & os, void const * tup, error_id to_print, char const * & prefix)
{
tuple_for_each<std::tuple_size<Tup>::value, Tup>::print(os, tup, to_print, prefix);
}
}

////////////////////////////////////////////
Expand Down Expand Up @@ -300,14 +306,15 @@ class context
template <class CharT, class Traits>
void print( std::basic_ostream<CharT, Traits> & os ) const
{
leaf_detail::tuple_for_each<std::tuple_size<Tup>::value,Tup>::print(os, &tup_, 0);
char const * prefix = "Contents:";
leaf_detail::print_tuple_contents<Tup>(os, &tup_, error_id(), prefix);
}

template <class CharT, class Traits>
friend std::ostream & operator<<( std::basic_ostream<CharT, Traits> & os, context const & ctx )
{
ctx.print(os);
return os;
return os << '\n';
}

template <class R, class... H>
Expand Down
17 changes: 9 additions & 8 deletions include/boost/leaf/detail/capture_list.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,16 @@
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

#include <boost/leaf/config.hpp>
#include <boost/leaf/detail/print.hpp>

#if BOOST_LEAF_CFG_CAPTURE

#include <iosfwd>

namespace boost { namespace leaf {

class error_id;

namespace leaf_detail
{
struct BOOST_LEAF_SYMBOL_VISIBLE tls_tag_id_factory_current_id;
Expand All @@ -31,7 +34,7 @@ namespace leaf_detail

virtual void unload( int err_id ) = 0;
#if BOOST_LEAF_CFG_DIAGNOSTICS
virtual void print( std::ostream &, int err_id_to_print ) const = 0;
virtual void print(std::ostream &, error_id const & to_print, char const * & prefix) const = 0;
#endif

protected:
Expand Down Expand Up @@ -94,23 +97,21 @@ namespace leaf_detail
}

template <class CharT, class Traits>
void print(std::basic_ostream<CharT, Traits> & os, int const err_id_to_print, char const * title = nullptr) const
void print(std::basic_ostream<CharT, Traits> & os, error_id const & to_print, char const * & prefix) const
{
#if BOOST_LEAF_CFG_DIAGNOSTICS
if( first_ )
{
if( title )
os << title;
for_each(
[&os, err_id_to_print]( node const & n )
[&os, &to_print, &prefix]( node const & n )
{
n.print(os, err_id_to_print);
n.print(os, to_print, prefix);
} );
}
#else
(void) os;
(void) title;
(void) err_id_to_print;
(void) prefix;
(void) to_print;
#endif
}
};
Expand Down
118 changes: 63 additions & 55 deletions include/boost/leaf/detail/demangle.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -109,69 +109,77 @@ namespace leaf_detail
{
return cpp11_suffix<S1, S2, S1 - 2, S2 - 2>::check(str, suffix) ? S1 - S2 : 0;
}
}

struct parsed_name
{
char const * name;
int len;
parsed_name(char const * name, int len) noexcept:
name(name),
len(len)
{
}
template <int S>
parsed_name(char const(&name)[S]) noexcept:
name(name),
len(S-1)
{
}
bool parse_success() const noexcept
struct parsed_name
{
return name[len] != 0;
}
template <class CharT, class Traits>
friend std::ostream & operator<<(std::basic_ostream<CharT, Traits> & os, parsed_name const & pn)
char const * name;
int len;
parsed_name(char const * name, int len) noexcept:
name(name),
len(len)
{
}
template <int S>
parsed_name(char const(&name)[S]) noexcept:
name(name),
len(S-1)
{
}
bool parse_success() const noexcept
{
return name[len] != 0;
}
template <class CharT, class Traits>
friend std::ostream & operator<<(std::basic_ostream<CharT, Traits> & os, parsed_name const & pn)
{
return os.write(pn.name, pn.len);
}
};

// Workaround - we only use this function if parse_name (below) fails to parse __PRETTY_FUNCTION__ / __FUNCSIG__.
// In this case parse_name should be fixed to support the newly encountered (note, parsing is done at compile-time).
template <class Name>
parsed_name please_update_parse_name()
{
return os.write(pn.name, pn.len);
return parsed_name(BOOST_LEAF_PRETTY_FUNCTION);
}
};

template <class Name>
parsed_name parse_name()
{
// Workaround for older gcc compilers where __PRETTY_FUNCTION__ is not constexpr.
// Instead of evaluating constexpr int x = f(__PRETTY_FUNCTION__), which fails,
// we evaluate int const x = f(__PRETTY_FUNCTION__). Then we enforce compile-time
// execution by evaluating sizeof(char[1 + x]) -1.
template <class Name>
parsed_name parse_name()
{
// Workaround for older gcc compilers where __PRETTY_FUNCTION__ is not constexpr.
// Instead of evaluating constexpr int x = f(__PRETTY_FUNCTION__), which fails,
// we evaluate int const x = f(__PRETTY_FUNCTION__). Then we enforce compile-time
// execution by evaluating sizeof(char[1 + x]) -1.
#define BOOST_LEAF_PARSE_PF(prefix, suffix) \
{ \
if( int const s = leaf_detail::check_suffix(BOOST_LEAF_PRETTY_FUNCTION, suffix) ) \
if( int const p = leaf_detail::check_prefix(BOOST_LEAF_PRETTY_FUNCTION, prefix) ) \
return parsed_name(BOOST_LEAF_PRETTY_FUNCTION + sizeof(char[1 + p]) - 1, sizeof(char[1 + s - p]) - 1); \
}
// clang style:
BOOST_LEAF_PARSE_PF( "parsed_name boost::leaf::parse_name() [Name = ", "]");
// old clang style:
BOOST_LEAF_PARSE_PF( "boost::leaf::parsed_name boost::leaf::parse_name() [Name = ", "]");
// gcc style:
BOOST_LEAF_PARSE_PF( "boost::leaf::parsed_name boost::leaf::parse_name() [with Name = ", "]");
// msvc style, __cdecl, struct/class/enum:
BOOST_LEAF_PARSE_PF( "struct boost::leaf::parsed_name __cdecl boost::leaf::parse_name<struct ", ">(void)");
BOOST_LEAF_PARSE_PF( "struct boost::leaf::parsed_name __cdecl boost::leaf::parse_name<class ", ">(void)");
BOOST_LEAF_PARSE_PF( "struct boost::leaf::parsed_name __cdecl boost::leaf::parse_name<enum ", ">(void)");
// msvc style, __stdcall, struct/class/enum:
BOOST_LEAF_PARSE_PF( "struct boost::leaf::parsed_name __stdcall boost::leaf::parse_name<struct ", ">(void)");
BOOST_LEAF_PARSE_PF( "struct boost::leaf::parsed_name __stdcall boost::leaf::parse_name<class ", ">(void)");
BOOST_LEAF_PARSE_PF( "struct boost::leaf::parsed_name __stdcall boost::leaf::parse_name<enum ", ">(void)");
// msvc style, __fastcall, struct/class/enum:
BOOST_LEAF_PARSE_PF( "struct boost::leaf::parsed_name __fastcall boost::leaf::parse_name<struct ", ">(void)");
BOOST_LEAF_PARSE_PF( "struct boost::leaf::parsed_name __fastcall boost::leaf::parse_name<class ", ">(void)");
BOOST_LEAF_PARSE_PF( "struct boost::leaf::parsed_name __fastcall boost::leaf::parse_name<enum ", ">(void)");
{ \
if( int const s = leaf_detail::check_suffix(BOOST_LEAF_PRETTY_FUNCTION, suffix) ) \
if( int const p = leaf_detail::check_prefix(BOOST_LEAF_PRETTY_FUNCTION, prefix) ) \
return parsed_name(BOOST_LEAF_PRETTY_FUNCTION + sizeof(char[1 + p]) - 1, sizeof(char[1 + s - p]) - 1); \
}
// clang style:
BOOST_LEAF_PARSE_PF( "parsed_name boost::leaf::leaf_detail::parse_name() [Name = ", "]");
// old clang style:
BOOST_LEAF_PARSE_PF( "boost::leaf::leaf_detail::parsed_name boost::leaf::leaf_detail::parse_name() [Name = ", "]");
// gcc style:
BOOST_LEAF_PARSE_PF( "boost::leaf::leaf_detail::parsed_name boost::leaf::leaf_detail::parse_name() [with Name = ", "]");
// msvc style, __cdecl, struct/class/enum:
BOOST_LEAF_PARSE_PF( "struct boost::leaf::leaf_detail::parsed_name __cdecl boost::leaf::leaf_detail::parse_name<struct ", ">(void)");
BOOST_LEAF_PARSE_PF( "struct boost::leaf::leaf_detail::parsed_name __cdecl boost::leaf::leaf_detail::parse_name<class ", ">(void)");
BOOST_LEAF_PARSE_PF( "struct boost::leaf::leaf_detail::parsed_name __cdecl boost::leaf::leaf_detail::parse_name<enum ", ">(void)");
// msvc style, __stdcall, struct/class/enum:
BOOST_LEAF_PARSE_PF( "struct boost::leaf::leaf_detail::parsed_name __stdcall boost::leaf::leaf_detail::parse_name<struct ", ">(void)");
BOOST_LEAF_PARSE_PF( "struct boost::leaf::leaf_detail::parsed_name __stdcall boost::leaf::leaf_detail::parse_name<class ", ">(void)");
BOOST_LEAF_PARSE_PF( "struct boost::leaf::leaf_detail::parsed_name __stdcall boost::leaf::leaf_detail::parse_name<enum ", ">(void)");
// msvc style, __fastcall, struct/class/enum:
BOOST_LEAF_PARSE_PF( "struct boost::leaf::leaf_detail::parsed_name __fastcall boost::leaf::leaf_detail::parse_name<struct ", ">(void)");
BOOST_LEAF_PARSE_PF( "struct boost::leaf::leaf_detail::parsed_name __fastcall boost::leaf::leaf_detail::parse_name<class ", ">(void)");
BOOST_LEAF_PARSE_PF( "struct boost::leaf::leaf_detail::parsed_name __fastcall boost::leaf::leaf_detail::parse_name<enum ", ">(void)");
#undef BOOST_LEAF_PARSE_PF

// Unrecognized __PRETTY_FUNCTION__/__FUNSIG__ format, return as-is. Note, parsing is done at compile-time.
return parsed_name(BOOST_LEAF_PRETTY_FUNCTION);
// Unrecognized __PRETTY_FUNCTION__ / __FUNCSIG__ format, return as-is. Note, parsing is done at compile-time.
return please_update_parse_name<Name>();
}
}

} }
Expand Down
Loading

0 comments on commit acf0ae1

Please sign in to comment.