Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-09-13 08:38:30

0001 #ifndef BOOST_LEAF_DETAIL_DEMANGLE_HPP_INCLUDED
0002 #define BOOST_LEAF_DETAIL_DEMANGLE_HPP_INCLUDED
0003 
0004 // Copyright 2018-2024 Emil Dotchevski and Reverge Studios, Inc.
0005 // Distributed under the Boost Software License, Version 1.0. (See accompanying
0006 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
0007 
0008 // This file is based on boost::core::demangle
0009 //
0010 // Copyright 2014 Peter Dimov
0011 // Copyright 2014 Andrey Semashev
0012 //
0013 // Distributed under the Boost Software License, Version 1.0.
0014 // See accompanying file LICENSE_1_0.txt or copy at
0015 // http://www.boost.org/LICENSE_1_0.txt
0016 
0017 #include <boost/leaf/config.hpp>
0018 #include <iosfwd>
0019 #include <cstdlib>
0020 
0021 #if BOOST_LEAF_CFG_DIAGNOSTICS
0022 
0023 // __has_include is currently supported by GCC and Clang. However GCC 4.9 may have issues and
0024 // returns 1 for 'defined( __has_include )', while '__has_include' is actually not supported:
0025 // https://gcc.gnu.org/bugzilla/show_bug.cgi?id=63662
0026 #if defined(__has_include) && (!defined(__GNUC__) || defined(__clang__) || (__GNUC__ + 0) >= 5)
0027 #   if __has_include(<cxxabi.h>)
0028 #       define BOOST_LEAF_HAS_CXXABI_H
0029 #   endif
0030 #elif defined(__GLIBCXX__) || defined(__GLIBCPP__)
0031 #   define BOOST_LEAF_HAS_CXXABI_H
0032 #endif
0033 
0034 #if defined(BOOST_LEAF_HAS_CXXABI_H)
0035 #   include <cxxabi.h>
0036 //  For some archtectures (mips, mips64, x86, x86_64) cxxabi.h in Android NDK is implemented by gabi++ library
0037 //  (https://android.googlesource.com/platform/ndk/+/master/sources/cxx-stl/gabi++/), which does not implement
0038 //  abi::__cxa_demangle(). We detect this implementation by checking the include guard here.
0039 #   if defined(__GABIXX_CXXABI_H__)
0040 #       undef BOOST_LEAF_HAS_CXXABI_H
0041 #   endif
0042 #endif
0043 
0044 #endif
0045 
0046 namespace boost { namespace leaf {
0047 
0048 namespace detail
0049 {
0050     // The functions below are C++11 constexpr, but we use BOOST_LEAF_ALWAYS_INLINE to control object file
0051     // section count / template bleat. Evidently this makes a difference on gcc / windows at least.
0052 
0053     template <int S1, int S2, int I, bool = S1 >= S2>
0054     struct cpp11_prefix
0055     {
0056         BOOST_LEAF_ALWAYS_INLINE constexpr static bool check(char const (&)[S1], char const (&)[S2]) noexcept
0057         {
0058             return false;
0059         }
0060     };
0061     template <int S1, int S2, int I>
0062     struct cpp11_prefix<S1, S2, I, true>
0063     {
0064         BOOST_LEAF_ALWAYS_INLINE constexpr static bool check(char const (&str)[S1], char const (&prefix)[S2]) noexcept
0065         {
0066             return str[I] == prefix[I] && cpp11_prefix<S1, S2, I - 1>::check(str, prefix);
0067         }
0068     };
0069     template <int S1, int S2>
0070     struct cpp11_prefix<S1, S2, 0, true>
0071     {
0072         BOOST_LEAF_ALWAYS_INLINE constexpr static bool check(char const (&str)[S1], char const (&prefix)[S2]) noexcept
0073         {
0074             return str[0] == prefix[0];
0075         }
0076     };
0077     template <int S1, int S2>
0078     BOOST_LEAF_ALWAYS_INLINE constexpr int check_prefix(char const (&str)[S1], char const (&prefix)[S2]) noexcept
0079     {
0080         return cpp11_prefix<S1, S2, S2 - 2>::check(str, prefix) ? S2 - 1 : 0;
0081     }
0082 
0083     ////////////////////////////////////////
0084 
0085     template <int S1, int S2, int I1, int I2, bool = S1 >= S2>
0086     struct cpp11_suffix
0087     {
0088         BOOST_LEAF_ALWAYS_INLINE constexpr static bool check(char const (&)[S1], char const (&)[S2]) noexcept
0089         {
0090             return false;
0091         }
0092     };
0093     template <int S1, int S2, int I1, int I2>
0094     struct cpp11_suffix<S1, S2, I1, I2, true>
0095     {
0096         BOOST_LEAF_ALWAYS_INLINE constexpr static bool check(char const (&str)[S1], char const (&suffix)[S2]) noexcept
0097         {
0098             return str[I1] == suffix[I2] && cpp11_suffix<S1, S2, I1 - 1, I2 - 1>::check(str, suffix);
0099         }
0100     };
0101     template <int S1, int S2, int I1>
0102     struct cpp11_suffix<S1, S2, I1, 0, true>
0103     {
0104         BOOST_LEAF_ALWAYS_INLINE constexpr static bool check(char const (&str)[S1], char const (&suffix)[S2]) noexcept
0105         {
0106             return str[I1] == suffix[0];
0107         }
0108     };
0109     template <int S1, int S2>
0110     BOOST_LEAF_ALWAYS_INLINE constexpr int check_suffix(char const (&str)[S1], char const (&suffix)[S2]) noexcept
0111     {
0112         return cpp11_suffix<S1, S2, S1 - 2, S2 - 2>::check(str, suffix) ? S1 - S2 : 0;
0113     }
0114 }
0115 
0116 namespace n
0117 {
0118     struct r
0119     {
0120         char const * name;
0121         int len;
0122         r(char const * name, int len) noexcept:
0123             name(name),
0124             len(len)
0125         {
0126         }
0127         template <class CharT, class Traits>
0128         friend std::ostream & operator<<(std::basic_ostream<CharT, Traits> & os, r const & pn)
0129         {
0130             return os.write(pn.name, pn.len);
0131         }
0132     };
0133 
0134     template <class T>
0135     BOOST_LEAF_ALWAYS_INLINE r p()
0136     {
0137         // C++11 compile-time parsing of __PRETTY_FUNCTION__/__FUNCSIG__. The sizeof hacks are a
0138         // workaround for older GCC versions, where __PRETTY_FUNCTION__ is not constexpr, which triggers
0139         // compile errors when used in constexpr expressinos, yet evaluating a sizeof exrpession works.
0140 
0141         // We don't try to recognize the compiler based on compiler-specific macros. Any compiler/version
0142         // is supported as long as it uses one of the formats we recognize.
0143 
0144         // Unrecognized __PRETTY_FUNCTION__/__FUNCSIG__ formats will result in compiler diagnostics.
0145         // In that case, please file an issue on https://github.com/boostorg/leaf.
0146 
0147 #define BOOST_LEAF_P(P) (sizeof(char[1 + detail::check_prefix(BOOST_LEAF_PRETTY_FUNCTION, P)]) - 1)
0148         // clang style:
0149         int const p01 = BOOST_LEAF_P("r boost::leaf::n::p() [T = ");
0150         int const p02 = BOOST_LEAF_P("r __cdecl boost::leaf::n::p(void) [T = ");
0151         int const p03 = BOOST_LEAF_P("r __stdcall boost::leaf::n::p(void) [T = ");
0152         int const p04 = BOOST_LEAF_P("r __fastcall boost::leaf::n::p(void) [T = ");
0153         // old clang style:
0154         int const p05 = BOOST_LEAF_P("boost::leaf::n::r boost::leaf::n::p() [T = ");
0155         int const p06 = BOOST_LEAF_P("boost::leaf::n::r __cdecl boost::leaf::n::p(void) [T = ");
0156         int const p07 = BOOST_LEAF_P("boost::leaf::n::r __stdcall boost::leaf::n::p(void) [T = ");
0157         int const p08 = BOOST_LEAF_P("boost::leaf::n::r __fastcall boost::leaf::n::p(void) [T = ");
0158         // gcc style:
0159         int const p09 = BOOST_LEAF_P("boost::leaf::n::r boost::leaf::n::p() [with T = ");
0160         int const p10 = BOOST_LEAF_P("boost::leaf::n::r __cdecl boost::leaf::n::p() [with T = ");
0161         int const p11 = BOOST_LEAF_P("boost::leaf::n::r __stdcall boost::leaf::n::p() [with T = ");
0162         int const p12 = BOOST_LEAF_P("boost::leaf::n::r __fastcall boost::leaf::n::p() [with T = ");
0163         // msvc style, struct:
0164         int const p13 = BOOST_LEAF_P("struct boost::leaf::n::r __cdecl boost::leaf::n::p<struct ");
0165         int const p14 = BOOST_LEAF_P("struct boost::leaf::n::r __stdcall boost::leaf::n::p<struct ");
0166         int const p15 = BOOST_LEAF_P("struct boost::leaf::n::r __fastcall boost::leaf::n::p<struct ");
0167         // msvc style, class:
0168         int const p16 = BOOST_LEAF_P("struct boost::leaf::n::r __cdecl boost::leaf::n::p<class ");
0169         int const p17 = BOOST_LEAF_P("struct boost::leaf::n::r __stdcall boost::leaf::n::p<class ");
0170         int const p18 = BOOST_LEAF_P("struct boost::leaf::n::r __fastcall boost::leaf::n::p<class ");
0171         // msvc style, enum:
0172         int const p19 = BOOST_LEAF_P("struct boost::leaf::n::r __cdecl boost::leaf::n::p<enum ");
0173         int const p20 = BOOST_LEAF_P("struct boost::leaf::n::r __stdcall boost::leaf::n::p<enum ");
0174         int const p21 = BOOST_LEAF_P("struct boost::leaf::n::r __fastcall boost::leaf::n::p<enum ");
0175         // msvc style, built-in type:
0176         int const p22 = BOOST_LEAF_P("struct boost::leaf::n::r __cdecl boost::leaf::n::p<");
0177         int const p23 = BOOST_LEAF_P("struct boost::leaf::n::r __stdcall boost::leaf::n::p<");
0178         int const p24 = BOOST_LEAF_P("struct boost::leaf::n::r __fastcall boost::leaf::n::p<");
0179 #undef BOOST_LEAF_P
0180 
0181 #define BOOST_LEAF_S(S) (sizeof(char[1 + detail::check_suffix(BOOST_LEAF_PRETTY_FUNCTION, S)]) - 1)
0182         // clang/gcc style:
0183         int const s01 = BOOST_LEAF_S("]");
0184         // msvc style:
0185         int const s02 = BOOST_LEAF_S(">(void)");
0186 #undef BOOST_LEAF_S
0187 
0188         char static_assert_unrecognized_pretty_function_format_please_file_github_issue[sizeof(
0189             char[
0190                 (s01 && (1 == (!!p01 + !!p02 + !!p03 + !!p04 + !!p05 + !!p06 + !!p07 + !!p08 + !!p09 + !!p10 + !!p11 + !!p12)))
0191                 ||
0192                 (s02 && (1 == (!!p13 + !!p14 + !!p15 + !!p16 + !!p17 + !!p18 + !!p19 + !!p20 + !!p21)))
0193                 ||
0194                 (s02 && (1 == (!!p22 + !!p23 + !!p24)))
0195             ]
0196         ) * 2 - 1];
0197         (void) static_assert_unrecognized_pretty_function_format_please_file_github_issue;
0198 
0199         if( int const p = sizeof(char[1 + !!s01 * (p01 + p02 + p03 + p04 + p05 + p06 + p07 + p08 + p09 + p10 + p11 + p12)]) - 1 )
0200             return { BOOST_LEAF_PRETTY_FUNCTION + p, s01 - p };
0201 
0202         if( int const p = sizeof(char[1 + !!s02 * (p13 + p14 + p15 + p16 + p17 + p18 + p19 + p20 + p21)]) - 1 )
0203             return { BOOST_LEAF_PRETTY_FUNCTION + p, s02 - p };
0204 
0205         int const p = sizeof(char[1 + !!s02 * (p22 + p23 + p24)]) - 1; // p is not zero, we've static asserted the hell out of it
0206         return { BOOST_LEAF_PRETTY_FUNCTION + p, s02 - p };
0207     }
0208 }
0209 
0210 using parsed = n::r;
0211 
0212 template <class T>
0213 parsed parse()
0214 {
0215     return n::p<T>();
0216 }
0217 
0218 } }
0219 
0220 ////////////////////////////////////////
0221 
0222 namespace boost { namespace leaf {
0223 
0224 namespace detail
0225 {
0226     template <class CharT, class Traits>
0227     std::ostream & demangle_and_print(std::basic_ostream<CharT, Traits> & os, char const * mangled_name)
0228     {
0229         BOOST_LEAF_ASSERT(mangled_name);
0230 #if defined(BOOST_LEAF_CFG_DIAGNOSTICS) && defined(BOOST_LEAF_HAS_CXXABI_H)
0231         struct raii
0232         {
0233             char * demangled_name;
0234             raii(char const * mangled_name) noexcept 
0235             {
0236                 int status = 0;
0237                 demangled_name = abi::__cxa_demangle(mangled_name, nullptr, nullptr, &status);
0238             }
0239             ~raii() noexcept
0240             {
0241                 std::free(demangled_name);
0242             }
0243         } d(mangled_name);
0244         if( d.demangled_name )
0245             return os << d.demangled_name;
0246 #endif
0247         return os << mangled_name;
0248     }
0249 }
0250 
0251 } }
0252 
0253 #endif // BOOST_LEAF_DETAIL_DEMANGLE_HPP_INCLUDED