1 // Copyright David Abrahams 2001.
2 // Distributed under the Boost Software License, Version 1.0. (See
3 // accompanying file LICENSE_1_0.txt or copy at
4 // http://www.boost.org/LICENSE_1_0.txt)
6 #include <boost/python/type_id.hpp>
7 #include <boost/python/detail/decorated_type_id.hpp>
15 #if defined(__QNXNTO__)
17 #else /* defined(__QNXNTO__) */
19 #if !defined(__GNUC__) || __GNUC__ >= 3 || __SGI_STL_PORT || __EDG_VERSION__
25 # ifdef BOOST_PYTHON_HAVE_GCC_CP_DEMANGLE
26 # if defined(__GNUC__) && __GNUC__ >= 3
28 // http://lists.debian.org/debian-gcc/2003/09/msg00055.html notes
29 // that, in cxxabi.h of gcc-3.x for x < 4, this type is used before it
31 # if __GNUC__ == 3 && __GNUC_MINOR__ < 4
32 class __class_type_info
;
38 #endif /* defined(__QNXNTO__) */
40 namespace boost
{ namespace python
{
42 # ifdef BOOST_PYTHON_HAVE_GCC_CP_DEMANGLE
44 # if defined(__QNXNTO__)
46 extern "C" char* __cxa_demangle(char const*, char*, std::size_t*, int*);
48 # else /* defined(__QNXNTO__) */
53 namespace cxxabi
= :: ;
54 extern "C" char* __cxa_demangle(char const*, char*, std::size_t*, int*);
57 namespace cxxabi
= ::abi
; // GCC 3.1 and later
59 # if __GNUC__ == 3 && __GNUC_MINOR__ == 0
62 extern "C" char* __cxa_demangle(char const*, char*, std::size_t*, int*);
64 # endif /* __GNUC__ == 3 && __GNUC_MINOR__ == 0 */
65 # endif /* __GNUC__ < 3 */
66 # endif /* __GNUC__ */
67 # endif /* defined(__QNXNTO__) */
71 struct compare_first_cstring
74 bool operator()(T
const& x
, T
const& y
)
76 return std::strcmp(x
.first
,y
.first
) < 0;
93 bool cxxabi_cxa_demangle_is_broken()
95 static bool was_tested
= false;
96 static bool is_broken
= false;
99 free_mem
keeper(cxxabi::__cxa_demangle("b", 0, 0, &status
));
101 if (status
== -2 || strcmp(keeper
.p
, "bool") != 0) {
110 BOOST_PYTHON_DECL
char const* gcc_demangle(char const* mangled
)
113 std::pair
<char const*, char const*>
116 static mangling_map demangler
;
117 mangling_map::iterator p
119 demangler
.begin(), demangler
.end()
120 , std::make_pair(mangled
, (char const*)0)
121 , compare_first_cstring());
123 if (p
== demangler
.end() || strcmp(p
->first
, mangled
))
127 cxxabi::__cxa_demangle(mangled
, 0, 0, &status
)
130 assert(status
!= -3); // invalid argument error
134 throw std::bad_alloc();
138 char const* demangled
140 // Invalid mangled name. Best we can do is to
145 // Ult Mundane, 2005 Aug 17
146 // Contributed under the Boost Software License, Version 1.0.
147 // (See accompanying file LICENSE_1_0.txt or copy at
148 // http://www.boost.org/LICENSE_1_0.txt)
149 // The __cxa_demangle function is supposed to translate
150 // builtin types from their one-character mangled names,
151 // but it doesn't in gcc 3.3.5 and gcc 3.4.x.
152 if (cxxabi_cxa_demangle_is_broken()
153 && status
== -2 && strlen(mangled
) == 1)
156 // http://www.codesourcery.com/cxx-abi/abi.html
159 case 'v': demangled
= "void"; break;
160 case 'w': demangled
= "wchar_t"; break;
161 case 'b': demangled
= "bool"; break;
162 case 'c': demangled
= "char"; break;
163 case 'a': demangled
= "signed char"; break;
164 case 'h': demangled
= "unsigned char"; break;
165 case 's': demangled
= "short"; break;
166 case 't': demangled
= "unsigned short"; break;
167 case 'i': demangled
= "int"; break;
168 case 'j': demangled
= "unsigned int"; break;
169 case 'l': demangled
= "long"; break;
170 case 'm': demangled
= "unsigned long"; break;
171 case 'x': demangled
= "long long"; break;
172 case 'y': demangled
= "unsigned long long"; break;
173 case 'n': demangled
= "__int128"; break;
174 case 'o': demangled
= "unsigned __int128"; break;
175 case 'f': demangled
= "float"; break;
176 case 'd': demangled
= "double"; break;
177 case 'e': demangled
= "long double"; break;
178 case 'g': demangled
= "__float128"; break;
179 case 'z': demangled
= "..."; break;
183 p
= demangler
.insert(p
, std::make_pair(mangled
, demangled
));
193 BOOST_PYTHON_DECL
std::ostream
& operator<<(std::ostream
& os
, type_info
const& x
)
195 return os
<< x
.name();
200 BOOST_PYTHON_DECL
std::ostream
& operator<<(std::ostream
& os
, detail::decorated_type_info
const& x
)
203 if (x
.m_decoration
& decorated_type_info::const_
)
205 if (x
.m_decoration
& decorated_type_info::volatile_
)
207 if (x
.m_decoration
& decorated_type_info::reference
)
212 }} // namespace boost::python::converter