Add debug output about skipping files and functions
[deliverable/binutils-gdb.git] / gdb / rust-lang.c
index ed0394592fac5e730f65e16ad000d417504368ba..1871ec7df9beea2d5022eb0bf82a42680aaa7dc1 100644 (file)
 #include "objfiles.h"
 #include "psymtab.h"
 #include "rust-lang.h"
+#include "typeprint.h"
 #include "valprint.h"
 #include "varobj.h"
+#include <algorithm>
 #include <string>
 #include <vector>
 
@@ -95,8 +97,8 @@ rust_tuple_type_p (struct type *type)
      nothing else in the debuginfo to distinguish a tuple from a
      struct.  */
   return (TYPE_CODE (type) == TYPE_CODE_STRUCT
-         && TYPE_TAG_NAME (type) != NULL
-         && TYPE_TAG_NAME (type)[0] == '(');
+         && TYPE_NAME (type) != NULL
+         && TYPE_NAME (type)[0] == '(');
 }
 
 /* Return true if all non-static fields of a structlike type are in a
@@ -143,9 +145,9 @@ static bool
 rust_slice_type_p (struct type *type)
 {
   return (TYPE_CODE (type) == TYPE_CODE_STRUCT
-         && TYPE_TAG_NAME (type) != NULL
-         && (strncmp (TYPE_TAG_NAME (type), "&[", 2) == 0
-             || strcmp (TYPE_TAG_NAME (type), "&str") == 0));
+         && TYPE_NAME (type) != NULL
+         && (strncmp (TYPE_NAME (type), "&[", 2) == 0
+             || strcmp (TYPE_NAME (type), "&str") == 0));
 }
 
 /* Return true if TYPE is a range type, otherwise false.  */
@@ -157,8 +159,8 @@ rust_range_type_p (struct type *type)
 
   if (TYPE_CODE (type) != TYPE_CODE_STRUCT
       || TYPE_NFIELDS (type) > 2
-      || TYPE_TAG_NAME (type) == NULL
-      || strstr (TYPE_TAG_NAME (type), "::Range") == NULL)
+      || TYPE_NAME (type) == NULL
+      || strstr (TYPE_NAME (type), "::Range") == NULL)
     return false;
 
   if (TYPE_NFIELDS (type) == 0)
@@ -187,8 +189,8 @@ rust_range_type_p (struct type *type)
 static bool
 rust_inclusive_range_type_p (struct type *type)
 {
-  return (strstr (TYPE_TAG_NAME (type), "::RangeInclusive") != NULL
-         || strstr (TYPE_TAG_NAME (type), "::RangeToInclusive") != NULL);
+  return (strstr (TYPE_NAME (type), "::RangeInclusive") != NULL
+         || strstr (TYPE_NAME (type), "::RangeToInclusive") != NULL);
 }
 
 /* Return true if TYPE seems to be the type "u8", otherwise false.  */
