Index: gdb/cp-support.c |
diff --git a/gdb/cp-support.c b/gdb/cp-support.c |
index bafdb86cf7a9fdebe47b625b3b675ad912eb6e08..6b85ecb2f87a585f55cbdc301cf9d1594c1af576 100644 |
--- a/gdb/cp-support.c |
+++ b/gdb/cp-support.c |
@@ -1,5 +1,5 @@ |
/* Helper routines for C++ support in GDB. |
- Copyright (C) 2002-2005, 2007-2012 Free Software Foundation, Inc. |
+ Copyright (C) 2002-2013 Free Software Foundation, Inc. |
Contributed by MontaVista Software. |
@@ -20,7 +20,7 @@ |
#include "defs.h" |
#include "cp-support.h" |
-#include "gdb_string.h" |
+#include <string.h> |
#include "demangle.h" |
#include "gdb_assert.h" |
#include "gdbcmd.h" |
@@ -38,8 +38,6 @@ |
#include "safe-ctype.h" |
-#include "psymtab.h" |
- |
#define d_left(dc) (dc)->u.s_binary.left |
#define d_right(dc) (dc)->u.s_binary.right |
@@ -81,7 +79,9 @@ static const char * const ignore_typedefs[] = |
static void |
replace_typedefs (struct demangle_parse_info *info, |
- struct demangle_component *ret_comp); |
+ struct demangle_component *ret_comp, |
+ canonicalization_ftype *finder, |
+ void *data); |
/* A convenience function to copy STRING into OBSTACK, returning a pointer |
to the newly allocated string and saving the number of bytes saved in LEN. |
@@ -152,7 +152,9 @@ cp_already_canonical (const char *string) |
static int |
inspect_type (struct demangle_parse_info *info, |
- struct demangle_component *ret_comp) |
+ struct demangle_component *ret_comp, |
+ canonicalization_ftype *finder, |
+ void *data) |
{ |
int i; |
char *name; |
@@ -182,8 +184,23 @@ inspect_type (struct demangle_parse_info *info, |
{ |
struct type *otype = SYMBOL_TYPE (sym); |
- /* If the type is a typedef, replace it. */ |
- if (TYPE_CODE (otype) == TYPE_CODE_TYPEDEF) |
+ if (finder != NULL) |
+ { |
+ const char *new_name = (*finder) (otype, data); |
+ |
+ if (new_name != NULL) |
+ { |
+ ret_comp->u.s_name.s = new_name; |
+ ret_comp->u.s_name.len = strlen (new_name); |
+ return 1; |
+ } |
+ |
+ return 0; |
+ } |
+ |
+ /* If the type is a typedef or namespace alias, replace it. */ |
+ if (TYPE_CODE (otype) == TYPE_CODE_TYPEDEF |
+ || TYPE_CODE (otype) == TYPE_CODE_NAMESPACE) |
{ |
long len; |
int is_anon; |
@@ -194,6 +211,13 @@ inspect_type (struct demangle_parse_info *info, |
/* Get the real type of the typedef. */ |
type = check_typedef (otype); |
+ /* If the symbol is a namespace and its type name is no different |
+ than the name we looked up, this symbol is not a namespace |
+ alias and does not need to be substituted. */ |
+ if (TYPE_CODE (otype) == TYPE_CODE_NAMESPACE |
+ && strcmp (TYPE_NAME (type), name) == 0) |
+ return 0; |
+ |
is_anon = (TYPE_TAG_NAME (type) == NULL |
&& (TYPE_CODE (type) == TYPE_CODE_ENUM |
|| TYPE_CODE (type) == TYPE_CODE_STRUCT |
@@ -249,7 +273,7 @@ inspect_type (struct demangle_parse_info *info, |
if the type is anonymous (that would lead to infinite |
looping). */ |
if (!is_anon) |
- replace_typedefs (info, ret_comp); |
+ replace_typedefs (info, ret_comp, finder, data); |
} |
else |
{ |
@@ -286,7 +310,9 @@ inspect_type (struct demangle_parse_info *info, |
static void |
replace_typedefs_qualified_name (struct demangle_parse_info *info, |
- struct demangle_component *ret_comp) |
+ struct demangle_component *ret_comp, |
+ canonicalization_ftype *finder, |
+ void *data) |
{ |
long len; |
char *name; |
@@ -310,7 +336,7 @@ replace_typedefs_qualified_name (struct demangle_parse_info *info, |
new.type = DEMANGLE_COMPONENT_NAME; |
new.u.s_name.s = name; |
new.u.s_name.len = len; |
- if (inspect_type (info, &new)) |
+ if (inspect_type (info, &new, finder, data)) |
{ |
char *n, *s; |
long slen; |
@@ -344,7 +370,7 @@ replace_typedefs_qualified_name (struct demangle_parse_info *info, |
/* The current node is not a name, so simply replace any |
typedefs in it. Then print it to the stream to continue |
checking for more typedefs in the tree. */ |
- replace_typedefs (info, d_left (comp)); |
+ replace_typedefs (info, d_left (comp), finder, data); |
name = cp_comp_to_string (d_left (comp), 100); |
if (name == NULL) |
{ |
@@ -355,6 +381,7 @@ replace_typedefs_qualified_name (struct demangle_parse_info *info, |
fputs_unfiltered (name, buf); |
xfree (name); |
} |
+ |
ui_file_write (buf, "::", 2); |
comp = d_right (comp); |
} |
@@ -374,10 +401,10 @@ replace_typedefs_qualified_name (struct demangle_parse_info *info, |
ret_comp->type = DEMANGLE_COMPONENT_NAME; |
ret_comp->u.s_name.s = name; |
ret_comp->u.s_name.len = len; |
- inspect_type (info, ret_comp); |
+ inspect_type (info, ret_comp, finder, data); |
} |
else |
- replace_typedefs (info, comp); |
+ replace_typedefs (info, comp, finder, data); |
ui_file_delete (buf); |
} |
@@ -405,10 +432,48 @@ check_cv_qualifiers (struct demangle_component *ret_comp) |
static void |
replace_typedefs (struct demangle_parse_info *info, |
- struct demangle_component *ret_comp) |
+ struct demangle_component *ret_comp, |
+ canonicalization_ftype *finder, |
+ void *data) |
{ |
if (ret_comp) |
{ |
+ if (finder != NULL |
+ && (ret_comp->type == DEMANGLE_COMPONENT_NAME |
+ || ret_comp->type == DEMANGLE_COMPONENT_QUAL_NAME |
+ || ret_comp->type == DEMANGLE_COMPONENT_TEMPLATE |
+ || ret_comp->type == DEMANGLE_COMPONENT_BUILTIN_TYPE)) |
+ { |
+ char *local_name = cp_comp_to_string (ret_comp, 10); |
+ |
+ if (local_name != NULL) |
+ { |
+ struct symbol *sym; |
+ volatile struct gdb_exception except; |
+ |
+ sym = NULL; |
+ TRY_CATCH (except, RETURN_MASK_ALL) |
+ { |
+ sym = lookup_symbol (local_name, 0, VAR_DOMAIN, 0); |
+ } |
+ xfree (local_name); |
+ |
+ if (except.reason >= 0 && sym != NULL) |
+ { |
+ struct type *otype = SYMBOL_TYPE (sym); |
+ const char *new_name = (*finder) (otype, data); |
+ |
+ if (new_name != NULL) |
+ { |
+ ret_comp->type = DEMANGLE_COMPONENT_NAME; |
+ ret_comp->u.s_name.s = new_name; |
+ ret_comp->u.s_name.len = strlen (new_name); |
+ return; |
+ } |
+ } |
+ } |
+ } |
+ |
switch (ret_comp->type) |
{ |
case DEMANGLE_COMPONENT_ARGLIST: |
@@ -419,23 +484,23 @@ replace_typedefs (struct demangle_parse_info *info, |
case DEMANGLE_COMPONENT_TEMPLATE: |
case DEMANGLE_COMPONENT_TEMPLATE_ARGLIST: |
case DEMANGLE_COMPONENT_TYPED_NAME: |
- replace_typedefs (info, d_left (ret_comp)); |
- replace_typedefs (info, d_right (ret_comp)); |
+ replace_typedefs (info, d_left (ret_comp), finder, data); |
+ replace_typedefs (info, d_right (ret_comp), finder, data); |
break; |
case DEMANGLE_COMPONENT_NAME: |
- inspect_type (info, ret_comp); |
+ inspect_type (info, ret_comp, finder, data); |
break; |
case DEMANGLE_COMPONENT_QUAL_NAME: |
- replace_typedefs_qualified_name (info, ret_comp); |
+ replace_typedefs_qualified_name (info, ret_comp, finder, data); |
break; |
case DEMANGLE_COMPONENT_LOCAL_NAME: |
case DEMANGLE_COMPONENT_CTOR: |
case DEMANGLE_COMPONENT_ARRAY_TYPE: |
case DEMANGLE_COMPONENT_PTRMEM_TYPE: |
- replace_typedefs (info, d_right (ret_comp)); |
+ replace_typedefs (info, d_right (ret_comp), finder, data); |
break; |
case DEMANGLE_COMPONENT_CONST: |
@@ -446,7 +511,7 @@ replace_typedefs (struct demangle_parse_info *info, |
case DEMANGLE_COMPONENT_RESTRICT_THIS: |
case DEMANGLE_COMPONENT_POINTER: |
case DEMANGLE_COMPONENT_REFERENCE: |
- replace_typedefs (info, d_left (ret_comp)); |
+ replace_typedefs (info, d_left (ret_comp), finder, data); |
break; |
default: |
@@ -458,10 +523,13 @@ replace_typedefs (struct demangle_parse_info *info, |
/* Parse STRING and convert it to canonical form, resolving any typedefs. |
If parsing fails, or if STRING is already canonical, return NULL. |
Otherwise return the canonical form. The return value is allocated via |
- xmalloc. */ |
+ xmalloc. If FINDER is not NULL, then type components are passed to |
+ FINDER to be looked up. DATA is passed verbatim to FINDER. */ |
char * |
-cp_canonicalize_string_no_typedefs (const char *string) |
+cp_canonicalize_string_full (const char *string, |
+ canonicalization_ftype *finder, |
+ void *data) |
{ |
char *ret; |
unsigned int estimated_len; |
@@ -473,7 +541,7 @@ cp_canonicalize_string_no_typedefs (const char *string) |
if (info != NULL) |
{ |
/* Replace all the typedefs in the tree. */ |
- replace_typedefs (info, info->tree); |
+ replace_typedefs (info, info->tree, finder, data); |
/* Convert the tree back into a string. */ |
ret = cp_comp_to_string (info->tree, estimated_len); |
@@ -494,6 +562,15 @@ cp_canonicalize_string_no_typedefs (const char *string) |
return ret; |
} |
+/* Like cp_canonicalize_string_full, but always passes NULL for |
+ FINDER. */ |
+ |
+char * |
+cp_canonicalize_string_no_typedefs (const char *string) |
+{ |
+ return cp_canonicalize_string_full (string, NULL, NULL); |
+} |
+ |
/* 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. */ |
@@ -564,7 +641,7 @@ mangled_name_to_comp (const char *mangled_name, int options, |
/* If it doesn't, or if that failed, then try to demangle the |
name. */ |
- demangled_name = cplus_demangle (mangled_name, options); |
+ demangled_name = gdb_demangle (mangled_name, options); |
if (demangled_name == NULL) |
return NULL; |
@@ -1405,6 +1482,14 @@ cp_lookup_rtti_type (const char *name, struct block *block) |
return rtti_type; |
} |
+/* A wrapper for bfd_demangle. */ |
+ |
+char * |
+gdb_demangle (const char *name, int options) |
+{ |
+ return bfd_demangle (NULL, name, options); |
+} |
+ |
/* Don't allow just "maintenance cplus". */ |
static void |