* cp-support.c: Include "safe-ctype.h".
(cp_already_canonical): New function. (cp_canonicalize_string): Use it. Return NULL for already canonical strings. (mangled_name_to_comp): Update call to cp_demangled_name_to_comp. (cp_func_name, remove_params): Likewise. (cp_find_first_component_aux): Use ISSPACE. * cp-support.h (cp_demangled_name_to_comp): Correct comment. Remove MEMORY_P argument. * cp-name-parser.y (ALLOC_CHUNK): Define. (struct demangle_info): Add PREV and NEXT. Increase the size of COMPS. (d_grab): Convert to a function. (allocate_info): Rewrite. (cp_demangled_name_to_comp): Remove MEMORY argument. Do not use strlen. Update call to allocate_info. Do not free it on failure. (main): Update calls to cp_demangled_name_to_comp. * Makefile.in (cp-support.o): Update.
This commit is contained in:
parent
e35879dbf0
commit
f88e9fd315
@ -1,3 +1,24 @@
|
||||
2007-10-22 Daniel Jacobowitz <dan@codesourcery.com>
|
||||
|
||||
* cp-support.c: Include "safe-ctype.h".
|
||||
(cp_already_canonical): New function.
|
||||
(cp_canonicalize_string): Use it. Return NULL for already canonical
|
||||
strings.
|
||||
(mangled_name_to_comp): Update call to cp_demangled_name_to_comp.
|
||||
(cp_func_name, remove_params): Likewise.
|
||||
(cp_find_first_component_aux): Use ISSPACE.
|
||||
* cp-support.h (cp_demangled_name_to_comp): Correct comment. Remove
|
||||
MEMORY_P argument.
|
||||
* cp-name-parser.y (ALLOC_CHUNK): Define.
|
||||
(struct demangle_info): Add PREV and NEXT. Increase the size of
|
||||
COMPS.
|
||||
(d_grab): Convert to a function.
|
||||
(allocate_info): Rewrite.
|
||||
(cp_demangled_name_to_comp): Remove MEMORY argument. Do not use
|
||||
strlen. Update call to allocate_info. Do not free it on failure.
|
||||
(main): Update calls to cp_demangled_name_to_comp.
|
||||
* Makefile.in (cp-support.o): Update.
|
||||
|
||||
2007-10-22 Markus Deuling <deuling@de.ibm.com>
|
||||
|
||||
* std-regs.c (value_of_builtin_frame_fp_reg)
|
||||
|
@ -1931,7 +1931,7 @@ cp-namespace.o: cp-namespace.c $(defs_h) $(cp_support_h) $(gdb_obstack_h) \
|
||||
cp-support.o: cp-support.c $(defs_h) $(cp_support_h) $(gdb_string_h) \
|
||||
$(demangle_h) $(gdb_assert_h) $(gdbcmd_h) $(dictionary_h) \
|
||||
$(objfiles_h) $(frame_h) $(symtab_h) $(block_h) $(complaints_h) \
|
||||
$(gdbtypes_h)
|
||||
$(gdbtypes_h) $(safe_ctype_h)
|
||||
cp-valprint.o: cp-valprint.c $(defs_h) $(gdb_obstack_h) $(symtab_h) \
|
||||
$(gdbtypes_h) $(expression_h) $(value_h) $(command_h) $(gdbcmd_h) \
|
||||
$(demangle_h) $(annotate_h) $(gdb_string_h) $(c_lang_h) $(target_h) \
|
||||
|
@ -54,13 +54,38 @@ static const char *lexptr, *prev_lexptr, *error_lexptr, *global_errmsg;
|
||||
/* The components built by the parser are allocated ahead of time,
|
||||
and cached in this structure. */
|
||||
|
||||
#define ALLOC_CHUNK 100
|
||||
|
||||
struct demangle_info {
|
||||
int used;
|
||||
struct demangle_component comps[1];
|
||||
struct demangle_info *prev, *next;
|
||||
struct demangle_component comps[ALLOC_CHUNK];
|
||||
};
|
||||
|
||||
static struct demangle_info *demangle_info;
|
||||
#define d_grab() (&demangle_info->comps[demangle_info->used++])
|
||||
|
||||
static struct demangle_component *
|
||||
d_grab (void)
|
||||
{
|
||||
struct demangle_info *more;
|
||||
|
||||
if (demangle_info->used >= ALLOC_CHUNK)
|
||||
{
|
||||
if (demangle_info->next == NULL)
|
||||
{
|
||||
more = malloc (sizeof (struct demangle_info));
|
||||
more->prev = demangle_info;
|
||||
more->next = NULL;
|
||||
demangle_info->next = more;
|
||||
}
|
||||
else
|
||||
more = demangle_info->next;
|
||||
|
||||
more->used = 0;
|
||||
demangle_info = more;
|
||||
}
|
||||
return &demangle_info->comps[demangle_info->used++];
|
||||
}
|
||||
|
||||
/* The parse tree created by the parser is stored here after a successful
|
||||
parse. */
|
||||
@ -1923,19 +1948,24 @@ yyerror (char *msg)
|
||||
global_errmsg = msg ? msg : "parse error";
|
||||
}
|
||||
|
||||
/* Allocate all the components we'll need to build a tree. We generally
|
||||
allocate too many components, but the extra memory usage doesn't hurt
|
||||
because the trees are temporary. If we start keeping the trees for
|
||||
a longer lifetime we'll need to be cleverer. */
|
||||
static struct demangle_info *
|
||||
allocate_info (int comps)
|
||||
/* Allocate a chunk of the components we'll need to build a tree. We
|
||||
generally allocate too many components, but the extra memory usage
|
||||
doesn't hurt because the trees are temporary and the storage is
|
||||
reused. More may be allocated later, by d_grab. */
|
||||
static void
|
||||
allocate_info (void)
|
||||
{
|
||||
struct demangle_info *ret;
|
||||
if (demangle_info == NULL)
|
||||
{
|
||||
demangle_info = malloc (sizeof (struct demangle_info));
|
||||
demangle_info->prev = NULL;
|
||||
demangle_info->next = NULL;
|
||||
}
|
||||
else
|
||||
while (demangle_info->prev)
|
||||
demangle_info = demangle_info->prev;
|
||||
|
||||
ret = malloc (sizeof (struct demangle_info)
|
||||
+ sizeof (struct demangle_component) * (comps - 1));
|
||||
ret->used = 0;
|
||||
return ret;
|
||||
demangle_info->used = 0;
|
||||
}
|
||||
|
||||
/* Convert RESULT to a string. The return value is allocated
|
||||
@ -1975,26 +2005,23 @@ cp_comp_to_string (struct demangle_component *result, int estimated_len)
|
||||
return (buf);
|
||||
}
|
||||
|
||||
/* Convert a demangled name to a demangle_component tree. *MEMORY is set to the
|
||||
block of used memory that should be freed when finished with the
|
||||
tree. On error, NULL is returned, and an error message will be
|
||||
set in *ERRMSG (which does not need to be freed). */
|
||||
/* Convert a demangled name to a demangle_component tree. On success,
|
||||
the root of the new tree is returned; it is valid until the next
|
||||
call to this function and should not be freed. On error, NULL is
|
||||
returned, and an error message will be set in *ERRMSG (which does
|
||||
not need to be freed). */
|
||||
|
||||
struct demangle_component *
|
||||
cp_demangled_name_to_comp (const char *demangled_name, void **memory,
|
||||
const char **errmsg)
|
||||
cp_demangled_name_to_comp (const char *demangled_name, const char **errmsg)
|
||||
{
|
||||
static char errbuf[60];
|
||||
struct demangle_component *result;
|
||||
|
||||
int len = strlen (demangled_name);
|
||||
|
||||
len = len + len / 8;
|
||||
prev_lexptr = lexptr = demangled_name;
|
||||
error_lexptr = NULL;
|
||||
global_errmsg = NULL;
|
||||
|
||||
demangle_info = allocate_info (len);
|
||||
allocate_info ();
|
||||
|
||||
if (yyparse ())
|
||||
{
|
||||
@ -2005,11 +2032,9 @@ cp_demangled_name_to_comp (const char *demangled_name, void **memory,
|
||||
strcat (errbuf, "'");
|
||||
*errmsg = errbuf;
|
||||
}
|
||||
free (demangle_info);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
*memory = demangle_info;
|
||||
result = global_result;
|
||||
global_result = NULL;
|
||||
|
||||
@ -2063,11 +2088,10 @@ trim_chars (char *lexptr, char **extra_chars)
|
||||
int
|
||||
main (int argc, char **argv)
|
||||
{
|
||||
char *str2, *extra_chars, c;
|
||||
char *str2, *extra_chars = "", c;
|
||||
char buf[65536];
|
||||
int arg;
|
||||
const char *errmsg;
|
||||
void *memory;
|
||||
struct demangle_component *result;
|
||||
|
||||
arg = 1;
|
||||
@ -2094,7 +2118,7 @@ main (int argc, char **argv)
|
||||
printf ("%s\n", buf);
|
||||
continue;
|
||||
}
|
||||
result = cp_demangled_name_to_comp (str2, &memory, &errmsg);
|
||||
result = cp_demangled_name_to_comp (str2, &errmsg);
|
||||
if (result == NULL)
|
||||
{
|
||||
fputs (errmsg, stderr);
|
||||
@ -2103,7 +2127,6 @@ main (int argc, char **argv)
|
||||
}
|
||||
|
||||
cp_print (result);
|
||||
free (memory);
|
||||
|
||||
free (str2);
|
||||
if (c)
|
||||
@ -2115,7 +2138,7 @@ main (int argc, char **argv)
|
||||
}
|
||||
else
|
||||
{
|
||||
result = cp_demangled_name_to_comp (argv[arg], &memory, &errmsg);
|
||||
result = cp_demangled_name_to_comp (argv[arg], &errmsg);
|
||||
if (result == NULL)
|
||||
{
|
||||
fputs (errmsg, stderr);
|
||||
@ -2124,7 +2147,6 @@ main (int argc, char **argv)
|
||||
}
|
||||
cp_print (result);
|
||||
putchar ('\n');
|
||||
free (memory);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
@ -19,7 +19,6 @@
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
#include "defs.h"
|
||||
#include <ctype.h>
|
||||
#include "cp-support.h"
|
||||
#include "gdb_string.h"
|
||||
#include "demangle.h"
|
||||
@ -33,6 +32,8 @@
|
||||
#include "complaints.h"
|
||||
#include "gdbtypes.h"
|
||||
|
||||
#include "safe-ctype.h"
|
||||
|
||||
#define d_left(dc) (dc)->u.s_binary.left
|
||||
#define d_right(dc) (dc)->u.s_binary.right
|
||||
|
||||
@ -68,30 +69,63 @@ struct cmd_list_element *maint_cplus_cmd_list = NULL;
|
||||
static void maint_cplus_command (char *arg, int from_tty);
|
||||
static void first_component_command (char *arg, int from_tty);
|
||||
|
||||
/* Return the canonicalized form of STRING, or NULL if STRING can not be
|
||||
parsed. The return value is allocated via xmalloc.
|
||||
/* Return 1 if STRING is clearly already in canonical form. This
|
||||
function is conservative; things which it does not recognize are
|
||||
assumed to be non-canonical, and the parser will sort them out
|
||||
afterwards. This speeds up the critical path for alphanumeric
|
||||
identifiers. */
|
||||
|
||||
drow/2005-03-07: Should we also return NULL for things that trivially do
|
||||
not require any change? e.g. simple identifiers. This could be more
|
||||
efficient. */
|
||||
static int
|
||||
cp_already_canonical (const char *string)
|
||||
{
|
||||
/* Identifier start character [a-zA-Z_]. */
|
||||
if (!ISIDST (string[0]))
|
||||
return 0;
|
||||
|
||||
/* These are the only two identifiers which canonicalize to other
|
||||
than themselves or an error: unsigned -> unsigned int and
|
||||
signed -> int. */
|
||||
if (string[0] == 'u' && strcmp (&string[1], "nsigned") == 0)
|
||||
return 0;
|
||||
else if (string[0] == 's' && strcmp (&string[1], "igned") == 0)
|
||||
return 0;
|
||||
|
||||
/* Identifier character [a-zA-Z0-9_]. */
|
||||
while (ISIDNUM (string[1]))
|
||||
string++;
|
||||
|
||||
if (string[1] == '\0')
|
||||
return 1;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Parse STRING and convert it to canonical form. If parsing fails,
|
||||
or if STRING is already canonical, return NULL. Otherwise return
|
||||
the canonical form. The return value is allocated via xmalloc. */
|
||||
|
||||
char *
|
||||
cp_canonicalize_string (const char *string)
|
||||
{
|
||||
void *storage;
|
||||
struct demangle_component *ret_comp;
|
||||
unsigned int estimated_len;
|
||||
char *ret;
|
||||
int len = strlen (string);
|
||||
|
||||
len = len + len / 8;
|
||||
if (cp_already_canonical (string))
|
||||
return NULL;
|
||||
|
||||
ret_comp = cp_demangled_name_to_comp (string, &storage, NULL);
|
||||
ret_comp = cp_demangled_name_to_comp (string, NULL);
|
||||
if (ret_comp == NULL)
|
||||
return NULL;
|
||||
|
||||
ret = cp_comp_to_string (ret_comp, len);
|
||||
estimated_len = strlen (string) * 2;
|
||||
ret = cp_comp_to_string (ret_comp, estimated_len);
|
||||
|
||||
xfree (storage);
|
||||
if (strcmp (string, ret) == 0)
|
||||
{
|
||||
xfree (ret);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
@ -128,7 +162,7 @@ mangled_name_to_comp (const char *mangled_name, int options,
|
||||
return NULL;
|
||||
|
||||
/* If we could demangle the name, parse it to build the component tree. */
|
||||
ret = cp_demangled_name_to_comp (demangled_name, memory, NULL);
|
||||
ret = cp_demangled_name_to_comp (demangled_name, NULL);
|
||||
|
||||
if (ret == NULL)
|
||||
{
|
||||
@ -321,12 +355,11 @@ method_name_from_physname (const char *physname)
|
||||
char *
|
||||
cp_func_name (const char *full_name)
|
||||
{
|
||||
void *storage;
|
||||
char *ret;
|
||||
struct demangle_component *ret_comp;
|
||||
int done;
|
||||
|
||||
ret_comp = cp_demangled_name_to_comp (full_name, &storage, NULL);
|
||||
ret_comp = cp_demangled_name_to_comp (full_name, NULL);
|
||||
if (!ret_comp)
|
||||
return NULL;
|
||||
|
||||
@ -336,7 +369,6 @@ cp_func_name (const char *full_name)
|
||||
if (ret_comp != NULL)
|
||||
ret = cp_comp_to_string (ret_comp, 10);
|
||||
|
||||
xfree (storage);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -349,13 +381,12 @@ remove_params (const char *demangled_name)
|
||||
{
|
||||
int done = 0;
|
||||
struct demangle_component *ret_comp;
|
||||
void *storage;
|
||||
char *ret = NULL;
|
||||
|
||||
if (demangled_name == NULL)
|
||||
return NULL;
|
||||
|
||||
ret_comp = cp_demangled_name_to_comp (demangled_name, &storage, NULL);
|
||||
ret_comp = cp_demangled_name_to_comp (demangled_name, NULL);
|
||||
if (ret_comp == NULL)
|
||||
return NULL;
|
||||
|
||||
@ -381,7 +412,6 @@ remove_params (const char *demangled_name)
|
||||
if (ret_comp->type == DEMANGLE_COMPONENT_TYPED_NAME)
|
||||
ret = cp_comp_to_string (d_left (ret_comp), 10);
|
||||
|
||||
xfree (storage);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -511,7 +541,7 @@ cp_find_first_component_aux (const char *name, int permissive)
|
||||
&& strncmp (name + index, "operator", LENGTH_OF_OPERATOR) == 0)
|
||||
{
|
||||
index += LENGTH_OF_OPERATOR;
|
||||
while (isspace(name[index]))
|
||||
while (ISSPACE(name[index]))
|
||||
++index;
|
||||
switch (name[index])
|
||||
{
|
||||
|
@ -114,10 +114,10 @@ extern void cp_check_possible_namespace_symbols (const char *name,
|
||||
|
||||
struct type *cp_lookup_transparent_type (const char *name);
|
||||
|
||||
/* Functions from cp-names.y. */
|
||||
/* Functions from cp-name-parser.y. */
|
||||
|
||||
extern struct demangle_component *cp_demangled_name_to_comp
|
||||
(const char *demangled_name, void **memory_p, const char **errmsg);
|
||||
(const char *demangled_name, const char **errmsg);
|
||||
|
||||
extern char *cp_comp_to_string (struct demangle_component *result,
|
||||
int estimated_len);
|
||||
|
Loading…
Reference in New Issue
Block a user