* mips-dis.c (print_insn_mips16): Set insn_info information.
[deliverable/binutils-gdb.git] / gdb / c-typeprint.c
index 40e3f52369c5515874746a1e648b0a4fffb5748d..3347050b5c12fb9f63439716656f8289426c91e5 100644 (file)
@@ -1,5 +1,6 @@
 /* Support for printing C and C++ types for GDB, the GNU debugger.
-   Copyright 1986, 1988, 1989, 1991 Free Software Foundation, Inc.
+   Copyright 1986, 1988, 1989, 1991, 1993, 1994, 1995, 1996
+   Free Software Foundation, Inc.
 
 This file is part of GDB.
 
@@ -15,7 +16,7 @@ GNU General Public License for more details.
 
 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.  */
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
 
 #include "defs.h"
 #include "obstack.h"
@@ -33,25 +34,21 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
 #include "c-lang.h"
 #include "typeprint.h"
 
-#include <string.h>
+#include "gdb_string.h"
 #include <errno.h>
-
-extern int demangle;   /* whether to print C++ syms raw or source-form */
+#include <ctype.h>
 
 static void
-c_type_print_args PARAMS ((struct type *, FILE *));
+c_type_print_args PARAMS ((struct type *, GDB_FILE *));
 
 static void
-c_type_print_varspec_suffix PARAMS ((struct type *, FILE *, int, int, int));
+c_type_print_varspec_suffix PARAMS ((struct type *, GDB_FILE *, int, int, int));
 
 static void
-cp_type_print_derivation_info PARAMS ((FILE *, struct type *));
-
-void
-c_type_print_varspec_prefix PARAMS ((struct type *, FILE *, int, int));
+cp_type_print_derivation_info PARAMS ((GDB_FILE *, struct type *));
 
 void
-c_type_print_base PARAMS ((struct type *, FILE *, int, int));
+c_type_print_varspec_prefix PARAMS ((struct type *, GDB_FILE *, int, int));
 
 \f
 /* Print a description of a type in the format of a 
@@ -62,8 +59,9 @@ void
 c_typedef_print (type, new, stream)
    struct type *type;
    struct symbol *new;
-   FILE *stream;
+   GDB_FILE *stream;
 {
+  CHECK_TYPEDEF (type);
    switch (current_language->la_language)
    {
 #ifdef _LANG_c
@@ -87,12 +85,17 @@ c_typedef_print (type, new, stream)
       type_print(type,"",stream,0);
       break;
 #endif
-/* start-sanitize-chill */
 #ifdef _LANG_chill
    case language_chill:
-      error ("Missing Chill support in function c_typedef_print."); /*FIXME*/
+      fprintf_filtered(stream, "SYNMODE ");
+      if(!TYPE_NAME(SYMBOL_TYPE(new)) ||
+        !STREQ (TYPE_NAME(SYMBOL_TYPE(new)), SYMBOL_NAME(new)))
+       fprintf_filtered(stream, "%s = ", SYMBOL_SOURCE_NAME(new));
+      else
+        fprintf_filtered(stream, "<builtin> = ");
+      type_print(type,"",stream,0);
+      break;
 #endif
-/* end-sanitize-chill */
    default:
       error("Language not supported.");
    }
@@ -106,13 +109,16 @@ void
 c_print_type (type, varstring, stream, show, level)
      struct type *type;
      char *varstring;
