1 #ifndef BOOST_CORE_DEMANGLE_HPP_INCLUDED
2 #define BOOST_CORE_DEMANGLE_HPP_INCLUDED
3 
4 // core::demangle
5 //
6 // Copyright 2014 Peter Dimov
7 // Copyright 2014 Andrey Semashev
8 //
9 // Distributed under the Boost Software License, Version 1.0.
10 // See accompanying file LICENSE_1_0.txt or copy at
11 // http://www.boost.org/LICENSE_1_0.txt
12 
13 #include <boost/config.hpp>
14 #include <string>
15 
16 #if defined(BOOST_HAS_PRAGMA_ONCE)
17 # pragma once
18 #endif
19 
20 #if defined( __clang__ ) && defined( __has_include )
21 # if __has_include(<cxxabi.h>)
22 #  define BOOST_CORE_HAS_CXXABI_H
23 # endif
24 #elif defined( __GLIBCXX__ ) || defined( __GLIBCPP__ )
25 # define BOOST_CORE_HAS_CXXABI_H
26 #endif
27 
28 #if defined( BOOST_CORE_HAS_CXXABI_H )
29 # include <cxxabi.h>
30 # include <cstdlib>
31 # include <cstddef>
32 #endif
33 
34 namespace boost
35 {
36 
37 namespace core
38 {
39 
40 inline char const * demangle_alloc( char const * name ) BOOST_NOEXCEPT;
41 inline void demangle_free( char const * name ) BOOST_NOEXCEPT;
42 
43 class scoped_demangled_name
44 {
45 private:
46     char const * m_p;
47 
48 public:
scoped_demangled_name(char const * name)49     explicit scoped_demangled_name( char const * name ) BOOST_NOEXCEPT :
50         m_p( demangle_alloc( name ) )
51     {
52     }
53 
~scoped_demangled_name()54     ~scoped_demangled_name() BOOST_NOEXCEPT
55     {
56         demangle_free( m_p );
57     }
58 
get() const59     char const * get() const BOOST_NOEXCEPT
60     {
61         return m_p;
62     }
63 
64     BOOST_DELETED_FUNCTION(scoped_demangled_name( scoped_demangled_name const& ))
65     BOOST_DELETED_FUNCTION(scoped_demangled_name& operator= ( scoped_demangled_name const& ))
66 };
67 
68 
69 #if defined( BOOST_CORE_HAS_CXXABI_H )
70 
demangle_alloc(char const * name)71 inline char const * demangle_alloc( char const * name ) BOOST_NOEXCEPT
72 {
73     int status = 0;
74     std::size_t size = 0;
75     return abi::__cxa_demangle( name, NULL, &size, &status );
76 }
77 
demangle_free(char const * name)78 inline void demangle_free( char const * name ) BOOST_NOEXCEPT
79 {
80     std::free( const_cast< char* >( name ) );
81 }
82 
demangle(char const * name)83 inline std::string demangle( char const * name )
84 {
85     scoped_demangled_name demangled_name( name );
86     char const * const p = demangled_name.get();
87     if( p )
88     {
89         return p;
90     }
91     else
92     {
93         return name;
94     }
95 }
96 
97 #else
98 
demangle_alloc(char const * name)99 inline char const * demangle_alloc( char const * name ) BOOST_NOEXCEPT
100 {
101     return name;
102 }
103 
demangle_free(char const *)104 inline void demangle_free( char const * ) BOOST_NOEXCEPT
105 {
106 }
107 
demangle(char const * name)108 inline std::string demangle( char const * name )
109 {
110     return name;
111 }
112 
113 #endif
114 
115 } // namespace core
116 
117 } // namespace boost
118 
119 #undef BOOST_CORE_HAS_CXXABI_H
120 
121 #endif // #ifndef BOOST_CORE_DEMANGLE_HPP_INCLUDED
122