// Copyright (c) 2014-2021 Dr. Colin Hirsch and Daniel Frey // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt) #ifndef TAO_PEGTL_DEMANGLE_HPP #define TAO_PEGTL_DEMANGLE_HPP #include #include #include "config.hpp" namespace TAO_PEGTL_NAMESPACE { #if defined( __clang__ ) #if defined( _LIBCPP_VERSION ) template< typename T > [[nodiscard]] constexpr std::string_view demangle() noexcept { constexpr std::string_view sv = __PRETTY_FUNCTION__; constexpr auto begin = sv.find( '=' ); static_assert( begin != std::string_view::npos ); return sv.substr( begin + 2, sv.size() - begin - 3 ); } #else // When using libstdc++ with clang, std::string_view::find is not constexpr :( template< char C > constexpr const char* find( const char* p, std::size_t n ) noexcept { while( n ) { if( *p == C ) { return p; } ++p; --n; } return nullptr; } template< typename T > [[nodiscard]] constexpr std::string_view demangle() noexcept { constexpr std::string_view sv = __PRETTY_FUNCTION__; constexpr auto begin = find< '=' >( sv.data(), sv.size() ); static_assert( begin != nullptr ); return { begin + 2, sv.data() + sv.size() - begin - 3 }; } #endif #elif defined( __GNUC__ ) #if( __GNUC__ == 7 ) // GCC 7 wrongly sometimes disallows __PRETTY_FUNCTION__ in constexpr functions, // therefore we drop the 'constexpr' and hope for the best. template< typename T > [[nodiscard]] std::string_view demangle() noexcept { const std::string_view sv = __PRETTY_FUNCTION__; const auto begin = sv.find( '=' ); const auto tmp = sv.substr( begin + 2 ); const auto end = tmp.rfind( ';' ); return tmp.substr( 0, end ); } #elif( __GNUC__ == 9 ) && ( __GNUC_MINOR__ < 3 ) // GCC 9.1 and 9.2 have a bug that leads to truncated __PRETTY_FUNCTION__ names, // see https://gcc.gnu.org/bugzilla/show_bug.cgi?id=91155 template< typename T > [[nodiscard]] constexpr std::string_view demangle() noexcept { // fallback: requires RTTI, no demangling return typeid( T ).name(); } #else template< typename T > [[nodiscard]] constexpr std::string_view demangle() noexcept { constexpr std::string_view sv = __PRETTY_FUNCTION__; constexpr auto begin = sv.find( '=' ); static_assert( begin != std::string_view::npos ); constexpr auto tmp = sv.substr( begin + 2 ); constexpr auto end = tmp.rfind( ';' ); static_assert( end != std::string_view::npos ); return tmp.substr( 0, end ); } #endif #elif defined( _MSC_VER ) #if( _MSC_VER < 1920 ) template< typename T > [[nodiscard]] constexpr std::string_view demangle() noexcept { const std::string_view sv = __FUNCSIG__; const auto begin = sv.find( "demangle<" ); const auto tmp = sv.substr( begin + 9 ); const auto end = tmp.rfind( '>' ); return tmp.substr( 0, end ); } #else template< typename T > [[nodiscard]] constexpr std::string_view demangle() noexcept { constexpr std::string_view sv = __FUNCSIG__; constexpr auto begin = sv.find( "demangle<" ); static_assert( begin != std::string_view::npos ); constexpr auto tmp = sv.substr( begin + 9 ); constexpr auto end = tmp.rfind( '>' ); static_assert( end != std::string_view::npos ); return tmp.substr( 0, end ); } #endif #else template< typename T > [[nodiscard]] constexpr std::string_view demangle() noexcept { // fallback: requires RTTI, no demangling return typeid( T ).name(); } #endif } // namespace TAO_PEGTL_NAMESPACE #endif