Some improvements to g++ debugging.
authorPer Bothner <per@bothner.com>
Thu, 19 Mar 1992 00:05:35 +0000 (00:05 +0000)
committerPer Bothner <per@bothner.com>
Thu, 19 Mar 1992 00:05:35 +0000 (00:05 +0000)
* symtab.c (list_symbols): demangle before pattern matching.
* symtab.c:  Other fixes to improve handing of operators.
* valprint.c (type_print_base):  Fix test for constructor.
* values.c (value_static_field):  Allow evaluation of
CLASS::METHOD, returning a function pointer.

gdb/ChangeLog
gdb/symtab.c
gdb/valprint.c
gdb/values.c

index ac9878909401ededbad8e3c8cc285c5c6a9f9f1b..177d7a134cad57165d502da5820033071ae1b978 100644 (file)
@@ -1,3 +1,12 @@
+Wed Mar 18 15:51:15 1992  Per Bothner  (bothner@cygnus.com)
+
+       Some improvements to g++ debugging.
+       * symtab.c (list_symbols): demangle before pattern matching.
+       * symtab.c:  Other fixes to improve handing of operators.
+       * valprint.c (type_print_base):  Fix test for constructor.
+       * values.c (value_static_field):  Allow evaluation of
+       CLASS::METHOD, returning a function pointer.
+
 Wed Mar 18 08:39:52 1992  Fred Fish  (fnf@cygnus.com)
 
        * Makefile.in (VERSION):  Roll  4.4.6.
index 55f3899d95c06f18b7fab2921b1f090de814aaef..9814774b116d5e1650fc5df3b8f3c748d5eb6924 100644 (file)
@@ -37,10 +37,11 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
 #include <fcntl.h>
 #include <string.h>
 #include <sys/stat.h>
+#include <ctype.h>
 
 /* Prototypes for local functions */
 
-static int
+extern int
 find_methods PARAMS ((struct type *, char *, char **, struct symbol **));
 
 static void
@@ -1260,14 +1261,24 @@ operator_chars (p, end)
 
   /* Don't get faked out by `operator' being part of a longer
      identifier.  */
-  if ((*p >= 'A' && *p <= 'Z') || (*p >= 'a' && *p <= 'z')
-      || *p == '_' || *p == '$' || *p == '\0')
+  if (isalpha(*p) || *p == '_' || *p == '$' || *p == '\0')
     return *end;
 
   /* Allow some whitespace between `operator' and the operator symbol.  */
   while (*p == ' ' || *p == '\t')
     p++;
 
+  /* Recognize 'operator TYPENAME'. */
+
+  if (isalpha(*p) || *p == '_' || *p == '$')
+    {
+      register char *q = p+1;
+      while (isalnum(*q) || *q == '_' || *q == '$')
+       q++;
+      *end = q;
+      return p;
+    }
+
   switch (*p)
     {
     case '!':
@@ -1328,7 +1339,7 @@ operator_chars (p, end)
  * physnames = (char **) alloca (TYPE_NFN_FIELDS_TOTAL (t) * sizeof(char*));
  */
 
-static int
+int
 find_methods (t, name, physnames, sym_arr)
      struct type *t;
      char *name;
@@ -1392,6 +1403,12 @@ find_methods (t, name, physnames, sym_arr)
                                             (int *) NULL,
                                             (struct symtab **) NULL);
                if (sym_arr[i1]) i1++;
+               else
+                 {
+                   fputs_filtered("(Cannot find method ", stdout);
+                   fputs_demangled(phys_name, stdout, 0);
+                   fputs_filtered(" - possibly inlined.)\n", stdout);
+                 }
              }
        }
     }
@@ -1525,18 +1542,22 @@ decode_line_1 (argptr, funfirstline, default_symtab, default_line)
              while (*p && *p != ' ' && *p != '\t' && *p != ',' && *p !=':') p++;
              q = operator_chars (*argptr, &q1);
 