@@ -353,13 +355,13 @@ val_print_struct (struct type *type, int embedded_offset,
 
   if (!is_tuple)
     {
-      if (TYPE_TAG_NAME (type) != NULL)
-        fprintf_filtered (stream, "%s", TYPE_TAG_NAME (type));
+      if (TYPE_NAME (type) != NULL)
+        fprintf_filtered (stream, "%s", TYPE_NAME (type));
 
       if (TYPE_NFIELDS (type) == 0)
         return;
 
-      if (TYPE_TAG_NAME (type) != NULL)
+      if (TYPE_NAME (type) != NULL)
         fputs_filtered (" ", stream);
     }
 
@@ -616,19 +618,19 @@ static void
 rust_internal_print_type (struct type *type, const char *varstring,
                          struct ui_file *stream, int show, int level,
                          const struct type_print_options *flags,
-                         bool for_rust_enum);
+                         bool for_rust_enum, print_offset_data *podata);
 
 /* Print a struct or union typedef.  */
 static void
 rust_print_struct_def (struct type *type, const char *varstring,
                       struct ui_file *stream, int show, int level,
                       const struct type_print_options *flags,
-                      bool for_rust_enum)
+                      bool for_rust_enum, print_offset_data *podata)
 {
   /* Print a tuple type simply.  */
   if (rust_tuple_type_p (type))
     {
-      fputs_filtered (TYPE_TAG_NAME (type), stream);
+      fputs_filtered (TYPE_NAME (type), stream);
       return;
     }
 
@@ -636,9 +638,16 @@ rust_print_struct_def (struct type *type, const char *varstring,
   if (TYPE_N_BASECLASSES (type) > 0)
     c_print_type (type, varstring, stream, show, level, flags);
 
+  if (flags->print_offsets)
+    {
+      /* Temporarily bump the level so that the output lines up
+        correctly.  */
+      level += 2;
+    }
+
   /* Compute properties of TYPE here because, in the enum case, the
      rest of the code ends up looking only at the variant part.  */
-  const char *tagname = TYPE_TAG_NAME (type);
+  const char *tagname = TYPE_NAME (type);
   bool is_tuple_struct = rust_tuple_struct_type_p (type);
   bool is_tuple = rust_tuple_type_p (type);
   bool is_enum = rust_enum_p (type);
@@ -674,16 +683,41 @@ rust_print_struct_def (struct type *type, const char *varstring,
 
   if (TYPE_NFIELDS (type) == 0 && !is_tuple)
     return;
-  if (for_rust_enum)
+  if (for_rust_enum && !flags->print_offsets)
     fputs_filtered (is_tuple_struct ? "(" : "{", stream);
   else
     fputs_filtered (is_tuple_struct ? " (\n" : " {\n", stream);
 
+  /* When printing offsets, we rearrange the fields into storage
+     order.  This lets us show holes more clearly.  We work using
+     field indices here because it simplifies calls to
+     print_offset_data::update below.  */
+  std::vector<int> fields;
   for (int i = 0; i < TYPE_NFIELDS (type); ++i)
     {
-      QUIT;
       if (field_is_static (&TYPE_FIELD (type, i)))
        continue;
+      if (is_enum && i == enum_discriminant_index)
+       continue;
+      fields.push_back (i);
+    }
+  if (flags->print_offsets)
+    std::sort (fields.begin (), fields.end (),
+              [&] (int a, int b)
+              {
+                return (TYPE_FIELD_BITPOS (type, a)
+                        < TYPE_FIELD_BITPOS (type, b));
+              });
+
+  for (int i : fields)
+    {
+      QUIT;
+
+      gdb_assert (!field_is_static (&TYPE_FIELD (type, i)));
+      gdb_assert (! (is_enum && i == enum_discriminant_index));
+
+      if (flags->print_offsets)
+       podata->update (type, i, stream);
 
       /* We'd like to print "pub" here as needed, but rustc
         doesn't emit the debuginfo, and our types don't have
@@ -691,27 +725,35 @@ rust_print_struct_def (struct type *type, const char *varstring,
 
       /* For a tuple struct we print the type but nothing
         else.  */
-      if (!for_rust_enum)
+      if (!for_rust_enum || flags->print_offsets)
        print_spaces_filtered (level + 2, stream);
       if (is_enum)
-       {
-         if (i == enum_discriminant_index)
-           continue;
-         fputs_filtered (TYPE_FIELD_NAME (type, i), stream);
-       }
+       fputs_filtered (TYPE_FIELD_NAME (type, i), stream);
       else if (!is_tuple_struct)
        fprintf_filtered (stream, "%s: ", TYPE_FIELD_NAME (type, i));
 
       rust_internal_print_type (TYPE_FIELD_TYPE (type, i), NULL,
                                stream, (is_enum ? show : show - 1),
-                               level + 2, flags, is_enum);
-      if (!for_rust_enum)
+                               level + 2, flags, is_enum, podata);
+      if (!for_rust_enum || flags->print_offsets)
        fputs_filtered (",\n", stream);
+      /* Note that this check of "I" is ok because we only sorted the
+        fields by offset when print_offsets was set, so we won't take
+        this branch in that case.  */
       else if (i + 1 < TYPE_NFIELDS (type))
        fputs_filtered (", ", stream);
     }
 
-  if (!for_rust_enum)
+  if (flags->print_offsets)
+    {
+      /* Undo the temporary level increase we did above.  */
+      level -= 2;
+      podata->finish (type, level, stream);
+      print_spaces_filtered (print_offset_data::indentation, stream);
+      if (level == 0)
+       print_spaces_filtered (2, stream);
+    }
+  if (!for_rust_enum || flags->print_offsets)
     print_spaces_filtered (level, stream);
   fputs_filtered (is_tuple_struct ? ")" : "}", stream);
 }
@@ -735,7 +777,7 @@ static void
 rust_internal_print_type (struct type *type, const char *varstring,
                          struct ui_file *stream, int show, int level,
                          const struct type_print_options *flags,
-                         bool for_rust_enum)
+                         bool for_rust_enum, print_offset_data *podata)
 {
   int i;
 
@@ -778,7 +820,7 @@ rust_internal_print_type (struct type *type, const char *varstring,
          if (i > 0)
            fputs_filtered (", ", stream);
          rust_internal_print_type (TYPE_FIELD_TYPE (type, i), "", stream,
-                                   -1, 0, flags, false);
+                                   -1, 0, flags, false, podata);
        }
       fputs_filtered (")", stream);
       /* If it returns unit, we can omit the return type.  */
