Fix things pointed up by Fred Fish's test suite; see ChangeLog.
authorJohn Gilmore <gnu@cygnus>
Thu, 5 Dec 1991 11:56:20 +0000 (11:56 +0000)
committerJohn Gilmore <gnu@cygnus>
Thu, 5 Dec 1991 11:56:20 +0000 (11:56 +0000)
gdb/ChangeLog
gdb/buildsym.c
gdb/c-exp.y
gdb/inflow.c
gdb/valops.c
gdb/valprint.c

index a1cabeb13da633b81f41f839240ff597b93ff447..18139592826a0e264717e9f6a50f70b73a99cffd 100644 (file)
@@ -1,3 +1,32 @@
+Thu Dec  5 03:34:21 1991  John Gilmore  (gnu at cygnus.com)
+
+       * inflow.c:  Remember whether GDB has a terminal.  Avoid switching
+       terminals back and forth if we don't have one.
+
+       * c-exp.y (parse_number):  Zero is not an unsigned int constant!
+       * dbxread.c (read_dbx_symtab):  Enum type numbers can be in (1,2) form.
+
+       Improve type parsing.
+       * buildsym.c (define_symbol, read_range_type): Add
+       long_kludge_name that passes the names of range types being
+       defined, down to where we must choose between 'int' and 'long'
+       variants.  This fails on Sun C anyway since the compiler itself is
+       confused between int and long.
+       (read_array_type, cleanup_undefined_types):  Correct the size of
+       array type whose element-type size isn't immediately known.
+
+       Early preparation to blow away many builtin types, building them
+       on the fly as needed.  Don't compare types to builtin types with
+       ==; examine the relevant fields instead.
+       * coffread.c (process_coff_symbol: C_ARG, C_REGPARM):  Avoid ==.
+       * buildsym.c (define_symbol, case 'p'):  Avoid ==.
+       * valops.c (value_arg_coerce):  Avoid ==.  Don't assume host and
+       target types are the same.
+       * valprint.c (val_print):  I finally understand arrays, remove FIXME.
+
+       * symmisc.c (printpsyms_command):  Reduce redundancy, and put all
+       addresses in GDB itself into parens for easy cleanup and diffing.
+
 Wed Dec  4 21:05:30 1991  Fred Fish  (fnf at cygnus.com)
 
        * dwarfread (enum_type):  Arrange for the order of enumeration
index 86e726f858f133d2cf548d29499f123c2abe244d..4f1fc24f313736b1984677725ef746e481c22994 100644 (file)
@@ -1,5 +1,5 @@
 /* Build symbol tables in GDB's internal format.
-   Copyright (C) 1986-1991 Free Software Foundation, Inc.
+   Copyright 1986, 1987, 1988, 1989, 1990, 1991 Free Software Foundation, Inc.
 
 This file is part of GDB.
 
@@ -66,6 +66,14 @@ static const char vb_name[] =   { '_','v','b',CPLUS_MARKER,'\0' };
 #define BELIEVE_PCC_PROMOTION 0
 #endif
 
+/* During some calls to read_type (and thus to read_range_type), this
+   contains the name of the type being defined.  Range types are only
+   used in C as basic types.  We use the name to distinguish the otherwise
+   identical basic types "int" and "long" and their unsigned versions.
+   FIXME, this should disappear with better type management.  */
+
+static char *long_kludge_name;
+
 /* Make a list of forward references which haven't been defined.  */
 static struct type **undef_types;
 static int undef_types_allocated, undef_types_length;
@@ -1117,6 +1125,14 @@ define_symbol (valu, string, desc, type)
                                            strlen (SYMBOL_NAME (sym)));
        }
 
+      /* Here we save the name of the symbol for read_range_type, which
+        ends up reading in the basic types.  In stabs, unfortunately there
+        is no distinction between "int" and "long" types except their
+        names.  Until we work out a saner type policy (eliminating most
+        builtin types and using the names specified in the files), we
+        save away the name so that far away from here in read_range_type,
+        we can examine it to decide between "int" and "long".  FIXME.  */
+      long_kludge_name = SYMBOL_NAME (sym);
       type_read = read_type (&p);
 
       if ((deftype == 'F' || deftype == 'f')
@@ -1230,29 +1246,31 @@ define_symbol (valu, string, desc, type)
         up).  I made this code adapt so that it will offset the symbol
         if it was pointing at an int-aligned location and not
         otherwise.  This way you can use the same gdb for 4.0.x and
