demangle.hpp 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126
  1. #ifndef BOOST_CORE_DEMANGLE_HPP_INCLUDED
  2. #define BOOST_CORE_DEMANGLE_HPP_INCLUDED
  3. // core::demangle
  4. //
  5. // Copyright 2014 Peter Dimov
  6. // Copyright 2014 Andrey Semashev
  7. //
  8. // Distributed under the Boost Software License, Version 1.0.
  9. // See accompanying file LICENSE_1_0.txt or copy at
  10. // http://www.boost.org/LICENSE_1_0.txt
  11. #include <boost/config.hpp>
  12. #include <string>
  13. #if defined(BOOST_HAS_PRAGMA_ONCE)
  14. # pragma once
  15. #endif
  16. // __has_include is currently supported by GCC and Clang. However GCC 4.9 may have issues and
  17. // returns 1 for 'defined( __has_include )', while '__has_include' is actually not supported:
  18. // https://gcc.gnu.org/bugzilla/show_bug.cgi?id=63662
  19. #if defined( __has_include ) && (!defined( BOOST_GCC ) || (__GNUC__ + 0) >= 5)
  20. # if __has_include(<cxxabi.h>)
  21. # define BOOST_CORE_HAS_CXXABI_H
  22. # endif
  23. #elif defined( __GLIBCXX__ ) || defined( __GLIBCPP__ )
  24. # define BOOST_CORE_HAS_CXXABI_H
  25. #endif
  26. #if defined( BOOST_CORE_HAS_CXXABI_H )
  27. # include <cxxabi.h>
  28. // For some archtectures (mips, mips64, x86, x86_64) cxxabi.h in Android NDK is implemented by gabi++ library
  29. // (https://android.googlesource.com/platform/ndk/+/master/sources/cxx-stl/gabi++/), which does not implement
  30. // abi::__cxa_demangle(). We detect this implementation by checking the include guard here.
  31. # if defined( __GABIXX_CXXABI_H__ )
  32. # undef BOOST_CORE_HAS_CXXABI_H
  33. # else
  34. # include <cstdlib>
  35. # include <cstddef>
  36. # endif
  37. #endif
  38. namespace boost
  39. {
  40. namespace core
  41. {
  42. inline char const * demangle_alloc( char const * name ) BOOST_NOEXCEPT;
  43. inline void demangle_free( char const * name ) BOOST_NOEXCEPT;
  44. class scoped_demangled_name
  45. {
  46. private:
  47. char const * m_p;
  48. public:
  49. explicit scoped_demangled_name( char const * name ) BOOST_NOEXCEPT :
  50. m_p( demangle_alloc( name ) )
  51. {
  52. }
  53. ~scoped_demangled_name() BOOST_NOEXCEPT
  54. {
  55. demangle_free( m_p );
  56. }
  57. char const * get() const BOOST_NOEXCEPT
  58. {
  59. return m_p;
  60. }
  61. BOOST_DELETED_FUNCTION(scoped_demangled_name( scoped_demangled_name const& ))
  62. BOOST_DELETED_FUNCTION(scoped_demangled_name& operator= ( scoped_demangled_name const& ))
  63. };
  64. #if defined( BOOST_CORE_HAS_CXXABI_H )
  65. inline char const * demangle_alloc( char const * name ) BOOST_NOEXCEPT
  66. {
  67. int status = 0;
  68. std::size_t size = 0;
  69. return abi::__cxa_demangle( name, NULL, &size, &status );
  70. }
  71. inline void demangle_free( char const * name ) BOOST_NOEXCEPT
  72. {
  73. std::free( const_cast< char* >( name ) );
  74. }
  75. inline std::string demangle( char const * name )
  76. {
  77. scoped_demangled_name demangled_name( name );
  78. char const * p = demangled_name.get();
  79. if( !p )
  80. p = name;
  81. return p;
  82. }
  83. #else
  84. inline char const * demangle_alloc( char const * name ) BOOST_NOEXCEPT
  85. {
  86. return name;
  87. }
  88. inline void demangle_free( char const * ) BOOST_NOEXCEPT
  89. {
  90. }
  91. inline std::string demangle( char const * name )
  92. {
  93. return name;
  94. }
  95. #endif
  96. } // namespace core
  97. } // namespace boost
  98. #undef BOOST_CORE_HAS_CXXABI_H
  99. #endif // #ifndef BOOST_CORE_DEMANGLE_HPP_INCLUDED