-             copy = (char *) alloca (p - *argptr + 1 + (q1 - q));
              if (q1 - q)
                {
-                 copy[0] = 'o';
-                 copy[1] = 'p';
-                 copy[2] = CPLUS_MARKER;
-                 bcopy (q, copy + 3, q1 - q);
-                 copy[3 + (q1 - q)] = '\0';
+                 char *opname;
+                 char *tmp = alloca (q1 - q + 1);
+                 memcpy (tmp, q, q1 - q);
+                 tmp[q1 - q] = '\0';
+                 opname = cplus_mangle_opname (tmp, 1);
+                 if (opname == NULL)
+                   error ("No mangling for \"%s\"", tmp);
+                 copy = (char*) alloca (3 + strlen(opname));
+                 sprintf (copy, "__%s", opname);
                  p = q1;
                }
              else
                {
+                 copy = (char *) alloca (p - *argptr + 1 + (q1 - q));
                  bcopy (*argptr, copy, p - *argptr);
                  copy[p - *argptr] = '\0';
                }
@@ -1709,6 +1730,7 @@ decode_line_1 (argptr, funfirstline, default_symtab, default_line)
 
   /* Arg token is not digits => try it as a variable name
      Find the next token (everything up to end or next whitespace).  */
+
   p = *argptr;
   while (*p && *p != ' ' && *p != '\t' && *p != ',') p++;
   copy = (char *) alloca (p - *argptr + 1);
@@ -2027,6 +2049,21 @@ sources_info ()
   printf_filtered ("\n");
 }
 
+static int
+name_match(name)
+     char *name;
+{
+  char *demangled = cplus_demangle(name, -1);
+  if (demangled != NULL)
+    {
+      int cond = re_exec (demangled);
+      free (demangled);
+      return cond;
+    }
+  return re_exec(name);
+}
+#define NAME_MATCH(NAME) name_match(NAME)
+
 /* List all symbols (if REGEXP is 0) or all symbols matching REGEXP.
    If CLASS is zero, list all symbols except functions and type names.
    If CLASS is 1, list only functions.
@@ -2052,7 +2089,8 @@ list_symbols (regexp, class, bpt)
   struct partial_symbol *psym;
   struct objfile *objfile;
   struct minimal_symbol *msymbol;
-  char *val;
+  char *val, *q2;
+/*  char *mangled;*/
   static char *classnames[]
     = {"variable", "function", "type", "method"};
   int found_in_file = 0;
@@ -2064,9 +2102,42 @@ list_symbols (regexp, class, bpt)
   enum minimal_symbol_type ourtype = types[class];
   enum minimal_symbol_type ourtype2 = types2[class];
 
+
   if (regexp)
-    if (0 != (val = re_comp (regexp)))
-      error ("Invalid regexp (%s): %s", val, regexp);
+    {
+      /* Make sure spacing is right for C++ operators.
+        This is just a courtesy to make the matching less sensitive
+        to how many spaces the user leaves between 'operator'
+        and <TYPENAME> or <OPERATOR>. */
+      char *opend;
+      char *opname = operator_chars (regexp, &opend);
+      if (*opname)
+       {
+          int fix = -1; /* -1 means ok; otherwise number of spaces needed. */
+         if (isalpha(*opname) || *opname == '_' || *opname == '$')
+           {
+             /* There should 1 space between 'operator' and 'TYPENAME'. */
+             if (opname[-1] != ' ' || opname[-2] == ' ')
+               fix = 1;
+           }
+         else
+           {
+             /* There should 0 spaces between 'operator' and 'OPERATOR'. */
+             if (opname[-1] == ' ')
+               fix = 0;
+           }
+         /* If wrong number of spaces, fix it. */
+         if (fix >= 0)
+           {
+             char *tmp = (char*) alloca(opend-opname+10);
+             sprintf(tmp, "operator%.*s%s", fix, " ", opname);
+             regexp = tmp;
+           }
+        }
+      
+      if (0 != (val = re_comp (regexp)))
+       error ("Invalid regexp (%s): %s", val, regexp);
+    }
 
   /* Search through the partial symtabs *first* for all symbols
      matching the regexp.  That way we don't have to reproduce all of
@@ -2104,10 +2175,10 @@ list_symbols (regexp, class, bpt)
              else
                {
                  QUIT;
-                 
+
                  /* If it would match (logic taken from loop below)
                     load the file and go on to the next one */