-     FILE *stream;
+     GDB_FILE *stream;
      int show;
      int level;
 {
   register enum type_code code;
   int demangled_args;
 
+  if (show > 0)
+    CHECK_TYPEDEF (type);
+
   c_type_print_base (type, stream, show, level);
   code = TYPE_CODE (type);
   if ((varstring != NULL && *varstring != '\0')
@@ -134,46 +140,10 @@ c_print_type (type, varstring, stream, show, level)
   /* For demangled function names, we have the arglist as part of the name,
      so don't print an additional pair of ()'s */
 
-  demangled_args = varstring[strlen(varstring) - 1] == ')';
+  demangled_args = strchr(varstring, '(') != NULL;
   c_type_print_varspec_suffix (type, stream, show, 0, demangled_args);
 
 }
-
-/* Print the C++ method arguments ARGS to the file STREAM.  */
-
-void
-cp_type_print_method_args (args, prefix, varstring, staticp, stream)
-     struct type **args;
-     char *prefix;
-     char *varstring;
-     int staticp;
-     FILE *stream;
-{
-  int i;
-
-  fputs_demangled (prefix, stream, DMGL_ANSI | DMGL_PARAMS);
-  fputs_demangled (varstring, stream, DMGL_ANSI | DMGL_PARAMS);
-  fputs_filtered (" (", stream);
-  if (args && args[!staticp] && args[!staticp]->code != TYPE_CODE_VOID)
-    {
-      i = !staticp;            /* skip the class variable */
-      while (1)
-       {
-         type_print (args[i++], "", stream, 0);
-         if (!args[i]) 
-           {
-             fprintf_filtered (stream, " ...");
-             break;
-           }
-         else if (args[i]->code != TYPE_CODE_VOID)
-           {
-             fprintf_filtered (stream, ", ");
-           }
-         else break;
-       }
-    }
-  fprintf_filtered (stream, ")");
-}
   
 /* If TYPE is a derived type, then print out derivation information.
    Print only the actual base classes of this type, not the base classes
@@ -201,7 +171,7 @@ cp_type_print_method_args (args, prefix, varstring, staticp, stream)
 
 static void
 cp_type_print_derivation_info (stream, type)
-     FILE *stream;
+     GDB_FILE *stream;
      struct type *type;
 {
   char *name;
@@ -233,7 +203,7 @@ cp_type_print_derivation_info (stream, type)
 void
 c_type_print_varspec_prefix (type, stream, show, passed_a_ptr)
      struct type *type;
-     FILE *stream;
+     GDB_FILE *stream;
      int show;
      int passed_a_ptr;
 {
@@ -268,7 +238,7 @@ c_type_print_varspec_prefix (type, stream, show, passed_a_ptr)
 
     case TYPE_CODE_METHOD:
       if (passed_a_ptr)
-       fprintf (stream, "(");
+       fprintf_filtered (stream, "(");
       c_type_print_varspec_prefix (TYPE_TARGET_TYPE (type), stream, 0, 0);
       if (passed_a_ptr)
        {
@@ -307,7 +277,10 @@ c_type_print_varspec_prefix (type, stream, show, passed_a_ptr)
     case TYPE_CODE_BOOL:
     case TYPE_CODE_SET:
     case TYPE_CODE_RANGE:
-    case TYPE_CODE_PASCAL_ARRAY:
+    case TYPE_CODE_STRING:
+    case TYPE_CODE_BITSTRING:
+    case TYPE_CODE_COMPLEX:
+    case TYPE_CODE_TYPEDEF:
       /* These types need no prefix.  They are listed here so that
         gcc -Wall will reveal any types that haven't been handled.  */
       break;
@@ -317,7 +290,7 @@ c_type_print_varspec_prefix (type, stream, show, passed_a_ptr)
 static void
 c_type_print_args (type, stream)
      struct type *type;
-     FILE *stream;
+     GDB_FILE *stream;
 {
   int i;
   struct type **args;
@@ -359,7 +332,7 @@ c_type_print_args (type, stream)
 static void
 c_type_print_varspec_suffix (type, stream, show, passed_a_ptr, demangled_args)
      struct type *type;
-     FILE *stream;
+     GDB_FILE *stream;
      int show;
      int passed_a_ptr;
      int demangled_args;
@@ -379,7 +352,8 @@ c_type_print_varspec_suffix (type, stream, show, passed_a_ptr, demangled_args)
        fprintf_filtered (stream, ")");
       
       fprintf_filtered (stream, "[");
-      if (TYPE_LENGTH (type) > 0 && TYPE_LENGTH (TYPE_TARGET_TYPE (type)) > 0)
+      if (TYPE_LENGTH (type) >= 0 && TYPE_LENGTH (TYPE_TARGET_TYPE (type)) > 0
+         && TYPE_ARRAY_UPPER_BOUND_TYPE(type) != BOUND_CANNOT_BE_DETERMINED)
        fprintf_filtered (stream, "%d",
                          (TYPE_LENGTH (type)
                           / TYPE_LENGTH (TYPE_TARGET_TYPE (type))));
@@ -410,12 +384,24 @@ c_type_print_varspec_suffix (type, stream, show, passed_a_ptr, demangled_args)
       break;
 
     case TYPE_CODE_FUNC:
-      c_type_print_varspec_suffix (TYPE_TARGET_TYPE (type), stream, 0,
-                                passed_a_ptr, 0);
       if (passed_a_ptr)
        fprintf_filtered (stream, ")");
       if (!demangled_args)
-       fprintf_filtered (stream, "()");
+       { int i, len = TYPE_NFIELDS (type);
+         fprintf_filtered (stream, "(");
+         for (i = 0; i < len; i++)
+           {
+             if (i > 0)
+               {
+                 fputs_filtered (", ", stream);
+                 wrap_here ("    ");
+               }
+             c_print_type (TYPE_FIELD_TYPE (type, i), "", stream, -1, 0);
+           }
+         fprintf_filtered (stream, ")");
+       }
+      c_type_print_varspec_suffix (TYPE_TARGET_TYPE (type), stream, 0,
+                                  passed_a_ptr, 0);
       break;
 
     case TYPE_CODE_UNDEF:
@@ -430,7 +416,10 @@ c_type_print_varspec_suffix (type, stream, show, passed_a_ptr, demangled_args)
     case TYPE_CODE_BOOL:
     case TYPE_CODE_SET:
     case TYPE_CODE_RANGE:
-    case TYPE_CODE_PASCAL_ARRAY:
+    case TYPE_CODE_STRING:
+    case TYPE_CODE_BITSTRING:
+    case TYPE_CODE_COMPLEX:
+    case TYPE_CODE_TYPEDEF:
       /* These types do not need a suffix.  They are listed so that
         gcc -Wall will report types that may not have been considered.  */
       break;
@@ -441,23 +430,25 @@ c_type_print_varspec_suffix (type, stream, show, passed_a_ptr, demangled_args)
    function value or array element), or the description of a
    structure or union.
 
-   SHOW nonzero means don't print this type as just its name;
-   show its real definition even if it has a name.
-   SHOW zero means print just typename or struct tag if there is one
-   SHOW negative means abbreviate structure elements.
-   SHOW is decremented for printing of structure elements.
+   SHOW positive means print details about the type (e.g. enum values),
+   and print structure elements passing SHOW - 1 for show.
+   SHOW negative means just print the type name or struct tag if there is one.
+   If there is no name, print something sensible but concise like
+   "struct {...}".
+   SHOW zero means just print the type name or struct tag if there is one.
+   If there is no name, print something sensible but not as concise like
+   "struct {int x; int y;}".
 
-   LEVEL is the depth to indent by.
+   LEVEL is the number of spaces to indent by.
    We increase it for some recursive calls.  */
 
 void
 c_type_print_base (type, stream, show, level)
      struct type *type;
-     FILE *stream;
+     GDB_FILE *stream;
      int show;
      int level;
 {
-  char *name;
   register int i;
   register int len;
   register int lastval;
@@ -474,16 +465,23 @@ c_type_print_base (type, stream, show, level)
     }
 
   /* When SHOW is zero or less, and there is a valid type name, then always
-     just print the type name directly from the type. */
+     just print the type name directly from the type.  */
+  /* If we have "typedef struct foo {. . .} bar;" do we want to print it
+     as "struct foo" or as "bar"?  Pick the latter, because C++ folk tend
+     to expect things like "class5 *foo" rather than "struct class5 *foo".  */
 
-  if ((show <= 0) && (TYPE_NAME (type) != NULL))
+  if (show <= 0
+      && TYPE_NAME (type) != NULL)
     {
       fputs_filtered (TYPE_NAME (type), stream);
       return;
     }
 
+  CHECK_TYPEDEF (type);
+         
   switch (TYPE_CODE (type))
     {
+    case TYPE_CODE_TYPEDEF:
     case TYPE_CODE_ARRAY:
     case TYPE_CODE_PTR:
     case TYPE_CODE_MEMBER:
@@ -494,25 +492,35 @@ c_type_print_base (type, stream, show, level)
       break;
 
     case TYPE_CODE_STRUCT:
-      fprintf_filtered (stream,
-                       HAVE_CPLUS_STRUCT (type) ? "class " : "struct ");
+      if (HAVE_CPLUS_STRUCT (type))
+       {
+         fprintf_filtered (stream, "class ");
+       }
+      else
+       {
+         fprintf_filtered (stream, "struct ");
+       }
       goto struct_union;
 
     case TYPE_CODE_UNION:
       fprintf_filtered (stream, "union ");
+
     struct_union:
-      if ((name = type_name_no_tag (type)) != NULL)
+      if (TYPE_TAG_NAME (type) != NULL)
        {
-         fputs_filtered (name, stream);
-         fputs_filtered (" ", stream);
-         wrap_here ("    ");
+         fputs_filtered (TYPE_TAG_NAME (type), stream);
+         if (show > 0)
+           fputs_filtered (" ", stream);
        }
+      wrap_here ("    ");
       if (show < 0)
-       fprintf_filtered (stream, "{...}");
-      else
        {
-         check_stub_type (type);
-         
+         /* If we just printed a tag name, no need to print anything else.  */
+         if (TYPE_TAG_NAME (type) == NULL)
+           fprintf_filtered (stream, "{...}");
+       }
+      else if (show > 0 || TYPE_TAG_NAME (type) == NULL)
+       {
          cp_type_print_derivation_info (stream, type);
          
          fprintf_filtered (stream, "{\n");
@@ -538,8 +546,8 @@ c_type_print_base (type, stream, show, level)
            {
              QUIT;
              /* Don't print out virtual function table.  */
-             if ((TYPE_FIELD_NAME (type, i))[5] == CPLUS_MARKER &&
-                 !strncmp (TYPE_FIELD_NAME (type, i), "_vptr", 5))
+             if (STREQN (TYPE_FIELD_NAME (type, i), "_vptr", 5)
+                 && is_cplus_marker ((TYPE_FIELD_NAME (type, i))[5]))
                continue;
 
              /* If this is a C++ class we can print the various C++ section
@@ -608,9 +616,18 @@ c_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);
+             char *name = type_name_no_tag (type);
              int is_constructor = name && STREQ(method_name, name);
              for (j = 0; j < len2; j++)
                {
+                 char *physname = TYPE_FN_FIELD_PHYSNAME (f, j);
+                 int is_full_physname_constructor = 
+                   ((physname[0] == '_' && physname[1] == '_'
+                     && strchr ("0123456789Qt", physname[2]))
+                    || STREQN (physname, "__ct__", 6)
+                    || DESTRUCTOR_PREFIX_P (physname)
+                    || STREQN (physname, "__dt__", 6));
+
                  QUIT;
                  if (TYPE_FN_FIELD_PROTECTED (f, j))
                    {
@@ -646,43 +663,46 @@ c_type_print_base (type, stream, show, level)
                  if (TYPE_TARGET_TYPE (TYPE_FN_FIELD_TYPE (f, j)) == 0)
                    {
                      /* Keep GDB from crashing here.  */
-                     fprintf (stream, "<undefined type> %s;\n",
+                     fprintf_filtered (stream, "<undefined type> %s;\n",
                               TYPE_FN_FIELD_PHYSNAME (f, j));
                      break;
                    }
-                 else if (!is_constructor)
+                 else if (!is_constructor && !is_full_physname_constructor)
                    {
                      type_print (TYPE_TARGET_TYPE (TYPE_FN_FIELD_TYPE (f, j)),
-                                 "", stream, 0);
+                                 "", stream, -1);
                      fputs_filtered (" ", stream);
                    }
                  if (TYPE_FN_FIELD_STUB (f, j))
+                   /* Build something we can demangle.  */
+                   mangled_name = gdb_mangle_name (type, i, j);
+                 else
+                   mangled_name = TYPE_FN_FIELD_PHYSNAME (f, j);
+
+                 demangled_name =
+                   cplus_demangle (mangled_name,
+                                   DMGL_ANSI | DMGL_PARAMS);
+                 if (demangled_name == NULL)
+                   fprintf_filtered (stream, "<badly mangled name '%s'>",
+                                     mangled_name);
+                 else
                    {
-                     /* Build something we can demangle.  */
-                     mangled_name = gdb_mangle_name (type, i, j);
-                     demangled_name =
-                         cplus_demangle (mangled_name,
-                                         DMGL_ANSI | DMGL_PARAMS);
-                     if (demangled_name == NULL)
-                       fprintf_filtered (stream, "<badly mangled name %s>",
-                           mangled_name);
-                     else 
+                     char *demangled_no_class =
+                       strchr (demangled_name, ':');
+
+                     if (demangled_no_class == NULL)
+                       demangled_no_class = demangled_name;
+                     else
                        {
-                         fprintf_filtered (stream, "%s",
-                             strchr (demangled_name, ':') + 2);
-                         free (demangled_name);
+                         if (*++demangled_no_class == ':')
+                           ++demangled_no_class;
                        }
-                     free (mangled_name);
+                     fputs_filtered (demangled_no_class, stream);
+                     free (demangled_name);
                    }
-                 else if (TYPE_FN_FIELD_PHYSNAME (f, j)[0] == '_'
-                       && TYPE_FN_FIELD_PHYSNAME (f, j)[1] == CPLUS_MARKER)
-                   cp_type_print_method_args (TYPE_FN_FIELD_ARGS (f, j) + 1,
-                                              "~", method_name, 0, stream);
-                 else
-                   cp_type_print_method_args (TYPE_FN_FIELD_ARGS (f, j), "",
-                                              method_name,
-                                              TYPE_FN_FIELD_STATIC_P (f, j),
-                                              stream);
+
+                 if (TYPE_FN_FIELD_STUB (f, j))
+                   free (mangled_name);
 
                  fprintf_filtered (stream, ";\n");
                }
@@ -694,15 +714,21 @@ c_type_print_base (type, stream, show, level)
 
     case TYPE_CODE_ENUM:
       fprintf_filtered (stream, "enum ");
-      if ((name = type_name_no_tag (type)) != NULL)
+      if (TYPE_TAG_NAME (type) != NULL)
        {
-         fputs_filtered (name, stream);
-         fputs_filtered (" ", stream);
+         fputs_filtered (TYPE_TAG_NAME (type), stream);
+         if (show > 0)
+           fputs_filtered (" ", stream);
        }
+
       wrap_here ("    ");
       if (show < 0)
-       fprintf_filtered (stream, "{...}");
-      else
+       {
+         /* If we just printed a tag name, no need to print anything else.  */
+         if (TYPE_TAG_NAME (type) == NULL)
+           fprintf_filtered (stream, "{...}");
+       }
+      else if (show > 0 || TYPE_TAG_NAME (type) == NULL)
        {
          fprintf_filtered (stream, "{");
          len = TYPE_NFIELDS (type);
@@ -752,7 +778,10 @@ c_type_print_base (type, stream, show, level)
        }
       else
        {
-         error ("Invalid type code (%d) in symbol table.", TYPE_CODE (type));
+         /* At least for dump_symtab, it is important that this not be
+            an error ().  */
+         fprintf_filtered (stream, "<invalid type code %d>",
+                           TYPE_CODE (type));
        }
       break;
     }
This page took 0.037815 seconds and 4 git commands to generate.