[PATCH][RFC] Malloc-less demangler interface
Ian Lance Taylor
iant@google.com
Tue Jan 23 18:32:00 GMT 2007
simonb@google.com (Simon Baldwin) writes:
> diff -rcp3 orig/include/demangle.h new/include/demangle.h
> *** orig/include/demangle.h Wed Dec 27 12:03:11 2006
> --- new/include/demangle.h Tue Jan 9 10:01:25 2007
> *************** cplus_demangle_print (int options,
> *** 529,534 ****
> --- 529,555 ----
> int estimated_length,
> size_t *p_allocated_size);
>
> + /* This function takes a struct demangle_component tree and passes back
> + a demangled string in one or more calls to a callback function.
> + The first argument is DMGL_* options. The second is the tree to
> + demangle. The third is an opaque value used as a callback argument.
> + The fourth is a pointer to a callback function, called with opaque
> + as its first argument, and its second and third arguments an element
> + of the demangled string and its length. The callback is called once
> + or more to return the full demangled string; the demangled element
> + string is always nul-terminated, although its length is also provided
> + for convenience. In contrast to cplus_demangle_print(), this function
> + does not allocate heap memory to grow output strings (except perhaps
> + where alloca() is implemented by malloc()), and so is normally safe
> + for use where the heap has been corrupted. On success, this function
> + returns 1; on failure, 0. */
> +
> + typedef void (*demangle_callbackref) (void*, const char*, size_t);
> + extern int
> + cplus_demangle_callback (int options,
> + const struct demangle_component *tree,
> + void *opaque, demangle_callbackref);
> +
I think the function 'cplus_demangle_callback' should take a char*
parameter rather than a struct demangle_component*. That will be
parallel to 'cplus_demangle'. I think the function here named
'cplus_demangle_callback' should instead be named
'cplus_demangle_print_callback', since it is parallel to
'cplus_demangle_print'.
Then in cp-demangle.c, when IN_LIBGCC2 or IN_GLIBCPP_V3 is defined,
'cplus_demangle_callback' should be renamed to
'__gcclibcxx_demangle_callback' (following Andrew's suggestion).
Also: the gcc convention (e.g., walk_tree) is to pass the callback
function first, and then the opaque argument. And in the callback
function, the opaque argument is last. So, although I know this is
tedious, I think this should be written as
typedef void (*demangle_callbackref) (const char *, size_t, void *);
extern int cplus_demangle_print_callback (int options,
const struct demangle_component *tree,
demangle_callbackref, void *);
And, this is C code, not C++: write pointers as "type *", not "type*".
> + #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 */
> +
For horrible reasons which are simply too awful to get into, code
which may call alloca must put this before any non-comment code
(including any #include) in the file:
#if defined (_AIX) && !defined (__GNUC__)
#pragma alloca
#endif
See, e.g., libiberty/putenv.c.
> *************** d_identifier (struct d_info *di, int len
> *** 1333,1339 ****
> #define NL(s) s, (sizeof s) - 1
>
> CP_STATIC_IF_GLIBCPP_V3
> ! const struct demangle_operator_info cplus_demangle_operators[] =
> {
> { "aN", NL ("&="), 2 },
> { "aS", NL ("="), 2 },
> --- 1362,1369 ----
> #define NL(s) s, (sizeof s) - 1
>
> CP_STATIC_IF_GLIBCPP_V3
> ! const struct demangle_operator_info
> ! cplus_demangle_operators[D_OPERATORS_COUNT] =
> {
> { "aN", NL ("&="), 2 },
> { "aS", NL ("="), 2 },
Why introduce D_OPERATORS_COUNT? I'd prefer to leave it out if we
don't need it.
> ! newbuf = (char *) realloc (dgs->buf, newalc);
This shows a good faith in a standards-conformant realloc: that it
will handle a NULL first argument correctly. I think I'm OK with that
at this point, but I wanted to call it out in case anybody reading
this finds that problematic.
> ! if (dgs->allocation_failure == 1)
> ! return;
dgs->allocation_failure is logically speaking a boolean variable, and
it only takes on the values 0 and 1. I think it would be clearer to
write
if (dgs->allocation_failure)
here and in a couple of other places.
Patch is OK with this niggling changes. Thanks and sorry for the
delay.
Ian
More information about the Gcc-patches
mailing list