1 // C++ IA64 / g++ v3 demangler -*- C++ -*-
3 // Copyright (C) 2003, 2004 Free Software Foundation, Inc.
4 // Written by Carlo Wood <carlo@alinoe.com>
6 // This file is part of the GNU ISO C++ Library. This library is free
7 // software; you can redistribute it and/or modify it under the
8 // terms of the GNU General Public License as published by the
9 // Free Software Foundation; either version 2, or (at your option)
12 // This library is distributed in the hope that it will be useful,
13 // but WITHOUT ANY WARRANTY; without even the implied warranty of
14 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 // GNU General Public License for more details.
17 // You should have received a copy of the GNU General Public License along
18 // with this library; see the file COPYING. If not, write to the Free
19 // Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
22 // As a special exception, you may use this file as part of a free software
23 // library without restriction. Specifically, if other files instantiate
24 // templates or use macros or inline functions from this file, or you compile
25 // this file and link it with other files to produce an executable, this
26 // file does not by itself cause the resulting executable to be covered by
27 // the GNU General Public License. This exception does not however
28 // invalidate any other reasons why the executable file might be covered by
29 // the GNU General Public License.
31 #include <bits/demangle.h>
36 // Demangle a C++ symbol or type name.
38 // `mangled-name' is a pointer to a null-terminated array of characters.
39 // It may be either an external name, i.e. with a "_Z" prefix, or an
40 // internal NTBS mangling, e.g. of a type for type_info.
42 // `buf' may be null. If it is non-null, then n must also be non-null,
43 // and buf is a pointer to an array, of at least *n characters, that
44 // was allocated using malloc.
46 // `status' points to an int that is used as an error indicator. It is
47 // permitted to be null, in which case the user just doesn't get any
48 // detailed error information.
50 // Returns: a pointer to a null-terminated array of characters, the
51 // demangled name. Or NULL in case of failure.
53 // If there is an error in demangling, the return value is a null pointer.
54 // The user can examine *status to find out what kind of error occurred.
55 // Meaning of error indications:
58 // * -1: memory allocation failure
59 // * -2: invalid mangled name
60 // * -3: invalid arguments (e.g. buf nonnull and n null)
67 char* const error = 0;
72 memory_allocation_failure = -1,
73 invalid_mangled_name = -2,
78 failure(status_codes error_code, int* status)
86 finish(char const* demangled_name, size_t demangled_name_size,
87 char* buf, size_t* n, int* status)
89 if (!buf || *n < demangled_name_size + 1)
92 *n = demangled_name_size + 1;
93 buf = (char*)realloc(buf, demangled_name_size + 1);
95 return failure(memory_allocation_failure, status);
99 std::strncpy(buf, demangled_name, demangled_name_size);
100 buf[demangled_name_size] = 0;
106 __cxa_demangle(char const* mangled_name, char* buf, std::size_t* n,
110 using namespace __gnu_cxx;
111 typedef demangler::session<std::allocator<char> > session_type;
113 if (!mangled_name || (buf && !n))
114 return failure(invalid_argument, status);
117 if (mangled_name[0] == '_')
120 if (mangled_name[1] == 'Z')
123 int cnt = session_type::
124 decode_encoding(result, mangled_name + 2, INT_MAX);
125 if (cnt < 0 || mangled_name[cnt + 2] != 0)
126 return failure(invalid_mangled_name, status);
127 return finish(result.data(), result.size(), buf, n, status);
129 else if (mangled_name[1] == 'G')
131 // Possible _GLOBAL__ extension?
132 if (!std::strncmp(mangled_name, "_GLOBAL__", 9)
133 && (mangled_name[9] == 'D' || mangled_name[9] == 'I')
134 && mangled_name[10] == '_')
136 if (mangled_name[9] == 'D')
137 result.assign("global destructors keyed to ", 28);
139 result.assign("global constructors keyed to ", 29);
140 // Output the disambiguation part as-is.
141 result += mangled_name + 11;
142 return finish(result.data(), result.size(), buf, n, status);
147 // Ambiguities are possible between extern "C" object names and
148 // internal built-in type names, e.g. "i" may be either an object
149 // named "i" or the built-in "int" type. Such ambiguities should
150 // be resolved to user names over built-in names. Builtin types
151 // are any single lower case character. Any other single
152 // character is not a mangled type so we can treat those the same
154 if (mangled_name[1] == 0)
155 return finish(mangled_name, 1, buf, n, status);
157 // Not a built-in type or external name, try to demangle input as
158 // NTBS mangled type name.
159 session_type demangler_session(mangled_name, INT_MAX);
160 if (!demangler_session.decode_type(result)
161 || demangler_session.remaining_input_characters())
163 // Failure to demangle, assume extern "C" name.
164 result = mangled_name;
166 return finish(result.data(), result.size(), buf, n, status);
167 } catch (std::bad_alloc&) {
168 return failure(memory_allocation_failure, status);
171 } // namespace __cxxabiv1
173 // Explicit instantiations.
176 template class demangler::qualifier_list<std::allocator<char> >;
177 template class demangler::session<std::allocator<char> >;
178 } // namespace __gnu_cxx
183 void vector<int>::_M_insert_aux(vector<int>::iterator, const int&);
185 typedef __gnu_cxx::demangler::substitution_st value_type1;
187 void vector<value_type1>::_M_insert_aux(vector<value_type1>::iterator,
190 typedef __gnu_cxx::demangler::qualifier<std::allocator<char> > value_type2;
192 void vector<value_type2>::_M_insert_aux(vector<value_type2>::iterator,