2012-05-09 Frank Ch. Eigler <fche@redhat.com>
[deliverable/binutils-gdb.git] / gdb / c-typeprint.c
index feee86d03b27b98d9c2371f242ee1c3d41d1de1a..a5892b50b8b65539ffbe86e2a0cfe190620f69a3 100644 (file)
@@ -1,7 +1,6 @@
 /* Support for printing C and C++ types for GDB, the GNU debugger.
-   Copyright (C) 1986, 1988, 1989, 1991, 1992, 1993, 1994, 1995, 1996, 1998,
-   1999, 2000, 2001, 2002, 2003, 2006, 2007, 2008, 2009, 2010, 2011
-   Free Software Foundation, Inc.
+   Copyright (C) 1986, 1988-1989, 1991-1996, 1998-2003, 2006-2012 Free
+   Software Foundation, Inc.
 
    This file is part of GDB.
 
@@ -81,7 +80,7 @@ c_print_type (struct type *type,
       fputs_filtered (varstring, stream);
 
       /* For demangled function names, we have the arglist as part of
-         the name, so don't print an additional pair of ()'s */
+         the name, so don't print an additional pair of ()'s */
 
       demangled_args = strchr (varstring, '(') != NULL;
       c_type_print_varspec_suffix (type, stream, show,
@@ -143,7 +142,7 @@ static void
 cp_type_print_derivation_info (struct ui_file *stream,
                               struct type *type)
 {
-  char *name;
+  const char *name;
   int i;
 
   for (i = 0; i < TYPE_N_BASECLASSES (type); i++)
@@ -166,8 +165,8 @@ cp_type_print_derivation_info (struct ui_file *stream,
 /* Print the C++ method arguments ARGS to the file STREAM.  */
 
 static void
-cp_type_print_method_args (struct type *mtype, char *prefix,
-                          char *varstring, int staticp,
+cp_type_print_method_args (struct type *mtype, const char *prefix,
+                          const char *varstring, int staticp,
                           struct ui_file *stream)
 {
   struct field *args = TYPE_FIELDS (mtype);
@@ -239,7 +238,7 @@ c_type_print_varspec_prefix (struct type *type,
                             int show, int passed_a_ptr,
                             int need_post_space)
 {
-  char *name;
+  const char *name;
 
   if (type == 0)
     return;
@@ -387,14 +386,16 @@ c_type_print_modifier (struct type *type, struct ui_file *stream,
 
 /* Print out the arguments of TYPE, which should have TYPE_CODE_METHOD
    or TYPE_CODE_FUNC, to STREAM.  Artificial arguments, such as "this"
-   in non-static methods, are displayed if SHOW_ARTIFICIAL is
-   non-zero.  LANGUAGE is the language in which TYPE was defined.
-   This is a necessary evil since this code is used by the C, C++, and
-   Java backends.  */
+   in non-static methods, are displayed if LINKAGE_NAME is zero.  If
+   LINKAGE_NAME is non-zero and LANGUAGE is language_cplus the topmost
+   parameter types get removed their possible const and volatile qualifiers to
+   match demangled linkage name parameters part of such function type.
+   LANGUAGE is the language in which TYPE was defined.  This is a necessary
+   evil since this code is used by the C, C++, and Java backends.  */
 
 void
 c_type_print_args (struct type *type, struct ui_file *stream,
-                  int show_artificial, enum language language)
+                  int linkage_name, enum language language)
 {
   int i, len;
   struct field *args;
@@ -406,7 +407,9 @@ c_type_print_args (struct type *type, struct ui_file *stream,
 
   for (i = 0; i < TYPE_NFIELDS (type); i++)
     {
-      if (TYPE_FIELD_ARTIFICIAL (type, i) && !show_artificial)
+      struct type *param_type;
+
+      if (TYPE_FIELD_ARTIFICIAL (type, i) && linkage_name)
        continue;
 
       if (printed_any)
@@ -415,12 +418,24 @@ c_type_print_args (struct type *type, struct ui_file *stream,
          wrap_here ("    ");
        }
 
+      param_type = TYPE_FIELD_TYPE (type, i);
+
+      if (language == language_cplus && linkage_name)
+       {
+         /* C++ standard, 13.1 Overloadable declarations, point 3, item:
+            - Parameter declarations that differ only in the presence or
+              absence of const and/or volatile are equivalent.
+
+            And the const/volatile qualifiers are not present in the mangled
+            names as produced by GCC.  */
+
+         param_type = make_cv_type (0, 0, param_type, NULL);
+       }
+
       if (language == language_java)
-       java_print_type (TYPE_FIELD_TYPE (type, i),
-                        "", stream, -1, 0);
+       java_print_type (param_type, "", stream, -1, 0);
       else
-       c_print_type (TYPE_FIELD_TYPE (type, i),
-                     "", stream, -1, 0);
+       c_print_type (param_type, "", stream, -1, 0);
       printed_any = 1;
     }
 
@@ -456,7 +471,7 @@ is_type_conversion_operator (struct type *type, int i, int j)
      by their name is pretty terrible.  But I don't think our present
      data structure gives us any other way to tell.  If you know of
      some other way, feel free to rewrite this function.  */
-  char *name = TYPE_FN_FIELDLIST_NAME (type, i);
+  const char *name = TYPE_FN_FIELDLIST_NAME (type, i);
 
   if (strncmp (name, "operator", 8) != 0)
     return 0;
@@ -509,10 +524,10 @@ is_type_conversion_operator (struct type *type, int i, int j)
 static char *
 remove_qualifiers (char *qid)
 {
-  int quoted = 0;      /* zero if we're not in quotes;
+  int quoted = 0;      /* Zero if we're not in quotes;
                           '"' if we're in a double-quoted string;
                           '\'' if we're in a single-quoted string.  */
-  int depth = 0;       /* number of unclosed parens we've seen */
+  int depth = 0;       /* Number of unclosed parens we've seen.  */
   char *parenstack = (char *) alloca (strlen (qid));
   char *scan;
   char *last = 0;      /* The character after the rightmost
@@ -641,8 +656,7 @@ c_type_print_varspec_suffix (struct type *type,
       if (passed_a_ptr)
        fprintf_filtered (stream, ")");
       if (!demangled_args)
-       c_type_print_args (type, stream, 1,
-                          current_language->la_language);
+       c_type_print_args (type, stream, 0, current_language->la_language);
       c_type_print_varspec_suffix (TYPE_TARGET_TYPE (type), stream,
                                   show, passed_a_ptr, 0);
       break;
@@ -703,10 +717,6 @@ c_type_print_base (struct type *type, struct ui_file *stream,
 {
   int i;
   int len, real_len;
-  int lastval;
-  char *mangled_name;
-  char *demangled_name;
-  char *demangled_no_static;
   enum
     {
       s_none, s_public, s_private, s_protected
@@ -843,7 +853,8 @@ c_type_print_base (struct type *type, struct ui_file *stream,
                    {
                      len = TYPE_FN_FIELDLIST_LENGTH (type, j);
                      for (i = 0; i < len; i++)
-                       if (!TYPE_FN_FIELD_PRIVATE (TYPE_FN_FIELDLIST1 (type, j), i))
+                       if (!TYPE_FN_FIELD_PRIVATE (TYPE_FN_FIELDLIST1 (type,
+                                                                       j), i))
                          {
                            need_access_label = 1;
                            break;
@@ -873,8 +884,11 @@ c_type_print_base (struct type *type, struct ui_file *stream,
                      QUIT;
                      len = TYPE_FN_FIELDLIST_LENGTH (type, j);
                      for (i = 0; i < len; i++)
-                       if (TYPE_FN_FIELD_PRIVATE (TYPE_FN_FIELDLIST1 (type, j), i)
-                           || TYPE_FN_FIELD_PROTECTED (TYPE_FN_FIELDLIST1 (type, j), i))
+                       if (TYPE_FN_FIELD_PROTECTED (TYPE_FN_FIELDLIST1 (type,
+                                                                        j), i)
+                           || TYPE_FN_FIELD_PRIVATE (TYPE_FN_FIELDLIST1 (type,
+                                                                         j),
+                                                     i))
                          {
                            need_access_label = 1;
                            break;
@@ -970,19 +984,22 @@ c_type_print_base (struct type *type, struct ui_file *stream,
          if (real_len > 0 && section_type != s_none)
            fprintf_filtered (stream, "\n");
 
-         /* C++: print out the methods */
+         /* C++: print out the methods */
          for (i = 0; i < len; i++)
            {
              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);
+             const char *method_name = TYPE_FN_FIELDLIST_NAME (type, i);
+             const char *name = type_name_no_tag (type);
              int is_constructor = name && strcmp (method_name,
                                                   name) == 0;
 
              for (j = 0; j < len2; j++)
                {
-                 char *physname = TYPE_FN_FIELD_PHYSNAME (f, j);
+                 const char *mangled_name;
+                 char *demangled_name;
+                 struct cleanup *inner_cleanup;
+                 const char *physname = TYPE_FN_FIELD_PHYSNAME (f, j);
                  int is_full_physname_constructor =
                    is_constructor_name (physname) 
                    || is_destructor_name (physname)
@@ -992,6 +1009,8 @@ c_type_print_base (struct type *type, struct ui_file *stream,
                  if (TYPE_FN_FIELD_ARTIFICIAL (f, j))
                    continue;
 
+                 inner_cleanup = make_cleanup (null_cleanup, NULL);
+
                  QUIT;
                  if (TYPE_FN_FIELD_PROTECTED (f, j))
                    {
@@ -1045,8 +1064,14 @@ c_type_print_base (struct type *type, struct ui_file *stream,
                      fputs_filtered (" ", stream);
                    }
                  if (TYPE_FN_FIELD_STUB (f, j))
-                   /* Build something we can demangle.  */
-                   mangled_name = gdb_mangle_name (type, i, j);
+                   {
+                     char *tem;
+
+                     /* Build something we can demangle.  */
+                     tem = gdb_mangle_name (type, i, j);
+                     make_cleanup (xfree, tem);
+                     mangled_name = tem;
+                   }
                  else
                    mangled_name = TYPE_FN_FIELD_PHYSNAME (f, j);
 
@@ -1088,6 +1113,7 @@ c_type_print_base (struct type *type, struct ui_file *stream,
                      if (p != NULL)
                        {
                          int length = p - demangled_no_class;
+                         char *demangled_no_static;
 
                          demangled_no_static
                            = (char *) xmalloc (length + 1);
@@ -1102,8 +1128,7 @@ c_type_print_base (struct type *type, struct ui_file *stream,
                      xfree (demangled_name);
                    }
 
-                 if (TYPE_FN_FIELD_STUB (f, j))
-                   xfree (mangled_name);
+                 do_cleanups (inner_cleanup);
 
                  fprintf_filtered (stream, ";\n");
                }
@@ -1168,9 +1193,10 @@ c_type_print_base (struct type *type, struct ui_file *stream,
        }
       else if (show > 0 || TYPE_TAG_NAME (type) == NULL)
        {
+         LONGEST lastval = 0;
+
          fprintf_filtered (stream, "{");
          len = TYPE_NFIELDS (type);
-         lastval = 0;
          for (i = 0; i < len; i++)
            {
              QUIT;
@@ -1178,11 +1204,11 @@ c_type_print_base (struct type *type, struct ui_file *stream,
                fprintf_filtered (stream, ", ");
              wrap_here ("    ");
              fputs_filtered (TYPE_FIELD_NAME (type, i), stream);
-             if (lastval != TYPE_FIELD_BITPOS (type, i))
+             if (lastval != TYPE_FIELD_ENUMVAL (type, i))
                {
-                 fprintf_filtered (stream, " = %d", 
-                                   TYPE_FIELD_BITPOS (type, i));
-                 lastval = TYPE_FIELD_BITPOS (type, i);
+                 fprintf_filtered (stream, " = %s",
+                                   plongest (TYPE_FIELD_ENUMVAL (type, i)));
+                 lastval = TYPE_FIELD_ENUMVAL (type, i);
                }
              lastval++;
            }
@@ -1203,7 +1229,7 @@ c_type_print_base (struct type *type, struct ui_file *stream,
       break;
 
     case TYPE_CODE_RANGE:
-      /* This should not occur */
+      /* This should not occur */
       fprintf_filtered (stream, _("<range type>"));
       break;
 
This page took 0.027477 seconds and 4 git commands to generate.