Brian Silverman | 407d3cd | 2018-08-04 17:48:52 -0700 | [diff] [blame^] | 1 | [/ |
| 2 | Copyright 2014 Peter Dimov |
| 3 | Copyright 2014 Andrey Semashev |
| 4 | |
| 5 | Distributed under the Boost Software License, Version 1.0. |
| 6 | |
| 7 | See accompanying file LICENSE_1_0.txt |
| 8 | or copy at http://boost.org/LICENSE_1_0.txt |
| 9 | ] |
| 10 | |
| 11 | [section:demangle demangle] |
| 12 | |
| 13 | [simplesect Authors] |
| 14 | |
| 15 | * Peter Dimov |
| 16 | * Andrey Semashev |
| 17 | |
| 18 | [endsimplesect] |
| 19 | |
| 20 | [section Header <boost/core/demangle.hpp>] |
| 21 | |
| 22 | The header `<boost/core/demangle.hpp>` defines several tools for undecorating |
| 23 | symbol names. |
| 24 | |
| 25 | [section Synopsis] |
| 26 | |
| 27 | namespace boost |
| 28 | { |
| 29 | |
| 30 | namespace core |
| 31 | { |
| 32 | std::string demangle( char const * name ); |
| 33 | |
| 34 | char const * demangle_alloc( char const * name ) noexcept; |
| 35 | void demangle_free( char const * demangled_name ) noexcept; |
| 36 | |
| 37 | class scoped_demangled_name |
| 38 | { |
| 39 | public: |
| 40 | explicit scoped_demangled_name( char const * name ) noexcept; |
| 41 | ~scoped_demangled_name() noexcept; |
| 42 | char const * get() const noexcept; |
| 43 | |
| 44 | scoped_demangled_name( scoped_demangled_name const& ) = delete; |
| 45 | scoped_demangled_name& operator= ( scoped_demangled_name const& ) = delete; |
| 46 | }; |
| 47 | } |
| 48 | |
| 49 | } |
| 50 | |
| 51 | [endsect] |
| 52 | |
| 53 | [section Conventional interface] |
| 54 | |
| 55 | The function `boost::core::demangle` is the conventional |
| 56 | way to obtain demangled symbol name. It takes a mangled string such as |
| 57 | those returned by `typeid(T).name()` on certain implementations |
| 58 | such as `g++`, and returns its demangled, human-readable, form. In case if |
| 59 | demangling fails (e.g. if `name` cannot be interpreted as a mangled name) |
| 60 | the function returns `name`. |
| 61 | |
| 62 | [section Example] |
| 63 | |
| 64 | #include <boost/core/demangle.hpp> |
| 65 | #include <typeinfo> |
| 66 | #include <iostream> |
| 67 | |
| 68 | template<class T> struct X |
| 69 | { |
| 70 | }; |
| 71 | |
| 72 | int main() |
| 73 | { |
| 74 | char const * name = typeid( X<int> ).name(); |
| 75 | |
| 76 | std::cout << name << std::endl; // prints 1XIiE |
| 77 | std::cout << boost::core::demangle( name ) << std::endl; // prints X<int> |
| 78 | } |
| 79 | |
| 80 | [endsect] |
| 81 | |
| 82 | [endsect] |
| 83 | |
| 84 | [section Low level interface] |
| 85 | |
| 86 | In some cases more low level interface may be desirable. For example: |
| 87 | |
| 88 | * Assuming that symbol demangling may fail, the user wants to be able to handle such errors. |
| 89 | * The user needs to post-process the demangled name (e.g. remove common namespaces), and |
| 90 | allocating a temporary string with the complete demangled name is significant overhead. |
| 91 | |
| 92 | The function `boost::core::demangle_alloc` performs name demangling and returns a pointer |
| 93 | to a string with the demangled name, if succeeded, or `nullptr` otherwise. The returned pointer |
| 94 | must be passed to `boost::core::demangle_free` to reclaim resources. Note that on some platforms |
| 95 | the pointer returned by `boost::core::demangle_alloc` may refer to the string denoted by `name`, |
| 96 | so this string must be kept immutable for the whole life time of the returned pointer. |
| 97 | |
| 98 | The `boost::core::scoped_demangled_name` class is a scope guard that automates the calls to |
| 99 | `boost::core::demangle_alloc` (on its construction) and `boost::core::demangle_free` (on destruction). |
| 100 | The string with the demangled name can be obtained with its `get` method. Note that this method may |
| 101 | return `nullptr` if demangling failed. |
| 102 | |
| 103 | [section Example] |
| 104 | |
| 105 | #include <boost/core/demangle.hpp> |
| 106 | #include <typeinfo> |
| 107 | #include <iostream> |
| 108 | |
| 109 | template<class T> struct X |
| 110 | { |
| 111 | }; |
| 112 | |
| 113 | int main() |
| 114 | { |
| 115 | char const * name = typeid( X<int> ).name(); |
| 116 | boost::core::scoped_demangled_name demangled( name ); |
| 117 | |
| 118 | std::cout << name << std::endl; // prints 1XIiE |
| 119 | std::cout << (demangled.get() ? demangled.get() : "[unknown]") << std::endl; // prints X<int> |
| 120 | } |
| 121 | |
| 122 | [endsect] |
| 123 | |
| 124 | [endsect] |
| 125 | |
| 126 | [endsect] |
| 127 | |
| 128 | [section Acknowledgments] |
| 129 | |
| 130 | The implementation of `core::demangle` was taken from |
| 131 | `boost/exception/detail/type_info.hpp`, which in turn was adapted |
| 132 | from `boost/units/detail/utility.hpp` and `boost/log/utility/type_info_wrapper.hpp`. |
| 133 | |
| 134 | [endsect] |
| 135 | |
| 136 | [endsect] |