-        4.1 systems.  */
-
-      if (0 == SYMBOL_VALUE (sym) % sizeof (int))
-       {
-         if (SYMBOL_TYPE (sym) == builtin_type_char
-             || SYMBOL_TYPE (sym) == builtin_type_unsigned_char)
-           SYMBOL_VALUE (sym) += 3;
-         else if (SYMBOL_TYPE (sym) == builtin_type_short
-             || SYMBOL_TYPE (sym) == builtin_type_unsigned_short)
-           SYMBOL_VALUE (sym) += 2;
-       }
+        4.1 systems.
+
+       If the parameter is shorter than an int, and is integral
+       (e.g. char, short, or unsigned equivalent), and is claimed to
+       be passed on an integer boundary, don't believe it!  Offset the
+       parameter's address to the tail-end of that integer.  */
+
+      if (TYPE_LENGTH (SYMBOL_TYPE (sym)) < TYPE_LENGTH (builtin_type_int)
+       && TYPE_CODE (SYMBOL_TYPE (sym)) == TYPE_CODE_INT
+       && 0 == SYMBOL_VALUE (sym) % TYPE_LENGTH (builtin_type_int)) {
+       SYMBOL_VALUE (sym) += TYPE_LENGTH (builtin_type_int)
+                          -  TYPE_LENGTH (SYMBOL_TYPE (sym));
+      }
       break;
 
 #else /* no BELIEVE_PCC_PROMOTION_TYPE.  */
 
       /* If PCC says a parameter is a short or a char,
         it is really an int.  */
-      if (SYMBOL_TYPE (sym) == builtin_type_char
-         || SYMBOL_TYPE (sym) == builtin_type_short)
-       SYMBOL_TYPE (sym) = builtin_type_int;
-      else if (SYMBOL_TYPE (sym) == builtin_type_unsigned_char
-              || SYMBOL_TYPE (sym) == builtin_type_unsigned_short)
-       SYMBOL_TYPE (sym) = builtin_type_unsigned_int;
+      if (TYPE_LENGTH (SYMBOL_TYPE (sym)) < TYPE_LENGTH (builtin_type_int)
+       && TYPE_CODE (SYMBOL_TYPE (sym) == TYPE_CODE_INT) {
+       SYMBOL_TYPE (sym) = TYPE_UNSIGNED (SYMBOL_TYPE (sym))?
+                               builtin_type_unsigned_int:
+                               builtin_type_int;
+      }
       break;
 
 #endif /* no BELIEVE_PCC_PROMOTION_TYPE.  */
@@ -1386,45 +1404,86 @@ add_undefined_type (type)
   undef_types[undef_types_length++] = type;
 }
 
-/* Add here something to go through each undefined type, see if it's
-   still undefined, and do a full lookup if so.  */
+/* Go through each undefined type, see if it's still undefined, and fix it
+   up if possible.  We have two kinds of undefined types:
+
+   TYPE_CODE_ARRAY:  Array whose target type wasn't defined yet.
+                       Fix:  update array length using the element bounds
+                       and the target type's length.
+   TYPE_CODE_STRUCT, TYPE_CODE_UNION:  Structure whose fields were not
+                       yet defined at the time a pointer to it was made.
+                       Fix:  Do a full lookup on the struct/union tag.  */
 static void
 cleanup_undefined_types ()
 {
   struct type **type;
 
-  for (type = undef_types; type < undef_types + undef_types_length; type++)
-    {
-      /* Reasonable test to see if it's been defined since.  */
-      if (TYPE_NFIELDS (*type) == 0)
-       {
-         struct pending *ppt;
-         int i;
-         /* Name of the type, without "struct" or "union" */
-         char *typename = TYPE_NAME (*type);
+  for (type = undef_types; type < undef_types + undef_types_length; type++) {
+      switch (TYPE_CODE (*type)) {
 
-         if (!strncmp (typename, "struct ", 7))
-           typename += 7;
-         if (!strncmp (typename, "union ", 6))
-           typename += 6;
+      case TYPE_CODE_STRUCT:
+      case TYPE_CODE_UNION:
+       {
+         /* Reasonable test to see if it's been defined since.  */
+         if (TYPE_NFIELDS (*type) == 0)
+           {
+             struct pending *ppt;
+             int i;
+             /* Name of the type, without "struct" or "union" */
+             char *typename = TYPE_NAME (*type);
+
+             if (!strncmp (typename, "struct ", 7))
+               typename += 7;
+             if (!strncmp (typename, "union ", 6))
+               typename += 6;
+
+             for (ppt = file_symbols; ppt; ppt = ppt->next)
+               for (i = 0; i < ppt->nsyms; i++)
+                 {
+                   struct symbol *sym = ppt->symbol[i];
+
+                   if (SYMBOL_CLASS (sym) == LOC_TYPEDEF
+                       && SYMBOL_NAMESPACE (sym) == STRUCT_NAMESPACE
+                       && (TYPE_CODE (SYMBOL_TYPE (sym)) ==
+                           TYPE_CODE (*type))
+                       && !strcmp (SYMBOL_NAME (sym), typename))
+                     bcopy (SYMBOL_TYPE (sym), *type, sizeof (struct type));
+                 }
+           }
+         else
+           /* It has been defined; don't mark it as a stub.  */
+           TYPE_FLAGS (*type) &= ~TYPE_FLAG_STUB;
+       }
+       break;
 
-         for (ppt = file_symbols; ppt; ppt = ppt->next)
-           for (i = 0; i < ppt->nsyms; i++)
-             {
-               struct symbol *sym = ppt->symbol[i];
-
-               if (SYMBOL_CLASS (sym) == LOC_TYPEDEF
-                   && SYMBOL_NAMESPACE (sym) == STRUCT_NAMESPACE
-                   && (TYPE_CODE (SYMBOL_TYPE (sym)) ==
-                       TYPE_CODE (*type))
-                   && !strcmp (SYMBOL_NAME (sym), typename))
-                 bcopy (SYMBOL_TYPE (sym), *type, sizeof (struct type));
-             }
+      case TYPE_CODE_ARRAY:
+       {
+         struct type *range_type;
+         int lower, upper;
+
+         if (TYPE_LENGTH (*type) != 0)         /* Better be unknown */
+           goto badtype;
+         if (TYPE_NFIELDS (*type) != 1)
+           goto badtype;
+         range_type = TYPE_FIELD_TYPE (*type, 0);
+         if (TYPE_CODE (range_type) != TYPE_CODE_RANGE)
+           goto badtype;
+
+         /* Now recompute the length of the array type, based on its
+            number of elements and the target type's length.  */
+         lower = TYPE_FIELD_BITPOS (range_type, 0);
+         upper = TYPE_FIELD_BITPOS (range_type, 1);
+         TYPE_LENGTH (*type) = (upper - lower + 1)
+                         * TYPE_LENGTH (TYPE_TARGET_TYPE (*type));
        }
-      else
-       /* It has been defined; don't mark it as a stub.  */
-       TYPE_FLAGS (*type) &= ~TYPE_FLAG_STUB;
+       break;
+
+      default:
+      badtype:
+       error ("GDB internal error.  cleanup_undefined_types with bad type.");
+       break;
     }
+  }
   undef_types_length = 0;
 }
 \f
@@ -2579,6 +2638,11 @@ read_array_type (pp, type)
                                    sizeof (struct field));
   TYPE_FIELD_TYPE (type, 0) = range_type;
 
+  /* If we have an array whose element type is not yet known, but whose
+     bounds *are* known, record it to be adjusted at the end of the file.  */
+  if (TYPE_LENGTH (element_type) == 0 && !adjustable)
+    add_undefined_type (type);
+
   return type;
 }
 