-                 if ((regexp == 0 || re_exec (SYMBOL_NAME (psym)))
+                 if ((regexp == 0 || NAME_MATCH (SYMBOL_NAME (psym)))
                      && ((class == 0 && SYMBOL_CLASS (psym) != LOC_TYPEDEF
                           && SYMBOL_CLASS (psym) != LOC_BLOCK)
                          || (class == 1 && SYMBOL_CLASS (psym) == LOC_BLOCK)
@@ -2138,7 +2209,7 @@ list_symbols (regexp, class, bpt)
            {
              if (msymbol -> type == ourtype || msymbol -> type == ourtype2)
                {
-                 if (regexp == 0 || re_exec (msymbol -> name))
+                 if (regexp == 0 || NAME_MATCH (msymbol -> name))
                    {
                      if (0 == find_pc_symtab (msymbol -> address))
                        {
@@ -2181,7 +2252,7 @@ list_symbols (regexp, class, bpt)
                  {
                    QUIT;
                    sym = BLOCK_SYM (b, j);
-                   if ((regexp == 0 || re_exec (SYMBOL_NAME (sym)))
+                   if ((regexp == 0 || NAME_MATCH (SYMBOL_NAME (sym)))
                        && ((class == 0 && SYMBOL_CLASS (sym) != LOC_TYPEDEF
                             && SYMBOL_CLASS (sym) != LOC_BLOCK)
                            || (class == 1 && SYMBOL_CLASS (sym) == LOC_BLOCK)
@@ -2251,7 +2322,7 @@ list_symbols (regexp, class, bpt)
            {
              if (msymbol -> type == ourtype || msymbol -> type == ourtype2)
                {
-                 if (regexp == 0 || re_exec (msymbol -> name))
+                 if (regexp == 0 || NAME_MATCH (msymbol -> name))
                    {
                      /* Functions:  Look up by address. */
                      if (class != 1 &&
index b031e16e9ca293d06c79f660639ff5ebf6ecf269..8b8c40523b6cfcd43731e8cb549b6514f07e7d9d 100644 (file)
@@ -17,10 +17,10 @@ You should have received a copy of the GNU General Public License
 along with this program; if not, write to the Free Software
 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
 
-#include <stdio.h>
-#include <string.h>
 #include "defs.h"
+#include <string.h>
 #include "symtab.h"
+#include "gdbtypes.h"
 #include "value.h"
 #include "gdbcore.h"
 #include "gdbcmd.h"
@@ -29,11 +29,59 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
 #include "language.h"
 
 #include <errno.h>
+
+/* Prototypes for local functions */
+
+static void
+print_string PARAMS ((FILE *, char *, unsigned int, int));
+
+static void
+show_print PARAMS ((char *, int));
+
+static void
+set_print PARAMS ((char *, int));
+
+static void
+set_radix PARAMS ((char *, int, struct cmd_list_element *));
+
+static void
+set_output_radix PARAMS ((char *, int, struct cmd_list_element *));
+
+static void
+type_print_base PARAMS ((struct type *, FILE *, int, int));
+
+static void
+type_print_varspec_suffix PARAMS ((struct type *, FILE *, int, int));
+
+static void
+type_print_varspec_prefix PARAMS ((struct type *, FILE *, int, int));
+
+static void
+type_print_derivation_info PARAMS ((FILE *, struct type *));
+
+static void
+type_print_method_args PARAMS ((struct type **, char *, char *, int, FILE *));
+
+static void
+cplus_val_print PARAMS ((struct type *, char *, FILE *, int, int,
+                        enum val_prettyprint, struct type **));
+
+static void
+val_print_fields PARAMS ((struct type *, char *, FILE *, int, int,
+                         enum val_prettyprint, struct type **));
+
+static int
+is_vtbl_member PARAMS ((struct type *));
+
+static int
+is_vtbl_ptr_type PARAMS ((struct type *));
+
+static void
+print_hex_chars PARAMS ((FILE *, unsigned char *, unsigned));
+
 extern int sys_nerr;
 extern char *sys_errlist[];
 
-extern void print_scalar_formatted();  /* printcmd.c */
-extern void print_address_demangle();  /* printcmd.c */
 extern int demangle;   /* whether to print C++ syms raw or source-form */
 
 /* Maximum number of chars to print for a string pointer value
@@ -41,11 +89,6 @@ extern int demangle; /* whether to print C++ syms raw or source-form */
 
 static unsigned int print_max;
 
-static void type_print_varspec_suffix ();
-static void type_print_varspec_prefix ();
-static void type_print_base ();
-static void type_print_method_args ();
-
 /* Default input and output radixes, and output format letter.  */
 
 unsigned input_radix = 10;
@@ -74,14 +117,13 @@ int objectprint;   /* Controls looking up an object's derived type
 
 struct obstack dont_print_obstack;
 
-static void cplus_val_print ();
 \f
 /* Print the character string STRING, printing at most LENGTH characters.
    Printing stops early if the number hits print_max; repeat counts
    are printed as appropriate.  Print ellipses at the end if we
    had to stop before printing LENGTH characters, or if FORCE_ELLIPSES.  */
 
-void
+static void
 print_string (stream, string, length, force_ellipses)
      FILE *stream;
      char *string;
@@ -286,7 +328,7 @@ int
 value_print (val, stream, format, pretty)
      value val;
      FILE *stream;
-     char format;
+     int format;
      enum val_prettyprint pretty;
 {
   register unsigned int i, n, typelen;
@@ -439,12 +481,13 @@ is_vtbl_member(type)
 
    DONT_PRINT is an array of baseclass types that we
    should not print, or zero if called from top level.  */
+
 static void
 val_print_fields (type, valaddr, stream, format, recurse, pretty, dont_print)
      struct type *type;
      char *valaddr;
      FILE *stream;
-     char format;
+     int format;
      int recurse;
      enum val_prettyprint pretty;
      struct type **dont_print;
@@ -547,7 +590,7 @@ cplus_val_print (type, valaddr, stream, format, recurse, pretty, dont_print)
      struct type *type;
      char *valaddr;
      FILE *stream;
-     char format;
+     int format;
      int recurse;
      enum val_prettyprint pretty;
      struct type **dont_print;
@@ -634,13 +677,12 @@ cplus_val_print (type, valaddr, stream, format, recurse, pretty, dont_print)
    The PRETTY parameter controls prettyprinting.  */
 
 int
-val_print (type, valaddr, address, stream, format,
-          deref_ref, recurse, pretty)
+val_print (type, valaddr, address, stream, format, deref_ref, recurse, pretty)
      struct type *type;
      char *valaddr;
      CORE_ADDR address;
      FILE *stream;
-     char format;
+     int format;
      int deref_ref;
      int recurse;
      enum val_prettyprint pretty;
@@ -927,10 +969,17 @@ val_print (type, valaddr, address, stream, format,
                     slower if print_max is set high, e.g. if you set
                     print_max to 1000, not only will it take a long
                     time to fetch short strings, but if you are near
-                    the end of the address space, it might not work.
-                    FIXME.  */
+                    the end of the address space, it might not work. */
                  QUIT;
                  errcode = target_read_memory (addr, string, print_max);
+                 if (errcode != 0)
+                   {
+                     /* Try reading just one character.  If that succeeds,
+                        assume we hit the end of the address space, but
+                        the initial part of the string is probably safe. */
+                     char x[1];
+                     errcode = target_read_memory (addr, x, 1);
+                   }
                  if (errcode != 0)
                      force_ellipses = 0;
                  else 
@@ -974,13 +1023,12 @@ val_print (type, valaddr, address, stream, format,
            {
              CORE_ADDR vt_address = unpack_pointer (type, valaddr);
 
-             int vt_index = find_pc_misc_function (vt_address);
-             if (vt_index >= 0
-                 && vt_address == misc_function_vector[vt_index].address)
+             struct minimal_symbol *msymbol =
+               lookup_minimal_symbol_by_pc (vt_address);
+             if ((msymbol != NULL) && (vt_address == msymbol -> address))
                {
                  fputs_filtered (" <", stream);
-                 fputs_demangled (misc_function_vector[vt_index].name,
-                                  stream, 1);
+                 fputs_demangled (msymbol -> name, stream, 1);
                  fputs_filtered (">", stream);
                }
              if (vtblprint)
@@ -1698,7 +1746,7 @@ type_print_base (type, stream, show, level)
              struct fn_field *f = TYPE_FN_FIELDLIST1 (type, i);
              int j, len2 = TYPE_FN_FIELDLIST_LENGTH (type, i);
              char *method_name = TYPE_FN_FIELDLIST_NAME (type, i);
-             int is_constructor = strcmp(method_name, TYPE_NAME (type)) == 0;
+             int is_constructor = name && strcmp(method_name, name) == 0;
              for (j = 0; j < len2; j++)
                {
                  QUIT;
@@ -1723,7 +1771,6 @@ type_print_base (type, stream, show, level)
                  if (TYPE_FN_FIELD_STUB (f, j))
                    {
                      /* Build something we can demangle.  */
-                     char *strchr (), *gdb_mangle_name (), *cplus_demangle ();
                      char *mangled_name = gdb_mangle_name (type, i, j);
                      char *demangled_name = cplus_demangle (mangled_name, 1);
                      if (demangled_name == 0)
@@ -2011,7 +2058,7 @@ _initialize_valprint ()
                  "Set default input and output number radix.",
                  &setlist);
   add_show_from_set (c, &showlist);
-  c->function = set_radix;
+  c->function.sfunc = set_radix;
 
   /* Give people the defaults which they are used to.  */
   prettyprint = 0;
index 34875ca0f20a3d6247b2f7615477d9bf0b9a4201..bb5fa68c29d48aee69eee0c831838071c6253752 100644 (file)
@@ -1124,6 +1124,8 @@ value_static_field (type, fieldname, fieldno)
 
   if (fieldno < 0)
     {
+      char **physnames;
+      struct symbol **sym_arr;
       /* Look for static field.  */
       int i;
       for (i = TYPE_NFIELDS (type) - 1; i >= TYPE_N_BASECLASSES (type); i--)
@@ -1144,14 +1146,24 @@ value_static_field (type, fieldname, fieldno)
            return v;
        }
 
-      if (destructor_name_p (fieldname, type))
-       error ("Cannot get value of destructor");
-
-      for (i = TYPE_NFN_FIELDS (type) - 1; i >= 0; i--)
+      sym_arr = (struct symbol **)
+         alloca(TYPE_NFN_FIELDS_TOTAL (type) * sizeof(struct symbol*));
+      physnames = (char **)
+         alloca (TYPE_NFN_FIELDS_TOTAL (type) * sizeof(char*));
+      /* Note: This does duplicate work, since find_methods does a
+        recursive search *and* so does value_static_field.  FIXME */
+      i = find_methods (type, fieldname, physnames, sym_arr);
+      if (i > 1)
+       error ("Cannot get value of overloaded method \"%s\"", fieldname);
+      else if (i)
        {
-         if (! strcmp (TYPE_FN_FIELDLIST_NAME (type, i), fieldname))
-           error ("Cannot get value of method \"%s\"", fieldname);
-       }
+         struct symbol *sym = sym_arr[0];
+         value val = read_var_value (sym, (FRAME) 0);
+         if (val == 0)
+            error ("Address of method \"%s\" is unknown (possibly inlined).",
+                   fieldname);
+         return val;
+        }
       error("there is no field named %s", fieldname);
     }
 
@@ -1161,8 +1173,7 @@ value_static_field (type, fieldname, fieldno)
   if (! sym) error ("Internal error: could not find physical static variable named %s", phys_name);
 
   type = TYPE_FIELD_TYPE (type, fieldno);
-  v = value_at (type, (CORE_ADDR)SYMBOL_BLOCK_VALUE (sym));
-  return v;
+  return value_at (type, (CORE_ADDR)SYMBOL_BLOCK_VALUE (sym));
 }
 
 /* Compute the address of the baseclass which is