[PATCH 1/5] gdb/mi: introduce new class mi_command_builtin

Jan Vrany jan.vrany@labware.com
Mon Jan 17 12:44:21 GMT 2022


The motivation for this commit is that GDB/MI commands have their names
statically allocated whereas Python-based commands (that will be
introduced in later) will have their name dynamically allocated.

To support this, this commit introduces new abstract class
`mi_command_builtin` that allows for its name to be statically allocated.
Future Python-based commands will hold onto dynamically allocated
std::string.
---
 gdb/mi/mi-cmds.c | 43 ++++++++++++++++++++++++++++++-------------
 gdb/mi/mi-cmds.h | 14 +++++---------
 2 files changed, 35 insertions(+), 22 deletions(-)

diff --git a/gdb/mi/mi-cmds.c b/gdb/mi/mi-cmds.c
index cd7cabdda9b..57fe32c1cc6 100644
--- a/gdb/mi/mi-cmds.c
+++ b/gdb/mi/mi-cmds.c
@@ -34,16 +34,42 @@ using mi_command_up = std::unique_ptr<struct mi_command>;
 
 static std::map<std::string, mi_command_up> mi_cmd_table;
 
+/* The abstract base class for all built-in MI command types.  */
+
+struct mi_command_builtin : public mi_command
+{
+  /* Constructor.  NAME is the name of this MI command, excluding any
+     leading dash, that is the initial string the user will enter to run
+     this command.  For SUPPRESS_NOTIFICATION see mi_command
+     constructor, FUNC is the function called from do_invoke, which
+     implements this MI command.  */
+  mi_command_builtin (const char *name, int *suppress_notification)
+    : mi_command (suppress_notification),
+      m_name (name)
+  {
+    gdb_assert (m_name != nullptr && m_name[0] != '\0' && m_name[0] != '-');
+  }
+
+  virtual const char *name () const override
+  {
+    return m_name;
+  }
+
+private:
+  /* The name of the command.  */
+  const char *m_name;
+};
+
 /* MI command with a pure MI implementation.  */
 
-struct mi_command_mi : public mi_command
+struct mi_command_mi : public mi_command_builtin
 {
   /* Constructor.  For NAME and SUPPRESS_NOTIFICATION see mi_command
      constructor, FUNC is the function called from do_invoke, which
      implements this MI command.  */
   mi_command_mi (const char *name, mi_cmd_argv_ftype func,
                  int *suppress_notification)
-    : mi_command (name, suppress_notification),
+    : mi_command_builtin (name, suppress_notification),
       m_argv_function (func)
   {
     gdb_assert (func != nullptr);
@@ -72,7 +98,7 @@ struct mi_command_mi : public mi_command
 
 /* MI command implemented on top of a CLI command.  */
 
-struct mi_command_cli : public mi_command
+struct mi_command_cli : public mi_command_builtin
 {
   /* Constructor.  For NAME and SUPPRESS_NOTIFICATION see mi_command
      constructor, CLI_NAME is the name of a CLI command that should be
@@ -82,7 +108,7 @@ struct mi_command_cli : public mi_command
      false, nullptr is send to CLI_NAME as its argument string.  */
   mi_command_cli (const char *name, const char *cli_name, bool args_p,
                   int *suppress_notification)
-    : mi_command (name, suppress_notification),
+    : mi_command_builtin (name, suppress_notification),
       m_cli_name (cli_name),
       m_args_p (args_p)
   { /* Nothing.  */ }
@@ -159,15 +185,6 @@ add_mi_cmd_cli (const char *name, const char *cli_name, int args_p,
 
 /* See mi-cmds.h.  */
 
-mi_command::mi_command (const char *name, int *suppress_notification)
-  : m_name (name),
-    m_suppress_notification (suppress_notification)
-{
-  gdb_assert (m_name != nullptr && m_name[0] != '\0');
-}
-
-/* See mi-cmds.h.  */
-
 void
 mi_command::invoke (struct mi_parse *parse) const
 {
diff --git a/gdb/mi/mi-cmds.h b/gdb/mi/mi-cmds.h
index 2a93a9f5476..94ecb271d48 100644
--- a/gdb/mi/mi-cmds.h
+++ b/gdb/mi/mi-cmds.h
@@ -143,12 +143,12 @@ extern mi_cmd_argv_ftype mi_cmd_complete;
 
 struct mi_command
 {
-  /* Constructor.  NAME is the name of this MI command, excluding any
-     leading dash, that is the initial string the user will enter to run
-     this command.  The SUPPRESS_NOTIFICATION pointer is a flag which will
+  /* Constructor.  The SUPPRESS_NOTIFICATION pointer is a flag which will
      be set to 1 when this command is invoked, and reset to its previous
      value once the command invocation has completed.  */
-  mi_command (const char *name, int *suppress_notification);
+  mi_command (int *suppress_notification)
+    : m_suppress_notification (suppress_notification)
+  {}
 
   /* Destructor.  */
   virtual ~mi_command () = default;
@@ -156,8 +156,7 @@ struct mi_command
   /* Return the name of this command.  This is the command that the user
      will actually type in, without any arguments, and without the leading
      dash.  */
-  const char *name () const
-  { return m_name; }
+  virtual const char *name () const = 0;
 
   /* Execute the MI command.  Can throw an exception if something goes
      wrong.  */
@@ -180,9 +179,6 @@ struct mi_command
      then this function returns an empty gdb::optional.  */
   gdb::optional<scoped_restore_tmpl<int>> do_suppress_notification () const;
 
-  /* The name of the command.  */
-  const char *m_name;
-
   /* Pointer to integer to set during command's invocation.  */
   int *m_suppress_notification;
 };
-- 
2.30.2



More information about the Gdb-patches mailing list