@@ -2881,7 +2945,9 @@ read_range_type (pp, typenums)
      and they give no way to distinguish between double and single-complex!
      We don't have complex types, so we would lose on all fortran files!
      So return type `double' for all of those.  It won't work right
-     for the complex values, but at least it makes the file loadable.  */
+     for the complex values, but at least it makes the file loadable.
+
+     FIXME, we may be able to distinguish these by their names. FIXME.  */
 
   if (n3 == 0 && n2 > 0)
     {
@@ -2894,11 +2960,15 @@ read_range_type (pp, typenums)
 
   else if (n2 == 0 && n3 == -1)
     {
-      /* FIXME -- this confuses host and target type sizes.  */
-      if (sizeof (int) == sizeof (long))
-       return builtin_type_unsigned_int;
-      else
+      /* FIXME -- the only way to distinguish `unsigned int' from `unsigned
+         long' is to look at its name!  */
+      if (
+       long_kludge_name && ((long_kludge_name[0] == 'u' /* unsigned */ &&
+                                    long_kludge_name[9] == 'l' /* long */)
+                        || (long_kludge_name[0] == 'l' /* long unsigned */)))
        return builtin_type_unsigned_long;
+      else
+       return builtin_type_unsigned_int;
     }
 
   /* Special case: char is defined (Who knows why) as a subrange of
@@ -2908,6 +2978,8 @@ read_range_type (pp, typenums)
 
   /* Assumptions made here: Subrange of self is equivalent to subrange
      of int.  FIXME:  Host and target type-sizes assumed the same.  */
+  /* FIXME:  This is the *only* place in GDB that depends on comparing
+     some type to a builtin type with ==.  Fix it! */
   else if (n2 == 0
           && (self_subrange ||
               *dbx_lookup_type (rangenums) == builtin_type_int))
@@ -2917,10 +2989,15 @@ read_range_type (pp, typenums)
       if (n3 == - sizeof (long long))
        return builtin_type_unsigned_long_long;
 #endif
+      /* FIXME -- the only way to distinguish `unsigned int' from `unsigned
+        long' is to look at its name!  */
+      if (n3 == (unsigned long)~0L &&
+       long_kludge_name && ((long_kludge_name[0] == 'u' /* unsigned */ &&
+                                    long_kludge_name[9] == 'l' /* long */)
+                        || (long_kludge_name[0] == 'l' /* long unsigned */)))
+       return builtin_type_unsigned_long;
       if (n3 == (unsigned int)~0L)
        return builtin_type_unsigned_int;
