* cp-support.c (inspect_type,
authorTom Tromey <tromey@redhat.com>
Mon, 12 Nov 2012 17:30:06 +0000 (17:30 +0000)
committerTom Tromey <tromey@redhat.com>
Mon, 12 Nov 2012 17:30:06 +0000 (17:30 +0000)
replace_typedefs_qualified_name, replace_typedefs): Add
finder, data arguments.  Call as needed.
(cp_canonicalize_string_full): New function.
(cp_canonicalize_string_no_typedefs): Rewrite.
* cp-support.h (canonicalization_ftype): New typedef.
(cp_canonicalize_string_full): Declare.

gdb/ChangeLog
gdb/cp-support.c
gdb/cp-support.h

index 2b0af1af0d7a3373cc0fad04b58436acdc236854..78cf6c6d4226c0903ea1198c24c39d04e701d9f3 100644 (file)
@@ -1,3 +1,13 @@
+2012-11-12  Tom Tromey  <tromey@redhat.com>
+
+       * cp-support.c (inspect_type,
+       replace_typedefs_qualified_name, replace_typedefs): Add
+       finder, data arguments.  Call as needed.
+       (cp_canonicalize_string_full): New function.
+       (cp_canonicalize_string_no_typedefs): Rewrite.
+       * cp-support.h (canonicalization_ftype): New typedef.
+       (cp_canonicalize_string_full): Declare.
+
 2012-11-12  Tom Tromey  <tromey@redhat.com>
 
        * NEWS: Update.
index bafdb86cf7a9fdebe47b625b3b675ad912eb6e08..97524ed579f36b094dd089dc6ba1fa1d0bf798bd 100644 (file)
@@ -81,7 +81,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 +154,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,6 +186,20 @@ inspect_type (struct demangle_parse_info *info,
     {
       struct type *otype = SYMBOL_TYPE (sym);
 
+      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, replace it.  */
       if (TYPE_CODE (otype) == TYPE_CODE_TYPEDEF)
        {
@@ -249,7 +267,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 +304,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 +330,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 +364,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 +375,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 +395,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 +426,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 +478,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 +505,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 +517,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 +535,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 +556,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.  */
index 0d2b5131b549eae2e006096d198b4fdd0a495568..86ccd5ecea1d84dd01b823786f9aae7e431b9a62 100644 (file)
@@ -149,6 +149,12 @@ extern char *cp_canonicalize_string (const char *string);
 
 extern char *cp_canonicalize_string_no_typedefs (const char *string);
 
+typedef const char *(canonicalization_ftype) (struct type *, void *);
+
+extern char *cp_canonicalize_string_full (const char *string,
+                                         canonicalization_ftype *finder,
+                                         void *data);
+
 extern char *cp_class_name_from_physname (const char *physname);
 
 extern char *method_name_from_physname (const char *physname);