@@ -786,7 +828,7 @@ rust_internal_print_type (struct type *type, const char *varstring,
         {
           fputs_filtered (" -> ", stream);
           rust_internal_print_type (TYPE_TARGET_TYPE (type), "", stream,
-                                   -1, 0, flags, false);
+                                   -1, 0, flags, false, podata);
         }
       break;
 
@@ -796,7 +838,8 @@ rust_internal_print_type (struct type *type, const char *varstring,
 
        fputs_filtered ("[", stream);
        rust_internal_print_type (TYPE_TARGET_TYPE (type), NULL,
-                                 stream, show - 1, level, flags, false);
+                                 stream, show - 1, level, flags, false,
+                                 podata);
 
        if (TYPE_HIGH_BOUND_KIND (TYPE_INDEX_TYPE (type)) == PROP_LOCEXPR
            || TYPE_HIGH_BOUND_KIND (TYPE_INDEX_TYPE (type)) == PROP_LOCLIST)
@@ -811,7 +854,7 @@ rust_internal_print_type (struct type *type, const char *varstring,
     case TYPE_CODE_UNION:
     case TYPE_CODE_STRUCT:
       rust_print_struct_def (type, varstring, stream, show, level, flags,
-                            for_rust_enum);
+                            for_rust_enum, podata);
       break;
 
     case TYPE_CODE_ENUM:
@@ -819,11 +862,11 @@ rust_internal_print_type (struct type *type, const char *varstring,
        int i, len = 0;
 
        fputs_filtered ("enum ", stream);
-       if (TYPE_TAG_NAME (type) != NULL)
+       if (TYPE_NAME (type) != NULL)
          {
-           fputs_filtered (TYPE_TAG_NAME (type), stream);
+           fputs_filtered (TYPE_NAME (type), stream);
            fputs_filtered (" ", stream);
-           len = strlen (TYPE_TAG_NAME (type));
+           len = strlen (TYPE_NAME (type));
          }
        fputs_filtered ("{\n", stream);
 
@@ -834,7 +877,7 @@ rust_internal_print_type (struct type *type, const char *varstring,
            QUIT;
 
            if (len > 0
-               && strncmp (name, TYPE_TAG_NAME (type), len) == 0
+               && strncmp (name, TYPE_NAME (type), len) == 0
                && name[len] == ':'
                && name[len + 1] == ':')
              name += len + 2;
@@ -856,8 +899,9 @@ rust_print_type (struct type *type, const char *varstring,
                 struct ui_file *stream, int show, int level,
                 const struct type_print_options *flags)
 {
+  print_offset_data podata;
   rust_internal_print_type (type, varstring, stream, show, level,
-                           flags, false);
+                           flags, false, &podata);
 }
 
 \f
@@ -882,7 +926,6 @@ rust_composite_type (struct type *original,
 
   TYPE_CODE (result) = TYPE_CODE_STRUCT;
   TYPE_NAME (result) = name;
-  TYPE_TAG_NAME (result) = name;
 
   TYPE_NFIELDS (result) = nfields;
   TYPE_FIELDS (result)
@@ -1060,10 +1103,10 @@ rust_evaluate_funcall (struct expression *exp, int *pos, enum noside noside)
        && TYPE_CODE (type) != TYPE_CODE_ENUM)
       || rust_tuple_type_p (type))
     error (_("Method calls only supported on struct or enum types"));