-      if (n3 == (unsigned long)~0L)
-       return builtin_type_unsigned_long;
       if (n3 == (unsigned short)~0L)
        return builtin_type_unsigned_short;
       if (n3 == (unsigned char)~0L)
@@ -2933,10 +3010,13 @@ read_range_type (pp, typenums)
   else if (n2 == -n3 -1)
     {
       /* a signed type */
+      /* FIXME -- the only way to distinguish `int' from `long' is to look
+        at its name!  */
+      if ((n3 == (1 << (8 * sizeof (long) - 1)) - 1) &&
+       long_kludge_name && long_kludge_name[0] == 'l' /* long */)
+        return builtin_type_long;
       if (n3 == (1 << (8 * sizeof (int) - 1)) - 1)
        return builtin_type_int;
-      if (n3 == (1 << (8 * sizeof (long) - 1)) - 1)
-        return builtin_type_long;
       if (n3 == (1 << (8 * sizeof (short) - 1)) - 1)
        return builtin_type_short;
       if (n3 == (1 << (8 * sizeof (char) - 1)) - 1)
@@ -2972,26 +3052,6 @@ read_range_type (pp, typenums)
   TYPE_FIELD_BITPOS (result_type, 0) = n2;
   TYPE_FIELD_BITPOS (result_type, 1) = n3;
 
-#if 0
-/* Note that TYPE_LENGTH (result_type) is just overridden a few
-   statements down.  What do we really need here?  */
-  /* We have to figure out how many bytes it takes to hold this
-     range type.  I'm going to assume that anything that is pushing
-     the bounds of a long was taken care of above.  */
-  if (n2 >= MIN_OF_C_TYPE(char) && n3 <= MAX_OF_C_TYPE(char))
-    TYPE_LENGTH (result_type) = 1;
-  else if (n2 >= MIN_OF_C_TYPE(short) && n3 <= MAX_OF_C_TYPE(short))
-    TYPE_LENGTH (result_type) = sizeof (short);
-  else if (n2 >= MIN_OF_C_TYPE(int) && n3 <= MAX_OF_C_TYPE(int))
-    TYPE_LENGTH (result_type) = sizeof (int);
-  else if (n2 >= MIN_OF_C_TYPE(long) && n3 <= MAX_OF_C_TYPE(long))
-    TYPE_LENGTH (result_type) = sizeof (long);
-  else
-    /* Ranged type doesn't fit within known sizes.  */
-    /* FIXME -- use "long long" here.  */
-    return error_type (pp);
-#endif
-
   TYPE_LENGTH (result_type) = TYPE_LENGTH (TYPE_TARGET_TYPE (result_type));
 
   return result_type;
index 192ed47c1cf13f089765de37b1e3f850ca655ea6..7d4b1777ad3d8c4b710567319945d3c80b06c393 100644 (file)
@@ -977,10 +977,11 @@ parse_number (p, len, parsed_float, putithere)
        }
       if (i >= base)
        return ERROR;           /* Invalid digit in this base */
-      if(!unsigned_p && (prevn >= n))
+      /* Portably test for overflow (only works for nonzero values, so make
+        a second check for zero).  */
+      if((prevn >= n) && n != 0)
         unsigned_p=1;          /* Try something unsigned */
