gdb: move Modula2 language class into a header file
authorAndrew Burgess <andrew.burgess@embecosm.com>
Fri, 14 Aug 2020 13:50:48 +0000 (14:50 +0100)
committerAndrew Burgess <andrew.burgess@embecosm.com>
Fri, 23 Oct 2020 09:57:13 +0000 (10:57 +0100)
Move the m2_language class from m2-lang.c into m2-lang.h.  The benefit
of this move is that we can remove trampoline functions.  Currently
the language implementation is split of different m2-* files with
m2-lang.h including declaration for all the language implementation
functions.

Currently the m2_language class in m2-lang.c has member functions that
then call the global functions declared in m2-lang.h.

After this change the m2_language class is declared in m2-lang.h, and
the member functions are the implementations defined in all the m2-*
files.

There should be no user visible changes after this commit.

gdb/ChangeLog:

* m2-exp.y (m2_parse): Rename to...
(m2_language::parser): ...this.  Update function signature.
* m2-lang.c (m2_printchar): Renamed to m2_language::printchar.
(m2_op_print): Rename to...
(m2_language::op_print_tab): ...this, and make const.
(exp_descriptor_modula2): Rename to...
(m2_language::exp_descriptor_modula2): ...this.
(class m2_language): Move to m2-lang.h.
(m2_language::language_arch_info): New function, moved out of
class declaration.
(m2_language::printchar): New function, body from m2_printchar.
(m2_language::printstr): New function, moved out of class
declaration.
(m2_language::emitchar): Likewise.
* m2-lang.h (m2_parse): Delete declaration.
(m2_print_typedef): Delete declaration.
(m2_value_print_inner): Delete declaration.
(class m2_language): Class declaration moved from m2-lang.c,
larger functions are left in m2-lang.c.
* m2-typeprint.c (m2_print_typedef): Rename to...
(m2_language::print_typedef): ...this, and update function
signature.
* m2-valprint.c (m2_value_print_inner): Rename to...
(m2_language::value_print_inner): ...this, replace use of
LA_PRINT_STRING with a direct call to printstr member function,
and update recursive call.

gdb/ChangeLog
gdb/m2-exp.y
gdb/m2-lang.c
gdb/m2-lang.h
gdb/m2-typeprint.c
gdb/m2-valprint.c

index 8de837632a643e3700041db7d0a4c4b0fc1e4e19..e9ab8ec22264aa7df3182932a420a539b4c2d000 100644 (file)
@@ -1,3 +1,32 @@
+2020-10-23  Andrew Burgess  <andrew.burgess@embecosm.com>
+
+       * m2-exp.y (m2_parse): Rename to...
+       (m2_language::parser): ...this.  Update function signature.
+       * m2-lang.c (m2_printchar): Renamed to m2_language::printchar.
+       (m2_op_print): Rename to...
+       (m2_language::op_print_tab): ...this, and make const.
+       (exp_descriptor_modula2): Rename to...
+       (m2_language::exp_descriptor_modula2): ...this.
+       (class m2_language): Move to m2-lang.h.
+       (m2_language::language_arch_info): New function, moved out of
+       class declaration.
+       (m2_language::printchar): New function, body from m2_printchar.
+       (m2_language::printstr): New function, moved out of class
+       declaration.
+       (m2_language::emitchar): Likewise.
+       * m2-lang.h (m2_parse): Delete declaration.
+       (m2_print_typedef): Delete declaration.
+       (m2_value_print_inner): Delete declaration.
+       (class m2_language): Class declaration moved from m2-lang.c,
+       larger functions are left in m2-lang.c.
+       * m2-typeprint.c (m2_print_typedef): Rename to...
+       (m2_language::print_typedef): ...this, and update function
+       signature.
+       * m2-valprint.c (m2_value_print_inner): Rename to...
+       (m2_language::value_print_inner): ...this, replace use of
+       LA_PRINT_STRING with a direct call to printstr member function,
+       and update recursive call.
+
 2020-10-23  Andrew Burgess  <andrew.burgess@embecosm.com>
 
        * language.c (default_is_string_type_p): Delete, implementation
