1 // C++ IA64 / g++ v3 demangler -*- C++ -*-
3 // Copyright (C) 2003 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.
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,
109 using namespace __gnu_cxx;
110 typedef demangler::session<std::allocator<char> > session_type;
112 if (!mangled_name || (buf && !n))
113 return failure(invalid_argument, status);
116 if (mangled_name[0] == '_')
119 if (mangled_name[1] == 'Z')
122 int cnt = session_type::
123 decode_encoding(result, mangled_name + 2, INT_MAX);
124 if (cnt < 0 || mangled_name[cnt + 2] != 0)
125 return failure(invalid_mangled_name, status);
126 return finish(result.data(), result.size(), buf, n, status);
128 else if (mangled_name[1] == 'G')
130 // Possible _GLOBAL__ extension?
131 if (!std::strncmp(mangled_name, "_GLOBAL__", 9)
132 && (mangled_name[9] == 'D' || mangled_name[9] == 'I')
133 && mangled_name[10] == '_' && mangled_name[11] == '_'
134 && mangled_name[12] == 'Z')
136 if (mangled_name[9] == 'D')
137 result.assign("global destructors keyed to ", 28);
139 result.assign("global constructors keyed to ", 29);
140 int cnt = session_type::
141 decode_encoding(result, mangled_name + 13, INT_MAX);
142 if (cnt < 0 || mangled_name[cnt + 13] != 0)
143 return failure(invalid_mangled_name, status);
144 return finish(result.data(), result.size(), buf, n, status);
149 // Ambiguities are possible between extern "C" object names and
150 // internal built-in type names, e.g. "i" may be either an object
151 // named "i" or the built-in "int" type. Such ambiguities should
152 // be resolved to user names over built-in names. Builtin types
153 // are any single lower case character. Any other single
154 // character is not a mangled type so we can treat those the same
156 if (mangled_name[1] == 0)
157 return finish(mangled_name, 1, buf, n, status);
159 // Not a built-in type or external name, try to demangle input as
160 // NTBS mangled type name.
161 session_type demangler_session(mangled_name, INT_MAX);
162 if (!demangler_session.decode_type(result)
163 || demangler_session.remaining_input_characters())
165 // Failure to demangle, assume extern "C" name.
166 result = mangled_name;
168 return finish(result.data(), result.size(), buf, n, status);
170 } // namespace __cxxabiv1