-  if (TYPE_TAG_NAME (type) == NULL)
+  if (TYPE_NAME (type) == NULL)
     error (_("Method call on nameless type"));
 
-  std::string name = std::string (TYPE_TAG_NAME (type)) + "::" + method;
+  std::string name = std::string (TYPE_NAME (type)) + "::" + method;
 
   block = get_selected_block (0);
   sym = lookup_symbol (name.c_str (), block, VAR_DOMAIN, NULL);
@@ -1512,7 +1555,7 @@ rust_evaluate_subexp (struct type *expect_type, struct expression *exp,
 
     case OP_RUST_ARRAY:
       {
-       int pc = (*pos)++;
+       (*pos)++;
        int copies;
        struct value *elt;
        struct value *ncopies;
@@ -1546,7 +1589,7 @@ rust_evaluate_subexp (struct type *expect_type, struct expression *exp,
         /* Anonymous field access, i.e. foo.1.  */
         struct value *lhs;
         int pc, field_number, nfields;
-        struct type *type, *variant_type;
+        struct type *type;
 
         pc = (*pos)++;
         field_number = longest_to_int (exp->elts[pc + 1].longconst);
@@ -1583,13 +1626,13 @@ rust_evaluate_subexp (struct type *expect_type, struct expression *exp,
                if (outer_type != NULL)
                  error(_("Cannot access field %d of variant %s::%s, "
                          "there are only %d fields"),
-                       field_number, TYPE_TAG_NAME (outer_type),
-                       rust_last_path_segment (TYPE_TAG_NAME (type)),
+                       field_number, TYPE_NAME (outer_type),
+                       rust_last_path_segment (TYPE_NAME (type)),
                        nfields);
                else
                  error(_("Cannot access field %d of %s, "
                          "there are only %d fields"),
-                       field_number, TYPE_TAG_NAME (type), nfields);
+                       field_number, TYPE_NAME (type), nfields);
              }
 
            /* Tuples are tuple structs too.  */
@@ -1597,13 +1640,13 @@ rust_evaluate_subexp (struct type *expect_type, struct expression *exp,
              {
                if (outer_type != NULL)
                  error(_("Variant %s::%s is not a tuple variant"),
-                       TYPE_TAG_NAME (outer_type),
-                       rust_last_path_segment (TYPE_TAG_NAME (type)));
+                       TYPE_NAME (outer_type),
+                       rust_last_path_segment (TYPE_NAME (type)));
                else
                  error(_("Attempting to access anonymous field %d "
                          "of %s, which is not a tuple, tuple struct, or "
                          "tuple-like variant"),
-                     field_number, TYPE_TAG_NAME (type));
+                     field_number, TYPE_NAME (type));
              }
 
            result = value_primitive_field (lhs, 0, field_number, type);
@@ -1645,7 +1688,7 @@ tuple structs, and tuple-like enum variants"));
            if (rust_tuple_type_p (type) || rust_tuple_struct_type_p (type))
                error (_("Attempting to access named field foo of tuple "
                         "variant %s::%s, which has only anonymous fields"),
-                      TYPE_TAG_NAME (outer_type),
+                      TYPE_NAME (outer_type),
                       rust_last_path_segment (TYPE_NAME (type)));
 
            TRY
@@ -1656,7 +1699,7 @@ tuple structs, and tuple-like enum variants"));
            CATCH (except, RETURN_MASK_ERROR)
              {
                error (_("Could not find field %s of struct variant %s::%s"),
-                      field_name, TYPE_TAG_NAME (outer_type),
+                      field_name, TYPE_NAME (outer_type),
                       rust_last_path_segment (TYPE_NAME (type)));
              }
            END_CATCH
@@ -2014,7 +2057,6 @@ extern const struct language_defn rust_language_defn =
   rust_extensions,
   &exp_descriptor_rust,
   rust_parse,
-  rustyyerror,
   null_post_parser,
   rust_printchar,              /* Print a character constant */
   rust_printstr,               /* Function to print string constant */
This page took 0.043091 seconds and 4 git commands to generate.