index c79c1f25828b3a0a95b39d0b678ec37adc9a8fc4..5924e895c7022573e7694b28774b06e717ea1d87 100644 (file)
@@ -1031,7 +1031,7 @@ yylex (void)
 }
 
 int
-m2_parse (struct parser_state *par_state)
+m2_language::parser (struct parser_state *par_state) const
 {
   /* Setting up the parser state.  */
   scoped_restore pstate_restore = make_scoped_restore (&pstate);
index 3cc0364b4a147c5d8cc1f2767e97b17af28c9753..2f671eff08f11e8d6d5f505fece4c492b8d8e848 100644 (file)
 #include "valprint.h"
 #include "gdbarch.h"
 
-static void m2_printchar (int, struct type *, struct ui_file *);
-
-/* FIXME:  This is a copy of the same function from c-exp.y.  It should
-   be replaced with a true Modula version.  */
-
-static void
-m2_printchar (int c, struct type *type, struct ui_file *stream)
-{
-  fputs_filtered ("'", stream);
-  LA_EMIT_CHAR (c, type, stream, '\'');
-  fputs_filtered ("'", stream);
-}
-
 static struct value *
 evaluate_subexp_modula2 (struct type *expect_type, struct expression *exp,
                         int *pos, enum noside noside)
@@ -140,7 +127,7 @@ evaluate_subexp_modula2 (struct type *expect_type, struct expression *exp,
 
 /* Table of operators and their precedences for printing expressions.  */
 
-static const struct op_print m2_op_print_tab[] =
+const struct op_print m2_language::op_print_tab[] =
 {
   {"+", BINOP_ADD, PREC_ADD, 0},
   {"+", UNOP_PLUS, PREC_PREFIX, 0},
@@ -185,7 +172,7 @@ enum m2_primitive_types {
   nr_m2_primitive_types
 };
 
-const struct exp_descriptor exp_descriptor_modula2 = 
+const struct exp_descriptor m2_language::exp_descriptor_modula2 =
 {
   print_subexp_standard,
   operator_length_standard,
@@ -195,262 +182,173 @@ const struct exp_descriptor exp_descriptor_modula2 =
   evaluate_subexp_modula2
 };
 
-/* Class representing the M2 language.  */
-
-class m2_language : public language_defn
-{
-public:
-  m2_language ()
-    : language_defn (language_m2)
-  { /* Nothing.  */ }
-
-  /* See language.h.  */
-
-  const char *name () const override
-  { return "modula-2"; }
-
-  /* See language.h.  */
-
-  const char *natural_name () const override
-  { return "Modula-2"; }
-
-  /* See language.h.  */
-  void language_arch_info (struct gdbarch *gdbarch,
-                          struct language_arch_info *lai) const override
-  {
-    const struct builtin_m2_type *builtin = builtin_m2_type (gdbarch);
-
-    lai->string_char_type = builtin->builtin_char;
-    lai->primitive_type_vector
-      = GDBARCH_OBSTACK_CALLOC (gdbarch, nr_m2_primitive_types + 1,
-                               struct type *);
-
-    lai->primitive_type_vector [m2_primitive_type_char]
-      = builtin->builtin_char;
-    lai->primitive_type_vector [m2_primitive_type_int]
-      = builtin->builtin_int;
-    lai->primitive_type_vector [m2_primitive_type_card]
-      = builtin->builtin_card;
-    lai->primitive_type_vector [m2_primitive_type_real]
-      = builtin->builtin_real;
-    lai->primitive_type_vector [m2_primitive_type_bool]
-      = builtin->builtin_bool;
-
-    lai->bool_type_symbol = "BOOLEAN";
-    lai->bool_type_default = builtin->builtin_bool;
-  }
-
-  /* See language.h.  */
-
-  void print_type (struct type *type, const char *varstring,
-                  struct ui_file *stream, int show, int level,
-                  const struct type_print_options *flags) const override
-  {
-    m2_print_type (type, varstring, stream, show, level, flags);
-  }
-
-  /* See language.h.  */
-
-  void value_print_inner
-       (struct value *val, struct ui_file *stream, int recurse,
-        const struct value_print_options *options) const override
-  {
-    return m2_value_print_inner (val, stream, recurse, options);
-  }
-
-  /* See language.h.  */
-
-  int parser (struct parser_state *ps) const override
-  {
-    return m2_parse (ps);
-  }
-
-  /* See language.h.  */
-
-  void emitchar (int ch, struct type *chtype,
-                struct ui_file *stream, int quoter) const override
-  {
-    ch &= 0xFF;                        /* Avoid sign bit follies.  */
-
-    if (PRINT_LITERAL_FORM (ch))
-      {
-       if (ch == '\\' || ch == quoter)
-         fputs_filtered ("\\", stream);
-       fprintf_filtered (stream, "%c", ch);
-      }
-    else
-      {
-       switch (ch)
-         {
-         case '\n':
-           fputs_filtered ("\\n", stream);
-           break;
-         case '\b':
-           fputs_filtered ("\\b", stream);
-           break;
-         case '\t':
-           fputs_filtered ("\\t", stream);
-           break;
-         case '\f':
-           fputs_filtered ("\\f", stream);
-           break;
-         case '\r':
-           fputs_filtered ("\\r", stream);
-           break;
-         case '\033':
-           fputs_filtered ("\\e", stream);
-           break;
-         case '\007':
-           fputs_filtered ("\\a", stream);
-           break;
-         default:
-           fprintf_filtered (stream, "\\%.3o", (unsigned int) ch);
-           break;
-         }
-      }
-  }
-
-  /* See language.h.  */
-
-  void printchar (int ch, struct type *chtype,
-                 struct ui_file *stream) const override
-  {
-    m2_printchar (ch, chtype, stream);
-  }
-
-  /* See language.h.  */
-
-  void printstr (struct ui_file *stream, struct type *elttype,
-                const gdb_byte *string, unsigned int length,
-                const char *encoding, int force_ellipses,
-                const struct value_print_options *options) const override
-  {
-    unsigned int i;
-    unsigned int things_printed = 0;
-    int in_quotes = 0;
-    int need_comma = 0;
-
-    if (length == 0)
-      {
-       fputs_filtered ("\"\"", gdb_stdout);
-       return;
-      }
-
-    for (i = 0; i < length && things_printed < options->print_max; ++i)
-      {
-       /* Position of the character we are examining
-          to see whether it is repeated.  */
-       unsigned int rep1;
-       /* Number of repetitions we have detected so far.  */
-       unsigned int reps;
-
-       QUIT;
-
-       if (need_comma)
-         {
-           fputs_filtered (", ", stream);
-           need_comma = 0;
-         }
-
-       rep1 = i + 1;
-       reps = 1;
-       while (rep1 < length && string[rep1] == string[i])
-         {
-           ++rep1;
-           ++reps;
-         }
-
-       if (reps > options->repeat_count_threshold)
-         {
-           if (in_quotes)
-             {
-               fputs_filtered ("\", ", stream);
-               in_quotes = 0;
-             }
-           m2_printchar (string[i], elttype, stream);
-           fprintf_filtered (stream, " <repeats %u times>", reps);
-           i = rep1 - 1;
-           things_printed += options->repeat_count_threshold;
-           need_comma = 1;
-         }
-       else
-         {
-           if (!in_quotes)
-             {
-               fputs_filtered ("\"", stream);
-               in_quotes = 1;
-             }
-           LA_EMIT_CHAR (string[i], elttype, stream, '"');
-           ++things_printed;
-         }
-      }
-
-    /* Terminate the quotes if necessary.  */
-    if (in_quotes)
-      fputs_filtered ("\"", stream);
+/* Single instance of the M2 language.  */
 
-    if (force_ellipses || i < length)
-      fputs_filtered ("...", stream);
-  }
+static m2_language m2_language_defn;
 
-  /* See language.h.  */
+/* See language.h.  */
 
-  void print_typedef (struct type *type, struct symbol *new_symbol,
-                     struct ui_file *stream) const override
-  {
-    m2_print_typedef (type, new_symbol, stream);
-  }
+void
+m2_language::language_arch_info (struct gdbarch *gdbarch,
+                                struct language_arch_info *lai) const
+{
+  const struct builtin_m2_type *builtin = builtin_m2_type (gdbarch);
+
+  lai->string_char_type = builtin->builtin_char;
+  lai->primitive_type_vector
+    = GDBARCH_OBSTACK_CALLOC (gdbarch, nr_m2_primitive_types + 1,
+                             struct type *);
+
+  lai->primitive_type_vector [m2_primitive_type_char]
+    = builtin->builtin_char;
+  lai->primitive_type_vector [m2_primitive_type_int]
+    = builtin->builtin_int;
+  lai->primitive_type_vector [m2_primitive_type_card]
+    = builtin->builtin_card;
+  lai->primitive_type_vector [m2_primitive_type_real]
+    = builtin->builtin_real;
+  lai->primitive_type_vector [m2_primitive_type_bool]
+    = builtin->builtin_bool;
+
+  lai->bool_type_symbol = "BOOLEAN";
+  lai->bool_type_default = builtin->builtin_bool;
+}
 
-  /* See language.h.  */
+/* See languge.h.  */
 
-  bool is_string_type_p (struct type *type) const override
-  {
-    type = check_typedef (type);
-    if (type->code () == TYPE_CODE_ARRAY
-       && TYPE_LENGTH (type) > 0
-       && TYPE_LENGTH (TYPE_TARGET_TYPE (type)) > 0)
-      {
-       struct type *elttype = check_typedef (TYPE_TARGET_TYPE (type));
+void
+m2_language::printchar (int c, struct type *type,
+                       struct ui_file *stream) const
+{
+  fputs_filtered ("'", stream);
+  emitchar (c, type, stream, '\'');
+  fputs_filtered ("'", stream);
+}
 
-       if (TYPE_LENGTH (elttype) == 1
-           && (elttype->code () == TYPE_CODE_INT
-               || elttype->code () == TYPE_CODE_CHAR))
-         return true;
-      }
+/* See language.h.  */
 
-    return false;
-  }
+void
+m2_language::printstr (struct ui_file *stream, struct type *elttype,
+                       const gdb_byte *string, unsigned int length,
+                       const char *encoding, int force_ellipses,
+                       const struct value_print_options *options) const
+{
+  unsigned int i;
+  unsigned int things_printed = 0;
+  int in_quotes = 0;
+  int need_comma = 0;
 
-  /* See language.h.  */
+  if (length == 0)
+    {
+      fputs_filtered ("\"\"", gdb_stdout);
+      return;
+    }
 
-  bool c_style_arrays_p () const override
-  { return false; }
+  for (i = 0; i < length && things_printed < options->print_max; ++i)
+    {
+      /* Position of the character we are examining
+        to see whether it is repeated.  */
+      unsigned int rep1;
+      /* Number of repetitions we have detected so far.  */
+      unsigned int reps;
 
-  /* See language.h.  Despite not having C-style arrays, Modula-2 uses 0
-     for its string lower bounds.  */
+      QUIT;
 
-  char string_lower_bound () const override
-  { return 0; }
+      if (need_comma)
+       {
+         fputs_filtered (", ", stream);
+         need_comma = 0;
+       }
 
-  /* See language.h.  */
+      rep1 = i + 1;
+      reps = 1;
+      while (rep1 < length && string[rep1] == string[i])
+       {
+         ++rep1;
+         ++reps;
+       }
 
-  bool range_checking_on_by_default () const override
-  { return true; }
+      if (reps > options->repeat_count_threshold)
+       {
+         if (in_quotes)
+           {
+             fputs_filtered ("\", ", stream);
+             in_quotes = 0;
+           }
+         printchar (string[i], elttype, stream);
+         fprintf_filtered (stream, " <repeats %u times>", reps);
+         i = rep1 - 1;
+         things_printed += options->repeat_count_threshold;
+         need_comma = 1;
+       }
+      else
+       {
+         if (!in_quotes)
+           {
+             fputs_filtered ("\"", stream);
+             in_quotes = 1;
+           }
+         emitchar (string[i], elttype, stream, '"');
+         ++things_printed;
+       }
+    }
 
-  /* See language.h.  */
+  /* Terminate the quotes if necessary.  */
+  if (in_quotes)
+    fputs_filtered ("\"", stream);
 
-  const struct exp_descriptor *expression_ops () const override
-  { return &exp_descriptor_modula2; }
+  if (force_ellipses || i < length)
+    fputs_filtered ("...", stream);
+}
 
-  /* See language.h.  */
+/* See language.h.  */
 
-  const struct op_print *opcode_print_table () const override
-  { return m2_op_print_tab; }
-};
+void
+m2_language::emitchar (int ch, struct type *chtype,
+                      struct ui_file *stream, int quoter) const
+{
+  ch &= 0xFF;                  /* Avoid sign bit follies.  */
 
-/* Single instance of the M2 language.  */
+  if (PRINT_LITERAL_FORM (ch))
+    {
+      if (ch == '\\' || ch == quoter)
+       fputs_filtered ("\\", stream);
+      fprintf_filtered (stream, "%c", ch);
+    }
+  else
+    {
+      switch (ch)
+       {
+       case '\n':
+         fputs_filtered ("\\n", stream);
+         break;
+       case '\b':
+         fputs_filtered ("\\b", stream);
+         break;
+       case '\t':
+         fputs_filtered ("\\t", stream);
+         break;
+       case '\f':
+         fputs_filtered ("\\f", stream);
+         break;
+       case '\r':
+         fputs_filtered ("\\r", stream);
+         break;
+       case '\033':
+         fputs_filtered ("\\e", stream);
+         break;
+       case '\007':
+         fputs_filtered ("\\a", stream);
+         break;
+       default:
+         fprintf_filtered (stream, "\\%.3o", (unsigned int) ch);
+         break;
+       }
+    }
+}
 
-static m2_language m2_language_defn;
+/* Called during architecture gdbarch initialisation to create language
+   specific types.  */
 
 static void *
 build_m2_types (struct gdbarch *gdbarch)
index de477e58d5abf2b20b73e128d8f0bf117ea8044c..3cf32587030fbbe92944df405797f0d24b275357 100644 (file)
 struct type_print_options;
 struct parser_state;
 
-extern int m2_parse (struct parser_state *); /* Defined in m2-exp.y */
-
 /* Defined in m2-typeprint.c */
 extern void m2_print_type (struct type *, const char *, struct ui_file *, int,
                           int, const struct type_print_options *);
 
-extern void m2_print_typedef (struct type *, struct symbol *,
-                             struct ui_file *);
-
 extern int m2_is_long_set (struct type *type);
 extern int m2_is_unbounded_array (struct type *type);
 
-/* Implement la_value_print_inner for Modula-2.  */
-
-extern void m2_value_print_inner (struct value *, struct ui_file *, int,
-                                 const struct value_print_options *);
-
 extern int get_long_set_bounds (struct type *type, LONGEST *low,
                                LONGEST *high);
 
@@ -57,4 +47,124 @@ struct builtin_m2_type
 /* Return the Modula-2 type table for the specified architecture.  */
 extern const struct builtin_m2_type *builtin_m2_type (struct gdbarch *gdbarch);
 
+/* Class representing the M2 language.  */
+
+class m2_language : public language_defn
+{
+public:
+  m2_language ()
+    : language_defn (language_m2)
+  { /* Nothing.  */ }
+
+  /* See language.h.  */
+
+  const char *name () const override
+  { return "modula-2"; }
+
+  /* See language.h.  */
+
+  const char *natural_name () const override
+  { return "Modula-2"; }
+
+  /* See language.h.  */
+
+  void language_arch_info (struct gdbarch *gdbarch,
+                          struct language_arch_info *lai) const override;
+
+  /* See language.h.  */
+
+  void print_type (struct type *type, const char *varstring,
+                  struct ui_file *stream, int show, int level,
+                  const struct type_print_options *flags) const override
+  {
+    m2_print_type (type, varstring, stream, show, level, flags);
+  }
+
+  /* See language.h.  */
+
+  void value_print_inner (struct value *val, struct ui_file *stream,
+                         int recurse,
+                         const struct value_print_options *options) const override;
+
+  /* See language.h.  */
+
+  int parser (struct parser_state *ps) const override;
+
+  /* See language.h.  */
+
+  void emitchar (int ch, struct type *chtype,
+                struct ui_file *stream, int quoter) const override;
+
+  /* See language.h.  */
+
+  void printchar (int ch, struct type *chtype,
+                 struct ui_file *stream) const override;
+
+  /* See language.h.  */
+
+  void printstr (struct ui_file *stream, struct type *elttype,
+                const gdb_byte *string, unsigned int length,
+                const char *encoding, int force_ellipses,
+                const struct value_print_options *options) const override;
+
+  /* See language.h.  */
+
+  void print_typedef (struct type *type, struct symbol *new_symbol,
+                     struct ui_file *stream) const override;
+
+  /* See language.h.  */
+
+  bool is_string_type_p (struct type *type) const override
+  {
+    type = check_typedef (type);
+    if (type->code () == TYPE_CODE_ARRAY
+       && TYPE_LENGTH (type) > 0
+       && TYPE_LENGTH (TYPE_TARGET_TYPE (type)) > 0)
+      {
+       struct type *elttype = check_typedef (TYPE_TARGET_TYPE (type));
+
+       if (TYPE_LENGTH (elttype) == 1
+           && (elttype->code () == TYPE_CODE_INT
+               || elttype->code () == TYPE_CODE_CHAR))
+         return true;
+      }
+
+    return false;
+  }
+
+  /* See language.h.  */
+
+  bool c_style_arrays_p () const override
+  { return false; }
+
+  /* See language.h.  Despite not having C-style arrays, Modula-2 uses 0
+     for its string lower bounds.  */
+
+  char string_lower_bound () const override
+  { return 0; }
+
+  /* See language.h.  */
+
+  bool range_checking_on_by_default () const override
+  { return true; }
+
+  /* See language.h.  */
+
+  const struct exp_descriptor *expression_ops () const override
+  { return &exp_descriptor_modula2; }
+
+  /* See language.h.  */
+
+  const struct op_print *opcode_print_table () const override
+  { return op_print_tab; }
+
+private:
+  /* Table of expression handling functions for use by EXPRESSION_OPS
+     member function.  */
+  static const struct exp_descriptor exp_descriptor_modula2;
+
+  /* Table of opcode data for use by OPCODE_PRINT_TABLE member function.  */
+  static const struct op_print op_print_tab[];
+};
+
 #endif /* M2_LANG_H */
index 963d12596be63e8d4242204f190ab3315d171107..dbe112c4fcc2084f5b288ce04d639ac908cf4539 100644 (file)
@@ -158,8 +158,8 @@ m2_print_type (struct type *type, const char *varstring,
    which to print.  */
 
 void
-m2_print_typedef (struct type *type, struct symbol *new_symbol,
-                 struct ui_file *stream)
+m2_language::print_typedef (struct type *type, struct symbol *new_symbol,
+                           struct ui_file *stream) const
 {
   type = check_typedef (type);
   fprintf_filtered (stream, "TYPE ");
index c285543f4bfd5379f1b9732c91b51ed4519b4a12..fdccbaf500d30ad62b00d1972b042fe6272e10e0 100644 (file)
@@ -298,8 +298,9 @@ static const struct generic_val_print_decorations m2_decorations =
 /* See m2-lang.h.  */
 
 void
-m2_value_print_inner (struct value *val, struct ui_file *stream, int recurse,
-                     const struct value_print_options *options)
+m2_language::value_print_inner (struct value *val, struct ui_file *stream,
+                               int recurse,
+                               const struct value_print_options *options) const
 {
   unsigned len;
   struct type *elttype;
@@ -336,8 +337,8 @@ m2_value_print_inner (struct value *val, struct ui_file *stream, int recurse,
                  len = temp_len;
                }
 
-             LA_PRINT_STRING (stream, TYPE_TARGET_TYPE (type),
-                              valaddr, len, NULL, 0, options);
+             printstr (stream, TYPE_TARGET_TYPE (type), valaddr, len,
+                       NULL, 0, options);
            }
          else
            {
@@ -445,7 +446,7 @@ m2_value_print_inner (struct value *val, struct ui_file *stream, int recurse,
       if (TYPE_LENGTH (type) == TYPE_LENGTH (TYPE_TARGET_TYPE (type)))
        {
          struct value *v = value_cast (TYPE_TARGET_TYPE (type), val);
-         m2_value_print_inner (v, stream, recurse, options);
+         value_print_inner (v, stream, recurse, options);
          break;
        }
       /* FALLTHROUGH */