summaryrefslogtreecommitdiffstats
path: root/contrib/binutils/libiberty/cp-demangle.c
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/binutils/libiberty/cp-demangle.c')
-rw-r--r--contrib/binutils/libiberty/cp-demangle.c854
1 files changed, 509 insertions, 345 deletions
diff --git a/contrib/binutils/libiberty/cp-demangle.c b/contrib/binutils/libiberty/cp-demangle.c
index 109d533..992b358 100644
--- a/contrib/binutils/libiberty/cp-demangle.c
+++ b/contrib/binutils/libiberty/cp-demangle.c
@@ -1,5 +1,5 @@
/* Demangler for g++ V3 ABI.
- Copyright (C) 2003, 2004, 2005 Free Software Foundation, Inc.
+ Copyright (C) 2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc.
Written by Ian Lance Taylor <ian@wasabisystems.com>.
This file is part of the libiberty library, which is part of GCC.
@@ -42,6 +42,10 @@
This file will normally define the following functions, q.v.:
char *cplus_demangle_v3(const char *mangled, int options)
char *java_demangle_v3(const char *mangled)
+ int cplus_demangle_v3_callback(const char *mangled, int options,
+ demangle_callbackref callback)
+ int java_demangle_v3_callback(const char *mangled,
+ demangle_callbackref callback)
enum gnu_v3_ctor_kinds is_gnu_v3_mangled_ctor (const char *name)
enum gnu_v3_dtor_kinds is_gnu_v3_mangled_dtor (const char *name)
@@ -50,12 +54,14 @@
defined in demangle.h:
enum demangle_component_type
struct demangle_component
+ demangle_callbackref
and these functions defined in this file:
cplus_demangle_fill_name
cplus_demangle_fill_extended_operator
cplus_demangle_fill_ctor
cplus_demangle_fill_dtor
cplus_demangle_print
+ cplus_demangle_print_callback
and other functions defined in the file cp-demint.c.
This file also defines some other functions and variables which are
@@ -64,14 +70,20 @@
Preprocessor macros you can define while compiling this file:
IN_LIBGCC2
- If defined, this file defines the following function, q.v.:
+ If defined, this file defines the following functions, q.v.:
char *__cxa_demangle (const char *mangled, char *buf, size_t *len,
int *status)
- instead of cplus_demangle_v3() and java_demangle_v3().
+ int __gcclibcxx_demangle_callback (const char *,
+ void (*)
+ (const char *, size_t, void *),
+ void *)
+ instead of cplus_demangle_v3[_callback]() and
+ java_demangle_v3[_callback]().
IN_GLIBCPP_V3
- If defined, this file defines only __cxa_demangle(), and no other
- publically visible functions or variables.
+ If defined, this file defines only __cxa_demangle() and
+ __gcclibcxx_demangle_callback(), and no other publically visible
+ functions or variables.
STANDALONE_DEMANGLER
If defined, this file defines a main() function which demangles
@@ -82,6 +94,10 @@
stdout about the mangled string. This is not generally useful.
*/
+#if defined (_AIX) && !defined (__GNUC__)
+ #pragma alloca
+#endif
+
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
@@ -95,6 +111,18 @@
#include <string.h>
#endif
+#ifdef HAVE_ALLOCA_H
+# include <alloca.h>
+#else
+# ifndef alloca
+# ifdef __GNUC__
+# define alloca __builtin_alloca
+# else
+extern char *alloca ();
+# endif /* __GNUC__ */
+# endif /* alloca */
+#endif /* HAVE_ALLOCA_H */
+
#include "ansidecl.h"
#include "libiberty.h"
#include "demangle.h"
@@ -135,6 +163,10 @@ static struct demangle_component *d_type (struct d_info *);
#define cplus_demangle_print d_print
static char *d_print (int, const struct demangle_component *, int, size_t *);
+#define cplus_demangle_print_callback d_print_callback
+static int d_print_callback (int, const struct demangle_component *,
+ demangle_callbackref, void *);
+
#define cplus_demangle_init_info d_init_info
static void d_init_info (const char *, int, size_t, struct d_info *);
@@ -162,8 +194,8 @@ static void d_init_info (const char *, int, size_t, struct d_info *);
V3 demangler code.
As of this writing this file has the following undefined references
- when compiled with -DIN_GLIBCPP_V3: malloc, realloc, free, memcpy,
- strcpy, strcat, strlen. */
+ when compiled with -DIN_GLIBCPP_V3: realloc, free, memcpy, strcpy,
+ strcat, strlen. */
#define IS_DIGIT(c) ((c) >= '0' && (c) <= '9')
#define IS_UPPER(c) ((c) >= 'A' && (c) <= 'Z')
@@ -228,58 +260,46 @@ struct d_print_mod
struct d_print_template *templates;
};
-/* We use this structure to hold information during printing. */
+/* We use these structures to hold information during printing. */
-struct d_print_info
+struct d_growable_string
{
- /* The options passed to the demangler. */
- int options;
/* Buffer holding the result. */
char *buf;
/* Current length of data in buffer. */
size_t len;
/* Allocated size of buffer. */
size_t alc;
+ /* Set to 1 if we had a memory allocation failure. */
+ int allocation_failure;
+};
+
+enum { D_PRINT_BUFFER_LENGTH = 256 };
+struct d_print_info
+{
+ /* The options passed to the demangler. */
+ int options;
+ /* Fixed-length allocated buffer for demangled data, flushed to the
+ callback with a NUL termination once full. */
+ char buf[D_PRINT_BUFFER_LENGTH];
+ /* Current length of data in buffer. */
+ size_t len;
+ /* The last character printed, saved individually so that it survives
+ any buffer flush. */
+ char last_char;
+ /* Callback function to handle demangled buffer flush. */
+ demangle_callbackref callback;
+ /* Opaque callback argument. */
+ void *opaque;
/* The current list of templates, if any. */
struct d_print_template *templates;
/* The current list of modifiers (e.g., pointer, reference, etc.),
if any. */
struct d_print_mod *modifiers;
- /* Set to 1 if we had a memory allocation failure. */
- int allocation_failure;
+ /* Set to 1 if we saw a demangling error. */
+ int demangle_failure;
};
-#define d_print_saw_error(dpi) ((dpi)->buf == NULL)
-
-#define d_append_char(dpi, c) \
- do \
- { \
- if ((dpi)->buf != NULL && (dpi)->len < (dpi)->alc) \
- (dpi)->buf[(dpi)->len++] = (c); \
- else \
- d_print_append_char ((dpi), (c)); \
- } \
- while (0)
-
-#define d_append_buffer(dpi, s, l) \
- do \
- { \
- if ((dpi)->buf != NULL && (dpi)->len + (l) <= (dpi)->alc) \
- { \
- memcpy ((dpi)->buf + (dpi)->len, (s), (l)); \
- (dpi)->len += l; \
- } \
- else \
- d_print_append_buffer ((dpi), (s), (l)); \
- } \
- while (0)
-
-#define d_append_string_constant(dpi, s) \
- d_append_buffer (dpi, (s), sizeof (s) - 1)
-
-#define d_last_char(dpi) \
- ((dpi)->buf == NULL || (dpi)->len == 0 ? '\0' : (dpi)->buf[(dpi)->len - 1])
-
#ifdef CP_DEMANGLE_DEBUG
static void d_dump (struct demangle_component *, int);
#endif
@@ -389,14 +409,34 @@ d_add_substitution (struct d_info *, struct demangle_component *);
static struct demangle_component *d_substitution (struct d_info *, int);
-static void d_print_resize (struct d_print_info *, size_t);
+static void d_growable_string_init (struct d_growable_string *, size_t);
-static void d_print_append_char (struct d_print_info *, int);
+static inline void
+d_growable_string_resize (struct d_growable_string *, size_t);
+
+static inline void
+d_growable_string_append_buffer (struct d_growable_string *,
+ const char *, size_t);
+static void
+d_growable_string_callback_adapter (const char *, size_t, void *);
static void
-d_print_append_buffer (struct d_print_info *, const char *, size_t);
+d_print_init (struct d_print_info *, int, demangle_callbackref, void *);
-static void d_print_error (struct d_print_info *);
+static inline void d_print_error (struct d_print_info *);
+
+static inline int d_print_saw_error (struct d_print_info *);
+
+static inline void d_print_flush (struct d_print_info *);
+
+static inline void d_append_char (struct d_print_info *, char);
+
+static inline void d_append_buffer (struct d_print_info *,
+ const char *, size_t);
+
+static inline void d_append_string (struct d_print_info *, const char *);
+
+static inline char d_last_char (struct d_print_info *);
static void
d_print_comp (struct d_print_info *, const struct demangle_component *);
@@ -426,6 +466,8 @@ d_print_expr_op (struct d_print_info *, const struct demangle_component *);
static void
d_print_cast (struct d_print_info *, const struct demangle_component *);
+static int d_demangle_callback (const char *, int,
+ demangle_callbackref, void *);
static char *d_demangle (const char *, int, size_t *);
#ifdef CP_DEMANGLE_DEBUG
@@ -436,7 +478,11 @@ d_dump (struct demangle_component *dc, int indent)
int i;
if (dc == NULL)
- return;
+ {
+ if (indent == 0)
+ printf ("failed demangling\n");
+ return;
+ }
for (i = 0; i < indent; ++i)
putchar (' ');
@@ -913,9 +959,9 @@ CP_STATIC_IF_GLIBCPP_V3
struct demangle_component *
cplus_demangle_mangled_name (struct d_info *di, int top_level)
{
- if (d_next_char (di) != '_')
+ if (! d_check_char (di, '_'))
return NULL;
- if (d_next_char (di) != 'Z')
+ if (! d_check_char (di, 'Z'))
return NULL;
return d_encoding (di, top_level);
}
@@ -1021,7 +1067,7 @@ d_encoding (struct d_info *di, int top_level)
}
peek = d_peek_char (di);
- if (peek == '\0' || peek == 'E')
+ if (dc == NULL || peek == '\0' || peek == 'E')
return dc;
return d_make_comp (di, DEMANGLE_COMPONENT_TYPED_NAME, dc,
d_bare_function_type (di, has_return_type (dc)));
@@ -1054,6 +1100,9 @@ d_name (struct d_info *di)
case 'Z':
return d_local_name (di);
+ case 'L':
+ return d_unqualified_name (di);
+
case 'S':
{
int subst;
@@ -1123,7 +1172,7 @@ d_nested_name (struct d_info *di)
struct demangle_component *ret;
struct demangle_component **pret;
- if (d_next_char (di) != 'N')
+ if (! d_check_char (di, 'N'))
return NULL;
pret = d_cv_qualifiers (di, &ret, 1);
@@ -1134,7 +1183,7 @@ d_nested_name (struct d_info *di)
if (*pret == NULL)
return NULL;
- if (d_next_char (di) != 'E')
+ if (! d_check_char (di, 'E'))
return NULL;
return ret;
@@ -1174,7 +1223,8 @@ d_prefix (struct d_info *di)
if (IS_DIGIT (peek)
|| IS_LOWER (peek)
|| peek == 'C'
- || peek == 'D')
+ || peek == 'D'
+ || peek == 'L')
dc = d_unqualified_name (di);
else if (peek == 'S')
dc = d_substitution (di, 1);
@@ -1208,6 +1258,9 @@ d_prefix (struct d_info *di)
/* <unqualified-name> ::= <operator-name>
::= <ctor-dtor-name>
::= <source-name>
+ ::= <local-source-name>
+
+ <local-source-name> ::= L <source-name> <discriminator>
*/
static struct demangle_component *
@@ -1229,6 +1282,19 @@ d_unqualified_name (struct d_info *di)
}
else if (peek == 'C' || peek == 'D')
return d_ctor_dtor_name (di);
+ else if (peek == 'L')
+ {
+ struct demangle_component * ret;
+
+ d_advance (di, 1);
+
+ ret = d_source_name (di);
+ if (ret == NULL)
+ return NULL;
+ if (! d_discriminator (di))
+ return NULL;
+ return ret;
+ }
else
return NULL;
}
@@ -1449,11 +1515,8 @@ d_operator_name (struct d_info *di)
static struct demangle_component *
d_special_name (struct d_info *di)
{
- char c;
-
di->expansion += 20;
- c = d_next_char (di);
- if (c == 'T')
+ if (d_check_char (di, 'T'))
{
switch (d_next_char (di))
{
@@ -1502,7 +1565,7 @@ d_special_name (struct d_info *di)
offset = d_number (di);
if (offset < 0)
return NULL;
- if (d_next_char (di) != '_')
+ if (! d_check_char (di, '_'))
return NULL;
base_type = cplus_demangle_type (di);
/* We don't display the offset. FIXME: We should display
@@ -1523,7 +1586,7 @@ d_special_name (struct d_info *di)
return NULL;
}
}
- else if (c == 'G')
+ else if (d_check_char (di, 'G'))
{
switch (d_next_char (di))
{
@@ -1570,14 +1633,14 @@ d_call_offset (struct d_info *di, int c)
else if (c == 'v')
{
d_number (di);
- if (d_next_char (di) != '_')
+ if (! d_check_char (di, '_'))
return 0;
d_number (di);
}
else
return 0;
- if (d_next_char (di) != '_')
+ if (! d_check_char (di, '_'))
return 0;
return 1;
@@ -1601,13 +1664,13 @@ d_ctor_dtor_name (struct d_info *di)
else if (di->last_name->type == DEMANGLE_COMPONENT_SUB_STD)
di->expansion += di->last_name->u.s_string.len;
}
- switch (d_next_char (di))
+ switch (d_peek_char (di))
{
case 'C':
{
enum gnu_v3_ctor_kinds kind;
- switch (d_next_char (di))
+ switch (d_peek_next_char (di))
{
case '1':
kind = gnu_v3_complete_object_ctor;
@@ -1621,6 +1684,7 @@ d_ctor_dtor_name (struct d_info *di)
default:
return NULL;
}
+ d_advance (di, 2);
return d_make_ctor (di, kind, di->last_name);
}
@@ -1628,7 +1692,7 @@ d_ctor_dtor_name (struct d_info *di)
{
enum gnu_v3_dtor_kinds kind;
- switch (d_next_char (di))
+ switch (d_peek_next_char (di))
{
case '0':
kind = gnu_v3_deleting_dtor;
@@ -1642,6 +1706,7 @@ d_ctor_dtor_name (struct d_info *di)
default:
return NULL;
}
+ d_advance (di, 2);
return d_make_dtor (di, kind, di->last_name);
}
@@ -1735,7 +1800,7 @@ cplus_demangle_type (struct d_info *di)
if (pret == NULL)
return NULL;
*pret = cplus_demangle_type (di);
- if (! d_add_substitution (di, ret))
+ if (! *pret || ! d_add_substitution (di, ret))
return NULL;
return ret;
}
@@ -1925,7 +1990,7 @@ d_function_type (struct d_info *di)
{
struct demangle_component *ret;
- if (d_next_char (di) != 'F')
+ if (! d_check_char (di, 'F'))
return NULL;
if (d_peek_char (di) == 'Y')
{
@@ -1934,7 +1999,7 @@ d_function_type (struct d_info *di)
d_advance (di, 1);
}
ret = d_bare_function_type (di, 1);
- if (d_next_char (di) != 'E')
+ if (! d_check_char (di, 'E'))
return NULL;
return ret;
}
@@ -2021,7 +2086,7 @@ d_array_type (struct d_info *di)
char peek;
struct demangle_component *dim;
- if (d_next_char (di) != 'A')
+ if (! d_check_char (di, 'A'))
return NULL;
peek = d_peek_char (di);
@@ -2049,7 +2114,7 @@ d_array_type (struct d_info *di)
return NULL;
}
- if (d_next_char (di) != '_')
+ if (! d_check_char (di, '_'))
return NULL;
return d_make_comp (di, DEMANGLE_COMPONENT_ARRAY_TYPE, dim,
@@ -2065,7 +2130,7 @@ d_pointer_to_member_type (struct d_info *di)
struct demangle_component *mem;
struct demangle_component **pmem;
- if (d_next_char (di) != 'M')
+ if (! d_check_char (di, 'M'))
return NULL;
cl = cplus_demangle_type (di);
@@ -2081,12 +2146,23 @@ d_pointer_to_member_type (struct d_info *di)
g++ does not work that way. g++ treats only the CV-qualified
member function as a substitution source. FIXME. So to work
with g++, we need to pull off the CV-qualifiers here, in order to
- avoid calling add_substitution() in cplus_demangle_type(). */
+ avoid calling add_substitution() in cplus_demangle_type(). But
+ for a CV-qualified member which is not a function, g++ does
+ follow the ABI, so we need to handle that case here by calling
+ d_add_substitution ourselves. */
pmem = d_cv_qualifiers (di, &mem, 1);
if (pmem == NULL)
return NULL;
*pmem = cplus_demangle_type (di);
+ if (*pmem == NULL)
+ return NULL;
+
+ if (pmem != &mem && (*pmem)->type != DEMANGLE_COMPONENT_FUNCTION_TYPE)
+ {
+ if (! d_add_substitution (di, mem))
+ return NULL;
+ }
return d_make_comp (di, DEMANGLE_COMPONENT_PTRMEM_TYPE, cl, mem);
}
@@ -2100,7 +2176,7 @@ d_template_param (struct d_info *di)
{
long param;
- if (d_next_char (di) != 'T')
+ if (! d_check_char (di, 'T'))
return NULL;
if (d_peek_char (di) == '_')
@@ -2113,7 +2189,7 @@ d_template_param (struct d_info *di)
param += 1;
}
- if (d_next_char (di) != '_')
+ if (! d_check_char (di, '_'))
return NULL;
++di->did_subs;
@@ -2135,7 +2211,7 @@ d_template_args (struct d_info *di)
constructor or destructor. */
hold_last_name = di->last_name;
- if (d_next_char (di) != 'I')
+ if (! d_check_char (di, 'I'))
return NULL;
al = NULL;
@@ -2180,7 +2256,7 @@ d_template_arg (struct d_info *di)
case 'X':
d_advance (di, 1);
ret = d_expression (di);
- if (d_next_char (di) != 'E')
+ if (! d_check_char (di, 'E'))
return NULL;
return ret;
@@ -2307,7 +2383,7 @@ d_expr_primary (struct d_info *di)
{
struct demangle_component *ret;
- if (d_next_char (di) != 'L')
+ if (! d_check_char (di, 'L'))
return NULL;
if (d_peek_char (di) == '_')
ret = cplus_demangle_mangled_name (di, 0);
@@ -2353,7 +2429,7 @@ d_expr_primary (struct d_info *di)
}
ret = d_make_comp (di, t, type, d_make_name (di, s, d_str (di) - s));
}
- if (d_next_char (di) != 'E')
+ if (! d_check_char (di, 'E'))
return NULL;
return ret;
}
@@ -2367,12 +2443,12 @@ d_local_name (struct d_info *di)
{
struct demangle_component *function;
- if (d_next_char (di) != 'Z')
+ if (! d_check_char (di, 'Z'))
return NULL;
function = d_encoding (di, 0);
- if (d_next_char (di) != 'E')
+ if (! d_check_char (di, 'E'))
return NULL;
if (d_peek_char (di) == 's')
@@ -2477,7 +2553,7 @@ d_substitution (struct d_info *di, int prefix)
{
char c;
- if (d_next_char (di) != 'S')
+ if (! d_check_char (di, 'S'))
return NULL;
c = d_next_char (di);
@@ -2496,6 +2572,8 @@ d_substitution (struct d_info *di, int prefix)
id = id * 36 + c - 'A' + 10;
else
return NULL;
+ if (id < 0)
+ return NULL;
c = d_next_char (di);
}
while (c != '_');
@@ -2557,80 +2635,181 @@ d_substitution (struct d_info *di, int prefix)
}
}
-/* Resize the print buffer. */
+/* Initialize a growable string. */
static void
-d_print_resize (struct d_print_info *dpi, size_t add)
+d_growable_string_init (struct d_growable_string *dgs, size_t estimate)
{
- size_t need;
+ dgs->buf = NULL;
+ dgs->len = 0;
+ dgs->alc = 0;
+ dgs->allocation_failure = 0;
- if (dpi->buf == NULL)
+ if (estimate > 0)
+ d_growable_string_resize (dgs, estimate);
+}
+
+/* Grow a growable string to a given size. */
+
+static inline void
+d_growable_string_resize (struct d_growable_string *dgs, size_t need)
+{
+ size_t newalc;
+ char *newbuf;
+
+ if (dgs->allocation_failure)
return;
- need = dpi->len + add;
- while (need > dpi->alc)
- {
- size_t newalc;
- char *newbuf;
- newalc = dpi->alc * 2;
- newbuf = (char *) realloc (dpi->buf, newalc);
- if (newbuf == NULL)
- {
- free (dpi->buf);
- dpi->buf = NULL;
- dpi->allocation_failure = 1;
- return;
- }
- dpi->buf = newbuf;
- dpi->alc = newalc;
+ /* Start allocation at two bytes to avoid any possibility of confusion
+ with the special value of 1 used as a return in *palc to indicate
+ allocation failures. */
+ newalc = dgs->alc > 0 ? dgs->alc : 2;
+ while (newalc < need)
+ newalc <<= 1;
+
+ newbuf = (char *) realloc (dgs->buf, newalc);
+ if (newbuf == NULL)
+ {
+ free (dgs->buf);
+ dgs->buf = NULL;
+ dgs->len = 0;
+ dgs->alc = 0;
+ dgs->allocation_failure = 1;
+ return;
}
+ dgs->buf = newbuf;
+ dgs->alc = newalc;
}
-/* Append a character to the print buffer. */
+/* Append a buffer to a growable string. */
-static void
-d_print_append_char (struct d_print_info *dpi, int c)
+static inline void
+d_growable_string_append_buffer (struct d_growable_string *dgs,
+ const char *s, size_t l)
{
- if (dpi->buf != NULL)
- {
- if (dpi->len >= dpi->alc)
- {
- d_print_resize (dpi, 1);
- if (dpi->buf == NULL)
- return;
- }
+ size_t need;
- dpi->buf[dpi->len] = c;
- ++dpi->len;
- }
+ need = dgs->len + l + 1;
+ if (need > dgs->alc)
+ d_growable_string_resize (dgs, need);
+
+ if (dgs->allocation_failure)
+ return;
+
+ memcpy (dgs->buf + dgs->len, s, l);
+ dgs->buf[dgs->len + l] = '\0';
+ dgs->len += l;
}
-/* Append a buffer to the print buffer. */
+/* Bridge growable strings to the callback mechanism. */
static void
-d_print_append_buffer (struct d_print_info *dpi, const char *s, size_t l)
+d_growable_string_callback_adapter (const char *s, size_t l, void *opaque)
{
- if (dpi->buf != NULL)
- {
- if (dpi->len + l > dpi->alc)
- {
- d_print_resize (dpi, l);
- if (dpi->buf == NULL)
- return;
- }
+ struct d_growable_string *dgs = (struct d_growable_string*) opaque;
- memcpy (dpi->buf + dpi->len, s, l);
- dpi->len += l;
- }
+ d_growable_string_append_buffer (dgs, s, l);
}
-/* Indicate that an error occurred during printing. */
+/* Initialize a print information structure. */
static void
+d_print_init (struct d_print_info *dpi, int options,
+ demangle_callbackref callback, void *opaque)
+{
+ dpi->options = options;
+ dpi->len = 0;
+ dpi->last_char = '\0';
+ dpi->templates = NULL;
+ dpi->modifiers = NULL;
+
+ dpi->callback = callback;
+ dpi->opaque = opaque;
+
+ dpi->demangle_failure = 0;
+}
+
+/* Indicate that an error occurred during printing, and test for error. */
+
+static inline void
d_print_error (struct d_print_info *dpi)
{
- free (dpi->buf);
- dpi->buf = NULL;
+ dpi->demangle_failure = 1;
+}
+
+static inline int
+d_print_saw_error (struct d_print_info *dpi)
+{
+ return dpi->demangle_failure != 0;
+}
+
+/* Flush buffered characters to the callback. */
+
+static inline void
+d_print_flush (struct d_print_info *dpi)
+{
+ dpi->buf[dpi->len] = '\0';
+ dpi->callback (dpi->buf, dpi->len, dpi->opaque);
+ dpi->len = 0;
+}
+
+/* Append characters and buffers for printing. */
+
+static inline void
+d_append_char (struct d_print_info *dpi, char c)
+{
+ if (dpi->len == sizeof (dpi->buf) - 1)
+ d_print_flush (dpi);
+
+ dpi->buf[dpi->len++] = c;
+ dpi->last_char = c;
+}
+
+static inline void
+d_append_buffer (struct d_print_info *dpi, const char *s, size_t l)
+{
+ size_t i;
+
+ for (i = 0; i < l; i++)
+ d_append_char (dpi, s[i]);
+}
+
+static inline void
+d_append_string (struct d_print_info *dpi, const char *s)
+{
+ d_append_buffer (dpi, s, strlen (s));
+}
+
+static inline char
+d_last_char (struct d_print_info *dpi)
+{
+ return dpi->last_char;
+}
+
+/* Turn components into a human readable string. OPTIONS is the
+ options bits passed to the demangler. DC is the tree to print.
+ CALLBACK is a function to call to flush demangled string segments
+ as they fill the intermediate buffer, and OPAQUE is a generalized
+ callback argument. On success, this returns 1. On failure,
+ it returns 0, indicating a bad parse. It does not use heap
+ memory to build an output string, so cannot encounter memory
+ allocation failure. */
+
+CP_STATIC_IF_GLIBCPP_V3
+int
+cplus_demangle_print_callback (int options,
+ const struct demangle_component *dc,
+ demangle_callbackref callback, void *opaque)
+{
+ struct d_print_info dpi;
+
+ d_print_init (&dpi, options, callback, opaque);
+
+ d_print_comp (&dpi, dc);
+
+ d_print_flush (&dpi);
+
+ return ! d_print_saw_error (&dpi);
}
/* Turn components into a human readable string. OPTIONS is the
@@ -2646,34 +2825,21 @@ char *
cplus_demangle_print (int options, const struct demangle_component *dc,
int estimate, size_t *palc)
{
- struct d_print_info dpi;
+ struct d_growable_string dgs;
- dpi.options = options;
+ d_growable_string_init (&dgs, estimate);
- dpi.alc = estimate + 1;
- dpi.buf = (char *) malloc (dpi.alc);
- if (dpi.buf == NULL)
+ if (! cplus_demangle_print_callback (options, dc,
+ d_growable_string_callback_adapter,
+ &dgs))
{
- *palc = 1;
+ free (dgs.buf);
+ *palc = 0;
return NULL;
}
- dpi.len = 0;
- dpi.templates = NULL;
- dpi.modifiers = NULL;
-
- dpi.allocation_failure = 0;
-
- d_print_comp (&dpi, dc);
-
- d_append_char (&dpi, '\0');
-
- if (dpi.buf != NULL)
- *palc = dpi.alc;
- else
- *palc = dpi.allocation_failure;
-
- return dpi.buf;
+ *palc = dgs.allocation_failure ? 1 : dgs.alc;
+ return dgs.buf;
}
/* Subroutine to handle components. */
@@ -2703,7 +2869,7 @@ d_print_comp (struct d_print_info *dpi,
case DEMANGLE_COMPONENT_LOCAL_NAME:
d_print_comp (dpi, d_left (dc));
if ((dpi->options & DMGL_JAVA) == 0)
- d_append_string_constant (dpi, "::");
+ d_append_string (dpi, "::");
else
d_append_char (dpi, '.');
d_print_comp (dpi, d_right (dc));
@@ -2812,6 +2978,7 @@ d_print_comp (struct d_print_info *dpi,
case DEMANGLE_COMPONENT_TEMPLATE:
{
struct d_print_mod *hold_dpm;
+ struct demangle_component *dcl;
/* Don't push modifiers into a template definition. Doing so
could give the wrong definition for a template argument.
@@ -2820,16 +2987,32 @@ d_print_comp (struct d_print_info *dpi,
hold_dpm = dpi->modifiers;
dpi->modifiers = NULL;
- d_print_comp (dpi, d_left (dc));
- if (d_last_char (dpi) == '<')
- d_append_char (dpi, ' ');
- d_append_char (dpi, '<');
- d_print_comp (dpi, d_right (dc));
- /* Avoid generating two consecutive '>' characters, to avoid
- the C++ syntactic ambiguity. */
- if (d_last_char (dpi) == '>')
- d_append_char (dpi, ' ');
- d_append_char (dpi, '>');
+ dcl = d_left (dc);
+
+ if ((dpi->options & DMGL_JAVA) != 0
+ && dcl->type == DEMANGLE_COMPONENT_NAME
+ && dcl->u.s_name.len == 6
+ && strncmp (dcl->u.s_name.s, "JArray", 6) == 0)
+ {
+ /* Special-case Java arrays, so that JArray<TYPE> appears
+ instead as TYPE[]. */
+
+ d_print_comp (dpi, d_right (dc));
+ d_append_string (dpi, "[]");
+ }
+ else
+ {
+ d_print_comp (dpi, dcl);
+ if (d_last_char (dpi) == '<')
+ d_append_char (dpi, ' ');
+ d_append_char (dpi, '<');
+ d_print_comp (dpi, d_right (dc));
+ /* Avoid generating two consecutive '>' characters, to avoid
+ the C++ syntactic ambiguity. */
+ if (d_last_char (dpi) == '>')
+ d_append_char (dpi, ' ');
+ d_append_char (dpi, '>');
+ }
dpi->modifiers = hold_dpm;
@@ -2892,69 +3075,69 @@ d_print_comp (struct d_print_info *dpi,
return;
case DEMANGLE_COMPONENT_VTABLE:
- d_append_string_constant (dpi, "vtable for ");
+ d_append_string (dpi, "vtable for ");
d_print_comp (dpi, d_left (dc));
return;
case DEMANGLE_COMPONENT_VTT:
- d_append_string_constant (dpi, "VTT for ");
+ d_append_string (dpi, "VTT for ");
d_print_comp (dpi, d_left (dc));
return;
case DEMANGLE_COMPONENT_CONSTRUCTION_VTABLE:
- d_append_string_constant (dpi, "construction vtable for ");
+ d_append_string (dpi, "construction vtable for ");
d_print_comp (dpi, d_left (dc));
- d_append_string_constant (dpi, "-in-");
+ d_append_string (dpi, "-in-");
d_print_comp (dpi, d_right (dc));
return;
case DEMANGLE_COMPONENT_TYPEINFO:
- d_append_string_constant (dpi, "typeinfo for ");
+ d_append_string (dpi, "typeinfo for ");
d_print_comp (dpi, d_left (dc));
return;
case DEMANGLE_COMPONENT_TYPEINFO_NAME:
- d_append_string_constant (dpi, "typeinfo name for ");
+ d_append_string (dpi, "typeinfo name for ");
d_print_comp (dpi, d_left (dc));
return;
case DEMANGLE_COMPONENT_TYPEINFO_FN:
- d_append_string_constant (dpi, "typeinfo fn for ");
+ d_append_string (dpi, "typeinfo fn for ");
d_print_comp (dpi, d_left (dc));
return;
case DEMANGLE_COMPONENT_THUNK:
- d_append_string_constant (dpi, "non-virtual thunk to ");
+ d_append_string (dpi, "non-virtual thunk to ");
d_print_comp (dpi, d_left (dc));
return;
case DEMANGLE_COMPONENT_VIRTUAL_THUNK:
- d_append_string_constant (dpi, "virtual thunk to ");
+ d_append_string (dpi, "virtual thunk to ");
d_print_comp (dpi, d_left (dc));
return;
case DEMANGLE_COMPONENT_COVARIANT_THUNK:
- d_append_string_constant (dpi, "covariant return thunk to ");
+ d_append_string (dpi, "covariant return thunk to ");
d_print_comp (dpi, d_left (dc));
return;
case DEMANGLE_COMPONENT_JAVA_CLASS:
- d_append_string_constant (dpi, "java Class for ");
+ d_append_string (dpi, "java Class for ");
d_print_comp (dpi, d_left (dc));
return;
case DEMANGLE_COMPONENT_GUARD:
- d_append_string_constant (dpi, "guard variable for ");
+ d_append_string (dpi, "guard variable for ");
d_print_comp (dpi, d_left (dc));
return;
case DEMANGLE_COMPONENT_REFTEMP:
- d_append_string_constant (dpi, "reference temporary for ");
+ d_append_string (dpi, "reference temporary for ");
d_print_comp (dpi, d_left (dc));
return;
case DEMANGLE_COMPONENT_HIDDEN_ALIAS:
- d_append_string_constant (dpi, "hidden alias for ");
+ d_append_string (dpi, "hidden alias for ");
d_print_comp (dpi, d_left (dc));
return;
@@ -3153,7 +3336,7 @@ d_print_comp (struct d_print_info *dpi,
{
d_append_char (dpi, ' ');
d_print_comp (dpi, d_left (dc));
- d_append_string_constant (dpi, "::*");
+ d_append_string (dpi, "::*");
}
dpi->modifiers = dpm.next;
@@ -3166,7 +3349,7 @@ d_print_comp (struct d_print_info *dpi,
d_print_comp (dpi, d_left (dc));
if (d_right (dc) != NULL)
{
- d_append_string_constant (dpi, ", ");
+ d_append_string (dpi, ", ");
d_print_comp (dpi, d_right (dc));
}
return;
@@ -3175,7 +3358,7 @@ d_print_comp (struct d_print_info *dpi,
{
char c;
- d_append_string_constant (dpi, "operator");
+ d_append_string (dpi, "operator");
c = dc->u.s_operator.op->name[0];
if (IS_LOWER (c))
d_append_char (dpi, ' ');
@@ -3185,12 +3368,12 @@ d_print_comp (struct d_print_info *dpi,
}
case DEMANGLE_COMPONENT_EXTENDED_OPERATOR:
- d_append_string_constant (dpi, "operator ");
+ d_append_string (dpi, "operator ");
d_print_comp (dpi, dc->u.s_extended_operator.name);
return;
case DEMANGLE_COMPONENT_CAST:
- d_append_string_constant (dpi, "operator ");
+ d_append_string (dpi, "operator ");
d_print_cast (dpi, dc);
return;
@@ -3225,9 +3408,9 @@ d_print_comp (struct d_print_info *dpi,
d_append_char (dpi, '(');
d_print_comp (dpi, d_left (d_right (dc)));
- d_append_string_constant (dpi, ") ");
+ d_append_string (dpi, ") ");
d_print_expr_op (dpi, d_left (dc));
- d_append_string_constant (dpi, " (");
+ d_append_string (dpi, " (");
d_print_comp (dpi, d_right (d_right (dc)));
d_append_char (dpi, ')');
@@ -3252,11 +3435,11 @@ d_print_comp (struct d_print_info *dpi,
}
d_append_char (dpi, '(');
d_print_comp (dpi, d_left (d_right (dc)));
- d_append_string_constant (dpi, ") ");
+ d_append_string (dpi, ") ");
d_print_expr_op (dpi, d_left (dc));
- d_append_string_constant (dpi, " (");
+ d_append_string (dpi, " (");
d_print_comp (dpi, d_left (d_right (d_right (dc))));
- d_append_string_constant (dpi, ") : (");
+ d_append_string (dpi, ") : (");
d_print_comp (dpi, d_right (d_right (d_right (dc))));
d_append_char (dpi, ')');
return;
@@ -3301,13 +3484,13 @@ d_print_comp (struct d_print_info *dpi,
d_append_char (dpi, 'l');
break;
case D_PRINT_UNSIGNED_LONG:
- d_append_string_constant (dpi, "ul");
+ d_append_string (dpi, "ul");
break;
case D_PRINT_LONG_LONG:
- d_append_string_constant (dpi, "ll");
+ d_append_string (dpi, "ll");
break;
case D_PRINT_UNSIGNED_LONG_LONG:
- d_append_string_constant (dpi, "ull");
+ d_append_string (dpi, "ull");
break;
}
return;
@@ -3322,10 +3505,10 @@ d_print_comp (struct d_print_info *dpi,
switch (d_right (dc)->u.s_name.s[0])
{
case '0':
- d_append_string_constant (dpi, "false");
+ d_append_string (dpi, "false");
return;
case '1':
- d_append_string_constant (dpi, "true");
+ d_append_string (dpi, "true");
return;
default:
break;
@@ -3464,7 +3647,7 @@ d_print_mod_list (struct d_print_info *dpi,
dpi->modifiers = hold_modifiers;
if ((dpi->options & DMGL_JAVA) == 0)
- d_append_string_constant (dpi, "::");
+ d_append_string (dpi, "::");
else
d_append_char (dpi, '.');
@@ -3497,15 +3680,15 @@ d_print_mod (struct d_print_info *dpi,
{
case DEMANGLE_COMPONENT_RESTRICT:
case DEMANGLE_COMPONENT_RESTRICT_THIS:
- d_append_string_constant (dpi, " restrict");
+ d_append_string (dpi, " restrict");
return;
case DEMANGLE_COMPONENT_VOLATILE:
case DEMANGLE_COMPONENT_VOLATILE_THIS:
- d_append_string_constant (dpi, " volatile");
+ d_append_string (dpi, " volatile");
return;
case DEMANGLE_COMPONENT_CONST:
case DEMANGLE_COMPONENT_CONST_THIS:
- d_append_string_constant (dpi, " const");
+ d_append_string (dpi, " const");
return;
case DEMANGLE_COMPONENT_VENDOR_TYPE_QUAL:
d_append_char (dpi, ' ');
@@ -3520,16 +3703,16 @@ d_print_mod (struct d_print_info *dpi,
d_append_char (dpi, '&');
return;
case DEMANGLE_COMPONENT_COMPLEX:
- d_append_string_constant (dpi, "complex ");
+ d_append_string (dpi, "complex ");
return;
case DEMANGLE_COMPONENT_IMAGINARY:
- d_append_string_constant (dpi, "imaginary ");
+ d_append_string (dpi, "imaginary ");
return;
case DEMANGLE_COMPONENT_PTRMEM_TYPE:
if (d_last_char (dpi) != '(')
d_append_char (dpi, ' ');
d_print_comp (dpi, d_left (mod));
- d_append_string_constant (dpi, "::*");
+ d_append_string (dpi, "::*");
return;
case DEMANGLE_COMPONENT_TYPED_NAME:
d_print_comp (dpi, d_left (mod));
@@ -3662,7 +3845,7 @@ d_print_array_type (struct d_print_info *dpi,
}
if (need_paren)
- d_append_string_constant (dpi, " (");
+ d_append_string (dpi, " (");
d_print_mod_list (dpi, mods, 0);
@@ -3768,26 +3951,19 @@ cplus_demangle_init_info (const char *mangled, int options, size_t len,
di->expansion = 0;
}
-/* Entry point for the demangler. If MANGLED is a g++ v3 ABI mangled
- name, return a buffer allocated with malloc holding the demangled
- name. OPTIONS is the usual libiberty demangler options. On
- success, this sets *PALC to the allocated size of the returned
- buffer. On failure, this sets *PALC to 0 for a bad name, or 1 for
- a memory allocation failure. On failure, this returns NULL. */
+/* Internal implementation for the demangler. If MANGLED is a g++ v3 ABI
+ mangled name, return strings in repeated callback giving the demangled
+ name. OPTIONS is the usual libiberty demangler options. On success,
+ this returns 1. On failure, returns 0. */
-static char *
-d_demangle (const char* mangled, int options, size_t *palc)
+static int
+d_demangle_callback (const char *mangled, int options,
+ demangle_callbackref callback, void *opaque)
{
- size_t len;
int type;
struct d_info di;
struct demangle_component *dc;
- int estimate;
- char *ret;
-
- *palc = 0;
-
- len = strlen (mangled);
+ int status;
if (mangled[0] == '_' && mangled[1] == 'Z')
type = 0;
@@ -3796,57 +3972,41 @@ d_demangle (const char* mangled, int options, size_t *palc)
&& (mangled[9] == 'D' || mangled[9] == 'I')
&& mangled[10] == '_')
{
- char *r;
+ const char *intro;
- r = (char *) malloc (40 + len - 11);
- if (r == NULL)
- *palc = 1;
- else
- {
- if (mangled[9] == 'I')
- strcpy (r, "global constructors keyed to ");
- else
- strcpy (r, "global destructors keyed to ");
- strcat (r, mangled + 11);
- }
- return r;
+ intro = (mangled[9] == 'I')
+ ? "global constructors keyed to "
+ : "global destructors keyed to ";
+
+ callback (intro, strlen (intro), opaque);
+ callback (mangled + 11, strlen (mangled + 11), opaque);
+ return 1;
}
else
{
if ((options & DMGL_TYPES) == 0)
- return NULL;
+ return 0;
type = 1;
}
- cplus_demangle_init_info (mangled, options, len, &di);
+ cplus_demangle_init_info (mangled, options, strlen (mangled), &di);
{
#ifdef CP_DYNAMIC_ARRAYS
__extension__ struct demangle_component comps[di.num_comps];
__extension__ struct demangle_component *subs[di.num_subs];
- di.comps = &comps[0];
- di.subs = &subs[0];
+ di.comps = comps;
+ di.subs = subs;
#else
- di.comps = ((struct demangle_component *)
- malloc (di.num_comps * sizeof (struct demangle_component)));
- di.subs = ((struct demangle_component **)
- malloc (di.num_subs * sizeof (struct demangle_component *)));
- if (di.comps == NULL || di.subs == NULL)
- {
- if (di.comps != NULL)
- free (di.comps);
- if (di.subs != NULL)
- free (di.subs);
- *palc = 1;
- return NULL;
- }
+ di.comps = alloca (di.num_comps * sizeof (*di.comps));
+ di.subs = alloca (di.num_subs * sizeof (*di.subs));
#endif
- if (! type)
- dc = cplus_demangle_mangled_name (&di, 1);
- else
+ if (type)
dc = cplus_demangle_type (&di);
+ else
+ dc = cplus_demangle_mangled_name (&di, 1);
/* If DMGL_PARAMS is set, then if we didn't consume the entire
mangled string, then we didn't successfully demangle it. If
@@ -3856,46 +4016,43 @@ d_demangle (const char* mangled, int options, size_t *palc)
dc = NULL;
#ifdef CP_DEMANGLE_DEBUG
- if (dc == NULL)
- printf ("failed demangling\n");
- else
- d_dump (dc, 0);
+ d_dump (dc, 0);
#endif
- /* We try to guess the length of the demangled string, to minimize
- calls to realloc during demangling. */
- estimate = len + di.expansion + 10 * di.did_subs;
- estimate += estimate / 8;
+ status = (dc != NULL)
+ ? cplus_demangle_print_callback (options, dc, callback, opaque)
+ : 0;
+ }
- ret = NULL;
- if (dc != NULL)
- ret = cplus_demangle_print (options, dc, estimate, palc);
+ return status;
+}
-#ifndef CP_DYNAMIC_ARRAYS
- free (di.comps);
- free (di.subs);
-#endif
+/* Entry point for the demangler. If MANGLED is a g++ v3 ABI mangled
+ name, return a buffer allocated with malloc holding the demangled
+ name. OPTIONS is the usual libiberty demangler options. On
+ success, this sets *PALC to the allocated size of the returned
+ buffer. On failure, this sets *PALC to 0 for a bad name, or 1 for
+ a memory allocation failure, and returns NULL. */
-#ifdef CP_DEMANGLE_DEBUG
- if (ret != NULL)
- {
- int rlen;
-
- rlen = strlen (ret);
- if (rlen > 2 * estimate)
- printf ("*** Length %d much greater than estimate %d\n",
- rlen, estimate);
- else if (rlen > estimate)
- printf ("*** Length %d greater than estimate %d\n",
- rlen, estimate);
- else if (rlen < estimate / 2)
- printf ("*** Length %d much less than estimate %d\n",
- rlen, estimate);
- }
-#endif
- }
+static char *
+d_demangle (const char *mangled, int options, size_t *palc)
+{
+ struct d_growable_string dgs;
+ int status;
- return ret;
+ d_growable_string_init (&dgs, 0);
+
+ status = d_demangle_callback (mangled, options,
+ d_growable_string_callback_adapter, &dgs);
+ if (status == 0)
+ {
+ free (dgs.buf);
+ *palc = 0;
+ return NULL;
+ }
+
+ *palc = dgs.allocation_failure ? 1 : 0;
+ return dgs.buf;
}
#if defined(IN_LIBGCC2) || defined(IN_GLIBCPP_V3)
@@ -3912,7 +4069,7 @@ extern char *__cxa_demangle (const char *, char *, size_t *, int *);
OUTPUT_BUFFER may instead be NULL; in that case, the demangled name
is placed in a region of memory allocated with malloc.
- If LENGTH is non-NULL, the length of the buffer conaining the
+ If LENGTH is non-NULL, the length of the buffer containing the
demangled name, is placed in *LENGTH.
The return value is a pointer to the start of the NUL-terminated
@@ -3989,6 +4146,48 @@ __cxa_demangle (const char *mangled_name, char *output_buffer,
return demangled;
}
+extern int __gcclibcxx_demangle_callback (const char *,
+ void (*)
+ (const char *, size_t, void *),
+ void *);
+
+/* Alternative, allocationless entry point in the C++ runtime library
+ for performing demangling. MANGLED_NAME is a NUL-terminated character
+ string containing the name to be demangled.
+
+ CALLBACK is a callback function, called with demangled string
+ segments as demangling progresses; it is called at least once,
+ but may be called more than once. OPAQUE is a generalized pointer
+ used as a callback argument.
+
+ The return code is one of the following values, equivalent to
+ the STATUS values of __cxa_demangle() (excluding -1, since this
+ function performs no memory allocations):
+ 0: The demangling operation succeeded.
+ -2: MANGLED_NAME is not a valid name under the C++ ABI mangling rules.
+ -3: One of the arguments is invalid.
+
+ The demangling is performed using the C++ ABI mangling rules, with
+ GNU extensions. */
+
+int
+__gcclibcxx_demangle_callback (const char *mangled_name,
+ void (*callback) (const char *, size_t, void *),
+ void *opaque)
+{
+ int status;
+
+ if (mangled_name == NULL || callback == NULL)
+ return -3;
+
+ status = d_demangle_callback (mangled_name, DMGL_PARAMS | DMGL_TYPES,
+ callback, opaque);
+ if (status == 0)
+ return -2;
+
+ return 0;
+}
+
#else /* ! (IN_LIBGCC2 || IN_GLIBCPP_V3) */
/* Entry point for libiberty demangler. If MANGLED is a g++ v3 ABI
@@ -3996,61 +4195,41 @@ __cxa_demangle (const char *mangled_name, char *output_buffer,
demangled name. Otherwise, return NULL. */
char *
-cplus_demangle_v3 (const char* mangled, int options)
+cplus_demangle_v3 (const char *mangled, int options)
{
size_t alc;
return d_demangle (mangled, options, &alc);
}
+int
+cplus_demangle_v3_callback (const char *mangled, int options,
+ demangle_callbackref callback, void *opaque)
+{
+ return d_demangle_callback (mangled, options, callback, opaque);
+}
+
/* Demangle a Java symbol. Java uses a subset of the V3 ABI C++ mangling
conventions, but the output formatting is a little different.
- This instructs the C++ demangler not to emit pointer characters ("*"), and
- to use Java's namespace separator symbol ("." instead of "::"). It then
- does an additional pass over the demangled output to replace instances
- of JArray<TYPE> with TYPE[]. */
+ This instructs the C++ demangler not to emit pointer characters ("*"), to
+ use Java's namespace separator symbol ("." instead of "::"), and to output
+ JArray<TYPE> as TYPE[]. */
char *
-java_demangle_v3 (const char* mangled)
+java_demangle_v3 (const char *mangled)
{
size_t alc;
- char *demangled;
- int nesting;
- char *from;
- char *to;
- demangled = d_demangle (mangled, DMGL_JAVA | DMGL_PARAMS | DMGL_RET_POSTFIX,
- &alc);
-
- if (demangled == NULL)
- return NULL;
-
- nesting = 0;
- from = demangled;
- to = from;
- while (*from != '\0')
- {
- if (strncmp (from, "JArray<", 7) == 0)
- {
- from += 7;
- ++nesting;
- }
- else if (nesting > 0 && *from == '>')
- {
- while (to > demangled && to[-1] == ' ')
- --to;
- *to++ = '[';
- *to++ = ']';
- --nesting;
- ++from;
- }
- else
- *to++ = *from++;
- }
-
- *to = '\0';
+ return d_demangle (mangled, DMGL_JAVA | DMGL_PARAMS | DMGL_RET_POSTFIX, &alc);
+}
- return demangled;
+int
+java_demangle_v3_callback (const char *mangled,
+ demangle_callbackref callback, void *opaque)
+{
+ return d_demangle_callback (mangled,
+ DMGL_JAVA | DMGL_PARAMS | DMGL_RET_POSTFIX,
+ callback, opaque);
}
#endif /* IN_LIBGCC2 || IN_GLIBCPP_V3 */
@@ -4080,21 +4259,11 @@ is_ctor_or_dtor (const char *mangled,
__extension__ struct demangle_component comps[di.num_comps];
__extension__ struct demangle_component *subs[di.num_subs];
- di.comps = &comps[0];
- di.subs = &subs[0];
+ di.comps = comps;
+ di.subs = subs;
#else
- di.comps = ((struct demangle_component *)
- malloc (di.num_comps * sizeof (struct demangle_component)));
- di.subs = ((struct demangle_component **)
- malloc (di.num_subs * sizeof (struct demangle_component *)));
- if (di.comps == NULL || di.subs == NULL)
- {
- if (di.comps != NULL)
- free (di.comps);
- if (di.subs != NULL)
- free (di.subs);
- return 0;
- }
+ di.comps = alloca (di.num_comps * sizeof (*di.comps));
+ di.subs = alloca (di.num_subs * sizeof (*di.subs));
#endif
dc = cplus_demangle_mangled_name (&di, 1);
@@ -4133,11 +4302,6 @@ is_ctor_or_dtor (const char *mangled,
break;
}
}
-
-#ifndef CP_DYNAMIC_ARRAYS
- free (di.subs);
- free (di.comps);
-#endif
}
return ret;
OpenPOWER on IntegriCloud