-      /* Don't do the range check if n==i and i==0, since that special
-        case will give an overflow error. */
+      /* If range checking enabled, portably test for unsigned overflow.  */
       if(RANGE_CHECK && n!=0)
       {        
         if((unsigned_p && (unsigned)prevn >= (unsigned)n))
index 698cfb4f8be48f8a8494102b442f3bc58cddf31e..0a66a4ccf9abd275432bcf238478bd0a81e755cf 100644 (file)
@@ -38,6 +38,8 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
 #include <sys/dir.h>
 #include <signal.h>
 
+extern char *strerror();               /* strings corresponding to errno */
+
 extern struct target_ops child_ops;
 
 /* Nonzero if we are debugging an attached outside process
@@ -48,6 +50,9 @@ int attach_flag;
 \f
 /* Record terminal status separately for debugger and inferior.  */
 
+/* Does GDB have a terminal (on stdin)?  */
+int gdb_has_a_terminal;
+
 static TERMINAL sg_inferior;
 static TERMINAL sg_ours;
 
@@ -82,15 +87,25 @@ static void (*sigint_ours) ();
 static void (*sigquit_ours) ();
 #endif /* TIOCGPGRP */
 
-/* Copy of inferior_io_terminal when inferior was last started.  */
-static char *inferior_thisrun_terminal;
+/* The name of the tty (from the `tty' command) that we gave to the inferior
+   when it was last started.  */
 
-static void terminal_ours_1 ();
+static char *inferior_thisrun_terminal;
 
 /* Nonzero if our terminal settings are in effect.
    Zero if the inferior's settings are in effect.  */
+
 static int terminal_is_ours;
 
+/* Macro for printing errors from ioctl operations */
+
+#define        OOPSY(what)     \
+  if (result == -1)    \
+    fprintf(stderr, "[%s failed in terminal_inferior: %s]\n", \
+           what, strerror (errno))
+
+static void terminal_ours_1 ();
+
 /* Initialize the terminal settings we record for the inferior,
    before we actually run the inferior.  */
 
@@ -125,24 +140,32 @@ terminal_init_inferior ()
 void
 terminal_inferior ()
 {
-  if (terminal_is_ours && inferior_thisrun_terminal == 0)
+  int result;
+
+  if (gdb_has_a_terminal && terminal_is_ours && inferior_thisrun_terminal == 0)
     {
-      fcntl (0, F_SETFL, tflags_inferior);
-      fcntl (0, F_SETFL, tflags_inferior);
-      ioctl (0, TIOCSETN, &sg_inferior);
+      result = fcntl (0, F_SETFL, tflags_inferior);
+      result = fcntl (0, F_SETFL, tflags_inferior);
+      OOPSY ("fcntl F_SETFL");
+      result = ioctl (0, TIOCSETN, &sg_inferior);
+      OOPSY ("ioctl TIOCSETN");
 
 #if defined(TIOCGETC) && !defined(TIOCGETC_BROKEN)
-      ioctl (0, TIOCSETC, &tc_inferior);
+      result = ioctl (0, TIOCSETC, &tc_inferior);
+      OOPSY ("ioctl TIOCSETC");
 #endif
 #if defined(TIOCGLTC) && !defined(TIOCGLTC_BROKEN)
-      ioctl (0, TIOCSLTC, &ltc_inferior);
+      result = ioctl (0, TIOCSLTC, &ltc_inferior);
+      OOPSY ("ioctl TIOCSLTC");
 #endif
 #ifdef TIOCLGET
-      ioctl (0, TIOCLSET, &lmode_inferior);
+      result = ioctl (0, TIOCLSET, &lmode_inferior);
+      OOPSY ("ioctl TIOCLSET");
 #endif
 
 #ifdef TIOCGPGRP
-      ioctl (0, TIOCSPGRP, &pgrp_inferior);
+      result = ioctl (0, TIOCSPGRP, &pgrp_inferior);
+      OOPSY ("ioctl TIOCSPGRP");
 #else
       sigint_ours = (void (*) ()) signal (SIGINT, SIG_IGN);
       sigquit_ours = (void (*) ()) signal (SIGQUIT, SIG_IGN);
@@ -179,17 +202,17 @@ static void
 terminal_ours_1 (output_only)
      int output_only;
 {
+  int result;
 #ifdef TIOCGPGRP
   /* Ignore this signal since it will happen when we try to set the pgrp.  */
   void (*osigttou) ();
 #endif /* TIOCGPGRP */
 
-  /* The check for inferior_thisrun_terminal had been commented out
-     when the call to ioctl (TIOCNOTTY) was commented out.
-     Checking inferior_thisrun_terminal is necessary so that
+  /* Checking inferior_thisrun_terminal is necessary so that
      if GDB is running in the background, it won't block trying
-     to do the ioctl()'s below.  */
-  if (inferior_thisrun_terminal != 0)
+     to do the ioctl()'s below.  Checking gdb_has_a_terminal
+     avoids attempting all the ioctl's when running in batch.  */
+  if (inferior_thisrun_terminal != 0 || gdb_has_a_terminal == 0)
     return;
 
   if (!terminal_is_ours)
@@ -199,8 +222,8 @@ terminal_ours_1 (output_only)
 #ifdef TIOCGPGRP
       osigttou = (void (*) ()) signal (SIGTTOU, SIG_IGN);
 
-      ioctl (0, TIOCGPGRP, &pgrp_inferior);
-      ioctl (0, TIOCSPGRP, &pgrp_ours);
+      result = ioctl (0, TIOCGPGRP, &pgrp_inferior);
+      result = ioctl (0, TIOCSPGRP, &pgrp_ours);
 
       signal (SIGTTOU, osigttou);
 #else
@@ -209,16 +232,16 @@ terminal_ours_1 (output_only)
 #endif /* TIOCGPGRP */
 
       tflags_inferior = fcntl (0, F_GETFL, 0);
-      ioctl (0, TIOCGETP, &sg_inferior);
+      result = ioctl (0, TIOCGETP, &sg_inferior);
 
 #if defined(TIOCGETC) && !defined(TIOCGETC_BROKEN)
-      ioctl (0, TIOCGETC, &tc_inferior);
+      result = ioctl (0, TIOCGETC, &tc_inferior);
 #endif
 #if defined(TIOCGLTC) && !defined(TIOCGLTC_BROKEN)
-      ioctl (0, TIOCGLTC, &ltc_inferior);
+      result = ioctl (0, TIOCGLTC, &ltc_inferior);
 #endif
 #ifdef TIOCLGET
-      ioctl (0, TIOCLGET, &lmode_inferior);
+      result = ioctl (0, TIOCLGET, &lmode_inferior);
 #endif
     }
 
@@ -232,18 +255,18 @@ terminal_ours_1 (output_only)
     sg_ours.sg_flags |= (RAW | CBREAK) & sg_inferior.sg_flags;
 #endif /* not HAVE_TERMIO */
 
-  fcntl (0, F_SETFL, tflags_ours);
-  fcntl (0, F_SETFL, tflags_ours);
-  ioctl (0, TIOCSETN, &sg_ours);
+  result = fcntl (0, F_SETFL, tflags_ours);
+  result = fcntl (0, F_SETFL, tflags_ours);
+  result = ioctl (0, TIOCSETN, &sg_ours);
 
 #if defined(TIOCGETC) && !defined(TIOCGETC_BROKEN)
-  ioctl (0, TIOCSETC, &tc_ours);
+  result = ioctl (0, TIOCSETC, &tc_ours);
 #endif
 #if defined(TIOCGLTC) && !defined(TIOCGLTC_BROKEN)
-  ioctl (0, TIOCSLTC, &ltc_ours);
+  result = ioctl (0, TIOCSLTC, &ltc_ours);
 #endif
 #ifdef TIOCLGET
-  ioctl (0, TIOCLSET, &lmode_ours);
+  result = ioctl (0, TIOCLSET, &lmode_ours);
 #endif
 
 #ifdef HAVE_TERMIO
@@ -270,12 +293,20 @@ child_terminal_info (args, from_tty)
 {
   register int i;
 
+  if (!gdb_has_a_terminal) {
+    printf_filtered ("This GDB does not control a terminal.\n");
+    return;
+  }
+
   printf_filtered ("Inferior's terminal status (currently saved by GDB):\n");
 
+  printf_filtered ("owner pgrp = %d, fcntl flags = 0x%x.\n",
+         pgrp_inferior, tflags_inferior);
+
 #ifdef HAVE_TERMIO
 
-  printf_filtered ("fcntl flags = 0x%x, c_iflag = 0x%x, c_oflag = 0x%x,\n",
-         tflags_inferior, sg_inferior.c_iflag, sg_inferior.c_oflag);
+  printf_filtered (c_iflag = 0x%x, c_oflag = 0x%x,\n",
+         sg_inferior.c_iflag, sg_inferior.c_oflag);
   printf_filtered ("c_cflag = 0x%x, c_lflag = 0x%x, c_line = 0x%x.\n",
          sg_inferior.c_cflag, sg_inferior.c_lflag, sg_inferior.c_line);
   printf_filtered ("c_cc: ");
@@ -285,22 +316,21 @@ child_terminal_info (args, from_tty)
 
 #else /* not HAVE_TERMIO */
 
-  printf_filtered ("fcntl flags = 0x%x, sgttyb.sg_flags = 0x%x, owner pid = %d.\n",
-         tflags_inferior, sg_inferior.sg_flags, pgrp_inferior);
+  printf_filtered ("sgttyb.sg_flags = 0x%x.\n", sg_inferior.sg_flags);
 
 #endif /* not HAVE_TERMIO */
 
 #if defined(TIOCGETC) && !defined(TIOCGETC_BROKEN)
   printf_filtered ("tchars: ");
   for (i = 0; i < (int)sizeof (struct tchars); i++)
-    printf_filtered ("0x%x ", ((char *)&tc_inferior)[i]);
+    printf_filtered ("0x%x ", ((unsigned char *)&tc_inferior)[i]);
   printf_filtered ("\n");
 #endif
 
 #if defined(TIOCGLTC) && !defined(TIOCGLTC_BROKEN)
   printf_filtered ("ltchars: ");
   for (i = 0; i < (int)sizeof (struct ltchars); i++)
-    printf_filtered ("0x%x ", ((char *)&ltc_inferior)[i]);
+    printf_filtered ("0x%x ", ((unsigned char *)&ltc_inferior)[i]);
   printf_filtered ("\n");
 #endif
   
@@ -472,6 +502,8 @@ try_writing_regs_command (arg, from_tty)
 void
 _initialize_inflow ()
 {
+  int result;
+
   add_info ("terminal", term_info,
           "Print inferior's saved terminal status.");
 
@@ -486,23 +518,31 @@ Report which ones can be written.");
 
   inferior_pid = 0;
 
-  ioctl (0, TIOCGETP, &sg_ours);
+  /* Get all the current tty settings (including whether we have a tty at
+     all!).  */
+
   tflags_ours = fcntl (0, F_GETFL, 0);
+  OOPSY ("fcntl F_GETFL");             /* Should always work */
 
+  result = ioctl (0, TIOCGETP, &sg_ours);
+  if (result == 0) {
+    gdb_has_a_terminal = 1;
+    /* Get the rest of the tty settings, then... */
 #if defined(TIOCGETC) && !defined(TIOCGETC_BROKEN)
-  ioctl (0, TIOCGETC, &tc_ours);
+    ioctl (0, TIOCGETC, &tc_ours);
 #endif
 #if defined(TIOCGLTC) && !defined(TIOCGLTC_BROKEN)
-  ioctl (0, TIOCGLTC, &ltc_ours);
+    ioctl (0, TIOCGLTC, &ltc_ours);
 #endif
 #ifdef TIOCLGET
-  ioctl (0, TIOCLGET, &lmode_ours);
+    ioctl (0, TIOCLGET, &lmode_ours);
 #endif
-
 #ifdef TIOCGPGRP
-  ioctl (0, TIOCGPGRP, &pgrp_ours);
+    ioctl (0, TIOCGPGRP, &pgrp_ours);
 #endif /* TIOCGPGRP */
+  } else {
+    gdb_has_a_terminal = 0;
+  }
 
   terminal_is_ours = 1;
 }
-
index 45cca2e2eeb39cc6d9083499ed5769a36d93b7a6..0becbf4e331ff52049906e8a383d1f0c66b2295a 100644 (file)
@@ -69,7 +69,7 @@ value_cast (type, arg2)
             offset the pointer rather than just change its type.  */
          struct type *t1 = TYPE_TARGET_TYPE (type);
          struct type *t2 = TYPE_TARGET_TYPE (VALUE_TYPE (arg2));
-         if (TYPE_CODE (t1) == TYPE_CODE_STRUCT
+         if (   TYPE_CODE (t1) == TYPE_CODE_STRUCT
              && TYPE_CODE (t2) == TYPE_CODE_STRUCT
              && TYPE_NAME (t1) != 0) /* if name unknown, can't have supercl */
            {
@@ -565,10 +565,11 @@ value_arg_coerce (arg)
   type = VALUE_TYPE (arg);
 
   if (TYPE_CODE (type) == TYPE_CODE_INT
-      && TYPE_LENGTH (type) < sizeof (int))
+      && TYPE_LENGTH (type) < TYPE_LENGTH (builtin_type_int))
     return value_cast (builtin_type_int, arg);
 
-  if (type == builtin_type_float)
+  if (TYPE_CODE (type) == TYPE_CODE_FLT
+      && TYPE_LENGTH (type) < TYPE_LENGTH (builtin_type_double))
     return value_cast (builtin_type_double, arg);
 
   return arg;
@@ -949,7 +950,7 @@ value_string (ptr, len)
 \f
 /* Helper function used by value_struct_elt to recurse through baseclasses.
    Look for a field NAME in ARG1. Adjust the address of ARG1 by OFFSET bytes,
-   and treat the result as having type TYPE.
+   and search in it assuming it has (class) type TYPE.
    If found, return value, else return NULL.
 
    If LOOKING_FOR_BASECLASS, then instead of looking for struct fields,
@@ -1019,7 +1020,7 @@ search_struct_field (name, arg1, offset, type, looking_for_baseclass)
 
 /* Helper function used by value_struct_elt to recurse through baseclasses.
    Look for a field NAME in ARG1. Adjust the address of ARG1 by OFFSET bytes,
-   and treat the result as having type TYPE.
+   and search in it assuming it has (class) type TYPE.
    If found, return value, else return NULL. */
 
 static value
@@ -1127,7 +1128,7 @@ value_struct_elt (argp, args, name, static_memfuncp, err)
   if (TYPE_CODE (t) == TYPE_CODE_MEMBER)
     error ("not implemented: member type in value_struct_elt");
 
-  if (TYPE_CODE (t) != TYPE_CODE_STRUCT
+  if (   TYPE_CODE (t) != TYPE_CODE_STRUCT
       && TYPE_CODE (t) != TYPE_CODE_UNION)
     error ("Attempt to extract a component of a value that is not a %s.", err);
 
@@ -1275,7 +1276,7 @@ check_field (arg1, name)
   if (TYPE_CODE (t) == TYPE_CODE_MEMBER)
     error ("not implemented: member type in check_field");
 
-  if (TYPE_CODE (t) != TYPE_CODE_STRUCT
+  if (   TYPE_CODE (t) != TYPE_CODE_STRUCT
       && TYPE_CODE (t) != TYPE_CODE_UNION)
     error ("Internal error: `this' is not an aggregate");
 
@@ -1283,10 +1284,11 @@ check_field (arg1, name)
 }
 
 /* C++: Given an aggregate type DOMAIN, and a member name NAME,
-   return the address of this member as a pointer to member
+   return the address of this member as a "pointer to member"
    type.  If INTYPE is non-null, then it will be the type
    of the member we are looking for.  This will help us resolve
-   pointers to member functions.  */
+   "pointers to member functions".  This function is only used
+   to resolve user expressions of the form "&class::member".  */
 
 value
 value_struct_elt_for_address (domain, intype, name)
@@ -1299,7 +1301,7 @@ value_struct_elt_for_address (domain, intype, name)
 
   struct type *baseclass;
 
-  if (TYPE_CODE (t) != TYPE_CODE_STRUCT
+  if (   TYPE_CODE (t) != TYPE_CODE_STRUCT
       && TYPE_CODE (t) != TYPE_CODE_UNION)
     error ("Internal error: non-aggregate type to value_struct_elt_for_address");
 
@@ -1310,6 +1312,7 @@ value_struct_elt_for_address (domain, intype, name)
       for (i = TYPE_NFIELDS (t) - 1; i >= TYPE_N_BASECLASSES (t); i--)
        {
          char *t_field_name = TYPE_FIELD_NAME (t, i);
+
          if (t_field_name && !strcmp (t_field_name, name))
            {
              if (TYPE_FIELD_STATIC (t, i))
@@ -1317,7 +1320,10 @@ value_struct_elt_for_address (domain, intype, name)
                  char *phys_name = TYPE_FIELD_STATIC_PHYSNAME (t, i);
                  struct symbol *sym =
                      lookup_symbol (phys_name, 0, VAR_NAMESPACE, 0, NULL);
-                 if (! sym) error ("Internal error: could not find physical static variable named %s", phys_name);
+                 if (! sym)
+                   error (
+       "Internal error: could not find physical static variable named %s",
+                          phys_name);
                  return value_from_longest (
                        lookup_pointer_type (TYPE_FIELD_TYPE (t, i)),
                                      (LONGEST)SYMBOL_BLOCK_VALUE (sym));
@@ -1345,7 +1351,7 @@ value_struct_elt_for_address (domain, intype, name)
   /* Destructors are a special case.  */
   if (destructor_name_p (name, t))
     {
-      error ("pointers to destructors not implemented yet");
+      error ("member pointers to destructors not implemented yet");
     }
 
   /* Perform all necessary dereferencing.  */
@@ -1374,7 +1380,8 @@ value_struct_elt_for_address (domain, intype, name)
              else
                j = 0;
 
-             check_stub_method (t, i, j);
+             if (TYPE_FLAGS (TYPE_FN_FIELD_TYPE (f, j)) & TYPE_FLAG_STUB)
+               check_stub_method (t, i, j);
              if (TYPE_FN_FIELD_VIRTUAL_P (f, j))
                {
                  return value_from_longest (
@@ -1388,7 +1395,9 @@ value_struct_elt_for_address (domain, intype, name)
                  struct symbol *s = lookup_symbol (TYPE_FN_FIELD_PHYSNAME (f, j),
                                                    0, VAR_NAMESPACE, 0, NULL);
                  v = locate_var_value (s, 0);
-                 VALUE_TYPE (v) = lookup_pointer_type (lookup_member_type (TYPE_FN_FIELD_TYPE (f, j), baseclass));
+                 VALUE_TYPE (v) = lookup_pointer_type (
+                       lookup_member_type (TYPE_FN_FIELD_TYPE (f, j),
+                                           baseclass));
                  return v;
                }
            }
index 96808501b12c673adc60bc81544be76c01ff0c08..139679ac4186cc0d7a4575a6a6c6b9dafe9db7a6 100644 (file)
@@ -671,11 +671,7 @@ val_print (type, valaddr, address, stream, format,
   switch (TYPE_CODE (type))
     {
     case TYPE_CODE_ARRAY:
-      /* FIXME: TYPE_LENGTH (type) is unsigned and therefore always
-        >= 0.  Is "> 0" meant? I'm not sure what an "array of
-        unspecified length" (mentioned in the comment for the else-part
-        of this if) is.  */
-      if (TYPE_LENGTH (type) >= 0
+      if (TYPE_LENGTH (type) > 0
          && TYPE_LENGTH (TYPE_TARGET_TYPE (type)) > 0)
        {
          elttype = TYPE_TARGET_TYPE (type);
@@ -772,7 +768,7 @@ val_print (type, valaddr, address, stream, format,
 
          addr = unpack_pointer (lookup_pointer_type (builtin_type_void),
                                valaddr);
-         if (addr < 128)
+         if (addr < 128)                       /* FIXME!  What is this 128? */
            {
              len = TYPE_NFN_FIELDS (domain);
              for (i = 0; i < len; i++)
@@ -854,7 +850,7 @@ val_print (type, valaddr, address, stream, format,
                  /* Somehow pointing into a field.  */
                  i -= 1;
                  extra = (val - TYPE_FIELD_BITPOS (domain, i));
-                 if (extra & 0x3)
+                 if (extra & 0x7)
                    bits = 1;
                  else
                    extra >>= 3;
@@ -1463,6 +1459,7 @@ type_print_varspec_prefix (type, stream, show, passed_a_ptr)
                                 0);
       if (passed_a_ptr)
        fprintf_filtered (stream, "(");
+      break;
 
     case TYPE_CODE_UNDEF:
     case TYPE_CODE_STRUCT: