/* Demangler for IA64 / g++ V3 ABI.
- Copyright (C) 2000, 2001 Free Software Foundation, Inc.
+ Copyright (C) 2000, 2001, 2002 Free Software Foundation, Inc.
Written by Alex Samuel <samuel@codesourcery.com>.
This file is part of GNU CC.
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
+ In addition to the permissions in the GNU General Public License, the
+ Free Software Foundation gives you unlimited permission to link the
+ compiled version of this file into combinations with other programs,
+ and to distribute those combinations without any restriction coming
+ from the use of this file. (The General Public License restrictions
+ do apply in other respects; for example, they cover modification of
+ the file, and distribution when not linked into a combined
+ executable.)
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
static status_t demangle_identifier
PARAMS ((demangling_t, int, dyn_string_t));
static status_t demangle_operator_name
- PARAMS ((demangling_t, int, int *));
+ PARAMS ((demangling_t, int, int *, int *));
static status_t demangle_nv_offset
PARAMS ((demangling_t));
static status_t demangle_v_offset
if (peek == 'c' && peek_char_next (dm) == 'v')
*suppress_return_type = 1;
- RETURN_IF_ERROR (demangle_operator_name (dm, 0, &num_args));
+ RETURN_IF_ERROR (demangle_operator_name (dm, 0, &num_args, NULL));
}
else if (peek == 'C' || peek == 'D')
{
/* Demangles and emits an <operator-name>. If SHORT_NAME is non-zero,
the short form is emitted; otherwise the full source form
(`operator +' etc.) is emitted. *NUM_ARGS is set to the number of
- operands that the operator takes.
+ operands that the operator takes. If TYPE_ARG is non-NULL,
+ *TYPE_ARG is set to 1 if the first argument is a type and 0
+ otherwise.
<operator-name>
::= nw # new
::= cl # ()
::= ix # []
::= qu # ?
- ::= sz # sizeof
+ ::= st # sizeof (a type)
+ ::= sz # sizeof (an expression)
::= cv <type> # cast
::= v [0-9] <source-name> # vendor extended operator */
static status_t
-demangle_operator_name (dm, short_name, num_args)
+demangle_operator_name (dm, short_name, num_args, type_arg)
demangling_t dm;
int short_name;
int *num_args;
+ int *type_arg;
{
struct operator_code
{
DEMANGLE_TRACE ("operator-name", dm);
+ /* Assume the first argument is not a type. */
+ if (type_arg)
+ *type_arg = 0;
+
/* Is this a vendor-extended operator? */
if (c0 == 'v' && IS_DIGIT (c1))
{
return STATUS_OK;
}
+ /* Is it the sizeof variant that takes a type? */
+ if (c0 == 's' && c1 == 't')
+ {
+ RETURN_IF_ERROR (result_add (dm, " sizeof"));
+ *num_args = 1;
+ if (type_arg)
+ *type_arg = 1;
+ return STATUS_OK;
+ }
+
/* Perform a binary search for the operator code. */
while (1)
{
/* An operator expression. */
{
int num_args;
+ int type_arg;
status_t status = STATUS_OK;
dyn_string_t operator_name;
operations in infix notation, capture the operator name
first. */
RETURN_IF_ERROR (result_push (dm));
- RETURN_IF_ERROR (demangle_operator_name (dm, 1, &num_args));
+ RETURN_IF_ERROR (demangle_operator_name (dm, 1, &num_args,
+ &type_arg));
operator_name = (dyn_string_t) result_pop (dm);
/* If it's binary, do an operand first. */
/* Emit its second (if binary) or only (if unary) operand. */
RETURN_IF_ERROR (result_add_char (dm, '('));
- RETURN_IF_ERROR (demangle_expression (dm));
+ if (type_arg)
+ RETURN_IF_ERROR (demangle_type (dm));
+ else
+ RETURN_IF_ERROR (demangle_expression (dm));
RETURN_IF_ERROR (result_add_char (dm, ')'));
/* The ternary operator takes a third operand. */
dyn_string_t result;
{
status_t status;
- demangling_t dm = demangling_new (type_name, 0);
+ demangling_t dm = demangling_new (type_name, DMGL_GNU_V3);
if (dm == NULL)
return STATUS_ALLOCATION_FAILED;
return status;
}
-#ifdef IN_LIBGCC2
+#if defined(IN_LIBGCC2) || defined(IN_GLIBCPP_V3)
extern char *__cxa_demangle PARAMS ((const char *, char *, size_t *, int *));
/* ia64 ABI-mandated entry point in the C++ runtime library for performing
}
}
-#else /* !IN_LIBGCC2 */
+#else /* ! (IN_LIBGCC2 || IN_GLIBCPP_V3) */
/* Variant entry point for integration with the existing cplus-dem
demangler. Attempts to demangle MANGLED. If the demangling
If the demangling failes, returns NULL. */
char *
-cplus_demangle_v3 (mangled)
+cplus_demangle_v3 (mangled, options)
const char* mangled;
+ int options;
{
dyn_string_t demangled;
status_t status;
+ int type = !!(options & DMGL_TYPES);
+
+ if (mangled[0] == '_' && mangled[1] == 'Z')
+ /* It is not a type. */
+ type = 0;
+ else
+ {
+ /* It is a type. Stop if we don't want to demangle types. */
+ if (!type)
+ return NULL;
+ }
+
+ flag_verbose = !!(options & DMGL_VERBOSE);
/* Create a dyn_string to hold the demangled name. */
demangled = dyn_string_new (0);
/* Attempt the demangling. */
- if (mangled[0] == '_' && mangled[1] == 'Z')
+ if (!type)
/* Appears to be a function or variable name. */
status = cp_demangle (mangled, demangled, 0);
else
free (cplus_demangled);
- return_value = dyn_string_release (demangled);
+ if (demangled)
+ return_value = dyn_string_release (demangled);
+ else
+ return_value = NULL;
+
return return_value;
}
-#endif /* IN_LIBGCC2 */
+#endif /* IN_LIBGCC2 || IN_GLIBCPP_V3 */
+#ifndef IN_GLIBCPP_V3
/* Demangle NAME in the G++ V3 ABI demangling style, and return either
zero, indicating that some error occurred, or a demangling_t
holding the results. */
else
return 0;
}
+#endif /* IN_GLIBCPP_V3 */
#ifdef STANDALONE_DEMANGLER